Implement 4.4's SUGID flag, which keeps track of processes which
[unix-history] / sys / netiso / cltp_usrreq.c
CommitLineData
15637ed4
RG
1/*
2 * Copyright (c) 1989 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 *
43371f85 33 * from: @(#)cltp_usrreq.c 7.6 (Berkeley) 6/27/91
4c45483e 34 * $Id: cltp_usrreq.c,v 1.4 1993/11/07 17:49:27 wollman Exp $
15637ed4
RG
35 */
36
37#ifndef CLTPOVAL_SRC /* XXX -- till files gets changed */
38#include "param.h"
dd18dc33 39#include "systm.h"
15637ed4
RG
40#include "malloc.h"
41#include "mbuf.h"
42#include "protosw.h"
43#include "socket.h"
44#include "socketvar.h"
45#include "errno.h"
46#include "stat.h"
47
48#include "../net/if.h"
49#include "../net/route.h"
50
51#include "argo_debug.h"
52#include "iso.h"
53#include "iso_pcb.h"
54#include "iso_var.h"
55#include "clnp.h"
56#include "cltp_var.h"
57#endif
58
8ace4366
GW
59struct isopcb cltb;
60struct cltpstat cltpstat;
61
62
15637ed4
RG
63/*
64 * CLTP protocol implementation.
65 * Per ISO 8602, December, 1987.
66 */
4c45483e 67void
15637ed4
RG
68cltp_init()
69{
70
71 cltb.isop_next = cltb.isop_prev = &cltb;
72}
73
74int cltp_cksum = 1;
75
76
77/* ARGUSED */
4c45483e 78int
15637ed4
RG
79cltp_input(m0, srcsa, dstsa, cons_channel, output)
80 struct mbuf *m0;
81 struct sockaddr *srcsa, *dstsa;
82 u_int cons_channel;
83 int (*output)();
84{
85 register struct isopcb *isop;
86 register struct mbuf *m = m0;
87 register u_char *up = mtod(m, u_char *);
88 register struct sockaddr_iso *src = (struct sockaddr_iso *)srcsa;
89 int len, hdrlen = *up + 1, dlen = 0;
90 u_char *uplim = up + hdrlen;
4c45483e 91 caddr_t dtsap = 0;
15637ed4
RG
92
93 for (len = 0; m; m = m->m_next)
94 len += m->m_len;
95 up += 2; /* skip header */
96 while (up < uplim) switch (*up) { /* process options */
97 case CLTPOVAL_SRC:
98 src->siso_tlen = up[1];
99 src->siso_len = up[1] + TSEL(src) - (caddr_t)src;
100 if (src->siso_len < sizeof(*src))
101 src->siso_len = sizeof(*src);
102 else if (src->siso_len > sizeof(*src)) {
103 MGET(m, M_DONTWAIT, MT_SONAME);
104 if (m == 0)
105 goto bad;
106 m->m_len = src->siso_len;
107 src = mtod(m, struct sockaddr_iso *);
108 bcopy((caddr_t)srcsa, (caddr_t)src, srcsa->sa_len);
109 }
110 bcopy((caddr_t)up + 2, TSEL(src), up[1]);
111 up += 2 + src->siso_tlen;
112 continue;
113
114 case CLTPOVAL_DST:
115 dtsap = 2 + (caddr_t)up;
116 dlen = up[1];
117 up += 2 + dlen;
118 continue;
119
120 case CLTPOVAL_CSM:
121 if (iso_check_csum(m0, len)) {
122 cltpstat.cltps_badsum++;
123 goto bad;
124 }
125 up += 4;
126 continue;
127
128 default:
129 printf("clts: unknown option (%x)\n", up[0]);
130 cltpstat.cltps_hdrops++;
131 goto bad;
132 }
133 if (dlen == 0 || src->siso_tlen == 0)
134 goto bad;
135 for (isop = cltb.isop_next;; isop = isop->isop_next) {
136 if (isop == &cltb) {
137 cltpstat.cltps_noport++;
138 goto bad;
139 }
140 if (isop->isop_laddr &&
141 bcmp(TSEL(isop->isop_laddr), dtsap, dlen) == 0)
142 break;
143 }
144 m = m0;
145 m->m_len -= hdrlen;
146 m->m_data += hdrlen;
147 if (sbappendaddr(&isop->isop_socket->so_rcv, (struct sockaddr *)src,
148 m, (struct mbuf *)0) == 0)
149 goto bad;
150 cltpstat.cltps_ipackets++;
151 sorwakeup(isop->isop_socket);
152 m0 = 0;
153bad:
154 if (src != (struct sockaddr_iso *)srcsa)
155 m_freem(dtom(src));
156 if (m0)
157 m_freem(m0);
158 return 0;
159}
160
161/*
162 * Notify a cltp user of an asynchronous error;
163 * just wake up so that he can collect error status.
164 */
4c45483e 165void
15637ed4
RG
166cltp_notify(isop)
167 register struct isopcb *isop;
168{
169
170 sorwakeup(isop->isop_socket);
171 sowwakeup(isop->isop_socket);
172}
173
4c45483e 174void
15637ed4
RG
175cltp_ctlinput(cmd, sa)
176 int cmd;
177 struct sockaddr *sa;
178{
179 extern u_char inetctlerrmap[];
180 struct sockaddr_iso *siso;
181 int iso_rtchange();
182
183 if ((unsigned)cmd > PRC_NCMDS)
184 return;
185 if (sa->sa_family != AF_ISO && sa->sa_family != AF_CCITT)
186 return;
187 siso = (struct sockaddr_iso *)sa;
188 if (siso == 0 || siso->siso_nlen == 0)
189 return;
190
191 switch (cmd) {
192 case PRC_ROUTEDEAD:
193 case PRC_REDIRECT_NET:
194 case PRC_REDIRECT_HOST:
195 case PRC_REDIRECT_TOSNET:
196 case PRC_REDIRECT_TOSHOST:
197 iso_pcbnotify(&cltb, siso,
198 (int)inetctlerrmap[cmd], iso_rtchange);
199 break;
200
201 default:
202 if (inetctlerrmap[cmd] == 0)
203 return; /* XXX */
204 iso_pcbnotify(&cltb, siso, (int)inetctlerrmap[cmd],
205 cltp_notify);
206 }
207}
208
4c45483e 209int
15637ed4
RG
210cltp_output(isop, m)
211 register struct isopcb *isop;
212 register struct mbuf *m;
213{
214 register int len;
215 register struct sockaddr_iso *siso;
216 int hdrlen, error = 0, docsum;
217 register u_char *up;
218
219 if (isop->isop_laddr == 0 || isop->isop_faddr == 0) {
220 error = ENOTCONN;
221 goto bad;
222 }
223 /*
224 * Calculate data length and get a mbuf for CLTP header.
225 */
226 hdrlen = 2 + 2 + isop->isop_laddr->siso_tlen
227 + 2 + isop->isop_faddr->siso_tlen;
228 if (docsum = /*isop->isop_flags & CLNP_NO_CKSUM*/ cltp_cksum)
229 hdrlen += 4;
230 M_PREPEND(m, hdrlen, M_WAIT);
231 len = m->m_pkthdr.len;
232 /*
233 * Fill in mbuf with extended CLTP header
234 */
235 up = mtod(m, u_char *);
236 up[0] = hdrlen - 1;
237 up[1] = UD_TPDU_type;
238 up[2] = CLTPOVAL_SRC;
239 up[3] = (siso = isop->isop_laddr)->siso_tlen;
240 up += 4;
241 bcopy(TSEL(siso), (caddr_t)up, siso->siso_tlen);
242 up += siso->siso_tlen;
243 up[0] = CLTPOVAL_DST;
244 up[1] = (siso = isop->isop_faddr)->siso_tlen;
245 up += 2;
246 bcopy(TSEL(siso), (caddr_t)up, siso->siso_tlen);
247 /*
248 * Stuff checksum and output datagram.
249 */
250 if (docsum) {
251 up += siso->siso_tlen;
252 up[0] = CLTPOVAL_CSM;
253 up[1] = 2;
254 iso_gen_csum(m, 2 + up - mtod(m, u_char *), len);
255 }
256 cltpstat.cltps_opackets++;
257 return (tpclnp_output(isop, m, len, !docsum));
258bad:
259 m_freem(m);
260 return (error);
261}
262
263#ifndef TP_LOCAL
264/* XXXX should go in iso.h maybe? from tp_param.h, in any case */
265#define TP_LOCAL 22
266#define TP_FOREIGN 33
267#endif
268
269u_long cltp_sendspace = 9216; /* really max datagram size */
270u_long cltp_recvspace = 40 * (1024 + sizeof(struct sockaddr_iso));
271 /* 40 1K datagrams */
272
273
274/*ARGSUSED*/
4c45483e 275int
15637ed4
RG
276cltp_usrreq(so, req, m, nam, control)
277 struct socket *so;
278 int req;
279 struct mbuf *m, *nam, *control;
280{
281 struct isopcb *isop = sotoisopcb(so);
4c45483e 282 int s = 0, error = 0;
15637ed4
RG
283
284 if (req == PRU_CONTROL)
285 return (iso_control(so, (int)m, (caddr_t)nam,
286 (struct ifnet *)control));
287 if ((isop == NULL && req != PRU_ATTACH) ||
288 (control && control->m_len)) {
289 error = EINVAL;
290 goto release;
291 }
292 switch (req) {
293
294 case PRU_ATTACH:
295 if (isop != NULL) {
296 error = EINVAL;
297 break;
298 }
299 error = iso_pcballoc(so, &cltb);
300 if (error)
301 break;
302 error = soreserve(so, cltp_sendspace, cltp_recvspace);
303 if (error)
304 break;
305 break;
306
307 case PRU_DETACH:
308 iso_pcbdetach(isop);
309 break;
310
311 case PRU_BIND:
312 error = iso_pcbbind(isop, nam);
313 break;
314
315 case PRU_LISTEN:
316 error = EOPNOTSUPP;
317 break;
318
319 case PRU_CONNECT:
320 if (isop->isop_faddr) {
321 error = EISCONN;
322 break;
323 }
324 error = iso_pcbconnect(isop, nam);
325 if (error == 0)
326 soisconnected(so);
327 break;
328
329 case PRU_CONNECT2:
330 error = EOPNOTSUPP;
331 break;
332
333 case PRU_ACCEPT:
334 error = EOPNOTSUPP;
335 break;
336
337 case PRU_DISCONNECT:
338 if (isop->isop_faddr == 0) {
339 error = ENOTCONN;
340 break;
341 }
342 iso_pcbdisconnect(isop);
343 so->so_state &= ~SS_ISCONNECTED; /* XXX */
344 break;
345
346 case PRU_SHUTDOWN:
347 socantsendmore(so);
348 break;
349
350 case PRU_SEND:
351 if (nam) {
352 if (isop->isop_faddr) {
353 error = EISCONN;
354 break;
355 }
356 /*
357 * Must block input while temporarily connected.
358 */
359 s = splnet();
360 error = iso_pcbconnect(isop, nam);
361 if (error) {
362 splx(s);
363 break;
364 }
365 } else {
366 if (isop->isop_faddr == 0) {
367 error = ENOTCONN;
368 break;
369 }
370 }
371 error = cltp_output(isop, m);
372 m = 0;
373 if (nam) {
374 iso_pcbdisconnect(isop);
375 splx(s);
376 }
377 break;
378
379 case PRU_ABORT:
380 soisdisconnected(so);
381 iso_pcbdetach(isop);
382 break;
383
384 case PRU_SOCKADDR:
385 iso_getnetaddr(isop, nam, TP_LOCAL);
386 break;
387
388 case PRU_PEERADDR:
389 iso_getnetaddr(isop, nam, TP_FOREIGN);
390 break;
391
392 case PRU_SENSE:
393 /*
394 * stat: don't bother with a blocksize.
395 */
396 return (0);
397
398 case PRU_SENDOOB:
399 case PRU_FASTTIMO:
400 case PRU_SLOWTIMO:
401 case PRU_PROTORCV:
402 case PRU_PROTOSEND:
403 error = EOPNOTSUPP;
404 break;
405
406 case PRU_RCVD:
407 case PRU_RCVOOB:
408 return (EOPNOTSUPP); /* do not free mbuf's */
409
410 default:
411 panic("cltp_usrreq");
412 }
413release:
414 if (control != NULL)
415 m_freem(control);
416 if (m != NULL)
417 m_freem(m);
418 return (error);
419}