Commit | Line | Data |
---|---|---|
fcfe450e | 1 | /* raw_imp.c 4.13 82/10/09 */ |
718d1f9e BJ |
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" | |
fcfe450e BJ |
8 | #include "../netinet/in.h" |
9 | #include "../netinet/in_systm.h" | |
718d1f9e | 10 | #include "../net/if.h" |
fcfe450e | 11 | #include "../netimp/if_imp.h" |
718d1f9e | 12 | #include "../net/raw_cb.h" |
126472ab | 13 | #include <errno.h> |
718d1f9e BJ |
14 | |
15 | /* | |
16 | * Raw interface to IMP. | |
17 | */ | |
18 | ||
718d1f9e BJ |
19 | /* |
20 | * Generate IMP leader and pass packet to impoutput. | |
21 | * The user must create a skeletal leader in order to | |
22 | * communicate message type, message subtype, etc. | |
23 | * We fill in holes where needed and verify parameters | |
24 | * supplied by user. | |
25 | */ | |
8e999b50 | 26 | rimp_output(m, so) |
718d1f9e BJ |
27 | register struct mbuf *m; |
28 | struct socket *so; | |
29 | { | |
30 | struct mbuf *n; | |
126472ab | 31 | int len, error = 0; |
a0b7c7fb | 32 | register struct imp_leader *ip; |
718d1f9e BJ |
33 | register struct sockaddr_in *sin; |
34 | register struct rawcb *rp = sotorawcb(so); | |
a2cd4df7 BJ |
35 | struct ifnet *ifp; |
36 | struct control_leader *cp; | |
718d1f9e | 37 | |
718d1f9e BJ |
38 | /* |
39 | * Verify user has supplied necessary space | |
40 | * for the leader and check parameters in it. | |
41 | */ | |
a2cd4df7 | 42 | if ((m->m_off > MMAXOFF || m->m_len < sizeof(struct control_leader)) && |
126472ab SL |
43 | (m = m_pullup(m, sizeof(struct control_leader))) == 0) { |
44 | error = EMSGSIZE; /* XXX */ | |
45 | goto bad; | |
46 | } | |
a2cd4df7 BJ |
47 | cp = mtod(m, struct control_leader *); |
48 | if (cp->dl_mtype == IMPTYPE_DATA) | |
49 | if (m->m_len < sizeof(struct imp_leader) && | |
126472ab SL |
50 | (m = m_pullup(m, sizeof(struct imp_leader))) == 0) { |
51 | error = EMSGSIZE; /* XXX */ | |
52 | goto bad; | |
53 | } | |
a0b7c7fb | 54 | ip = mtod(m, struct imp_leader *); |
126472ab SL |
55 | if (ip->il_format != IMP_NFF) { |
56 | error = EMSGSIZE; /* XXX */ | |
718d1f9e | 57 | goto bad; |
126472ab | 58 | } |
27cadab0 | 59 | #ifdef notdef |
a0b7c7fb | 60 | if (ip->il_link != IMPLINK_IP && |
126472ab SL |
61 | (ip->il_link<IMPLINK_LOWEXPER || ip->il_link>IMPLINK_HIGHEXPER)) { |
62 | error = EPERM; | |
718d1f9e | 63 | goto bad; |
126472ab | 64 | } |
27cadab0 | 65 | #endif |
718d1f9e BJ |
66 | |
67 | /* | |
68 | * Fill in IMP leader -- impoutput refrains from rebuilding | |
69 | * the leader when it sees the protocol family PF_IMPLINK. | |
70 | * (message size calculated by walking through mbuf's) | |
71 | */ | |
72 | for (len = 0, n = m; n; n = n->m_next) | |
73 | len += n->m_len; | |
668cc26d | 74 | ip->il_length = htons((u_short)(len << 3)); |
126472ab | 75 | sin = (struct sockaddr_in *)&rp->rcb_faddr; |
02122dcc | 76 | #ifdef notdef |
a0b7c7fb | 77 | ip->il_network = sin->sin_addr.s_net; |
02122dcc SL |
78 | #else |
79 | ip->il_network = 0; | |
80 | #endif | |
a0b7c7fb SL |
81 | ip->il_host = sin->sin_addr.s_host; |
82 | ip->il_imp = sin->sin_addr.s_imp; | |
ee787340 | 83 | /* no routing here */ |
02122dcc | 84 | ifp = if_ifonnetof(sin->sin_addr.s_net); |
126472ab SL |
85 | if (ifp) |
86 | return (impoutput(ifp, m, (struct sockaddr *)sin)); | |
87 | error = ENETUNREACH; | |
718d1f9e BJ |
88 | bad: |
89 | m_freem(m); | |
126472ab | 90 | return (error); |
718d1f9e | 91 | } |