最近有个服务需要伪造源IP发送UDP包,于是在网上找到了这段代码在自己的机器上调通了,记录在此。
1 #include <stdio.h>
2 #include <unistd.h>
3 #include <fcntl.h>
4 #include <time.h>
5 #include <sys/types.h>
6 #include <sys/socket.h>
7 #include <sys/time.h>
8 #include <netinet/in.h>
9 #include <arpa/inet.h>
10 #include <string.h>
11 #include<errno.h>
12
13 #define SRC_IP "10.10.10.24"
14 #define SRC_PORT 7894
15 #define DST_IP "10.10.10.25"
16 #define DST_PORT 7894
17
18 typedef struct {
19 unsigned char iphVerLen;
20 unsigned char ipTos;
21 unsigned short ipLength;
22 unsigned short ipIdent;
23 unsigned short ipFlags;
24 unsigned char ipTTL;
25 unsigned char ipProtocol;
26 unsigned short ipChecksum;
27 unsigned int ipSource;
28 unsigned int ipDestination;
29 } IPHeader;
30
31 typedef struct {
32 unsigned short sourcePort;
33 unsigned short destinationPort;
34 unsigned short len;
35 unsigned short checksum;
36 } UDPHeader;
37
38 typedef struct {
39 unsigned int sourceIp;
40 unsigned int destIp;
41 unsigned char filling;
42 unsigned char protocalType;
43 unsigned short UDPLength;
44 } UDPFakeHead;
45
46 unsigned short CheckSum(unsigned short* buf, int size) {
47
48 unsigned long sum=0;
49 while(size > 1) {
50 sum += *buf;
51 buf++;
52 size -= 2;
53 }
54 if(size) {
55 sum += *(char *)buf;
56 }
57 sum = (sum>>16) + (sum&0xffff);
58 sum += sum>>16;
59 return (~sum);
60 }
61
62 int main(int argc, char* argv[])
63 {
64
65 int fd;
66 struct sockaddr_in src_addr;
67 struct sockaddr_in dst_addr;
68 char szMsg[]="Hello, Can you receive my message!";
69 int one = 1;
70 const int *val = &one;
71
72 fd = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
73 if(fd < 0) {
74 printf("create socket fail!\n");
75 return -1;
76 }
77
78 printf("create socket success!\n");
79
80 if(setsockopt(fd, IPPROTO_IP, IP_HDRINCL, val, sizeof(int))) {
81
82 printf("setsockopt fail!\n");
83 return -1;
84
85 } else {
86
87 printf("setsockopt success!\n");
88 }
89
90 //创建并填充IP首部
91 char buf[1024]={0};
92 IPHeader *pIpHead=(IPHeader *)buf;
93 pIpHead->iphVerLen=4<<4| 5;
94 pIpHead->ipLength=htons(sizeof(IPHeader)+sizeof(UDPHeader)+sizeof(szMsg));
95 pIpHead->ipTTL=128;
96 pIpHead->ipProtocol=IPPROTO_UDP;
97 pIpHead->ipSource=inet_addr(SRC_IP);
98 pIpHead->ipDestination=inet_addr(DST_IP);
99 //pIpHead->ipChecksum=CheckSum((unsigned short*)pIpHead,sizeof(IPHeader));//IP 首部的校验和只需要校验IP首部
100
101 //填充UDP首部
102 UDPHeader *pUdpHeader=(UDPHeader *)&buf[sizeof(IPHeader)];
103 pUdpHeader->sourcePort=htons(SRC_PORT);
104 pUdpHeader->destinationPort=htons(DST_PORT);
105 pUdpHeader->len=htons(sizeof(UDPHeader)+sizeof(szMsg));
106 pUdpHeader->checksum=0;
107
108 //填充UDP数据
109 char *pData;
110 pData=&buf[sizeof(IPHeader)+sizeof(UDPHeader)];
111 memcpy(pData,szMsg,sizeof(szMsg));
112
113 //计算UDP校验和
114 UDPFakeHead mUDPFakeHead;
115 mUDPFakeHead.sourceIp=pIpHead->ipSource;
116 mUDPFakeHead.destIp=pIpHead->ipDestination;
117 mUDPFakeHead.filling=0;
118 mUDPFakeHead.protocalType=IPPROTO_UDP;
119 mUDPFakeHead.UDPLength=htons(sizeof(UDPHeader)+sizeof(szMsg));
120
121 //设置szBuffer目的是计算UDP校验和
122 char szBuffer[1024];
123 memcpy(szBuffer,&mUDPFakeHead,sizeof(UDPFakeHead));
124 memcpy(&szBuffer[sizeof(UDPFakeHead)],pUdpHeader,sizeof(UDPHeader));
125 memcpy(&szBuffer[sizeof(UDPFakeHead)+sizeof(UDPHeader)],szMsg,sizeof(szMsg));
126 pUdpHeader->checksum=CheckSum((unsigned short*)szBuffer,sizeof(UDPFakeHead)+sizeof(UDPHeader)+sizeof(szMsg));
127
128 printf("creat packet success!\n");
129
130 memset(&dst_addr, 0, sizeof(dst_addr));
131 dst_addr.sin_family = AF_INET;
132 dst_addr.sin_addr.s_addr = inet_addr(DST_IP);
133 dst_addr.sin_port = htons(DST_PORT);
134
135 int i = 0;
136
137 while (i++ < 5) {
138 int ret=sendto(fd, buf, sizeof(IPHeader)+sizeof(UDPHeader)+sizeof(szMsg), 0, (struct sockaddr*)&dst_addr, sizeof(dst_addr));
139 if (ret == -1){
140 printf("send %ld packet error, errorno:%ld.\n", i, errno);
141 break;
142 } else {
143 printf("send %ld packet success.\n", i);
144 }
145
146 sleep(5);
147 }
148
149 close(fd);
150
151 return 0;
152 }
153