branch for network release (byte order #ifdefs)
[unix-history] / usr / src / sys / netinet / udp_usrreq.c
index fac561f..9245aa3 100644 (file)
@@ -1,9 +1,15 @@
 /*
 /*
- * 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 Regents of the University of California.
+ * All rights reserved.
  *
  *
- *     @(#)udp_usrreq.c        6.15 (Berkeley) %G%
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this notice is preserved and that due credit is given
+ * to the University of California at 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'' without express or implied warranty.
+ *
+ *     @(#)udp_usrreq.c        7.5 (Berkeley) %G%
  */
 
 #include "param.h"
  */
 
 #include "param.h"
@@ -38,11 +44,18 @@ udp_init()
        udb.inp_next = udb.inp_prev = &udb;
 }
 
        udb.inp_next = udb.inp_prev = &udb;
 }
 
+#ifndef        COMPAT_42
 int    udpcksum = 1;
 int    udpcksum = 1;
+#else
+int    udpcksum = 0;           /* XXX */
+#endif
+int    udp_ttl = UDP_TTL;
+
 struct sockaddr_in udp_in = { AF_INET };
 
 struct sockaddr_in udp_in = { AF_INET };
 
-udp_input(m0)
+udp_input(m0, ifp)
        struct mbuf *m0;
        struct mbuf *m0;
+       struct ifnet *ifp;
 {
        register struct udpiphdr *ui;
        register struct inpcb *inp;
 {
        register struct udpiphdr *ui;
        register struct inpcb *inp;
@@ -106,7 +119,8 @@ udp_input(m0)
                if (in_broadcast(ui->ui_dst))
                        goto bad;
                *(struct ip *)ui = ip;
                if (in_broadcast(ui->ui_dst))
                        goto bad;
                *(struct ip *)ui = ip;
-               icmp_error((struct ip *)ui, ICMP_UNREACH, ICMP_UNREACH_PORT);
+               icmp_error((struct ip *)ui, ICMP_UNREACH, ICMP_UNREACH_PORT,
+                   ifp);
                return;
        }
 
                return;
        }
 
@@ -127,6 +141,18 @@ bad:
        m_freem(m);
 }
 
        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;
 udp_ctlinput(cmd, sa)
        int cmd;
        struct sockaddr *sa;
@@ -160,19 +186,17 @@ udp_ctlinput(cmd, sa)
                if (inetctlerrmap[cmd] == 0)
                        return;         /* XXX */
                in_pcbnotify(&udb, &sin->sin_addr, (int)inetctlerrmap[cmd],
                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, m0)
-       struct inpcb *inp;
+       register struct inpcb *inp;
        struct mbuf *m0;
 {
        register struct mbuf *m;
        register struct udpiphdr *ui;
        struct mbuf *m0;
 {
        register struct mbuf *m;
        register struct udpiphdr *ui;
-       register struct socket *so;
        register int len = 0;
        register int len = 0;
-       register struct route *ro;
 
        /*
         * Calculate data length and get a mbuf
 
        /*
         * Calculate data length and get a mbuf
@@ -210,30 +234,12 @@ 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 = 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_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, inp->inp_options, (struct route *)0,
-                   (so->so_options & SO_BROADCAST) | IP_ROUTETOIF));
-       /*
-        * Use cached route for previous datagram if
-        * this is also to the same destination. 
-        *
-        * NB: We don't handle broadcasts because that
-        *     would require 3 subroutine calls.
-        */
-       ro = &inp->inp_route;
-#define        satosin(sa)     ((struct sockaddr_in *)(sa))
-       if (ro->ro_rt &&
-           satosin(&ro->ro_dst)->sin_addr.s_addr != ui->ui_dst.s_addr) {
-               RTFREE(ro->ro_rt);
-               ro->ro_rt = (struct rtentry *)0;
-       }
-       return (ip_output(m, inp->inp_options, ro, 
-           so->so_options & SO_BROADCAST));
+       ((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_sendspace = 2048;           /* really max datagram size */
@@ -275,10 +281,6 @@ udp_usrreq(so, req, m, nam, rights)
                break;
 
        case PRU_DETACH:
                break;
 
        case PRU_DETACH:
-               if (inp == NULL) {
-                       error = ENOTCONN;
-                       break;
-               }
                in_pcbdetach(inp);
                break;
 
                in_pcbdetach(inp);
                break;
 
@@ -314,7 +316,7 @@ udp_usrreq(so, req, m, nam, rights)
                        break;
                }
                in_pcbdisconnect(inp);
                        break;
                }
                in_pcbdisconnect(inp);
-               soisdisconnected(so);
+               so->so_state &= ~SS_ISCONNECTED;                /* XXX */
                break;
 
        case PRU_SHUTDOWN:
                break;
 
        case PRU_SHUTDOWN:
@@ -357,9 +359,8 @@ udp_usrreq(so, req, m, nam, rights)
                break;
 
        case PRU_ABORT:
                break;
 
        case PRU_ABORT:
-               in_pcbdetach(inp);
-               sofree(so);
                soisdisconnected(so);
                soisdisconnected(so);
+               in_pcbdetach(inp);
                break;
 
        case PRU_SOCKADDR:
                break;
 
        case PRU_SOCKADDR: