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