1*6339Ssam /*	raw_imp.c	4.9	82/03/28	*/
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"
85637Sroot #include "../net/in.h"
95637Sroot #include "../net/in_systm.h"
105637Sroot #include "../net/if.h"
115637Sroot #include "../net/if_imp.h"
125637Sroot #include "../net/raw_cb.h"
136045Swnj #include "../errno.h"
145637Sroot 
155637Sroot /*
165637Sroot  * Raw interface to IMP.
175637Sroot  */
185637Sroot 
19*6339Ssam struct	sockaddr_in rawimpaddr = { AF_IMPLINK };
205637Sroot /*
215637Sroot  * Generate IMP leader and pass packet to impoutput.
225637Sroot  * The user must create a skeletal leader in order to
235637Sroot  * communicate message type, message subtype, etc.
245637Sroot  * We fill in holes where needed and verify parameters
255637Sroot  * supplied by user.
265637Sroot  */
275847Sroot rimp_output(m, so)
285637Sroot 	register struct mbuf *m;
295637Sroot 	struct socket *so;
305637Sroot {
315637Sroot 	struct mbuf *n;
325637Sroot 	int len;
335647Ssam 	register struct imp_leader *ip;
345637Sroot 	register struct sockaddr_in *sin;
355637Sroot 	register struct rawcb *rp = sotorawcb(so);
365772Swnj 	struct ifnet *ifp;
375772Swnj 	struct control_leader *cp;
385637Sroot 
395847Sroot COUNT(RIMP_OUTPUT);
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)) &&
455772Swnj 	    (m = m_pullup(m, sizeof(struct control_leader))) == 0)
465772Swnj 		return (0);
475772Swnj 	cp = mtod(m, struct control_leader *);
485772Swnj 	if (cp->dl_mtype == IMPTYPE_DATA)
495772Swnj 		if (m->m_len < sizeof(struct imp_leader) &&
505772Swnj 		    (m = m_pullup(m, sizeof(struct imp_leader))) == 0)
515772Swnj 			return (0);
525647Ssam 	ip = mtod(m, struct imp_leader *);
535647Ssam 	if (ip->il_format != IMP_NFF)
545637Sroot 		goto bad;
555870Sroot #ifdef notdef
565647Ssam 	if (ip->il_link != IMPLINK_IP &&
575647Ssam 	    (ip->il_link < IMPLINK_LOWEXPER || ip->il_link > IMPLINK_HIGHEXPER))
585637Sroot 		goto bad;
595870Sroot #endif
605637Sroot 
615637Sroot 	/*
625637Sroot 	 * Fill in IMP leader -- impoutput refrains from rebuilding
635637Sroot 	 * the leader when it sees the protocol family PF_IMPLINK.
645637Sroot 	 * (message size calculated by walking through mbuf's)
655637Sroot 	 */
665637Sroot 	for (len = 0, n = m; n; n = n->m_next)
675637Sroot 		len += n->m_len;
686161Ssam 	ip->il_length = htons((u_short)(len << 3));
695637Sroot 	sin = (struct sockaddr_in *)&rp->rcb_addr;
705647Ssam 	ip->il_network = sin->sin_addr.s_net;
715647Ssam 	ip->il_host = sin->sin_addr.s_host;
725647Ssam 	ip->il_imp = sin->sin_addr.s_imp;
73*6339Ssam 	/* no routing here */
74*6339Ssam 	ifp = if_ifonnetof(ip->il_network);
75*6339Ssam 	if (ifp == 0)
76*6339Ssam 		goto bad;
77*6339Ssam 	return (impoutput(ifp, m, (struct sockaddr *)&rawimpaddr));
785637Sroot 
795637Sroot bad:
805637Sroot 	m_freem(m);
815637Sroot 	return (0);
825637Sroot }
83