1 /*
2 * udp6 : A security assessment tool that exploits potential flaws in the
3 * processing of UDP/IPv6 packets
4 *
5 * Copyright (C) 2011-2015 Fernando Gont <fgont@si6networks.com>
6 *
7 * Programmed by Fernando Gont for SI6 Networks <http://www.si6networks.com>
8 *
9 * This program is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation, either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 *
22 * Build with: make udp6
23 *
24 * It requires that the libpcap library be installed on your system.
25 *
26 * Please send any bug reports to Fernando Gont <fgont@si6networks.com>
27 */
28
29 #include <sys/socket.h>
30 #include <sys/types.h>
31 #include <sys/param.h>
32 #include <sys/select.h>
33
34 #include <net/if.h>
35 #include <netinet/in.h>
36 #include <netinet/ip6.h>
37 #include <netinet/icmp6.h>
38 #include <arpa/inet.h>
39
40 #include <pcap.h>
41 #include <stdlib.h>
42 #include <stdio.h>
43 #include <errno.h>
44 #include <time.h>
45 #include <getopt.h>
46 #include <limits.h>
47 #include <unistd.h>
48 #include <signal.h>
49 #include <string.h>
50 #include <setjmp.h>
51 #include <pwd.h>
52
53 #include "udp6.h"
54 #include "ipv6toolkit.h"
55 #include "libipv6.h"
56
57
58 /* Function prototypes */
59 void init_packet_data(struct iface_data *);
60 void send_packet(struct iface_data *, const u_char *, struct pcap_pkthdr *);
61 void print_attack_info(struct iface_data *);
62 void usage(void);
63 void print_help(void);
64 void frag_and_send(struct iface_data *);
65 int is_valid_udp_datagram(struct iface_data *, const u_char *, struct pcap_pkthdr *);
66
67 /* Flags */
68 unsigned char floodt_f=0;
69 unsigned char listen_f=0, accepted_f=0, loop_f=0, sleep_f=0;
70 unsigned char hoplimit_f=0, rand_link_src_f=0, rand_src_f=0;
71 unsigned char floods_f=0, floodp_f=0, donesending_f=0;
72 unsigned char data_f=0, senddata_f=0, useaddrkey_f=0;
73
74 /* Flags used for UDP (specifically) */
75 unsigned char srcport_f=0, dstport_f=0;
76 unsigned char rhbytes_f=0;
77 unsigned char pps_f=0, bps_f=0, probemode_f=0, retrans_f=0, rto_f=0;
78 unsigned int probemode;
79
80 uint16_t srcport, dstport;
81 unsigned int retrans, rto;
82 unsigned int rhbytes, currentsize, packetsize;
83
84
85 /* Used for router discovery */
86 struct iface_data idata;
87
88 /* Data structures for packets read from the wire */
89 struct pcap_pkthdr *pkthdr;
90 const u_char *pktdata;
91 unsigned char *pkt_end;
92 struct ether_header *pkt_ether;
93 struct nd_neighbor_solicit *pkt_ns;
94 struct ip6_hdr *pkt_ipv6;
95 struct udp_hdr *pkt_udp;
96 struct in6_addr *pkt_ipv6addr;
97 unsigned int pktbytes;
98
99
100 bpf_u_int32 my_netmask;
101 bpf_u_int32 my_ip;
102 struct bpf_program pcap_filter;
103 char dev[64], errbuf[PCAP_ERRBUF_SIZE];
104 unsigned char buffer[65556], buffrh[MIN_IPV6_HLEN + MIN_UDP_HLEN];
105 unsigned char *v6buffer, *ptr, *startofprefixes;
106 char *pref;
107 char data[DATA_BUFFER_LEN];
108 unsigned int datalen;
109 char iface[IFACE_LENGTH];
110 char line[LINE_BUFFER_SIZE];
111
112 struct ip6_hdr *ipv6;
113 struct udp_hdr *udp;
114
115 struct ether_header *ethernet;
116 struct nd_opt_tlla *tllaopt;
117
118 struct in6_addr targetaddr, randprefix;
119 struct ether_addr linkaddr[MAX_TLLA_OPTION];
120 unsigned int nlinkaddr=0, linkaddrs;
121
122 char *lasts, *rpref;
123 char *charptr;
124
125 size_t nw;
126 unsigned long ul_res, ul_val, rate;
127 unsigned int i, j, startrand;
128 unsigned int skip;
129 unsigned int sources, nsources, ports, nports, nsleep;
130 unsigned char randpreflen;
131
132 uint16_t mask;
133 uint8_t hoplimit;
134 uint16_t addr_key;
135
136 char plinkaddr[ETHER_ADDR_PLEN];
137 char psrcaddr[INET6_ADDRSTRLEN], pdstaddr[INET6_ADDRSTRLEN], pv6addr[INET6_ADDRSTRLEN];
138
139
140 /* Support for Extension Headers */
141 unsigned int dstopthdrs, dstoptuhdrs, hbhopthdrs;
142 char hbhopthdr_f=0, dstoptuhdr_f=0, dstopthdr_f=0;
143 unsigned char *dstopthdr[MAX_DST_OPT_HDR], *dstoptuhdr[MAX_DST_OPT_U_HDR];
144 unsigned char *hbhopthdr[MAX_HBH_OPT_HDR];
145 unsigned int dstopthdrlen[MAX_DST_OPT_HDR], dstoptuhdrlen[MAX_DST_OPT_U_HDR];
146 unsigned int hbhopthdrlen[MAX_HBH_OPT_HDR], m, pad;
147
148 struct ip6_frag fraghdr, *fh;
149 struct ip6_hdr *fipv6;
150
151 unsigned char fragbuffer[ETHER_HDR_LEN+MIN_IPV6_HLEN+MAX_IPV6_PAYLOAD];
152 unsigned char *fragpart, *fptr, *fptrend, *ptrend, *ptrhdr, *ptrhdrend;
153 unsigned int hdrlen, ndstopthdr=0, nhbhopthdr=0, ndstoptuhdr=0;
154 unsigned int nfrags, fragsize;
155 unsigned char *prev_nh, *startoffragment;
156
157 struct filters filters;
158
main(int argc,char ** argv)159 int main(int argc, char **argv){
160 extern char *optarg;
161 /* char *endptr; Used by strtoul() */
162 fd_set sset, rset;
163 /* fd_set wset, eset; */
164 int r, sel;
165 struct timeval timeout, stimeout, curtime, lastprobe;
166 unsigned char end_f=0;
167 unsigned long pktinterval=0;
168 unsigned int retr=0;
169 struct target_ipv6 targetipv6;
170
171 static struct option longopts[] = {
172 {"interface", required_argument, 0, 'i'},
173 {"src-address", required_argument, 0, 's'},
174 {"dst-address", required_argument, 0, 'd'},
175 {"hop-limit", required_argument, 0, 'A'},
176 {"data", required_argument, 0, 'Z'},
177 {"dst-opt-hdr", required_argument, 0, 'u'},
178 {"dst-opt-u-hdr", required_argument, 0, 'U'},
179 {"hbh-opt-hdr", required_argument, 0, 'H'},
180 {"frag-hdr", required_argument, 0, 'y'},
181 {"link-src-addr", required_argument, 0, 'S'},
182 {"link-dst-addr", required_argument, 0, 'D'},
183 {"payload-size", required_argument, 0, 'P'},
184 {"src-port", required_argument, 0, 'o'},
185 {"dst-port", required_argument, 0, 'a'},
186 {"block-src-addr", required_argument, 0, 'j'},
187 {"block-dst-addr", required_argument, 0, 'k'},
188 {"block-link-src-addr", required_argument, 0, 'J'},
189 {"block-link-dst-addr", required_argument, 0, 'K'},
190 {"accept-src-addr", required_argument, 0, 'b'},
191 {"accept-dst-addr", required_argument, 0, 'g'},
192 {"accept-link-src-addr", required_argument, 0, 'B'},
193 {"accept-link-dst-addr", required_argument, 0, 'G'},
194 {"flood-sources", required_argument, 0, 'F'},
195 {"flood-ports", required_argument, 0, 'T'},
196 {"loop", no_argument, 0, 'l'},
197 {"rate-limit", required_argument, 0, 'r'},
198 {"sleep", required_argument, 0, 'z'},
199 {"listen", no_argument, 0, 'L'},
200 {"probe-mode", required_argument, 0, 'p'},
201 {"retrans", required_argument, 0, 'x'},
202 {"verbose", no_argument, 0, 'v'},
203 {"help", no_argument, 0, 'h'},
204 {0, 0, 0, 0 }
205 };
206
207 char shortopts[]= "i:s:d:A:Z:u:U:H:y:S:D:P:o:a:j:k:J:K:b:g:B:G:F:T:lr:z:Lp:x:vh";
208
209 char option;
210
211 if(argc<=1){
212 usage();
213 exit(EXIT_FAILURE);
214 }
215
216 hoplimit=255;
217 pktinterval= 0;
218 lastprobe.tv_sec= 0;
219 lastprobe.tv_usec= 0;
220
221 /* Initialize filters structure */
222 if(init_filters(&filters) == -1){
223 puts("Error initializing internal data structure");
224 exit(EXIT_FAILURE);
225 }
226
227 if(init_iface_data(&idata) == FAILURE){
228 puts("Error initializing internal data structure");
229 exit(EXIT_FAILURE);
230 }
231
232 while((r=getopt_long(argc, argv, shortopts, longopts, NULL)) != -1) {
233 option= r;
234
235 switch(option){
236 case 'i': /* Interface */
237 strncpy(idata.iface, optarg, IFACE_LENGTH-1);
238 idata.iface[IFACE_LENGTH-1]=0;
239 idata.ifindex= if_nametoindex(idata.iface);
240 idata.iface_f=TRUE;
241 break;
242
243 case 's': /* IPv6 Source Address */
244 if(idata.srcaddr_f){
245 puts("Error: Multiple '-s' options have been specified");
246 exit(EXIT_FAILURE);
247 }
248
249 if((charptr = strtok_r(optarg, "/", &lasts)) == NULL){
250 puts("Error in Source Address");
251 exit(EXIT_FAILURE);
252 }
253
254 if ( inet_pton(AF_INET6, charptr, &(idata.srcaddr)) <= 0){
255 puts("inet_pton(): Source Address not valid");
256 exit(EXIT_FAILURE);
257 }
258
259 idata.srcaddr_f = 1;
260
261 if((charptr = strtok_r(NULL, " ", &lasts)) != NULL){
262 idata.srcpreflen = atoi(charptr);
263
264 if(idata.srcpreflen>128){
265 puts("Prefix length error in IPv6 Source Address");
266 exit(EXIT_FAILURE);
267 }
268
269 if(idata.srcpreflen == 64)
270 useaddrkey_f= 1;
271
272 sanitize_ipv6_prefix(&(idata.srcaddr), idata.srcpreflen);
273 idata.srcprefix_f=1;
274 }
275
276 break;
277
278 case 'd': /* IPv6 Destination Address */
279 strncpy( targetipv6.name, optarg, NI_MAXHOST);
280 targetipv6.name[NI_MAXHOST-1]= 0;
281 targetipv6.flags= AI_CANONNAME;
282
283 if( (r=get_ipv6_target(&targetipv6)) != 0){
284
285 if(r < 0){
286 printf("Unknown Destination: %s\n", gai_strerror(targetipv6.res));
287 }
288 else{
289 puts("Unknown Destination: No IPv6 address found for specified destination");
290 }
291
292 exit(1);
293 }
294
295 idata.dstaddr= targetipv6.ip6;
296 idata.dstaddr_f = 1;
297 break;
298
299 case 'A': /* Hop Limit */
300 hoplimit= atoi(optarg);
301 hoplimit_f=1;
302 break;
303
304 case 'Z': /* Data */
305 datalen= Strnlen(optarg, MAX_CMDLINE_OPT_LEN);
306
307 if(datalen >= DATA_BUFFER_LEN)
308 datalen= DATA_BUFFER_LEN-1;
309
310 strncpy(data, optarg, DATA_BUFFER_LEN-1);
311 data_f=1;
312 break;
313
314 case 'u': /* Destinations Options Header */
315 if(ndstopthdr >= MAX_DST_OPT_HDR){
316 puts("Too many Destination Options Headers");
317 exit(EXIT_FAILURE);
318 }
319
320 hdrlen= atoi(optarg);
321
322 if(hdrlen < 8){
323 puts("Bad length in Destination Options Header");
324 exit(EXIT_FAILURE);
325 }
326
327 hdrlen = ((hdrlen+7)/8) * 8;
328 dstopthdrlen[ndstopthdr]= hdrlen;
329
330 if( (dstopthdr[ndstopthdr]= malloc(hdrlen)) == NULL){
331 puts("Not enough memory for Destination Options Header");
332 exit(EXIT_FAILURE);
333 }
334
335 ptrhdr= dstopthdr[ndstopthdr] + 2;
336 ptrhdrend= dstopthdr[ndstopthdr] + hdrlen;
337
338 while( ptrhdr < ptrhdrend){
339
340 if( (ptrhdrend-ptrhdr)>257)
341 pad= 257;
342 else
343 pad= ptrhdrend-ptrhdr;
344
345 if(!insert_pad_opt(ptrhdr, ptrhdrend, pad)){
346 puts("Destination Options Header Too Big");
347 exit(EXIT_FAILURE);
348 }
349
350 ptrhdr= ptrhdr + pad;
351 }
352
353 *(dstopthdr[ndstopthdr]+1)= (hdrlen/8)-1;
354 ndstopthdr++;
355 dstopthdr_f=1;
356 break;
357
358 case 'U': /* Destination Options Header (Unfragmentable Part) */
359 if(ndstoptuhdr >= MAX_DST_OPT_U_HDR){
360 puts("Too many Destination Options Headers (Unfragmentable Part)");
361 exit(EXIT_FAILURE);
362 }
363
364 hdrlen= atoi(optarg);
365
366 if(hdrlen < 8){
367 puts("Bad length in Destination Options Header (Unfragmentable Part)");
368 exit(EXIT_FAILURE);
369 }
370
371 hdrlen = ((hdrlen+7)/8) * 8;
372 dstoptuhdrlen[ndstoptuhdr]= hdrlen;
373
374 if( (dstoptuhdr[ndstoptuhdr]= malloc(hdrlen)) == NULL){
375 puts("Not enough memory for Destination Options Header (Unfragmentable Part)");
376 exit(EXIT_FAILURE);
377 }
378
379 ptrhdr= dstoptuhdr[ndstoptuhdr]+2;
380 ptrhdrend= dstoptuhdr[ndstoptuhdr] + hdrlen;
381
382 while( ptrhdr < ptrhdrend){
383
384 if( (ptrhdrend-ptrhdr)>257)
385 pad= 257;
386 else
387 pad= ptrhdrend-ptrhdr;
388
389 if(!insert_pad_opt(ptrhdr, ptrhdrend, pad)){
390 puts("Destination Options Header (Unfragmentable Part) Too Big");
391 exit(EXIT_FAILURE);
392 }
393
394 ptrhdr = ptrhdr + pad;
395 }
396
397 *(dstoptuhdr[ndstoptuhdr]+1)= (hdrlen/8) - 1;
398 ndstoptuhdr++;
399 dstoptuhdr_f=1;
400 break;
401
402 case 'H': /* Hop-by-Hop Options Header */
403 if(nhbhopthdr >= MAX_HBH_OPT_HDR){
404 puts("Too many Hop-by-Hop Options Headers");
405 exit(EXIT_FAILURE);
406 }
407
408 hdrlen= atoi(optarg);
409
410 if(hdrlen < 8){
411 puts("Bad length in Hop-by-Hop Options Header");
412 exit(EXIT_FAILURE);
413 }
414
415 hdrlen = ((hdrlen+7)/8) * 8;
416 hbhopthdrlen[nhbhopthdr]= hdrlen;
417
418 if( (hbhopthdr[nhbhopthdr]= malloc(hdrlen)) == NULL){
419 puts("Not enough memory for Hop-by-Hop Options Header");
420 exit(EXIT_FAILURE);
421 }
422
423 ptrhdr= hbhopthdr[nhbhopthdr] + 2;
424 ptrhdrend= hbhopthdr[nhbhopthdr] + hdrlen;
425
426
427 while( ptrhdr < ptrhdrend){
428
429 if( (ptrhdrend-ptrhdr)>257)
430 pad= 257;
431 else
432 pad= ptrhdrend-ptrhdr;
433
434 if(!insert_pad_opt(ptrhdr, ptrhdrend, pad)){
435 puts("Hop-by-Hop Options Header Too Big");
436 exit(EXIT_FAILURE);
437 }
438
439 ptrhdr = ptrhdr + pad;
440 }
441
442 *(hbhopthdr[nhbhopthdr]+1)= (hdrlen/8) - 1;
443 nhbhopthdr++;
444 hbhopthdr_f=1;
445 break;
446
447 case 'y': /* Fragment header */
448 nfrags= atoi(optarg);
449 if(nfrags < 8){
450 puts("Error in Fragmentation option: Fragment Size must be at least 8 bytes");
451 exit(EXIT_FAILURE);
452 }
453
454 nfrags = (nfrags +7) & 0xfff8;
455 idata.fragh_f= 1;
456 break;
457
458 case 'S': /* Source Ethernet address */
459 if(ether_pton(optarg, &(idata.hsrcaddr), sizeof(idata.hsrcaddr)) == 0){
460 puts("Error in Source link-layer address.");
461 exit(EXIT_FAILURE);
462 }
463
464 idata.hsrcaddr_f = 1;
465 break;
466
467 case 'D': /* Destination Ethernet Address */
468 if(ether_pton(optarg, &(idata.hdstaddr), sizeof(idata.hdstaddr)) == 0){
469 puts("Error in Source link-layer address.");
470 exit(EXIT_FAILURE);
471 }
472
473 idata.hdstaddr_f = 1;
474 break;
475
476 case 'P': /* Payload Size*/
477 rhbytes= atoi(optarg);
478 rhbytes_f= 1;
479 break;
480
481 case 'o': /* UDP Source Port */
482 srcport= atoi(optarg);
483 srcport_f= 1;
484 break;
485
486 case 'a': /* UDP Destination Port */
487 dstport= atoi(optarg);
488 dstport_f= 1;
489 break;
490
491 case 'j': /* IPv6 Source Address (block) filter */
492 if(filters.nblocksrc >= MAX_BLOCK_SRC){
493 puts("Too many IPv6 Source Address (block) filters.");
494 exit(EXIT_FAILURE);
495 }
496
497 if((pref = strtok_r(optarg, "/", &lasts)) == NULL){
498 printf("Error in IPv6 Source Address (block) filter number %u.\n", \
499 filters.nblocksrc+1);
500 exit(EXIT_FAILURE);
501 }
502
503 if ( inet_pton(AF_INET6, pref, &(filters.blocksrc[filters.nblocksrc])) <= 0){
504 printf("Error in IPv6 Source Address (block) filter number %u.", \
505 filters.nblocksrc+1);
506 exit(EXIT_FAILURE);
507 }
508
509 if((charptr = strtok_r(NULL, " ", &lasts)) == NULL){
510 filters.blocksrclen[filters.nblocksrc] = 128;
511 }
512 else{
513 filters.blocksrclen[filters.nblocksrc] = atoi(charptr);
514
515 if(filters.blocksrclen[filters.nblocksrc]>128){
516 printf("Length error in IPv6 Source Address (block) filter number %u.\n", \
517 filters.nblocksrc+1);
518 exit(EXIT_FAILURE);
519 }
520 }
521
522 sanitize_ipv6_prefix(&(filters.blocksrc[filters.nblocksrc]), filters.blocksrclen[filters.nblocksrc]);
523 (filters.nblocksrc)++;
524 break;
525
526 case 'k': /* IPv6 Destination Address (block) filter */
527 if(filters.nblockdst >= MAX_BLOCK_DST){
528 puts("Too many IPv6 Destination Address (block) filters.");
529 exit(EXIT_FAILURE);
530 }
531
532 if((pref = strtok_r(optarg, "/", &lasts)) == NULL){
533 printf("Error in IPv6 Destination Address (block) filter number %u.\n", \
534 filters.nblockdst+1);
535 exit(EXIT_FAILURE);
536 }
537
538 if ( inet_pton(AF_INET6, pref, &(filters.blockdst[filters.nblockdst])) <= 0){
539 printf("Error in IPv6 Source Address (block) filter number %u.", \
540 filters.nblockdst+1);
541 exit(EXIT_FAILURE);
542 }
543
544 if((charptr = strtok_r(NULL, " ", &lasts)) == NULL){
545 filters.blockdstlen[filters.nblockdst] = 128;
546 }
547 else{
548 filters.blockdstlen[filters.nblockdst] = atoi(charptr);
549
550 if(filters.blockdstlen[filters.nblockdst]>128){
551 printf("Length error in IPv6 Source Address (block) filter number %u.\n", \
552 filters.nblockdst+1);
553 exit(EXIT_FAILURE);
554 }
555 }
556
557 sanitize_ipv6_prefix(&(filters.blockdst[filters.nblockdst]), filters.blockdstlen[filters.nblockdst]);
558 (filters.nblockdst)++;
559 break;
560
561 case 'J': /* Link Source Address (block) filter */
562 if(filters.nblocklinksrc > MAX_BLOCK_LINK_SRC){
563 puts("Too many link-layer Source Address (accept) filters.");
564 exit(EXIT_FAILURE);
565 }
566
567 if(ether_pton(optarg, &(filters.blocklinksrc[filters.nblocklinksrc]), sizeof(struct ether_addr)) == 0){
568 printf("Error in link-layer Source Address (blick) filter number %u.\n", \
569 filters.nblocklinksrc+1);
570 exit(EXIT_FAILURE);
571 }
572
573 (filters.nblocklinksrc)++;
574 break;
575
576 case 'K': /* Link Destination Address (block) filter */
577 if(filters.nblocklinkdst > MAX_BLOCK_LINK_DST){
578 puts("Too many link-layer Destination Address (block) filters.");
579 exit(EXIT_FAILURE);
580 }
581
582 if(ether_pton(optarg, &(filters.blocklinkdst[filters.nblocklinkdst]), sizeof(struct ether_addr)) == 0){
583 printf("Error in link-layer Destination Address (blick) filter number %u.\n", \
584 filters.nblocklinkdst+1);
585 exit(EXIT_FAILURE);
586 }
587
588 filters.nblocklinkdst++;
589 break;
590
591 case 'b': /* IPv6 Source Address (accept) filter */
592 if(filters.nacceptsrc > MAX_ACCEPT_SRC){
593 puts("Too many IPv6 Source Address (accept) filters.");
594 exit(EXIT_FAILURE);
595 }
596
597 if((pref = strtok_r(optarg, "/", &lasts)) == NULL){
598 printf("Error in IPv6 Source Address (accept) filter number %u.\n", \
599 filters.nacceptsrc+1);
600 exit(EXIT_FAILURE);
601 }
602
603 if ( inet_pton(AF_INET6, pref, &(filters.acceptsrc[filters.nacceptsrc])) <= 0){
604 printf("Error in IPv6 Source Address (accept) filter number %u.\n", \
605 filters.nacceptsrc+1);
606 exit(EXIT_FAILURE);
607 }
608
609 if((charptr = strtok_r(NULL, " ", &lasts)) == NULL){
610 filters.acceptsrclen[filters.nacceptsrc] = 128;
611 }
612 else{
613 filters.acceptsrclen[filters.nacceptsrc] = atoi(charptr);
614
615 if(filters.acceptsrclen[filters.nacceptsrc]>128){
616 printf("Length error in IPv6 Source Address (accept) filter number %u.\n", \
617 filters.nacceptsrc+1);
618 exit(EXIT_FAILURE);
619 }
620 }
621
622 sanitize_ipv6_prefix(&(filters.acceptsrc[filters.nacceptsrc]), filters.acceptsrclen[filters.nacceptsrc]);
623 (filters.nacceptsrc)++;
624 filters.acceptfilters_f=1;
625 break;
626
627
628 case 'g': /* IPv6 Destination Address (accept) filter */
629 if(filters.nacceptdst > MAX_ACCEPT_DST){
630 puts("Too many IPv6 Destination Address (accept) filters.");
631 exit(EXIT_FAILURE);
632 }
633
634 if((pref = strtok_r(optarg, "/", &lasts)) == NULL){
635 printf("Error in IPv6 Destination Address (accept) filter number %u.\n", \
636 filters.nacceptdst+1);
637 exit(EXIT_FAILURE);
638 }
639
640 if ( inet_pton(AF_INET6, pref, &(filters.acceptdst[filters.nacceptdst])) <= 0){
641 printf("Error in IPv6 Source Address (accept) filter number %u.\n", \
642 filters.nacceptdst+1);
643 exit(EXIT_FAILURE);
644 }
645
646 if((charptr = strtok_r(NULL, " ", &lasts)) == NULL){
647 filters.acceptdstlen[filters.nacceptdst] = 128;
648 }
649 else{
650 filters.acceptdstlen[filters.nacceptdst] = atoi(charptr);
651
652 if(filters.acceptdstlen[filters.nacceptdst] > 128){
653 printf("Length error in IPv6 Source Address (accept) filter number %u.\n", \
654 filters.nacceptdst+1);
655 exit(EXIT_FAILURE);
656 }
657 }
658
659 sanitize_ipv6_prefix(&(filters.acceptdst[filters.nacceptdst]), filters.acceptdstlen[filters.nacceptdst]);
660 (filters.nacceptdst)++;
661 filters.acceptfilters_f=1;
662 break;
663
664 case 'B': /* Link-layer Source Address (accept) filter */
665 if(filters.nacceptlinksrc > MAX_ACCEPT_LINK_SRC){
666 puts("Too many link-later Source Address (accept) filters.");
667 exit(EXIT_FAILURE);
668 }
669
670 if(ether_pton(optarg, &(filters.acceptlinksrc[filters.nacceptlinksrc]), sizeof(struct ether_addr)) == 0){
671 printf("Error in link-layer Source Address (accept) filter number %u.\n", \
672 filters.nacceptlinksrc+1);
673 exit(EXIT_FAILURE);
674 }
675
676 (filters.nacceptlinksrc)++;
677 filters.acceptfilters_f=1;
678 break;
679
680 case 'G': /* Link Destination Address (accept) filter */
681 if(filters.nacceptlinkdst > MAX_ACCEPT_LINK_DST){
682 puts("Too many link-layer Destination Address (accept) filters.");
683 exit(EXIT_FAILURE);
684 }
685
686 if(ether_pton(optarg, &(filters.acceptlinkdst[filters.nacceptlinkdst]), sizeof(struct ether_addr)) == 0){
687 printf("Error in link-layer Destination Address (accept) filter number %u.\n",\
688 filters.nacceptlinkdst+1);
689 exit(EXIT_FAILURE);
690 }
691
692 (filters.nacceptlinkdst)++;
693 filters.acceptfilters_f=1;
694 break;
695
696 case 'F': /* Flood source addresses */
697 nsources= atoi(optarg);
698 if(nsources == 0){
699 puts("Invalid number of source addresses in option -F");
700 exit(EXIT_FAILURE);
701 }
702
703 floods_f= 1;
704 break;
705
706 case 'T': /* Flood source ports */
707 nports= atoi(optarg);
708
709 if(nports == 0){
710 puts("Invalid number of source ports in option -T");
711 exit(EXIT_FAILURE);
712 }
713
714 floodp_f= 1;
715 break;
716
717 case 'f':
718 rand_src_f=1;
719 break;
720
721 case 'R':
722 rand_link_src_f=1;
723 break;
724
725 case 'l': /* "Loop mode */
726 loop_f = 1;
727 break;
728
729 case 'r':
730 if( Strnlen(optarg, LINE_BUFFER_SIZE-1) >= (LINE_BUFFER_SIZE-1)){
731 puts("udp6: -r option is too long");
732 exit(EXIT_FAILURE);
733 }
734
735 sscanf(optarg, "%lu%s", &rate, line);
736 line[LINE_BUFFER_SIZE-1]=0;
737
738 if(strncmp(line, "pps", 3) == 0)
739 pps_f=1;
740 else if(strncmp(line, "bps", 3) == 0)
741 bps_f=1;
742 else{
743 puts("udp6: Unknown unit of for the rate limit ('-r' option). Unit should be 'bps' or 'pps'");
744 exit(EXIT_FAILURE);
745 }
746
747 break;
748
749
750 case 'z': /* Sleep option */
751 nsleep=atoi(optarg);
752 if(nsleep==0){
753 puts("Invalid number of seconds in '-z' option");
754 exit(EXIT_FAILURE);
755 }
756
757 sleep_f=1;
758 break;
759
760 case 'L': /* "Listen mode */
761 listen_f = 1;
762 break;
763
764 case 'p': /* Probe mode */
765 if(strncmp(optarg, "dump", MAX_CMDLINE_OPT_LEN) == 0){
766 probemode= PROBE_DUMP;
767 }
768 else if(strncmp(optarg, "script", MAX_CMDLINE_OPT_LEN) == 0){
769 probemode= PROBE_SCRIPT;
770 }
771 else{
772 puts("Error: Unknown open mode in '-Y' option");
773 exit(EXIT_FAILURE);
774 }
775
776 probemode_f=1;
777 break;
778
779 case 'x': /* Number of retrnasmissions */
780 retrans= atoi(optarg);
781 retrans_f=1;
782 break;
783
784 case 'v': /* Be verbose */
785 (idata.verbose_f)++;
786 break;
787
788 case 'h': /* Help */
789 print_help();
790 exit(EXIT_FAILURE);
791 break;
792
793 default:
794 usage();
795 exit(EXIT_FAILURE);
796 break;
797
798 } /* switch */
799 } /* while(getopt) */
800
801 if(geteuid()) {
802 puts("udp6 needs root privileges to run.");
803 exit(EXIT_FAILURE);
804 }
805
806 srandom(time(NULL));
807
808 /*
809 If the flood option ("-F") has been specified, but no prefix has been specified,
810 assume a /64 prefix.
811 */
812 if(floods_f && !idata.srcprefix_f){
813 idata.srcpreflen=64;
814 }
815
816 if(idata.srcprefix_f && !floods_f && loop_f){
817 floods_f=1;
818 nsources= 1;
819 }
820
821 if(!(idata.dstaddr_f) && !listen_f){ /* Must specify IPv6 Destination Address if listening mode not used */
822 puts("IPv6 Destination Address not specified (and listening mode not selected)");
823 exit(EXIT_FAILURE);
824 }
825
826 if(rhbytes_f && data_f){
827 puts("Cannot set '--data' and '--payload-size' at the same time");
828 exit(EXIT_FAILURE);
829 }
830
831 if(!idata.iface_f){
832 if(idata.dstaddr_f && IN6_IS_ADDR_LINKLOCAL(&(idata.dstaddr))){
833 puts("Must specify a network interface for link-local destinations");
834 exit(EXIT_FAILURE);
835 }
836 else if(listen_f){
837 puts("Must specify a network interface when employing the 'listenging' mode");
838 exit(EXIT_FAILURE);
839 }
840 }
841
842 if(load_dst_and_pcap(&idata, (idata.dstaddr_f?LOAD_SRC_NXT_HOP:LOAD_PCAP_ONLY)) == FAILURE){
843 puts("Error while learning Souce Address and Next Hop");
844 exit(EXIT_FAILURE);
845 }
846
847 release_privileges();
848
849 if(data_f){
850 data[datalen]=0;
851
852 if(!string_escapes(data, &datalen, DATA_BUFFER_LEN-1)){
853 puts("Error in data string option ('-Z')");
854 exit(EXIT_FAILURE);
855 }
856
857 data[datalen]=0;
858 }
859
860 if(!floods_f)
861 nsources=1;
862
863 if(!floodp_f)
864 nports=1;
865
866 if(!sleep_f)
867 nsleep=1;
868
869 if(sleep_f && (pps_f || bps_f)){
870 puts("Cannot specify a rate-limit (-r) and a sleep time at the same time");
871 exit(EXIT_FAILURE);
872 }
873
874 if(pps_f && bps_f){
875 puts("Cannot specify a rate-limit in bps and pps at the same time");
876 exit(EXIT_FAILURE);
877 }
878
879 if(pps_f){
880 if(rate < 1)
881 rate=1;
882
883 pktinterval= 1000000/rate;
884 }
885
886 if(bps_f){
887 packetsize= MIN_IPV6_HLEN + sizeof(struct udp_hdr) + rhbytes;
888
889 for(i=0; i < ndstopthdr; i++)
890 packetsize+= dstopthdrlen[i];
891
892 for(i=0; i < ndstoptuhdr; i++)
893 packetsize+= dstoptuhdrlen[i];
894
895 for(i=0; i < nhbhopthdr; i++)
896 packetsize+= hbhopthdrlen[i];
897
898 if(idata.fragh_f)
899 packetsize+= sizeof(struct ip6_frag);
900
901 if(rate == 0 || ((packetsize * 8)/rate) <= 0)
902 pktinterval= 1000000;
903 else
904 pktinterval= ((packetsize * 8)/rate) * 1000000;
905 }
906
907 /* We Default to 1000 pps */
908 if(!pps_f && !bps_f)
909 pktinterval= 1000;
910
911 if( !idata.fragh_f && dstoptuhdr_f){
912 puts("Dst. Options Header (Unfragmentable Part) set, but Fragmentation not specified");
913 exit(EXIT_FAILURE);
914 }
915
916 /*
917 * If we are going to send packets to a specified target, we must set some default values
918 */
919 if(idata.dstaddr_f){
920 if(!srcport_f)
921 srcport= random();
922
923 if(!dstport_f)
924 dstport= random();
925 }
926
927 if(!rhbytes_f)
928 rhbytes=0;
929
930 if(idata.verbose_f){
931 print_attack_info(&idata);
932 }
933
934 /*
935 Set filter for IPv6 packets (find_ipv6_router() set its own filter fore receiving RAs)
936 */
937 if(pcap_compile(idata.pfd, &pcap_filter, PCAP_UDPIPV6_NS_FILTER, PCAP_OPT, PCAP_NETMASK_UNKNOWN) == -1){
938 printf("pcap_compile(): %s", pcap_geterr(idata.pfd));
939 exit(EXIT_FAILURE);
940 }
941
942 if(pcap_setfilter(idata.pfd, &pcap_filter) == -1){
943 printf("pcap_setfilter(): %s", pcap_geterr(idata.pfd));
944 exit(EXIT_FAILURE);
945 }
946
947 pcap_freecode(&pcap_filter);
948
949 /* Set initial contents of the attack packet */
950 init_packet_data(&idata);
951 addr_key= random();
952
953 if(sleep_f)
954 pktinterval= (nsleep * 1000000)/(nsources * nports);
955
956 timeout.tv_sec= pktinterval / 1000000 ;
957 timeout.tv_usec= pktinterval % 1000000;
958 stimeout= timeout;
959
960 if(probemode_f){
961 end_f=0;
962
963 if(!dstport_f)
964 dstport= 80;
965
966 if(!srcport_f)
967 srcport= 50000 + random() % 15000; /* We select ports from the "high ports" range */
968
969 if(!rto_f)
970 rto=1;
971
972 if(!retrans_f)
973 retrans=0;
974
975 retr=0;
976 retrans++;
977
978 FD_ZERO(&sset);
979 FD_SET(idata.fd, &sset);
980
981 lastprobe.tv_sec= 0;
982 lastprobe.tv_usec=0;
983
984 while(!end_f){
985 if(gettimeofday(&curtime, NULL) == -1){
986 if(idata.verbose_f)
987 perror("udp6");
988
989 exit(EXIT_FAILURE);
990 }
991
992 if(is_time_elapsed(&curtime, &lastprobe, rto * 1000000) && retr < retrans){
993 retr++;
994 lastprobe= curtime;
995 send_packet(&idata, NULL, NULL);
996 }
997
998 if(is_time_elapsed(&curtime, &lastprobe, rto * 1000000) && retr >= retrans){
999 end_f=1;
1000 break;
1001 }
1002
1003 rset= sset;
1004 timeout.tv_usec=0;
1005 timeout.tv_sec= (rto < 1)?rto:1;
1006
1007 if((sel=select(idata.fd+1, &rset, NULL, NULL, &timeout)) == -1){
1008 if(errno == EINTR){
1009 continue;
1010 }
1011 else{
1012 puts("Error in select()");
1013 exit(EXIT_FAILURE);
1014 }
1015 }
1016
1017 #if !defined(sun) && !defined(__sun) && !defined(__linux__)
1018 if(sel && FD_ISSET(idata.fd, &rset)){
1019 #else
1020 if(TRUE){
1021 #endif
1022 /* Read a packet */
1023
1024 if((r=pcap_next_ex(idata.pfd, &pkthdr, &pktdata)) == -1){
1025 printf("pcap_next_ex(): %s", pcap_geterr(idata.pfd));
1026 exit(EXIT_FAILURE);
1027 }
1028 else if(r == 1 && pktdata != NULL){
1029 pkt_ether = (struct ether_header *) pktdata;
1030 pkt_ipv6 = (struct ip6_hdr *)((char *) pkt_ether + idata.linkhsize);
1031 pkt_udp= (struct udp_hdr *) ( (char *) pkt_ipv6 + MIN_IPV6_HLEN);
1032 pkt_ns= (struct nd_neighbor_solicit *) ( (char *) pkt_ipv6 + MIN_IPV6_HLEN);
1033 pkt_end = (unsigned char *) pktdata + pkthdr->caplen;
1034
1035 /* Some preliminar sanity checks. */
1036 /* XXX: Might need/could remove some of the checks below */
1037 if(!is_valid_udp_datagram(&idata, pktdata, pkthdr))
1038 continue;
1039
1040 /* Check that we are able to look into the IPv6 header */
1041 if( (pkt_end - pktdata) < (idata.linkhsize + MIN_IPV6_HLEN))
1042 continue;
1043
1044 if(is_eq_in6_addr(&(pkt_ipv6->ip6_src), &(idata.srcaddr))){
1045 continue;
1046 }
1047
1048 if(!is_eq_in6_addr(&(pkt_ipv6->ip6_dst), &(idata.srcaddr))){
1049 continue;
1050 }
1051
1052 if(pkt_udp->uh_sport != htons(dstport)){
1053 continue;
1054 }
1055
1056 if(pkt_udp->uh_dport != htons(srcport)){
1057 continue;
1058 }
1059
1060 /* The UDP checksum must be valid */
1061 if(in_chksum(pkt_ipv6, pkt_udp, pkt_end-((unsigned char *)pkt_udp), IPPROTO_UDP) != 0)
1062 continue;
1063
1064 printf("RESPONSE:UDP6\n");
1065 exit(EXIT_SUCCESS);
1066 }
1067 }
1068 }
1069
1070 puts("RESPONSE:TIMEOUT:");
1071 exit(EXIT_SUCCESS);
1072 }
1073
1074
1075 /* Fire a UDP packet if an IPv6 Destination Address was specified */
1076 if(!listen_f && idata.dstaddr_f){
1077 if(loop_f){
1078 if(idata.verbose_f)
1079 printf("Sending UDP datagrams every %u second%s...\n", nsleep, \
1080 ((nsleep>1)?"s":""));
1081 }
1082
1083 do{
1084 send_packet(&idata, NULL, NULL);
1085
1086 if(loop_f && (sel=select(0, NULL, NULL, NULL, &timeout)) == -1){
1087 if(errno == EINTR){
1088 continue;
1089 }
1090 else{
1091 puts("Error in select()");
1092 exit(EXIT_FAILURE);
1093 }
1094 }
1095 }while(loop_f);
1096
1097 if(idata.verbose_f)
1098 puts("Initial attack packet(s) sent successfully.");
1099
1100 exit(EXIT_SUCCESS);
1101 }
1102 else if(listen_f){
1103 FD_ZERO(&sset);
1104 FD_SET(idata.fd, &sset);
1105
1106 if(idata.verbose_f){
1107 print_filters(&idata, &filters);
1108 puts("Listening to incoming UDP datagrams...");
1109 }
1110
1111 while(listen_f){
1112 rset= sset;
1113
1114 timeout= stimeout;
1115
1116 /* XXX: need to address the select() thing */
1117 #if !defined(sun) && !defined(__sun) && !defined(__linux__)
1118 if((sel=select(idata.fd+1, &rset, NULL, NULL, ((floods_f || floodp_f) && !donesending_f)?(&timeout):NULL)) == -1){
1119 #else
1120 timeout.tv_usec=10000;
1121 timeout.tv_sec= 0;
1122 if((sel=select(idata.fd+1, &rset, NULL, NULL, &timeout)) == -1){
1123 #endif
1124 if(errno == EINTR){
1125 continue;
1126 }
1127 else{
1128 puts("Error in select()");
1129 exit(EXIT_FAILURE);
1130 }
1131 }
1132
1133 /* If there are some bits set, we need to check whether it's time to send packets */
1134 #if !defined(sun) && !defined(__sun) && !defined(__linux__)
1135 if(sel){
1136 #else
1137 if(TRUE){
1138 #endif
1139 if(gettimeofday(&curtime, NULL) == -1){
1140 if(idata.verbose_f)
1141 perror("udp6");
1142
1143 exit(EXIT_FAILURE);
1144 }
1145 }
1146
1147 #if !defined(sun) && !defined(__sun) && !defined(__linux__)
1148 if(sel && FD_ISSET(idata.fd, &rset)){
1149 #else
1150 if(TRUE){
1151 #endif
1152 /* Read a packet */
1153 if((r=pcap_next_ex(idata.pfd, &pkthdr, &pktdata)) == -1){
1154 printf("pcap_next_ex(): %s", pcap_geterr(idata.pfd));
1155 exit(EXIT_FAILURE);
1156 }
1157 else if(r == 1 && pktdata != NULL){
1158 pkt_ether = (struct ether_header *) pktdata;
1159 pkt_ipv6 = (struct ip6_hdr *)((char *) pkt_ether + idata.linkhsize);
1160 pkt_udp= (struct udp_hdr *) ( (char *) pkt_ipv6 + MIN_IPV6_HLEN);
1161 pkt_ns= (struct nd_neighbor_solicit *) ( (char *) pkt_ipv6 + MIN_IPV6_HLEN);
1162 pkt_end = (unsigned char *) pktdata + pkthdr->caplen;
1163
1164 /* Check that we are able to look into the IPv6 header */
1165 if( (pkt_end - pktdata) < (idata.linkhsize + MIN_IPV6_HLEN))
1166 continue;
1167
1168 accepted_f=0;
1169
1170 if(idata.type == DLT_EN10MB && !(idata.flags & IFACE_LOOPBACK)){
1171 if(filters.nblocklinksrc){
1172 if(match_ether(filters.blocklinksrc, filters.nblocklinksrc, &(pkt_ether->src))){
1173 if(idata.verbose_f>1)
1174 print_filter_result(&idata, pktdata, BLOCKED);
1175
1176 continue;
1177 }
1178 }
1179
1180 if(filters.nblocklinkdst){
1181 if(match_ether(filters.blocklinkdst, filters.nblocklinkdst, &(pkt_ether->dst))){
1182 if(idata.verbose_f>1)
1183 print_filter_result(&idata, pktdata, BLOCKED);
1184
1185 continue;
1186 }
1187 }
1188 }
1189
1190 if(filters.nblocksrc){
1191 if(match_ipv6(filters.blocksrc, filters.blocksrclen, filters.nblocksrc, &(pkt_ipv6->ip6_src))){
1192 if(idata.verbose_f>1)
1193 print_filter_result(&idata, pktdata, BLOCKED);
1194
1195 continue;
1196 }
1197 }
1198
1199 if(filters.nblockdst){
1200 if(match_ipv6(filters.blockdst, filters.blockdstlen, filters.nblockdst, &(pkt_ipv6->ip6_dst))){
1201 if(idata.verbose_f>1)
1202 print_filter_result(&idata, pktdata, BLOCKED);
1203
1204 continue;
1205 }
1206 }
1207
1208 if(idata.type == DLT_EN10MB && !(idata.flags & IFACE_LOOPBACK)){
1209 if(filters.nacceptlinksrc){
1210 if(match_ether(filters.acceptlinksrc, filters.nacceptlinksrc, &(pkt_ether->src)))
1211 accepted_f=1;
1212 }
1213
1214 if(filters.nacceptlinkdst && !accepted_f){
1215 if(match_ether(filters.acceptlinkdst, filters.nacceptlinkdst, &(pkt_ether->dst)))
1216 accepted_f= 1;
1217 }
1218 }
1219
1220 if(filters.nacceptsrc && !accepted_f){
1221 if(match_ipv6(filters.acceptsrc, filters.acceptsrclen, filters.nacceptsrc, &(pkt_ipv6->ip6_src)))
1222 accepted_f= 1;
1223 }
1224
1225 if(filters.nacceptdst && !accepted_f){
1226 if(match_ipv6(filters.acceptdst, filters.acceptdstlen, filters.nacceptdst, &(pkt_ipv6->ip6_dst)))
1227 accepted_f=1;
1228 }
1229
1230 if(filters.acceptfilters_f && !accepted_f){
1231 if(idata.verbose_f>1)
1232 print_filter_result(&idata, pktdata, BLOCKED);
1233
1234 continue;
1235 }
1236
1237 if(idata.verbose_f>1)
1238 print_filter_result(&idata, pktdata, ACCEPTED);
1239
1240 if(pkt_ipv6->ip6_nxt == IPPROTO_UDP){
1241 /* Some preliminar sanity checks. */
1242 /* XXX: Might need/could remove some of the checks below */
1243 if(!is_valid_udp_datagram(&idata, pktdata, pkthdr))
1244 continue;
1245
1246 /* Check that we are able to look into the UDP header */
1247 if( (pkt_end - pktdata) < (idata.linkhsize + MIN_IPV6_HLEN + sizeof(struct udp_hdr))){
1248 continue;
1249 }
1250
1251 if(idata.dstaddr_f){
1252 if(!floods_f){
1253 /* Discard our own packets */
1254 if(is_eq_in6_addr(&(pkt_ipv6->ip6_src), &(idata.srcaddr))){
1255 continue;
1256 }
1257
1258 if(!is_eq_in6_addr(&(pkt_ipv6->ip6_dst), &(idata.srcaddr))){
1259 continue;
1260 }
1261 }
1262 else{
1263 /* Discard our own packets */
1264 if(!is_eq_in6_addr(&(pkt_ipv6->ip6_src), &(idata.dstaddr))){
1265 continue;
1266 }
1267
1268 if(useaddrkey_f){
1269 if( (ntohl(pkt_ipv6->ip6_src.s6_addr32[2]) & 0x0000ffff) == ( (uint16_t)(ntohl(pkt_ipv6->ip6_src.s6_addr32[2])>>16) ^ addr_key) && \
1270 (ntohl(pkt_ipv6->ip6_src.s6_addr32[3]) & 0x0000ffff) == ( (uint16_t)(ntohl(pkt_ipv6->ip6_src.s6_addr32[3])>>16) ^ addr_key)){
1271 continue;
1272 }
1273
1274 if( (ntohl(pkt_ipv6->ip6_dst.s6_addr32[2]) & 0x0000ffff) != ((uint16_t)(ntohl(pkt_ipv6->ip6_dst.s6_addr32[2]) >> 16) ^ addr_key) || \
1275 (ntohl(pkt_ipv6->ip6_dst.s6_addr32[3]) & 0x0000ffff) != ((uint16_t)(ntohl(pkt_ipv6->ip6_dst.s6_addr32[3])>>16) ^ addr_key)){
1276 continue;
1277 }
1278 }
1279 }
1280
1281 /* The UDP checksum must be valid */
1282 if(in_chksum(pkt_ipv6, pkt_udp, pkt_end-((unsigned char *)pkt_udp), IPPROTO_UDP) != 0)
1283 continue;
1284
1285 if(pkt_udp->uh_sport != htons(dstport)){
1286 continue;
1287 }
1288
1289 if(!floodp_f && pkt_udp->uh_dport != htons(srcport)){
1290 continue;
1291 }
1292 }
1293
1294 /* Send a UDP datagram */
1295 send_packet(&idata, pktdata, pkthdr);
1296 }
1297 else if(pkt_ipv6->ip6_nxt == IPPROTO_ICMPV6){
1298
1299 /* Check that we are able to look into the NS header */
1300 if( (pkt_end - pktdata) < (idata.linkhsize + MIN_IPV6_HLEN + sizeof(struct nd_neighbor_solicit))){
1301 continue;
1302 }
1303
1304 if(idata.type == DLT_EN10MB && !(idata.flags & IFACE_LOOPBACK)){
1305 if(floods_f){
1306 if(useaddrkey_f){
1307 if( (ntohl(pkt_ns->nd_ns_target.s6_addr32[2]) & 0x0000ffff) != ( (ntohl(pkt_ns->nd_ns_target.s6_addr32[2]) >>16) ^ addr_key) || \
1308 (ntohl(pkt_ns->nd_ns_target.s6_addr32[3]) & 0x0000ffff) != ( (ntohl(pkt_ns->nd_ns_target.s6_addr32[3]) >>16) ^ addr_key)){
1309 continue;
1310 }
1311 }
1312
1313 /* Check that the target address belongs to the prefix from which we are sending packets */
1314 if(!match_ipv6(&(idata.srcaddr), &idata.srcpreflen, 1, &(pkt_ns->nd_ns_target))){
1315 continue;
1316 }
1317 }
1318 else{
1319 if(!is_eq_in6_addr( &(pkt_ns->nd_ns_target), &(idata.srcaddr)) ){
1320 continue;
1321 }
1322 }
1323
1324 if(send_neighbor_advert(&idata, idata.pfd, pktdata) == -1){
1325 puts("Error sending Neighbor Advertisement");
1326 exit(EXIT_FAILURE);
1327 }
1328 }
1329 }
1330 }
1331 }
1332
1333 if(idata.dstaddr_f && !donesending_f && is_time_elapsed(&curtime, &lastprobe, pktinterval)){
1334 lastprobe= curtime;
1335 send_packet(&idata, NULL, NULL);
1336 }
1337 }
1338
1339 exit(EXIT_SUCCESS);
1340 }
1341
1342 if(!(idata.dstaddr_f) && !listen_f){
1343 puts("Error: Nothing to send! (Destination Address left unspecified, and not using listening mode)");
1344 exit(EXIT_FAILURE);
1345 }
1346
1347 exit(EXIT_SUCCESS);
1348 }
1349
1350
1351
1352 /*
1353 * Function: init_packet_data()
1354 *
1355 * Initialize the contents of the attack packet (Ethernet header, IPv6 Header, and ICMPv6 header)
1356 * that are expected to remain constant for the specified attack.
1357 */
1358 void init_packet_data(struct iface_data *idata){
1359 struct dlt_null *dlt_null;
1360 ethernet= (struct ether_header *) buffer;
1361 dlt_null= (struct dlt_null *) buffer;
1362 v6buffer = buffer + idata->linkhsize;
1363 ipv6 = (struct ip6_hdr *) v6buffer;
1364
1365 if(idata->type == DLT_EN10MB){
1366 ethernet->ether_type = htons(ETHERTYPE_IPV6);
1367
1368 if(!(idata->flags & IFACE_LOOPBACK)){
1369 ethernet->src = idata->hsrcaddr;
1370 ethernet->dst = idata->hdstaddr;
1371 }
1372 }
1373 else if(idata->type == DLT_NULL){
1374 dlt_null->family= PF_INET6;
1375 }
1376 #if defined (__OpenBSD__)
1377 else if(idata->type == DLT_LOOP){
1378 dlt_null->family= htonl(PF_INET6);
1379 }
1380 #endif
1381
1382 ipv6->ip6_flow=0;
1383 ipv6->ip6_vfc= 0x60;
1384 ipv6->ip6_hlim= hoplimit;
1385 ipv6->ip6_src= idata->srcaddr;
1386 ipv6->ip6_dst= idata->dstaddr;
1387
1388 prev_nh = (unsigned char *) &(ipv6->ip6_nxt);
1389
1390 ptr = (unsigned char *) v6buffer + MIN_IPV6_HLEN;
1391
1392 if(hbhopthdr_f){
1393 hbhopthdrs=0;
1394
1395 while(hbhopthdrs < nhbhopthdr){
1396 if((ptr+ hbhopthdrlen[hbhopthdrs]) > (v6buffer+ idata->mtu)){
1397 puts("Packet too large while processing HBH Opt. Header");
1398 exit(EXIT_FAILURE);
1399 }
1400
1401 *prev_nh = IPPROTO_HOPOPTS;
1402 prev_nh = ptr;
1403 memcpy(ptr, hbhopthdr[hbhopthdrs], hbhopthdrlen[hbhopthdrs]);
1404 ptr = ptr + hbhopthdrlen[hbhopthdrs];
1405 hbhopthdrs++;
1406 }
1407 }
1408
1409 if(dstoptuhdr_f){
1410 dstoptuhdrs=0;
1411
1412 while(dstoptuhdrs < ndstoptuhdr){
1413 if((ptr+ dstoptuhdrlen[dstoptuhdrs]) > (v6buffer+ idata->mtu)){
1414 puts("Packet too large while processing Dest. Opt. Header (Unfrag. Part)");
1415 exit(EXIT_FAILURE);
1416 }
1417
1418 *prev_nh = IPPROTO_DSTOPTS;
1419 prev_nh = ptr;
1420 memcpy(ptr, dstoptuhdr[dstoptuhdrs], dstoptuhdrlen[dstoptuhdrs]);
1421 ptr = ptr + dstoptuhdrlen[dstoptuhdrs];
1422 dstoptuhdrs++;
1423 }
1424 }
1425
1426 /* Everything that follows is the Fragmentable Part of the packet */
1427 fragpart = ptr;
1428
1429 if(idata->fragh_f){
1430 /* Check that we are able to send the Unfragmentable Part, together with a
1431 Fragment Header and a chunk data over our link layer
1432 */
1433 if( (fragpart+sizeof(fraghdr)+nfrags) > (v6buffer+idata->mtu)){
1434 puts("Unfragmentable part too large for current MTU");
1435 exit(EXIT_FAILURE);
1436 }
1437
1438 /* We prepare a separete Fragment Header, but we do not include it in the packet to be sent.
1439 This Fragment Header will be used (an assembled with the rest of the packet by the
1440 send_packet() function.
1441 */
1442 memset(&fraghdr, 0, FRAG_HDR_SIZE);
1443 *prev_nh = IPPROTO_FRAGMENT;
1444 prev_nh = (unsigned char *) &fraghdr;
1445 }
1446
1447 if(dstopthdr_f){
1448 dstopthdrs=0;
1449
1450 while(dstopthdrs < ndstopthdr){
1451 if((ptr+ dstopthdrlen[dstopthdrs]) > (v6buffer+ idata->max_packet_size)){
1452 puts("Packet too large while processing Dest. Opt. Header (should be using the Frag. option?)");
1453 exit(EXIT_FAILURE);
1454 }
1455
1456 *prev_nh = IPPROTO_DSTOPTS;
1457 prev_nh = ptr;
1458 memcpy(ptr, dstopthdr[dstopthdrs], dstopthdrlen[dstopthdrs]);
1459 ptr = ptr + dstopthdrlen[dstopthdrs];
1460 dstopthdrs++;
1461 }
1462 }
1463
1464
1465 *prev_nh = IPPROTO_UDP;
1466
1467 startofprefixes=ptr;
1468 }
1469
1470
1471
1472 /*
1473 * Function: send_packet()
1474 *
1475 * Initialize the remaining fields of the UDP datagram, and send the attack packet(s).
1476 */
1477 void send_packet(struct iface_data *idata, const u_char *pktdata, struct pcap_pkthdr *pkthdr){
1478 static unsigned int sources=0, ports=0;
1479 ptr=startofprefixes;
1480 senddata_f= 0;
1481
1482 if(pktdata != NULL){ /* Sending an UDP datagram in response to a received packet */
1483 pkt_ether = (struct ether_header *) pktdata;
1484 pkt_ipv6 = (struct ip6_hdr *)((char *) pkt_ether + idata->linkhsize);
1485 pkt_udp= (struct udp_hdr *)( (char *) pkt_ipv6 + sizeof(struct ip6_hdr));
1486 pkt_end = (unsigned char *) pktdata + pkthdr->caplen;
1487
1488 /* The packet length is the minimum of what we capured, and what is specified in the
1489 IPv6 Total Lenght field
1490 */
1491 if( pkt_end > ((unsigned char *)pkt_ipv6 + sizeof(struct ip6_hdr) + pkt_ipv6->ip6_plen) )
1492 pkt_end = (unsigned char *)pkt_ipv6 + sizeof(struct ip6_hdr) + pkt_ipv6->ip6_plen;
1493
1494
1495 pkt_ipv6addr = &(pkt_ipv6->ip6_src);
1496
1497 /*
1498 We don't send any packets if the Source Address of the captured packet is the unspecified
1499 address or a multicast address
1500 */
1501 if(IN6_IS_ADDR_UNSPECIFIED(pkt_ipv6addr) || IN6_IS_ADDR_MULTICAST(pkt_ipv6addr)){
1502 return;
1503 }
1504 else{
1505 ipv6->ip6_dst = pkt_ipv6->ip6_src;
1506
1507 if(idata->type == DLT_EN10MB && !(idata->flags & IFACE_LOOPBACK))
1508 ethernet->dst = pkt_ether->src;
1509 }
1510
1511 pkt_ipv6addr = &(pkt_ipv6->ip6_dst);
1512
1513 /*
1514 We do not send any packets if the Destination Address of the captured packet is the unspecified
1515 address or a multicast address
1516 */
1517 if(IN6_IS_ADDR_MULTICAST(pkt_ipv6addr) || IN6_IS_ADDR_MULTICAST(pkt_ipv6addr)){
1518 return;
1519 }
1520 else{
1521 ipv6->ip6_src = pkt_ipv6->ip6_dst;
1522
1523 if(idata->type == DLT_EN10MB && !(idata->flags & IFACE_LOOPBACK))
1524 ethernet->src = pkt_ether->dst;
1525 }
1526
1527
1528 if( (ptr+sizeof(struct udp_hdr)) > (v6buffer+ idata->max_packet_size)){
1529 puts("Packet Too Large while inserting UDP header");
1530 exit(EXIT_FAILURE);
1531 }
1532
1533 udp = (struct udp_hdr *) ptr;
1534 memset(udp, 0, sizeof(struct udp_hdr));
1535
1536 udp->uh_sport= pkt_udp->uh_dport;
1537 udp->uh_dport= pkt_udp->uh_sport;
1538 ptr+= sizeof(struct udp_hdr);
1539
1540 if(rhbytes_f){
1541 if( (ptr + rhbytes) > v6buffer+ idata->max_packet_size){
1542 puts("Packet Too Large while inserting UDP datagram");
1543 exit(EXIT_FAILURE);
1544 }
1545
1546 while(rhbytes>=4){
1547 *(uint32_t *)ptr = random();
1548 ptr += sizeof(uint32_t);
1549 rhbytes -= sizeof(uint32_t);
1550 }
1551
1552 while(rhbytes>0){
1553 *(uint8_t *) ptr= (uint8_t) random();
1554 ptr++;
1555 rhbytes--;
1556 }
1557 }
1558 else if(data_f){
1559 ptr= (unsigned char *)udp + sizeof(struct udp_hdr);
1560
1561 if((ptr+ datalen) > (v6buffer + idata->max_packet_size)){
1562 if(idata->verbose_f)
1563 puts("Packet too large while inserting UDP data");
1564 exit(EXIT_FAILURE);
1565 }
1566
1567 memcpy(ptr, data, datalen);
1568 ptr+= datalen;
1569 }
1570
1571 udp->uh_ulen= htons(ptr - (unsigned char *) udp);
1572 udp->uh_sum = 0;
1573 udp->uh_sum = in_chksum(v6buffer, udp, ptr-((unsigned char *)udp), IPPROTO_UDP);
1574
1575 frag_and_send(idata);
1576
1577 return;
1578 }
1579 else{
1580 if(ports >= nports){
1581 sources++;
1582 ports= 0;
1583 }
1584
1585 if(sources >= nsources){
1586 if(loop_f){
1587 sources= 0;
1588 }
1589 else{
1590 donesending_f= 1;
1591 return;
1592 }
1593 }
1594
1595 if( (ptr+sizeof(struct udp_hdr)) > (v6buffer + idata->max_packet_size)){
1596 puts("Packet Too Large while inserting UDP header");
1597 exit(EXIT_FAILURE);
1598 }
1599
1600 udp= (struct udp_hdr *) ptr;
1601 memset(ptr, 0, sizeof(struct udp_hdr));
1602 udp->uh_sport= htons(srcport);
1603 udp->uh_dport= htons(dstport);
1604 ptr += sizeof(struct udp_hdr);
1605
1606 if(rhbytes_f){
1607 if( (ptr + rhbytes) > v6buffer + idata->max_packet_size){
1608 puts("Packet Too Large while inserting UDP datagram");
1609 exit(EXIT_FAILURE);
1610 }
1611
1612 while(rhbytes>=4){
1613 *(uint32_t *)ptr = random();
1614 ptr += sizeof(uint32_t);
1615 rhbytes -= sizeof(uint32_t);
1616 }
1617
1618 while(rhbytes>0){
1619 *(uint8_t *) ptr= (uint8_t) random();
1620 ptr++;
1621 rhbytes--;
1622 }
1623 }
1624 else if(data_f){
1625 ptr= (unsigned char *)udp + sizeof(struct udp_hdr);
1626
1627 if((ptr+ datalen) > (v6buffer + idata->max_packet_size)){
1628 if(idata->verbose_f)
1629 puts("Packet too large while inserting UDP data");
1630 exit(EXIT_FAILURE);
1631 }
1632
1633 memcpy(ptr, data, datalen);
1634 ptr+= datalen;
1635 }
1636
1637 udp->uh_ulen= htons(ptr - (unsigned char *) udp);
1638
1639 if(pktdata == NULL && (floods_f && ports == 0)){
1640 /*
1641 Randomizing the IPv6 Source address based on the prefix specified by
1642 "srcaddr" and srcpreflen.
1643 */
1644
1645 randomize_ipv6_addr( &(ipv6->ip6_src), &(idata->srcaddr), idata->srcpreflen);
1646
1647 /*
1648 If we need to respond to incomming packets, we set the Interface ID such that we can
1649 detect which IPv6 addresses we have used.
1650 */
1651 if(listen_f && useaddrkey_f){
1652 ipv6->ip6_src.s6_addr32[2]= ntohl((uint32_t)random() <<16);
1653 ipv6->ip6_src.s6_addr32[2]= htonl(ntohl(ipv6->ip6_src.s6_addr32[2]) | ((ntohl(ipv6->ip6_src.s6_addr32[2])>>16) ^ addr_key));
1654
1655 ipv6->ip6_src.s6_addr32[3]= ntohl((uint32_t)random() <<16);
1656 ipv6->ip6_src.s6_addr32[3]= htonl(ntohl(ipv6->ip6_src.s6_addr32[3]) | (uint32_t)((ntohl(ipv6->ip6_src.s6_addr32[3]) >>16) ^ addr_key));
1657 }
1658
1659 if(idata->type == DLT_EN10MB && !(idata->flags & IFACE_LOOPBACK) && !(idata->hsrcaddr_f)){
1660 for(i=0; i<6; i++)
1661 ethernet->src.a[i]= random();
1662 }
1663 }
1664
1665 if(pktdata == NULL && floodp_f){
1666 udp->uh_sport= random();
1667 }
1668
1669 udp->uh_sum = 0;
1670 udp->uh_sum = in_chksum(v6buffer, udp, ptr-((unsigned char *)udp), IPPROTO_UDP);
1671
1672 frag_and_send(idata);
1673
1674 if(pktdata == NULL)
1675 ports++;
1676
1677 return;
1678 }
1679 }
1680
1681
1682 /*
1683 * Function: frag_and_send()
1684 *
1685 * Send an IPv6 datagram, and fragment if selected
1686 */
1687 void frag_and_send(struct iface_data *idata){
1688 if(!idata->fragh_f){
1689 ipv6->ip6_plen = htons((ptr - v6buffer) - MIN_IPV6_HLEN);
1690
1691 if((nw=pcap_inject(idata->pfd, buffer, ptr - buffer)) == -1){
1692 printf("pcap_inject(): %s\n", pcap_geterr(idata->pfd));
1693 exit(EXIT_FAILURE);
1694 }
1695
1696 if(nw != (ptr-buffer)){
1697 printf("pcap_inject(): only wrote %lu bytes (rather than %lu bytes)\n", \
1698 (LUI) nw, (LUI) (ptr-buffer));
1699 exit(EXIT_FAILURE);
1700 }
1701 }
1702 else{
1703 ptrend= ptr;
1704 ptr= fragpart;
1705 fptr = fragbuffer;
1706 fipv6 = (struct ip6_hdr *) (fragbuffer + idata->linkhsize);
1707 fptrend = fptr + idata->linkhsize+MIN_IPV6_HLEN+MAX_IPV6_PAYLOAD;
1708 memcpy(fptr, buffer, fragpart-buffer);
1709 fptr = fptr + (fragpart-buffer);
1710
1711 if( (fptr+FRAG_HDR_SIZE)> fptrend){
1712 puts("Unfragmentable Part is Too Large");
1713 exit(EXIT_FAILURE);
1714 }
1715
1716 memcpy(fptr, (char *) &fraghdr, FRAG_HDR_SIZE);
1717 fh= (struct ip6_frag *) fptr;
1718 fh->ip6f_ident=random();
1719 startoffragment = fptr + FRAG_HDR_SIZE;
1720
1721 /*
1722 * Check that the selected fragment size is not larger than the largest
1723 * fragment size that can be sent
1724 */
1725 if(nfrags <= (fptrend - fptr))
1726 fragsize=nfrags;
1727 else
1728 fragsize= (fptrend-fptr) & IP6F_OFF_MASK;
1729
1730 m=IP6F_MORE_FRAG;
1731
1732 while((ptr< ptrend) && m==IP6F_MORE_FRAG){
1733 fptr= startoffragment;
1734
1735 if( (ptrend-ptr) <= fragsize){
1736 fragsize= ptrend-ptr;
1737 m=0;
1738 }
1739
1740 memcpy(fptr, ptr, fragsize);
1741 fh->ip6f_offlg = (htons(ptr-fragpart) & IP6F_OFF_MASK) | m;
1742 ptr+=fragsize;
1743 fptr+=fragsize;
1744
1745 fipv6->ip6_plen = htons((fptr - fragbuffer) - MIN_IPV6_HLEN - idata->linkhsize);
1746
1747 if((nw=pcap_inject(idata->pfd, fragbuffer, fptr - fragbuffer)) == -1){
1748 printf("pcap_inject(): %s\n", pcap_geterr(idata->pfd));
1749 exit(EXIT_FAILURE);
1750 }
1751
1752 if(nw != (fptr- fragbuffer)){
1753 printf("pcap_inject(): only wrote %lu bytes (rather than %lu bytes)\n", \
1754 (LUI) nw, (LUI) (ptr-buffer));
1755 exit(EXIT_FAILURE);
1756 }
1757 } /* Sending fragments */
1758 } /* Sending fragmented datagram */
1759 }
1760
1761
1762 /*
1763 * Function: usage()
1764 *
1765 * Prints the syntax of the udp6 tool
1766 */
1767 void usage(void){
1768 puts("usage: udp6 [-i INTERFACE] [-S LINK_SRC_ADDR] [-D LINK-DST-ADDR] "
1769 "[-s SRC_ADDR[/LEN]] [-d DST_ADDR] [-A HOP_LIMIT] [-y FRAG_SIZE] [-u DST_OPT_HDR_SIZE] "
1770 "[-U DST_OPT_U_HDR_SIZE] [-H HBH_OPT_HDR_SIZE] [-P PAYLOAD_SIZE] [-o SRC_PORT] "
1771 "[-a DST_PORT] "
1772 "[-N] [-f] [-j PREFIX[/LEN]] [-k PREFIX[/LEN]] [-J LINK_ADDR] [-K LINK_ADDR] "
1773 "[-b PREFIX[/LEN]] [-g PREFIX[/LEN]] [-B LINK_ADDR] [-G LINK_ADDR] "
1774 "[-F N_SOURCES] [-T N_PORTS] [-L | -l] [-z SECONDS] [-v] [-h]");
1775 }
1776
1777
1778 /*
1779 * Function: print_help()
1780 *
1781 * Prints help information for the udp6 tool
1782 */
1783 void print_help(void){
1784 puts(SI6_TOOLKIT);
1785 puts( "udp6: Security assessment tool for attack vectors based on UDP/IPv6 packets\n");
1786 usage();
1787
1788 puts("\nOPTIONS:\n"
1789 " --interface, -i Network interface\n"
1790 " --src-address, -s IPv6 Source Address\n"
1791 " --dst-address, -d IPv6 Destination Address\n"
1792 " --hop-limit, -A IPv6 Hop Limit\n"
1793 " --frag-hdr. -y Fragment Header\n"
1794 " --dst-opt-hdr, -u Destination Options Header (Fragmentable Part)\n"
1795 " --dst-opt-u-hdr, -U Destination Options Header (Unfragmentable Part)\n"
1796 " --hbh-opt-hdr, -H Hop by Hop Options Header\n"
1797 " --link-src-address, -S Link-layer Destination Address\n"
1798 " --link-dst-address, -D Link-layer Source Address\n"
1799 " --payload-size, -P UDP Payload Size\n"
1800 " --src-port, -o UDP Source Port\n"
1801 " --dst-port, -a UDP Destination Port\n"
1802 " --data, -Z UDP payload data\n"
1803 " --rate-limit, -r Rate limit the address scan to specified rate\n"
1804 " --probe-mode, -p UDP probe mode {dump,script}\n"
1805 " --block-src, -j Block IPv6 Source Address prefix\n"
1806 " --block-dst, -k Block IPv6 Destination Address prefix\n"
1807 " --block-link-src, -J Block Ethernet Source Address\n"
1808 " --block-link-dst, -K Block Ethernet Destination Address\n"
1809 " --accept-src, -b Accept IPv6 Source Addres prefix\n"
1810 " --accept-dst, -g Accept IPv6 Destination Address prefix\n"
1811 " --accept-link-src, -B Accept Ethernet Source Address\n"
1812 " --accept-link-dst, -G Accept Ethernet Destination Address\n"
1813 " --flood-sources, -F Flood from multiple IPv6 Source Addresses\n"
1814 " --flood-ports, -T Flood from multiple UDP Source Ports\n"
1815 " --listen, -L Listen to incoming packets\n"
1816 " --loop, -l Send periodic UDP segments\n"
1817 " --sleep, -z Pause between sending UDP segments\n"
1818 " --help, -h Print help for the udp6 tool\n"
1819 " --verbose, -v Be verbose\n"
1820 "\n"
1821 "Programmed by Fernando Gont for SI6 Networks <http://www.si6networks.com>\n"
1822 "Please send any bug reports to <fgont@si6networks.com>\n"
1823 );
1824 }
1825
1826
1827 /*
1828 * Function: print_attack_info()
1829 *
1830 * Prints attack details (when the verbose ("-v") option is specified).
1831 */
1832
1833 void print_attack_info(struct iface_data *idata){
1834 puts(SI6_TOOLKIT);
1835 puts( "udp6: Security assessment tool for attack vectors based on UDP/IPv6 packets\n");
1836
1837 if(floods_f)
1838 printf("Flooding the target from %u different IPv6 Source Addresses\n", nsources);
1839
1840 if(floodp_f)
1841 printf("Flooding the target from %u different UDP ports\n", nports);
1842
1843 if(idata->type == DLT_EN10MB && !(idata->flags & IFACE_LOOPBACK)){
1844 if(idata->hsrcaddr_f){
1845 if(ether_ntop(&(idata->hsrcaddr), plinkaddr, sizeof(plinkaddr)) == 0){
1846 puts("ether_ntop(): Error converting address");
1847 exit(EXIT_FAILURE);
1848 }
1849
1850 printf("Ethernet Source Address: %s\n", plinkaddr);
1851 }
1852 else{
1853 if(idata->dstaddr_f){
1854 if(ether_ntop(&(idata->hsrcaddr), plinkaddr, sizeof(plinkaddr)) == 0){
1855 puts("ether_ntop(): Error converting address");
1856 exit(EXIT_FAILURE);
1857 }
1858
1859 printf("Ethernet Source Address: %s%s\n", plinkaddr, ((!(idata->hsrcaddr_f))?" (randomized)":""));
1860 }
1861 else
1862 puts("Ethernet Source Address: Automatically selected for each packet");
1863 }
1864
1865 /*
1866 Ethernet Destination Address only used if a IPv6 Destination Address or an
1867 Ethernet Destination Address were specified.
1868 */
1869 if(idata->dstaddr_f){
1870 if(ether_ntop(&(idata->hdstaddr), plinkaddr, sizeof(plinkaddr)) == 0){
1871 puts("ether_ntop(): Error converting address");
1872 exit(EXIT_FAILURE);
1873 }
1874
1875 printf("Ethernet Destination Address: %s\n", plinkaddr);
1876 }
1877 }
1878
1879 if(inet_ntop(AF_INET6, &(idata->srcaddr), psrcaddr, sizeof(psrcaddr)) == NULL){
1880 puts("inet_ntop(): Error converting IPv6 Source Address to presentation format");
1881 exit(EXIT_FAILURE);
1882 }
1883
1884 if(!floods_f){
1885 if(idata->dstaddr_f){
1886 printf("IPv6 Source Address: %s%s\n", psrcaddr, ((idata->srcaddr_f != TRUE)?" (randomized)":""));
1887 }
1888 }
1889 else{
1890 printf("IPv6 Source Address: randomized, from the fc00:1::/%u prefix%s\n", idata->srcpreflen, \
1891 (!idata->srcprefix_f)?" (default)":"");
1892 }
1893
1894 if(idata->dstaddr_f){
1895 if(inet_ntop(AF_INET6, &(idata->dstaddr), pdstaddr, sizeof(pdstaddr)) == NULL){
1896 puts("inet_ntop(): Error converting IPv6 Destination Address to presentation format");
1897 exit(EXIT_FAILURE);
1898 }
1899
1900 printf("IPv6 Destination Address: %s\n", pdstaddr);
1901 }
1902
1903 printf("IPv6 Hop Limit: %u%s\n", hoplimit, (hoplimit_f)?"":" (default)");
1904
1905 for(i=0; i<ndstoptuhdr; i++)
1906 printf("Destination Options Header (Unfragmentable part): %u bytes\n", dstoptuhdrlen[i]);
1907
1908 for(i=0; i<nhbhopthdr; i++)
1909 printf("Hop by Hop Options Header: %u bytes\n", hbhopthdrlen[i]);
1910
1911 for(i=0; i<ndstopthdr; i++)
1912 printf("Destination Options Header: %u bytes\n", dstopthdrlen[i]);
1913
1914 if(idata->fragh_f)
1915 printf("Sending each packet in fragments of %u bytes (plus the Unfragmentable part)\n", nfrags);
1916
1917 if(idata->dstaddr_f){
1918 if(!floodp_f || (floodp_f && nports ==1)){
1919 printf("Source Port: %u%s\t", srcport, (srcport_f?"":" (randomized)"));
1920 }
1921 else{
1922 printf("Source Port: (randomized)\t");
1923 }
1924
1925 printf("Destination Port: %u%s\n", dstport, (dstport_f?"":" (randomized)"));
1926 }
1927 else{
1928 printf("Source Port: Auto\tDestination Port: Auto\n");
1929 }
1930 }
1931
1932
1933
1934
1935 /*
1936 * Function: is_valid_tcp_segment()
1937 *
1938 * Performs sanity checks on an incomming UDP/IPv6 segment
1939 */
1940
1941 int is_valid_udp_datagram(struct iface_data *idata, const u_char *pktdata, struct pcap_pkthdr *pkthdr){
1942 struct ether_header *pkt_ether;
1943 struct ip6_hdr *pkt_ipv6;
1944 struct udp_hdr *pkt_udp;
1945 unsigned char *pkt_end;
1946
1947 pkt_ether = (struct ether_header *) pktdata;
1948 pkt_ipv6 = (struct ip6_hdr *)((char *) pkt_ether + idata->linkhsize);
1949 pkt_udp = (struct udp_hdr *) ((char *) pkt_ipv6 + MIN_IPV6_HLEN);
1950
1951 pkt_end = (unsigned char *) pktdata + pkthdr->caplen;
1952
1953 /* XXX: We are assuming no extension headers on incoming packets -- this should be improved! */
1954
1955 /* The packet length is the minimum of what we capured, and what is specified in the
1956 IPv6 Total Lenght field
1957 */
1958 if( pkt_end > ((unsigned char *)pkt_udp + pkt_ipv6->ip6_plen) )
1959 pkt_end = (unsigned char *)pkt_udp + pkt_ipv6->ip6_plen;
1960
1961 /*
1962 Discard the packet if it is not of the minimum size to contain a UDP header
1963 */
1964 if( (pkt_end - (unsigned char *) pkt_udp) < sizeof(struct udp_hdr)){
1965 return FALSE;
1966 }
1967
1968 /*
1969 Discard the packet if it is not of the minimum size to contain a UDP header
1970 */
1971 if( (pkt_end - (unsigned char *) pkt_udp) < ntohs(pkt_udp->uh_ulen)){
1972 return FALSE;
1973 }
1974
1975 /* Check that the UDP checksum is correct */
1976 if(in_chksum(pkt_ipv6, pkt_udp, pkt_end-((unsigned char *)pkt_udp), IPPROTO_UDP) != 0){
1977 return FALSE;
1978 }
1979
1980
1981 /* XXX: Should perform additional checks on the IPv6 header */
1982 /*
1983 Sanity checks on the Source Address and the Destination Address
1984 */
1985 if(IN6_IS_ADDR_UNSPECIFIED(&(pkt_ipv6->ip6_src)) || IN6_IS_ADDR_UNSPECIFIED(&(pkt_ipv6->ip6_dst))){
1986 return FALSE;
1987 }
1988
1989 if(IN6_IS_ADDR_MULTICAST(&(pkt_ipv6->ip6_src)) || IN6_IS_ADDR_MULTICAST(&(pkt_ipv6->ip6_dst))){
1990 return FALSE;
1991 }
1992
1993 return TRUE;
1994 }
1995
1996