Skip to content

Commit 952bb25

Browse files
committed
fix(checksum): Ensure 16-bit alignment for checksum calculation in TCP/UDP header
1 parent 3574348 commit 952bb25

File tree

1 file changed

+30
-10
lines changed

1 file changed

+30
-10
lines changed

src/chksum.c

+30-10
Original file line numberDiff line numberDiff line change
@@ -57,8 +57,12 @@ int chksum6(struct pkt_ip6hdr_t *iph) {
5757
hdr.zero[0]=hdr.zero[1]=hdr.zero[2]=0;
5858
hdr.next_header = iph->next_header;
5959
icmp->check = 0;
60-
sum = in_cksum((uint16_t *)&hdr, sizeof(hdr));
61-
sum += in_cksum((uint16_t *)icmp, ntohs(iph->data_len));
60+
uint16_t hdr_buf[sizeof(hdr) / 2];
61+
memcpy(hdr_buf, &hdr, sizeof(hdr));
62+
sum = in_cksum(hdr_buf, sizeof(hdr));
63+
uint16_t icmp_buf[ntohs(iph->data_len) / 2];
64+
memcpy(icmp_buf, icmp, ntohs(iph->data_len));
65+
sum += in_cksum(icmp_buf, ntohs(iph->data_len));
6266
icmp->check = cksum_wrap(sum);
6367
break;
6468
}
@@ -74,8 +78,12 @@ int chksum6(struct pkt_ip6hdr_t *iph) {
7478
hdr.zero[0]=hdr.zero[1]=hdr.zero[2]=0;
7579
hdr.next_header = iph->next_header;
7680
udphdr->check = 0;
77-
sum = in_cksum((uint16_t *)&hdr, sizeof(hdr));
78-
sum += in_cksum((uint16_t *)udphdr, udplen);
81+
uint16_t hdr_buf[sizeof(hdr) / 2];
82+
memcpy(hdr_buf, &hdr, sizeof(hdr));
83+
sum = in_cksum(hdr_buf, sizeof(hdr));
84+
uint16_t udphdr_buf[udplen / 2];
85+
memcpy(udphdr_buf, udphdr, udplen);
86+
sum += in_cksum(udphdr_buf, udplen);
7987
udphdr->check = cksum_wrap(sum);
8088
}
8189
break;
@@ -91,8 +99,12 @@ int chksum6(struct pkt_ip6hdr_t *iph) {
9199
hdr.zero[0]=hdr.zero[1]=hdr.zero[2]=0;
92100
hdr.next_header = iph->next_header;
93101
tcphdr->check = 0;
94-
sum = in_cksum((uint16_t *)&hdr, sizeof(hdr));
95-
sum += in_cksum((uint16_t *)tcphdr, tcplen);
102+
uint16_t hdr_buf[sizeof(hdr) / 2];
103+
memcpy(hdr_buf, &hdr, sizeof(hdr));
104+
sum = in_cksum(hdr_buf, sizeof(hdr));
105+
uint16_t tcphdr_buf[tcplen / 2];
106+
memcpy(tcphdr_buf, tcphdr, tcplen);
107+
sum += in_cksum(tcphdr_buf, tcplen);
96108
tcphdr->check = cksum_wrap(sum);
97109
}
98110
break;
@@ -138,7 +150,9 @@ int chksum(struct pkt_iphdr_t *iph) {
138150
tcph->check = 0;
139151
sum = in_cksum(((uint16_t *)iph)+6/*saddr*/, 8);
140152
sum += ntohs(IPPROTO_TCP + len);
141-
sum += in_cksum((uint16_t *)tcph, len);
153+
uint16_t tcph_buf[len / 2];
154+
memcpy(tcph_buf, tcph, len);
155+
sum += in_cksum(tcph_buf, len);
142156
tcph->check = cksum_wrap(sum);
143157
}
144158
break;
@@ -155,7 +169,9 @@ int chksum(struct pkt_iphdr_t *iph) {
155169
udph->check = 0;
156170
sum = in_cksum(((uint16_t *)iph)+6/*saddr*/, 8);
157171
sum += ntohs(IPPROTO_UDP + udplen);
158-
sum += in_cksum((uint16_t *)udph, udplen);
172+
uint16_t udph_buf[udplen / 2];
173+
memcpy(udph_buf, udph, udplen);
174+
sum += in_cksum(udph_buf, udplen);
159175
udph->check = cksum_wrap(sum);
160176
}
161177
break;
@@ -166,14 +182,18 @@ int chksum(struct pkt_iphdr_t *iph) {
166182
(struct pkt_icmphdr_t *)(((void *)iph) + hlen);
167183
len -= hlen;
168184
icmph->check = 0;
169-
sum = in_cksum((uint16_t *)icmph, len);
185+
uint16_t icmph_buf[len / 2];
186+
memcpy(icmph_buf, icmph, len);
187+
sum = in_cksum(icmph_buf, len);
170188
icmph->check = cksum_wrap(sum);
171189
}
172190
break;
173191
}
174192

175193
iph->check = 0;
176-
sum = in_cksum((uint16_t *)iph, hlen);
194+
uint16_t iph_buf[hlen / 2];
195+
memcpy(iph_buf, iph, hlen);
196+
sum = in_cksum(iph_buf, hlen);
177197
iph->check = cksum_wrap(sum);
178198

179199
return 0;

0 commit comments

Comments
 (0)