linux icmp 时间戳过滤,ICMP-linux c 时间戳请求功能实现
#include //校驗和計算
unsigned short calc_cksum(char *buff,int len)
{
int blen = len;
unsigned short *mid = (unsigned short*)buff;
unsigned short te = 0;
unsigned int sum = 0;
while(blen > 1)
{
sum += *mid++;
blen -= 2;
}
if(blen == 1)
{
te = *(unsigned char*)mid;
te = (te << 8) & 0xff;
sum += te;
}
sum = (sum >> 16) + (sum&0xffff);
sum += sum >>16;
return (unsigned short)(~sum);
}
static void time_packet(char *buff,int len,int id,int seq)
{
time_t *ti;
struct icmp *icmp = (struct icmp*)buff;
struct timeval val;
icmp->icmp_type = 13; //Timestamp Request
icmp->icmp_code = 0;
icmp->icmp_cksum = 0; //first set zero
icmp->icmp_id = id & 0xffff;
icmp->icmp_seq = seq;
gettimeofday(&val,NULL);
//24*60*60 = 86400 自午夜開始計算的毫秒數(shù)
icmp->icmp_otime = htonl((val.tv_sec % 86400)*1000 + val.tv_usec / 1000);
icmp->icmp_rtime = 0;
icmp->icmp_ttime = 0;
//計算校驗和
icmp->icmp_cksum = calc_cksum(buff,len);
return;
}
void parse_packet(char *buff,int len)
{
struct icmp *icmp;
struct iphdr *iphead = (struct iphdr *)buff;
struct in_addr addr;
addr.s_addr = iphead->saddr;
printf("comefrom ip=%s ",inet_ntoa(addr));
//跳過ip頭
icmp = (struct icmp *)(buff+sizeof(struct iphdr));
//看傳輸回的包校驗和是否正確
if(calc_cksum((char *)icmp,len-sizeof(sizeof(struct iphdr))) > 1)
{
printf("receiver error\n");
return;
}
printf("type=%d seq=%d id=%d pid=%d otime=%d rtime=%d ttime=%d\n",icmp->icmp_type,icmp->icmp_seq,icmp->icmp_id,(getpid()&0xffff),ntohl(icmp->icmp_otime),ntohl(icmp->icmp_rtime),ntohl(icmp->icmp_ttime));
}
int main(int argc,char *argv[])
{
int skfd;
struct sockaddr_in addr={0};
struct sockaddr_in saddr={0};
char buff[64]={0};
char recvbuff[512]={0};
int ret;
int addrlen = 0;
int count = 5;
int i = 1;
skfd = socket(PF_INET,SOCK_RAW,IPPROTO_ICMP);
if(skfd < 0)
{
printf("socket error\n");
return -1;
}
addr.sin_family = AF_INET;
addr.sin_addr.s_addr = inet_addr("192.168.21.244");
//每一秒發(fā)送一次 共發(fā)送count次
while(count > 0)
{
//序列號seq 從1 開始傳輸 buff的大小為64
memset(buff,0,sizeof(buff));
time_packet(buff,64,getpid(),i);
i++;
count --;
//將數(shù)據(jù)發(fā)送出去
ret = sendto(skfd,buff,64,0,(struct sockaddr *)&addr,sizeof(addr));
if(ret <= 0)
{
printf("send error\n");
goto out;
}
else
printf("send success ret=%d\n",ret);
//接收echo replay
memset(recvbuff,0,sizeof(recvbuff));
memset(&saddr,0,sizeof(saddr));
addrlen = sizeof(saddr);
ret = recvfrom(skfd,recvbuff,sizeof(recvbuff),0,(struct sockaddr *)&saddr,&addrlen);
if(ret <= 0)
{
printf("recv error\n");
continue;
}
parse_packet(recvbuff,ret);
sleep(2);
}
out:
close(skfd);
return 0;
}
總結(jié)
以上是生活随笔為你收集整理的linux icmp 时间戳过滤,ICMP-linux c 时间戳请求功能实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: TCP/IP网络编程_第6章基于UDP的
- 下一篇: 【设计模式系列19】状态模式原理分析及其