| version 1.39, 1996/10/25 06:35:16 |
version 1.40, 1997/01/11 05:21:14 |
| Line 76 int udpcksum = 0; /* XXX */ |
|
| Line 76 int udpcksum = 0; /* XXX */ |
|
| #endif |
#endif |
| |
|
| static void udp_notify __P((struct inpcb *, int)); |
static void udp_notify __P((struct inpcb *, int)); |
| static struct mbuf *udp_saveopt __P((caddr_t, int, int)); |
|
| |
|
| #ifndef UDBHASHSIZE |
#ifndef UDBHASHSIZE |
| #define UDBHASHSIZE 128 |
#define UDBHASHSIZE 128 |
| Line 174 udp_input(m, va_alist) |
|
| Line 173 udp_input(m, va_alist) |
|
| |
|
| if (IN_MULTICAST(ip->ip_dst.s_addr) || |
if (IN_MULTICAST(ip->ip_dst.s_addr) || |
| in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif)) { |
in_broadcast(ip->ip_dst, m->m_pkthdr.rcvif)) { |
| struct socket *last; |
struct inpcb *last; |
| /* |
/* |
| * Deliver a multicast or broadcast datagram to *all* sockets |
* Deliver a multicast or broadcast datagram to *all* sockets |
| * for which the local and remote addresses and ports match |
* for which the local and remote addresses and ports match |
| Line 226 udp_input(m, va_alist) |
|
| Line 225 udp_input(m, va_alist) |
|
| struct mbuf *n; |
struct mbuf *n; |
| |
|
| if ((n = m_copy(m, 0, M_COPYALL)) != NULL) { |
if ((n = m_copy(m, 0, M_COPYALL)) != NULL) { |
| if (sbappendaddr(&last->so_rcv, |
if (last->inp_flags & INP_CONTROLOPTS |
| sintosa(&udpsrc), n, |
|| last->inp_socket->so_options & |
| (struct mbuf *)0) == 0) { |
SO_TIMESTAMP) { |
| |
ip_savecontrol(last, &opts, |
| |
ip, n); |
| |
} |
| |
if (sbappendaddr( |
| |
&last->inp_socket->so_rcv, |
| |
sintosa(&udpsrc), n, opts) == 0) { |
| m_freem(n); |
m_freem(n); |
| udpstat.udps_fullsock++; |
if (opts) |
| |
m_freem(opts); |
| } else |
} 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 |
* Don't look for additional matches if this one does |
| * not have either the SO_REUSEPORT or SO_REUSEADDR |
* not have either the SO_REUSEPORT or SO_REUSEADDR |
| Line 244 udp_input(m, va_alist) |
|
| Line 251 udp_input(m, va_alist) |
|
| * port. It * assumes that an application will never |
* port. It * assumes that an application will never |
| * clear these options after setting them. |
* 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; |
break; |
| } |
} |
| |
|
| Line 257 udp_input(m, va_alist) |
|
| Line 265 udp_input(m, va_alist) |
|
| udpstat.udps_noportbcast++; |
udpstat.udps_noportbcast++; |
| goto bad; |
goto bad; |
| } |
} |
| if (sbappendaddr(&last->so_rcv, sintosa(&udpsrc), m, |
if (last->inp_flags & INP_CONTROLOPTS || |
| (struct mbuf *)0) == 0) { |
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++; |
udpstat.udps_fullsock++; |
| goto bad; |
goto bad; |
| } |
} |
| sorwakeup(last); |
sorwakeup(last->inp_socket); |
| return; |
return; |
| } |
} |
| /* |
/* |
| Line 306 udp_input(m, va_alist) |
|
| Line 317 udp_input(m, va_alist) |
|
| udpsrc.sin_port = uh->uh_sport; |
udpsrc.sin_port = uh->uh_sport; |
| bzero((caddr_t)udpsrc.sin_zero, sizeof(udpsrc.sin_zero)); |
bzero((caddr_t)udpsrc.sin_zero, sizeof(udpsrc.sin_zero)); |
| |
|
| if (inp->inp_flags & INP_CONTROLOPTS) { |
if (inp->inp_flags & INP_CONTROLOPTS || |
| struct mbuf **mp = &opts; |
inp->inp_socket->so_options & SO_TIMESTAMP) |
| |
ip_savecontrol(inp, &opts, ip, m); |
| 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 |
|
| } |
|
| iphlen += sizeof(struct udphdr); |
iphlen += sizeof(struct udphdr); |
| m->m_len -= iphlen; |
m->m_len -= iphlen; |
| m->m_pkthdr.len -= iphlen; |
m->m_pkthdr.len -= iphlen; |
|
|
| } |
} |
| |
|
| /* |
/* |
| * 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; |
* Notify a udp user of an asynchronous error; |
| * just wake up so that he can collect error status. |
* just wake up so that he can collect error status. |
| */ |
*/ |