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