first working version
authorBill Joy <root@ucbvax.Berkeley.EDU>
Mon, 27 Sep 1982 10:30:41 +0000 (02:30 -0800)
committerBill Joy <root@ucbvax.Berkeley.EDU>
Mon, 27 Sep 1982 10:30:41 +0000 (02:30 -0800)
SCCS-vsn: sys/netinet/in_pcb.c 4.31
SCCS-vsn: sys/netinet/tcp_input.c 1.74
SCCS-vsn: sys/netinet/tcp_usrreq.c 1.62
SCCS-vsn: sys/netinet/udp_usrreq.c 4.32

usr/src/sys/netinet/in_pcb.c
usr/src/sys/netinet/tcp_input.c
usr/src/sys/netinet/tcp_usrreq.c
usr/src/sys/netinet/udp_usrreq.c

index dcdee56..513ac48 100644 (file)
@@ -1,4 +1,4 @@
-/*     in_pcb.c        4.30    82/07/24        */
+/*     in_pcb.c        4.31    82/09/26        */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
 #include "../net/in_pcb.h"
 #include "../h/protosw.h"
 
 #include "../net/in_pcb.h"
 #include "../h/protosw.h"
 
-/*
- * Routines to manage internet protocol control blocks.
- *
- * At PRU_ATTACH time a protocol control block is allocated in
- * in_pcballoc() and inserted on a doubly-linked list of such blocks
- * for the protocol.  A port address is either requested (and verified
- * to not be in use) or assigned at this time.  We also allocate
- * space in the socket sockbuf structures here, although this is
- * not a clearly correct place to put this function.
- *
- * A connectionless protocol will have its protocol control block
- * removed at PRU_DETACH time, when the socket will be freed (freeing
- * the space reserved) and the block will be removed from the list of
- * blocks for its protocol.
- *
- * A connection-based protocol may be connected to a remote peer at
- * PRU_CONNECT time through the routine in_pcbconnect().  In the normal
- * case a PRU_DISCONNECT occurs causing a in_pcbdisconnect().
- * It is also possible that higher-level routines will opt out of the
- * relationship with the connection before the connection shut down
- * is complete.  This often occurs in protocols like TCP where we must
- * hold on to the protocol control block for a unreasonably long time
- * after the connection is used up to avoid races in later connection
- * establishment.  To handle this we allow higher-level routines to
- * disassociate themselves from the socket, marking it SS_NOFDREF while
- * the disconnect is in progress.  We notice that this has happened
- * when the disconnect is complete, and perform the PRU_DETACH operation,
- * freeing the socket.
- *
- * TODO:
- *     use hashing
- */
 struct in_addr zeroin_addr;
 
 in_pcbreserve(so, sndcc, rcvcc)
 struct in_addr zeroin_addr;
 
 in_pcbreserve(so, sndcc, rcvcc)
@@ -82,116 +50,51 @@ in_pcballoc(so, head)
        return (0);
 }
        
        return (0);
 }
        
-in_pcbbind(inp, sin)
+in_pcbbind(inp, nam)
        register struct inpcb *inp;
        register struct inpcb *inp;
-       struct sockaddr_in *sin;
+       struct mbuf *nam;
 {
        register struct socket *so = inp->inp_socket;
        register struct inpcb *head = inp->inp_head;
 {
        register struct socket *so = inp->inp_socket;
        register struct inpcb *head = inp->inp_head;
+       register struct sockaddr_in *sin;
        u_short lport = 0;
 
        if (ifnet == 0)
                return (EADDRNOTAVAIL);
        u_short lport = 0;
 
        if (ifnet == 0)
                return (EADDRNOTAVAIL);
-       if (sin) {
-               if (sin->sin_family != AF_INET)
-                       return (EAFNOSUPPORT);
-               if (sin->sin_addr.s_addr) {
-                       int tport = sin->sin_port;
+       if (inp->inp_lport || inp->inp_laddr.s_addr)
+               return (EINVAL);
+       if (nam == 0)
+               goto noname;
+       sin = mtod(nam, struct sockaddr_in *);
+       if (nam->m_len != sizeof (*sin))
+               return (EINVAL);
+       if (sin->sin_addr.s_addr) {
+               int tport = sin->sin_port;
 
 
-                       sin->sin_port = 0;              /* yech... */
-                       if (if_ifwithaddr((struct sockaddr *)sin) == 0)
-                               return (EADDRNOTAVAIL);
-                       sin->sin_port = tport;
-               }
-               lport = sin->sin_port;
-               if (lport) {
-                       u_short aport = lport;
-                       int wild = 0;
-#if vax
-                       aport = htons(aport);
-#endif
-                       /* GROSS */
-                       if (aport < IPPORT_RESERVED && u.u_uid != 0)
-                               return (EACCES);
-                       if ((so->so_proto->pr_flags & PR_CONNREQUIRED) == 0 ||
-                           (so->so_options & SO_ACCEPTCONN) == 0)
-                               wild = INPLOOKUP_WILDCARD;
-                       if (in_pcblookup(head,
-                           zeroin_addr, 0, sin->sin_addr, lport, wild))
-                               return (EADDRINUSE);
-               }
+               sin->sin_port = 0;              /* yech... */
+               if (if_ifwithaddr((struct sockaddr *)sin) == 0)
+                       return (EADDRNOTAVAIL);
+               sin->sin_port = tport;
        }
        }
-       if (sin)
-               inp->inp_laddr = sin->sin_addr;
-       if (lport == 0)
-               do {
-                       if (head->inp_lport++ < IPPORT_RESERVED)
-                               head->inp_lport = IPPORT_RESERVED;
-                       lport = htons(head->inp_lport);
-               } while (in_pcblookup(head,
-                           zeroin_addr, 0, inp->inp_laddr, lport, 0));
-       inp->inp_lport = lport;
-       return (0);
-}
-
-/* BEGIN DEPRECATED */
-/*
- * Allocate a protocol control block, space
- * for send and receive data, and local host information.
- * Return error.  If no error make socket point at pcb.
- */
-in_pcbattach(so, head, sndcc, rcvcc, sin)
-       struct socket *so;
-       struct inpcb *head;
-       int sndcc, rcvcc;
-       struct sockaddr_in *sin;
-{
-       struct mbuf *m;
-       register struct inpcb *inp;
-       u_short lport = 0;
-
-       if (ifnet == 0)
-               return (EADDRNOTAVAIL);
-       if (sin) {
-               if (sin->sin_family != AF_INET)
-                       return (EAFNOSUPPORT);
-               if (sin->sin_addr.s_addr) {
-                       int tport = sin->sin_port;
+       lport = sin->sin_port;
+       if (lport) {
+               u_short aport = lport;
+               int wild = 0;
 
 
-                       sin->sin_port = 0;              /* yech... */
-                       if (if_ifwithaddr((struct sockaddr *)sin) == 0)
-                               return (EADDRNOTAVAIL);
-                       sin->sin_port = tport;
-               }
-               lport = sin->sin_port;
-               if (lport) {
-                       u_short aport = lport;
-                       int wild = 0;
 #if vax
 #if vax
-                       aport = htons(aport);
+               aport = htons(aport);
 #endif
 #endif
-                       /* GROSS */
-                       if (aport < IPPORT_RESERVED && u.u_uid != 0)
-                               return (EACCES);
-                       if ((so->so_proto->pr_flags & PR_CONNREQUIRED) == 0 ||
-                           (so->so_options & SO_ACCEPTCONN) == 0)
-                               wild = INPLOOKUP_WILDCARD;
-                       if (in_pcblookup(head,
-                           zeroin_addr, 0, sin->sin_addr, lport, wild))
-                               return (EADDRINUSE);
-               }
+               /* GROSS */
+               if (aport < IPPORT_RESERVED && u.u_uid != 0)
+                       return (EACCES);
+               if ((so->so_proto->pr_flags & PR_CONNREQUIRED) == 0)
+                       wild = INPLOOKUP_WILDCARD;
+               if (in_pcblookup(head,
+                   zeroin_addr, 0, sin->sin_addr, lport, wild))
+                       return (EADDRINUSE);
        }
        }
-       m = m_getclr(M_DONTWAIT);
-       if (m == 0)
-               return (ENOBUFS);
-       if (sbreserve(&so->so_snd, sndcc) == 0)
-               goto bad;
-       if (sbreserve(&so->so_rcv, rcvcc) == 0)
-               goto bad2;
-       inp = mtod(m, struct inpcb *);
-       inp->inp_head = head;
-       if (sin)
-               inp->inp_laddr = sin->sin_addr;
+       inp->inp_laddr = sin->sin_addr;
+noname:
        if (lport == 0)
                do {
                        if (head->inp_lport++ < IPPORT_RESERVED)
        if (lport == 0)
                do {
                        if (head->inp_lport++ < IPPORT_RESERVED)
@@ -200,17 +103,8 @@ in_pcbattach(so, head, sndcc, rcvcc, sin)
                } while (in_pcblookup(head,
                            zeroin_addr, 0, inp->inp_laddr, lport, 0));
        inp->inp_lport = lport;
                } while (in_pcblookup(head,
                            zeroin_addr, 0, inp->inp_laddr, lport, 0));
        inp->inp_lport = lport;
-       inp->inp_socket = so;
-       insque(inp, head);
-       so->so_pcb = (caddr_t)inp;
        return (0);
        return (0);
-bad2:
-       sbrelease(&so->so_snd);
-bad:
-       (void) m_free(m);
-       return (ENOBUFS);
 }
 }
-/* END DEPRECATED */
 
 /*
  * Connect from a socket to a specified address.
 
 /*
  * Connect from a socket to a specified address.
@@ -218,13 +112,16 @@ bad:
  * If don't have a local address for this socket yet,
  * then pick one.
  */
  * If don't have a local address for this socket yet,
  * then pick one.
  */
-in_pcbconnect(inp, sin)
+in_pcbconnect(inp, nam)
        struct inpcb *inp;
        struct inpcb *inp;
-       struct sockaddr_in *sin;
+       struct mbuf *nam;
 {
        struct ifnet *ifp;
        struct sockaddr_in *ifaddr;
 {
        struct ifnet *ifp;
        struct sockaddr_in *ifaddr;
+       register struct sockaddr_in *sin = mtod(nam, struct sockaddr_in *);
 
 
+       if (nam->m_len != sizeof (*sin))
+               return (EINVAL);
        if (sin->sin_family != AF_INET)
                return (EAFNOSUPPORT);
        if (sin->sin_addr.s_addr == 0 || sin->sin_port == 0)
        if (sin->sin_family != AF_INET)
                return (EAFNOSUPPORT);
        if (sin->sin_addr.s_addr == 0 || sin->sin_port == 0)
@@ -281,12 +178,14 @@ in_pcbdetach(inp)
        (void) m_free(dtom(inp));
 }
 
        (void) m_free(dtom(inp));
 }
 
-in_setsockaddr(sin, inp)
-       register struct sockaddr_in *sin;
+in_setsockaddr(inp, nam)
        register struct inpcb *inp;
        register struct inpcb *inp;
+       struct mbuf *nam;
 {
 {
-       if (sin == 0 || inp == 0)
-               panic("setsockaddr_in");
+       register struct sockaddr_in *sin = mtod(nam, struct sockaddr_in *);
+       
+       nam->m_len = sizeof (*sin);
+       sin = mtod(nam, struct sockaddr_in *);
        bzero((caddr_t)sin, sizeof (*sin));
        sin->sin_family = AF_INET;
        sin->sin_port = inp->inp_lport;
        bzero((caddr_t)sin, sizeof (*sin));
        sin->sin_family = AF_INET;
        sin->sin_port = inp->inp_lport;
@@ -323,9 +222,6 @@ in_pcbnotify(head, dst, errno, abort)
        splx(s);
 }
 
        splx(s);
 }
 
-/*
- * SHOULD ALLOW MATCH ON MULTI-HOMING ONLY
- */
 struct inpcb *
 in_pcblookup(head, faddr, fport, laddr, lport, flags)
        struct inpcb *head;
 struct inpcb *
 in_pcblookup(head, faddr, fport, laddr, lport, flags)
        struct inpcb *head;
index 4e4b2ff..b173e14 100644 (file)
@@ -1,4 +1,4 @@
-/*     tcp_input.c     1.73    82/07/24        */
+/*     tcp_input.c     1.74    82/09/26        */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
@@ -24,7 +24,7 @@
 
 int    tcpprintfs = 0;
 int    tcpcksum = 1;
 
 int    tcpprintfs = 0;
 int    tcpcksum = 1;
-struct sockaddr_in tcp_in = { AF_INET };
+struct mbuf tcp_mb;
 struct tcpiphdr tcp_saveti;
 extern tcpnodelack;
 
 struct tcpiphdr tcp_saveti;
 extern tcpnodelack;
 
@@ -133,8 +133,7 @@ tcp_input(m0)
 #endif
 
        /*
 #endif
 
        /*
-        * Locate pcb for segment.  On match, update the local
-        * address stored in the block to reflect anchoring.
+        * Locate pcb for segment.
         */
        inp = in_pcblookup
                (&tcb, ti->ti_src, ti->ti_sport, ti->ti_dst, ti->ti_dport,
         */
        inp = in_pcblookup
                (&tcb, ti->ti_src, ti->ti_sport, ti->ti_dst, ti->ti_dport,
@@ -202,22 +201,33 @@ tcp_input(m0)
         * Enter SYN_RECEIVED state, and process any other fields of this
         * segment in this state.
         */
         * Enter SYN_RECEIVED state, and process any other fields of this
         * segment in this state.
         */
-       case TCPS_LISTEN:
+       case TCPS_LISTEN: {
+               struct mbuf *m = m_get(M_DONTWAIT);
+               register struct sockaddr_in *sin;
+
+               if (m == 0)
+                       goto drop;
+               m->m_off = MMINOFF;
+               m->m_len = sizeof (struct sockaddr_in);
                if (tiflags & TH_RST)
                        goto drop;
                if (tiflags & TH_ACK)
                        goto dropwithreset;
                if ((tiflags & TH_SYN) == 0)
                        goto drop;
                if (tiflags & TH_RST)
                        goto drop;
                if (tiflags & TH_ACK)
                        goto dropwithreset;
                if ((tiflags & TH_SYN) == 0)
                        goto drop;
-               tcp_in.sin_addr = ti->ti_src;
-               tcp_in.sin_port = ti->ti_sport;
+               sin = mtod(m, struct sockaddr_in *);
+               sin->sin_family = AF_INET;
+               sin->sin_addr = ti->ti_src;
+               sin->sin_port = ti->ti_sport;
                laddr = inp->inp_laddr;
                if (inp->inp_laddr.s_addr == 0)
                        inp->inp_laddr = ti->ti_dst;
                laddr = inp->inp_laddr;
                if (inp->inp_laddr.s_addr == 0)
                        inp->inp_laddr = ti->ti_dst;
-               if (in_pcbconnect(inp, (struct sockaddr_in *)&tcp_in)) {
+               if (in_pcbconnect(inp, m)) {
                        inp->inp_laddr = laddr;
                        inp->inp_laddr = laddr;
+                       m_free(m);
                        goto drop;
                }
                        goto drop;
                }
+               m_free(m);
                tp->t_template = tcp_template(tp);
                if (tp->t_template == 0) {
                        in_pcbdisconnect(inp);
                tp->t_template = tcp_template(tp);
                if (tp->t_template == 0) {
                        in_pcbdisconnect(inp);
@@ -232,6 +242,7 @@ tcp_input(m0)
                tp->t_state = TCPS_SYN_RECEIVED;
                tp->t_timer[TCPT_KEEP] = TCPTV_KEEP;
                goto trimthenstep6;
                tp->t_state = TCPS_SYN_RECEIVED;
                tp->t_timer[TCPT_KEEP] = TCPTV_KEEP;
                goto trimthenstep6;
+               }
 
        /*
         * If the state is SYN_SENT:
 
        /*
         * If the state is SYN_SENT:
index 02a468d..37e8541 100644 (file)
@@ -1,4 +1,4 @@
-/*     tcp_usrreq.c    1.61    82/07/24        */
+/*     tcp_usrreq.c    1.62    82/09/26        */
 
 #include "../h/param.h"
 #include "../h/systm.h"
 
 #include "../h/param.h"
 #include "../h/systm.h"
@@ -33,11 +33,11 @@ struct      tcpcb *tcp_newtcpcb();
  * then m is the mbuf chain of send data.  If this is a timer expiration
  * (called from the software clock routine), then timertype tells which timer.
  */
  * then m is the mbuf chain of send data.  If this is a timer expiration
  * (called from the software clock routine), then timertype tells which timer.
  */
-tcp_usrreq(so, req, m, addr)
+tcp_usrreq(so, req, m, nam, opt)
        struct socket *so;
        int req;
        struct socket *so;
        int req;
-       struct mbuf *m;
-       caddr_t addr;
+       struct mbuf *m, *nam;
+       struct socketopt *opt;
 {
        register struct inpcb *inp = sotoinpcb(so);
        register struct tcpcb *tp;
 {
        register struct inpcb *inp = sotoinpcb(so);
        register struct tcpcb *tp;
@@ -49,16 +49,6 @@ tcp_usrreq(so, req, m, addr)
         * When a TCP is attached to a socket, then there will be
         * a (struct inpcb) pointed at by the socket, and this
         * structure will point at a subsidary (struct tcpcb).
         * When a TCP is attached to a socket, then there will be
         * a (struct inpcb) pointed at by the socket, and this
         * structure will point at a subsidary (struct tcpcb).
-        * The normal sequence of events is:
-        *      PRU_ATTACH              creating these structures
-        *      PRU_CONNECT             connecting to a remote peer
-        *      (PRU_SEND|PRU_RCVD)*    exchanging data
-        *      PRU_DISCONNECT          disconnecting from remote peer
-        *      PRU_DETACH              deleting the structures
-        * With the operations from PRU_CONNECT through PRU_DISCONNECT
-        * possible repeated several times.
-        *
-        * MULTIPLE CONNECTS ARE NOT YET IMPLEMENTED.
         */
        if (inp == 0 && req != PRU_ATTACH) {
                splx(s);
         */
        if (inp == 0 && req != PRU_ATTACH) {
                splx(s);
@@ -66,6 +56,7 @@ tcp_usrreq(so, req, m, addr)
        }
        if (inp) {
                tp = intotcpcb(inp);
        }
        if (inp) {
                tp = intotcpcb(inp);
+               /* WHAT IF TP IS 0? */
 #ifdef KPROF
                tcp_acounts[tp->t_state][req]++;
 #endif
 #ifdef KPROF
                tcp_acounts[tp->t_state][req]++;
 #endif
@@ -76,16 +67,14 @@ tcp_usrreq(so, req, m, addr)
 
        /*
         * TCP attaches to socket via PRU_ATTACH, reserving space,
 
        /*
         * TCP attaches to socket via PRU_ATTACH, reserving space,
-        * and internet and TCP control blocks.
-        * If the socket is to receive connections,
-        * then the LISTEN state is entered.
+        * and an internet control block.
         */
        case PRU_ATTACH:
                if (inp) {
                        error = EISCONN;
                        break;
                }
         */
        case PRU_ATTACH:
                if (inp) {
                        error = EISCONN;
                        break;
                }
-               error = tcp_attach(so, (struct sockaddr *)addr);
+               error = tcp_attach(so, nam);
                if (error)
                        break;
                if ((so->so_options & SO_DONTLINGER) == 0)
                if (error)
                        break;
                if ((so->so_options & SO_DONTLINGER) == 0)
@@ -109,6 +98,25 @@ tcp_usrreq(so, req, m, addr)
                }
                break;
 
                }
                break;
 
+       /*
+        * Give the socket an address.
+        */
+       case PRU_BIND:
+               error = in_pcbbind(inp, nam);
+               if (error)
+                       break;
+               break;
+
+       /*
+        * Prepare to accept connections.
+        */
+       case PRU_LISTEN:
+               if (inp->inp_lport == 0)
+                       error = in_pcbbind(inp, (struct mbuf *)0);
+               if (error == 0)
+                       tp->t_state = TCPS_LISTEN;
+               break;
+
        /*
         * Initiate connection to peer.
         * Create a template for use in transmissions on this connection.
        /*
         * Initiate connection to peer.
         * Create a template for use in transmissions on this connection.
@@ -117,7 +125,12 @@ tcp_usrreq(so, req, m, addr)
         * Send initial segment on connection.
         */
        case PRU_CONNECT:
         * Send initial segment on connection.
         */
        case PRU_CONNECT:
-               error = in_pcbconnect(inp, (struct sockaddr_in *)addr);
+               if (inp->inp_lport == 0) {
+                       error = in_pcbbind(inp, (struct mbuf *)0);
+                       if (error)
+                               break;
+               }
+               error = in_pcbconnect(inp, nam);
                if (error)
                        break;
                tp->t_template = tcp_template(tp);
                if (error)
                        break;
                tp->t_template = tcp_template(tp);
@@ -155,16 +168,14 @@ tcp_usrreq(so, req, m, addr)
         * of the peer, storing through addr.
         */
        case PRU_ACCEPT: {
         * of the peer, storing through addr.
         */
        case PRU_ACCEPT: {
-               struct sockaddr_in *sin = (struct sockaddr_in *)addr;
+               struct sockaddr_in *sin = mtod(nam, struct sockaddr_in *);
 
 
-               if (sin) {
-                       bzero((caddr_t)sin, sizeof (*sin));
-                       sin->sin_family = AF_INET;
-                       sin->sin_port = inp->inp_fport;
-                       sin->sin_addr = inp->inp_faddr;
-               }
-               }
+               nam->m_len = sizeof (struct sockaddr_in);
+               sin->sin_family = AF_INET;
+               sin->sin_port = inp->inp_fport;
+               sin->sin_addr = inp->inp_faddr;
                break;
                break;
+               }
 
        /*
         * Mark the connection as being incapable of further output.
 
        /*
         * Mark the connection as being incapable of further output.
@@ -253,7 +264,7 @@ tcp_usrreq(so, req, m, addr)
                break;
 
        case PRU_SOCKADDR:
                break;
 
        case PRU_SOCKADDR:
-               in_setsockaddr((struct sockaddr_in *)addr, inp);
+               in_setsockaddr(inp, nam);
                break;
 
        /*
                break;
 
        /*
@@ -261,8 +272,8 @@ tcp_usrreq(so, req, m, addr)
         * routine for tracing's sake.
         */
        case PRU_SLOWTIMO:
         * routine for tracing's sake.
         */
        case PRU_SLOWTIMO:
-               tcp_timers(tp, (int)addr);
-               req |= (int)addr << 8;          /* for debug's sake */
+               tcp_timers(tp, (int)nam);
+               req |= (int)nam << 8;           /* for debug's sake */
                break;
 
        default:
                break;
 
        default:
@@ -281,9 +292,8 @@ int tcp_recvspace = 1024*2;
  * internet protocol control block, tcp control block,
  * bufer space, and entering LISTEN state if to accept connections.
  */
  * internet protocol control block, tcp control block,
  * bufer space, and entering LISTEN state if to accept connections.
  */
-tcp_attach(so, sa)
+tcp_attach(so)
        struct socket *so;
        struct socket *so;
-       struct sockaddr *sa;
 {
        register struct tcpcb *tp;
        struct inpcb *inp;
 {
        register struct tcpcb *tp;
        struct inpcb *inp;
@@ -294,20 +304,14 @@ tcp_attach(so, sa)
                goto bad;
        error = in_pcballoc(so, &tcb);
        if (error)
                goto bad;
        error = in_pcballoc(so, &tcb);
        if (error)
-               goto bad2;
-       inp = (struct inpcb *)so->so_pcb;
-       if (sa || ((so->so_options & SO_ACCEPTCONN) == 0 && so->so_head == 0)) {
-               error = in_pcbbind(inp, sa);
-               if (error)
-                       goto bad2;
-       }
+               goto bad;
+       inp = sotoinpcb(so);
        tp = tcp_newtcpcb(inp);
        if (tp == 0) {
                error = ENOBUFS;
                goto bad2;
        }
        tp = tcp_newtcpcb(inp);
        if (tp == 0) {
                error = ENOBUFS;
                goto bad2;
        }
-       tp->t_state =
-           (so->so_options & SO_ACCEPTCONN) ? TCPS_LISTEN : TCPS_CLOSED;
+       tp->t_state = TCPS_CLOSED;
        return (0);
 bad2:
        in_pcbdetach(inp);
        return (0);
 bad2:
        in_pcbdetach(inp);
index 3a2893a..6c2e535 100644 (file)
@@ -1,4 +1,4 @@
-/*     udp_usrreq.c    4.31    82/08/15        */
+/*     udp_usrreq.c    4.32    82/09/26        */
 
 #include "../h/param.h"
 #include "../h/dir.h"
 
 #include "../h/param.h"
 #include "../h/dir.h"
@@ -204,11 +204,11 @@ udp_output(inp, m0)
            so->so_state & SS_PRIV));
 }
 
            so->so_state & SS_PRIV));
 }
 
-udp_usrreq(so, req, m, addr)
+udp_usrreq(so, req, m, nam, opt)
        struct socket *so;
        int req;
        struct socket *so;
        int req;
-       struct mbuf *m;
-       caddr_t addr;
+       struct mbuf *m, *nam;
+       struct socketopt *opt;
 {
        struct inpcb *inp = sotoinpcb(so);
        int error = 0;
 {
        struct inpcb *inp = sotoinpcb(so);
        int error = 0;
@@ -220,8 +220,12 @@ udp_usrreq(so, req, m, addr)
        case PRU_ATTACH:
                if (inp != 0)
                        return (EINVAL);
        case PRU_ATTACH:
                if (inp != 0)
                        return (EINVAL);
-               error = in_pcbattach(so, &udb, 2048, 2048,
-                               (struct sockaddr_in *)addr);
+               error = in_pcballoc(so, &udb);
+               if (error)
+                       break;
+               error = in_pcbreserve(so, 2048, 2048);
+               if (error)
+                       break;
                break;
 
        case PRU_DETACH:
                break;
 
        case PRU_DETACH:
@@ -230,10 +234,18 @@ udp_usrreq(so, req, m, addr)
                in_pcbdetach(inp);
                break;
 
                in_pcbdetach(inp);
                break;
 
+       case PRU_BIND:
+               error = in_pcbbind(inp, nam);
+               break;
+
+       case PRU_LISTEN:
+               error = EOPNOTSUPP;
+               break;
+
        case PRU_CONNECT:
                if (inp->inp_faddr.s_addr)
                        return (EISCONN);
        case PRU_CONNECT:
                if (inp->inp_faddr.s_addr)
                        return (EISCONN);
-               error = in_pcbconnect(inp, (struct sockaddr_in *)addr);
+               error = in_pcbconnect(inp, nam);
                if (error == 0)
                        soisconnected(so);
                break;
                if (error == 0)
                        soisconnected(so);
                break;
@@ -255,11 +267,11 @@ udp_usrreq(so, req, m, addr)
        case PRU_SEND: {
                struct in_addr laddr;
 
        case PRU_SEND: {
                struct in_addr laddr;
 
-               if (addr) {
+               if (nam) {
                        laddr = inp->inp_laddr;
                        if (inp->inp_faddr.s_addr)
                                return (EISCONN);
                        laddr = inp->inp_laddr;
                        if (inp->inp_faddr.s_addr)
                                return (EISCONN);
-                       error = in_pcbconnect(inp, (struct sockaddr_in *)addr);
+                       error = in_pcbconnect(inp, nam);
                        if (error)
                                break;
                } else {
                        if (error)
                                break;
                } else {
@@ -267,7 +279,7 @@ udp_usrreq(so, req, m, addr)
                                return (ENOTCONN);
                }
                error = udp_output(inp, m);
                                return (ENOTCONN);
                }
                error = udp_output(inp, m);
-               if (addr) {
+               if (nam) {
                        in_pcbdisconnect(inp);
                        inp->inp_laddr = laddr;
                }
                        in_pcbdisconnect(inp);
                        inp->inp_laddr = laddr;
                }
@@ -284,7 +296,7 @@ udp_usrreq(so, req, m, addr)
                return (EOPNOTSUPP);
 
        case PRU_SOCKADDR:
                return (EOPNOTSUPP);
 
        case PRU_SOCKADDR:
-               in_setsockaddr((struct sockaddr_in *)addr, inp);
+               in_setsockaddr(inp, nam);
                break;
 
        default:
                break;
 
        default: