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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

raw socket编程实例

發布時間:2024/8/1 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 raw socket编程实例 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

由于最經做模擬TCP三次握手的實驗,需要用到raw socket編程。

運行第一段代碼,發送ip數據報,第二段代碼接收ip數據報。需要運行第二段代碼,否則將無法接收數據報。

#include<stdio.h> #include<string.h> #include<stdlib.h> #include<sys/socket.h> #include<sys/types.h> #include<netinet/in.h>struct iphead{ //該結構體模擬IP首部(代碼中,控制套接字不添加IP數據包首部,需要自己添加), //關于各變量的含義,可對照IP數據報格式,一目了然。unsigned char ip_hl:4, ip_version:4; //ip_hl,ip_version各占四個bit位。unsigned char ip_tos;unsigned short int ip_len; unsigned short int ip_id;unsigned short int ip_off; unsigned char ip_ttl;unsigned char ip_pro;unsigned short int ip_sum;unsigned int ip_src;unsigned int ip_dst; };struct icmphead{ //該結構體模擬ICMP報文首部unsigned char icmp_type;unsigned char icmp_code;unsigned short int icmp_sum;unsigned short int icmp_id;unsigned short int icmp_seq; };unsigned short int cksum(char buffer[], int size){ //計算校驗和,具體的算法可自行百度,或查閱資料unsigned long sum = 0;unsigned short int answer;unsigned short int *temp;temp = (short int *)buffer;for( ; temp<buffer+size; temp+=1){sum += *temp;}sum = (sum >> 16) + (sum & 0xffff);sum += (sum >> 16);answer = ~sum;return answer; }int main(){int sockfd;struct sockaddr_in conn;struct iphead *ip;struct icmphead *icmp;unsigned char package[sizeof(struct iphead) + sizeof(struct icmphead)]; //package存儲IP數據報的首部和數據memset(package, 0, sizeof(package));ip = (struct iphead*)package;icmp = (struct icmphead*)(package+sizeof(struct iphead)); //IP數據報數據字段僅僅包含一個ICMP首部sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); //創建套接字if(sockfd < 0){printf("Create socket failed\n");return -1;}conn.sin_family = AF_INET;conn.sin_addr.s_addr = inet_addr("192.168.230.135");int one = 1;if(setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, &one, sizeof(one)) < 0){ //設置套接字行為,此處設置套接字不添加IP首部printf("setsockopt failed!\n");return -1;}/*設置IP首部各個字段的值*/ ip->ip_version = 4; ip->ip_hl = 5;ip->ip_tos = 0;ip->ip_len = htons(sizeof(struct iphead) + sizeof(struct icmphead)); //關于htons()、htonl()的作用,可自行百度 ip->ip_id = htons(1);ip->ip_off = htons(0x4000);ip->ip_ttl = 10;ip->ip_pro = IPPROTO_ICMP;ip->ip_src = htonl(inet_addr("192.168.230.135"));ip->ip_dst = htonl(inet_addr("192.168.230.135"));printf("ipcksum : %d\n", cksum(package, 20)); ip->ip_sum = cksum(package, 20); // 計算校驗和,應當在其他字段之后設置(實驗中發現檢驗和會被自動添加上)/*設置ICMP首部各字段值*/icmp->icmp_type = 8;icmp->icmp_code = 0;icmp->icmp_id = 1;icmp->icmp_seq = 0;icmp->icmp_sum = (cksum(package+20, 8));/*接下來發送IP數據報即可*/if(sendto(sockfd, package, htons(ip->ip_len), 0,(struct sockaddr *)&conn, sizeof(struct sockaddr)) < 0){printf("send failed\n"); return -1;}printf("send successful\n"); return 0; }


#include<stdio.h> #include<string.h> #include<stdlib.h> #include<sys/socket.h> #include<sys/types.h> #include<netinet/in.h> #include<unistd.h> #include<linux/if_ether.h>unsigned short int cksum(char buffer[], int size){ //校驗函數unsigned long sum = 0;unsigned short int answer;unsigned short int *temp;temp = (short int *)buffer;for( ; temp<buffer+size; temp+=1)sum += *temp;sum = (sum >> 16) + (sum & 0xffff);sum += (sum >> 16);answer = ~sum;return answer; }int main(){unsigned char buffer[1024];// int sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);//不知為啥,無法設置原始套接字在網絡層抓IP數據報int sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP)); //此處,利用原始套接字在數據鏈路層抓取MAC幀,去掉if(sockfd < 0){ //14個字節的MAC幀首部即可printf("create sock failed\n");return -1;} int n = recvfrom(sockfd, buffer, 1024, 0, NULL, NULL); //接收MAC幀printf("receive %d bytes\n", n);for(int i=14; i<n; i++){ //去掉MAC幀首部,直接輸出IP數據報每個字節的數據if((i-14) % 16 == 0)printf("\n");printf("%d ",buffer[i]);}printf("\n");printf("ipcksum: %d\n", cksum(buffer+14, 20)); //此處再次校驗時,應當輸出0return 0; }
這是之前參考過的一篇文章,寫的還可以:http://www.it165.net/pro/html/201208/3450.html


總結

以上是生活随笔為你收集整理的raw socket编程实例的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。