由于是简单写写,所以要求读者有一定的基础,当然大神不需要看我的文章了,贼,哈哈哈。
首先是头文件需求:
#include <stdio.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <unistd.h>
#include <signal.h>
#include <arpa/inet.h>
#include <errno.h>
#include <sys/time.h>
#include <string.h>
#include <netdb.h>
#include <stdlib.h>
这些必备写上,不然gcc时候会出现没有定义的现象。
然后分析ICMP,ICMP一共有8个字节,不算数据哦,数据另外定义
struct icmp 这些一个icmp结构体,包含了icmp头,具体定义这里就不列出了,自行查阅,
定义两个struct sockaddr_in serveraddr,readdr;IP地址+端口变量,但是ICMP不注重端口,协议以及IP地址即可
唯一难点就应该是校验和算法了吧,不过不难,代码如下:
unsigned short cal_chksum(unsigned short *addr,int len)
{ int nleft=len;
int sum=0;
unsigned short *w=addr;
unsigned short answer=0;
/*把ICMP报头二进制数据以2字节为单位累加起来*/
while(nleft>1)
{
sum+=*w++;
nleft-=2;
}
/*若ICMP报头为奇数个字节,会剩下最后一字节。把最后一个字节视为一个2字节数据的高字节,这个2字节数据的低字节为0,继续累加*/
if( nleft==1)
{
*(unsigned char *)(&answer)=*(unsigned char *)w;
sum+=answer;
}
sum=(sum>>16)+(sum&0xffff);
sum+=(sum>>16);
answer=~sum;
return answer;
}
就是把所有数据相加进位再相加,然后取反。。这个校验有点鸡肋,跟玩的一样
然后就是发送和接受数据了:
sendDatalen = sendto(serversocketfd, sedata, packlen,0, (struct sockaddr *)&serveraddr, sizeof(serveraddr))
recvDataLen = recvfrom(serversocketfd, redata, sizeof(redata), 0, (struct sockaddr *)&readdr,&addr_len))
最后要判断收到的数据
answericmp->icmp_type == ICMP_ECHOREPLY && answericmp->icmp_id == getpid()
记得一定要用 && 网上有些文章用|| 误人子弟。
以上是小可第一篇文章,文本不想写的,但是不想当空军,一起勉励,希望大神指导,谢谢。