1*10900Ssam /* raw_imp.c 4.15 83/02/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" 8*10900Ssam #include "../h/errno.h" 9*10900Ssam 10*10900Ssam #include "../net/if.h" 11*10900Ssam #include "../net/raw_cb.h" 12*10900Ssam 138401Swnj #include "../netinet/in.h" 148401Swnj #include "../netinet/in_systm.h" 158401Swnj #include "../netimp/if_imp.h" 165637Sroot 175637Sroot /* 185637Sroot * Raw interface to IMP. 195637Sroot */ 205637Sroot 215637Sroot /* 225637Sroot * Generate IMP leader and pass packet to impoutput. 235637Sroot * The user must create a skeletal leader in order to 245637Sroot * communicate message type, message subtype, etc. 255637Sroot * We fill in holes where needed and verify parameters 265637Sroot * supplied by user. 275637Sroot */ 285847Sroot rimp_output(m, so) 295637Sroot register struct mbuf *m; 305637Sroot struct socket *so; 315637Sroot { 325637Sroot struct mbuf *n; 336509Ssam int len, error = 0; 345647Ssam register struct imp_leader *ip; 355637Sroot register struct sockaddr_in *sin; 365637Sroot register struct rawcb *rp = sotorawcb(so); 375772Swnj struct ifnet *ifp; 385772Swnj struct control_leader *cp; 395637Sroot 405637Sroot /* 415637Sroot * Verify user has supplied necessary space 425637Sroot * for the leader and check parameters in it. 435637Sroot */ 445772Swnj if ((m->m_off > MMAXOFF || m->m_len < sizeof(struct control_leader)) && 456509Ssam (m = m_pullup(m, sizeof(struct control_leader))) == 0) { 466509Ssam error = EMSGSIZE; /* XXX */ 476509Ssam goto bad; 486509Ssam } 495772Swnj cp = mtod(m, struct control_leader *); 505772Swnj if (cp->dl_mtype == IMPTYPE_DATA) 515772Swnj if (m->m_len < sizeof(struct imp_leader) && 526509Ssam (m = m_pullup(m, sizeof(struct imp_leader))) == 0) { 536509Ssam error = EMSGSIZE; /* XXX */ 546509Ssam goto bad; 556509Ssam } 565647Ssam ip = mtod(m, struct imp_leader *); 576509Ssam if (ip->il_format != IMP_NFF) { 586509Ssam error = EMSGSIZE; /* XXX */ 595637Sroot goto bad; 606509Ssam } 615870Sroot #ifdef notdef 625647Ssam if (ip->il_link != IMPLINK_IP && 636509Ssam (ip->il_link<IMPLINK_LOWEXPER || ip->il_link>IMPLINK_HIGHEXPER)) { 646509Ssam error = EPERM; 655637Sroot goto bad; 666509Ssam } 675870Sroot #endif 685637Sroot 695637Sroot /* 705637Sroot * Fill in IMP leader -- impoutput refrains from rebuilding 715637Sroot * the leader when it sees the protocol family PF_IMPLINK. 725637Sroot * (message size calculated by walking through mbuf's) 735637Sroot */ 745637Sroot for (len = 0, n = m; n; n = n->m_next) 755637Sroot len += n->m_len; 766161Ssam ip->il_length = htons((u_short)(len << 3)); 776509Ssam sin = (struct sockaddr_in *)&rp->rcb_faddr; 786529Ssam #ifdef notdef 795647Ssam ip->il_network = sin->sin_addr.s_net; 806529Ssam #else 816529Ssam ip->il_network = 0; 826529Ssam #endif 835647Ssam ip->il_host = sin->sin_addr.s_host; 845647Ssam ip->il_imp = sin->sin_addr.s_imp; 856339Ssam /* no routing here */ 868783Sroot ifp = if_ifonnetof((int)sin->sin_addr.s_net); 876509Ssam if (ifp) 886509Ssam return (impoutput(ifp, m, (struct sockaddr *)sin)); 896509Ssam error = ENETUNREACH; 905637Sroot bad: 915637Sroot m_freem(m); 926509Ssam return (error); 935637Sroot } 94