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