1*5647Ssam /* raw_imp.c 4.2 82/02/01 */ 25637Sroot 35637Sroot #include "../h/param.h" 45637Sroot #include "../h/mbuf.h" 55637Sroot #include "../h/socket.h" 65637Sroot #include "../h/protosw.h" 75637Sroot #include "../h/socketvar.h" 85637Sroot #include "../net/in.h" 95637Sroot #include "../net/in_systm.h" 105637Sroot #include "../net/if.h" 115637Sroot #include "../net/if_imp.h" 125637Sroot #include "../net/raw_cb.h" 135637Sroot #include "/usr/include/errno.h" 145637Sroot 155637Sroot /* 165637Sroot * Raw interface to IMP. 175637Sroot */ 185637Sroot 195637Sroot /*ARGSUSED*/ 205637Sroot imp_ctlinput(m) 215637Sroot struct mbuf *m; 225637Sroot { 235637Sroot COUNT(IMP_CTLINPUT); 245637Sroot } 255637Sroot 265637Sroot /* 275637Sroot * Generate IMP leader and pass packet to impoutput. 285637Sroot * The user must create a skeletal leader in order to 295637Sroot * communicate message type, message subtype, etc. 305637Sroot * We fill in holes where needed and verify parameters 315637Sroot * supplied by user. 325637Sroot */ 335637Sroot imp_output(m, so) /* too close to impoutput */ 345637Sroot register struct mbuf *m; 355637Sroot struct socket *so; 365637Sroot { 375637Sroot struct mbuf *n; 385637Sroot int len; 39*5647Ssam register struct imp_leader *ip; 405637Sroot register struct sockaddr_in *sin; 415637Sroot register struct rawcb *rp = sotorawcb(so); 425637Sroot 435637Sroot COUNT(IMP_OUTPUT); 445637Sroot /* 455637Sroot * Verify user has supplied necessary space 465637Sroot * for the leader and check parameters in it. 475637Sroot */ 485637Sroot if ((m->m_off > MMAXOFF || m->m_len < sizeof(struct imp_leader)) && 495637Sroot (m = m_pullup(m, sizeof(struct imp_leader))) == 0) 505637Sroot goto bad; 51*5647Ssam ip = mtod(m, struct imp_leader *); 52*5647Ssam if (ip->il_format != IMP_NFF) 535637Sroot goto bad; 54*5647Ssam if (ip->il_link != IMPLINK_IP && 55*5647Ssam (ip->il_link < IMPLINK_LOWEXPER || ip->il_link > IMPLINK_HIGHEXPER)) 565637Sroot goto bad; 575637Sroot 585637Sroot /* 595637Sroot * Fill in IMP leader -- impoutput refrains from rebuilding 605637Sroot * the leader when it sees the protocol family PF_IMPLINK. 615637Sroot * (message size calculated by walking through mbuf's) 625637Sroot */ 635637Sroot for (len = 0, n = m; n; n = n->m_next) 645637Sroot len += n->m_len; 65*5647Ssam ip->il_length = len << 3; 665637Sroot sin = (struct sockaddr_in *)&rp->rcb_addr; 67*5647Ssam ip->il_network = sin->sin_addr.s_net; 68*5647Ssam ip->il_host = sin->sin_addr.s_host; 69*5647Ssam ip->il_imp = sin->sin_addr.s_imp; 705637Sroot 715637Sroot return (impoutput((struct ifnet *)rp->rcb_pcb, m, PF_IMPLINK)); 725637Sroot 735637Sroot bad: 745637Sroot m_freem(m); 755637Sroot return (0); 765637Sroot } 775637Sroot 785637Sroot /* 795637Sroot * Intercept operations required to 805637Sroot * maintain interface pointer used on output. 815637Sroot */ 825637Sroot imp_usrreq(so, req, m, addr) 835637Sroot struct socket *so; 845637Sroot int req; 855637Sroot struct mbuf *m; 865637Sroot caddr_t addr; 875637Sroot { 885637Sroot register struct rawcb *rp = sotorawcb(so); 895637Sroot 905637Sroot COUNT(IMP_USRREQ); 915637Sroot if (rp == 0 && req != PRU_ATTACH) 925637Sroot return (EINVAL); 935637Sroot 945637Sroot switch (req) { 955637Sroot 965637Sroot /* 975637Sroot * Verify address has an interface to go with it 985637Sroot * and record information for use in output routine. 995637Sroot */ 1005637Sroot case PRU_SEND: 1015637Sroot case PRU_CONNECT: { 1025637Sroot register struct sockaddr_in *sin; 1035637Sroot register struct ifnet *ifp; 1045637Sroot 1055637Sroot sin = (struct sockaddr_in *)addr; 1065637Sroot ifp = if_ifonnetof(sin->sin_addr); 1075637Sroot if (ifp == 0) { 1085637Sroot ifp = if_gatewayfor(sin->sin_addr); 1095637Sroot if (ifp == 0) 1105637Sroot return (EADDRNOTAVAIL); /* XXX */ 1115637Sroot } 1125637Sroot rp->rcb_pcb = (caddr_t)ifp; 1135637Sroot break; 1145637Sroot } 1155637Sroot 1165637Sroot case PRU_DISCONNECT: 1175637Sroot rp->rcb_pcb = 0; 1185637Sroot break; 1195637Sroot 1205637Sroot case PRU_CONTROL: 1215637Sroot return (EOPNOTSUPP); 1225637Sroot } 1235637Sroot return (raw_usrreq(so, req, m, addr)); 1245637Sroot } 125