BSD 4_3_Tahoe release
[unix-history] / usr / src / sys / net / raw_cb.c
index 9b77724..e1e5929 100644 (file)
@@ -1,74 +1,72 @@
-/*     raw_cb.c        4.3     82/02/12        */
-
-#include "../h/param.h"
-#include "../h/systm.h"
-#include "../h/mbuf.h"
-#include "../h/socket.h"
-#include "../h/socketvar.h"
-#include "../h/mtpr.h"
-#include "../net/in.h"
-#include "../net/in_systm.h"
-#include "../net/if.h"
-#include "../net/raw_cb.h"
-#include "/usr/include/errno.h"
+/*
+ * Copyright (c) 1980, 1986 Regents of the University of California.
+ * All rights reserved.
+ *
+ * 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.
+ *
+ *     @(#)raw_cb.c    7.6 (Berkeley) 6/27/88
+ */
+
+#include "param.h"
+#include "systm.h"
+#include "mbuf.h"
+#include "socket.h"
+#include "socketvar.h"
+#include "domain.h"
+#include "protosw.h"
+#include "errno.h"
+
+#include "if.h"
+#include "route.h"
+#include "raw_cb.h"
+#include "../netinet/in.h"
+
+#include "../machine/mtpr.h"
 
 /*
  * Routines to manage the raw protocol control blocks. 
  *
  * TODO:
  *     hash lookups by protocol family/protocol + address family
 
 /*
  * Routines to manage the raw protocol control blocks. 
  *
  * TODO:
  *     hash lookups by protocol family/protocol + address family
- *     take care of unique address problems per AF
+ *     take care of unique address problems per AF?
+ *     redo address binding to allow wildcards
  */
 
 /*
  * Allocate a control block and a nominal amount
  * of buffer space for the socket.
  */
  */
 
 /*
  * Allocate a control block and a nominal amount
  * of buffer space for the socket.
  */
-raw_attach(so, addr)
+raw_attach(so, proto)
        register struct socket *so;
        register struct socket *so;
-       struct sockaddr *addr;
+       int proto;
 {
        struct mbuf *m;
        register struct rawcb *rp;
 {
        struct mbuf *m;
        register struct rawcb *rp;
-       struct ifnet *ifp = ifnet;
-
-COUNT(RAW_ATTACH);
-       /*
-        * Should we verify address not already in use?
-        * Some say yes, others no.
-        */
-       if (addr) switch (addr->sa_family) {
 
 
-       case AF_IMPLINK:
-       case AF_INET: {
-               register struct sockaddr_in *sin = (struct sockaddr_in *)addr;
-
-               if (ifnet && sin->sin_addr.s_addr == 0)
-                       sin->sin_addr = ifnet->if_addr;
-               ifp = if_ifwithaddr(sin->sin_addr);
-               break;
-               }
-
-       default:
-               return (EAFNOSUPPORT);
-       }
-       if (ifp == 0)
-               return (EADDRNOTAVAIL);
-       m = m_getclr(M_DONTWAIT);
+       m = m_getclr(M_DONTWAIT, MT_PCB);
        if (m == 0)
                return (ENOBUFS);
        if (m == 0)
                return (ENOBUFS);
-       if (sbreserve(&so->so_snd, RAWSNDQ) == 0)
+       if (sbreserve(&so->so_snd, (u_long) RAWSNDQ) == 0)
                goto bad;
                goto bad;
-       if (sbreserve(&so->so_rcv, RAWRCVQ) == 0)
+       if (sbreserve(&so->so_rcv, (u_long) RAWRCVQ) == 0)
                goto bad2;
        rp = mtod(m, struct rawcb *);
        rp->rcb_socket = so;
                goto bad2;
        rp = mtod(m, struct rawcb *);
        rp->rcb_socket = so;
-       insque(rp, &rawcb);
        so->so_pcb = (caddr_t)rp;
        rp->rcb_pcb = 0;
        so->so_pcb = (caddr_t)rp;
        rp->rcb_pcb = 0;
-
-       if (addr)
-               bcopy(addr, &so->so_addr, sizeof(*addr));
+       rp->rcb_proto.sp_family = so->so_proto->pr_domain->dom_family;
+       rp->rcb_proto.sp_protocol = proto;
+       insque(rp, &rawcb);
        return (0);
 bad2:
        sbrelease(&so->so_snd);
        return (0);
 bad2:
        sbrelease(&so->so_snd);
@@ -86,11 +84,14 @@ raw_detach(rp)
 {
        struct socket *so = rp->rcb_socket;
 
 {
        struct socket *so = rp->rcb_socket;
 
-COUNT(RAW_DETACH);
+       if (rp->rcb_route.ro_rt)
+               rtfree(rp->rcb_route.ro_rt);
        so->so_pcb = 0;
        sofree(so);
        remque(rp);
        so->so_pcb = 0;
        sofree(so);
        remque(rp);
-       (void) m_freem(dtom(rp));
+       if (rp->rcb_options)
+               m_freem(rp->rcb_options);
+       m_freem(dtom(rp));
 }
 
 /*
 }
 
 /*
@@ -99,21 +100,58 @@ COUNT(RAW_DETACH);
 raw_disconnect(rp)
        struct rawcb *rp;
 {
 raw_disconnect(rp)
        struct rawcb *rp;
 {
-COUNT(RAW_DISCONNECT);
-       rp->rcb_flags &= ~RAW_ADDR;
-       if (rp->rcb_socket->so_state & SS_USERGONE)
+
+       rp->rcb_flags &= ~RAW_FADDR;
+       if (rp->rcb_socket->so_state & SS_NOFDREF)
                raw_detach(rp);
 }
 
                raw_detach(rp);
 }
 
+raw_bind(so, nam)
+       register struct socket *so;
+       struct mbuf *nam;
+{
+       struct sockaddr *addr = mtod(nam, struct sockaddr *);
+       register struct rawcb *rp;
+
+       if (ifnet == 0)
+               return (EADDRNOTAVAIL);
+/* BEGIN DUBIOUS */
+       /*
+        * Should we verify address not already in use?
+        * Some say yes, others no.
+        */
+       switch (addr->sa_family) {
+
+#ifdef INET
+       case AF_IMPLINK:
+       case AF_INET: {
+               if (((struct sockaddr_in *)addr)->sin_addr.s_addr &&
+                   ifa_ifwithaddr(addr) == 0)
+                       return (EADDRNOTAVAIL);
+               break;
+       }
+#endif
+
+       default:
+               return (EAFNOSUPPORT);
+       }
+/* END DUBIOUS */
+       rp = sotorawcb(so);
+       bcopy((caddr_t)addr, (caddr_t)&rp->rcb_laddr, sizeof (*addr));
+       rp->rcb_flags |= RAW_LADDR;
+       return (0);
+}
+
 /*
  * Associate a peer's address with a
  * raw connection block.
  */
 /*
  * Associate a peer's address with a
  * raw connection block.
  */
-raw_connaddr(rp, addr)
+raw_connaddr(rp, nam)
        struct rawcb *rp;
        struct rawcb *rp;
-       struct sockaddr *addr;
+       struct mbuf *nam;
 {
 {
-COUNT(RAW_CONNADDR);
-       bcopy(addr, &rp->rcb_addr, sizeof(struct sockaddr));
-       rp->rcb_flags |= RAW_ADDR;
+       struct sockaddr *addr = mtod(nam, struct sockaddr *);
+
+       bcopy((caddr_t)addr, (caddr_t)&rp->rcb_faddr, sizeof(*addr));
+       rp->rcb_flags |= RAW_FADDR;
 }
 }