BSD 4_3 release
[unix-history] / usr / src / sys / netimp / raw_imp.c
CommitLineData
8ae0e4b4 1/*
0880b18e 2 * Copyright (c) 1982, 1986 Regents of the University of California.
8ae0e4b4
KM
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 *
95f51977 6 * @(#)raw_imp.c 7.1 (Berkeley) 6/4/86
8ae0e4b4 7 */
718d1f9e 8
54cf16ba
JB
9#include "param.h"
10#include "mbuf.h"
11#include "socket.h"
12#include "protosw.h"
13#include "socketvar.h"
14#include "errno.h"
f4d55810
SL
15
16#include "../net/if.h"
515ee6c7 17#include "../net/route.h"
f4d55810
SL
18#include "../net/raw_cb.h"
19
fcfe450e
BJ
20#include "../netinet/in.h"
21#include "../netinet/in_systm.h"
91b2c865 22#include "../netinet/in_var.h"
54cf16ba 23#include "if_imp.h"
718d1f9e
BJ
24
25/*
26 * Raw interface to IMP.
27 */
28
718d1f9e
BJ
29/*
30 * Generate IMP leader and pass packet to impoutput.
31 * The user must create a skeletal leader in order to
32 * communicate message type, message subtype, etc.
33 * We fill in holes where needed and verify parameters
34 * supplied by user.
35 */
8e999b50 36rimp_output(m, so)
718d1f9e
BJ
37 register struct mbuf *m;
38 struct socket *so;
39{
40 struct mbuf *n;
126472ab 41 int len, error = 0;
a0b7c7fb 42 register struct imp_leader *ip;
718d1f9e
BJ
43 register struct sockaddr_in *sin;
44 register struct rawcb *rp = sotorawcb(so);
91b2c865 45 struct in_ifaddr *ia;
a2cd4df7 46 struct control_leader *cp;
718d1f9e 47
718d1f9e
BJ
48 /*
49 * Verify user has supplied necessary space
50 * for the leader and check parameters in it.
51 */
a2cd4df7 52 if ((m->m_off > MMAXOFF || m->m_len < sizeof(struct control_leader)) &&
126472ab
SL
53 (m = m_pullup(m, sizeof(struct control_leader))) == 0) {
54 error = EMSGSIZE; /* XXX */
55 goto bad;
56 }
a2cd4df7
BJ
57 cp = mtod(m, struct control_leader *);
58 if (cp->dl_mtype == IMPTYPE_DATA)
59 if (m->m_len < sizeof(struct imp_leader) &&
126472ab
SL
60 (m = m_pullup(m, sizeof(struct imp_leader))) == 0) {
61 error = EMSGSIZE; /* XXX */
62 goto bad;
63 }
a0b7c7fb 64 ip = mtod(m, struct imp_leader *);
126472ab
SL
65 if (ip->il_format != IMP_NFF) {
66 error = EMSGSIZE; /* XXX */
718d1f9e 67 goto bad;
126472ab 68 }
27cadab0 69#ifdef notdef
a0b7c7fb 70 if (ip->il_link != IMPLINK_IP &&
126472ab
SL
71 (ip->il_link<IMPLINK_LOWEXPER || ip->il_link>IMPLINK_HIGHEXPER)) {
72 error = EPERM;
718d1f9e 73 goto bad;
126472ab 74 }
27cadab0 75#endif
718d1f9e
BJ
76
77 /*
78 * Fill in IMP leader -- impoutput refrains from rebuilding
79 * the leader when it sees the protocol family PF_IMPLINK.
80 * (message size calculated by walking through mbuf's)
81 */
82 for (len = 0, n = m; n; n = n->m_next)
83 len += n->m_len;
668cc26d 84 ip->il_length = htons((u_short)(len << 3));
126472ab 85 sin = (struct sockaddr_in *)&rp->rcb_faddr;
91b2c865 86 imp_addr_to_leader(ip, sin->sin_addr.s_addr); /* BRL */
ee787340 87 /* no routing here */
91b2c865
MK
88 ia = in_iaonnetof(in_netof(sin->sin_addr));
89 if (ia)
90 return (impoutput(ia->ia_ifp, m, (struct sockaddr *)sin));
126472ab 91 error = ENETUNREACH;
718d1f9e
BJ
92bad:
93 m_freem(m);
126472ab 94 return (error);
718d1f9e 95}