date and time created 82/02/01 12:59:39 by root
authorBill Joy <root@ucbvax.Berkeley.EDU>
Tue, 2 Feb 1982 04:59:39 +0000 (20:59 -0800)
committerBill Joy <root@ucbvax.Berkeley.EDU>
Tue, 2 Feb 1982 04:59:39 +0000 (20:59 -0800)
SCCS-vsn: sys/deprecated/netimp/raw_imp.c 4.1

usr/src/sys/deprecated/netimp/raw_imp.c [new file with mode: 0644]

diff --git a/usr/src/sys/deprecated/netimp/raw_imp.c b/usr/src/sys/deprecated/netimp/raw_imp.c
new file mode 100644 (file)
index 0000000..7e1bf59
--- /dev/null
@@ -0,0 +1,124 @@
+/*     raw_imp.c       4.1     82/02/01        */
+
+#include "../h/param.h"
+#include "../h/mbuf.h"
+#include "../h/socket.h"
+#include "../h/protosw.h"
+#include "../h/socketvar.h"
+#include "../net/in.h"
+#include "../net/in_systm.h"
+#include "../net/if.h"
+#include "../net/if_imp.h"
+#include "../net/raw_cb.h"
+#include "/usr/include/errno.h"
+
+/*
+ * Raw interface to IMP.
+ */
+
+/*ARGSUSED*/
+imp_ctlinput(m)
+       struct mbuf *m;
+{
+COUNT(IMP_CTLINPUT);
+}
+
+/*
+ * Generate IMP leader and pass packet to impoutput.
+ * The user must create a skeletal leader in order to
+ * communicate message type, message subtype, etc.
+ * We fill in holes where needed and verify parameters
+ * supplied by user.
+ */
+imp_output(m, so)              /* too close to impoutput */
+       register struct mbuf *m;
+       struct socket *so;
+{
+       struct mbuf *n;
+       int len;
+       register struct imp_leader *il;
+       register struct sockaddr_in *sin;
+       register struct rawcb *rp = sotorawcb(so);
+
+COUNT(IMP_OUTPUT);
+       /*
+        * Verify user has supplied necessary space
+        * for the leader and check parameters in it.
+        */
+       if ((m->m_off > MMAXOFF || m->m_len < sizeof(struct imp_leader)) &&
+           (m = m_pullup(m, sizeof(struct imp_leader))) == 0)
+               goto bad;
+       il = mtod(m, struct imp_leader *);
+       if (il->il_format != IMP_NFF)
+               goto bad;
+       if (il->il_link != IMPLINK_IP &&
+           (il->il_link < IMPLINK_LOWEXPER || il->il_link > IMPLINK_HIGHEXPER))
+               goto bad;
+
+       /*
+        * Fill in IMP leader -- impoutput refrains from rebuilding
+        * the leader when it sees the protocol family PF_IMPLINK.
+        * (message size calculated by walking through mbuf's)
+        */
+       for (len = 0, n = m; n; n = n->m_next)
+               len += n->m_len;
+       il->il_length = len << 3;
+       sin = (struct sockaddr_in *)&rp->rcb_addr;
+       il->il_network = sin->sin_addr.s_net;
+       il->il_host = sin->sin_addr.s_host;
+       il->il_imp = sin->sin_addr.s_imp;
+
+       return (impoutput((struct ifnet *)rp->rcb_pcb, m, PF_IMPLINK));
+
+bad:
+       m_freem(m);
+       return (0);
+}
+
+/*
+ * Intercept operations required to
+ * maintain interface pointer used on output.
+ */
+imp_usrreq(so, req, m, addr)
+       struct socket *so;
+       int req;
+       struct mbuf *m;
+       caddr_t addr;
+{
+       register struct rawcb *rp = sotorawcb(so);
+
+COUNT(IMP_USRREQ);
+       if (rp == 0 && req != PRU_ATTACH)
+               return (EINVAL);
+
+       switch (req) {
+
+       /*
+        * Verify address has an interface to go with it
+        * and record information for use in output routine.
+        */
+       case PRU_SEND:
+       case PRU_CONNECT: {
+               register struct sockaddr_in *sin;
+               register struct ifnet *ifp;
+
+               sin = (struct sockaddr_in *)addr;
+               ifp = if_ifonnetof(sin->sin_addr);
+               if (ifp == 0) {
+                       ifp = if_gatewayfor(sin->sin_addr);
+                       if (ifp == 0)
+                               return (EADDRNOTAVAIL); /* XXX */
+               }
+               rp->rcb_pcb = (caddr_t)ifp;
+               break;
+               }
+
+       case PRU_DISCONNECT:
+               rp->rcb_pcb = 0;
+               break;
+
+       case PRU_CONTROL:
+               return (EOPNOTSUPP);
+       }
+       return (raw_usrreq(so, req, m, addr));
+}