remove ip_ctlinput, do all the work in higher level ctlinput's
[unix-history] / usr / src / sys / netinet / udp_usrreq.c
index 5a830d3..568437c 100644 (file)
@@ -1,26 +1,26 @@
-/*     udp_usrreq.c    6.6     84/08/21        */
-
-#include "../h/param.h"
-#include "../h/dir.h"
-#include "../h/user.h"
-#include "../h/mbuf.h"
-#include "../h/protosw.h"
-#include "../h/socket.h"
-#include "../h/socketvar.h"
-#include "../h/errno.h"
-#include "../h/stat.h"
+/*     udp_usrreq.c    6.13    85/05/28        */
+
+#include "param.h"
+#include "dir.h"
+#include "user.h"
+#include "mbuf.h"
+#include "protosw.h"
+#include "socket.h"
+#include "socketvar.h"
+#include "errno.h"
+#include "stat.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/ip_var.h"
-#include "../netinet/ip_icmp.h"
-#include "../netinet/udp.h"
-#include "../netinet/udp_var.h"
+#include "in.h"
+#include "in_pcb.h"
+#include "in_systm.h"
+#include "ip.h"
+#include "ip_var.h"
+#include "ip_icmp.h"
+#include "udp.h"
+#include "udp_var.h"
 
 /*
  * UDP protocol implementation.
 
 /*
  * UDP protocol implementation.
@@ -32,7 +32,7 @@ udp_init()
        udb.inp_next = udb.inp_prev = &udb;
 }
 
        udb.inp_next = udb.inp_prev = &udb;
 }
 
-int    udpcksum = 0;
+int    udpcksum = 1;
 struct sockaddr_in udp_in = { AF_INET };
 
 udp_input(m0)
 struct sockaddr_in udp_in = { AF_INET };
 
 udp_input(m0)
@@ -76,7 +76,7 @@ udp_input(m0)
        if (udpcksum && ui->ui_sum) {
                ui->ui_next = ui->ui_prev = 0;
                ui->ui_x1 = 0;
        if (udpcksum && ui->ui_sum) {
                ui->ui_next = ui->ui_prev = 0;
                ui->ui_x1 = 0;
-               ui->ui_len = htons((u_short)len);
+               ui->ui_len = ui->ui_ulen;
                if (ui->ui_sum = in_cksum(m, len + sizeof (struct ip))) {
                        udpstat.udps_badsum++;
                        m_freem(m);
                if (ui->ui_sum = in_cksum(m, len + sizeof (struct ip))) {
                        udpstat.udps_badsum++;
                        m_freem(m);
@@ -92,7 +92,7 @@ udp_input(m0)
                INPLOOKUP_WILDCARD);
        if (inp == 0) {
                /* don't send ICMP response for broadcast packet */
                INPLOOKUP_WILDCARD);
        if (inp == 0) {
                /* don't send ICMP response for broadcast packet */
-               if (in_lnaof(ui->ui_dst) == INADDR_ANY)
+               if (in_broadcast(ui->ui_dst))
                        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;
@@ -128,8 +128,9 @@ udp_ctlinput(cmd, arg)
        int cmd;
        caddr_t arg;
 {
        int cmd;
        caddr_t arg;
 {
-       struct in_addr *sin;
+       struct in_addr *in;
        extern u_char inetctlerrmap[];
        extern u_char inetctlerrmap[];
+       int in_rtchange();
 
        if (cmd < 0 || cmd > PRC_NCMDS)
                return;
 
        if (cmd < 0 || cmd > PRC_NCMDS)
                return;
@@ -138,18 +139,27 @@ udp_ctlinput(cmd, arg)
        case PRC_ROUTEDEAD:
                break;
 
        case PRC_ROUTEDEAD:
                break;
 
-       case PRC_QUENCH:
+       case PRC_REDIRECT_NET:
+       case PRC_REDIRECT_HOST:
+               in = &((struct icmp *)arg)->icmp_ip.ip_dst;
+               in_pcbnotify(&udb, in, 0, in_rtchange);
                break;
 
                break;
 
-       /* these are handled by ip */
        case PRC_IFDOWN:
        case PRC_IFDOWN:
+               in = &((struct sockaddr_in *)arg)->sin_addr;
+               goto notify;
+
        case PRC_HOSTDEAD:
        case PRC_HOSTUNREACH:
        case PRC_HOSTDEAD:
        case PRC_HOSTUNREACH:
-               break;
+               in = (struct in_addr *)arg;
+               goto notify;
 
        default:
 
        default:
-               sin = &((struct icmp *)arg)->icmp_ip.ip_dst;
-               in_pcbnotify(&udb, sin, (int)inetctlerrmap[cmd], udp_abort);
+               if (inetctlerrmap[cmd] == 0)
+                       return;         /* XXX */
+               in = &((struct icmp *)arg)->icmp_ip.ip_dst;
+notify:
+               in_pcbnotify(&udb, in, (int)inetctlerrmap[cmd], udp_abort);
        }
 }
 
        }
 }
 
@@ -169,7 +179,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, MT_HEADER);
+       MGET(m, M_DONTWAIT, MT_HEADER);
        if (m == 0) {
                m_freem(m0);
                return (ENOBUFS);
        if (m == 0) {
                m_freem(m0);
                return (ENOBUFS);
@@ -197,14 +207,16 @@ udp_output(inp, m0)
         * Stuff checksum and output datagram.
         */
        ui->ui_sum = 0;
         * Stuff checksum and output datagram.
         */
        ui->ui_sum = 0;
-       if ((ui->ui_sum = in_cksum(m, sizeof (struct udpiphdr) + len)) == 0)
+       if (udpcksum) {
+           if ((ui->ui_sum = in_cksum(m, sizeof (struct udpiphdr) + len)) == 0)
                ui->ui_sum = -1;
                ui->ui_sum = -1;
+       }
        ((struct ip *)ui)->ip_len = sizeof (struct udpiphdr) + len;
        ((struct ip *)ui)->ip_ttl = MAXTTL;
        so = inp->inp_socket;
        if (so->so_options & SO_DONTROUTE)
                return (ip_output(m, (struct mbuf *)0, (struct route *)0,
        ((struct ip *)ui)->ip_len = sizeof (struct udpiphdr) + len;
        ((struct ip *)ui)->ip_ttl = MAXTTL;
        so = inp->inp_socket;
        if (so->so_options & SO_DONTROUTE)
                return (ip_output(m, (struct mbuf *)0, (struct route *)0,
-                   (so->so_state & SS_PRIV) | IP_ROUTETOIF));
+                   (so->so_options & SO_BROADCAST) | IP_ROUTETOIF));
        /*
         * Use cached route for previous datagram if
         * this is also to the same destination. 
        /*
         * Use cached route for previous datagram if
         * this is also to the same destination. 
@@ -219,9 +231,13 @@ udp_output(inp, m0)
                RTFREE(ro->ro_rt);
                ro->ro_rt = (struct rtentry *)0;
        }
                RTFREE(ro->ro_rt);
                ro->ro_rt = (struct rtentry *)0;
        }
-       return (ip_output(m, (struct mbuf *)0, ro, so->so_state & SS_PRIV));
+       return (ip_output(m, (struct mbuf *)0, ro, 
+           so->so_options & SO_BROADCAST));
 }
 
 }
 
+int    udp_sendspace = 2048;           /* really max datagram size */
+int    udp_recvspace = 4 * (1024+sizeof(struct sockaddr_in)); /* 4 1K dgrams */
+
 /*ARGSUSED*/
 udp_usrreq(so, req, m, nam, rights)
        struct socket *so;
 /*ARGSUSED*/
 udp_usrreq(so, req, m, nam, rights)
        struct socket *so;
@@ -231,6 +247,9 @@ udp_usrreq(so, req, m, nam, rights)
        struct inpcb *inp = sotoinpcb(so);
        int error = 0;
 
        struct inpcb *inp = sotoinpcb(so);
        int error = 0;
 
+       if (req == PRU_CONTROL)
+               return (in_control(so, (int)m, (caddr_t)nam,
+                       (struct ifnet *)rights));
        if (rights && rights->m_len) {
                error = EINVAL;
                goto release;
        if (rights && rights->m_len) {
                error = EINVAL;
                goto release;
@@ -249,7 +268,7 @@ udp_usrreq(so, req, m, nam, rights)
                error = in_pcballoc(so, &udb);
                if (error)
                        break;
                error = in_pcballoc(so, &udb);
                if (error)
                        break;
-               error = soreserve(so, 2048, 2048);
+               error = soreserve(so, udp_sendspace, udp_recvspace);
                if (error)
                        break;
                break;
                if (error)
                        break;
                break;
@@ -330,8 +349,8 @@ udp_usrreq(so, req, m, nam, rights)
                m = NULL;
                if (nam) {
                        in_pcbdisconnect(inp);
                m = NULL;
                if (nam) {
                        in_pcbdisconnect(inp);
-                       splx(s);
                        inp->inp_laddr = laddr;
                        inp->inp_laddr = laddr;
+                       splx(s);
                }
                }
                break;
                }
                }
                break;
@@ -364,7 +383,6 @@ udp_usrreq(so, req, m, nam, rights)
                error =  EOPNOTSUPP;
                break;
 
                error =  EOPNOTSUPP;
                break;
 
-       case PRU_CONTROL:
        case PRU_RCVD:
        case PRU_RCVOOB:
                return (EOPNOTSUPP);    /* do not free mbuf's */
        case PRU_RCVD:
        case PRU_RCVOOB:
                return (EOPNOTSUPP);    /* do not free mbuf's */