1
0
mirror of https://code.semirocket.science/wrapsix synced 2024-09-19 23:11:04 +03:00

Fixed IPv4 checksum computation

Added missing checksum recheck in UDP
This commit is contained in:
Michal Zima 2012-04-06 23:23:00 +02:00
parent d6f93792cd
commit 495d68296a
3 changed files with 23 additions and 9 deletions

View File

@ -95,11 +95,11 @@ unsigned short checksum_ipv4(struct s_ipv4_addr ip_src,
header->ip_dest = ip_dest; header->ip_dest = ip_dest;
header->zeros = 0x0; header->zeros = 0x0;
header->proto = proto; header->proto = proto;
header->len = htonl((unsigned int) length); header->len = htons(length);
memcpy(buffer + sizeof(struct s_ipv4_pseudo), payload, (int) length); memcpy(buffer + sizeof(struct s_ipv4_pseudo), payload, (int) length);
sum = checksum(buffer, sizeof(struct s_ipv6_pseudo) + (int) length); sum = checksum(buffer, sizeof(struct s_ipv4_pseudo) + (int) length);
free(buffer); free(buffer);

View File

@ -53,7 +53,7 @@ struct s_ipv4_pseudo {
struct s_ipv4_addr ip_dest; /* 32 b; destination address */ struct s_ipv4_addr ip_dest; /* 32 b; destination address */
unsigned char zeros; /* 8 b */ unsigned char zeros; /* 8 b */
unsigned char proto; /* 8 b; protocol in payload */ unsigned char proto; /* 8 b; protocol in payload */
unsigned int len; /* 32 b; payload length */ unsigned short len; /* 16 b; payload length */
} __attribute__ ((__packed__)); } __attribute__ ((__packed__));
int ipv4(struct s_ethernet *eth, char *packet); int ipv4(struct s_ethernet *eth, char *packet);

View File

@ -58,7 +58,20 @@ int udp_ipv4(struct s_ethernet *eth, struct s_ipv4 *ip4, char *payload,
/* parse UDP header */ /* parse UDP header */
udp = (struct s_udp *) payload; udp = (struct s_udp *) payload;
/* TODO: checksum recheck */ /* checksum recheck */
if (udp->checksum != 0x0000) {
orig_checksum = udp->checksum;
udp->checksum = 0;
udp->checksum = checksum_ipv4(ip4->ip_src, ip4->ip_dest,
payload_size, IPPROTO_UDP,
(unsigned char *) udp);
if (udp->checksum != orig_checksum) {
/* packet is corrupted and shouldn't be processed */
printf("[Debug] Wrong checksum\n");
return 1;
}
}
/* find connection in NAT */ /* find connection in NAT */
connection = nat_in(nat4_udp, ip4->ip_src, udp->port_src, udp->port_dest); connection = nat_in(nat4_udp, ip4->ip_src, udp->port_src, udp->port_dest);
@ -185,16 +198,17 @@ int udp_ipv6(struct s_ethernet *eth, struct s_ipv6 *ip6, char *payload)
udp->port_src = connection->ipv4_port_src; udp->port_src = connection->ipv4_port_src;
/* compute UDP checksum */ /* compute UDP checksum */
udp->checksum = 0; udp->checksum = 0x0;
/* TODO: checksum computation; in IPv4 it's optional in UDP */ udp->checksum = checksum_ipv4(ip4->ip_src, ip4->ip_dest,
htons(ip6->len), IPPROTO_UDP,
(unsigned char *) payload);
/* copy the payload data (with new checksum) */ /* copy the payload data (with new checksum) */
memcpy(packet + sizeof(struct s_ipv4), payload, htons(ip6->len)); memcpy(packet + sizeof(struct s_ipv4), payload, htons(ip6->len));
/* compute IPv4 checksum */ /* compute IPv4 checksum */
ip4->checksum = checksum_ipv4(ip4->ip_src, ip4->ip_dest, ip4->checksum = 0x0;
htons(ip4->len), IPPROTO_UDP, ip4->checksum = checksum(ip4, sizeof(struct s_ipv4));
(unsigned char *) udp);
/* send translated packet */ /* send translated packet */
printf("[Debug] transmitting\n"); printf("[Debug] transmitting\n");