1 /*	raw_imp.c	4.16	83/06/30	*/
2 
3 #include "../h/param.h"
4 #include "../h/mbuf.h"
5 #include "../h/socket.h"
6 #include "../h/protosw.h"
7 #include "../h/socketvar.h"
8 #include "../h/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 "../netimp/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 #ifdef notdef
80 	ip->il_network = sin->sin_addr.s_net;
81 #else
82 	ip->il_network = 0;
83 #endif
84 	ip->il_host = sin->sin_addr.s_host;
85 	ip->il_imp = sin->sin_addr.s_imp;
86 	/* no routing here */
87 	ifp = if_ifonnetof((int)sin->sin_addr.s_net);
88 	if (ifp)
89 		return (impoutput(ifp, m, (struct sockaddr *)sin));
90 	error = ENETUNREACH;
91 bad:
92 	m_freem(m);
93 	return (error);
94 }
95