Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/sys/netinet/udp_usrreq.c,v rcsdiff: /ftp/cvs/cvsroot/src/sys/netinet/udp_usrreq.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.36 retrieving revision 1.43 diff -u -p -r1.36 -r1.43 --- src/sys/netinet/udp_usrreq.c 1996/09/16 17:45:19 1.36 +++ src/sys/netinet/udp_usrreq.c 1997/09/12 10:58:31 1.43 @@ -1,4 +1,4 @@ -/* $NetBSD: udp_usrreq.c,v 1.36 1996/09/16 17:45:19 mycroft Exp $ */ +/* $NetBSD: udp_usrreq.c,v 1.43 1997/09/12 10:58:31 drochner Exp $ */ /* * Copyright (c) 1982, 1986, 1988, 1990, 1993 @@ -34,6 +34,7 @@ * * @(#)udp_usrreq.c 8.4 (Berkeley) 1/21/94 */ +#include "ipkdb.h" #include #include @@ -75,7 +76,6 @@ int udpcksum = 0; /* XXX */ #endif static void udp_notify __P((struct inpcb *, int)); -static struct mbuf *udp_saveopt __P((caddr_t, int, int)); #ifndef UDBHASHSIZE #define UDBHASHSIZE 128 @@ -173,7 +173,7 @@ udp_input(m, va_alist) if (IN_MULTICAST(ip->ip_dst.s_addr) || in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif)) { - struct socket *last; + struct inpcb *last; /* * Deliver a multicast or broadcast datagram to *all* sockets * for which the local and remote addresses and ports match @@ -199,8 +199,10 @@ udp_input(m, va_alist) udpsrc.sin_port = uh->uh_sport; bzero((caddr_t)udpsrc.sin_zero, sizeof(udpsrc.sin_zero)); - m->m_len -= sizeof (struct udpiphdr); - m->m_data += sizeof (struct udpiphdr); + iphlen += sizeof(struct udphdr); + m->m_len -= iphlen; + m->m_pkthdr.len -= iphlen; + m->m_data += iphlen; /* * Locate pcb(s) for datagram. * (Algorithm copied from raw_intr().) @@ -225,16 +227,24 @@ udp_input(m, va_alist) struct mbuf *n; if ((n = m_copy(m, 0, M_COPYALL)) != NULL) { - if (sbappendaddr(&last->so_rcv, - sintosa(&udpsrc), n, - (struct mbuf *)0) == 0) { + if (last->inp_flags & INP_CONTROLOPTS + || last->inp_socket->so_options & + SO_TIMESTAMP) { + ip_savecontrol(last, &opts, + ip, n); + } + if (sbappendaddr( + &last->inp_socket->so_rcv, + sintosa(&udpsrc), n, opts) == 0) { m_freem(n); - udpstat.udps_fullsock++; + if (opts) + m_freem(opts); } else - sorwakeup(last); + sorwakeup(last->inp_socket); + opts = 0; } } - last = inp->inp_socket; + last = inp; /* * Don't look for additional matches if this one does * not have either the SO_REUSEPORT or SO_REUSEADDR @@ -243,7 +253,8 @@ udp_input(m, va_alist) * port. It * assumes that an application will never * clear these options after setting them. */ - if ((last->so_options&(SO_REUSEPORT|SO_REUSEADDR)) == 0) + if ((last->inp_socket->so_options & + (SO_REUSEPORT|SO_REUSEADDR)) == 0) break; } @@ -256,12 +267,15 @@ udp_input(m, va_alist) udpstat.udps_noportbcast++; goto bad; } - if (sbappendaddr(&last->so_rcv, sintosa(&udpsrc), m, - (struct mbuf *)0) == 0) { + if (last->inp_flags & INP_CONTROLOPTS || + last->inp_socket->so_options & SO_TIMESTAMP) + ip_savecontrol(last, &opts, ip, m); + if (sbappendaddr(&last->inp_socket->so_rcv, + sintosa(&udpsrc), m, opts) == 0) { udpstat.udps_fullsock++; goto bad; } - sorwakeup(last); + sorwakeup(last->inp_socket); return; } /* @@ -279,7 +293,16 @@ udp_input(m, va_alist) goto bad; } *ip = save_ip; - ip->ip_len += iphlen; +#if NIPKDB > 0 + if (checkipkdb(&ip->ip_src, + uh->uh_sport, + uh->uh_dport, + m, + iphlen + sizeof(struct udphdr), + len - sizeof(struct udphdr))) + /* It was a debugger connect packet, just drop it now */ + goto bad; +#endif icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_PORT, 0, 0); return; } @@ -295,32 +318,9 @@ udp_input(m, va_alist) udpsrc.sin_port = uh->uh_sport; bzero((caddr_t)udpsrc.sin_zero, sizeof(udpsrc.sin_zero)); - if (inp->inp_flags & INP_CONTROLOPTS) { - struct mbuf **mp = &opts; - - if (inp->inp_flags & INP_RECVDSTADDR) { - *mp = udp_saveopt((caddr_t) &ip->ip_dst, - sizeof(struct in_addr), IP_RECVDSTADDR); - if (*mp) - mp = &(*mp)->m_next; - } -#ifdef notyet - /* options were tossed above */ - if (inp->inp_flags & INP_RECVOPTS) { - *mp = udp_saveopt((caddr_t) opts_deleted_above, - sizeof(struct in_addr), IP_RECVOPTS); - if (*mp) - mp = &(*mp)->m_next; - } - /* ip_srcroute doesn't do what we want here, need to fix */ - if (inp->inp_flags & INP_RECVRETOPTS) { - *mp = udp_saveopt((caddr_t) ip_srcroute(), - sizeof(struct in_addr), IP_RECVRETOPTS); - if (*mp) - mp = &(*mp)->m_next; - } -#endif - } + if (inp->inp_flags & INP_CONTROLOPTS || + inp->inp_socket->so_options & SO_TIMESTAMP) + ip_savecontrol(inp, &opts, ip, m); iphlen += sizeof(struct udphdr); m->m_len -= iphlen; m->m_pkthdr.len -= iphlen; @@ -339,31 +339,6 @@ bad: } /* - * Create a "control" mbuf containing the specified data - * with the specified type for presentation with a datagram. - */ -struct mbuf * -udp_saveopt(p, size, type) - caddr_t p; - register int size; - int type; -{ - register struct cmsghdr *cp; - struct mbuf *m; - - if ((m = m_get(M_DONTWAIT, MT_CONTROL)) == NULL) - return ((struct mbuf *) NULL); - cp = (struct cmsghdr *) mtod(m, struct cmsghdr *); - bcopy(p, CMSG_DATA(cp), size); - size += sizeof(*cp); - m->m_len = size; - cp->cmsg_len = size; - cp->cmsg_level = IPPROTO_IP; - cp->cmsg_type = type; - return (m); -} - -/* * Notify a udp user of an asynchronous error; * just wake up so that he can collect error status. */ @@ -439,6 +414,15 @@ udp_output(m, va_alist) } /* + * Compute the packet length of the IP header, and + * punt if the length looks bogus. + */ + if ((len + sizeof(struct udpiphdr)) > IP_MAXPACKET) { + error = EMSGSIZE; + goto release; + } + + /* * Fill in mbuf with extended UDP header * and addresses and length put into network format. */ @@ -473,8 +457,8 @@ release: return (error); } -u_long udp_sendspace = 9216; /* really max datagram size */ -u_long udp_recvspace = 40 * (1024 + sizeof(struct sockaddr_in)); +int udp_sendspace = 9216; /* really max datagram size */ +int udp_recvspace = 40 * (1024 + sizeof(struct sockaddr_in)); /* 40 1K datagrams */ /*ARGSUSED*/ @@ -656,6 +640,12 @@ udp_sysctl(name, namelen, oldp, oldlenp, switch (name[0]) { case UDPCTL_CHECKSUM: return (sysctl_int(oldp, oldlenp, newp, newlen, &udpcksum)); + case UDPCTL_SENDSPACE: + return (sysctl_int(oldp, oldlenp, newp, newlen, + &udp_sendspace)); + case UDPCTL_RECVSPACE: + return (sysctl_int(oldp, oldlenp, newp, newlen, + &udp_recvspace)); default: return (ENOPROTOOPT); }