sun purge
[unix-history] / usr / src / sys / netinet / udp_usrreq.c
index ece5206..3995898 100644 (file)
@@ -1,4 +1,4 @@
-/*     udp_usrreq.c    4.37    82/10/20        */
+/*     udp_usrreq.c    4.50    83/06/14        */
 
 #include "../h/param.h"
 #include "../h/dir.h"
 
 #include "../h/param.h"
 #include "../h/dir.h"
@@ -7,9 +7,12 @@
 #include "../h/protosw.h"
 #include "../h/socket.h"
 #include "../h/socketvar.h"
 #include "../h/protosw.h"
 #include "../h/socket.h"
 #include "../h/socketvar.h"
-#include "../netinet/in.h"
+#include "../h/errno.h"
+
 #include "../net/if.h"
 #include "../net/route.h"
 #include "../net/if.h"
 #include "../net/route.h"
+
+#include "../netinet/in.h"
 #include "../netinet/in_pcb.h"
 #include "../netinet/in_systm.h"
 #include "../netinet/ip.h"
 #include "../netinet/in_pcb.h"
 #include "../netinet/in_systm.h"
 #include "../netinet/ip.h"
@@ -17,7 +20,6 @@
 #include "../netinet/ip_icmp.h"
 #include "../netinet/udp.h"
 #include "../netinet/udp_var.h"
 #include "../netinet/ip_icmp.h"
 #include "../netinet/udp.h"
 #include "../netinet/udp_var.h"
-#include <errno.h>
 
 /*
  * UDP protocol implementation.
 
 /*
  * UDP protocol implementation.
@@ -76,7 +78,6 @@ udp_input(m0)
                ui->ui_len = htons((u_short)len);
                if (ui->ui_sum = in_cksum(m, len + sizeof (struct ip))) {
                        udpstat.udps_badsum++;
                ui->ui_len = htons((u_short)len);
                if (ui->ui_sum = in_cksum(m, len + sizeof (struct ip))) {
                        udpstat.udps_badsum++;
-                       printf("udp cksum %x\n", ui->ui_sum);
                        m_freem(m);
                        return;
                }
                        m_freem(m);
                        return;
                }
@@ -89,11 +90,8 @@ udp_input(m0)
            ui->ui_src, ui->ui_sport, ui->ui_dst, ui->ui_dport,
                INPLOOKUP_WILDCARD);
        if (inp == 0) {
            ui->ui_src, ui->ui_sport, ui->ui_dst, ui->ui_dport,
                INPLOOKUP_WILDCARD);
        if (inp == 0) {
-               struct in_addr broadcastaddr;
-
-               broadcastaddr =
-                   if_makeaddr(in_netof((int)ui->ui_dst.s_net), INADDR_ANY);
-               if (ui->ui_dst.s_addr == broadcastaddr.s_addr)
+               /* don't send ICMP response for broadcast packet */
+               if (in_lnaof(ui->ui_dst) == INADDR_ANY)
                        goto bad;
                icmp_error((struct ip *)ui, ICMP_UNREACH, ICMP_UNREACH_PORT);
                return;
                        goto bad;
                icmp_error((struct ip *)ui, ICMP_UNREACH, ICMP_UNREACH_PORT);
                return;
@@ -107,10 +105,9 @@ udp_input(m0)
        udp_in.sin_addr = ui->ui_src;
        m->m_len -= sizeof (struct udpiphdr);
        m->m_off += sizeof (struct udpiphdr);
        udp_in.sin_addr = ui->ui_src;
        m->m_len -= sizeof (struct udpiphdr);
        m->m_off += sizeof (struct udpiphdr);
-SBCHECK(&inp->inp_socket->so_rcv, "udpinput before");
-       if (sbappendaddr(&inp->inp_socket->so_rcv, (struct sockaddr *)&udp_in, m) == 0)
+       if (sbappendaddr(&inp->inp_socket->so_rcv, (struct sockaddr *)&udp_in,
+           m, (struct mbuf *)0) == 0)
                goto bad;
                goto bad;
-SBCHECK(&inp->inp_socket->so_rcv, "udpinput after");
        sorwakeup(inp->inp_socket);
        return;
 bad:
        sorwakeup(inp->inp_socket);
        return;
 bad:
@@ -163,6 +160,7 @@ udp_output(inp, m0)
        register struct udpiphdr *ui;
        register struct socket *so;
        register int len = 0;
        register struct udpiphdr *ui;
        register struct socket *so;
        register int len = 0;
+       int flags;
 
        /*
         * Calculate data length and get a mbuf
 
        /*
         * Calculate data length and get a mbuf
@@ -170,7 +168,7 @@ udp_output(inp, m0)
         */
        for (m = m0; m; m = m->m_next)
                len += m->m_len;
         */
        for (m = m0; m; m = m->m_next)
                len += m->m_len;
-       m = m_get(M_DONTWAIT);
+       m = m_get(M_DONTWAIT, MT_HEADER);
        if (m == 0) {
                m_freem(m0);
                return (ENOBUFS);
        if (m == 0) {
                m_freem(m0);
                return (ENOBUFS);
@@ -202,39 +200,47 @@ udp_output(inp, m0)
        ((struct ip *)ui)->ip_len = sizeof (struct udpiphdr) + len;
        ((struct ip *)ui)->ip_ttl = MAXTTL;
        so = inp->inp_socket;
        ((struct ip *)ui)->ip_len = sizeof (struct udpiphdr) + len;
        ((struct ip *)ui)->ip_ttl = MAXTTL;
        so = inp->inp_socket;
-       return (ip_output(m, (struct mbuf *)0,
-           (so->so_options & SO_DONTROUTE) ? &routetoif : (struct route *)0,
-           so->so_state & SS_PRIV));
+       flags = (so->so_options & SO_DONTROUTE) | (so->so_state & SS_PRIV);
+       return (ip_output(m, (struct mbuf *)0, (struct route *)0, flags));
 }
 
 /*ARGSUSED*/
 }
 
 /*ARGSUSED*/
-udp_usrreq(so, req, m, nam, opt)
+udp_usrreq(so, req, m, nam, rights)
        struct socket *so;
        int req;
        struct socket *so;
        int req;
-       struct mbuf *m, *nam;
-       struct socketopt *opt;
+       struct mbuf *m, *nam, *rights;
 {
        struct inpcb *inp = sotoinpcb(so);
        int error = 0;
 
 {
        struct inpcb *inp = sotoinpcb(so);
        int error = 0;
 
-       if (inp == 0 && req != PRU_ATTACH)
-               return (EINVAL);
+       if (rights && rights->m_len) {
+               error = EINVAL;
+               goto release;
+       }
+       if (inp == NULL && req != PRU_ATTACH) {
+               error = EINVAL;
+               goto release;
+       }
        switch (req) {
 
        case PRU_ATTACH:
        switch (req) {
 
        case PRU_ATTACH:
-               if (inp != 0)
-                       return (EINVAL);
+               if (inp != NULL) {
+                       error = EINVAL;
+                       break;
+               }
                error = in_pcballoc(so, &udb);
                if (error)
                        break;
                error = in_pcballoc(so, &udb);
                if (error)
                        break;
-               error = in_pcbreserve(so, 2048, 2048);
+               error = soreserve(so, 2048, 2048);
                if (error)
                        break;
                break;
 
        case PRU_DETACH:
                if (error)
                        break;
                break;
 
        case PRU_DETACH:
-               if (inp == 0)
-                       return (ENOTCONN);
+               if (inp == NULL) {
+                       error = ENOTCONN;
+                       break;
+               }
                in_pcbdetach(inp);
                break;
 
                in_pcbdetach(inp);
                break;
 
@@ -247,19 +253,28 @@ udp_usrreq(so, req, m, nam, opt)
                break;
 
        case PRU_CONNECT:
                break;
 
        case PRU_CONNECT:
-               if (inp->inp_faddr.s_addr)
-                       return (EISCONN);
+               if (inp->inp_faddr.s_addr != INADDR_ANY) {
+                       error = EISCONN;
+                       break;
+               }
                error = in_pcbconnect(inp, nam);
                if (error == 0)
                        soisconnected(so);
                break;
 
                error = in_pcbconnect(inp, nam);
                if (error == 0)
                        soisconnected(so);
                break;
 
+       case PRU_CONNECT2:
+               error = EOPNOTSUPP;
+               break;
+
        case PRU_ACCEPT:
        case PRU_ACCEPT:
-               return (EOPNOTSUPP);
+               error = EOPNOTSUPP;
+               break;
 
        case PRU_DISCONNECT:
 
        case PRU_DISCONNECT:
-               if (inp->inp_faddr.s_addr == 0)
-                       return (ENOTCONN);
+               if (inp->inp_faddr.s_addr == INADDR_ANY) {
+                       error = ENOTCONN;
+                       break;
+               }
                in_pcbdisconnect(inp);
                soisdisconnected(so);
                break;
                in_pcbdisconnect(inp);
                soisdisconnected(so);
                break;
@@ -273,16 +288,21 @@ udp_usrreq(so, req, m, nam, opt)
 
                if (nam) {
                        laddr = inp->inp_laddr;
 
                if (nam) {
                        laddr = inp->inp_laddr;
-                       if (inp->inp_faddr.s_addr)
-                               return (EISCONN);
+                       if (inp->inp_faddr.s_addr != INADDR_ANY) {
+                               error = EISCONN;
+                               break;
+                       }
                        error = in_pcbconnect(inp, nam);
                        if (error)
                                break;
                } else {
                        error = in_pcbconnect(inp, nam);
                        if (error)
                                break;
                } else {
-                       if (inp->inp_faddr.s_addr == 0)
-                               return (ENOTCONN);
+                       if (inp->inp_faddr.s_addr == INADDR_ANY) {
+                               error = ENOTCONN;
+                               break;
+                       }
                }
                error = udp_output(inp, m);
                }
                error = udp_output(inp, m);
+               m = NULL;
                if (nam) {
                        in_pcbdisconnect(inp);
                        inp->inp_laddr = laddr;
                if (nam) {
                        in_pcbdisconnect(inp);
                        inp->inp_laddr = laddr;
@@ -296,15 +316,34 @@ udp_usrreq(so, req, m, nam, opt)
                soisdisconnected(so);
                break;
 
                soisdisconnected(so);
                break;
 
-       case PRU_CONTROL:
-               return (EOPNOTSUPP);
-
        case PRU_SOCKADDR:
                in_setsockaddr(inp, nam);
                break;
 
        case PRU_SOCKADDR:
                in_setsockaddr(inp, nam);
                break;
 
+       case PRU_CONTROL:
+               m = NULL;
+               error = EOPNOTSUPP;
+               break;
+
+       case PRU_SENSE:
+               m = NULL;
+               /* fall thru... */
+
+       case PRU_RCVD:
+       case PRU_RCVOOB:
+       case PRU_SENDOOB:
+       case PRU_FASTTIMO:
+       case PRU_SLOWTIMO:
+       case PRU_PROTORCV:
+       case PRU_PROTOSEND:
+               error =  EOPNOTSUPP;
+               break;
+
        default:
                panic("udp_usrreq");
        }
        default:
                panic("udp_usrreq");
        }
+release:
+       if (m != NULL)
+               m_freem(m);
        return (error);
 }
        return (error);
 }