1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
| /**
* @file ip_udp_send.c
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
/* ip首部长度 */
#define IP_HEADER_LEN sizeof(struct ip)
/* udp首部长度 */
#define UDP_HEADER_LEN sizeof(struct udphdr)
/* ip首部 + udp首部长度 */
#define IP_UDP_HEADER_LEN IP_HEADER_LEN + UDP_HEADER_LEN
void err_exit(const char *err_msg)
{
perror(err_msg);
exit(1);
}
/* 填充ip首部 */
struct ip *fill_ip_header(const char *src_ip, const char *dst_ip, int ip_packet_len)
{
struct ip *ip_header;
ip_header = (struct ip *)malloc(IP_HEADER_LEN);
ip_header->ip_v = IPVERSION;
ip_header->ip_hl = IP_HEADER_LEN / 4;
ip_header->ip_tos = 0;
ip_header->ip_len = htons(ip_packet_len);
ip_header->ip_id = 0;
ip_header->ip_off = 0;
ip_header->ip_ttl = MAXTTL;
ip_header->ip_p = IPPROTO_UDP; /* 这里是UDP */
ip_header->ip_sum = 0;
ip_header->ip_src.s_addr = inet_addr(src_ip);
ip_header->ip_dst.s_addr = inet_addr(dst_ip);
return ip_header;
}
/* 填充udp首部 */
struct udphdr *fill_udp_header(int src_port, int dst_port, int udp_packet_len)
{
struct udphdr *udp_header;
udp_header = (struct udphdr *)malloc(UDP_HEADER_LEN);
udp_header->source = htons(src_port);
udp_header->dest = htons(dst_port);
/* 这里的长度是整个UDP报文 */
udp_header->len = htons(udp_packet_len);
udp_header->check = 0;
return udp_header;
}
/* 发送ip_udp报文 */
void ip_udp_send(const char *src_ip, int src_port, const char *dst_ip, int dst_port, const char *data)
{
struct ip *ip_header;
struct udphdr *udp_header;
struct sockaddr_in dst_addr;
socklen_t sock_addrlen = sizeof(struct sockaddr_in);
int data_len = strlen(data);
int ip_packet_len = IP_UDP_HEADER_LEN + data_len;
int udp_packet_len = UDP_HEADER_LEN + data_len;
char buf[ip_packet_len];
int sockfd, ret_len, on = 1;
bzero(&dst_addr, sock_addrlen);
dst_addr.sin_family = PF_INET;
dst_addr.sin_addr.s_addr = inet_addr(dst_ip);
dst_addr.sin_port = htons(dst_port);
/* 创建udp原始套接字 */
if ((sockfd = socket(PF_INET, SOCK_RAW, IPPROTO_UDP)) == -1)
err_exit("socket()");
/* 开启IP_HDRINCL,自定义IP首部 */
if (setsockopt(sockfd, IPPROTO_IP, IP_HDRINCL, &on, sizeof(on)) == -1)
err_exit("setsockopt()");
/* ip首部 */
ip_header = fill_ip_header(src_ip, dst_ip, ip_packet_len);
/* udp首部 */
udp_header = fill_udp_header(src_port, dst_port, udp_packet_len);
bzero(buf, ip_packet_len);
memcpy(buf, ip_header, IP_HEADER_LEN);
memcpy(buf + IP_HEADER_LEN, udp_header, UDP_HEADER_LEN);
memcpy(buf + IP_UDP_HEADER_LEN, data, data_len);
/* 发送报文 */
ret_len = sendto(sockfd, buf, ip_packet_len, 0, (struct sockaddr *)&dst_addr, sock_addrlen);
if (ret_len > 0)
printf("sendto() ok!!!\n");
else printf("sendto() failed\n");
close(sockfd);
free(ip_header);
free(udp_header);
}
int main(int argc, const char *argv[])
{
if (argc != 6)
{
printf("usage:%s src_ip src_port dst_ip dst_port data\n", argv[0]);
exit(1);
}
/* 发送ip_udp报文 */
ip_udp_send(argv[1], atoi(argv[2]), argv[3], atoi(argv[4]), argv[5]);
return 0;
}
|