Date: Wed, 12 Oct 2005 08:50:18 GMT From: Maxim Konovalov <maxim@macomnet.ru> To: freebsd-bugs@FreeBSD.org Subject: Re: kern/87306: IP_PORTRANGE_HIGH causes bad UDP checksum Message-ID: <200510120850.j9C8oIMH057583@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/87306; it has been noted by GNATS. From: Maxim Konovalov <maxim@macomnet.ru> To: bms@freebsd.org Cc: Rickard Lind <rickard.lind@ntier.se>, bug-followup@freebsd.org Subject: Re: kern/87306: IP_PORTRANGE_HIGH causes bad UDP checksum Date: Wed, 12 Oct 2005 12:41:06 +0400 (MSD) > >Description: > Due to a mixup of two fields, setting the socket option > IP_PORTRANGE_HIGH on a UDP socket in order to bind a high (random) > port affects the checksum calculation such that the resulting > checksum is incorrect. > >How-To-Repeat: > Create a UDP (SOCK_DGRAM) socket. Set the IP_PORTRANGE_HIGH socket > option. Bind with a zero port. Send some data to another host. > Ethereal on the receiveing host reports the UDP checksum as > incorrect. > >Fix: > The problem is that the flag INP_ONESBCAST has the same value (0x10) > as the flag INP_HIGHPORT in sys/netinet/in_pcb.h, and INP_ONESBCAST > is tested against the inp_flags field (in sys/netinet/udp_usrreq.c > and sys/netinet/raw_ip.c) when it SHOULD be tested against the > inp_vflag field. This causes the checksum calculation on line 867 in > udp_usrreq.c to use the broadcast address leading to an incorrect > checksum. Ricard, it seems you analysis is correct. Thanks for the high quality bug report! Bruce, what is your opinion? Index: raw_ip.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/raw_ip.c,v retrieving revision 1.154 diff -u -r1.154 raw_ip.c --- raw_ip.c 4 Oct 2005 18:19:21 -0000 1.154 +++ raw_ip.c 12 Oct 2005 08:32:15 -0000 @@ -316,7 +316,7 @@ ipstat.ips_rawout++; } - if (inp->inp_flags & INP_ONESBCAST) + if (inp->inp_vflags & INP_ONESBCAST) flags |= IP_SENDONES; #ifdef MAC Index: udp_usrreq.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/udp_usrreq.c,v retrieving revision 1.177 diff -u -r1.177 udp_usrreq.c --- udp_usrreq.c 26 Sep 2005 20:25:16 -0000 1.177 +++ udp_usrreq.c 12 Oct 2005 08:32:31 -0000 @@ -860,14 +860,14 @@ ipflags |= IP_ROUTETOIF; if (inp->inp_socket->so_options & SO_BROADCAST) ipflags |= IP_ALLOWBROADCAST; - if (inp->inp_flags & INP_ONESBCAST) + if (inp->inp_vflags & INP_ONESBCAST) ipflags |= IP_SENDONES; /* * Set up checksum and output datagram. */ if (udpcksum) { - if (inp->inp_flags & INP_ONESBCAST) + if (inp->inp_vflags & INP_ONESBCAST) faddr.s_addr = INADDR_BROADCAST; ui->ui_sum = in_pseudo(ui->ui_src.s_addr, faddr.s_addr, htons((u_short)len + sizeof(struct udphdr) + IPPROTO_UDP)); %%% -- Maxim Konovalov
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200510120850.j9C8oIMH057583>