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