ImageVerifierCode 换一换
格式:DOCX , 页数:17 ,大小:24.35KB ,
资源ID:9524571      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/9524571.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(关于ping程序的一点注释.docx)为本站会员(b****7)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

关于ping程序的一点注释.docx

1、关于ping程序的一点注释Ping.c#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include busybox.h /这里告诉我们linux下的libc5库是不提供icmp支持的, 所以如果是libc5库的系统上如果要ping ,即需要自己定义相应的icmp结构/* It turns out that libc5 doesnt ha

2、ve proper icmp support* built into it header files, so we have to supplement it */#if _GNU_LIBRARY_ 5 static const int ICMP_MINLEN = 8; /icmp最小也要有8位,用来校验是判断 /* abs minimum */ /以下是定义icmp结构,通常icmp是通过ip包发送的,所以发送的数据在 通常是在外先裹层icmp报头,然后在进入网络层裹上ip报头一起发送的,所以接受时,我们往往要跳过ip报头 然后把icmp的东西取出来判断,这里对ip报头不分析,仅仅定义lib

3、c5需要的icmp结构 /常见的icmp通常由type code cksum 组成报头, 然后是根据不同需求需要发送的data字段,其中不同需求 由type的代码的不同 而对data字段的包含也不同,而ping中通常用的是ICMP_ECHO ;code是代码段,ping中通常为0 ;cksum 是网络中ip等通常用的校验算法,算法下面解释。struct icmp_ra_addr u_int32_t ira_addr;u_int32_t ira_preference;struct icmpu_int8_ticmp_type; /* type of message, see below */这是t

4、ypeu_int8_ticmp_code; /* type sub code */ /这是codeu_int16_t icmp_cksum; /* ones complement checksum of struct */ /校验/注意下面用了union结构,这是因为icmp除了探测主机,即ping外还有其他的功能,根据功能码的不同每次发出去的下面的数据段结构其实是不一样的,在这里我们只需用到struct ih_idseq因为这是ping所需要的结构,其他的icmp管理,我们暂时不用管,因为一次只会用到一种数据类型,所以用union定义一个最大的空间union /发送的各个data的最大值 u

5、_char ih_pptr; /* ICMP_PARAMPROB */ struct in_addr ih_gwaddr; /* gateway address */ struct ih_idseq /* echo datagram */ /echo是我们关心程序发送给主机用来探测的 u_int16_t icd_id;/这个是id u_int16_t icd_seq; /这个是seq就是包的顺序 ih_idseq; u_int32_t ih_void; /* ICMP_UNREACH_NEEDFRAG - Path MTU Discovery (RFC1191) */ struct ih_pm

6、tu/这个是关于MTU路径的。不用 u_int16_t ipm_void; u_int16_t ipm_nextmtu; ih_pmtu; struct ih_rtradv u_int8_t irt_num_addrs; u_int8_t irt_wpa; u_int16_t irt_lifetime; ih_rtradv; icmp_hun;#define icmp_pptr icmp_hun.ih_pptr/这个就不多说了,为了使用方便的定义#define icmp_gwaddr icmp_hun.ih_gwaddr#define icmp_id icmp_hun.ih_idseq.icd

7、_id#define icmp_seq icmp_hun.ih_idseq.icd_seq#define icmp_void icmp_hun.ih_void#define icmp_pmvoid icmp_hun.ih_pmtu.ipm_void#define icmp_nextmtu icmp_hun.ih_pmtu.ipm_nextmtu#define icmp_num_addrs icmp_hun.ih_rtradv.irt_num_addrs#define icmp_wpa icmp_hun.ih_rtradv.irt_wpa#define icmp_lifetime icmp_hu

8、n.ih_rtradv.irt_lifetimeunion/这里定义必要的主机回复的Union结构,Ping中需要用的是id_ts;代表响应时间 struct u_int32_t its_otime; u_int32_t its_rtime; u_int32_t its_ttime; id_ts; struct struct ip idi_ip; /* options and then 64 bits of data */ id_ip; struct icmp_ra_addr id_radv; u_int32_t id_mask; u_int8_t id_data1; icmp_dun; #d

9、efine icmp_otime icmp_dun.id_ts.its_otime/这个同上#define icmp_rtime icmp_dun.id_ts.its_rtime#define icmp_ttime icmp_dun.id_ts.its_ttime#define icmp_ip icmp_dun.id_ip.idi_ip#define icmp_radv icmp_dun.id_radv#define icmp_mask icmp_dun.id_mask#define icmp_data icmp_dun.id_data;#endif/这里icmp结构定义结束,好象很复杂,但是

10、在ping中真正用到的不多,还有一点,在IP报头中我们还需要用到IP报头长度IHL和生存时间TTL,报头长度用来让我们在ping时如果通过IP路由转发后连IP报头一起返回时跳过到icmp而ttl是我们ping中需要的,而还需说明的是ip因为是点对点的,不是tcp,所以ping中不需要bind和listen 只需把信息发送出去即可;切记/下面是数据包大小定义 ,icmp中最小也要有8位,否则就不是icmp 因为icmp报头包含type、code和cksum和这三项内容,长度为8位,8位和16位,然后id是16位的,seq是16位的,合起来正好8个字节,这也是icmp的最小长度了。而最大长度则看下

11、面的定义/公用基本的数据定义static const int DEFDATALEN = 56;/默认报头长度static const int MAXIPLEN = 60;/一个最大ip报头长度static const int MAXICMPLEN = 76;/一个最大icmp报头长度static const int MAXPACKET = 65468;/最大packet,icmp规定最大发送数据data=64k#define MAX_DUP_CHK (8 * 128) /这个Ping中没用到,其他地方有用 ,128个字节static const int MAXWAIT = 10; /最大等10

12、秒static const int PINGINTERVAL = 1;/两次间隔一秒 /* second */#define O_QUIET (1 3 /* identify byte in array */#define B(bit) (1 1) sum += *w+; /这个意思是把前面的长度以2字节位单位加起来,形成和sum,为什么以2字节为单位呢,因为cksum是个2字节大小的校验和 nleft -= 2; if (nleft = 1) *(unsigned char *) (&ans) = *(unsigned char *) w; /如果为奇数时,会多出一个, 把它作为两字节数据的

13、高16-8位,它的8-0位添零后在和原sum相加。这样保证所有长度都加上了 sum += ans; sum = (sum 16) + (sum & 0xFFFF); /然后是取反求得校验和的过程,这是网络上常用的校验过程 sum += (sum 16); ans = sum; return (ans);/* simple version */#ifndef BB_FEATURE_FANCY_PING/分两种情况 ,这种没参数static char *hostname = NULL;static void noresp(int ign)/无返回包输出无值信息 printf(No response

14、 from %sn, hostname); exit(0);static void ping(const char *host)/简单版下的ping程序 struct hostent *h; struct sockaddr_in pingaddr; struct icmp *pkt; int pingsock, c; char packetDEFDATALEN + MAXIPLEN + MAXICMPLEN;/申请空间大小,一个ping包一般最大也只能有那么大了 pingsock = create_icmp_socket();/建立icmp连接 memset(&pingaddr, 0, siz

15、eof(struct sockaddr_in);/初始化pingaddr地址大小sockaddr_in的内存空间 pingaddr.sin_family = AF_INET; h = xgethostbyname(host);/ 得到主机名 memcpy(&pingaddr.sin_addr, h-h_addr, sizeof(pingaddr.sin_addr); /同理 hostname = h-h_name; pkt = (struct icmp *) packet; /创建icmp包 memset(pkt, 0, sizeof(packet); pkt-icmp_type = ICMP

16、_ECHO;/告之所发送的是探测主机类型的icmp即ping pkt-icmp_cksum = in_cksum(unsigned short *) pkt, sizeof(packet); /进行校验和计算后添入发送包 c = sendto(pingsock, packet, sizeof(packet), 0,/发送给想探测的机器 (struct sockaddr *) &pingaddr, sizeof(struct sockaddr_in); if (c 0 | c != sizeof(packet) /可能是网络故障,网线不通? perror_msg_and_die(sendto);

17、 signal(SIGALRM, noresp); /如果超时无响应则退出到noresp,告之机器无响应 alarm(5); /等秒,简单版就一次ping,要不成功,要不失败 /* give the host 5000ms to respond */ /* listen for replies */ while (1) struct sockaddr_in from; size_t fromlen = sizeof(from);/接受机器的返回 if (c = recvfrom(pingsock, packet, sizeof(packet), 0, (struct sockaddr *) &

18、from, &fromlen) = 76) /* ip + icmp */ struct iphdr *iphdr = (struct iphdr *) packet; pkt = (struct icmp *) (packet + (iphdr-ihl 2); /* skip ip hdr */ /跳过ip报头 ihlicmp_type = ICMP_ECHOREPLY)/如果回复是ping应答类型则成功 break; printf(%s is alive!n, hostname);/告诉收到主机返回 return;extern int ping_main(int argc, char *a

19、rgv)/简单的ping main甚至不带除主机名之外任何参数 argc-; argv+; if (argc 1) show_usage(); ping(*argv);/执行ping return EXIT_SUCCESS;/以上是一个简单的ping程序,很简单,只是探测和返回通不通,即没发送什么数据,连时间ttl等都没有显示,它适合比较只需要简单的探测的情况,下面是比较正规的ping#else /* ! BB_FEATURE_FANCY_PING */带参数的版本,就是较正规的/* full(er) version */static char *hostname = NULL; /这些上面都

20、定义了static struct sockaddr_in pingaddr;static int pingsock = -1;static int datalen; /* intentionally uninitialized to work around gcc bug */static long ntransmitted = 0, nreceived = 0, nrepeats = 0, pingcount = 0;/几个常用数据,用来表示丢失数,收到数,发送数,次数等static int myid = 0, options = 0;static unsigned long tmin = ULONG_MAX, tmax = 0, tsum = 0;static char rcvd_tblMAX_DUP_CHK / 8;

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1