X-Git-Url: https://git.subgeniuskitty.com/unix-history/.git/blobdiff_plain/d55475b106b8e0084ff7602440883e8bf4e36127..986fd057089c0c3c193084e22eee9f05c565b9bb:/usr/src/sys/netinet/udp_usrreq.c diff --git a/usr/src/sys/netinet/udp_usrreq.c b/usr/src/sys/netinet/udp_usrreq.c index a5464006af..0edf4fa2b9 100644 --- a/usr/src/sys/netinet/udp_usrreq.c +++ b/usr/src/sys/netinet/udp_usrreq.c @@ -1,14 +1,26 @@ /* - * Copyright (c) 1982 Regents of the University of California. - * All rights reserved. The Berkeley software License Agreement - * specifies the terms and conditions for redistribution. + * Copyright (c) 1982, 1986, 1988 Regents of the University of California. + * All rights reserved. * - * @(#)udp_usrreq.c 6.17 (Berkeley) %G% + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * @(#)udp_usrreq.c 7.9 (Berkeley) %G% */ #include "param.h" #include "dir.h" #include "user.h" +#include "malloc.h" #include "mbuf.h" #include "protosw.h" #include "socket.h" @@ -38,31 +50,38 @@ udp_init() udb.inp_next = udb.inp_prev = &udb; } +#ifndef COMPAT_42 int udpcksum = 1; +#else +int udpcksum = 0; /* XXX */ +#endif +int udp_ttl = UDP_TTL; + struct sockaddr_in udp_in = { AF_INET }; -udp_input(m0, ifp) - struct mbuf *m0; - struct ifnet *ifp; +udp_input(m, iphlen) + register struct mbuf *m; + int iphlen; { register struct udpiphdr *ui; register struct inpcb *inp; - register struct mbuf *m; int len; struct ip ip; /* * Get IP and UDP header together in first mbuf. + * Note: IP leaves IP header in first mbuf. */ - m = m0; - if ((m->m_off > MMAXOFF || m->m_len < sizeof (struct udpiphdr)) && - (m = m_pullup(m, sizeof (struct udpiphdr))) == 0) { - udpstat.udps_hdrops++; - return; - } ui = mtod(m, struct udpiphdr *); - if (((struct ip *)ui)->ip_hl > (sizeof (struct ip) >> 2)) - ip_stripoptions((struct ip *)ui, (struct mbuf *)0); + if (iphlen > sizeof (struct ip)) + ip_stripoptions(m, (struct mbuf *)0); + if (m->m_len < sizeof (struct udpiphdr)) { + if ((m = m_pullup(m, sizeof (struct udpiphdr))) == 0) { + udpstat.udps_hdrops++; + return; + } + ui = mtod(m, struct udpiphdr *); + } /* * Make mbuf data length reflect UDP length. @@ -80,7 +99,7 @@ udp_input(m0, ifp) /* * Save a copy of the IP header in case we want restore it for ICMP. */ - ip = *(struct ip*)ui; + ip = *(struct ip *)ui; /* * Checksum extended UDP header and data. @@ -104,11 +123,10 @@ udp_input(m0, ifp) INPLOOKUP_WILDCARD); if (inp == 0) { /* don't send ICMP response for broadcast packet */ - if (in_broadcast(ui->ui_dst)) + if (m->m_flags & M_BCAST) goto bad; *(struct ip *)ui = ip; - icmp_error((struct ip *)ui, ICMP_UNREACH, ICMP_UNREACH_PORT, - ifp); + icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_PORT); return; } @@ -119,7 +137,8 @@ udp_input(m0, ifp) udp_in.sin_port = ui->ui_sport; udp_in.sin_addr = ui->ui_src; m->m_len -= sizeof (struct udpiphdr); - m->m_off += sizeof (struct udpiphdr); + m->m_pkthdr.len -= sizeof (struct udpiphdr); + m->m_data += sizeof (struct udpiphdr); if (sbappendaddr(&inp->inp_socket->so_rcv, (struct sockaddr *)&udp_in, m, (struct mbuf *)0) == 0) goto bad; @@ -129,6 +148,18 @@ bad: m_freem(m); } +/* + * Notify a udp user of an asynchronous error; + * just wake up so that he can collect error status. + */ +udp_notify(inp) + register struct inpcb *inp; +{ + + sorwakeup(inp->inp_socket); + sowwakeup(inp->inp_socket); +} + udp_ctlinput(cmd, sa) int cmd; struct sockaddr *sa; @@ -162,37 +193,27 @@ udp_ctlinput(cmd, sa) if (inetctlerrmap[cmd] == 0) return; /* XXX */ in_pcbnotify(&udb, &sin->sin_addr, (int)inetctlerrmap[cmd], - (int (*)())0); + udp_notify); } } -udp_output(inp, m0) +udp_output(inp, m) register struct inpcb *inp; - struct mbuf *m0; -{ register struct mbuf *m; +{ register struct udpiphdr *ui; - register int len = 0; + register int len = m->m_pkthdr.len; /* * Calculate data length and get a mbuf * for UDP and IP headers. */ - for (m = m0; m; m = m->m_next) - len += m->m_len; - MGET(m, M_DONTWAIT, MT_HEADER); - if (m == 0) { - m_freem(m0); - return (ENOBUFS); - } + M_PREPEND(m, sizeof(struct udpiphdr), M_WAIT); /* * Fill in mbuf with extended UDP header * and addresses and length put into network format. */ - m->m_off = MMAXOFF - sizeof (struct udpiphdr); - m->m_len = sizeof (struct udpiphdr); - m->m_next = m0; ui = mtod(m, struct udpiphdr *); ui->ui_next = ui->ui_prev = 0; ui->ui_x1 = 0; @@ -210,22 +231,22 @@ udp_output(inp, m0) ui->ui_sum = 0; if (udpcksum) { if ((ui->ui_sum = in_cksum(m, sizeof (struct udpiphdr) + len)) == 0) - ui->ui_sum = -1; + ui->ui_sum = 0xffff; } ((struct ip *)ui)->ip_len = sizeof (struct udpiphdr) + len; - ((struct ip *)ui)->ip_ttl = MAXTTL; + ((struct ip *)ui)->ip_ttl = udp_ttl; return (ip_output(m, inp->inp_options, &inp->inp_route, inp->inp_socket->so_options & (SO_DONTROUTE | SO_BROADCAST))); } -int udp_sendspace = 2048; /* really max datagram size */ -int udp_recvspace = 4 * (1024+sizeof(struct sockaddr_in)); /* 4 1K dgrams */ +u_long udp_sendspace = 2048; /* really max datagram size */ +u_long udp_recvspace = 4 * (1024+sizeof(struct sockaddr_in)); /* 4 1K dgrams */ /*ARGSUSED*/ -udp_usrreq(so, req, m, nam, rights) +udp_usrreq(so, req, m, nam, rights, control) struct socket *so; int req; - struct mbuf *m, *nam, *rights; + struct mbuf *m, *nam, *rights, *control; { struct inpcb *inp = sotoinpcb(so); int error = 0; @@ -257,10 +278,6 @@ udp_usrreq(so, req, m, nam, rights) break; case PRU_DETACH: - if (inp == NULL) { - error = ENOTCONN; - break; - } in_pcbdetach(inp); break; @@ -296,7 +313,7 @@ udp_usrreq(so, req, m, nam, rights) break; } in_pcbdisconnect(inp); - soisdisconnected(so); + so->so_state &= ~SS_ISCONNECTED; /* XXX */ break; case PRU_SHUTDOWN: @@ -339,9 +356,8 @@ udp_usrreq(so, req, m, nam, rights) break; case PRU_ABORT: - in_pcbdetach(inp); - sofree(so); soisdisconnected(so); + in_pcbdetach(inp); break; case PRU_SOCKADDR: