1 /* raw_imp.c 6.3 85/02/28 */ 2 3 #include "param.h" 4 #include "mbuf.h" 5 #include "socket.h" 6 #include "protosw.h" 7 #include "socketvar.h" 8 #include "errno.h" 9 10 #include "../net/if.h" 11 #include "../net/route.h" 12 #include "../net/raw_cb.h" 13 14 #include "../netinet/in.h" 15 #include "../netinet/in_systm.h" 16 #include "if_imp.h" 17 18 /* 19 * Raw interface to IMP. 20 */ 21 22 /* 23 * Generate IMP leader and pass packet to impoutput. 24 * The user must create a skeletal leader in order to 25 * communicate message type, message subtype, etc. 26 * We fill in holes where needed and verify parameters 27 * supplied by user. 28 */ 29 rimp_output(m, so) 30 register struct mbuf *m; 31 struct socket *so; 32 { 33 struct mbuf *n; 34 int len, error = 0; 35 register struct imp_leader *ip; 36 register struct sockaddr_in *sin; 37 register struct rawcb *rp = sotorawcb(so); 38 struct ifnet *ifp; 39 struct control_leader *cp; 40 41 /* 42 * Verify user has supplied necessary space 43 * for the leader and check parameters in it. 44 */ 45 if ((m->m_off > MMAXOFF || m->m_len < sizeof(struct control_leader)) && 46 (m = m_pullup(m, sizeof(struct control_leader))) == 0) { 47 error = EMSGSIZE; /* XXX */ 48 goto bad; 49 } 50 cp = mtod(m, struct control_leader *); 51 if (cp->dl_mtype == IMPTYPE_DATA) 52 if (m->m_len < sizeof(struct imp_leader) && 53 (m = m_pullup(m, sizeof(struct imp_leader))) == 0) { 54 error = EMSGSIZE; /* XXX */ 55 goto bad; 56 } 57 ip = mtod(m, struct imp_leader *); 58 if (ip->il_format != IMP_NFF) { 59 error = EMSGSIZE; /* XXX */ 60 goto bad; 61 } 62 #ifdef notdef 63 if (ip->il_link != IMPLINK_IP && 64 (ip->il_link<IMPLINK_LOWEXPER || ip->il_link>IMPLINK_HIGHEXPER)) { 65 error = EPERM; 66 goto bad; 67 } 68 #endif 69 70 /* 71 * Fill in IMP leader -- impoutput refrains from rebuilding 72 * the leader when it sees the protocol family PF_IMPLINK. 73 * (message size calculated by walking through mbuf's) 74 */ 75 for (len = 0, n = m; n; n = n->m_next) 76 len += n->m_len; 77 ip->il_length = htons((u_short)(len << 3)); 78 sin = (struct sockaddr_in *)&rp->rcb_faddr; 79 imp_addr_to_leader( ip, sin->sin_addr.s_addr ); /* BRL */ 80 /* no routing here */ 81 ifp = if_ifonnetof(in_netof(sin->sin_addr)); 82 if (ifp) 83 return (impoutput(ifp, m, (struct sockaddr *)sin)); 84 error = ENETUNREACH; 85 bad: 86 m_freem(m); 87 return (error); 88 } 89