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