1
0
mirror of https://code.semirocket.science/wrapsix synced 2024-09-19 15:01:06 +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->zeros = 0x0;
header->proto = proto;
header->len = htonl((unsigned int) length);
header->len = htons(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);

View File

@ -53,7 +53,7 @@ struct s_ipv4_pseudo {
struct s_ipv4_addr ip_dest; /* 32 b; destination address */
unsigned char zeros; /* 8 b */
unsigned char proto; /* 8 b; protocol in payload */
unsigned int len; /* 32 b; payload length */
unsigned short len; /* 16 b; payload length */
} __attribute__ ((__packed__));
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 */
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 */
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;
/* compute UDP checksum */
udp->checksum = 0;
/* TODO: checksum computation; in IPv4 it's optional in UDP */
udp->checksum = 0x0;
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) */
memcpy(packet + sizeof(struct s_ipv4), payload, htons(ip6->len));
/* compute IPv4 checksum */
ip4->checksum = checksum_ipv4(ip4->ip_src, ip4->ip_dest,
htons(ip4->len), IPPROTO_UDP,
(unsigned char *) udp);
ip4->checksum = 0x0;
ip4->checksum = checksum(ip4, sizeof(struct s_ipv4));
/* send translated packet */
printf("[Debug] transmitting\n");