]>
Commit | Line | Data |
---|---|---|
1c79356b A |
1 | /* |
2 | * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. | |
3 | * | |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
6 | * The contents of this file constitute Original Code as defined in and | |
7 | * are subject to the Apple Public Source License Version 1.1 (the | |
8 | * "License"). You may not use this file except in compliance with the | |
9 | * License. Please obtain a copy of the License at | |
10 | * http://www.apple.com/publicsource and read it before using this file. | |
11 | * | |
12 | * This Original Code and all software distributed under the License are | |
13 | * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
14 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, | |
15 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
16 | * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the | |
17 | * License for the specific language governing rights and limitations | |
18 | * under the License. | |
19 | * | |
20 | * @APPLE_LICENSE_HEADER_END@ | |
21 | */ | |
22 | /*- | |
23 | * Copyright (c) 1991, 1993 | |
24 | * The Regents of the University of California. All rights reserved. | |
25 | * | |
26 | * Redistribution and use in source and binary forms, with or without | |
27 | * modification, are permitted provided that the following conditions | |
28 | * are met: | |
29 | * 1. Redistributions of source code must retain the above copyright | |
30 | * notice, this list of conditions and the following disclaimer. | |
31 | * 2. Redistributions in binary form must reproduce the above copyright | |
32 | * notice, this list of conditions and the following disclaimer in the | |
33 | * documentation and/or other materials provided with the distribution. | |
34 | * 3. All advertising materials mentioning features or use of this software | |
35 | * must display the following acknowledgement: | |
36 | * This product includes software developed by the University of | |
37 | * California, Berkeley and its contributors. | |
38 | * 4. Neither the name of the University nor the names of its contributors | |
39 | * may be used to endorse or promote products derived from this software | |
40 | * without specific prior written permission. | |
41 | * | |
42 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | |
43 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |
44 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |
45 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | |
46 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |
47 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |
48 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |
49 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |
50 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |
51 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |
52 | * SUCH DAMAGE. | |
53 | * | |
54 | * @(#)clnp_raw.c 8.1 (Berkeley) 6/10/93 | |
55 | */ | |
56 | ||
57 | /*********************************************************** | |
58 | Copyright IBM Corporation 1987 | |
59 | ||
60 | All Rights Reserved | |
61 | ||
62 | Permission to use, copy, modify, and distribute this software and its | |
63 | documentation for any purpose and without fee is hereby granted, | |
64 | provided that the above copyright notice appear in all copies and that | |
65 | both that copyright notice and this permission notice appear in | |
66 | supporting documentation, and that the name of IBM not be | |
67 | used in advertising or publicity pertaining to distribution of the | |
68 | software without specific, written prior permission. | |
69 | ||
70 | IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING | |
71 | ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL | |
72 | IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR | |
73 | ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, | |
74 | WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | |
75 | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | |
76 | SOFTWARE. | |
77 | ||
78 | ******************************************************************/ | |
79 | ||
80 | /* | |
81 | * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison | |
82 | */ | |
83 | ||
84 | #include <sys/param.h> | |
85 | #include <sys/mbuf.h> | |
86 | #include <sys/domain.h> | |
87 | #include <sys/protosw.h> | |
88 | #include <sys/socket.h> | |
89 | #include <sys/socketvar.h> | |
90 | #include <sys/errno.h> | |
91 | #include <sys/time.h> | |
92 | #include <sys/malloc.h> | |
93 | ||
94 | #include <net/if.h> | |
95 | #include <net/route.h> | |
96 | #include <net/raw_cb.h> | |
97 | ||
98 | #include <netiso/iso.h> | |
99 | #include <netiso/iso_pcb.h> | |
100 | #include <netiso/clnp.h> | |
101 | #include <netiso/clnp_stat.h> | |
102 | #include <netiso/argo_debug.h> | |
103 | ||
104 | #include <netiso/tp_user.h> /* XXX -- defines SOL_NETWORK */ | |
105 | ||
106 | struct sockproto rclnp_proto = { PF_ISO, 0 }; | |
107 | /* | |
108 | * FUNCTION: rclnp_input | |
109 | * | |
110 | * PURPOSE: Setup generic address an protocol structures for | |
111 | * raw input routine, then pass them along with the | |
112 | * mbuf chain. | |
113 | * | |
114 | * RETURNS: none | |
115 | * | |
116 | * SIDE EFFECTS: | |
117 | * | |
118 | * NOTES: The protocol field of rclnp_proto is set to zero indicating | |
119 | * no protocol. | |
120 | */ | |
121 | rclnp_input(m, src, dst, hdrlen) | |
122 | struct mbuf *m; /* ptr to packet */ | |
123 | struct sockaddr_iso *src; /* ptr to src address */ | |
124 | struct sockaddr_iso *dst; /* ptr to dest address */ | |
125 | int hdrlen; /* length (in bytes) of clnp header */ | |
126 | { | |
127 | #ifdef TROLL | |
128 | if (trollctl.tr_ops & TR_CHUCK) { | |
129 | m_freem(m); | |
130 | return; | |
131 | } | |
132 | #endif /* TROLL */ | |
133 | ||
134 | raw_input(m, &rclnp_proto, (struct sockaddr *)src, (struct sockaddr *)dst); | |
135 | } | |
136 | ||
137 | /* | |
138 | * FUNCTION: rclnp_output | |
139 | * | |
140 | * PURPOSE: Prepare to send a raw clnp packet. Setup src and dest | |
141 | * addresses, count the number of bytes to send, and | |
142 | * call clnp_output. | |
143 | * | |
144 | * RETURNS: success - 0 | |
145 | * failure - an appropriate error code | |
146 | * | |
147 | * SIDE EFFECTS: | |
148 | * | |
149 | * NOTES: | |
150 | */ | |
151 | rclnp_output(m0, so) | |
152 | struct mbuf *m0; /* packet to send */ | |
153 | struct socket *so; /* socket to send from */ | |
154 | { | |
155 | register struct mbuf *m; /* used to scan a chain */ | |
156 | int len = 0; /* store length of chain here */ | |
157 | struct rawisopcb *rp = sotorawisopcb(so); /* ptr to raw cb */ | |
158 | int error; /* return value of function */ | |
159 | int flags; /* flags for clnp_output */ | |
160 | ||
161 | if (0 == (m0->m_flags & M_PKTHDR)) | |
162 | return (EINVAL); | |
163 | /* | |
164 | * Set up src address. If user has bound socket to an address, use it. | |
165 | * Otherwise, do not specify src (clnp_output will fill it in). | |
166 | */ | |
167 | if (rp->risop_rcb.rcb_laddr) { | |
168 | if (rp->risop_isop.isop_sladdr.siso_family != AF_ISO) { | |
169 | bad: | |
170 | m_freem(m0); | |
171 | return(EAFNOSUPPORT); | |
172 | } | |
173 | } | |
174 | /* set up dest address */ | |
175 | if (rp->risop_rcb.rcb_faddr == 0) | |
176 | goto bad; | |
177 | rp->risop_isop.isop_sfaddr = | |
178 | *(struct sockaddr_iso *)rp->risop_rcb.rcb_faddr; | |
179 | rp->risop_isop.isop_faddr = &rp->risop_isop.isop_sfaddr; | |
180 | ||
181 | /* get flags and ship it off */ | |
182 | flags = rp->risop_flags & CLNP_VFLAGS; | |
183 | ||
184 | error = clnp_output(m0, &rp->risop_isop, m0->m_pkthdr.len, | |
185 | flags|CLNP_NOCACHE); | |
186 | ||
187 | return (error); | |
188 | } | |
189 | ||
190 | /* | |
191 | * FUNCTION: rclnp_ctloutput | |
192 | * | |
193 | * PURPOSE: Raw clnp socket option processing | |
194 | * All options are stored inside an mbuf. | |
195 | * | |
196 | * RETURNS: success - 0 | |
197 | * failure - unix error code | |
198 | * | |
199 | * SIDE EFFECTS: If the options mbuf does not exist, it the mbuf passed | |
200 | * is used. | |
201 | * | |
202 | * NOTES: | |
203 | */ | |
204 | rclnp_ctloutput(op, so, level, optname, m) | |
205 | int op; /* type of operation */ | |
206 | struct socket *so; /* ptr to socket */ | |
207 | int level; /* level of option */ | |
208 | int optname; /* name of option */ | |
209 | struct mbuf **m; /* ptr to ptr to option data */ | |
210 | { | |
211 | int error = 0; | |
212 | register struct rawisopcb *rp = sotorawisopcb(so);/* raw cb ptr */ | |
213 | ||
214 | IFDEBUG(D_CTLOUTPUT) | |
215 | printf("rclnp_ctloutput: op = x%x, level = x%x, name = x%x\n", | |
216 | op, level, optname); | |
217 | if (*m != NULL) { | |
218 | printf("rclnp_ctloutput: %d bytes of mbuf data\n", (*m)->m_len); | |
219 | dump_buf(mtod((*m), caddr_t), (*m)->m_len); | |
220 | } | |
221 | ENDDEBUG | |
222 | ||
223 | #ifdef SOL_NETWORK | |
224 | if (level != SOL_NETWORK) | |
225 | error = EINVAL; | |
226 | else switch (op) { | |
227 | #else | |
228 | switch (op) { | |
229 | #endif /* SOL_NETWORK */ | |
230 | case PRCO_SETOPT: | |
231 | switch (optname) { | |
232 | case CLNPOPT_FLAGS: { | |
233 | u_short usr_flags; | |
234 | /* | |
235 | * Insure that the data passed has exactly one short in it | |
236 | */ | |
237 | if ((*m == NULL) || ((*m)->m_len != sizeof(short))) { | |
238 | error = EINVAL; | |
239 | break; | |
240 | } | |
241 | ||
242 | /* | |
243 | * Don't allow invalid flags to be set | |
244 | */ | |
245 | usr_flags = (*mtod((*m), short *)); | |
246 | ||
247 | if ((usr_flags & (CLNP_VFLAGS)) != usr_flags) { | |
248 | error = EINVAL; | |
249 | } else | |
250 | rp->risop_flags |= usr_flags; | |
251 | ||
252 | } break; | |
253 | ||
254 | case CLNPOPT_OPTS: | |
255 | if (error = clnp_set_opts(&rp->risop_isop.isop_options, m)) | |
256 | break; | |
257 | rp->risop_isop.isop_optindex = m_get(M_WAIT, MT_SOOPTS); | |
258 | (void) clnp_opt_sanity(rp->risop_isop.isop_options, | |
259 | mtod(rp->risop_isop.isop_options, caddr_t), | |
260 | rp->risop_isop.isop_options->m_len, | |
261 | mtod(rp->risop_isop.isop_optindex, | |
262 | struct clnp_optidx *)); | |
263 | break; | |
264 | } | |
265 | break; | |
266 | ||
267 | case PRCO_GETOPT: | |
268 | #ifdef notdef | |
269 | /* commented out to keep hi C quiet */ | |
270 | switch (optname) { | |
271 | default: | |
272 | error = EINVAL; | |
273 | break; | |
274 | } | |
275 | #endif /* notdef */ | |
276 | break; | |
277 | default: | |
278 | error = EINVAL; | |
279 | break; | |
280 | } | |
281 | if (op == PRCO_SETOPT) { | |
282 | /* note: m_freem does not barf is *m is NULL */ | |
283 | m_freem(*m); | |
284 | *m = NULL; | |
285 | } | |
286 | ||
287 | return error; | |
288 | } | |
289 | ||
290 | /*ARGSUSED*/ | |
291 | clnp_usrreq(so, req, m, nam, control) | |
292 | register struct socket *so; | |
293 | int req; | |
294 | struct mbuf *m, *nam, *control; | |
295 | { | |
296 | register int error = 0; | |
297 | register struct rawisopcb *rp = sotorawisopcb(so); | |
298 | ||
299 | rp = sotorawisopcb(so); | |
300 | switch (req) { | |
301 | ||
302 | case PRU_ATTACH: | |
303 | if (rp) | |
304 | panic("rip_attach"); | |
305 | MALLOC(rp, struct rawisopcb *, sizeof *rp, M_PCB, M_WAITOK); | |
306 | if (rp == 0) | |
307 | return (ENOBUFS); | |
308 | bzero((caddr_t)rp, sizeof *rp); | |
309 | so->so_pcb = (caddr_t)rp; | |
310 | break; | |
311 | ||
312 | case PRU_DETACH: | |
313 | if (rp == 0) | |
314 | panic("rip_detach"); | |
315 | if (rp->risop_isop.isop_options) | |
316 | m_freem(rp->risop_isop.isop_options); | |
317 | if (rp->risop_isop.isop_route.ro_rt) | |
318 | RTFREE(rp->risop_isop.isop_route.ro_rt); | |
319 | if (rp->risop_rcb.rcb_laddr) | |
320 | rp->risop_rcb.rcb_laddr = 0; | |
321 | /* free clnp cached hdr if necessary */ | |
322 | if (rp->risop_isop.isop_clnpcache != NULL) { | |
323 | struct clnp_cache *clcp = | |
324 | mtod(rp->risop_isop.isop_clnpcache, struct clnp_cache *); | |
325 | if (clcp->clc_hdr != NULL) { | |
326 | m_free(clcp->clc_hdr); | |
327 | } | |
328 | m_free(rp->risop_isop.isop_clnpcache); | |
329 | } | |
330 | if (rp->risop_isop.isop_optindex != NULL) | |
331 | m_free(rp->risop_isop.isop_optindex); | |
332 | ||
333 | break; | |
334 | ||
335 | case PRU_BIND: | |
336 | { | |
337 | struct sockaddr_iso *addr = mtod(nam, struct sockaddr_iso *); | |
338 | ||
339 | if (nam->m_len != sizeof(*addr)) | |
340 | return (EINVAL); | |
341 | if ((ifnet == 0) || | |
342 | (addr->siso_family != AF_ISO) || | |
343 | (addr->siso_addr.isoa_len && | |
344 | ifa_ifwithaddr((struct sockaddr *)addr) == 0)) | |
345 | return (EADDRNOTAVAIL); | |
346 | rp->risop_isop.isop_sladdr = *addr; | |
347 | rp->risop_rcb.rcb_laddr = (struct sockaddr *) | |
348 | (rp->risop_isop.isop_laddr = &rp->risop_isop.isop_sladdr); | |
349 | return (0); | |
350 | } | |
351 | case PRU_CONNECT: | |
352 | { | |
353 | struct sockaddr_iso *addr = mtod(nam, struct sockaddr_iso *); | |
354 | ||
355 | if ((nam->m_len > sizeof(*addr)) || (addr->siso_len > sizeof(*addr))) | |
356 | return (EINVAL); | |
357 | if (ifnet == 0) | |
358 | return (EADDRNOTAVAIL); | |
359 | if (addr->siso_family != AF_ISO) | |
360 | rp->risop_isop.isop_sfaddr = *addr; | |
361 | rp->risop_rcb.rcb_faddr = (struct sockaddr *) | |
362 | (rp->risop_isop.isop_faddr = &rp->risop_isop.isop_sfaddr); | |
363 | soisconnected(so); | |
364 | return (0); | |
365 | } | |
366 | } | |
367 | error = raw_usrreq(so, req, m, nam, control); | |
368 | ||
369 | if (error && req == PRU_ATTACH && so->so_pcb) | |
370 | FREE((caddr_t)rp, M_PCB); | |
371 | return (error); | |
372 | } |