Initial import, 0.1 + pk 0.2.4-B1
[unix-history] / sys / netiso / clnp_raw.c
CommitLineData
15637ed4
RG
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
41Permission to use, copy, modify, and distribute this software and its
42documentation for any purpose and without fee is hereby granted,
43provided that the above copyright notice appear in all copies and that
44both that copyright notice and this permission notice appear in
45supporting documentation, and that the name of IBM not be
46used in advertising or publicity pertaining to distribution of the
47software without specific, written prior permission.
48
49IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
50ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
51IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
52ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
53WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
54ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
55SOFTWARE.
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
86struct 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 */
101rclnp_input(m, src, dst, hdrlen)
102struct mbuf *m; /* ptr to packet */
103struct sockaddr_iso *src; /* ptr to src address */
104struct sockaddr_iso *dst; /* ptr to dest address */
105int 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 */
135rclnp_output(m0, so)
136struct mbuf *m0; /* packet to send */
137struct 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) {
153bad:
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 */
188rclnp_ctloutput(op, so, level, optname, m)
189int op; /* type of operation */
190struct socket *so; /* ptr to socket */
191int level; /* level of option */
192int optname; /* name of option */
193struct 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*/
275clnp_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}