PERFORCE change 102969 for review

Clément Lecigne clem1 at FreeBSD.org
Tue Aug 1 20:26:13 UTC 2006


http://perforce.freebsd.org/chv.cgi?CH=102969

Change 102969 by clem1 at 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 at 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 at FreeBSD.org)
+
+    o   made icmpsicng much faster.
+    o   -w option removed  
+
+ISICNG (v0.01.5) 06/07/21, by Clément Lecigne (clem1 at FreeBSD.org)
+
+    o   tunsicng generates IPv6-over-IPv4 packets.
+
 ISICNG (v0.01.4) 06/07/16, by Clément Lecigne (clem1 at 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);


More information about the p4-projects mailing list