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