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