1 /* 2 * Copyright (c) 1982, 1986, 1988 Regents of the University of California. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms are permitted 6 * provided that the above copyright notice and this paragraph are 7 * duplicated in all such forms and that any documentation, 8 * advertising materials, and other materials related to such 9 * distribution and use acknowledge that the software was developed 10 * by the University of California, Berkeley. The name of the 11 * University may not be used to endorse or promote products derived 12 * from this software without specific prior written permission. 13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16 * 17 * @(#)raw_imp.c 7.4 (Berkeley) 06/29/88 18 */ 19 20 #include "param.h" 21 #include "mbuf.h" 22 #include "socket.h" 23 #include "protosw.h" 24 #include "socketvar.h" 25 #include "errno.h" 26 27 #include "../net/if.h" 28 #include "../net/route.h" 29 #include "../net/raw_cb.h" 30 31 #include "../netinet/in.h" 32 #include "../netinet/in_systm.h" 33 #include "../netinet/in_var.h" 34 #include "if_imp.h" 35 36 /* 37 * Raw interface to IMP. 38 */ 39 40 /* 41 * Generate IMP leader and pass packet to impoutput. 42 * The user must create a skeletal leader in order to 43 * communicate message type, message subtype, etc. 44 * We fill in holes where needed and verify parameters 45 * supplied by user. 46 */ 47 rimp_output(m, so) 48 register struct mbuf *m; 49 struct socket *so; 50 { 51 struct mbuf *n; 52 int len, error = 0; 53 register struct imp_leader *ip; 54 register struct sockaddr_in *sin; 55 register struct rawcb *rp = sotorawcb(so); 56 struct in_ifaddr *ia; 57 struct control_leader *cp; 58 59 /* 60 * Verify user has supplied necessary space 61 * for the leader and check parameters in it. 62 */ 63 if ((m->m_off > MMAXOFF || m->m_len < sizeof(struct control_leader)) && 64 (m = m_pullup(m, sizeof(struct control_leader))) == 0) { 65 error = EMSGSIZE; /* XXX */ 66 goto bad; 67 } 68 cp = mtod(m, struct control_leader *); 69 if (cp->dl_mtype == IMPTYPE_DATA) 70 if (m->m_len < sizeof(struct imp_leader) && 71 (m = m_pullup(m, sizeof(struct imp_leader))) == 0) { 72 error = EMSGSIZE; /* XXX */ 73 goto bad; 74 } 75 ip = mtod(m, struct imp_leader *); 76 if (ip->il_format != IMP_NFF) { 77 error = EMSGSIZE; /* XXX */ 78 goto bad; 79 } 80 #ifdef notdef 81 if (ip->il_link != IMPLINK_IP && 82 (ip->il_link<IMPLINK_LOWEXPER || ip->il_link>IMPLINK_HIGHEXPER)) { 83 error = EPERM; 84 goto bad; 85 } 86 #endif 87 88 /* 89 * Fill in IMP leader -- impoutput refrains from rebuilding 90 * the leader when it sees the protocol family PF_IMPLINK. 91 * (message size calculated by walking through mbuf's) 92 */ 93 for (len = 0, n = m; n; n = n->m_next) 94 len += n->m_len; 95 ip->il_length = htons((u_short)(len << 3)); 96 sin = (struct sockaddr_in *)&rp->rcb_faddr; 97 imp_addr_to_leader((struct control_leader *)ip, sin->sin_addr.s_addr); 98 /* no routing here */ 99 ia = in_iaonnetof(in_netof(sin->sin_addr)); 100 if (ia) 101 return (impoutput(ia->ia_ifp, m, (struct sockaddr *)sin)); 102 error = ENETUNREACH; 103 bad: 104 m_freem(m); 105 return (error); 106 } 107