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