Hi,

Sorry for the late reply.

Stefanos Harhalakis wrote:
> Does the attached patch work?
Νο,

0x00007f7b17504c82 in libnet_do_checksum (l=0x604010, buf=0xb8 <Address
0xb8 out of bounds>, protocol=1, len=32) at libnet_checksum.c:129
129         if (iph_p && iph_p->ip_v == 6)

(gdb) bt
#0  0x00007f7b17504c82 in libnet_do_checksum (l=0x604010, buf=0xb8
<Address 0xb8 out of bounds>, protocol=1, len=32) at libnet_checksum.c:129
#1  0x00007f7b17507283 in libnet_pblock_coalesce (l=0x604010,
packet=0x7fffffffbd28, size=0x7fffffffbd34) at libnet_pblock.c:393
#2  0x00007f7b17508738 in libnet_write (l=0x604010) at libnet_write.c:59

Attached is a patch I made that fixes the problem (and also includes
your diff).

Not sure if libnet_pblock_record_ip_offset() is part of the ABI though.
It seems like it is (and hence the patch would be inappropriate for a
stable upload and a internal-only implementation of the function should
be made esp. for this bug) but OTOH, you didn't bump the SONAME with
1.1.4. Perhaps that's a bug of its own?

> If not I'd like to have a test case (either a sample program or step-by-step 
> instructions) in order to reproduce the bug. Just installing heartbeat isn't 
> enough since IPv6Addr gives:
> 
> # ./IPv6addr 2000::1 start
> IPv6addr[16323]: ERROR:  Generic error
> ERROR:  Generic error
> 
> (even with 1.1.4-2)
You should probably configure an interface with e.g. 2000::1/64 address
and then try IPv6addr with 2000:10/64.

Thanks,
Faidon
--- a/src/libnet_build_ip.c
+++ b/src/libnet_build_ip.c
@@ -238,7 +238,7 @@ u_int8_t *payload, u_int32_t payload_s, 
      * 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:
@@ -323,7 +323,7 @@ libnet_autobuild_ipv4(u_int16_t len, u_i
      * 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:
@@ -520,8 +520,12 @@ u_int8_t *payload, u_int32_t payload_s, 
     }
 
     /* 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);
--- a/src/libnet_pblock.c
+++ b/src/libnet_pblock.c
@@ -38,6 +38,7 @@
 #else
 #include "../include/win32/libnet.h"
 #endif
+#include <assert.h>
 
 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 @@ 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 || p->type == LIBNET_PBLOCK_IPV6_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;
 }
 
 
--- a/include/libnet/libnet-functions.h
+++ b/include/libnet/libnet-functions.h
@@ -2077,7 +2077,7 @@ u_int8_t type);
   * It updates the ip_pos field (referer) of each subsequent 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] 

Reply via email to