1*6509Ssam /* raw_imp.c 4.10 82/04/10 */ 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" 13*6509Ssam #include <errno.h> 145637Sroot 155637Sroot /* 165637Sroot * Raw interface to IMP. 175637Sroot */ 185637Sroot 195637Sroot /* 205637Sroot * Generate IMP leader and pass packet to impoutput. 215637Sroot * The user must create a skeletal leader in order to 225637Sroot * communicate message type, message subtype, etc. 235637Sroot * We fill in holes where needed and verify parameters 245637Sroot * supplied by user. 255637Sroot */ 265847Sroot rimp_output(m, so) 275637Sroot register struct mbuf *m; 285637Sroot struct socket *so; 295637Sroot { 305637Sroot struct mbuf *n; 31*6509Ssam int len, error = 0; 325647Ssam register struct imp_leader *ip; 335637Sroot register struct sockaddr_in *sin; 345637Sroot register struct rawcb *rp = sotorawcb(so); 355772Swnj struct ifnet *ifp; 365772Swnj struct control_leader *cp; 375637Sroot 385847Sroot COUNT(RIMP_OUTPUT); 395637Sroot /* 405637Sroot * Verify user has supplied necessary space 415637Sroot * for the leader and check parameters in it. 425637Sroot */ 435772Swnj if ((m->m_off > MMAXOFF || m->m_len < sizeof(struct control_leader)) && 44*6509Ssam (m = m_pullup(m, sizeof(struct control_leader))) == 0) { 45*6509Ssam error = EMSGSIZE; /* XXX */ 46*6509Ssam goto bad; 47*6509Ssam } 485772Swnj cp = mtod(m, struct control_leader *); 495772Swnj if (cp->dl_mtype == IMPTYPE_DATA) 505772Swnj if (m->m_len < sizeof(struct imp_leader) && 51*6509Ssam (m = m_pullup(m, sizeof(struct imp_leader))) == 0) { 52*6509Ssam error = EMSGSIZE; /* XXX */ 53*6509Ssam goto bad; 54*6509Ssam } 555647Ssam ip = mtod(m, struct imp_leader *); 56*6509Ssam if (ip->il_format != IMP_NFF) { 57*6509Ssam error = EMSGSIZE; /* XXX */ 585637Sroot goto bad; 59*6509Ssam } 605870Sroot #ifdef notdef 615647Ssam if (ip->il_link != IMPLINK_IP && 62*6509Ssam (ip->il_link<IMPLINK_LOWEXPER || ip->il_link>IMPLINK_HIGHEXPER)) { 63*6509Ssam error = EPERM; 645637Sroot goto bad; 65*6509Ssam } 665870Sroot #endif 675637Sroot 685637Sroot /* 695637Sroot * Fill in IMP leader -- impoutput refrains from rebuilding 705637Sroot * the leader when it sees the protocol family PF_IMPLINK. 715637Sroot * (message size calculated by walking through mbuf's) 725637Sroot */ 735637Sroot for (len = 0, n = m; n; n = n->m_next) 745637Sroot len += n->m_len; 756161Ssam ip->il_length = htons((u_short)(len << 3)); 76*6509Ssam sin = (struct sockaddr_in *)&rp->rcb_faddr; 775647Ssam ip->il_network = sin->sin_addr.s_net; 785647Ssam ip->il_host = sin->sin_addr.s_host; 795647Ssam ip->il_imp = sin->sin_addr.s_imp; 806339Ssam /* no routing here */ 816339Ssam ifp = if_ifonnetof(ip->il_network); 82*6509Ssam if (ifp) 83*6509Ssam return (impoutput(ifp, m, (struct sockaddr *)sin)); 84*6509Ssam error = ENETUNREACH; 855637Sroot bad: 865637Sroot m_freem(m); 87*6509Ssam return (error); 885637Sroot } 89