summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam Roberts <vieuxtech@gmail.com>2010-03-04 16:18:58 -0800
committerSam Roberts <vieuxtech@gmail.com>2010-03-04 16:18:58 -0800
commitb284eda57b691db7384e128a78871ce98f99c159 (patch)
tree234d3586f6690428e3e74dd65b270851ee5c4eb2
parent657246088b53891fd86c624b9f690c7723c28618 (diff)
downloadlibnet-b284eda57b691db7384e128a78871ce98f99c159.tar.gz
libnet_do_checksum(), despite being "internal", is used by external code.
libnet needs to maintain backwards API compatibility, tcpsic from the isic package is an example of a binary failing when calling the new API with the old arguments.
-rw-r--r--libnet/include/libnet/libnet-functions.h27
-rw-r--r--libnet/src/libnet_checksum.c19
-rw-r--r--libnet/src/libnet_pblock.c2
3 files changed, 44 insertions, 4 deletions
diff --git a/libnet/include/libnet/libnet-functions.h b/libnet/include/libnet/libnet-functions.h
index 47efe08..3d81d43 100644
--- a/libnet/include/libnet/libnet-functions.h
+++ b/libnet/include/libnet/libnet-functions.h
@@ -2147,10 +2147,33 @@ int
libnet_close_link(libnet_t *l);
/*
- * [Internal]
+ * [Internal]
+ * THIS FUNCTION IS BROKEN. IT WILL SEGFAULT OR CORRUPT MEMORY, OR JUST SILENTLY DO THE
+ * WRONG THING IF NOT CALLED CORRECTLY, AND CALLING IT CORRECTLY IS UNDOCUMENTED, AND
+ * ALMOST IMPOSSIBLE. YOU HAVE BEEN WARNED.
+ */
+int
+libnet_do_checksum(libnet_t *l, uint8_t *iphdr, int protocol, int h_len);
+
+/* Calculate internet checksums.
+ *
+ * IP (TCP, UDP, IGMP, ICMP, etc...) checksums usually need information from
+ * the IP header to construct the "pseudo header", this function takes a
+ * pointer to that header, the buffer boundaries, the "h_len" (see pblock_t for
+ * a description, it is increasinly unused, though, and I'm trying to remove it
+ * altogether), and the protocol number for the protocol that is to be
+ * checksummed.
+ *
+ * Finding that protocol requires that the IP header be well-formed... so this
+ * won't work well for invalid packets. But then, what is the valid checksum
+ * for a valid packet, anyhow?
+ *
+ * This doesn't work well for non-inet checksums, sorry, that's an original design
+ * flaw. pblock_t needs a pointer in it, to a packet assembly function that can be
+ * called at runtime to do assembly and checksumming.
*/
int
-libnet_do_checksum(libnet_t *l, uint8_t *iphdr, int protocol, int h_len, const uint8_t *beg, const uint8_t * end);
+libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int protocol, int h_len, const uint8_t *beg, const uint8_t * end);
/*
* [Internal]
diff --git a/libnet/src/libnet_checksum.c b/libnet/src/libnet_checksum.c
index de1cda0..fcbde5b 100644
--- a/libnet/src/libnet_checksum.c
+++ b/libnet/src/libnet_checksum.c
@@ -141,6 +141,23 @@ static int check_ip_payload_size(libnet_t*l, const uint8_t *iphdr, int ip_hl, in
return 0;
}
+
+/*
+ * For backwards binary compatibility. The calculations done here can easily
+ * result in buffer overreads and overwrites. You have been warned. And no, it
+ * is not possible to fix, the API contains no information on the buffer's
+ * boundary. libnet itself calls the safe function, libnet_inet_checksum(). So
+ * should you.
+ */
+int
+libnet_do_checksum(libnet_t *l, uint8_t *iphdr, int protocol, int h_len)
+{
+ return libnet_inet_checksum(l, iphdr, protocol, h_len,
+ iphdr, iphdr + LIBNET_IPV4_H + h_len
+ );
+}
+
+
#define CHECK_IP_PAYLOAD_SIZE() do { \
int e=check_ip_payload_size(l,iphdr,ip_hl, h_len, end, __func__);\
if(e) return e;\
@@ -155,7 +172,7 @@ static int check_ip_payload_size(libnet_t*l, const uint8_t *iphdr, int ip_hl, in
* len is the h_len from "q"
*/
int
-libnet_do_checksum(libnet_t *l, uint8_t *iphdr, int protocol, int h_len, const uint8_t *beg, const uint8_t * end)
+libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int protocol, int h_len, const uint8_t *beg, const uint8_t * end)
{
/* will need to update this for ipv6 at some point */
struct libnet_ipv4_hdr *iph_p = (struct libnet_ipv4_hdr *)iphdr;
diff --git a/libnet/src/libnet_pblock.c b/libnet/src/libnet_pblock.c
index 7218f21..0afb969 100644
--- a/libnet/src/libnet_pblock.c
+++ b/libnet/src/libnet_pblock.c
@@ -501,7 +501,7 @@ libnet_pblock_coalesce(libnet_t *l, uint8_t **packet, uint32_t *size)
q->ptag, libnet_diag_dump_pblock_type(q->type),
ip_offset);
#endif
- c = libnet_do_checksum(l, iph,
+ c = libnet_inet_checksum(l, iph,
libnet_pblock_p2p(q->type), q->h_len,
beg, end);
if (c == -1)