1 /* raw_imp.c 4.2 82/02/01 */ 2 3 #include "../h/param.h" 4 #include "../h/mbuf.h" 5 #include "../h/socket.h" 6 #include "../h/protosw.h" 7 #include "../h/socketvar.h" 8 #include "../net/in.h" 9 #include "../net/in_systm.h" 10 #include "../net/if.h" 11 #include "../net/if_imp.h" 12 #include "../net/raw_cb.h" 13 #include "/usr/include/errno.h" 14 15 /* 16 * Raw interface to IMP. 17 */ 18 19 /*ARGSUSED*/ 20 imp_ctlinput(m) 21 struct mbuf *m; 22 { 23 COUNT(IMP_CTLINPUT); 24 } 25 26 /* 27 * Generate IMP leader and pass packet to impoutput. 28 * The user must create a skeletal leader in order to 29 * communicate message type, message subtype, etc. 30 * We fill in holes where needed and verify parameters 31 * supplied by user. 32 */ 33 imp_output(m, so) /* too close to impoutput */ 34 register struct mbuf *m; 35 struct socket *so; 36 { 37 struct mbuf *n; 38 int len; 39 register struct imp_leader *ip; 40 register struct sockaddr_in *sin; 41 register struct rawcb *rp = sotorawcb(so); 42 43 COUNT(IMP_OUTPUT); 44 /* 45 * Verify user has supplied necessary space 46 * for the leader and check parameters in it. 47 */ 48 if ((m->m_off > MMAXOFF || m->m_len < sizeof(struct imp_leader)) && 49 (m = m_pullup(m, sizeof(struct imp_leader))) == 0) 50 goto bad; 51 ip = mtod(m, struct imp_leader *); 52 if (ip->il_format != IMP_NFF) 53 goto bad; 54 if (ip->il_link != IMPLINK_IP && 55 (ip->il_link < IMPLINK_LOWEXPER || ip->il_link > IMPLINK_HIGHEXPER)) 56 goto bad; 57 58 /* 59 * Fill in IMP leader -- impoutput refrains from rebuilding 60 * the leader when it sees the protocol family PF_IMPLINK. 61 * (message size calculated by walking through mbuf's) 62 */ 63 for (len = 0, n = m; n; n = n->m_next) 64 len += n->m_len; 65 ip->il_length = len << 3; 66 sin = (struct sockaddr_in *)&rp->rcb_addr; 67 ip->il_network = sin->sin_addr.s_net; 68 ip->il_host = sin->sin_addr.s_host; 69 ip->il_imp = sin->sin_addr.s_imp; 70 71 return (impoutput((struct ifnet *)rp->rcb_pcb, m, PF_IMPLINK)); 72 73 bad: 74 m_freem(m); 75 return (0); 76 } 77 78 /* 79 * Intercept operations required to 80 * maintain interface pointer used on output. 81 */ 82 imp_usrreq(so, req, m, addr) 83 struct socket *so; 84 int req; 85 struct mbuf *m; 86 caddr_t addr; 87 { 88 register struct rawcb *rp = sotorawcb(so); 89 90 COUNT(IMP_USRREQ); 91 if (rp == 0 && req != PRU_ATTACH) 92 return (EINVAL); 93 94 switch (req) { 95 96 /* 97 * Verify address has an interface to go with it 98 * and record information for use in output routine. 99 */ 100 case PRU_SEND: 101 case PRU_CONNECT: { 102 register struct sockaddr_in *sin; 103 register struct ifnet *ifp; 104 105 sin = (struct sockaddr_in *)addr; 106 ifp = if_ifonnetof(sin->sin_addr); 107 if (ifp == 0) { 108 ifp = if_gatewayfor(sin->sin_addr); 109 if (ifp == 0) 110 return (EADDRNOTAVAIL); /* XXX */ 111 } 112 rp->rcb_pcb = (caddr_t)ifp; 113 break; 114 } 115 116 case PRU_DISCONNECT: 117 rp->rcb_pcb = 0; 118 break; 119 120 case PRU_CONTROL: 121 return (EOPNOTSUPP); 122 } 123 return (raw_usrreq(so, req, m, addr)); 124 } 125