我是靠谱客的博主 玩命网络,最近开发中收集的这篇文章主要介绍raw socket 编程实例 raw socket编程实例 ,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

raw socket编程实例

1685人阅读 评论(0) 收藏 举报
分类:
网络编程(5)

由于最经做模拟TCP三次握手的实验,需要用到raw socket编程。

运行第一段代码,发送ip数据报,第二段代码接收ip数据报。需要运行第二段代码,否则将无法接收数据报。

[cpp] view plain copy
  1. <span style="font-size:18px;">#include<stdio.h>  
  2. #include<string.h>  
  3. #include<stdlib.h>  
  4. #include<sys/socket.h>  
  5. #include<sys/types.h>  
  6. #include<netinet/in.h>  
  7.   
  8. struct iphead{   //该结构体模拟IP首部(代码中,控制套接字不添加IP数据包首部,需要自己添加),</span>  
[cpp] view plain copy
  1. <span style="font-size:18px;"><span style="white-space:pre;">       </span>//关于各变量的含义,可对照IP数据报格式,一目了然。  
  2.     unsigned char ip_hl:4, ip_version:4;  //ip_hl,ip_version各占四个bit位。  
  3.     unsigned char ip_tos;  
  4.     unsigned short int ip_len;     
  5.     unsigned short int ip_id;  
  6.     unsigned short int ip_off;    
  7.     unsigned char ip_ttl;  
  8.     unsigned char ip_pro;  
  9.     unsigned short int ip_sum;  
  10.     unsigned int ip_src;  
  11.     unsigned int ip_dst;  
  12. };  
  13.   
  14. struct icmphead{  //</span><span style="font-size:18px;font-family:Arial, Helvetica, sans-serif;">该结构体模拟ICMP报文首部</span><span style="font-size:18px;">  
  15.     unsigned char icmp_type;  
  16.     unsigned char icmp_code;  
  17.     unsigned short int icmp_sum;  
  18.     unsigned short int icmp_id;  
  19.     unsigned short int icmp_seq;  
  20. };  
  21.   
  22. unsigned short int cksum(char buffer[], int size){   //计算校验和,具体的算法可自行百度,或查阅资料  
  23.     unsigned long sum = 0;  
  24.     unsigned short int answer;  
  25.     unsigned short int *temp;  
  26.     temp = (short int *)buffer;  
  27.     for( ; temp<buffer+size; temp+=1){  
  28.         sum += *temp;  
  29.     }  
  30.     sum = (sum >> 16) + (sum & 0xffff);  
  31.     sum += (sum >> 16);  
  32.     answer = ~sum;  
  33.     return answer;  
  34. }  
  35.   
  36. int main(){  
  37.      
  38.     int sockfd;  
  39.     struct sockaddr_in conn;  
  40.     struct iphead *ip;  
  41.     struct icmphead *icmp;  
  42.     unsigned char package[sizeof(struct iphead) + sizeof(struct icmphead)];  //package存储IP数据报的首部和数据  
  43.     memset(package, 0, sizeof(package));  
  44.   
  45.     ip = (struct iphead*)package;  
  46.     icmp = (struct icmphead*)(package+sizeof(struct iphead)); //IP数据报数据字段仅仅包含一个ICMP首部  
  47.     sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); //创建套接字  
  48.     if(sockfd < 0){  
  49.         printf("Create socket failedn");  
  50.         return -1;  
  51.     }  
  52.     conn.sin_family = AF_INET;  
  53.     conn.sin_addr.s_addr = inet_addr("192.168.230.135");  
  54.     int one = 1;  
  55.     if(setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, &one, sizeof(one)) < 0){  //设置套接字行为,此处设置套接字不添加IP首部  
  56.         printf("setsockopt failed!n");  
  57.         return -1;  
  58.     }  
  59.     /*设置IP首部各个字段的值*/    
  60.     ip->ip_version = 4;   
  61.     ip->ip_hl = 5;  
  62.     ip->ip_tos = 0;  
  63.     ip->ip_len = htons(sizeof(struct iphead) + sizeof(struct icmphead)); //关于htons()、htonl()的作用,可自行百度      
  64.     ip->ip_id = htons(1);  
  65.     ip->ip_off = htons(0x4000);  
  66.     ip->ip_ttl = 10;  
  67.     ip->ip_pro = IPPROTO_ICMP;  
  68.     ip->ip_src = htonl(inet_addr("192.168.230.135"));  
  69.     ip->ip_dst = htonl(inet_addr("192.168.230.135"));  
  70.     printf("ipcksum : %dn", cksum(package, 20));   
  71.     ip->ip_sum = cksum(package, 20);  // 计算校验和,应当在其他字段之后设置(实验中发现检验和会被自动添加上)  
  72.       
  73.     /*设置ICMP首部各字段值*/  
  74.     icmp->icmp_type = 8;  
  75.     icmp->icmp_code = 0;  
  76.     icmp->icmp_id = 1;  
  77.     icmp->icmp_seq = 0;  
  78.     icmp->icmp_sum = (cksum(package+20, 8));  
  79.     /*接下来发送IP数据报即可*/  
  80.     if(sendto(sockfd, package, htons(ip->ip_len), 0,(struct sockaddr *)&conn, sizeof(struct sockaddr)) < 0){  
  81.     printf("send failedn");   
  82.     return -1;  
  83.     }  
  84.     printf("send successfuln");      
  85.     return 0;  
  86. }</span>  



[plain] view plain copy
  1. <span style="font-size:18px;">#include<stdio.h>  
  2. #include<string.h>  
  3. #include<stdlib.h>  
  4. #include<sys/socket.h>  
  5. #include<sys/types.h>  
  6. #include<netinet/in.h>  
  7. #include<unistd.h>  
  8. #include<linux/if_ether.h>  
  9.   
  10. unsigned short int cksum(char buffer[], int size){  //校验函数  
  11.     unsigned long sum = 0;  
  12.     unsigned short int answer;  
  13.     unsigned short int *temp;  
  14.     temp = (short int *)buffer;  
  15.     for( ; temp<buffer+size; temp+=1)  
  16.         sum += *temp;  
  17.     sum = (sum >> 16) + (sum & 0xffff);  
  18.     sum += (sum >> 16);  
  19.     answer = ~sum;  
  20.     return answer;  
  21. }  
  22.   
  23. int main(){  
  24.     unsigned char buffer[1024];  
  25.       
  26.   //  int sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);//不知为啥,无法设置原始套接字在网络层抓IP数据报  
  27.     int sockfd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP)); //此处,利用原始套接字在数据链路层抓取MAC帧,去掉  
  28.     if(sockfd < 0){                                            //14个字节的MAC帧首部即可  
  29.         printf("create sock failedn");  
  30.     return -1;  
  31.     }      
  32.     int n = recvfrom(sockfd, buffer, 1024, 0, NULL, NULL); //接收MAC帧  
  33.   
  34.     printf("receive %d bytesn", n);  
  35.     for(int i=14; i<n; i++){      //去掉MAC帧首部,直接输出IP数据报每个字节的数据  
  36.     if((i-14) % 16 == 0)  
  37.         printf("n");  
  38.     printf("%d ",buffer[i]);  
  39.     }  
  40.     printf("n");  
  41.     printf("ipcksum: %dn", cksum(buffer+14, 20)); //此处再次校验时,应当输出0  
  42.     return 0;  
  43. }</span>  

这是之前参考过的一篇文章,写的还可以:http://www.it165.net/pro/html/201208/3450.html


最后

以上就是玩命网络为你收集整理的raw socket 编程实例 raw socket编程实例 的全部内容,希望文章能够帮你解决raw socket 编程实例 raw socket编程实例 所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(36)

评论列表共有 0 条评论

立即
投稿
返回
顶部