diff options
author | dwmalone <dwmalone@FreeBSD.org> | 2007-05-16 09:12:16 +0000 |
---|---|---|
committer | dwmalone <dwmalone@FreeBSD.org> | 2007-05-16 09:12:16 +0000 |
commit | 7ff161914ef497787d1f0b46938966ecd6ec85f4 (patch) | |
tree | 6a9173548fc36eecab46e3aef04441f1f3bc039e /sys | |
parent | 5e9f952e4cedd35d70d3caf2479c25155942b9a0 (diff) | |
download | FreeBSD-src-7ff161914ef497787d1f0b46938966ecd6ec85f4.zip FreeBSD-src-7ff161914ef497787d1f0b46938966ecd6ec85f4.tar.gz |
When verifying the IPv4 UDP checksum, don't overwrite the checksum
value in the mbuf with the result of the calculation. Previously,
if we chose to return an ICMP message, the quoted UDP checksum bytes
would be different to what was sent.
PR: 112471
Submitted by: Matthew Luckie <mluckie@cs.waikato.ac.nz>
MFC after: 3 weeks
Diffstat (limited to 'sys')
-rw-r--r-- | sys/netinet/udp_usrreq.c | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c index cf2661c..96dc044 100644 --- a/sys/netinet/udp_usrreq.c +++ b/sys/netinet/udp_usrreq.c @@ -250,24 +250,26 @@ udp_input(struct mbuf *m, int off) * Checksum extended UDP header and data. */ if (uh->uh_sum) { + u_short uh_sum; + if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) { if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) - uh->uh_sum = m->m_pkthdr.csum_data; + uh_sum = m->m_pkthdr.csum_data; else - uh->uh_sum = in_pseudo(ip->ip_src.s_addr, + uh_sum = in_pseudo(ip->ip_src.s_addr, ip->ip_dst.s_addr, htonl((u_short)len + m->m_pkthdr.csum_data + IPPROTO_UDP)); - uh->uh_sum ^= 0xffff; + uh_sum ^= 0xffff; } else { char b[9]; bcopy(((struct ipovly *)ip)->ih_x1, b, 9); bzero(((struct ipovly *)ip)->ih_x1, 9); ((struct ipovly *)ip)->ih_len = uh->uh_ulen; - uh->uh_sum = in_cksum(m, len + sizeof (struct ip)); + uh_sum = in_cksum(m, len + sizeof (struct ip)); bcopy(b, ((struct ipovly *)ip)->ih_x1, 9); } - if (uh->uh_sum) { + if (uh_sum) { udpstat.udps_badsum++; m_freem(m); return; |