Date: Tue, 1 Aug 2006 20:26:04 GMT From: Clément Lecigne <clem1@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 102969 for review Message-ID: <200608012026.k71KQ4Cl038045@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=102969 Change 102969 by clem1@clem1_ipv6vulns on 2006/08/01 20:25:24 isicng improvements : - allow extension headers for icmpsicng - introduce new options for icmpsicng - fasticmpsicng, a "faster" version of icmpsicng - tunsicng, 6to4 random packets generator - bugs fix libnet: checksum is OK when there are some extension headers. Affected files ... .. //depot/projects/soc2006/clem1_ipv6vulns/fuzzers/isicng/ChangeLog#5 edit .. //depot/projects/soc2006/clem1_ipv6vulns/fuzzers/isicng/Makefile.in#3 edit .. //depot/projects/soc2006/clem1_ipv6vulns/fuzzers/isicng/fasticmpsicng.c#1 add .. //depot/projects/soc2006/clem1_ipv6vulns/fuzzers/isicng/icmpsicng.c#5 edit .. //depot/projects/soc2006/clem1_ipv6vulns/fuzzers/isicng/isicng.c#5 edit .. //depot/projects/soc2006/clem1_ipv6vulns/fuzzers/isicng/tunsicng.c#1 add .. //depot/projects/soc2006/clem1_ipv6vulns/libnet/include/libnet/libnet-functions.h#8 edit .. //depot/projects/soc2006/clem1_ipv6vulns/libnet/src/libnet_checksum.c#3 edit Differences ... ==== //depot/projects/soc2006/clem1_ipv6vulns/fuzzers/isicng/ChangeLog#5 (text+ko) ==== @@ -1,3 +1,24 @@ +ISICNG (v0.01.7) 06/07/31, by Clément Lecigne (clem1@FreeBSD.org) + + o icmpsicng.c improvements: + o support all extension header. + o speed improvements. + o more options (flowlabel, hoplimit). + o fasticmpsic.c generates very simple icmp packets but much + faster than icmpsicng. + o tunsicng.c generates random ipv6 packets encapsulated into + random ipv4 packets. + + +ISICNG (v0.01.6) 06/07/30, by Clément Lecigne (clem1@FreeBSD.org) + + o made icmpsicng much faster. + o -w option removed + +ISICNG (v0.01.5) 06/07/21, by Clément Lecigne (clem1@FreeBSD.org) + + o tunsicng generates IPv6-over-IPv4 packets. + ISICNG (v0.01.4) 06/07/16, by Clément Lecigne (clem1@FreeBSD.org) o ipcompsicng generates random ipcomp (IPCompression) packets. ==== //depot/projects/soc2006/clem1_ipv6vulns/fuzzers/isicng/Makefile.in#3 (text+ko) ==== @@ -15,7 +15,7 @@ VERSION = 0.01 DEFS += -DVERSION=\"$(VERSION)\" -BINS = isicng tcpsicng udpsicng icmpsicng ipcompsicng +BINS = isicng tcpsicng udpsicng icmpsicng ipcompsicng tunsicng fasticmpsicng all: $(BINS) @@ -34,6 +34,12 @@ ipcompsicng: ipcompsicng.c isicng.h gcc -o ipcompsicng ipcompsicng.c -Wall -W $(CFLAGS) $(DEFS) $(LIBS) $(LDFLAGS) +tunsicng: tunsicng.c isicng.h + gcc -o tunsicng tunsicng.c -Wall -W $(CFLAGS) $(DEFS) $(LIBS) $(LDFLAGS) + +fasticmpsicng: fasticmpsicng.c isicng.h + gcc -o fasticmpsicng fasticmpsicng.c -Wall -W $(CFLAGS) $(DEFS) $(LIBS) $(LDFLAGS) + realclean: distclean distclean: clean rm -f config.cache config.log config.status ==== //depot/projects/soc2006/clem1_ipv6vulns/fuzzers/isicng/icmpsicng.c#5 (text+ko) ==== @@ -1,6 +1,8 @@ #include "isicng.h" -/* This is tuned for ethernet sized frames (1500 bytes) +/* $id: $ + * + * This is tuned for ethernet sized frames (1500 bytes) * For user over a modem or frame (or other) you will have to change the * 'rand() & 0x4ff' line below. The 0x4ff needs to be less than the size of * the frame size minus the length of the ip header (40 bytes IIRC) minus the @@ -29,10 +31,9 @@ u_int a; u_char *buf = NULL; u_short *payload = NULL; - u_int payload_s = 0; + u_int payload_s = 0, len; struct libnet_icmpv6_hdr *icmp = NULL; - struct icmp_option_base_header { u_int8_t type; u_int8_t length; @@ -46,10 +47,15 @@ /* Packet Variables */ struct libnet_ipv6_hdr *ip6; struct libnet_in6_addr ip_src, ip_dst; - u_int32_t flow; + u_int32_t flow = 0xdeadbeef; u_int8_t tc, hl = 0, ver, *nx, eo; u_int32_t maxsize, minsize, multiple; struct libnet_ipv6_frag_hdr *ip6f = NULL; + struct libnet_ipv6_routing_hdr *ip6r = NULL; + struct libnet_ipv6_destopts_hdr *ip6d = NULL; + struct libnet_ipv6_hbhopts_hdr *ip6h = NULL; + struct libnet_ah_hdr *ip6ah = NULL; + struct libnet_esp_hdr *ip6esp = NULL; #ifdef LIBNET_BSDISH_OS char *smac = NULL, *dmac = NULL; @@ -60,7 +66,6 @@ int src_ip_rand = 0, dst_ip_rand = 0, dst_ok = 0, what; struct timeval tv, tv2; float sec; - unsigned int wwait; unsigned int cx = 0; u_long max_pushed = 10240; /* 10MB/sec */ u_long num_to_send = 0xffffffff; /* Send 4billion packets */ @@ -71,6 +76,11 @@ /* Defaults */ float FragPct = 30; + float RthPct = 10; + float DopPct = 10; + float HbhPct = 10; + float EspPct = 0; + float AhPct = 0; float BadIPVer = 10; float ICMPCksm = 10; float TooBig = 5; @@ -84,25 +94,27 @@ float IcmpOpt = 0; float Llocal = 10; float Slocal = 5; - + int MaxEHdr = 2; + maxsize = 1279; minsize = 128; - multiple = 1; + multiple = 1; - wwait = 500; /* wait microseconds between each write() */ - /* Not crypto strong randomness but we don't really care. And this * * gives us a way to determine the seed while the program is running * * if we need to repeat the results */ seed = getpid(); - while((c = getopt(argc, argv, "hd:i:s:r:m:k:D:S:p:H:V:F:I:T:R:E:U:M:O:N:W:P:z:Z:K:vx:w:L:A:")) != EOF) + while((c = getopt(argc, argv, "hd:i:f:s:r:m:k:D:S:e:p:H:V:F:I:T:R:E:U:M:O:N:W:P:z:Z:K:vx:L:A:B:C:G:J:Q:")) != EOF) { switch (c) { case 'i': device = optarg; break; + case 'e': + MaxEHdr = atoi(optarg); + break; case 'L': Llocal = atof(optarg); break; @@ -136,6 +148,9 @@ case 'W': NI = atof(optarg); break; + case 'f': + flow = atoi(optarg); + break; case 'z': minsize = atoi(optarg); break; @@ -145,9 +160,6 @@ case 'K': multiple = atoi(optarg); break; - case 'w': - wwait = atoi(optarg); - break; case 'h': usage(argv[0]); exit(0); @@ -214,6 +226,21 @@ case 'F': FragPct = atof(optarg); break; + case 'B': + HbhPct = atof(optarg); + break; + case 'C': + DopPct = atof(optarg); + break; + case 'G': + RthPct = atof(optarg); + break; + case 'J': + EspPct = atof(optarg); + break; + case 'Q': + AhPct = atof(optarg); + break; case 'I': ICMPCksm = atof(optarg); break; @@ -295,7 +322,12 @@ printf("Maximum traffic rate = %.2f k/s\n", max_pushed/1024.0); printf("Bad IP Version\t= %.0f%%\t\t", BadIPVer); - printf("Frag header\t= %.0f%%\n", FragPct); + printf("Routing hdr\t=%.0f%%\t\t", RthPct); + printf("Destination opts hdr\t=%.0f%%\t\t", DopPct); + printf("Hop by hop hdr\t=%.0f%%\t\t", HbhPct); + printf("Esp hdr\t=%.0f%%\t\t", EspPct); + printf("Ah hdr\t=%.0f%%\t\t", AhPct); + printf("Frag hdr\t= %.0f%%\n", FragPct); printf("TooBig=%.0f%% Redirect=%.0f%% Echo=%.0f%% Router=%.0f%%\n", TooBig, Redir, Echo, RT); printf("Unreach=%.0f%% MLD=%.0f%% ND=%.0f%% NI=%.0f%%\n", Unreach, MLD, ND, NI); @@ -327,11 +359,11 @@ for(acx = 0; acx < num_to_send; acx++) { off = eo; - memset(buf + eo, 0x0, IP_MAXPACKET - eo); if (!hl) hl = rand() & 0xff; - flow = rand(); + if (flow == 0xdeadbeef) + flow = rand(); tc = rand() & 0xff; if (src_ip_rand == 1) @@ -363,19 +395,142 @@ off += 40; - /* fragmentation or not ? */ - if(rand() <= (RAND_MAX * FragPct) && payload_s >= 16) - { - ip6f = (struct libnet_ipv6_frag_hdr *)(buf + off); - *nx = 44; - ip6f->ip_nh = IPPROTO_ICMP6; - ip6f->ip_reserved = (rand() % 2) ? rand() & 0xff : 0; - ip6f->ip_frag = rand() & 0xffff; - ip6f->ip_id = (rand() % 10) ? rand() : getpid(); - off += 8; - payload_s -= 8; - } + for (c = 0; c < MaxEHdr; c++){ + switch (rand() % 6) + { + case 0: + /* Fragmentation header */ + if (rand() <= (RAND_MAX * FragPct)) + { + ip6f = (struct libnet_ipv6_frag_hdr *)(buf + off); + *nx = 44; + ip6f->ip_nh = IPPROTO_ICMP6; + nx = &ip6->ip_nh; + ip6f->ip_reserved = (rand() % 2) ? rand() & 0xff : 0; + ip6f->ip_frag = rand() & 0xffff; + ip6f->ip_id = (rand() % 10) ? rand() : getpid(); + off += 8; + payload_s -= 8; + } + break; + case 1: + /* Routing header */ + if (rand() <= (RAND_MAX * RthPct)) + { + ip6r = (struct libnet_ipv6_routing_hdr *)(buf + off); + *nx = 43; + ip6r->ip_nh = IPPROTO_ICMP6; + nx = &ip6r->ip_nh; + ip6r->ip_len = rand() & 0xff; + ip6r->ip_rtype = (rand() % 2) ? rand() & 0xff : 0; + ip6r->ip_segments = rand() & 0xff; + off += 4; + payload_s -= 4; + /* padding with addresses */ + len = ((ip6r->ip_len + 1) << 3) - 4; + if (payload_s >= len) + { + payload = (short int *)(buf + off); + for (a = 0; a < len; a++) + payload[a] = rand() & 0xff; + payload_s -= len; + off += len; + } + } + break; + case 2: + /* Destination opts */ + if (rand() <= (RAND_MAX * DopPct)) + { + ip6d = (struct libnet_ipv6_destopts_hdr *)(buf + off); + *nx = 60; + ip6d->ip_nh = IPPROTO_ICMP6; + nx = &ip6d->ip_nh; + ip6d->ip_len = rand() & 0xff; + off += 2; + payload_s -= 2; + /* padding with random option */ + len = ((ip6d->ip_len + 1) << 3) - 2; + if (payload_s >= len) + { + payload = (short int *)(buf + off); + for (a = 0; a < len; a++) + payload[a] = rand() & 0xff; + payload_s -= len; + off += len; + } + } + break; + case 3: + /* Hop by hop header */ + if (rand() <= (RAND_MAX * HbhPct)) + { + ip6h = (struct libnet_ipv6_hbhopts_hdr *)(buf + off); + *nx = 0; + ip6h->ip_nh = IPPROTO_ICMP6; + nx = &ip6h->ip_nh; + ip6h->ip_len = rand() & 0xff; + off += 2; + payload_s -= 2; + /* padding with addr */ + len = ((ip6h->ip_len + 1) << 3) - 2; + if (payload_s >= len) + { + payload = (short int *)(buf + off); + for (a = 0; a < len; a++) + payload[a] = rand() & 0xff; + payload_s -= len; + off += len; + } + + } + break; + case 4: + /* AH header */ + if (rand() <= (RAND_MAX * AhPct)) + { + ip6ah = (struct libnet_ah_hdr *)(buf + off); + *nx = 51; + ip6ah->ah_nh = IPPROTO_ICMP6; + nx = &ip6ah->ah_nh; + ip6ah->ah_len = rand() & 0xff; + ip6ah->ah_res = (rand() % 2) ? 0 : rand() % 0xffff; + ip6ah->ah_spi = rand(); + ip6ah->ah_seq = rand(); + ip6ah->ah_auth = rand(); + off += 16; + payload_s -= 16; + } + break; + case 5: + /* ESP header */ + if (rand() <= (RAND_MAX * EspPct)) + { + ip6esp = (struct libnet_esp_hdr *)(buf + off); + *nx = 50; + ip6esp->esp_spi = rand(); + ip6esp->esp_seq = rand(); + ip6esp->esp_iv = rand(); + off += 12; + payload_s -= 12; + } + break; + } + if (payload_s > maxsize) + break; + } + /* XXX: try to avoid this */ + if (payload_s > maxsize) + { + if (printout) + puts("you need to increase minsize or decrease max ehdr"); + payload_s = 0; + continue; + } + /* save payload_s size for checksum */ + len = payload_s; + icmp = (struct libnet_icmpv6_hdr *)(buf + off); what = rand(); @@ -530,7 +685,7 @@ payload = (short int *)(buf + off); for (a = 0; a < payload_s; a++) payload[a] = rand() & 0xff; - }else{ + }else if (payload_s <= maxsize){ payload = (short int *)(buf + off); for(cx = 0; cx <= (payload_s >> 1); cx+=1) (u_short) payload[cx] = rand() & 0xffff; @@ -539,12 +694,11 @@ if (rand() <= (RAND_MAX * ICMPCksm)) icmp->icmp_sum = rand() & 0xffff; else - libnet_do_checksum(l, buf + eo, IPPROTO_ICMP6, payload_s + (off - 40 - eo)); + libnet_do_checksum(l, buf + eo, IPPROTO_ICMP6, len); if (skip <= acx) { for (cx = 0; cx < repeat; cx++) { - usleep(wwait); #ifdef LIBNET_BSDISH_OS c = libnet_write_link(l, buf, off + payload_s); #else /* !BSD */ @@ -553,7 +707,7 @@ if (c != -1) datapushed += c; } - if ((u_int)c != (off + payload_s)) + if ((u_int)c != (off + payload_s) && printout) fprintf(stderr, "Failed to send packet: %s\n", libnet_geterror(l)); } @@ -672,7 +826,6 @@ } return (off); } - void usage(u_char *name) { @@ -685,10 +838,13 @@ #endif " [-r seed] [-m <max kB/s to generate>]\n" " [-p <pkts to generate>] [-k <skip packets>] [-x <send packet X times>]\n" - " [-z <minsize>] [-Z <maxsize>] [-K <size multiple>] [-w <wait time in ms>]\n" + " [-z <minsize>] [-Z <maxsize>] [-K <size multiple>]\n" "\n" - " Percentage Opts: [-F frags] [-V Bad IP Version]\n" + " Percentage Opts: [-e maxehdr] [-F frags] [-Q ipsecah]\n" + " [-J ipsecesp] [-G routing] [-C dstopts]\n" + " [-B hopbyhop] [-V Bad IP Version]\n" " [-H hop limit] [-I Bad checksum]\n" + " [-f flowlabel]\n" " [-L linklocal addr] [-A sitelocal addr]\n" " [-P IcmpOpt]\n" " [-T Toobig] [-R Redirect] [-E Echo]\n" ==== //depot/projects/soc2006/clem1_ipv6vulns/fuzzers/isicng/isicng.c#5 (text+ko) ==== ==== //depot/projects/soc2006/clem1_ipv6vulns/libnet/include/libnet/libnet-functions.h#8 (text+ko) ==== @@ -2347,6 +2347,12 @@ libnet_do_checksum(libnet_t *l, u_int8_t *packet, int protocol, int len); /* + * [Internal] + */ +int +libnet_payload_off(u_int8_t *buf, int len); + +/* * [Internal] */ u_int32_t ==== //depot/projects/soc2006/clem1_ipv6vulns/libnet/src/libnet_checksum.c#3 (text+ko) ==== @@ -94,6 +94,58 @@ } } +int +libnet_payload_off(u_int8_t *buf, int len) +{ + int proto; + int off; + struct libnet_ipv6_hdr *ip6; + struct libnet_ipv6_frag_hdr *ip6f; + struct libnet_ipv6_routing_hdr *ip6e; + + off = 0; + ip6 = (struct libnet_ipv6_hdr *)buf; + proto = ip6->ip_nh; + off += LIBNET_IPV6_H; + + while (1) + { + if (off > len) return (0); + switch (proto) + { + case IPPROTO_IPV6: + ip6 = (struct libnet_ipv6_hdr *)(buf + off); + proto = ip6->ip_nh; + off += LIBNET_IPV6_H; + break; + case IPPROTO_FRAGMENT: + ip6f = (struct libnet_ipv6_frag_hdr *)(buf + off); + proto = ip6f->ip_nh; + off += LIBNET_IPV6_FRAG_H; + break; + case IPPROTO_AH: + ip6e = (struct libnet_ipv6_routing_hdr *)(buf + off); + proto = ip6e->ip_nh; + off += (ip6e->ip_len + 2) << 2; + break; + case IPPROTO_HOPOPTS: + case IPPROTO_ROUTING: + case IPPROTO_DSTOPTS: + ip6e = (struct libnet_ipv6_routing_hdr *)(buf + off); + proto = ip6e->ip_nh; + off += (ip6e->ip_len + 1) << 3; + break; + case IPPROTO_ESP: + /* no need to checksum if ESP */ + return (-1); + default: + return (off); + } + } + /* never reached */ + return (off); +} + int libnet_do_checksum(libnet_t *l, u_int8_t *buf, int protocol, int len) @@ -104,8 +156,10 @@ int is_ipv6; int ip_hl; int sum; + int off; /* points to the payload start in buf */ is_ipv6 = 0; /* default to not using IPv6 */ + off = 0; sum = 0; iph_p = NULL; ip6h_p = NULL; @@ -128,6 +182,9 @@ ip6h_p = (struct libnet_ipv6_hdr *)buf; is_ipv6 = 1; ip_hl = LIBNET_IPV6_H; + off = libnet_payload_off(buf, len) - LIBNET_IPV6_H; + if (off == -1) + return 1; /* ESP */ } else { @@ -148,7 +205,7 @@ case IPPROTO_TCP: { struct libnet_tcp_hdr *tcph_p = - (struct libnet_tcp_hdr *)(buf + ip_hl); + (struct libnet_tcp_hdr *)(buf + ip_hl + off); #if (STUPID_SOLARIS_CHECKSUM_BUG) tcph_p->th_sum = tcph_p->th_off << 2; @@ -183,7 +240,7 @@ case IPPROTO_UDP: { struct libnet_udp_hdr *udph_p = - (struct libnet_udp_hdr *)(buf + ip_hl); + (struct libnet_udp_hdr *)(buf + ip_hl + off); udph_p->uh_sum = 0; if (is_ipv6) { @@ -202,7 +259,7 @@ case IPPROTO_ICMP6: { struct libnet_icmpv4_hdr *icmph_p = - (struct libnet_icmpv4_hdr *)(buf + ip_hl); + (struct libnet_icmpv4_hdr *)(buf + ip_hl + off); icmph_p->icmp_sum = 0; if (is_ipv6) { @@ -216,7 +273,7 @@ case IPPROTO_IGMP: { struct libnet_igmp_hdr *igmph_p = - (struct libnet_igmp_hdr *)(buf + ip_hl); + (struct libnet_igmp_hdr *)(buf + ip_hl + off); igmph_p->igmp_sum = 0; sum = libnet_in_cksum((u_int16_t *)igmph_p, len);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200608012026.k71KQ4Cl038045>