raw socket编程实例
生活随笔
收集整理的這篇文章主要介紹了
raw socket编程实例
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
由于最經做模擬TCP三次握手的實驗,需要用到raw socket編程。
運行第一段代碼,發(fā)送ip數(shù)據(jù)報,第二段代碼接收ip數(shù)據(jù)報。需要運行第二段代碼,否則將無法接收數(shù)據(jù)報。
#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數(shù)據(jù)包首部,需要自己添加), //關于各變量的含義,可對照IP數(shù)據(jù)報格式,一目了然。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數(shù)據(jù)報的首部和數(shù)據(jù)memset(package, 0, sizeof(package));ip = (struct iphead*)package;icmp = (struct icmphead*)(package+sizeof(struct iphead)); //IP數(shù)據(jù)報數(shù)據(jù)字段僅僅包含一個ICMP首部sockfd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP); //創(chuàng)建套接字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); // 計算校驗和,應當在其他字段之后設置(實驗中發(fā)現(xiàn)檢驗和會被自動添加上)/*設置ICMP首部各字段值*/icmp->icmp_type = 8;icmp->icmp_code = 0;icmp->icmp_id = 1;icmp->icmp_seq = 0;icmp->icmp_sum = (cksum(package+20, 8));/*接下來發(fā)送IP數(shù)據(jù)報即可*/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; }
這是之前參考過的一篇文章,寫的還可以:http://www.it165.net/pro/html/201208/3450.html
總結
以上是生活随笔為你收集整理的raw socket编程实例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: C++类库Pugixml与rapidxm
- 下一篇: arm安装jdk