Commit | Line | Data |
---|---|---|
a0b7c7fb | 1 | /* raw_imp.c 4.2 82/02/01 */ |
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" | |
8 | #include "../net/in.h" | |
9 | #include "../net/in_systm.h" | |
10 | #include "../net/if.h" | |
11 | #include "../net/if_imp.h" | |
12 | #include "../net/raw_cb.h" | |
13 | #include "/usr/include/errno.h" | |
14 | ||
15 | /* | |
16 | * Raw interface to IMP. | |
17 | */ | |
18 | ||
19 | /*ARGSUSED*/ | |
20 | imp_ctlinput(m) | |
21 | struct mbuf *m; | |
22 | { | |
23 | COUNT(IMP_CTLINPUT); | |
24 | } | |
25 | ||
26 | /* | |
27 | * Generate IMP leader and pass packet to impoutput. | |
28 | * The user must create a skeletal leader in order to | |
29 | * communicate message type, message subtype, etc. | |
30 | * We fill in holes where needed and verify parameters | |
31 | * supplied by user. | |
32 | */ | |
33 | imp_output(m, so) /* too close to impoutput */ | |
34 | register struct mbuf *m; | |
35 | struct socket *so; | |
36 | { | |
37 | struct mbuf *n; | |
38 | int len; | |
a0b7c7fb | 39 | register struct imp_leader *ip; |
718d1f9e BJ |
40 | register struct sockaddr_in *sin; |
41 | register struct rawcb *rp = sotorawcb(so); | |
42 | ||
43 | COUNT(IMP_OUTPUT); | |
44 | /* | |
45 | * Verify user has supplied necessary space | |
46 | * for the leader and check parameters in it. | |
47 | */ | |
48 | if ((m->m_off > MMAXOFF || m->m_len < sizeof(struct imp_leader)) && | |
49 | (m = m_pullup(m, sizeof(struct imp_leader))) == 0) | |
50 | goto bad; | |
a0b7c7fb SL |
51 | ip = mtod(m, struct imp_leader *); |
52 | if (ip->il_format != IMP_NFF) | |
718d1f9e | 53 | goto bad; |
a0b7c7fb SL |
54 | if (ip->il_link != IMPLINK_IP && |
55 | (ip->il_link < IMPLINK_LOWEXPER || ip->il_link > IMPLINK_HIGHEXPER)) | |
718d1f9e BJ |
56 | goto bad; |
57 | ||
58 | /* | |
59 | * Fill in IMP leader -- impoutput refrains from rebuilding | |
60 | * the leader when it sees the protocol family PF_IMPLINK. | |
61 | * (message size calculated by walking through mbuf's) | |
62 | */ | |
63 | for (len = 0, n = m; n; n = n->m_next) | |
64 | len += n->m_len; | |
a0b7c7fb | 65 | ip->il_length = len << 3; |
718d1f9e | 66 | sin = (struct sockaddr_in *)&rp->rcb_addr; |
a0b7c7fb SL |
67 | ip->il_network = sin->sin_addr.s_net; |
68 | ip->il_host = sin->sin_addr.s_host; | |
69 | ip->il_imp = sin->sin_addr.s_imp; | |
718d1f9e BJ |
70 | |
71 | return (impoutput((struct ifnet *)rp->rcb_pcb, m, PF_IMPLINK)); | |
72 | ||
73 | bad: | |
74 | m_freem(m); | |
75 | return (0); | |
76 | } | |
77 | ||
78 | /* | |
79 | * Intercept operations required to | |
80 | * maintain interface pointer used on output. | |
81 | */ | |
82 | imp_usrreq(so, req, m, addr) | |
83 | struct socket *so; | |
84 | int req; | |
85 | struct mbuf *m; | |
86 | caddr_t addr; | |
87 | { | |
88 | register struct rawcb *rp = sotorawcb(so); | |
89 | ||
90 | COUNT(IMP_USRREQ); | |
91 | if (rp == 0 && req != PRU_ATTACH) | |
92 | return (EINVAL); | |
93 | ||
94 | switch (req) { | |
95 | ||
96 | /* | |
97 | * Verify address has an interface to go with it | |
98 | * and record information for use in output routine. | |
99 | */ | |
100 | case PRU_SEND: | |
101 | case PRU_CONNECT: { | |
102 | register struct sockaddr_in *sin; | |
103 | register struct ifnet *ifp; | |
104 | ||
105 | sin = (struct sockaddr_in *)addr; | |
106 | ifp = if_ifonnetof(sin->sin_addr); | |
107 | if (ifp == 0) { | |
108 | ifp = if_gatewayfor(sin->sin_addr); | |
109 | if (ifp == 0) | |
110 | return (EADDRNOTAVAIL); /* XXX */ | |
111 | } | |
112 | rp->rcb_pcb = (caddr_t)ifp; | |
113 | break; | |
114 | } | |
115 | ||
116 | case PRU_DISCONNECT: | |
117 | rp->rcb_pcb = 0; | |
118 | break; | |
119 | ||
120 | case PRU_CONTROL: | |
121 | return (EOPNOTSUPP); | |
122 | } | |
123 | return (raw_usrreq(so, req, m, addr)); | |
124 | } |