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