ip_output takes 5 args now; other miscelleny due to prototypes in header files
[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 *
9f4ad8e6 7 * @(#)clnp_raw.c 7.12 (Berkeley) %G%
7bcd1bb8
KB
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
5548a02f
KB
39#include <sys/param.h>
40#include <sys/mbuf.h>
41#include <sys/domain.h>
42#include <sys/protosw.h>
43#include <sys/socket.h>
44#include <sys/socketvar.h>
45#include <sys/errno.h>
46#include <sys/time.h>
986fd057 47
5548a02f
KB
48#include <net/if.h>
49#include <net/route.h>
50#include <net/raw_cb.h>
986fd057 51
5548a02f
KB
52#include <netiso/iso.h>
53#include <netiso/iso_pcb.h>
54#include <netiso/clnp.h>
55#include <netiso/clnp_stat.h>
56#include <netiso/argo_debug.h>
986fd057 57
5548a02f 58#include <netiso/tp_user.h> /* XXX -- defines SOL_NETWORK */
a50e2bc0 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 }
4d8170e5 86#endif /* TROLL */
986fd057 87
9f4ad8e6 88 raw_input(m, &rclnp_proto, (struct sockaddr *)src, (struct sockaddr *)dst);
986fd057
KS
89}
90
91/*
92 * FUNCTION: rclnp_output
93 *
94 * PURPOSE: Prepare to send a raw clnp packet. Setup src and dest
95 * addresses, count the number of bytes to send, and
96 * call clnp_output.
97 *
98 * RETURNS: success - 0
99 * failure - an appropriate error code
100 *
101 * SIDE EFFECTS:
102 *
103 * NOTES:
104 */
105rclnp_output(m0, so)
106struct mbuf *m0; /* packet to send */
107struct socket *so; /* socket to send from */
108{
109 register struct mbuf *m; /* used to scan a chain */
110 int len = 0; /* store length of chain here */
a50e2bc0 111 struct rawisopcb *rp = sotorawisopcb(so); /* ptr to raw cb */
986fd057 112 int error; /* return value of function */
a50e2bc0 113 int flags; /* flags for clnp_output */
986fd057 114
97f0cba7 115 if (0 == (m0->m_flags & M_PKTHDR))
44f52ea5 116 return (EINVAL);
986fd057
KS
117 /*
118 * Set up src address. If user has bound socket to an address, use it.
119 * Otherwise, do not specify src (clnp_output will fill it in).
120 */
a50e2bc0
KS
121 if (rp->risop_rcb.rcb_laddr) {
122 if (rp->risop_isop.isop_sladdr.siso_family != AF_ISO) {
123bad:
986fd057
KS
124 m_freem(m0);
125 return(EAFNOSUPPORT);
126 }
986fd057 127 }
986fd057 128 /* set up dest address */
a50e2bc0
KS
129 if (rp->risop_rcb.rcb_faddr == 0)
130 goto bad;
131 rp->risop_isop.isop_sfaddr =
132 *(struct sockaddr_iso *)rp->risop_rcb.rcb_faddr;
133 rp->risop_isop.isop_faddr = &rp->risop_isop.isop_sfaddr;
986fd057
KS
134
135 /* get flags and ship it off */
a50e2bc0 136 flags = rp->risop_flags & CLNP_VFLAGS;
986fd057 137
44f52ea5
KS
138 error = clnp_output(m0, &rp->risop_isop, m0->m_pkthdr.len,
139 flags|CLNP_NOCACHE);
986fd057
KS
140
141 return (error);
142}
143
144/*
145 * FUNCTION: rclnp_ctloutput
146 *
147 * PURPOSE: Raw clnp socket option processing
148 * All options are stored inside an mbuf.
149 *
150 * RETURNS: success - 0
151 * failure - unix error code
152 *
153 * SIDE EFFECTS: If the options mbuf does not exist, it the mbuf passed
154 * is used.
155 *
156 * NOTES:
157 */
158rclnp_ctloutput(op, so, level, optname, m)
159int op; /* type of operation */
160struct socket *so; /* ptr to socket */
161int level; /* level of option */
162int optname; /* name of option */
163struct mbuf **m; /* ptr to ptr to option data */
164{
165 int error = 0;
a50e2bc0 166 register struct rawisopcb *rp = sotorawisopcb(so);/* raw cb ptr */
986fd057
KS
167
168 IFDEBUG(D_CTLOUTPUT)
169 printf("rclnp_ctloutput: op = x%x, level = x%x, name = x%x\n",
170 op, level, optname);
171 if (*m != NULL) {
172 printf("rclnp_ctloutput: %d bytes of mbuf data\n", (*m)->m_len);
173 dump_buf(mtod((*m), caddr_t), (*m)->m_len);
174 }
175 ENDDEBUG
176
177#ifdef SOL_NETWORK
178 if (level != SOL_NETWORK)
179 error = EINVAL;
180 else switch (op) {
181#else
182 switch (op) {
4d8170e5 183#endif /* SOL_NETWORK */
986fd057
KS
184 case PRCO_SETOPT:
185 switch (optname) {
186 case CLNPOPT_FLAGS: {
187 u_short usr_flags;
188 /*
189 * Insure that the data passed has exactly one short in it
190 */
191 if ((*m == NULL) || ((*m)->m_len != sizeof(short))) {
192 error = EINVAL;
193 break;
194 }
195
196 /*
197 * Don't allow invalid flags to be set
198 */
199 usr_flags = (*mtod((*m), short *));
200
201 if ((usr_flags & (CLNP_VFLAGS)) != usr_flags) {
202 error = EINVAL;
203 } else
a50e2bc0 204 rp->risop_flags |= usr_flags;
986fd057
KS
205
206 } break;
207
208 case CLNPOPT_OPTS:
a50e2bc0
KS
209 if (error = clnp_set_opts(&rp->risop_isop.isop_options, m))
210 break;
211 rp->risop_isop.isop_optindex = m_get(M_WAIT, MT_SOOPTS);
212 (void) clnp_opt_sanity(rp->risop_isop.isop_options,
213 mtod(rp->risop_isop.isop_options, caddr_t),
214 rp->risop_isop.isop_options->m_len,
215 mtod(rp->risop_isop.isop_optindex,
216 struct clnp_optidx *));
986fd057
KS
217 break;
218 }
219 break;
220
221 case PRCO_GETOPT:
222#ifdef notdef
223 /* commented out to keep hi C quiet */
224 switch (optname) {
225 default:
226 error = EINVAL;
227 break;
228 }
4d8170e5 229#endif /* notdef */
986fd057
KS
230 break;
231 default:
232 error = EINVAL;
233 break;
234 }
235 if (op == PRCO_SETOPT) {
236 /* note: m_freem does not barf is *m is NULL */
237 m_freem(*m);
238 *m = NULL;
239 }
240
241 return error;
242}
243
244/*ARGSUSED*/
118a1fb8 245clnp_usrreq(so, req, m, nam, control)
a50e2bc0 246 register struct socket *so;
986fd057 247 int req;
118a1fb8 248 struct mbuf *m, *nam, *control;
986fd057 249{
a50e2bc0
KS
250 register int error = 0;
251 register struct rawisopcb *rp = sotorawisopcb(so);
252
253 rp = sotorawisopcb(so);
254 switch (req) {
255
256 case PRU_ATTACH:
257 if (rp)
258 panic("rip_attach");
259 MALLOC(rp, struct rawisopcb *, sizeof *rp, M_PCB, M_WAITOK);
260 if (rp == 0)
261 return (ENOBUFS);
262 bzero((caddr_t)rp, sizeof *rp);
263 so->so_pcb = (caddr_t)rp;
264 break;
265
266 case PRU_DETACH:
267 if (rp == 0)
268 panic("rip_detach");
269 if (rp->risop_isop.isop_options)
270 m_freem(rp->risop_isop.isop_options);
271 if (rp->risop_isop.isop_route.ro_rt)
272 RTFREE(rp->risop_isop.isop_route.ro_rt);
273 if (rp->risop_rcb.rcb_laddr)
274 rp->risop_rcb.rcb_laddr = 0;
275 /* free clnp cached hdr if necessary */
276 if (rp->risop_isop.isop_clnpcache != NULL) {
277 struct clnp_cache *clcp =
278 mtod(rp->risop_isop.isop_clnpcache, struct clnp_cache *);
279 if (clcp->clc_hdr != NULL) {
280 m_free(clcp->clc_hdr);
281 }
282 m_free(rp->risop_isop.isop_clnpcache);
283 }
284 if (rp->risop_isop.isop_optindex != NULL)
285 m_free(rp->risop_isop.isop_optindex);
286
287 break;
288
289 case PRU_BIND:
290 {
291 struct sockaddr_iso *addr = mtod(nam, struct sockaddr_iso *);
292
293 if (nam->m_len != sizeof(*addr))
294 return (EINVAL);
295 if ((ifnet == 0) ||
296 (addr->siso_family != AF_ISO) ||
297 (addr->siso_addr.isoa_len &&
298 ifa_ifwithaddr((struct sockaddr *)addr) == 0))
299 return (EADDRNOTAVAIL);
300 rp->risop_isop.isop_sladdr = *addr;
301 rp->risop_rcb.rcb_laddr = (struct sockaddr *)
302 (rp->risop_isop.isop_laddr = &rp->risop_isop.isop_sladdr);
303 return (0);
304 }
305 case PRU_CONNECT:
306 {
307 struct sockaddr_iso *addr = mtod(nam, struct sockaddr_iso *);
308
309 if ((nam->m_len > sizeof(*addr)) || (addr->siso_len > sizeof(*addr)))
310 return (EINVAL);
311 if (ifnet == 0)
312 return (EADDRNOTAVAIL);
313 if (addr->siso_family != AF_ISO)
314 rp->risop_isop.isop_sfaddr = *addr;
315 rp->risop_rcb.rcb_faddr = (struct sockaddr *)
316 (rp->risop_isop.isop_faddr = &rp->risop_isop.isop_sfaddr);
317 soisconnected(so);
318 return (0);
319 }
320 }
118a1fb8 321 error = raw_usrreq(so, req, m, nam, control);
a50e2bc0
KS
322
323 if (error && req == PRU_ATTACH && so->so_pcb)
324 free((caddr_t)rp, M_PCB);
325 return (error);
986fd057 326}