11月8日icmp协议下ping命令学习

 ping命令的作用是通过icmp协议来发送数据包,
若ICMP报头为奇数个字节,会剩下最后一字节。把最后一个字节视为一个2字节数据的高
    if( nleft==1)
        {       *(unsigned char *)(&answer)=*(unsigned char *)w;
                sum+=answer;
        }
        sum=(sum>>16)+(sum&0xffff);
        sum+=(sum>>16);
        answer=~sum;
        return answer;
}
"回响请求消息来验证与另一台TCP/IP计算机的IP级连接状态,
进行相关的进程调度。
获取main的进程id,用于设置ICMP的标志符
        pid=getpid();
        printf("PING %s(%s): %d bytes data in ICMP packets.\n",argv[1],
                        inet_ntoa(dest_addr.sin_addr),datalen);
        send_packet();  /*发送所有ICMP报文*/
        recv_packet();  /*接收所有ICMP报文*/
        statistics(SIGALRM); /*进行统计*/
        return 0;
}
回响应答消息的接收情况将和往返过程的次数一起显示出来.
ping命令是用于检测网络连接性 可到达性和名称解析的疑难问题的主要TCP/IP命令.
1.基于icmp的接口函数命令,发送数据使用sendto()函数,接收数据使用recvfrom()函数。
2.把ICMP报头二进制数据以2字节为单位累加起来
        while(nleft>1)
        {       sum+=*w++;
                nleft-=2;
        }
3.设置ICMP报
int pack(int pack_no)
{       int i,packsize;
        struct icmp *icmp;
        struct timeval *tval;
        icmp=(struct icmp*)sendpacket;
        icmp->icmp_type=ICMP_ECHO;
        icmp->icmp_code=0;
        icmp->icmp_cksum=0;
        icmp->icmp_seq=pack_no;
        icmp->icmp_id=pid;
        packsize=8+datalen;
        tval= (struct timeval *)icmp->icmp_data;
        gettimeofday(tval,NULL); 
        icmp->icmp_cksum=cal_chksum( (unsigned short *)icmp,packsize);
        return packsize;
}
sendpacket为要发送的内容,由pack()函数设定,dest_addr是目的地址,

4.接收所有ICMP报文
void recv_packet()
{       int n,fromlen;
        extern int errno;


        signal(SIGALRM,statistics);
        fromlen=sizeof(from);
        while( nreceived<nsend)
        {       
                //alarm()用来设置信号SIGALRM在经过参数seconds指定的秒数后传送给目前的进程 
                alarm(MAX_WAIT_TIME);
                if( (n=recvfrom(sockfd,recvpacket,sizeof(recvpacket),0,
                                (struct sockaddr *)&from,&fromlen)) <0)
                {       if(errno==EINTR)   continue;
                        perror("recvfrom error");
                        continue;
                }
                gettimeofday(&tvrecv,NULL); 
                if(unpack(recvpacket,n)==-1)continue;
                nreceived++;
        }
}
5.求ip报头长度,即ip报头的长度标志乘4,头长度指明头中包含的4字节字的个数。可接受的最小值是5,最大值是15
        iphdrlen=ip->ip_hl<<2;    
        icmp=(struct icmp *)(buf+iphdrlen);  
        len-=iphdrlen;           
        if( len<8)                /*小于ICMP报头长度则不合理*/
        {       printf("ICMP packets\'s length is less than 8\n");
                return -1;
        }
 
 6.判断是主机名还是ip地址
        if( inaddr=inet_addr(argv[1])==INADDR_NONE)
        {       if((host=gethostbyname(argv[1]) )==NULL) 
                {       perror("gethostbyname error");
                        exit(1);
                }
                memcpy( (char *)&dest_addr.sin_addr,host->h_addr,host->h_length);
        }
        else  
                dest_addr.sin_addr.s_addr = inet_addr(argv[1]);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值