关于ping程序的一点注释Word格式.docx
- 文档编号:22660611
- 上传时间:2023-02-05
- 格式:DOCX
- 页数:17
- 大小:24.35KB
关于ping程序的一点注释Word格式.docx
《关于ping程序的一点注释Word格式.docx》由会员分享,可在线阅读,更多相关《关于ping程序的一点注释Word格式.docx(17页珍藏版)》请在冰豆网上搜索。
/*absminimum*/
//以下是定义icmp结构,通常icmp是通过ip包发送的,所以发送的数据在通常是在外先裹层icmp报头,然后在进入网络层裹上ip报头一起发送的,所以接受时,我们往往要跳过ip报头然后把icmp的东西取出来判断 ,这里对ip报头不分析,仅仅定义libc5需要的icmp结构
//常见的icmp通常由typecodecksum组成报头,然后是根据不同需求需要发送的data字段,其中不同需求由type的代码的不同而对data字段的包含也不同,而ping中通常用的是ICMP_ECHO;
code是代码段,ping中通常为0;
cksum是网络中ip等通常用的校验算法,算法下面解释。
structicmp_ra_addr
{
u_int32_tira_addr;
u_int32_tira_preference;
};
structicmp
u_int8_t
icmp_type;
/*typeofmessage,seebelow*/ //这是type
icmp_code;
/*typesubcode*/
//这是code
u_int16_ticmp_cksum;
/*onescomplementchecksumofstruct*///校验
//注意下面用了union结构,这是因为icmp除了探测主机,即ping外还有其他的功能,根据功能码的不同每次发出去的下面的数据段结构其实是不一样的,在这里我们只需用到structih_idseq 因为这是ping所需要的结构,其他的icmp管理,我们暂时不用管,因为一次只会用到一种数据类型,所以用union定义一个最大的空间
union
//发送的各个data的最大值
u_charih_pptr;
/*ICMP_PARAMPROB*/
structin_addrih_gwaddr;
/*gatewayaddress*/
structih_idseq
/*echodatagram*///echo是我们关心程序发送给主机用来探测的
{
u_int16_ticd_id;
//这个是id
u_int16_ticd_seq;
//这个是seq 就是包的顺序
}ih_idseq;
u_int32_tih_void;
/*ICMP_UNREACH_NEEDFRAG--PathMTUDiscovery(RFC1191)*/
structih_pmtu //这个是关于MTU路径的。
不用
u_int16_tipm_void;
u_int16_tipm_nextmtu;
}ih_pmtu;
structih_rtradv
u_int8_tirt_num_addrs;
u_int8_tirt_wpa;
u_int16_tirt_lifetime;
}ih_rtradv;
}icmp_hun;
#define
icmp_pptr
icmp_hun.ih_pptr //这个就不多说了,为了使用方便的定义
icmp_gwaddr
icmp_hun.ih_gwaddr
icmp_id
icmp_hun.ih_idseq.icd_id
icmp_seq
icmp_hun.ih_idseq.icd_seq
icmp_void
icmp_hun.ih_void
icmp_pmvoid
icmp_hun.ih_pmtu.ipm_void
icmp_nextmtu
icmp_hun.ih_pmtu.ipm_nextmtu
icmp_num_addrs
icmp_hun.ih_rtradv.irt_num_addrs
icmp_wpa
icmp_hun.ih_rtradv.irt_wpa
icmp_lifetime
icmp_hun.ih_rtradv.irt_lifetime
union //这里定义必要的主机回复的Union结构,Ping中需要用的是id_ts;
代表响应时间
struct
u_int32_tits_otime;
u_int32_tits_rtime;
u_int32_tits_ttime;
}id_ts;
structipidi_ip;
/*optionsandthen64bitsofdata*/
}id_ip;
structicmp_ra_addrid_radv;
u_int32_t
id_mask;
u_int8_t
id_data[1];
}icmp_dun;
icmp_otime
icmp_dun.id_ts.its_otime //这个同上
icmp_rtime
icmp_dun.id_ts.its_rtime
icmp_ttime
icmp_dun.id_ts.its_ttime
icmp_ip
icmp_dun.id_ip.idi_ip
icmp_radv
icmp_dun.id_radv
icmp_mask
icmp_dun.id_mask
icmp_data
icmp_dun.id_data
#endif
//这里icmp结构定义结束,好象很复杂,但是在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的最小长度了。
而最大长度则看下面的定义
//公用基本的数据定义
staticconstintDEFDATALEN=56;
//默认报头长度
staticconstintMAXIPLEN=60;
//一个最大ip报头长度
staticconstintMAXICMPLEN=76;
//一个最大icmp报头长度
staticconstintMAXPACKET=65468;
//最大packet,icmp规定最大发送数据data=64k
MAX_DUP_CHK
(8*128)//这个Ping中没用到,其他地方有用,128个字节
staticconstintMAXWAIT=10;
//最大等10秒
staticconstintPINGINTERVAL=1;
//两次间隔一秒
/*second*/
#defineO_QUIET
(1<
<
0)
//退出
//这段是其他管理用到的,ping程序中没起到什么作用
A(bit)
rcvd_tbl[(bit)>
>
3]
/*identifybyteinarray*/
B(bit)
(1<
((bit)&
0x07))
/*identifybitinbyte*/
SET(bit)
(A(bit)|=B(bit))
CLR(bit)
(A(bit)&
=(~B(bit)))
TST(bit)
B(bit))
staticvoidping(constchar*host);
/*commonroutines*/
staticintin_cksum(unsignedshort*buf,intsz) //计算校验和的函数
intnleft=sz;
intsum=0;
unsignedshort*w=buf;
unsignedshortans=0;
while(nleft>
1){
sum+=*w++;
//这个意思是把前面的长度以2字节位单位加起来,形成和sum,为什么以2字节为单位呢,因为cksum是个2字节大小的校验和
nleft-=2;
}
if(nleft==1){
*(unsignedchar*)(&
ans)=*(unsignedchar*)w;
//如果为奇数时,会多出一个,把它作为两字节数据的高16-8位,它的8-0位添零后在和原sum相加。
这样保证所有长度都加上了
sum+=ans;
sum=(sum>
16)+(sum&
0xFFFF);
//然后是取反求得校验和的过程,这是网络上常用的校验过程
sum+=(sum>
16);
ans=~sum;
return(ans);
}
/*simpleversion*/
#ifndefBB_FEATURE_FANCY_PING //分两种情况,这种没参数
staticchar*hostname=NULL;
staticvoidnoresp(intign) //无返回包输出无值信息
printf("
Noresponsefrom%s\n"
hostname);
exit(0);
staticvoidping(constchar*host) //简单版下的ping程序
structhostent*h;
structsockaddr_inpingaddr;
structicmp*pkt;
intpingsock,c;
charpacket[DEFDATALEN+MAXIPLEN+MAXICMPLEN];
//申请空间大小,一个ping包一般最大也只能有那么大了
pingsock=create_icmp_socket();
//建立icmp连接
memset(&
pingaddr,0,sizeof(structsockaddr_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=(structicmp*)packet;
//创建icmp包
memset(pkt,0,sizeof(packet));
pkt->
icmp_type=ICMP_ECHO;
//告之所发送的是探测主机类型的icmp 即ping
icmp_cksum=in_cksum((unsignedshort*)pkt,sizeof(packet));
//进行校验和计算后添入发送包
c=sendto(pingsock,packet,sizeof(packet),0,
//发送给想探测的机器
(structsockaddr*)&
pingaddr,sizeof(structsockaddr_in));
if(c<
0||c!
=sizeof(packet))
//可能是网络故障,网线不通?
perror_msg_and_die("
sendto"
);
signal(SIGALRM,noresp);
//如果超时无响应则退出到noresp,告之机器无响应
alarm(5);
//等5秒,简单版就一次ping,要不成功,要不失败
/*givethehost5000mstorespond*/
/*listenforreplies*/
while
(1){
structsockaddr_infrom;
size_tfromlen=sizeof(from);
//接受机器的返回
if((c=recvfrom(pingsock,packet,sizeof(packet),0,
(structsockaddr*)&
from,&
fromlen))<
0){
if(errno==EINTR)
continue;
perror_msg("
recvfrom"
}
//icmp的最大长度为76,如果大于,主机返回了ip报头,有这种情况
//如果返回ip报头,首先我们要跳过ip报头,然后才能进行icmp的判断,这就需要ihl长度了
if(c>
=76){
/*ip+icmp*/
structiphdr*iphdr=(structiphdr*)packet;
pkt=(structicmp*)(packet+(iphdr->
ihl<
2));
/*skipiphdr*/
//跳过ip报头ihl<
2是因为ihl是以4字节为一个单位来记录IP报头的长度,packet+()则跳过长度
if(pkt->
icmp_type==ICMP_ECHOREPLY)
//如果回复是ping应答类型则成功
break;
%sisalive!
\n"
//告诉收到主机返回
return;
externintping_main(intargc,char**argv) //简单的pingmain甚至不带除主机名之外任何参数
argc--;
argv++;
if(argc<
1)
show_usage();
ping(*argv);
//执行ping
returnEXIT_SUCCESS;
//以上是一个简单的ping程序,很简单,只是探测和返回通不通,即没发送什么数据,连时间ttl等都没有显示,它适合比较只需要简单的探测的情况,下面是比较正规的ping
#else/*!
BB_FEATURE_FANCY_PING*/ //带参数的版本,就是较正规的
/*full(er)version*/
//这些上面都定义了
staticstructsockaddr_inpingaddr;
staticintpingsock=-1;
staticintdatalen;
/*intentionallyuninitializedtoworkaroundgccbug*/
staticlongntransmitted=0,nreceived=0,nrepeats=0,pingcount=0;
//几个常用数据,用来表示丢失数,收到数,发送数,次数等
staticintmyid=0,options=0;
staticunsignedlongtmin=ULONG_MAX,tmax=0,tsum=0;
staticcharrcvd_tbl[MAX_DUP_CHK/8];
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 关于 ping 程序 一点 注释