file modes have to agree
[unix-history] / usr / src / sys / netiso / clnp_raw.c
CommitLineData
986fd057
KS
1/***********************************************************
2 Copyright IBM Corporation 1987
3
4 All Rights Reserved
5
6Permission to use, copy, modify, and distribute this software and its
7documentation for any purpose and without fee is hereby granted,
8provided that the above copyright notice appear in all copies and that
9both that copyright notice and this permission notice appear in
10supporting documentation, and that the name of IBM not be
11used in advertising or publicity pertaining to distribution of the
12software without specific, written prior permission.
13
14IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
15ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
16IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
17ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
18WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
19ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
20SOFTWARE.
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#ifndef lint
30static char *rcsid = "$Header: clnp_raw.c,v 4.2 88/06/29 14:58:56 hagens Exp $";
31#endif lint
32
33#ifdef ISO
34
35#include "../h/types.h"
36#include "../h/param.h"
37#include "../h/mbuf.h"
38#include "../h/domain.h"
39#include "../h/protosw.h"
40#include "../h/socket.h"
41#include "../h/socketvar.h"
42#include "../h/errno.h"
43#include "../h/time.h"
44
45#include "../net/if.h"
46#include "../net/route.h"
47#include "../net/raw_cb.h"
48
49#include "../netiso/iso.h"
50#include "../netiso/iso_pcb.h"
51#include "../netiso/clnp.h"
52#include "../netiso/clnp_stat.h"
53#include "../netiso/argo_debug.h"
54
55struct sockaddr_iso rclnp_src = { AF_ISO };
56struct sockaddr_iso rclnp_dst = { AF_ISO };
57struct sockproto rclnp_proto = { PF_ISO, 0 };
58/*
59 * FUNCTION: rclnp_input
60 *
61 * PURPOSE: Setup generic address an protocol structures for
62 * raw input routine, then pass them along with the
63 * mbuf chain.
64 *
65 * RETURNS: none
66 *
67 * SIDE EFFECTS:
68 *
69 * NOTES: The protocol field of rclnp_proto is set to zero indicating
70 * no protocol.
71 */
72rclnp_input(m, src, dst, hdrlen)
73struct mbuf *m; /* ptr to packet */
74struct iso_addr *src; /* ptr to src address */
75struct iso_addr *dst; /* ptr to dest address */
76int hdrlen; /* length (in bytes) of clnp header */
77{
78#ifdef TROLL
79 if (trollctl.tr_ops & TR_CHUCK) {
80 m_freem(m);
81 return;
82 }
83#endif TROLL
84
85 rclnp_src.siso_addr = *src;
86 rclnp_dst.siso_addr = *dst;
87 raw_input(m, &rclnp_proto, (struct sockaddr *)&rclnp_src,
88 (struct sockaddr *)&rclnp_dst);
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 */
111 struct rawcb *rp = sotorawcb(so); /* ptr to raw cb */
112 int error; /* return value of function */
113 u_int flags; /* flags for clnp_output */
114 struct isopcb isopcb; /* isopcb used to interface w/clnp */
115
116 /* Calculate length of data */
117 for (m = m0; m; m = m->m_next)
118 len += m->m_len;
119
120 bzero((caddr_t)&isopcb, sizeof(isopcb));
121
122 /*
123 * Set up src address. If user has bound socket to an address, use it.
124 * Otherwise, do not specify src (clnp_output will fill it in).
125 */
126 if (rp->rcb_flags & RAW_LADDR) {
127 if (rp->rcb_laddr.sa_family != AF_ISO) {
128 m_freem(m0);
129 return(EAFNOSUPPORT);
130 }
131 bcopy((caddr_t)&rp->rcb_laddr, &isopcb.isop_laddr,
132 sizeof(struct sockaddr_iso));
133 }
134
135 /* set up route structure, if route is present */
136 if (rp->rcb_route.ro_rt != NULL)
137 bcopy((caddr_t)&rp->rcb_route, (caddr_t)&isopcb.isop_route,
138 sizeof(struct route));
139
140 /* set up dest address */
141 bcopy((caddr_t)&rp->rcb_faddr, &isopcb.isop_faddr,
142 sizeof(struct sockaddr_iso));
143
144 /*
145 * setup option index - this was done when option was set, but raw
146 * cb has no place to put it.
147 */
148 if (rp->rcb_options != NULL) {
149 isopcb.isop_options = rp->rcb_options;
150 isopcb.isop_optindex = m_get(M_WAIT, MT_SOOPTS);
151 (void) clnp_opt_sanity(isopcb.isop_options,
152 mtod(isopcb.isop_options, caddr_t), isopcb.isop_options->m_len,
153 mtod(isopcb.isop_optindex, struct clnp_optidx *));
154 }
155
156 /* get flags and ship it off */
157 flags = rp->rcb_flags & CLNP_VFLAGS;
158
159#ifdef TROLL
160 if (trollctl.tr_ops & TR_BLAST) {
161 register int i;
162 struct timeval start, stop;
163 extern struct timeval time;
164 struct mbuf *mbuf_orig;
165
166 mbuf_orig = m0;
167 start = time;
168 for (i=0; i<trollctl.tr_blast_cnt; i++) {
169 m0 = m_copy(mbuf_orig, 0, M_COPYALL);
170 if (m0 == NULL) {
171 error = ENOBUFS;
172 } else {
173 error = clnp_output(m0, &isopcb, len, flags);
174 }
175 if (error)
176 break;
177 }
178 stop = time;
179 printf("rclnp_output: %d pkts in %d sec\n", i,
180 stop.tv_sec - start.tv_sec);
181 m_freem(mbuf_orig);
182 } else {
183 /*
184 * Don't bother creating the cache since this is raw; probably
185 * a one shot send
186 */
187 error = clnp_output(m0, &isopcb, len, flags|CLNP_NOCACHE);
188 }
189#else
190 error = clnp_output(m0, &isopcb, len, flags|CLNP_NOCACHE);
191#endif TROLL
192
193 if (isopcb.isop_route.ro_rt)
194 RTFREE(isopcb.isop_route.ro_rt);
195
196 /* free clnp cached hdr if necessary */
197 if (isopcb.isop_clnpcache != NULL) {
198 struct clnp_cache *clcp =
199 mtod(isopcb.isop_clnpcache, struct clnp_cache *);
200 if (clcp->clc_hdr != NULL) {
201 m_free(clcp->clc_hdr);
202 }
203 m_free(isopcb.isop_clnpcache);
204 }
205
206 if (isopcb.isop_optindex != NULL)
207 m_free(isopcb.isop_optindex);
208
209 return (error);
210}
211
212/*
213 * FUNCTION: rclnp_ctloutput
214 *
215 * PURPOSE: Raw clnp socket option processing
216 * All options are stored inside an mbuf.
217 *
218 * RETURNS: success - 0
219 * failure - unix error code
220 *
221 * SIDE EFFECTS: If the options mbuf does not exist, it the mbuf passed
222 * is used.
223 *
224 * NOTES:
225 */
226rclnp_ctloutput(op, so, level, optname, m)
227int op; /* type of operation */
228struct socket *so; /* ptr to socket */
229int level; /* level of option */
230int optname; /* name of option */
231struct mbuf **m; /* ptr to ptr to option data */
232{
233 int error = 0;
234 register struct rawcb *rp = sotorawcb(so);/* raw cb ptr */
235
236 IFDEBUG(D_CTLOUTPUT)
237 printf("rclnp_ctloutput: op = x%x, level = x%x, name = x%x\n",
238 op, level, optname);
239 if (*m != NULL) {
240 printf("rclnp_ctloutput: %d bytes of mbuf data\n", (*m)->m_len);
241 dump_buf(mtod((*m), caddr_t), (*m)->m_len);
242 }
243 ENDDEBUG
244
245#ifdef SOL_NETWORK
246 if (level != SOL_NETWORK)
247 error = EINVAL;
248 else switch (op) {
249#else
250 switch (op) {
251#endif SOL_NETWORK
252 case PRCO_SETOPT:
253 switch (optname) {
254 case CLNPOPT_FLAGS: {
255 u_short usr_flags;
256 /*
257 * Insure that the data passed has exactly one short in it
258 */
259 if ((*m == NULL) || ((*m)->m_len != sizeof(short))) {
260 error = EINVAL;
261 break;
262 }
263
264 /*
265 * Don't allow invalid flags to be set
266 */
267 usr_flags = (*mtod((*m), short *));
268
269 if ((usr_flags & (CLNP_VFLAGS)) != usr_flags) {
270 error = EINVAL;
271 } else
272 rp->rcb_flags |= usr_flags;
273
274 } break;
275
276 case CLNPOPT_OPTS:
277 error = clnp_set_opts(&rp->rcb_options, m);
278 break;
279 }
280 break;
281
282 case PRCO_GETOPT:
283#ifdef notdef
284 /* commented out to keep hi C quiet */
285 switch (optname) {
286 default:
287 error = EINVAL;
288 break;
289 }
290#endif notdef
291 break;
292 default:
293 error = EINVAL;
294 break;
295 }
296 if (op == PRCO_SETOPT) {
297 /* note: m_freem does not barf is *m is NULL */
298 m_freem(*m);
299 *m = NULL;
300 }
301
302 return error;
303}
304
305/*ARGSUSED*/
306clnp_usrreq(so, req, m, nam, rights)
307 struct socket *so;
308 int req;
309 struct mbuf *m, *nam, *rights;
310{
311 return EPROTOTYPE;
312}
313#endif ISO