From 14f67cc09cf7c98a871a5e07d699a0d57b2d7747 Mon Sep 17 00:00:00 2001 From: Sam Roberts Date: Fri, 6 Mar 2009 12:29:41 -0800 Subject: Bug fixes and reproduction code for ip_offset accounting problem in libnet_build_ipv4 What happens is the ip_offset doesn't get correctly updated, and the checksum is written into invalid memory. Depending on your architecture, and the location of invalid memory, you might segv, silently produce packets with bad checksums or the checksum overwriting some other part of the header, or corrupt glib's internal alloc data structures. See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=418975#47 for more information. --- .gitignore | 1 + libnet/include/libnet/libnet-functions.h | 5 +- libnet/include/libnet/libnet-structures.h | 15 +- libnet/sample/Makefile.am | 3 +- libnet/sample/test_ipv4.c | 165 ++++++++++++++++++++ libnet/src/libnet_build_ip.c | 47 +++++- libnet/src/libnet_init.c | 1 + libnet/src/libnet_pblock.c | 18 ++- unmerged/bug-418975.patch | 243 ------------------------------ unmerged/test_ipv4.c | 165 -------------------- 10 files changed, 238 insertions(+), 425 deletions(-) create mode 100644 libnet/sample/test_ipv4.c delete mode 100644 unmerged/bug-418975.patch delete mode 100644 unmerged/test_ipv4.c diff --git a/.gitignore b/.gitignore index 3008a76..dece2c8 100644 --- a/.gitignore +++ b/.gitignore @@ -52,6 +52,7 @@ libnet/sample/stp libnet/sample/synflood libnet/sample/synflood6 libnet/sample/synflood6_frag +libnet/sample/test_ipv4 libnet/sample/tcp1 libnet/sample/tcp2 libnet/sample/tftp diff --git a/libnet/include/libnet/libnet-functions.h b/libnet/include/libnet/libnet-functions.h index c4fe599..99b1139 100644 --- a/libnet/include/libnet/libnet-functions.h +++ b/libnet/include/libnet/libnet-functions.h @@ -794,6 +794,7 @@ u_int8_t *payload, u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag); /** * Builds a version 4 RFC 791 Internet Protocol (IP) header. * @param len total length of the IP packet including all subsequent data + * FIXME There is no reason this can't be calculated if zero is passed. * @param tos type of service bits * @param id IP identification number * @param frag fragmentation bits and offset @@ -2080,10 +2081,10 @@ u_int8_t type); * Function updates referer used to compute the checksum. All * pblock need to know where is their referer (ie IP header). * So, this function is called each time a new IP header is inserted. - * It updates the ip_pos field (referer) of each subsequent pblock. + * It updates the ip_offset field (referer) of each previous pblock. */ void -libnet_pblock_record_ip_offset(libnet_t *l, u_int32_t offset); +libnet_pblock_record_ip_offset(libnet_t *l, libnet_pblock_t *p); /* * [Internal] diff --git a/libnet/include/libnet/libnet-structures.h b/libnet/include/libnet/libnet-structures.h index 38aff5d..eb7de76 100644 --- a/libnet/include/libnet/libnet-structures.h +++ b/libnet/include/libnet/libnet-structures.h @@ -79,8 +79,19 @@ struct libnet_protocol_block u_int8_t *buf; /* protocol buffer */ u_int32_t b_len; /* length of buf */ u_int16_t h_len; /* header length (for checksumming) */ - u_int32_t ip_offset; /* offset to IP header for csums */ - u_int32_t copied; /* bytes copied */ + /* Unused for IPV4_H block types. + * For protocols that sit on top of IP, it should be the the amount of + * buf that is the header, and will be included in the checksum. + */ + u_int32_t ip_offset; /* offset from end of pkt to beginning of IP header for csums */ + /* Unused for IPV4_H block types. + * For protocols that sit on top of IP (UDP, ICMP, ...), they often + * include some information from the IP header (in the form of a "pseudo + * header") in their own checksum calculation. To build that + * pseudo-header, thet need to find the real header. + */ + u_int32_t copied; /* bytes copied - the amount of data copied into buf */ + /* Used and updated by libnet_pblock_append(). */ u_int8_t type; /* type of pblock */ /* this needs to be updated every time a new packet builder is added */ #define LIBNET_PBLOCK_ARP_H 0x01 /* ARP header */ diff --git a/libnet/sample/Makefile.am b/libnet/sample/Makefile.am index 05cccbb..3186f5d 100644 --- a/libnet/sample/Makefile.am +++ b/libnet/sample/Makefile.am @@ -14,7 +14,7 @@ noinst_PROGRAMS = arp cdp dhcp_discover get_addr icmp_timestamp icmp_unreach \ smurf dot1x dns rpc_tcp rpc_udp mpls icmp_timeexceed \ fddi_tcp1 fddi_tcp2 tring_tcp1 tring_tcp2 icmp_redirect \ bgp4_hdr bgp4_open bgp4_update bgp4_notification gre \ - synflood6_frag tftp ip_link ip_raw sebek + synflood6_frag tftp ip_link ip_raw sebek test_ipv4 arp_SOURCES = arp.c cdp_SOURCES = cdp.c @@ -59,5 +59,6 @@ gre_SOURCES = gre.c ip_raw_SOURCES = ip_raw.c ip_link_SOURCES = ip_link.c sebek_SOURCES = sebek.c +test_ipv4_SOURCES = test_ipv4.c LDADD = $(top_srcdir)/src/libnet.la diff --git a/libnet/sample/test_ipv4.c b/libnet/sample/test_ipv4.c new file mode 100644 index 0000000..cf1646b --- /dev/null +++ b/libnet/sample/test_ipv4.c @@ -0,0 +1,165 @@ +/* + * Regression test for bugs in ipv4 ip_offset and h_len handling, such as + * http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=418975 + * + * Copyright (c) 2009 Sam Roberts + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ +#if (HAVE_CONFIG_H) +#include "../include/config.h" +#endif +#include "./libnet_test.h" + +#include + +static void print_pblocks(libnet_t* l) +{ + libnet_pblock_t* p = l->protocol_blocks; + + while(p) { + /* h_len is header length for checksumming? "chksum length"? */ + printf(" tag %d flags %d type %20s/%#x buf %p b_len %2u h_len %2u ip_offset %2u, copied %2u\n", + p->ptag, p->flags, + libnet_diag_dump_pblock_type(p->type), p->type, + p->buf, p->b_len, p->h_len, p->ip_offset, p->copied); + p = p->next; + } + printf(" link_offset %d aligner %d total_size %u nblocks %d\n", + l->link_offset, l->aligner, l->total_size, l->n_pblocks); + +} + +static int build_ipv4(libnet_t* l, libnet_ptag_t ip_ptag, int payload_s) +{ + u_long src_ip = 0xf101f1f1; + u_long dst_ip = 0xf102f1f1; + u_int8_t* payload = malloc(payload_s); + assert(payload); + memset(payload, '\x00', payload_s); + + ip_ptag = libnet_build_ipv4( + LIBNET_IPV4_H + payload_s, /* length */ + 0, /* TOS */ + 0xbbbb, /* IP ID */ + 0, /* IP Frag */ + 0xcc, /* TTL */ + IPPROTO_UDP, /* protocol */ + 0, /* checksum */ + src_ip, /* source IP */ + dst_ip, /* destination IP */ + payload, /* payload */ + payload_s, /* payload size */ + l, /* libnet handle */ + ip_ptag); /* libnet id */ + + assert(ip_ptag > 0); + + free(payload); + + return ip_ptag; +} + +int +main(int argc, char *argv[]) +{ + libnet_t *l; + int r; + char *device = "eth0"; + u_int8_t enet_src[6] = {0x11, 0x11, 0x11, 0x11, 0x11, 0x11}; + u_int8_t enet_dst[6] = {0x22, 0x22, 0x22, 0x22, 0x22, 0x22}; + char errbuf[LIBNET_ERRBUF_SIZE]; + libnet_ptag_t ip_ptag = 0; + libnet_ptag_t eth_ptag = 0; + int pkt1_payload = 10; + u_int8_t* pkt1 = NULL; + u_int32_t pkt1_sz = 0; + struct libnet_ipv4_hdr* h1; + int pkt2_payload = 2; + u_int8_t* pkt2 = NULL; + u_int32_t pkt2_sz = 0; + struct libnet_ipv4_hdr* h2; + + + + l = libnet_init( LIBNET_LINK, device, errbuf); + + assert(l); + + /* Bug is triggered when rebuilding the ipv4 blocks with smaller payload. + * If change in payload size is larger than 20 (iph) + 14 (ether) + + * aligner, it will cause checksum to be written into the unallocated + * memory before the packet, possibly corrupting glib's memory allocation + * structures. + */ + + printf("Packet 1:\n"); + + ip_ptag = build_ipv4(l, ip_ptag, pkt1_payload); + + eth_ptag = libnet_build_ethernet( + enet_dst, /* ethernet destination */ + enet_src, /* ethernet source */ + ETHERTYPE_IP, /* protocol type */ + NULL, /* payload */ + 0, /* payload size */ + l, /* libnet handle */ + 0); /* libnet id */ + assert(eth_ptag > 0); + + r = libnet_pblock_coalesce(l, &pkt1, &pkt1_sz); + assert(r >= 0); + + print_pblocks(l); + + libnet_diag_dump_hex(pkt1, 14, 0, stdout); + libnet_diag_dump_hex(pkt1+14, pkt1_sz-14, 0, stdout); + + printf("Packet 2:\n"); + + ip_ptag = build_ipv4(l, ip_ptag, pkt2_payload); + + r = libnet_pblock_coalesce(l, &pkt2, &pkt2_sz); + assert(r >= 0); + + print_pblocks(l); + + libnet_diag_dump_hex(pkt2, 14, 0, stdout); + libnet_diag_dump_hex(pkt2+14, pkt2_sz-14, 0, stdout); + + /* Packets should differ only in the total length and cksum. */ + h1 = (struct libnet_ipv4_hdr*) (pkt1+14); + h2 = (struct libnet_ipv4_hdr*) (pkt2+14); + + assert(h1->ip_len == htons(20+pkt1_payload)); + assert(h2->ip_len == htons(20+pkt2_payload)); + + h1->ip_len = h2->ip_len = 0x5555; + h1->ip_sum = h2->ip_sum = 0x6666; + + assert(memcmp(pkt1, pkt2, 14 + 20) == 0); + + return (EXIT_SUCCESS); +} + diff --git a/libnet/src/libnet_build_ip.c b/libnet/src/libnet_build_ip.c index 3d3675b..e0e760d 100644 --- a/libnet/src/libnet_build_ip.c +++ b/libnet/src/libnet_build_ip.c @@ -45,7 +45,6 @@ libnet_build_ipv4(u_int16_t len, u_int8_t tos, u_int16_t id, u_int16_t frag, u_int8_t ttl, u_int8_t prot, u_int16_t sum, u_int32_t src, u_int32_t dst, u_int8_t *payload, u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag) { - int offset; u_int32_t h, n, i, j; libnet_pblock_t *p, *p_data, *p_temp; struct libnet_ipv4_hdr ip_hdr; @@ -58,9 +57,12 @@ u_int8_t *payload, u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag) n = LIBNET_IPV4_H; /* size of memory block */ h = len; /* header length */ + // WRONG - this is total len of ip packet, and is put into the IP header ptag_data = 0; /* used if options are present */ + // WRONG - is used if there is ipv4 payload if (h + payload_s > IP_MAXPACKET) + // WRONG - h is the total length, it already includes payload_s { snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, "%s(): IP packet too large\n", __func__); @@ -97,6 +99,9 @@ u_int8_t *payload, u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag) ip_hdr.ip_hl += j; } } + // Note that p->h_len is not adjusted. This seems a bug, but it is because + // it is not used! libnet_do_checksum() is passed the h_len (as `len'), + // but for IPPROTO_IP it is ignored in favor of the ip_hl. ip_hdr.ip_tos = tos; /* IP tos */ ip_hdr.ip_len = htons(h); /* total length */ @@ -123,7 +128,10 @@ u_int8_t *payload, u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag) } /* find and set the appropriate ptag, or else use the default of 0 */ - offset = payload_s; + /* When updating the ipv4 block, we need to find the data block, and + * adjust our ip_offset if the new payload size is different from what + * it used to be. + */ if (ptag_hold && p->prev) { p_temp = p->prev; @@ -136,9 +144,13 @@ u_int8_t *payload, u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag) if (p_temp->type == LIBNET_PBLOCK_IPDATA) { + int offset = payload_s; + ptag_data = p_temp->ptag; offset -= p_temp->b_len; - p->h_len += offset; + //p->h_len += offset; + // WRONG h_len is unused for checksum for IPv4, and even if it was used, + // the h_len doesn't depend on the payload size. } else { @@ -157,6 +169,16 @@ u_int8_t *payload, u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag) if (payload && payload_s) { /* update ptag_data with the new payload */ + // on create: + // b_len = payload_s + // l->total_size += b_len + // h_len = 0 + // on update: + // b_len = payload_s + // h_len += + // increments if if b_len goes up, down if it goes down + // in either case: + // copied = 0 p_data = libnet_pblock_probe(l, ptag_data, payload_s, LIBNET_PBLOCK_IPDATA); if (p_data == NULL) @@ -171,6 +193,7 @@ u_int8_t *payload, u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag) if (ptag_data == LIBNET_PTAG_INITIALIZER) { + // IPDATA's h_len gets set to payload_s in both branches if (p_data->prev->type == LIBNET_PBLOCK_IPV4_H) { libnet_pblock_update(l, p_data, payload_s, @@ -180,6 +203,10 @@ u_int8_t *payload, u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag) } else { + // SR - I'm not sure how to reach this code. Maybe if the first + // time we added an ipv4 block, there was no payload, but when + // we modify the block the next time, we have payload? + /* update without setting this as the final pblock */ p_data->type = LIBNET_PBLOCK_IPDATA; p_data->ptag = ++(l->ptag_state); @@ -187,6 +214,7 @@ u_int8_t *payload, u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag) /* Adjust h_len for checksum. */ p->h_len += payload_s; + // WRONG - IPV4 checksum doesn't include the payload_s. /* data was added after the initial construction */ for (p_temp = l->protocol_blocks; @@ -238,7 +266,16 @@ u_int8_t *payload, u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag) * FREDRAYNAL: as we insert a new IP header, all checksums for headers * placed after this one will refer to here. */ - libnet_pblock_record_ip_offset(l, l->total_size); + // WRONG - the total_size when updating the pblock will include the link layer + // WRONG - it isn't called after adding options, so will be wrong by the amount of ip options + // WRONG - it updates the wrong protocol blocks: + // - the first time it runs we set the ip offsets for p (ipv4), and + // ipdata to the total size of just the ip portion + // - the next time, it starts at end, which is the ethernet block, and + // updates everything up to but not including the ipv4 block to the total size, which means it + // changes just the ethernet block, and the offset it sets is the total size including the ethernet + // header.... WTF? + libnet_pblock_record_ip_offset(l, p); return (ptag); bad: @@ -323,7 +360,7 @@ libnet_autobuild_ipv4(u_int16_t len, u_int8_t prot, u_int32_t dst, libnet_t *l) * FREDRAYNAL: as we insert a new IP header, all checksums for headers * placed after this one will refer to here. */ - libnet_pblock_record_ip_offset(l, l->total_size); + libnet_pblock_record_ip_offset(l, p); return (ptag); bad: diff --git a/libnet/src/libnet_init.c b/libnet/src/libnet_init.c index 976b44c..58f4df1 100644 --- a/libnet/src/libnet_init.c +++ b/libnet/src/libnet_init.c @@ -250,6 +250,7 @@ libnet_getpbuf_size(libnet_t *l, libnet_ptag_t ptag) u_int32_t libnet_getpacket_size(libnet_t *l) { + // Why doesn't this return l->total_size? libnet_pblock_t *p; u_int32_t n; diff --git a/libnet/src/libnet_pblock.c b/libnet/src/libnet_pblock.c index 5e35aa5..b213b1d 100644 --- a/libnet/src/libnet_pblock.c +++ b/libnet/src/libnet_pblock.c @@ -38,6 +38,7 @@ #else #include "../include/win32/libnet.h" #endif +#include libnet_pblock_t * libnet_pblock_probe(libnet_t *l, libnet_ptag_t ptag, u_int32_t n, u_int8_t type) @@ -500,15 +501,18 @@ libnet_pblock_p2p(u_int8_t type) } void -libnet_pblock_record_ip_offset(libnet_t *l, u_int32_t offset) +libnet_pblock_record_ip_offset(libnet_t *l, libnet_pblock_t *p) { - libnet_pblock_t *p = l->pblock_end; + libnet_pblock_t *c; + u_int32_t ip_offset = 0; - do - { - p->ip_offset = offset; - p = p->prev; - } while (p && p->type != LIBNET_PBLOCK_IPV4_H); + assert(p->type == LIBNET_PBLOCK_IPV4_H); + + for(c = p; c; c = c->prev) + ip_offset += c->b_len; + + for(c = p; c; c = c->prev) + c->ip_offset = ip_offset; } diff --git a/unmerged/bug-418975.patch b/unmerged/bug-418975.patch deleted file mode 100644 index 7376070..0000000 --- a/unmerged/bug-418975.patch +++ /dev/null @@ -1,243 +0,0 @@ -Index: src/libnet_init.c -=================================================================== ---- src/libnet_init.c (revision 374) -+++ src/libnet_init.c (working copy) -@@ -250,6 +250,7 @@ - u_int32_t - libnet_getpacket_size(libnet_t *l) - { -+ // Why doesn't this return l->total_size? - libnet_pblock_t *p; - u_int32_t n; - -Index: src/libnet_build_ip.c -=================================================================== ---- src/libnet_build_ip.c (revision 374) -+++ src/libnet_build_ip.c (working copy) -@@ -45,7 +45,6 @@ - u_int8_t ttl, u_int8_t prot, u_int16_t sum, u_int32_t src, u_int32_t dst, - u_int8_t *payload, u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag) - { -- int offset; - u_int32_t h, n, i, j; - libnet_pblock_t *p, *p_data, *p_temp; - struct libnet_ipv4_hdr ip_hdr; -@@ -58,9 +57,12 @@ - - n = LIBNET_IPV4_H; /* size of memory block */ - h = len; /* header length */ -+ // WRONG - this is total len of ip packet, and is put into the IP header - ptag_data = 0; /* used if options are present */ -+ // WRONG - is used if there is ipv4 payload - - if (h + payload_s > IP_MAXPACKET) -+ // WRONG - h is the total length, it already includes payload_s - { - snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, - "%s(): IP packet too large\n", __func__); -@@ -97,6 +99,9 @@ - ip_hdr.ip_hl += j; - } - } -+ // Note that p->h_len is not adjusted. This seems a bug, but it is because -+ // it is not used! libnet_do_checksum() is passed the h_len (as `len'), -+ // but for IPPROTO_IP it is ignored in favor of the ip_hl. - - ip_hdr.ip_tos = tos; /* IP tos */ - ip_hdr.ip_len = htons(h); /* total length */ -@@ -123,7 +128,10 @@ - } - - /* find and set the appropriate ptag, or else use the default of 0 */ -- offset = payload_s; -+ /* When updating the ipv4 block, we need to find the data block, and -+ * adjust our ip_offset if the new payload size is different from what -+ * it used to be. -+ */ - if (ptag_hold && p->prev) - { - p_temp = p->prev; -@@ -136,9 +144,13 @@ - - if (p_temp->type == LIBNET_PBLOCK_IPDATA) - { -+ int offset = payload_s; -+ - ptag_data = p_temp->ptag; - offset -= p_temp->b_len; -- p->h_len += offset; -+ //p->h_len += offset; -+ // WRONG h_len is unused for checksum for IPv4, and even if it was used, -+ // the h_len doesn't depend on the payload size. - } - else - { -@@ -157,6 +169,16 @@ - if (payload && payload_s) - { - /* update ptag_data with the new payload */ -+ // on create: -+ // b_len = payload_s -+ // l->total_size += b_len -+ // h_len = 0 -+ // on update: -+ // b_len = payload_s -+ // h_len += -+ // increments if if b_len goes up, down if it goes down -+ // in either case: -+ // copied = 0 - p_data = libnet_pblock_probe(l, ptag_data, payload_s, - LIBNET_PBLOCK_IPDATA); - if (p_data == NULL) -@@ -171,6 +193,7 @@ - - if (ptag_data == LIBNET_PTAG_INITIALIZER) - { -+ // IPDATA's h_len gets set to payload_s in both branches - if (p_data->prev->type == LIBNET_PBLOCK_IPV4_H) - { - libnet_pblock_update(l, p_data, payload_s, -@@ -180,6 +203,10 @@ - } - else - { -+ // SR - I'm not sure how to reach this code. Maybe if the first -+ // time we added an ipv4 block, there was no payload, but when -+ // we modify the block the next time, we have payload? -+ - /* update without setting this as the final pblock */ - p_data->type = LIBNET_PBLOCK_IPDATA; - p_data->ptag = ++(l->ptag_state); -@@ -187,6 +214,7 @@ - - /* Adjust h_len for checksum. */ - p->h_len += payload_s; -+ // WRONG - IPV4 checksum doesn't include the payload_s. - - /* data was added after the initial construction */ - for (p_temp = l->protocol_blocks; -@@ -238,7 +266,16 @@ - * FREDRAYNAL: as we insert a new IP header, all checksums for headers - * placed after this one will refer to here. - */ -- libnet_pblock_record_ip_offset(l, l->total_size); -+ // WRONG - the total_size when updating the pblock will include the link layer -+ // WRONG - it isn't called after adding options, so will be wrong by the amount of ip options -+ // WRONG - it updates the wrong protocol blocks: -+ // - the first time it runs we set the ip offsets for p (ipv4), and -+ // ipdata to the total size of just the ip portion -+ // - the next time, it starts at end, which is the ethernet block, and -+ // updates everything up to but not including the ipv4 block to the total size, which means it -+ // changes just the ethernet block, and the offset it sets is the total size including the ethernet -+ // header.... WTF? -+ libnet_pblock_record_ip_offset(l, p); - - return (ptag); - bad: -@@ -323,7 +360,7 @@ - * FREDRAYNAL: as we insert a new IP header, all checksums for headers - * placed after this one will refer to here. - */ -- libnet_pblock_record_ip_offset(l, l->total_size); -+ libnet_pblock_record_ip_offset(l, p); - return (ptag); - - bad: -@@ -407,7 +444,7 @@ - } - - /* append padding */ -- n = libnet_pblock_append(l, p, "\0\0\0", adj_size - options_s); -+ n = libnet_pblock_append(l, p, (u_int8_t*) "\0\0\0", adj_size - options_s); - if (n == -1) - { - goto bad; -Index: src/libnet_pblock.c -=================================================================== ---- src/libnet_pblock.c (revision 374) -+++ src/libnet_pblock.c (working copy) -@@ -38,6 +38,7 @@ - #else - #include "../include/win32/libnet.h" - #endif -+#include - - libnet_pblock_t * - libnet_pblock_probe(libnet_t *l, libnet_ptag_t ptag, u_int32_t n, u_int8_t type) -@@ -496,15 +497,18 @@ - } - - void --libnet_pblock_record_ip_offset(libnet_t *l, u_int32_t offset) -+libnet_pblock_record_ip_offset(libnet_t *l, libnet_pblock_t *p) - { -- libnet_pblock_t *p = l->pblock_end; -+ libnet_pblock_t *c; -+ u_int32_t ip_offset = 0; - -- do -- { -- p->ip_offset = offset; -- p = p->prev; -- } while (p && p->type != LIBNET_PBLOCK_IPV4_H); -+ assert(p->type == LIBNET_PBLOCK_IPV4_H); -+ -+ for(c = p; c; c = c->prev) -+ ip_offset += c->b_len; -+ -+ for(c = p; c; c = c->prev) -+ c->ip_offset = ip_offset; - } - - -Index: include/libnet/libnet-structures.h -=================================================================== ---- include/libnet/libnet-structures.h (revision 374) -+++ include/libnet/libnet-structures.h (working copy) -@@ -79,8 +79,19 @@ - u_int8_t *buf; /* protocol buffer */ - u_int32_t b_len; /* length of buf */ - u_int16_t h_len; /* header length (for checksumming) */ -- u_int32_t ip_offset; /* offset to IP header for csums */ -- u_int32_t copied; /* bytes copied */ -+ /* Unused for IPV4_H block types. -+ * For protocols that sit on top of IP, it should be the the amount of -+ * buf that is the header, and will be included in the checksum. -+ */ -+ u_int32_t ip_offset; /* offset from end of pkt to beginning of IP header for csums */ -+ /* Unused for IPV4_H block types. -+ * For protocols that sit on top of IP (UDP, ICMP, ...), they often -+ * include some information from the IP header (in the form of a "pseudo -+ * header") in their own checksum calculation. To build that -+ * pseudo-header, thet need to find the real header. -+ */ -+ u_int32_t copied; /* bytes copied - the amount of data copied into buf */ -+ /* Used and updated by libnet_pblock_append(). */ - u_int8_t type; /* type of pblock */ - /* this needs to be updated every time a new packet builder is added */ - #define LIBNET_PBLOCK_ARP_H 0x01 /* ARP header */ -Index: include/libnet/libnet-functions.h -=================================================================== ---- include/libnet/libnet-functions.h (revision 374) -+++ include/libnet/libnet-functions.h (working copy) -@@ -794,6 +794,7 @@ - /** - * Builds a version 4 RFC 791 Internet Protocol (IP) header. - * @param len total length of the IP packet including all subsequent data -+ * FIXME There is no reason this can't be calculated if zero is passed. - * @param tos type of service bits - * @param id IP identification number - * @param frag fragmentation bits and offset -@@ -2074,10 +2075,10 @@ - * Function updates referer used to compute the checksum. All - * pblock need to know where is their referer (ie IP header). - * So, this function is called each time a new IP header is inserted. -- * It updates the ip_pos field (referer) of each subsequent pblock. -+ * It updates the ip_offset field (referer) of each previous pblock. - */ - void --libnet_pblock_record_ip_offset(libnet_t *l, u_int32_t offset); -+libnet_pblock_record_ip_offset(libnet_t *l, libnet_pblock_t *p); - - /* - * [Internal] diff --git a/unmerged/test_ipv4.c b/unmerged/test_ipv4.c deleted file mode 100644 index cf1646b..0000000 --- a/unmerged/test_ipv4.c +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Regression test for bugs in ipv4 ip_offset and h_len handling, such as - * http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=418975 - * - * Copyright (c) 2009 Sam Roberts - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ -#if (HAVE_CONFIG_H) -#include "../include/config.h" -#endif -#include "./libnet_test.h" - -#include - -static void print_pblocks(libnet_t* l) -{ - libnet_pblock_t* p = l->protocol_blocks; - - while(p) { - /* h_len is header length for checksumming? "chksum length"? */ - printf(" tag %d flags %d type %20s/%#x buf %p b_len %2u h_len %2u ip_offset %2u, copied %2u\n", - p->ptag, p->flags, - libnet_diag_dump_pblock_type(p->type), p->type, - p->buf, p->b_len, p->h_len, p->ip_offset, p->copied); - p = p->next; - } - printf(" link_offset %d aligner %d total_size %u nblocks %d\n", - l->link_offset, l->aligner, l->total_size, l->n_pblocks); - -} - -static int build_ipv4(libnet_t* l, libnet_ptag_t ip_ptag, int payload_s) -{ - u_long src_ip = 0xf101f1f1; - u_long dst_ip = 0xf102f1f1; - u_int8_t* payload = malloc(payload_s); - assert(payload); - memset(payload, '\x00', payload_s); - - ip_ptag = libnet_build_ipv4( - LIBNET_IPV4_H + payload_s, /* length */ - 0, /* TOS */ - 0xbbbb, /* IP ID */ - 0, /* IP Frag */ - 0xcc, /* TTL */ - IPPROTO_UDP, /* protocol */ - 0, /* checksum */ - src_ip, /* source IP */ - dst_ip, /* destination IP */ - payload, /* payload */ - payload_s, /* payload size */ - l, /* libnet handle */ - ip_ptag); /* libnet id */ - - assert(ip_ptag > 0); - - free(payload); - - return ip_ptag; -} - -int -main(int argc, char *argv[]) -{ - libnet_t *l; - int r; - char *device = "eth0"; - u_int8_t enet_src[6] = {0x11, 0x11, 0x11, 0x11, 0x11, 0x11}; - u_int8_t enet_dst[6] = {0x22, 0x22, 0x22, 0x22, 0x22, 0x22}; - char errbuf[LIBNET_ERRBUF_SIZE]; - libnet_ptag_t ip_ptag = 0; - libnet_ptag_t eth_ptag = 0; - int pkt1_payload = 10; - u_int8_t* pkt1 = NULL; - u_int32_t pkt1_sz = 0; - struct libnet_ipv4_hdr* h1; - int pkt2_payload = 2; - u_int8_t* pkt2 = NULL; - u_int32_t pkt2_sz = 0; - struct libnet_ipv4_hdr* h2; - - - - l = libnet_init( LIBNET_LINK, device, errbuf); - - assert(l); - - /* Bug is triggered when rebuilding the ipv4 blocks with smaller payload. - * If change in payload size is larger than 20 (iph) + 14 (ether) + - * aligner, it will cause checksum to be written into the unallocated - * memory before the packet, possibly corrupting glib's memory allocation - * structures. - */ - - printf("Packet 1:\n"); - - ip_ptag = build_ipv4(l, ip_ptag, pkt1_payload); - - eth_ptag = libnet_build_ethernet( - enet_dst, /* ethernet destination */ - enet_src, /* ethernet source */ - ETHERTYPE_IP, /* protocol type */ - NULL, /* payload */ - 0, /* payload size */ - l, /* libnet handle */ - 0); /* libnet id */ - assert(eth_ptag > 0); - - r = libnet_pblock_coalesce(l, &pkt1, &pkt1_sz); - assert(r >= 0); - - print_pblocks(l); - - libnet_diag_dump_hex(pkt1, 14, 0, stdout); - libnet_diag_dump_hex(pkt1+14, pkt1_sz-14, 0, stdout); - - printf("Packet 2:\n"); - - ip_ptag = build_ipv4(l, ip_ptag, pkt2_payload); - - r = libnet_pblock_coalesce(l, &pkt2, &pkt2_sz); - assert(r >= 0); - - print_pblocks(l); - - libnet_diag_dump_hex(pkt2, 14, 0, stdout); - libnet_diag_dump_hex(pkt2+14, pkt2_sz-14, 0, stdout); - - /* Packets should differ only in the total length and cksum. */ - h1 = (struct libnet_ipv4_hdr*) (pkt1+14); - h2 = (struct libnet_ipv4_hdr*) (pkt2+14); - - assert(h1->ip_len == htons(20+pkt1_payload)); - assert(h2->ip_len == htons(20+pkt2_payload)); - - h1->ip_len = h2->ip_len = 0x5555; - h1->ip_sum = h2->ip_sum = 0x6666; - - assert(memcmp(pkt1, pkt2, 14 + 20) == 0); - - return (EXIT_SUCCESS); -} - -- cgit v1.2.1 From 2fe8da3a8e01ecc8697e529de5cbba5a502473b5 Mon Sep 17 00:00:00 2001 From: Sam Roberts Date: Mon, 30 Mar 2009 17:57:41 -0700 Subject: Fix for debian bug# 418975, IPv6 wasn't updating ip_offset. See http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=418975 and sample test_ipv6_icmpv4.c for more information, and reproduction. --- libnet/sample/Makefile.am | 3 +- libnet/sample/test_ipv6_icmpv4.c | 123 +++++++++++++++++++++++++++++++++++++++ libnet/src/libnet_build_ip.c | 9 ++- libnet/src/libnet_pblock.c | 2 +- unmerged/test_ipv6_icmpv4.c | 123 --------------------------------------- 5 files changed, 133 insertions(+), 127 deletions(-) create mode 100644 libnet/sample/test_ipv6_icmpv4.c delete mode 100644 unmerged/test_ipv6_icmpv4.c diff --git a/libnet/sample/Makefile.am b/libnet/sample/Makefile.am index 3186f5d..87b76a7 100644 --- a/libnet/sample/Makefile.am +++ b/libnet/sample/Makefile.am @@ -14,7 +14,7 @@ noinst_PROGRAMS = arp cdp dhcp_discover get_addr icmp_timestamp icmp_unreach \ smurf dot1x dns rpc_tcp rpc_udp mpls icmp_timeexceed \ fddi_tcp1 fddi_tcp2 tring_tcp1 tring_tcp2 icmp_redirect \ bgp4_hdr bgp4_open bgp4_update bgp4_notification gre \ - synflood6_frag tftp ip_link ip_raw sebek test_ipv4 + synflood6_frag tftp ip_link ip_raw sebek test_ipv4 test_ipv6_icmpv4 arp_SOURCES = arp.c cdp_SOURCES = cdp.c @@ -60,5 +60,6 @@ ip_raw_SOURCES = ip_raw.c ip_link_SOURCES = ip_link.c sebek_SOURCES = sebek.c test_ipv4_SOURCES = test_ipv4.c +test_ipv6_icmpv4_SOURCES = test_ipv6_icmpv4.c LDADD = $(top_srcdir)/src/libnet.la diff --git a/libnet/sample/test_ipv6_icmpv4.c b/libnet/sample/test_ipv6_icmpv4.c new file mode 100644 index 0000000..b3dcd67 --- /dev/null +++ b/libnet/sample/test_ipv6_icmpv4.c @@ -0,0 +1,123 @@ +/* + * Regression test for bugs such as reported in: + * http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=418975 + * + * Copyright (c) 2009 Sam Roberts + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ +#if (HAVE_CONFIG_H) +#include "../include/config.h" +#endif +#include "./libnet_test.h" + +#include + +#include + +static void print_pblocks(libnet_t* l) +{ + libnet_pblock_t* p = l->protocol_blocks; + + while(p) { + /* h_len is header length for checksumming? "chksum length"? */ + printf(" tag %d flags %d type %20s/%#x buf %p b_len %2u h_len %2u ip_offset %2u, copied %2u\n", + p->ptag, p->flags, + libnet_diag_dump_pblock_type(p->type), p->type, + p->buf, p->b_len, p->h_len, p->ip_offset, p->copied); + p = p->next; + } + printf(" link_offset %d aligner %d total_size %u nblocks %d\n", + l->link_offset, l->aligner, l->total_size, l->n_pblocks); + +} + +int +main(int argc, char *argv[]) +{ + libnet_t *l; + int r; + char *device = "eth0"; + struct libnet_ether_addr *mac_address; + struct in6_addr src_ip; + struct libnet_in6_addr dst_ip; + char errbuf[LIBNET_ERRBUF_SIZE]; + libnet_ptag_t icmp_ptag = 0; + libnet_ptag_t ipv6_ptag = 0; + char payload[24] = { 0 }; + + memset(&src_ip, 0x66, sizeof(src_ip)); + + l = libnet_init( LIBNET_RAW6, device, errbuf); + + assert(l); + + mac_address = libnet_get_hwaddr(l); + assert(mac_address); + + dst_ip = libnet_name2addr6(l, "::1" /* BCAST_ADDR - defined where? */, LIBNET_DONT_RESOLVE); + + memcpy(payload,src_ip.s6_addr,16); + payload[16] = 2; /* 2 for Target Link-layer Address */ + payload[17] = 1; /* The length of the option */ + memcpy(payload+18,mac_address->ether_addr_octet, 6); + + /* 0x2000: RSO */ + icmp_ptag = libnet_build_icmpv4_echo( + 136,0,0,0x2000,0, + (u_int8_t *)payload,sizeof(payload), l, LIBNET_PTAG_INITIALIZER); + assert(icmp_ptag); + + ipv6_ptag = libnet_build_ipv6( + 0, 0, + LIBNET_ICMPV6_H + sizeof(payload), // ICMPV6_H == ICMPV4_H, luckily + IPPROTO_ICMP6, + 255, + *(struct libnet_in6_addr*)&src_ip, + dst_ip, + NULL, 0, + l, 0); + assert(icmp_ptag); + + print_pblocks(l); + + { + u_int8_t* pkt1 = NULL; + u_int32_t pkt1_sz = 0; + r = libnet_pblock_coalesce(l, &pkt1, &pkt1_sz); + assert(r >= 0); + + libnet_diag_dump_hex(pkt1, LIBNET_IPV6_H, 0, stdout); + libnet_diag_dump_hex(pkt1+LIBNET_IPV6_H, pkt1_sz-LIBNET_IPV6_H, 0, stdout); + + free(pkt1); + pkt1 = NULL; + } + + r = libnet_write(l); + assert(r >= 0); + + return (EXIT_SUCCESS); +} + diff --git a/libnet/src/libnet_build_ip.c b/libnet/src/libnet_build_ip.c index e0e760d..c23c296 100644 --- a/libnet/src/libnet_build_ip.c +++ b/libnet/src/libnet_build_ip.c @@ -557,8 +557,13 @@ u_int8_t *payload, u_int32_t payload_s, libnet_t *l, libnet_ptag_t ptag) } /* no checksum for IPv6 */ - return (ptag ? ptag : libnet_pblock_update(l, p, LIBNET_IPV6_H, - LIBNET_PBLOCK_IPV6_H)); + ptag = ptag ? ptag : libnet_pblock_update(l, p, LIBNET_IPV6_H, + LIBNET_PBLOCK_IPV6_H); + + libnet_pblock_record_ip_offset(l, p); + + return ptag; + bad: libnet_pblock_delete(l, p); return (-1); diff --git a/libnet/src/libnet_pblock.c b/libnet/src/libnet_pblock.c index b213b1d..5530c02 100644 --- a/libnet/src/libnet_pblock.c +++ b/libnet/src/libnet_pblock.c @@ -506,7 +506,7 @@ libnet_pblock_record_ip_offset(libnet_t *l, libnet_pblock_t *p) libnet_pblock_t *c; u_int32_t ip_offset = 0; - assert(p->type == LIBNET_PBLOCK_IPV4_H); + assert(p->type == LIBNET_PBLOCK_IPV4_H || p->type == LIBNET_PBLOCK_IPV6_H); for(c = p; c; c = c->prev) ip_offset += c->b_len; diff --git a/unmerged/test_ipv6_icmpv4.c b/unmerged/test_ipv6_icmpv4.c deleted file mode 100644 index b3dcd67..0000000 --- a/unmerged/test_ipv6_icmpv4.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Regression test for bugs such as reported in: - * http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=418975 - * - * Copyright (c) 2009 Sam Roberts - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ -#if (HAVE_CONFIG_H) -#include "../include/config.h" -#endif -#include "./libnet_test.h" - -#include - -#include - -static void print_pblocks(libnet_t* l) -{ - libnet_pblock_t* p = l->protocol_blocks; - - while(p) { - /* h_len is header length for checksumming? "chksum length"? */ - printf(" tag %d flags %d type %20s/%#x buf %p b_len %2u h_len %2u ip_offset %2u, copied %2u\n", - p->ptag, p->flags, - libnet_diag_dump_pblock_type(p->type), p->type, - p->buf, p->b_len, p->h_len, p->ip_offset, p->copied); - p = p->next; - } - printf(" link_offset %d aligner %d total_size %u nblocks %d\n", - l->link_offset, l->aligner, l->total_size, l->n_pblocks); - -} - -int -main(int argc, char *argv[]) -{ - libnet_t *l; - int r; - char *device = "eth0"; - struct libnet_ether_addr *mac_address; - struct in6_addr src_ip; - struct libnet_in6_addr dst_ip; - char errbuf[LIBNET_ERRBUF_SIZE]; - libnet_ptag_t icmp_ptag = 0; - libnet_ptag_t ipv6_ptag = 0; - char payload[24] = { 0 }; - - memset(&src_ip, 0x66, sizeof(src_ip)); - - l = libnet_init( LIBNET_RAW6, device, errbuf); - - assert(l); - - mac_address = libnet_get_hwaddr(l); - assert(mac_address); - - dst_ip = libnet_name2addr6(l, "::1" /* BCAST_ADDR - defined where? */, LIBNET_DONT_RESOLVE); - - memcpy(payload,src_ip.s6_addr,16); - payload[16] = 2; /* 2 for Target Link-layer Address */ - payload[17] = 1; /* The length of the option */ - memcpy(payload+18,mac_address->ether_addr_octet, 6); - - /* 0x2000: RSO */ - icmp_ptag = libnet_build_icmpv4_echo( - 136,0,0,0x2000,0, - (u_int8_t *)payload,sizeof(payload), l, LIBNET_PTAG_INITIALIZER); - assert(icmp_ptag); - - ipv6_ptag = libnet_build_ipv6( - 0, 0, - LIBNET_ICMPV6_H + sizeof(payload), // ICMPV6_H == ICMPV4_H, luckily - IPPROTO_ICMP6, - 255, - *(struct libnet_in6_addr*)&src_ip, - dst_ip, - NULL, 0, - l, 0); - assert(icmp_ptag); - - print_pblocks(l); - - { - u_int8_t* pkt1 = NULL; - u_int32_t pkt1_sz = 0; - r = libnet_pblock_coalesce(l, &pkt1, &pkt1_sz); - assert(r >= 0); - - libnet_diag_dump_hex(pkt1, LIBNET_IPV6_H, 0, stdout); - libnet_diag_dump_hex(pkt1+LIBNET_IPV6_H, pkt1_sz-LIBNET_IPV6_H, 0, stdout); - - free(pkt1); - pkt1 = NULL; - } - - r = libnet_write(l); - assert(r >= 0); - - return (EXIT_SUCCESS); -} - -- cgit v1.2.1 From 633599a72995f8f91ff55758b515e61049fb688a Mon Sep 17 00:00:00 2001 From: Sam Roberts Date: Mon, 30 Mar 2009 17:59:21 -0700 Subject: patch was merged with last commit --- unmerged/ipv6_icmpv4.patch | 32 -------------------------------- 1 file changed, 32 deletions(-) delete mode 100644 unmerged/ipv6_icmpv4.patch diff --git a/unmerged/ipv6_icmpv4.patch b/unmerged/ipv6_icmpv4.patch deleted file mode 100644 index 5b98685..0000000 --- a/unmerged/ipv6_icmpv4.patch +++ /dev/null @@ -1,32 +0,0 @@ -Index: src/libnet_build_ip.c -=================================================================== ---- src/libnet_build_ip.c (revision 382) -+++ src/libnet_build_ip.c (working copy) -@@ -557,8 +557,12 @@ - } - - /* no checksum for IPv6 */ -- return (ptag ? ptag : libnet_pblock_update(l, p, LIBNET_IPV6_H, -- LIBNET_PBLOCK_IPV6_H)); -+ ptag = ptag ? ptag : libnet_pblock_update(l, p, LIBNET_IPV6_H, -+ LIBNET_PBLOCK_IPV6_H); -+ -+ libnet_pblock_record_ip_offset(l, p); -+ -+ return ptag; - bad: - libnet_pblock_delete(l, p); - return (-1); -Index: src/libnet_pblock.c -=================================================================== ---- src/libnet_pblock.c (revision 382) -+++ src/libnet_pblock.c (working copy) -@@ -502,7 +509,7 @@ - libnet_pblock_t *c; - u_int32_t ip_offset = 0; - -- assert(p->type == LIBNET_PBLOCK_IPV4_H); -+ assert(p->type == LIBNET_PBLOCK_IPV4_H || p->type == LIBNET_PBLOCK_IPV6_H); - - for(c = p; c; c = c->prev) - ip_offset += c->b_len; -- cgit v1.2.1