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