1*10900Ssam /*	raw_imp.c	4.15	83/02/10	*/
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"
8*10900Ssam #include "../h/errno.h"
9*10900Ssam 
10*10900Ssam #include "../net/if.h"
11*10900Ssam #include "../net/raw_cb.h"
12*10900Ssam 
138401Swnj #include "../netinet/in.h"
148401Swnj #include "../netinet/in_systm.h"
158401Swnj #include "../netimp/if_imp.h"
165637Sroot 
175637Sroot /*
185637Sroot  * Raw interface to IMP.
195637Sroot  */
205637Sroot 
215637Sroot /*
225637Sroot  * Generate IMP leader and pass packet to impoutput.
235637Sroot  * The user must create a skeletal leader in order to
245637Sroot  * communicate message type, message subtype, etc.
255637Sroot  * We fill in holes where needed and verify parameters
265637Sroot  * supplied by user.
275637Sroot  */
285847Sroot rimp_output(m, so)
295637Sroot 	register struct mbuf *m;
305637Sroot 	struct socket *so;
315637Sroot {
325637Sroot 	struct mbuf *n;
336509Ssam 	int len, error = 0;
345647Ssam 	register struct imp_leader *ip;
355637Sroot 	register struct sockaddr_in *sin;
365637Sroot 	register struct rawcb *rp = sotorawcb(so);
375772Swnj 	struct ifnet *ifp;
385772Swnj 	struct control_leader *cp;
395637Sroot 
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)) &&
456509Ssam 	    (m = m_pullup(m, sizeof(struct control_leader))) == 0) {
466509Ssam 		error = EMSGSIZE;	/* XXX */
476509Ssam 		goto bad;
486509Ssam 	}
495772Swnj 	cp = mtod(m, struct control_leader *);
505772Swnj 	if (cp->dl_mtype == IMPTYPE_DATA)
515772Swnj 		if (m->m_len < sizeof(struct imp_leader) &&
526509Ssam 		    (m = m_pullup(m, sizeof(struct imp_leader))) == 0) {
536509Ssam 			error = EMSGSIZE;	/* XXX */
546509Ssam 			goto bad;
556509Ssam 		}
565647Ssam 	ip = mtod(m, struct imp_leader *);
576509Ssam 	if (ip->il_format != IMP_NFF) {
586509Ssam 		error = EMSGSIZE;		/* XXX */
595637Sroot 		goto bad;
606509Ssam 	}
615870Sroot #ifdef notdef
625647Ssam 	if (ip->il_link != IMPLINK_IP &&
636509Ssam 	    (ip->il_link<IMPLINK_LOWEXPER || ip->il_link>IMPLINK_HIGHEXPER)) {
646509Ssam 		error = EPERM;
655637Sroot 		goto bad;
666509Ssam 	}
675870Sroot #endif
685637Sroot 
695637Sroot 	/*
705637Sroot 	 * Fill in IMP leader -- impoutput refrains from rebuilding
715637Sroot 	 * the leader when it sees the protocol family PF_IMPLINK.
725637Sroot 	 * (message size calculated by walking through mbuf's)
735637Sroot 	 */
745637Sroot 	for (len = 0, n = m; n; n = n->m_next)
755637Sroot 		len += n->m_len;
766161Ssam 	ip->il_length = htons((u_short)(len << 3));
776509Ssam 	sin = (struct sockaddr_in *)&rp->rcb_faddr;
786529Ssam #ifdef notdef
795647Ssam 	ip->il_network = sin->sin_addr.s_net;
806529Ssam #else
816529Ssam 	ip->il_network = 0;
826529Ssam #endif
835647Ssam 	ip->il_host = sin->sin_addr.s_host;
845647Ssam 	ip->il_imp = sin->sin_addr.s_imp;
856339Ssam 	/* no routing here */
868783Sroot 	ifp = if_ifonnetof((int)sin->sin_addr.s_net);
876509Ssam 	if (ifp)
886509Ssam 		return (impoutput(ifp, m, (struct sockaddr *)sin));
896509Ssam 	error = ENETUNREACH;
905637Sroot bad:
915637Sroot 	m_freem(m);
926509Ssam 	return (error);
935637Sroot }
94