日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

002.ICMP--拼接ICMP包,实现简单Ping程序(原始套接字)

發(fā)布時間:2024/6/21 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 002.ICMP--拼接ICMP包,实现简单Ping程序(原始套接字) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一.大致流程:

??? 將ICMP頭和時間數(shù)據(jù)設置好后,通過創(chuàng)建好的原始套接字socket發(fā)出去。目的主機計算效驗和后會將數(shù)據(jù)原樣返回,用當前時間和返回的數(shù)據(jù)結(jié)算時間差,計算出rtt。

?

二.數(shù)據(jù)結(jié)構(gòu):

ICMP時間戳請求與應答報文格式:

????????????????????????????????????

ICMP頭部數(shù)據(jù)結(jié)構(gòu):

struct icmp //占8字節(jié),在<netinet/ip_icmp.h>頭文件中定義 {u_int8_t icmp_type; //類型u_int8_t icmp_code; //代碼u_int16_t icmp_cksum; //檢驗和u_int16_t icd_id; //標識符u_int16_t icd_seq; //序列號 }

注:對于icmp時間戳請求與應答是這樣的,我將不必要的數(shù)據(jù)定義省略了。

struct timeval時間結(jié)構(gòu)體:

struct timeval //該結(jié)構(gòu)在<time.h>中定義 {__time_t tv_sec; // 秒,實際上為long int類型__suseconds_t tv_usec; // 微秒(百萬分之一秒),實際上為long int類型 };

?

三.說明:

??? 1.我們以ping www.baidu.com為例,但我們并沒有計算平均rtt

??? 2.我們并沒有手動創(chuàng)建IP頭,而是交給了內(nèi)核去幫我們處理

??? 3.中間設計到的函數(shù)需要查相關(guān)資料

?

四.代碼實現(xiàn):

1 /* 2 ============================================================================ 3 Name : myping.c 4 Author : huh 5 Version : 0.01 6 Copyright : Your copyright notice 7 Description : Hello World in C, Ansi-style 8 ============================================================================ 9 */ 10 11 #include <sys/types.h> 12 #include <sys/select.h> 13 #include <stdio.h> 14 #include <time.h> 15 #include <string.h> 16 #include <netdb.h> 17 #include <arpa/inet.h> 18 #include <unistd.h> 19 #include <signal.h> 20 #include <sys/time.h> 21 #include <sys/socket.h> 22 #include <netinet/ip_icmp.h> 23 24 #define PACKET_SIZE 1024*4 25 26 int pid; 27 int sockfd; 28 int datalen = 56; 29 int nsent = 1, nrecv = 1; 30 char sendbuf[PACKET_SIZE]; 31 char recvbuf[PACKET_SIZE]; 32 struct sockaddr_in dest_addr; //socket目的地址 33 struct sockaddr_in src_addr; 34 struct timeval tvrecv; 35 36 void send_packet(); 37 void un_packet(int); 38 void tv_sub(struct timeval *out, struct timeval *in); 39 unsigned short in_chksum(unsigned short *addr, int len); 40 41 int main() 42 { 43 pid = getpid(); 44 char str[20]; 45 unsigned int inaddr; 46 struct hostent *host; 47 int size = 1024 * 25; 48 strcpy(str,"www.baidu.com"); 49 //IP地址(域名)到無符號整數(shù)的轉(zhuǎn)換 50 inaddr = inet_addr(str); 51 if (inaddr == INADDR_NONE) 52 { 53 host = gethostbyname(str); 54 if (host == NULL) 55 { 56 printf("參數(shù)格式不正確,請重新輸入!\n"); 57 return 0; 58 } 59 memcpy((char*) &inaddr, host->h_addr, sizeof(dest_addr.sin_addr)); 60 } 61 //設置套接字地址 62 dest_addr.sin_family = AF_INET; 63 memcpy((char *)&dest_addr.sin_addr, (char *)&inaddr,sizeof(inaddr)); 64 //創(chuàng)建套接字 65 sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); 66 //改變socket緩沖區(qū)大小 67 setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, &size, sizeof(size)); 68 69 printf("PING %s (%s) %d(84) bytes of data.\n",str, inet_ntoa(dest_addr.sin_addr), datalen); 70 //不停的發(fā)送和接受ICMP數(shù)據(jù)包 71 while (1) 72 { 73 send_packet(); 74 int src_addr_len = sizeof(struct sockaddr_in); 75 //接收數(shù)據(jù)包,一直阻塞到有數(shù)據(jù)包到達為止 76 int len = recvfrom(sockfd, recvbuf, sizeof(recvbuf), 0, (struct sockaddr *) &src_addr, (socklen_t *) &src_addr_len); 77 if(len < 0) 78 printf("recvfrom error!\n"); 79 un_packet(len); 80 sleep(1); //間隔一秒,后面會用信號實現(xiàn)每秒發(fā)送一個ICMP包。 81 } 82 return 0; 83 } 84 85 //解包 86 void un_packet(int len) 87 { 88 int hlen1; 89 double rtt; 90 struct ip *ip; 91 struct icmp *icmp; 92 struct timeval *tvsend; 93 94 ip = (struct ip *) recvbuf; 95 hlen1 = ip->ip_hl << 2; 96 if (ip->ip_p != IPPROTO_ICMP) 97 return ; 98 99 icmp = (struct icmp *) (recvbuf + hlen1); 100 len -= hlen1; 101 102 if ((icmp->icmp_type == ICMP_ECHOREPLY)) 103 { 104 if (icmp->icmp_id != pid) 105 return; 106 tvsend = (struct timeval *) icmp->icmp_data; //發(fā)送時間 107 gettimeofday(&tvrecv, NULL); //得到當前時間 108 109 tv_sub(&tvrecv, tvsend); //計算接收和發(fā)送的時間差 110 rtt = tvrecv.tv_sec * 1000.0 + tvrecv.tv_usec / 1000.0; //以毫秒單位計算rtt 111 printf("%d byte from %s: icmp_seq=%u ttl=%d rtt=%.3fms\n", len, inet_ntoa(src_addr.sin_addr), icmp->icmp_seq, ip->ip_ttl, rtt); 112 nrecv++; 113 } 114 } 115 116 //手動構(gòu)建數(shù)據(jù)包,并通過原始套接字發(fā)送 117 void send_packet() 118 { 119 int len; 120 struct icmp *icmp; 121 icmp = (struct icmp *) (sendbuf); 122 icmp->icmp_type = ICMP_ECHO; //拼接icmp 123 icmp->icmp_code = 0; 124 icmp->icmp_id = pid; //2字節(jié) 125 icmp->icmp_seq = nsent++; //2字節(jié) 126 memset(icmp->icmp_data, 0xa5, datalen); 127 gettimeofday((struct timeval *) icmp->icmp_data, NULL); //將發(fā)送時間作為數(shù)據(jù)傳遞過去 128 129 len = datalen + 8; 130 icmp->icmp_cksum = 0; //校驗和需要先置0 131 icmp->icmp_cksum = in_chksum((unsigned short *) icmp, len); //計算效驗和 132 133 sendto(sockfd, sendbuf, len, 0, (struct sockaddr *) &dest_addr, 134 sizeof(dest_addr)); //將包發(fā)出去 135 //printf("package have sent!\n"); 136 } 137 138 //計算效驗和 139 unsigned short in_chksum(unsigned short *addr, int len) 140 { 141 int nleft = len; 142 int sum = 0; 143 unsigned short *w = addr; 144 unsigned short answer = 0; 145 //把ICMP報頭二進制數(shù)據(jù)以2字節(jié)為單位累加起來 146 while (nleft > 1) 147 { 148 sum += *w++; 149 nleft -= 2; 150 } 151 if (nleft == 1) 152 { 153 *(unsigned char *) (&answer) = *(unsigned char *) w; 154 sum += answer; 155 } 156 sum = (sum >> 16) + (sum & 0xffff); 157 sum += (sum >> 16); 158 answer = ~sum; 159 return answer; 160 } 161 162 //計算時間差 163 void tv_sub(struct timeval *out, struct timeval *in) 164 { 165 if ((out->tv_usec -= in->tv_usec) < 0) 166 { 167 --out->tv_sec; 168 out->tv_usec += 1000000; 169 } 170 out->tv_sec -= in->tv_sec; 171 } myping

?

轉(zhuǎn)載于:https://www.cnblogs.com/ruo-yu/p/4978968.html

總結(jié)

以上是生活随笔為你收集整理的002.ICMP--拼接ICMP包,实现简单Ping程序(原始套接字)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 久久99精品国产91久久来源 | 久久这里只有精品国产 | 国产乱码精品一区二区三区五月婷 | 秋霞av鲁丝片一区二区 | 国内一级黄色片 | 日本肉体xxxx裸体137大胆图 | 18日本xxxxxxxxx95| 精品久久久久国产 | 久久麻豆精品 | 美女网站免费观看 | 男人天堂资源 | 免费黄网在线看 | 伊人亚洲天堂 | 国产精品变态另类虐交 | 欧美色图1 | 3d欧美精品动漫xxxx无尽 | 日本一本一道 | 天天色天天干天天 | 蜜桃av一区二区 | 丝袜人妻一区 | av在线资源网 | 在线看成人av | 欧美一区二区免费视频 | 亚洲色图插插插 | 一级国产精品 | 成年人视频免费 | 亚洲男人天堂2024 | 午夜一区二区三区在线 | 午夜肉伦伦 | 亚洲三级电影网站 | 少女情窦初开的第4集在线观看 | 中文在线免费 | 久久久无码精品亚洲无少妇 | 奇米影视一区二区三区 | 国产经典一区二区三区 | 成人av免费网站 | 亚洲黄片一区二区三区 | 无码 人妻 在线 视频 | 91久久久国产精品 | 人人妻人人澡人人爽人人欧美一区 | 国产成人a v | 午夜国产精品视频 | 狠狠插综合 | 精品动漫3d一区二区三区免费版 | 成人国产精品 | 国产精品大片 | 国产淫片av片久久久久久 | 97射射 | 深夜视频在线免费 | 黄色小视频免费在线观看 | 天堂va欧美ⅴa亚洲va一国产 | 亚洲色图第三页 | 国产午夜精品无码 | 国产成人精品123区免费视频 | 欧美一二三四五区 | 漂亮人妻洗澡被公强 日日躁 | 国产精品99久久久 | 一区二区美女视频 | 日韩成人av在线 | av自拍网| 天天谢天天干 | 少妇被又大又粗又爽毛片久久黑人 | 亚洲成a人无码 | 国产无套丰满白嫩对白 | 制服丝袜天堂 | 色七七网站 | 午夜天堂精品 | 久久精品国产99久久久 | 免费的av在线 | a天堂在线视频 | 新婚若妻侵犯中文字幕 | 日韩视频在线观看二区 | 成人免费一区二区三区在线观看 | 理论片中文字幕 | 日本一级淫片1000部 | 丰满尤物白嫩啪啪少妇 | www.av88| www插插插无码免费视频网站 | 国产精品久久久午夜夜伦鲁鲁 | jizzjizz黄大片| 国产精品免费一区二区三区 | 北条麻妃一区二区三区四区五区 | 一级黄色大片免费 | 婷婷综合六月 | 激情导航 | 麻豆视频在线观看 | 日韩1页| 欧美一区二区视频在线 | 国产av无码专区亚洲av | 俄罗斯av在线 | 一区二区视频网 | 内射一区二区三区 | 超级黄色片 | 末路1997全集免费观看完整版 | 狠狠操一区 | 精品福利一区 | 成人在线观看免费高清 | 高清免费视频日本 | 黄色午夜视频 |