-
Notifications
You must be signed in to change notification settings - Fork 0
/
raw_sender_ipv6.c
271 lines (224 loc) · 6.46 KB
/
raw_sender_ipv6.c
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
#include <sys/socket.h>
#include <errno.h>
#include <sys/types.h>
#include <netinet/ip6.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <netinet/in.h>
#include <time.h>
#include <netinet/udp.h>
#define DEST "::1"
#define IPV6_TLV_DFF 0xEE
#define IPV6_TLV_ROUTERALERT 5
#define NEXT_HOP 9
#define PADN 1
short unsigned sequence_number();
short unsigned number;
int main(void)
{
int j=0, pton_fd;
int i=0;
struct ip6_hbh hbh_hdr;
struct msghdr msg = {};
struct cmsghdr *cmsg;
struct udphdr *udphdr;
int cmsglen;
int tx_len; //used for udp payload
char src_ip[INET6_ADDRSTRLEN], dst_ip[INET6_ADDRSTRLEN];
int s,status;
struct sockaddr_in6 daddr;
char packet[40];
char payload[20];
//uint8_t IP_DFF = 0xEE;
//-----members for ancillary data-----------
struct iovec iov[2];
void *extbuf;
socklen_t extlen;
int currentlen;
void *databuf;
int offset;
uint8_t value;
uint8_t value1;
uint8_t value2;
/* add payload after extension header */
memset(payload,'A', sizeof(payload));
/* point the iphdr to the beginning of the packet */
struct ip6_hdr *ip = (struct ip6_hdr *)packet;
if ((s = socket(AF_INET6, SOCK_RAW, IPPROTO_RAW)) < 0) {
perror("error:");
exit(EXIT_FAILURE);
}
int setsock_offset = 2;
if(setsockopt(s, IPPROTO_IPV6, IPV6_CHECKSUM, &setsock_offset, sizeof(setsock_offset) < 0))
{
perror("setsockopt");
exit(EXIT_FAILURE);
}
daddr.sin6_family = AF_INET6;
daddr.sin6_port = 0; /* not needed in SOCK_RAW */
daddr.sin6_scope_id = if_nametoindex("eth0");
pton_fd = inet_pton(AF_INET6, "fe80::a00:27ff:fe30:9ae9", (struct in6_addr *)&daddr.sin6_addr.s6_addr);
if (pton_fd == 0)
{
printf("Does not contain a character string representing a network address");
exit(EXIT_FAILURE);
}
else if (pton_fd < 0)
{
perror("pton()");
exit(EXIT_FAILURE);
}
ip->ip6_flow = htonl ((6<<28) | (0<<20) | 0);
ip->ip6_plen = htons (28);
ip->ip6_nxt = 0;
ip->ip6_hops = 64;
#if 0
// Define TCP header
udphdr->source = htons(3423);
udphdr->dest = htons(5342);
udphdr->check = 0;
tx_len += sizeof(struct udphdr);
#endif
if ((status = inet_pton(AF_INET6, "fe80::921b:eff:fe03:637d", &(ip->ip6_src))) != 1)
{
fprintf(stderr,"inet_pton() failed.\nError message: %s",strerror(status)); exit(EXIT_FAILURE);
}
if ((status = inet_pton(AF_INET6, "fe80::a00:27ff:fe30:9ae9", &(ip->ip6_dst))) != 1)
{
fprintf(stderr,"inet_pton() failed.\nError message: %s",strerror(status)); exit(EXIT_FAILURE);
}
// Specifying the ancillary data for Hop-by-Hop headers
currentlen = inet6_opt_init(NULL,0);
if (currentlen == -1){
perror("1st opt_init");
exit(EXIT_FAILURE);
}
printf("Hop by Hop length: %d\n", currentlen);
// Setting Hop by Hop extension header next field
//hbh_hdr.ip6h_nxt = 59;
//hbh_hdr.ip6h_len = 0;
currentlen = inet6_opt_append(NULL, 0, currentlen, IPV6_TLV_ROUTERALERT, 2, 1, NULL);
if (currentlen == -1) {
printf("ERROR NO: %d\n",errno);
//perror("1st opt_append");
fprintf(stderr, "append error %s, %s\n",strerror(errno),strerror(currentlen));
exit(EXIT_FAILURE);
}
currentlen = inet6_opt_finish(NULL, 0, currentlen);
if (currentlen == -1) {
perror("1st opt_finish");
exit(EXIT_FAILURE);
}
printf("currentlen: %d\n",currentlen);
extlen = currentlen;
cmsglen = CMSG_SPACE(extlen);
cmsg = malloc(sizeof(cmsglen));
if (cmsg == NULL) {
perror("msg malloc");
exit(EXIT_FAILURE);
}
cmsg->cmsg_len = CMSG_LEN(extlen);
cmsg->cmsg_level = IPPROTO_IPV6;
cmsg->cmsg_type = IPV6_HOPOPTS;
extbuf = CMSG_DATA(cmsg);
extbuf = malloc(extlen);
printf("Size of extbuf: %ld",sizeof(extbuf));
if (extbuf == NULL) {
perror("malloc");
exit(EXIT_FAILURE);
}
printf("Extenlen: %d\n",extlen);
//hbh_hdr.ip6h_nxt = 59;
currentlen = inet6_opt_init(extbuf, extlen);
if (currentlen == -1) {
perror("2nd opt_init");
exit(EXIT_FAILURE);
}
//extbuf = (unsigned char*)extbuf;
//char ip6hop_nexth_value = 59;
*(unsigned char*)(extbuf) = 59;
unsigned char* temp = extbuf;
//for(i=0; i<extlen;i++) {
// printf("Ext buffer is: %d\n",*temp);
// temp++;
//}
currentlen = inet6_opt_append(extbuf, extlen, currentlen, IPV6_TLV_ROUTERALERT, 2, 1, &databuf);
if (currentlen == -1) {
perror("append() error");
exit(EXIT_FAILURE);
}
printf("len after append:%d\n", currentlen);
//insert value for the version and flags
offset = 0;
value = 0x11;
offset = inet6_opt_set_val(databuf, offset, &value, sizeof(value));
//value1 = 0x01;
//printf("Data buffer is: %x\n",databuf);
//offset = inet6_opt_set_val(databuf, offset, &value1, sizeof(value1));
value2 = 0x12;
offset = inet6_opt_set_val(databuf, offset, &value2, sizeof(value2));
currentlen = inet6_opt_finish(extbuf, extlen, currentlen);
if (currentlen == -1)
perror("opt_finish");
//*(uint8_t)(extbuf) = 59;
printf("Data buffer is: %x\n",*(unsigned char*)(databuf));
printf("Extlen is: %d\n",extlen);
printf("Currentlen is: %d\n", currentlen);
unsigned char* temp1 = databuf;
for(j=0; j<3;j++) {
printf("Data buffer is: %d\n",*temp1);
temp1++;
}
for(i=0;i<extlen;i++) {
printf("exbuf is:%d\n",*temp);
temp++;
}
/*
cmsglen = CMSG_SPACE(extlen);
cmsg = malloc(cmsglen);
if (cmsg == NULL) {
perror("msg malloc");
exit(EXIT_FAILURE);
}
cmsg->cmsg_len = CMSG_LEN(extlen);
cmsg->cmsg_level = IPPROTO_IPV6;
cmsg->cmsg_type = IPV6_HOPOPTS;
extbuf = CMSG_DATA(cmsg);
*/
iov[0].iov_base = packet;
iov[0].iov_len = sizeof(packet);
iov[1].iov_base = extbuf;
iov[1].iov_len = sizeof(extbuf);
iov[2].iov_base = payload;
iov[2].iov_len = sizeof(payload);
//iov[2].iov_base = databuf;
//iov[2].iov_len = sizeof(databuf);
msg.msg_control = cmsg;
msg.msg_controllen = cmsglen;
msg.msg_name = (struct sockaddr*)&daddr;
msg.msg_namelen = sizeof(daddr);
msg.msg_iov = &iov;
msg.msg_iovlen = 2;
msg.msg_flags = 0;
while(1) {
sleep(1);
/*if (sendto(s, (char *)packet, sizeof(packet), 0,
(struct sockaddr *)&daddr, (socklen_t)sizeof(daddr)) < 0)
perror("packet send error:");
}*/
if (sendmsg(s, &msg, 2) < 0) {
perror("sendmsg()");
}
else
printf("data sent\n");
}
exit(EXIT_SUCCESS);
}
short unsigned sequence_number()
{
number = rand();
return number;
}