|
|
1.1 root 1: /*
2: * Copyright (c) University of British Columbia, 1984
3: * Copyright (c) 1991 The Regents of the University of California.
4: * All rights reserved.
5: *
6: * This code is derived from software contributed to Berkeley by
7: * the Laboratory for Computation Vision and the Computer Science Department
8: * of the University of British Columbia.
9: *
10: * Redistribution and use in source and binary forms, with or without
11: * modification, are permitted provided that the following conditions
12: * are met:
13: * 1. Redistributions of source code must retain the above copyright
14: * notice, this list of conditions and the following disclaimer.
15: * 2. Redistributions in binary form must reproduce the above copyright
16: * notice, this list of conditions and the following disclaimer in the
17: * documentation and/or other materials provided with the distribution.
18: * 3. All advertising materials mentioning features or use of this software
19: * must display the following acknowledgement:
20: * This product includes software developed by the University of
21: * California, Berkeley and its contributors.
22: * 4. Neither the name of the University nor the names of its contributors
23: * may be used to endorse or promote products derived from this software
24: * without specific prior written permission.
25: *
26: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36: * SUCH DAMAGE.
37: *
1.1.1.3 ! root 38: * from: @(#)pk_input.c 7.14 (Berkeley) 7/16/91
! 39: * pk_input.c,v 1.3 1993/05/20 04:12:19 cgd Exp
1.1 root 40: */
41:
42: #include "param.h"
43: #include "systm.h"
44: #include "mbuf.h"
45: #include "socket.h"
46: #include "protosw.h"
47: #include "socketvar.h"
48: #include "errno.h"
49:
50: #include "../net/if.h"
51:
52: #include "x25.h"
53: #include "pk.h"
54: #include "pk_var.h"
55:
56: struct pkcb *
57: pk_newlink (ia, llnext)
58: struct x25_ifaddr *ia;
59: caddr_t llnext;
60: {
61: register struct x25config *xcp = &ia->ia_xc;
62: register struct pkcb *pkp;
63: register struct pklcd *lcp;
64: register struct protosw *pp;
65: unsigned size;
66:
67: pp = pffindproto (AF_CCITT, (int)xcp -> xc_lproto, 0);
68: if (pp == 0 || pp -> pr_output == 0) {
69: pk_message (0, xcp, "link level protosw error");
70: return ((struct pkcb *)0);
71: }
72: /*
73: * Allocate a network control block structure
74: */
75: size = sizeof (struct pkcb);
76: pkp = (struct pkcb *)malloc(size, M_PCB, M_WAITOK);
77: if (pkp == 0)
78: return ((struct pkcb *)0);
79: bzero ((caddr_t)pkp, size);
80: pkp -> pk_lloutput = pp -> pr_output;
81: pkp -> pk_xcp = xcp;
82: pkp -> pk_ia = ia;
83: pkp -> pk_state = DTE_WAITING;
84: pkp -> pk_next = pkcbhead;
85: pkp -> pk_llnext = llnext;
86: pkcbhead = pkp;
87:
88: /*
89: * set defaults
90: */
91:
92: if (xcp -> xc_pwsize == 0)
93: xcp -> xc_pwsize = DEFAULT_WINDOW_SIZE;
94: if (xcp -> xc_psize == 0)
95: xcp -> xc_psize = X25_PS128;
96: /*
97: * Allocate logical channel descriptor vector
98: */
99:
100: (void)pk_resize(pkp);
101: return (pkp);
102: }
103:
104: pk_resize (pkp)
105: register struct pkcb *pkp;
106: {
107: struct pklcd *dev_lcp = 0;
108: struct x25config *xcp = pkp -> pk_xcp;
109: if (pkp -> pk_chan &&
110: (pkp -> pk_maxlcn != xcp -> xc_maxlcn)) {
111: pk_restart (pkp, X25_RESTART_NETWORK_CONGESTION);
112: dev_lcp = pkp -> pk_chan[0];
113: free ((caddr_t)pkp -> pk_chan, M_IFADDR);
114: pkp -> pk_chan = 0;
115: }
116: if (pkp -> pk_chan == 0) {
117: unsigned size;
118: pkp -> pk_maxlcn = xcp -> xc_maxlcn;
119: size = (pkp -> pk_maxlcn + 1) * sizeof (struct pklcd *);
120: pkp -> pk_chan =
121: (struct pklcd **) malloc (size, M_IFADDR, M_WAITOK);
122: if (pkp -> pk_chan) {
123: bzero ((caddr_t)pkp -> pk_chan, size);
124: /*
125: * Allocate a logical channel descriptor for lcn 0
126: */
127: if (dev_lcp == 0 &&
128: (dev_lcp = pk_attach ((struct socket *)0)) == 0)
129: return (ENOBUFS);
130: dev_lcp -> lcd_state = READY;
131: dev_lcp -> lcd_pkp = pkp;
132: pkp -> pk_chan[0] = dev_lcp;
133: } else {
134: if (dev_lcp)
135: pk_close (dev_lcp);
136: return (ENOBUFS);
137: }
138: }
139: return 0;
140: }
141:
142: /*
143: * This procedure is called by the link level whenever the link
144: * becomes operational, is reset, or when the link goes down.
145: */
146:
147: pk_ctlinput (code, pkp)
148: register struct pkcb *pkp;
149: {
150:
151:
152: switch (code) {
153: case PRC_LINKUP:
154: if (pkp -> pk_state == DTE_WAITING)
155: pk_restart (pkp, X25_RESTART_NETWORK_CONGESTION);
156: break;
157:
158: case PRC_LINKDOWN:
159: pk_restart (pkp, -1); /* Clear all active circuits */
160: pkp -> pk_state = DTE_WAITING;
161: break;
162:
163: case PRC_LINKRESET:
164: pk_restart (pkp, X25_RESTART_NETWORK_CONGESTION);
165: break;
166:
167: }
168: return (0);
169: }
170: struct ifqueue pkintrq;
171: /*
172: * This routine is called if there are semi-smart devices that do HDLC
173: * in hardware and want to queue the packet and call level 3 directly
174: */
175: pkintr ()
176: {
177: register struct mbuf *m;
178: register struct ifaddr *ifa;
179: register struct ifnet *ifp;
180: register int s;
181:
182: for (;;) {
183: s = splimp ();
184: IF_DEQUEUE (&pkintrq, m);
185: splx (s);
186: if (m == 0)
187: break;
188: if (m->m_len < PKHEADERLN) {
189: printf ("pkintr: packet too short (len=%d)\n",
190: m->m_len);
191: m_freem (m);
192: continue;
193: }
194: pk_input(m);
195: }
196: }
197: struct mbuf *pk_bad_packet;
198: struct mbuf_cache pk_input_cache = {0 };
199: /*
200: * X.25 PACKET INPUT
201: *
202: * This procedure is called by a link level procedure whenever
203: * an information frame is received. It decodes the packet and
204: * demultiplexes based on the logical channel number.
205: *
206: * We change the original conventions of the UBC code here --
207: * since there may be multiple pkcb's for 802.2 class 2
208: * for a given interface, we must be informed which one it is;
209: * so we overwrite the pkthdr.rcvif; it can be recovered if necessary.
210: *
211: */
212:
213: pk_input (m)
214: register struct mbuf *m;
215: {
216: register struct x25_packet *xp;
217: register struct pklcd *lcp;
218: register struct socket *so = 0;
219: register struct pkcb *pkp;
220: int ptype, lcn, lcdstate = LISTEN;
221:
222: if (pk_input_cache.mbc_size || pk_input_cache.mbc_oldsize)
223: mbuf_cache(&pk_input_cache, m);
224: if ((m->m_flags & M_PKTHDR) == 0)
225: panic("pkintr");
226: if ((pkp = (struct pkcb *)m->m_pkthdr.rcvif) == 0)
227: return;
228: xp = mtod (m, struct x25_packet *);
229: ptype = pk_decode (xp);
230: lcn = LCN(xp);
231: lcp = pkp -> pk_chan[lcn];
232:
233: /*
234: * If the DTE is in Restart state, then it will ignore data,
235: * interrupt, call setup and clearing, flow control and reset
236: * packets.
237: */
238: if (lcn < 0 || lcn > pkp -> pk_maxlcn) {
239: pk_message (lcn, pkp -> pk_xcp, "illegal lcn");
240: m_freem (m);
241: return;
242: }
243:
244: pk_trace (pkp -> pk_xcp, m, "P-In");
245:
246: if (pkp -> pk_state != DTE_READY && ptype != RESTART && ptype != RESTART_CONF) {
247: m_freem (m);
248: return;
249: }
250: if (lcp) {
251: so = lcp -> lcd_so;
252: lcdstate = lcp -> lcd_state;
253: } else {
254: if (ptype == CLEAR) { /* idle line probe (Datapac specific) */
255: /* send response on lcd 0's output queue */
256: lcp = pkp -> pk_chan[0];
257: lcp -> lcd_template = pk_template (lcn, X25_CLEAR_CONFIRM);
258: pk_output (lcp);
259: m_freem (m);
260: return;
261: }
262: if (ptype != CALL)
263: ptype = INVALID_PACKET;
264: }
265:
266: if (lcn == 0 && ptype != RESTART && ptype != RESTART_CONF) {
267: pk_message (0, pkp -> pk_xcp, "illegal ptype (%d, %s) on lcn 0",
268: ptype, pk_name[ptype / MAXSTATES]);
269: if (pk_bad_packet)
270: m_freem (pk_bad_packet);
271: pk_bad_packet = m;
272: return;
273: }
274:
275: switch (ptype + lcdstate) {
276: /*
277: * Incoming Call packet received.
278: */
279: case CALL + LISTEN:
280: pk_incoming_call (pkp, m);
281: break;
282:
283: /*
284: * Call collision: Just throw this "incoming call" away since
285: * the DCE will ignore it anyway.
286: */
287: case CALL + SENT_CALL:
288: pk_message ((int)lcn, pkp -> pk_xcp,
289: "incoming call collision");
290: break;
291:
292: /*
293: * Call confirmation packet received. This usually means our
294: * previous connect request is now complete.
295: */
296: case CALL_ACCEPTED + SENT_CALL:
297: MCHTYPE(m, MT_CONTROL);
298: pk_call_accepted (lcp, m);
299: break;
300:
301: /*
302: * This condition can only happen if the previous state was
303: * SENT_CALL. Just ignore the packet, eventually a clear
304: * confirmation should arrive.
305: */
306: case CALL_ACCEPTED + SENT_CLEAR:
307: break;
308:
309: /*
310: * Clear packet received. This requires a complete tear down
311: * of the virtual circuit. Free buffers and control blocks.
312: * and send a clear confirmation.
313: */
314: case CLEAR + READY:
315: case CLEAR + RECEIVED_CALL:
316: case CLEAR + SENT_CALL:
317: case CLEAR + DATA_TRANSFER:
318: lcp -> lcd_state = RECEIVED_CLEAR;
319: lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_CLEAR_CONFIRM);
320: pk_output (lcp);
321: pk_clearcause (pkp, xp);
322: if (lcp -> lcd_upper) {
323: MCHTYPE(m, MT_CONTROL);
324: lcp -> lcd_upper (lcp, m);
325: }
326: pk_close (lcp);
327: lcp = 0;
328: break;
329:
330: /*
331: * Clear collision: Treat this clear packet as a confirmation.
332: */
333: case CLEAR + SENT_CLEAR:
334: pk_close (lcp);
335: break;
336:
337: /*
338: * Clear confirmation received. This usually means the virtual
339: * circuit is now completely removed.
340: */
341: case CLEAR_CONF + SENT_CLEAR:
342: pk_close (lcp);
343: break;
344:
345: /*
346: * A clear confirmation on an unassigned logical channel - just
347: * ignore it. Note: All other packets on an unassigned channel
348: * results in a clear.
349: */
350: case CLEAR_CONF + READY:
351: case CLEAR_CONF + LISTEN:
352: break;
353:
354: /*
355: * Data packet received. Pass on to next level. Move the Q and M
356: * bits into the data portion for the next level.
357: */
358: case DATA + DATA_TRANSFER:
359: if (lcp -> lcd_reset_condition) {
360: ptype = DELETE_PACKET;
361: break;
362: }
363:
364: /*
365: * Process the P(S) flow control information in this Data packet.
366: * Check that the packets arrive in the correct sequence and that
367: * they are within the "lcd_input_window". Input window rotation is
368: * initiated by the receive interface.
369: */
370:
371: if (PS(xp) != ((lcp -> lcd_rsn + 1) % MODULUS) ||
372: PS(xp) == ((lcp -> lcd_input_window + lcp->lcd_windowsize) % MODULUS)) {
373: m_freem (m);
374: pk_procerror (RESET, lcp, "p(s) flow control error", 1);
375: break;
376: }
377: lcp -> lcd_rsn = PS(xp);
378:
379: if (pk_ack (lcp, PR(xp)) != PACKET_OK) {
380: m_freem (m);
381: break;
382: }
383: m -> m_data += PKHEADERLN;
384: m -> m_len -= PKHEADERLN;
385: m -> m_pkthdr.len -= PKHEADERLN;
386:
387: lcp -> lcd_rxcnt++;
388: if (lcp -> lcd_flags & X25_MBS_HOLD) {
389: register struct mbuf *n = lcp -> lcd_cps;
390: int mbit = MBIT(xp);
391: octet q_and_d_bits;
392:
393: if (n) {
394: n -> m_pkthdr.len += m -> m_pkthdr.len;
395: while (n -> m_next)
396: n = n -> m_next;
397: n -> m_next = m;
398: m = lcp -> lcd_cps;
399:
400: if (lcp -> lcd_cpsmax &&
401: n -> m_pkthdr.len > lcp -> lcd_cpsmax) {
402: pk_procerror (RESET, lcp,
403: "C.P.S. overflow", 128);
404: return;
405: }
406: q_and_d_bits = 0xc0 & *(octet *)xp;
407: xp = (struct x25_packet *)
408: (mtod(m, octet *) - PKHEADERLN);
409: *(octet *)xp |= q_and_d_bits;
410: }
411: if (mbit) {
412: lcp -> lcd_cps = m;
413: pk_flowcontrol(lcp, 0, 1);
414: return;
415: }
416: lcp -> lcd_cps = 0;
417: }
418: if (so == 0)
419: break;
420: if (lcp -> lcd_flags & X25_MQBIT) {
421: octet t = (xp -> q_bit) ? t = 0x80 : 0;
422:
423: if (MBIT(xp))
424: t |= 0x40;
425: m -> m_data -= 1;
426: m -> m_len += 1;
427: m -> m_pkthdr.len += 1;
428: *mtod(m, octet *) = t;
429: }
430:
431: /*
432: * Discard Q-BIT packets if the application
433: * doesn't want to be informed of M and Q bit status
434: */
435: if (xp -> q_bit && (lcp -> lcd_flags & X25_MQBIT) == 0) {
436: m_freem (m);
437: /*
438: * NB. This is dangerous: sending a RR here can
439: * cause sequence number errors if a previous data
440: * packet has not yet been passed up to the application
441: * (RR's are normally generated via PRU_RCVD).
442: */
443: pk_flowcontrol(lcp, 0, 1);
444: } else {
445: sbappendrecord (&so -> so_rcv, m);
446: sorwakeup (so);
447: }
448: break;
449:
450: /*
451: * Interrupt packet received.
452: */
453: case INTERRUPT + DATA_TRANSFER:
454: if (lcp -> lcd_reset_condition)
455: break;
456: lcp -> lcd_intrdata = xp -> packet_data;
457: lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_INTERRUPT_CONFIRM);
458: pk_output (lcp);
459: m -> m_data += PKHEADERLN;
460: m -> m_len -= PKHEADERLN;
461: m -> m_pkthdr.len -= PKHEADERLN;
462: MCHTYPE(m, MT_OOBDATA);
463: if (so) {
464: if (so -> so_options & SO_OOBINLINE)
465: sbinsertoob (&so -> so_rcv, m);
466: else
467: m_freem (m);
468: sohasoutofband (so);
469: }
470: break;
471:
472: /*
473: * Interrupt confirmation packet received.
474: */
475: case INTERRUPT_CONF + DATA_TRANSFER:
476: if (lcp -> lcd_reset_condition)
477: break;
478: if (lcp -> lcd_intrconf_pending == TRUE)
479: lcp -> lcd_intrconf_pending = FALSE;
480: else
481: pk_procerror (RESET, lcp, "unexpected packet", 43);
482: break;
483:
484: /*
485: * Receiver ready received. Rotate the output window and output
486: * any data packets waiting transmission.
487: */
488: case RR + DATA_TRANSFER:
489: if (lcp -> lcd_reset_condition ||
490: pk_ack (lcp, PR(xp)) != PACKET_OK) {
491: ptype = DELETE_PACKET;
492: break;
493: }
494: if (lcp -> lcd_rnr_condition == TRUE)
495: lcp -> lcd_rnr_condition = FALSE;
496: pk_output (lcp);
497: break;
498:
499: /*
500: * Receiver Not Ready received. Packets up to the P(R) can be
501: * be sent. Condition is cleared with a RR.
502: */
503: case RNR + DATA_TRANSFER:
504: if (lcp -> lcd_reset_condition ||
505: pk_ack (lcp, PR(xp)) != PACKET_OK) {
506: ptype = DELETE_PACKET;
507: break;
508: }
509: lcp -> lcd_rnr_condition = TRUE;
510: break;
511:
512: /*
513: * Reset packet received. Set state to FLOW_OPEN. The Input and
514: * Output window edges ar set to zero. Both the send and receive
515: * numbers are reset. A confirmation is returned.
516: */
517: case RESET + DATA_TRANSFER:
518: if (lcp -> lcd_reset_condition)
519: /* Reset collision. Just ignore packet. */
520: break;
521:
522: pk_resetcause (pkp, xp);
523: lcp -> lcd_window_condition = lcp -> lcd_rnr_condition =
524: lcp -> lcd_intrconf_pending = FALSE;
525: lcp -> lcd_output_window = lcp -> lcd_input_window =
526: lcp -> lcd_last_transmitted_pr = 0;
527: lcp -> lcd_ssn = 0;
528: lcp -> lcd_rsn = MODULUS - 1;
529:
530: lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_RESET_CONFIRM);
531: pk_output (lcp);
532:
533: pk_flush(lcp);
534: if (so == 0)
535: break;
536: wakeup ((caddr_t) & so -> so_timeo);
537: sorwakeup (so);
538: sowwakeup (so);
539: break;
540:
541: /*
542: * Reset confirmation received.
543: */
544: case RESET_CONF + DATA_TRANSFER:
545: if (lcp -> lcd_reset_condition) {
546: lcp -> lcd_reset_condition = FALSE;
547: pk_output (lcp);
548: }
549: else
550: pk_procerror (RESET, lcp, "unexpected packet", 32);
551: break;
552:
553: case DATA + SENT_CLEAR:
554: ptype = DELETE_PACKET;
555: case RR + SENT_CLEAR:
556: case RNR + SENT_CLEAR:
557: case INTERRUPT + SENT_CLEAR:
558: case INTERRUPT_CONF + SENT_CLEAR:
559: case RESET + SENT_CLEAR:
560: case RESET_CONF + SENT_CLEAR:
561: /* Just ignore p if we have sent a CLEAR already.
562: */
563: break;
564:
565: /*
566: * Restart sets all the permanent virtual circuits to the "Data
567: * Transfer" stae and all the switched virtual circuits to the
568: * "Ready" state.
569: */
570: case RESTART + READY:
571: switch (pkp -> pk_state) {
572: case DTE_SENT_RESTART:
573: /* Restart collision. */
574: pkp -> pk_state = DTE_READY;
575: pk_message (0, pkp -> pk_xcp,
576: "Packet level operational");
577: break;
578:
579: default:
580: pk_restart (pkp, -1);
581: pk_restartcause (pkp, xp);
582: pkp -> pk_chan[0] -> lcd_template = pk_template (0,
583: X25_RESTART_CONFIRM);
584: pk_output (pkp -> pk_chan[0]);
585: }
586: break;
587:
588: /*
589: * Restart confirmation received. All logical channels are set
590: * to READY.
591: */
592: case RESTART_CONF + READY:
593: switch (pkp -> pk_state) {
594: case DTE_SENT_RESTART:
595: pkp -> pk_state = DTE_READY;
596: pk_message (0, pkp -> pk_xcp,
597: "Packet level operational");
598: break;
599:
600: default:
601: /* Restart local procedure error. */
602: pk_restart (pkp, X25_RESTART_LOCAL_PROCEDURE_ERROR);
603: pkp -> pk_state = DTE_SENT_RESTART;
604: }
605: break;
606:
607: default:
608: if (lcp) {
609: pk_procerror (CLEAR, lcp, "unknown packet error", 33);
610: pk_message (lcn, pkp -> pk_xcp,
611: "\"%s\" unexpected in \"%s\" state",
612: pk_name[ptype/MAXSTATES], pk_state[lcdstate]);
613: } else
614: pk_message (lcn, pkp -> pk_xcp,
615: "packet arrived on unassigned lcn");
616: break;
617: }
618: if (so == 0 && lcp && lcp -> lcd_upper && lcdstate == DATA_TRANSFER) {
619: if (ptype != DATA && ptype != INTERRUPT)
620: MCHTYPE(m, MT_CONTROL);
621: lcp -> lcd_upper (lcp, m);
622: } else if (ptype != DATA && ptype != INTERRUPT)
623: m_freem (m);
624: }
625:
626: static
627: prune_dnic(from, to, dnicname, xcp)
628: char *from, *to, *dnicname;
629: register struct x25config *xcp;
630: {
631: register char *cp1 = from, *cp2 = from;
632: if (xcp->xc_prepnd0 && *cp1 == '0') {
633: from = ++cp1;
634: goto copyrest;
635: }
636: if (xcp->xc_nodnic) {
637: for (cp1 = dnicname; *cp2 = *cp1++;)
638: cp2++;
639: cp1 = from;
640: }
641: copyrest:
642: for (cp1 = dnicname; *cp2 = *cp1++;)
643: cp2++;
644: }
645: /* static */
646: pk_simple_bsd (from, to, lower, len)
647: register octet *from, *to;
648: register len, lower;
649: {
650: register int c;
651: while (--len >= 0) {
652: c = *from;
653: if (lower & 0x01)
654: *from++;
655: else
656: c >>= 4;
657: c &= 0x0f; c |= 0x30; *to++ = c; lower++;
658: }
659: *to = 0;
660: }
661:
662: /*static octet * */
663: pk_from_bcd (a, iscalling, sa, xcp)
664: register struct x25_calladdr *a;
665: register struct sockaddr_x25 *sa;
666: register struct x25config *xcp;
667: {
668: octet buf[MAXADDRLN+1];
669: octet *cp;
670: unsigned count;
671:
672: bzero ((caddr_t)sa, sizeof (*sa));
673: sa -> x25_len = sizeof (*sa);
674: sa -> x25_family = AF_CCITT;
675: if (iscalling) {
676: cp = a -> address_field + (a -> called_addrlen / 2);
677: count = a -> calling_addrlen;
678: pk_simple_bsd (cp, buf, a -> called_addrlen, count);
679: } else {
680: count = a -> called_addrlen;
681: pk_simple_bsd (a -> address_field, buf, 0, count);
682: }
683: if (xcp -> xc_addr.x25_net && (xcp -> xc_nodnic || xcp ->xc_prepnd0)) {
684: octet dnicname[sizeof(long) * NBBY/3 + 2];
685:
1.1.1.2 root 686: sprintf ((char *) dnicname, "%d", xcp -> xc_addr.x25_net);
1.1 root 687: prune_dnic (buf, sa -> x25_addr, dnicname, xcp);
688: } else
689: bcopy ((caddr_t)buf, (caddr_t)sa -> x25_addr, count + 1);
690: }
691:
692: static
693: save_extra(m0, fp, so)
694: struct mbuf *m0;
695: octet *fp;
696: struct socket *so;
697: {
698: register struct mbuf *m;
699: struct cmsghdr cmsghdr;
700: if (m = m_copym (m, 0, (int)M_COPYALL)) {
701: int off = fp - mtod (m0, octet *);
702: int len = m->m_pkthdr.len - off + sizeof (cmsghdr);
703: cmsghdr.cmsg_len = len;
704: cmsghdr.cmsg_level = AF_CCITT;
705: cmsghdr.cmsg_type = PK_FACILITIES;
706: m_adj (m, off);
707: M_PREPEND (m, sizeof(cmsghdr), M_DONTWAIT);
708: if (m == 0)
709: return;
710: bcopy ((caddr_t)&cmsghdr, mtod (m, caddr_t), sizeof (cmsghdr));
711: MCHTYPE(m, MT_CONTROL);
712: sbappendrecord(&so -> so_rcv, m);
713: }
714: }
715:
716: /*
717: * This routine handles incoming call packets. It matches the protocol
718: * field on the Call User Data field (usually the first four bytes) with
719: * sockets awaiting connections.
720: */
721:
722: pk_incoming_call (pkp, m0)
723: struct mbuf *m0;
724: struct pkcb *pkp;
725: {
726: register struct pklcd *lcp = 0, *l;
727: register struct sockaddr_x25 *sa;
728: register struct x25_calladdr *a;
729: register struct socket *so = 0;
730: struct x25_packet *xp = mtod(m0, struct x25_packet *);
731: struct mbuf *m;
732: struct x25config *xcp = pkp -> pk_xcp;
733: int len = m0->m_pkthdr.len;
734: unsigned udlen;
735: char *errstr = "server unavailable";
736: octet *u, *facp;
737: int lcn = LCN(xp);
738:
739: /* First, copy the data from the incoming call packet to a X25 address
740: descriptor. It is to be regretted that you have
741: to parse the facilities into a sockaddr to determine
742: if reverse charging is being requested */
743: if ((m = m_get (M_DONTWAIT, MT_SONAME)) == 0)
744: return;
745: sa = mtod (m, struct sockaddr_x25 *);
746: a = (struct x25_calladdr *) &xp -> packet_data;
747: facp = u = (octet *) (a -> address_field +
748: ((a -> called_addrlen + a -> calling_addrlen + 1) / 2));
749: u += *u + 1;
750: udlen = min (16, ((octet *)xp) + len - u);
751: if (udlen < 0)
752: udlen = 0;
753: pk_from_bcd (a, 1, sa, pkp -> pk_xcp); /* get calling address */
1.1.1.2 root 754: pk_parse_facilities (facp, sa);
1.1 root 755: bcopy ((caddr_t)u, sa -> x25_udata, udlen);
756: sa -> x25_udlen = udlen;
757:
758: /*
1.1.1.2 root 759: * Now, loop through the listen sockets looking for a match on the
760: * PID. That is the first few octets of the user data field.
761: * This is the closest thing to a port number for X.25 packets.
762: * It does provide a way of multiplexing services at the user level.
1.1 root 763: */
764:
765: for (l = pk_listenhead; l; l = l -> lcd_listen) {
766: struct sockaddr_x25 *sxp = l -> lcd_ceaddr;
767:
768: if (bcmp (sxp -> x25_udata, u, sxp->x25_udlen))
769: continue;
770: if (sxp -> x25_net &&
771: sxp -> x25_net != xcp -> xc_addr.x25_net)
772: continue;
773: /*
774: * don't accept incoming calls with the D-Bit on
775: * unless the server agrees
776: */
777: if (xp -> d_bit && !(sxp -> x25_opts.op_flags & X25_DBIT)) {
778: errstr = "incoming D-Bit mismatch";
779: break;
780: }
781: /*
782: * don't accept incoming collect calls unless
783: * the server sets the reverse charging option.
784: */
785: if ((sxp -> x25_opts.op_flags & (X25_OLDSOCKADDR|X25_REVERSE_CHARGE)) == 0 &&
786: sa -> x25_opts.op_flags & X25_REVERSE_CHARGE) {
787: errstr = "incoming collect call refused";
788: break;
789: }
790: if (l -> lcd_so) {
791: if (so = sonewconn (l -> lcd_so, SS_ISCONNECTED))
792: lcp = (struct pklcd *) so -> so_pcb;
793: } else
794: lcp = pk_attach((struct socket *) 0);
795: if (lcp == 0) {
796: /*
797: * Insufficient space or too many unaccepted
798: * connections. Just throw the call away.
799: */
800: errstr = "server malfunction";
801: break;
802: }
803: lcp -> lcd_upper = l -> lcd_upper;
804: lcp -> lcd_upnext = l -> lcd_upnext;
805: lcp -> lcd_lcn = lcn;
806: lcp -> lcd_state = RECEIVED_CALL;
807: sa -> x25_opts.op_flags |= (sxp -> x25_opts.op_flags &
808: ~X25_REVERSE_CHARGE) | l -> lcd_flags;
809: pk_assoc (pkp, lcp, sa);
810: lcp -> lcd_faddr = *sa;
811: lcp -> lcd_laddr.x25_udlen = sxp -> x25_udlen;
812: lcp -> lcd_craddr = &lcp->lcd_faddr;
813: lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_CALL_ACCEPTED);
814: if (lcp -> lcd_flags & X25_DBIT) {
815: if (xp -> d_bit)
816: mtod(lcp -> lcd_template,
817: struct x25_packet *) -> d_bit = 1;
818: else
819: lcp -> lcd_flags &= ~X25_DBIT;
820: }
821: if (so) {
822: pk_output (lcp);
823: soisconnected (so);
824: if (so -> so_options & SO_OOBINLINE)
825: save_extra(m0, facp, so);
826: } else if (lcp -> lcd_upper) {
827: (*lcp -> lcd_upper) (lcp, m0);
828: }
829: (void) m_free (m);
830: return;
831: }
832:
833: /*
834: * If the call fails for whatever reason, we still need to build a
835: * skeleton LCD in order to be able to properly receive the CLEAR
836: * CONFIRMATION.
837: */
838: #ifdef WATERLOO /* be explicit */
839: if (l == 0 && bcmp(sa->x25_udata, "ean", 3) == 0)
840: pk_message (lcn, pkp -> pk_xcp, "host=%s ean%c: %s",
841: sa->x25_addr, sa->x25_udata[3] & 0xff, errstr);
842: else if (l == 0 && bcmp(sa->x25_udata, "\1\0\0\0", 4) == 0)
843: pk_message (lcn, pkp -> pk_xcp, "host=%s x29d: %s",
844: sa->x25_addr, errstr);
845: else
846: #endif
847: pk_message (lcn, pkp -> pk_xcp, "host=%s pid=%x %x %x %x: %s",
848: sa -> x25_addr, sa -> x25_udata[0] & 0xff,
849: sa -> x25_udata[1] & 0xff, sa -> x25_udata[2] & 0xff,
850: sa -> x25_udata[3] & 0xff, errstr);
851: if ((lcp = pk_attach((struct socket *)0)) == 0) {
852: (void) m_free (m);
853: return;
854: }
855: lcp -> lcd_lcn = lcn;
856: lcp -> lcd_state = RECEIVED_CALL;
857: pk_assoc (pkp, lcp, sa);
858: (void) m_free (m);
859: pk_clear (lcp, 0, 1);
860: }
861:
862: pk_call_accepted (lcp, m)
863: struct pklcd *lcp;
864: struct mbuf *m;
865: {
866: register struct x25_calladdr *ap;
867: register octet *fcp;
868: struct x25_packet *xp = mtod (m, struct x25_packet *);
869: int len = m -> m_len;
870:
871: lcp -> lcd_state = DATA_TRANSFER;
872: if (lcp -> lcd_so)
873: soisconnected (lcp -> lcd_so);
874: if ((lcp -> lcd_flags & X25_DBIT) && (xp -> d_bit == 0))
875: lcp -> lcd_flags &= ~X25_DBIT;
876: if (len > 3) {
877: ap = (struct x25_calladdr *) &xp -> packet_data;
878: fcp = (octet *) ap -> address_field + (ap -> calling_addrlen +
879: ap -> called_addrlen + 1) / 2;
880: if (fcp + *fcp <= ((octet *)xp) + len)
881: pk_parse_facilities (fcp, lcp -> lcd_ceaddr);
882: }
883: pk_assoc (lcp -> lcd_pkp, lcp, lcp -> lcd_ceaddr);
884: if (lcp -> lcd_so == 0 && lcp -> lcd_upper)
885: lcp -> lcd_upper(lcp, m);
886: }
887:
888: pk_parse_facilities (fcp, sa)
889: register octet *fcp;
890: register struct sockaddr_x25 *sa;
891: {
892: register octet *maxfcp;
893:
894: maxfcp = fcp + *fcp;
895: fcp++;
896: while (fcp < maxfcp) {
897: /*
898: * Ignore national DCE or DTE facilities
899: */
900: if (*fcp == 0 || *fcp == 0xff)
901: break;
902: switch (*fcp) {
903: case FACILITIES_WINDOWSIZE:
904: sa -> x25_opts.op_wsize = fcp[1];
905: fcp += 3;
906: break;
907:
908: case FACILITIES_PACKETSIZE:
909: sa -> x25_opts.op_psize = fcp[1];
910: fcp += 3;
911: break;
912:
913: case FACILITIES_THROUGHPUT:
914: sa -> x25_opts.op_speed = fcp[1];
915: fcp += 2;
916: break;
917:
918: case FACILITIES_REVERSE_CHARGE:
919: if (fcp[1] & 01)
920: sa -> x25_opts.op_flags |= X25_REVERSE_CHARGE;
921: /*
922: * Datapac specific: for a X.25(1976) DTE, bit 2
923: * indicates a "hi priority" (eg. international) call.
924: */
925: if (fcp[1] & 02 && sa -> x25_opts.op_psize == 0)
926: sa -> x25_opts.op_psize = X25_PS128;
927: fcp += 2;
928: break;
929:
930: default:
931: /*printf("unknown facility %x, class=%d\n", *fcp, (*fcp & 0xc0) >> 6);*/
932: switch ((*fcp & 0xc0) >> 6) {
933: case 0: /* class A */
934: fcp += 2;
935: break;
936:
937: case 1:
938: fcp += 3;
939: break;
940:
941: case 2:
942: fcp += 4;
943: break;
944:
945: case 3:
946: fcp++;
947: fcp += *fcp;
948: }
949: }
950: }
951: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.