Subject: kern/4087: incoming UDP broadcasts get inconsistent length information
To: None <gnats-bugs@gnats.netbsd.org>
From: Matthias Drochner <drochner@zelz26.zel.kfa-juelich.de>
List: netbsd-bugs
Date: 09/05/1997 12:20:30
>Number:         4087
>Category:       kern
>Synopsis:       incoming UDP broadcasts get inconsistent length information
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    kern-bug-people (Kernel Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Sep  5 03:35:01 1997
>Last-Modified:
>Originator:     Matthias Drochner
>Organization:
	KFA Juelich
>Release:        NetBSD-current, seems widespread and longstanding
>Environment:
	NetBSD-current / i386
System: NetBSD zelz26 1.2G NetBSD 1.2G (GENERIC.KGDB) #56: Thu Sep 4 23:48:56 MEST 1997 drochner@zelz26:/mnt/sys/arch/i386/compile/GENERIC.KGDB i386


>Description:
	UDP packets, read as mbuf from a socket, have inconsistent lenghth fields
in the mbuf header if they were sent as broadcasts. The fields "m->m_pkthdr.len"
and "m->m_len" differ by 28 (IP/UDP header length).
This is caused by an incomplete size adjustment in udp_input().
>How-To-Repeat:
	Do consistency checks like the following code snippet:

uio.uio_resid = 1 << 16;
rcvflg = 0;
error = soreceive(so, &from, &uio, &m, NULL, &rcvflg);
[...]
if(!m || !(m->m_flags & M_PKTHDR)
	|| (1 << 16) - uio.uio_resid != m->m_pkthdr.len)
		panic("???");

>Fix:
	This patch makes the adjustment similar to the unicast case:

Index: udp_usrreq.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/udp_usrreq.c,v
retrieving revision 1.42
diff -c -2 -r1.42 udp_usrreq.c
*** udp_usrreq.c	1997/07/28 22:19:53	1.42
--- udp_usrreq.c	1997/09/05 09:41:14
***************
*** 200,205 ****
  		bzero((caddr_t)udpsrc.sin_zero, sizeof(udpsrc.sin_zero));
  
! 		m->m_len -= sizeof (struct udpiphdr);
! 		m->m_data += sizeof (struct udpiphdr);
  		/*
  		 * Locate pcb(s) for datagram.
--- 200,207 ----
  		bzero((caddr_t)udpsrc.sin_zero, sizeof(udpsrc.sin_zero));
  
! 		iphlen += sizeof(struct udphdr);
! 		m->m_len -= iphlen;
! 		m->m_pkthdr.len -= iphlen;
! 		m->m_data += iphlen;
  		/*
  		 * Locate pcb(s) for datagram.
>Audit-Trail:
>Unformatted: