summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ldra.c26
1 files changed, 17 insertions, 9 deletions
diff --git a/ldra.c b/ldra.c
index ea2c683..5d2a6bc 100644
--- a/ldra.c
+++ b/ldra.c
@@ -155,7 +155,7 @@ u_int16_t csum_ipv6udp(struct ip6_hdr *ip6, const u_int16_t *data, size_t datal
*/
-int newalgo = 0; // does not work...
+int newalgo = 1;
u_int32_t wrapsum(u_int32_t sum) {
sum = ~sum & 0xFFFF;
@@ -200,17 +200,17 @@ u_int32_t checksum(unsigned char *buf, unsigned nbytes, u_int32_t sum) {
/* calulate a possibly partial checksum */
u_int32_t chksum(u_int8_t *buf, size_t n) {
- u_int32_t sum;
+ u_int32_t sum = 0;
int i;
- for (i = 0; i < n/2; i += 2)
- sum += (u_int16_t)ntohs(*(u_int16_t *)(buf + i));
+ for (i = 0; i <(n & ~1U); i += 2)
+ sum += (u_int16_t)ntohs(*((u_int16_t *)(buf + i)));
/* odd number of bytes? */
if (i < n)
sum += buf[i] << 8;
- return sum;
+ return (sum);
}
@@ -621,14 +621,22 @@ Steven McCanne and Van Jacobson of Lawrence Berkeley Laboratory.
udp->check = 0; /* reset before calculating new checksum */
if (!newalgo) { /* FIMXE: testing */
- udp->check = wrapsum(checksum((unsigned char *)udp, sizeof(struct udphdr) + datalen, /* udp header + packet data */
+ u_int16_t oldchksum, newchksum;
+
+ oldchksum = wrapsum(checksum((unsigned char *)udp, sizeof(struct udphdr) + datalen, /* udp header + packet data */
checksum((unsigned char *)&ip6->ip6_src, 2 * sizeof(ip6->ip6_src), /* src + dst address */
IPPROTO_UDP + (u_int32_t)ntohs(udp->len)))); /* final part of pseudo header */
-
- } else {
- udp->check = complement(chksum((u_int8_t *)udp, sizeof(struct udphdr) + datalen) + /* udp header + packet data */
+ newchksum = complement(chksum((u_int8_t *)udp, sizeof(struct udphdr) + datalen) + /* udp header + packet data */
chksum((u_int8_t *)&ip6->ip6_src, 2 * sizeof(ip6->ip6_src)) + /* src + dst address */
IPPROTO_UDP + (u_int32_t)ntohs(udp->len)); /* final part of pseudo header */
+
+ fprintf(stderr, "old chksum code: %#06hx, new checksum code: %#06hx\n",oldchksum,newchksum);
+ udp->check = oldchksum;
+
+ } else {
+ udp->check = complement(chksum((u_int8_t *)udp, sizeof(struct udphdr) + datalen) + /* udp header + packet data */
+ chksum((u_int8_t *)&ip6->ip6_src, 2 * sizeof(ip6->ip6_src)) + /* src + dst address */
+ IPPROTO_UDP + (u_int32_t)ntohs(udp->len)); /* final part of pseudo header */
}
packetlen = sizeof(struct ethhdr) + VLANTAGZ + sizeof(struct ip6_hdr) + ntohs(udp->len);