version 1.1.1.2, 2013/07/22 11:54:42
|
version 1.1.1.3, 2023/09/27 11:11:38
|
Line 30
|
Line 30
|
* |
* |
*/ |
*/ |
|
|
#if (HAVE_CONFIG_H) | #include "common.h" |
#include "../include/config.h" | |
#endif | |
#if (!(_WIN32) || (__CYGWIN__)) | |
#include "../include/libnet.h" | |
#else | |
#include "../include/win32/libnet.h" | |
#endif | |
|
|
/* FIXME - unit test these - 0 is debian's version, else is -RC1's */ |
|
/* Note about aliasing warning: |
|
* |
|
* http://mail.opensolaris.org/pipermail/tools-gcc/2005-August/000047.html |
|
* |
|
* See RFC 1071, and: |
|
* |
|
* http://mathforum.org/library/drmath/view/54379.html |
|
*/ |
|
#undef DEBIAN |
|
/* Note: len is in bytes, not 16-bit words! */ |
/* Note: len is in bytes, not 16-bit words! */ |
int |
int |
libnet_in_cksum(uint16_t *addr, int len) |
libnet_in_cksum(uint16_t *addr, int len) |
{ |
{ |
int sum; | int sum = 0; |
#ifdef DEBIAN | |
uint16_t last_byte; | |
| |
sum = 0; | |
last_byte = 0; | |
#else | |
union |
union |
{ |
{ |
uint16_t s; |
uint16_t s; |
uint8_t b[2]; |
uint8_t b[2]; |
}pad; | } pad; |
|
|
sum = 0; |
sum = 0; |
#endif |
|
|
|
while (len > 1) |
while (len > 1) |
{ |
{ |
sum += *addr++; |
sum += *addr++; |
len -= 2; |
len -= 2; |
} |
} |
#ifdef DEBIAN | |
if (len == 1) |
if (len == 1) |
{ |
{ |
*(uint8_t *)&last_byte = *(uint8_t *)addr; |
|
sum += last_byte; |
|
#else |
|
if (len == 1) |
|
{ |
|
pad.b[0] = *(uint8_t *)addr; |
pad.b[0] = *(uint8_t *)addr; |
pad.b[1] = 0; |
pad.b[1] = 0; |
sum += pad.s; |
sum += pad.s; |
#endif |
|
} |
} |
|
|
return (sum); |
return (sum); |
Line 133 static int check_ip_payload_size(libnet_t*l, const uin
|
Line 103 static int check_ip_payload_size(libnet_t*l, const uin
|
if((iphdr+ip_hl+h_len) > end) |
if((iphdr+ip_hl+h_len) > end) |
{ |
{ |
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, |
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, |
"%s(): ip payload not inside packet (pktsz %d, iphsz %d, payloadsz %d)\n", func, | "%s(): ip payload not inside packet (pktsz %d, iphsz %d, payloadsz %d)", func, |
(int)(end - iphdr), ip_hl, h_len); |
(int)(end - iphdr), ip_hl, h_len); |
return -1; |
return -1; |
} |
} |
Line 187 libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int
|
Line 157 libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int
|
/* will need to update this for ipv6 at some point */ |
/* will need to update this for ipv6 at some point */ |
struct libnet_ipv4_hdr *iph_p = (struct libnet_ipv4_hdr *)iphdr; |
struct libnet_ipv4_hdr *iph_p = (struct libnet_ipv4_hdr *)iphdr; |
struct libnet_ipv6_hdr *ip6h_p = NULL; /* default to not using IPv6 */ |
struct libnet_ipv6_hdr *ip6h_p = NULL; /* default to not using IPv6 */ |
int ip_hl = 0; | int ip_hl = 0; |
int sum = 0; | int sum = 0; |
| uint8_t ip_nh = 0; |
|
|
/* Check for memory under/over reads/writes. */ |
/* Check for memory under/over reads/writes. */ |
if(iphdr < beg || (iphdr+sizeof(*iph_p)) > end) |
if(iphdr < beg || (iphdr+sizeof(*iph_p)) > end) |
{ |
{ |
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, |
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, |
"%s(): ipv4 hdr not inside packet (where %d, size %d)\n", __func__, | "%s(): ipv4 hdr not inside packet (where %d, size %d)", __func__, |
(int)(iphdr-beg), (int)(end-beg)); |
(int)(iphdr-beg), (int)(end-beg)); |
return -1; |
return -1; |
} |
} |
Line 208 libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int
|
Line 179 libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int
|
ip6h_p = (struct libnet_ipv6_hdr *)iph_p; |
ip6h_p = (struct libnet_ipv6_hdr *)iph_p; |
iph_p = NULL; |
iph_p = NULL; |
ip_hl = 40; |
ip_hl = 40; |
|
ip_nh = ip6h_p->ip_nh; |
|
|
if((uint8_t*)(ip6h_p+1) > end) |
if((uint8_t*)(ip6h_p+1) > end) |
{ |
{ |
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, |
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, |
"%s(): ipv6 hdr not inside packet\n", __func__); | "%s(): ipv6 hdr not inside packet", __func__); |
return -1; |
return -1; |
} |
} |
|
|
|
/* FIXME this entire fragile exercise would be avoided if we just passed |
|
* in the pointer to the protocol block 'q' we are checksumming, which |
|
* we know. |
|
*/ |
|
while (ip_nh != protocol && (uint8_t*)ip6h_p + ip_hl + 1 < end) |
|
{ |
|
/* next header is not the upper layer protocol */ |
|
switch (ip_nh) |
|
{ |
|
case IPPROTO_DSTOPTS: |
|
case IPPROTO_HOPOPTS: |
|
case IPPROTO_ROUTING: |
|
case IPPROTO_FRAGMENT: |
|
case IPPROTO_AH: |
|
case IPPROTO_ESP: |
|
case IPPROTO_MH: |
|
/* |
|
* count option headers to the header length for |
|
* checksum processing |
|
*/ |
|
/* Common structure of ipv6 ext headers is: |
|
* uint8: next header protocol |
|
* uint8: length of this header, in multiples of 8, not |
|
* including first eight octets |
|
* The pointer arithmetic below follows from above. |
|
*/ |
|
ip_nh = *((uint8_t*)ip6h_p+ip_hl); /* next next header */ |
|
ip_hl += (*((uint8_t*)ip6h_p+ip_hl+1)+1)*8; /* ext header length */ |
|
break; |
|
default: |
|
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, |
|
"%s(): unsupported extension header (%d)", __func__, ip_nh); |
|
return -1; |
|
} |
|
|
|
} |
} |
} |
else |
else |
{ |
{ |
Line 223 libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int
|
Line 233 libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int
|
if((iphdr+ip_hl) > end) |
if((iphdr+ip_hl) > end) |
{ |
{ |
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, |
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, |
"%s(): ip hdr len not inside packet\n", __func__); | "%s(): ip hdr len not inside packet", __func__); |
return -1; |
return -1; |
} |
} |
|
|
Line 238 libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int
|
Line 248 libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int
|
struct libnet_tcp_hdr *tcph_p = |
struct libnet_tcp_hdr *tcph_p = |
(struct libnet_tcp_hdr *)(iphdr + ip_hl); |
(struct libnet_tcp_hdr *)(iphdr + ip_hl); |
|
|
h_len = end - (uint8_t*) tcph_p; /* ignore h_len, sum the packet we've coalesced */ | h_len = (int)(end - (uint8_t*) tcph_p); /* ignore h_len, sum the packet we've coalesced */ |
|
|
CHECK_IP_PAYLOAD_SIZE(); |
CHECK_IP_PAYLOAD_SIZE(); |
|
|
Line 292 libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int
|
Line 302 libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int
|
struct libnet_udp_hdr *udph_p = |
struct libnet_udp_hdr *udph_p = |
(struct libnet_udp_hdr *)(iphdr + ip_hl); |
(struct libnet_udp_hdr *)(iphdr + ip_hl); |
|
|
h_len = end - (uint8_t*) udph_p; /* ignore h_len, sum the packet we've coalesced */ | h_len = (int)(end - (uint8_t*) udph_p); /* ignore h_len, sum the packet we've coalesced */ |
|
|
CHECK_IP_PAYLOAD_SIZE(); |
CHECK_IP_PAYLOAD_SIZE(); |
|
|
Line 315 libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int
|
Line 325 libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int
|
struct libnet_icmpv4_hdr *icmph_p = |
struct libnet_icmpv4_hdr *icmph_p = |
(struct libnet_icmpv4_hdr *)(iphdr + ip_hl); |
(struct libnet_icmpv4_hdr *)(iphdr + ip_hl); |
|
|
h_len = end - (uint8_t*) icmph_p; /* ignore h_len, sum the packet we've coalesced */ | h_len = (int)(end - (uint8_t*) icmph_p); /* ignore h_len, sum the packet we've coalesced */ |
|
|
CHECK_IP_PAYLOAD_SIZE(); |
CHECK_IP_PAYLOAD_SIZE(); |
|
|
Line 337 libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int
|
Line 347 libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int
|
struct libnet_icmpv6_hdr *icmph_p = |
struct libnet_icmpv6_hdr *icmph_p = |
(struct libnet_icmpv6_hdr *)(iphdr + ip_hl); |
(struct libnet_icmpv6_hdr *)(iphdr + ip_hl); |
|
|
h_len = end - (uint8_t*) icmph_p; /* ignore h_len, sum the packet we've coalesced */ | h_len = (int)(end - (uint8_t*) icmph_p); /* ignore h_len, sum the packet we've coalesced */ |
|
|
CHECK_IP_PAYLOAD_SIZE(); |
CHECK_IP_PAYLOAD_SIZE(); |
|
|
Line 356 libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int
|
Line 366 libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int
|
struct libnet_igmp_hdr *igmph_p = |
struct libnet_igmp_hdr *igmph_p = |
(struct libnet_igmp_hdr *)(iphdr + ip_hl); |
(struct libnet_igmp_hdr *)(iphdr + ip_hl); |
|
|
h_len = end - (uint8_t*) igmph_p; /* ignore h_len, sum the packet we've coalesced */ | h_len = (int)(end - (uint8_t*) igmph_p); /* ignore h_len, sum the packet we've coalesced */ |
|
|
CHECK_IP_PAYLOAD_SIZE(); |
CHECK_IP_PAYLOAD_SIZE(); |
|
|
Line 380 libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int
|
Line 390 libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int
|
!(fv & (GRE_CSUM|GRE_VERSION_1))) |
!(fv & (GRE_CSUM|GRE_VERSION_1))) |
{ |
{ |
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, |
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, |
"%s(): can't compute GRE checksum (wrong flags_ver bits: 0x%x )\n", __func__, fv); | "%s(): can't compute GRE checksum (wrong flags_ver bits: 0x%x )", __func__, fv); |
return (-1); |
return (-1); |
} |
} |
sum = libnet_in_cksum((uint16_t *)greh_p, h_len); |
sum = libnet_in_cksum((uint16_t *)greh_p, h_len); |
Line 496 libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int
|
Line 506 libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int
|
if((iphdr+h_len) > end) |
if((iphdr+h_len) > end) |
{ |
{ |
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, |
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, |
"%s(): cdp payload not inside packet\n", __func__); | "%s(): cdp payload not inside packet", __func__); |
return -1; |
return -1; |
} |
} |
|
|
Line 519 libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int
|
Line 529 libnet_inet_checksum(libnet_t *l, uint8_t *iphdr, int
|
default: |
default: |
{ |
{ |
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, |
snprintf(l->err_buf, LIBNET_ERRBUF_SIZE, |
"%s(): unsupported protocol %d\n", __func__, protocol); | "%s(): unsupported protocol %d", __func__, protocol); |
return (-1); |
return (-1); |
} |
} |
} |
} |
Line 536 libnet_ip_check(uint16_t *addr, int len)
|
Line 546 libnet_ip_check(uint16_t *addr, int len)
|
return (LIBNET_CKSUM_CARRY(sum)); |
return (LIBNET_CKSUM_CARRY(sum)); |
} |
} |
|
|
/* EOF */ | /** |
| * Local Variables: |
| * indent-tabs-mode: nil |
| * c-file-style: "stroustrup" |
| * End: |
| */ |