141709Ssklower /*
241709Ssklower * Copyright (c) University of British Columbia, 1984
357024Ssklower * Copyright (C) Computer Science Department IV,
457024Ssklower * University of Erlangen-Nuremberg, Germany, 1992
5*63216Sbostic * Copyright (c) 1991, 1992, 1993
6*63216Sbostic * The Regents of the University of California. All rights reserved.
741709Ssklower *
857024Ssklower * This code is derived from software contributed to Berkeley by the
957024Ssklower * Laboratory for Computation Vision and the Computer Science Department
1057024Ssklower * of the the University of British Columbia and the Computer Science
1157024Ssklower * Department (IV) of the University of Erlangen-Nuremberg, Germany.
1241709Ssklower *
1341709Ssklower * %sccs.include.redist.c%
1441709Ssklower *
15*63216Sbostic * @(#)pk_input.c 8.1 (Berkeley) 06/10/93
1641709Ssklower */
1741591Ssklower
1856530Sbostic #include <sys/param.h>
1956530Sbostic #include <sys/systm.h>
2056530Sbostic #include <sys/mbuf.h>
2156530Sbostic #include <sys/socket.h>
2256530Sbostic #include <sys/protosw.h>
2356530Sbostic #include <sys/socketvar.h>
2456530Sbostic #include <sys/errno.h>
2541591Ssklower
2656530Sbostic #include <net/if.h>
2757032Ssklower #include <net/if_dl.h>
2857032Ssklower #include <net/if_llc.h>
2957032Ssklower #include <net/route.h>
3041591Ssklower
3157024Ssklower #include <netccitt/dll.h>
3256530Sbostic #include <netccitt/x25.h>
3356530Sbostic #include <netccitt/pk.h>
3456530Sbostic #include <netccitt/pk_var.h>
3557024Ssklower #include <netccitt/llc_var.h>
3641591Ssklower
3757024Ssklower struct pkcb_q pkcb_q = {&pkcb_q, &pkcb_q};
3857024Ssklower
3957024Ssklower /*
4057024Ssklower * ccittintr() is the generic interrupt handler for HDLC, LLC2, and X.25. This
4157024Ssklower * allows to have kernel running X.25 but no HDLC or LLC2 or both (in case we
4257024Ssklower * employ boards that do all the stuff themselves, e.g. ADAX X.25 or TPS ISDN.)
4357024Ssklower */
4457024Ssklower void
ccittintr()4557957Ssklower ccittintr ()
4657024Ssklower {
4757024Ssklower extern struct ifqueue pkintrq;
4857024Ssklower extern struct ifqueue hdintrq;
4957024Ssklower extern struct ifqueue llcintrq;
5057024Ssklower
5157024Ssklower #ifdef HDLC
5257024Ssklower if (hdintrq.ifq_len)
5357024Ssklower hdintr ();
5457024Ssklower #endif
5557024Ssklower #ifdef LLC
5657024Ssklower if (llcintrq.ifq_len)
5757024Ssklower llcintr ();
5857024Ssklower #endif
5957024Ssklower if (pkintrq.ifq_len)
6057024Ssklower pkintr ();
6157024Ssklower }
6257024Ssklower
6349930Ssklower struct pkcb *
pk_newlink(ia,llnext)6449930Ssklower pk_newlink (ia, llnext)
6549930Ssklower struct x25_ifaddr *ia;
6649930Ssklower caddr_t llnext;
6749930Ssklower {
6857957Ssklower register struct x25config *xcp = &ia -> ia_xc;
6949930Ssklower register struct pkcb *pkp;
7049930Ssklower register struct pklcd *lcp;
7149930Ssklower register struct protosw *pp;
7249930Ssklower unsigned size;
7349930Ssklower
7457957Ssklower pp = pffindproto (AF_CCITT, (int) xcp -> xc_lproto, 0);
7549930Ssklower if (pp == 0 || pp -> pr_output == 0) {
7649930Ssklower pk_message (0, xcp, "link level protosw error");
7749930Ssklower return ((struct pkcb *)0);
7849930Ssklower }
7949930Ssklower /*
8049930Ssklower * Allocate a network control block structure
8149930Ssklower */
8249930Ssklower size = sizeof (struct pkcb);
8357957Ssklower pkp = (struct pkcb *) malloc (size, M_PCB, M_WAITOK);
8449930Ssklower if (pkp == 0)
8549930Ssklower return ((struct pkcb *)0);
8657957Ssklower bzero ((caddr_t) pkp, size);
8749930Ssklower pkp -> pk_lloutput = pp -> pr_output;
8857957Ssklower pkp -> pk_llctlinput = (caddr_t (*)()) pp -> pr_ctlinput;
8949930Ssklower pkp -> pk_xcp = xcp;
9049930Ssklower pkp -> pk_ia = ia;
9149930Ssklower pkp -> pk_state = DTE_WAITING;
9249930Ssklower pkp -> pk_llnext = llnext;
9357957Ssklower insque (pkp, &pkcb_q);
9449930Ssklower
9549930Ssklower /*
9649930Ssklower * set defaults
9749930Ssklower */
9849930Ssklower
9949930Ssklower if (xcp -> xc_pwsize == 0)
10049930Ssklower xcp -> xc_pwsize = DEFAULT_WINDOW_SIZE;
10149930Ssklower if (xcp -> xc_psize == 0)
10249930Ssklower xcp -> xc_psize = X25_PS128;
10349930Ssklower /*
10449930Ssklower * Allocate logical channel descriptor vector
10549930Ssklower */
10649930Ssklower
10757957Ssklower (void) pk_resize (pkp);
10849930Ssklower return (pkp);
10949930Ssklower }
11049930Ssklower
11157024Ssklower
pk_dellink(pkp)11257024Ssklower pk_dellink (pkp)
11357024Ssklower register struct pkcb *pkp;
11457024Ssklower {
11557024Ssklower register int i;
11657024Ssklower register struct protosw *pp;
11757024Ssklower
11857024Ssklower /*
11957024Ssklower * Essentially we have the choice to
12057024Ssklower * (a) go ahead and let the route be deleted and
12157024Ssklower * leave the pkcb associated with that route
12257024Ssklower * as it is, i.e. the connections stay open
12357024Ssklower * (b) do a pk_disconnect() on all channels associated
12457024Ssklower * with the route via the pkcb and then proceed.
12557024Ssklower *
12657024Ssklower * For the time being we stick with (b)
12757024Ssklower */
12857024Ssklower
12957957Ssklower for (i = 1; i < pkp -> pk_maxlcn; ++i)
13057957Ssklower if (pkp -> pk_chan[i])
13157957Ssklower pk_disconnect (pkp -> pk_chan[i]);
13257024Ssklower
13357024Ssklower /*
13457024Ssklower * Free the pkcb
13557024Ssklower */
13657024Ssklower
13757024Ssklower /*
13857024Ssklower * First find the protoswitch to get hold of the link level
13957024Ssklower * protocol to be notified that the packet level entity is
14057024Ssklower * dissolving ...
14157024Ssklower */
14257957Ssklower pp = pffindproto (AF_CCITT, (int) pkp -> pk_xcp -> xc_lproto, 0);
14357024Ssklower if (pp == 0 || pp -> pr_output == 0) {
14457024Ssklower pk_message (0, pkp -> pk_xcp, "link level protosw error");
14557957Ssklower return (EPROTONOSUPPORT);
14657024Ssklower }
14757024Ssklower
14857024Ssklower pkp -> pk_refcount--;
14957024Ssklower if (!pkp -> pk_refcount) {
15057024Ssklower struct dll_ctlinfo ctlinfo;
15157024Ssklower
15257957Ssklower remque (pkp);
15357024Ssklower if (pkp -> pk_rt -> rt_llinfo == (caddr_t) pkp)
15457024Ssklower pkp -> pk_rt -> rt_llinfo = (caddr_t) NULL;
15557024Ssklower
15657024Ssklower /*
15757024Ssklower * Tell the link level that the pkcb is dissolving
15857024Ssklower */
15957024Ssklower if (pp -> pr_ctlinput && pkp -> pk_llnext) {
16057024Ssklower ctlinfo.dlcti_pcb = pkp -> pk_llnext;
16157024Ssklower ctlinfo.dlcti_rt = pkp -> pk_rt;
16257024Ssklower (pp -> pr_ctlinput)(PRC_DISCONNECT_REQUEST,
16357024Ssklower pkp -> pk_xcp, &ctlinfo);
16457024Ssklower }
16557957Ssklower free ((caddr_t) pkp -> pk_chan, M_IFADDR);
16657957Ssklower free ((caddr_t) pkp, M_PCB);
16757024Ssklower }
16857024Ssklower
16957024Ssklower return (0);
17057024Ssklower }
17157024Ssklower
17257024Ssklower
pk_resize(pkp)17349930Ssklower pk_resize (pkp)
17449930Ssklower register struct pkcb *pkp;
17549930Ssklower {
17649930Ssklower struct pklcd *dev_lcp = 0;
17749930Ssklower struct x25config *xcp = pkp -> pk_xcp;
17849930Ssklower if (pkp -> pk_chan &&
17949930Ssklower (pkp -> pk_maxlcn != xcp -> xc_maxlcn)) {
18049930Ssklower pk_restart (pkp, X25_RESTART_NETWORK_CONGESTION);
18149930Ssklower dev_lcp = pkp -> pk_chan[0];
18257957Ssklower free ((caddr_t) pkp -> pk_chan, M_IFADDR);
18349930Ssklower pkp -> pk_chan = 0;
18449930Ssklower }
18549930Ssklower if (pkp -> pk_chan == 0) {
18649930Ssklower unsigned size;
18749930Ssklower pkp -> pk_maxlcn = xcp -> xc_maxlcn;
18849930Ssklower size = (pkp -> pk_maxlcn + 1) * sizeof (struct pklcd *);
18949930Ssklower pkp -> pk_chan =
19049930Ssklower (struct pklcd **) malloc (size, M_IFADDR, M_WAITOK);
19149930Ssklower if (pkp -> pk_chan) {
19257957Ssklower bzero ((caddr_t) pkp -> pk_chan, size);
19349930Ssklower /*
19449930Ssklower * Allocate a logical channel descriptor for lcn 0
19549930Ssklower */
19649930Ssklower if (dev_lcp == 0 &&
19749930Ssklower (dev_lcp = pk_attach ((struct socket *)0)) == 0)
19849930Ssklower return (ENOBUFS);
19949930Ssklower dev_lcp -> lcd_state = READY;
20049930Ssklower dev_lcp -> lcd_pkp = pkp;
20149930Ssklower pkp -> pk_chan[0] = dev_lcp;
20249930Ssklower } else {
20349930Ssklower if (dev_lcp)
20449930Ssklower pk_close (dev_lcp);
20549930Ssklower return (ENOBUFS);
20649930Ssklower }
20749930Ssklower }
20849930Ssklower return 0;
20949930Ssklower }
21049930Ssklower
21141591Ssklower /*
21241591Ssklower * This procedure is called by the link level whenever the link
21341591Ssklower * becomes operational, is reset, or when the link goes down.
21441591Ssklower */
21557024Ssklower /*VARARGS*/
21657024Ssklower caddr_t
pk_ctlinput(code,src,addr)21757024Ssklower pk_ctlinput (code, src, addr)
21857024Ssklower struct sockaddr *src;
21957024Ssklower caddr_t addr;
22041591Ssklower {
22157957Ssklower register struct pkcb *pkp = (struct pkcb *) addr;
22241591Ssklower
22341591Ssklower switch (code) {
22441591Ssklower case PRC_LINKUP:
22541591Ssklower if (pkp -> pk_state == DTE_WAITING)
22641591Ssklower pk_restart (pkp, X25_RESTART_NETWORK_CONGESTION);
22741591Ssklower break;
22841591Ssklower
22941591Ssklower case PRC_LINKDOWN:
23041591Ssklower pk_restart (pkp, -1); /* Clear all active circuits */
23141591Ssklower pkp -> pk_state = DTE_WAITING;
23241591Ssklower break;
23341591Ssklower
23441591Ssklower case PRC_LINKRESET:
23541591Ssklower pk_restart (pkp, X25_RESTART_NETWORK_CONGESTION);
23641591Ssklower break;
23757024Ssklower
23857024Ssklower case PRC_CONNECT_INDICATION: {
23957024Ssklower struct rtentry *llrt;
24041591Ssklower
24157024Ssklower if ((llrt = rtalloc1(src, 0)) == 0)
24257024Ssklower return 0;
24357957Ssklower else llrt -> rt_refcnt--;
24457024Ssklower
24557957Ssklower pkp = (((struct npaidbentry *) llrt -> rt_llinfo) -> np_rt) ?
24657957Ssklower (struct pkcb *)(((struct npaidbentry *) llrt -> rt_llinfo) -> np_rt -> rt_llinfo) : (struct pkcb *) 0;
24757024Ssklower if (pkp == (struct pkcb *) 0)
24857024Ssklower return 0;
24957957Ssklower pkp -> pk_llnext = addr;
25057024Ssklower
25157024Ssklower return ((caddr_t) pkp);
25241591Ssklower }
25357024Ssklower case PRC_DISCONNECT_INDICATION:
25457024Ssklower pk_restart (pkp, -1) ; /* Clear all active circuits */
25557957Ssklower pkp -> pk_state = DTE_WAITING;
25657957Ssklower pkp -> pk_llnext = (caddr_t) 0;
25757024Ssklower }
25841591Ssklower return (0);
25941591Ssklower }
26045297Ssklower struct ifqueue pkintrq;
26145297Ssklower /*
26245297Ssklower * This routine is called if there are semi-smart devices that do HDLC
26345297Ssklower * in hardware and want to queue the packet and call level 3 directly
26445297Ssklower */
pkintr()26545297Ssklower pkintr ()
26645297Ssklower {
26745297Ssklower register struct mbuf *m;
26845297Ssklower register struct ifaddr *ifa;
26945297Ssklower register struct ifnet *ifp;
27045297Ssklower register int s;
27141591Ssklower
27245297Ssklower for (;;) {
27345297Ssklower s = splimp ();
27445297Ssklower IF_DEQUEUE (&pkintrq, m);
27545297Ssklower splx (s);
27645297Ssklower if (m == 0)
27745297Ssklower break;
27857957Ssklower if (m -> m_len < PKHEADERLN) {
27945297Ssklower printf ("pkintr: packet too short (len=%d)\n",
28057957Ssklower m -> m_len);
28145297Ssklower m_freem (m);
28245297Ssklower continue;
28345297Ssklower }
28457957Ssklower pk_input (m);
28545297Ssklower }
28645297Ssklower }
28745297Ssklower struct mbuf *pk_bad_packet;
28849593Ssklower struct mbuf_cache pk_input_cache = {0 };
28941591Ssklower /*
29041591Ssklower * X.25 PACKET INPUT
29141591Ssklower *
29241591Ssklower * This procedure is called by a link level procedure whenever
29341591Ssklower * an information frame is received. It decodes the packet and
29441591Ssklower * demultiplexes based on the logical channel number.
29541591Ssklower *
29649930Ssklower * We change the original conventions of the UBC code here --
29757955Ssklower * since there may be multiple pkcb's for a given interface
29857955Ssklower * of type 802.2 class 2, we retrieve which one it is from
29957955Ssklower * m_pkthdr.rcvif (which has been overwritten by lower layers);
30057955Ssklower * That field is then restored for the benefit of upper layers which
30157955Ssklower * may make use of it, such as CLNP.
30257957Ssklower *
30341591Ssklower */
30441591Ssklower
30557024Ssklower #define RESTART_DTE_ORIGINATED(xp) (((xp) -> packet_cause == X25_RESTART_DTE_ORIGINATED) || \
30657024Ssklower ((xp) -> packet_cause >= X25_RESTART_DTE_ORIGINATED2))
30757024Ssklower
pk_input(m)30849930Ssklower pk_input (m)
30941591Ssklower register struct mbuf *m;
31041591Ssklower {
31141591Ssklower register struct x25_packet *xp;
31241591Ssklower register struct pklcd *lcp;
31341591Ssklower register struct socket *so = 0;
31441591Ssklower register struct pkcb *pkp;
31541591Ssklower int ptype, lcn, lcdstate = LISTEN;
31641591Ssklower
31749593Ssklower if (pk_input_cache.mbc_size || pk_input_cache.mbc_oldsize)
31857957Ssklower mbuf_cache (&pk_input_cache, m);
31957957Ssklower if ((m -> m_flags & M_PKTHDR) == 0)
32057957Ssklower panic ("pkintr");
32157024Ssklower
32257957Ssklower if ((pkp = (struct pkcb *) m -> m_pkthdr.rcvif) == 0)
32349930Ssklower return;
32441591Ssklower xp = mtod (m, struct x25_packet *);
32541591Ssklower ptype = pk_decode (xp);
32645573Ssklower lcn = LCN(xp);
32741591Ssklower lcp = pkp -> pk_chan[lcn];
32841591Ssklower
32941591Ssklower /*
33041591Ssklower * If the DTE is in Restart state, then it will ignore data,
33141591Ssklower * interrupt, call setup and clearing, flow control and reset
33241591Ssklower * packets.
33341591Ssklower */
33441591Ssklower if (lcn < 0 || lcn > pkp -> pk_maxlcn) {
33541591Ssklower pk_message (lcn, pkp -> pk_xcp, "illegal lcn");
33641591Ssklower m_freem (m);
33741591Ssklower return;
33841591Ssklower }
33941591Ssklower
34045895Ssklower pk_trace (pkp -> pk_xcp, m, "P-In");
34141591Ssklower
34241591Ssklower if (pkp -> pk_state != DTE_READY && ptype != RESTART && ptype != RESTART_CONF) {
34341591Ssklower m_freem (m);
34441591Ssklower return;
34541591Ssklower }
34641591Ssklower if (lcp) {
34741591Ssklower so = lcp -> lcd_so;
34841591Ssklower lcdstate = lcp -> lcd_state;
34941591Ssklower } else {
35041591Ssklower if (ptype == CLEAR) { /* idle line probe (Datapac specific) */
35141591Ssklower /* send response on lcd 0's output queue */
35249930Ssklower lcp = pkp -> pk_chan[0];
35341591Ssklower lcp -> lcd_template = pk_template (lcn, X25_CLEAR_CONFIRM);
35441591Ssklower pk_output (lcp);
35541591Ssklower m_freem (m);
35641591Ssklower return;
35741591Ssklower }
35841591Ssklower if (ptype != CALL)
35941591Ssklower ptype = INVALID_PACKET;
36041591Ssklower }
36141591Ssklower
36241591Ssklower if (lcn == 0 && ptype != RESTART && ptype != RESTART_CONF) {
36345297Ssklower pk_message (0, pkp -> pk_xcp, "illegal ptype (%d, %s) on lcn 0",
36445297Ssklower ptype, pk_name[ptype / MAXSTATES]);
36545297Ssklower if (pk_bad_packet)
36645297Ssklower m_freem (pk_bad_packet);
36745297Ssklower pk_bad_packet = m;
36841591Ssklower return;
36941591Ssklower }
37041591Ssklower
37157955Ssklower m -> m_pkthdr.rcvif = pkp -> pk_ia -> ia_ifp;
37257955Ssklower
37341591Ssklower switch (ptype + lcdstate) {
37441591Ssklower /*
37541591Ssklower * Incoming Call packet received.
37641591Ssklower */
37741591Ssklower case CALL + LISTEN:
37849593Ssklower pk_incoming_call (pkp, m);
37941591Ssklower break;
38041591Ssklower
38141591Ssklower /*
38241591Ssklower * Call collision: Just throw this "incoming call" away since
38341591Ssklower * the DCE will ignore it anyway.
38441591Ssklower */
38541591Ssklower case CALL + SENT_CALL:
38657957Ssklower pk_message ((int) lcn, pkp -> pk_xcp,
38741591Ssklower "incoming call collision");
38841591Ssklower break;
38941591Ssklower
39041591Ssklower /*
39141591Ssklower * Call confirmation packet received. This usually means our
39241591Ssklower * previous connect request is now complete.
39341591Ssklower */
39441591Ssklower case CALL_ACCEPTED + SENT_CALL:
39549252Ssklower MCHTYPE(m, MT_CONTROL);
39649593Ssklower pk_call_accepted (lcp, m);
39741591Ssklower break;
39841591Ssklower
39941591Ssklower /*
40041591Ssklower * This condition can only happen if the previous state was
40141591Ssklower * SENT_CALL. Just ignore the packet, eventually a clear
40241591Ssklower * confirmation should arrive.
40341591Ssklower */
40441591Ssklower case CALL_ACCEPTED + SENT_CLEAR:
40541591Ssklower break;
40641591Ssklower
40741591Ssklower /*
40841591Ssklower * Clear packet received. This requires a complete tear down
40941591Ssklower * of the virtual circuit. Free buffers and control blocks.
41041591Ssklower * and send a clear confirmation.
41141591Ssklower */
41241591Ssklower case CLEAR + READY:
41341591Ssklower case CLEAR + RECEIVED_CALL:
41441591Ssklower case CLEAR + SENT_CALL:
41541591Ssklower case CLEAR + DATA_TRANSFER:
41641591Ssklower lcp -> lcd_state = RECEIVED_CLEAR;
41741591Ssklower lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_CLEAR_CONFIRM);
41841591Ssklower pk_output (lcp);
41941591Ssklower pk_clearcause (pkp, xp);
42049252Ssklower if (lcp -> lcd_upper) {
42149252Ssklower MCHTYPE(m, MT_CONTROL);
42249252Ssklower lcp -> lcd_upper (lcp, m);
42349252Ssklower }
42441591Ssklower pk_close (lcp);
42549252Ssklower lcp = 0;
42641591Ssklower break;
42741591Ssklower
42841591Ssklower /*
42941591Ssklower * Clear collision: Treat this clear packet as a confirmation.
43041591Ssklower */
43141591Ssklower case CLEAR + SENT_CLEAR:
43241591Ssklower pk_close (lcp);
43341591Ssklower break;
43441591Ssklower
43541591Ssklower /*
43641591Ssklower * Clear confirmation received. This usually means the virtual
43741591Ssklower * circuit is now completely removed.
43841591Ssklower */
43941591Ssklower case CLEAR_CONF + SENT_CLEAR:
44041591Ssklower pk_close (lcp);
44141591Ssklower break;
44241591Ssklower
44341591Ssklower /*
44441591Ssklower * A clear confirmation on an unassigned logical channel - just
44541591Ssklower * ignore it. Note: All other packets on an unassigned channel
44641591Ssklower * results in a clear.
44741591Ssklower */
44841591Ssklower case CLEAR_CONF + READY:
44949930Ssklower case CLEAR_CONF + LISTEN:
45041591Ssklower break;
45141591Ssklower
45241591Ssklower /*
45341591Ssklower * Data packet received. Pass on to next level. Move the Q and M
45441591Ssklower * bits into the data portion for the next level.
45541591Ssklower */
45641591Ssklower case DATA + DATA_TRANSFER:
45741591Ssklower if (lcp -> lcd_reset_condition) {
45841591Ssklower ptype = DELETE_PACKET;
45941591Ssklower break;
46041591Ssklower }
46141591Ssklower
46241591Ssklower /*
46341591Ssklower * Process the P(S) flow control information in this Data packet.
46441591Ssklower * Check that the packets arrive in the correct sequence and that
46541591Ssklower * they are within the "lcd_input_window". Input window rotation is
46641591Ssklower * initiated by the receive interface.
46741591Ssklower */
46841591Ssklower
46941591Ssklower if (PS(xp) != ((lcp -> lcd_rsn + 1) % MODULUS) ||
47057957Ssklower PS(xp) == ((lcp -> lcd_input_window + lcp -> lcd_windowsize) % MODULUS)) {
47141591Ssklower m_freem (m);
47245895Ssklower pk_procerror (RESET, lcp, "p(s) flow control error", 1);
47341591Ssklower break;
47441591Ssklower }
47541591Ssklower lcp -> lcd_rsn = PS(xp);
47641591Ssklower
47741591Ssklower if (pk_ack (lcp, PR(xp)) != PACKET_OK) {
47841591Ssklower m_freem (m);
47941591Ssklower break;
48041591Ssklower }
48145895Ssklower m -> m_data += PKHEADERLN;
48245895Ssklower m -> m_len -= PKHEADERLN;
48345895Ssklower m -> m_pkthdr.len -= PKHEADERLN;
48445895Ssklower
48549930Ssklower lcp -> lcd_rxcnt++;
48645895Ssklower if (lcp -> lcd_flags & X25_MBS_HOLD) {
48745895Ssklower register struct mbuf *n = lcp -> lcd_cps;
48845895Ssklower int mbit = MBIT(xp);
48945895Ssklower octet q_and_d_bits;
49045895Ssklower
49145895Ssklower if (n) {
49245895Ssklower n -> m_pkthdr.len += m -> m_pkthdr.len;
49345895Ssklower while (n -> m_next)
49445895Ssklower n = n -> m_next;
49545895Ssklower n -> m_next = m;
49645895Ssklower m = lcp -> lcd_cps;
49745895Ssklower
49845895Ssklower if (lcp -> lcd_cpsmax &&
49945895Ssklower n -> m_pkthdr.len > lcp -> lcd_cpsmax) {
50045895Ssklower pk_procerror (RESET, lcp,
50145895Ssklower "C.P.S. overflow", 128);
50245895Ssklower return;
50345895Ssklower }
50457957Ssklower q_and_d_bits = 0xc0 & *(octet *) xp;
50545895Ssklower xp = (struct x25_packet *)
50657957Ssklower (mtod (m, octet *) - PKHEADERLN);
50757957Ssklower *(octet *) xp |= q_and_d_bits;
50845895Ssklower }
50945895Ssklower if (mbit) {
51045895Ssklower lcp -> lcd_cps = m;
51157957Ssklower pk_flowcontrol (lcp, 0, 1);
51245895Ssklower return;
51345895Ssklower }
51445895Ssklower lcp -> lcd_cps = 0;
51545895Ssklower }
51645297Ssklower if (so == 0)
51745297Ssklower break;
51841591Ssklower if (lcp -> lcd_flags & X25_MQBIT) {
51957024Ssklower octet t = (X25GBITS(xp -> bits, q_bit)) ? t = 0x80 : 0;
52041591Ssklower
52145573Ssklower if (MBIT(xp))
52245573Ssklower t |= 0x40;
52343361Ssklower m -> m_data -= 1;
52441591Ssklower m -> m_len += 1;
52545895Ssklower m -> m_pkthdr.len += 1;
52657957Ssklower *mtod (m, octet *) = t;
52741591Ssklower }
52841591Ssklower
52941591Ssklower /*
53041591Ssklower * Discard Q-BIT packets if the application
53141591Ssklower * doesn't want to be informed of M and Q bit status
53241591Ssklower */
53357024Ssklower if (X25GBITS(xp -> bits, q_bit)
53457024Ssklower && (lcp -> lcd_flags & X25_MQBIT) == 0) {
53541591Ssklower m_freem (m);
53641591Ssklower /*
53741591Ssklower * NB. This is dangerous: sending a RR here can
53841591Ssklower * cause sequence number errors if a previous data
53941591Ssklower * packet has not yet been passed up to the application
54041591Ssklower * (RR's are normally generated via PRU_RCVD).
54141591Ssklower */
54257957Ssklower pk_flowcontrol (lcp, 0, 1);
54341591Ssklower } else {
54441591Ssklower sbappendrecord (&so -> so_rcv, m);
54541591Ssklower sorwakeup (so);
54641591Ssklower }
54741591Ssklower break;
54841591Ssklower
54941591Ssklower /*
55041591Ssklower * Interrupt packet received.
55141591Ssklower */
55241591Ssklower case INTERRUPT + DATA_TRANSFER:
55341591Ssklower if (lcp -> lcd_reset_condition)
55441591Ssklower break;
55541591Ssklower lcp -> lcd_intrdata = xp -> packet_data;
55641591Ssklower lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_INTERRUPT_CONFIRM);
55741591Ssklower pk_output (lcp);
55845895Ssklower m -> m_data += PKHEADERLN;
55945895Ssklower m -> m_len -= PKHEADERLN;
56045895Ssklower m -> m_pkthdr.len -= PKHEADERLN;
56145297Ssklower MCHTYPE(m, MT_OOBDATA);
56245895Ssklower if (so) {
56345895Ssklower if (so -> so_options & SO_OOBINLINE)
56445895Ssklower sbinsertoob (&so -> so_rcv, m);
56545895Ssklower else
56645895Ssklower m_freem (m);
56745297Ssklower sohasoutofband (so);
56845895Ssklower }
56941591Ssklower break;
57041591Ssklower
57141591Ssklower /*
57241591Ssklower * Interrupt confirmation packet received.
57341591Ssklower */
57441591Ssklower case INTERRUPT_CONF + DATA_TRANSFER:
57541591Ssklower if (lcp -> lcd_reset_condition)
57641591Ssklower break;
57741591Ssklower if (lcp -> lcd_intrconf_pending == TRUE)
57841591Ssklower lcp -> lcd_intrconf_pending = FALSE;
57941591Ssklower else
58045895Ssklower pk_procerror (RESET, lcp, "unexpected packet", 43);
58141591Ssklower break;
58241591Ssklower
58341591Ssklower /*
58441591Ssklower * Receiver ready received. Rotate the output window and output
58541591Ssklower * any data packets waiting transmission.
58641591Ssklower */
58741591Ssklower case RR + DATA_TRANSFER:
58845297Ssklower if (lcp -> lcd_reset_condition ||
58945297Ssklower pk_ack (lcp, PR(xp)) != PACKET_OK) {
59045297Ssklower ptype = DELETE_PACKET;
59141591Ssklower break;
59245297Ssklower }
59341591Ssklower if (lcp -> lcd_rnr_condition == TRUE)
59441591Ssklower lcp -> lcd_rnr_condition = FALSE;
59541591Ssklower pk_output (lcp);
59641591Ssklower break;
59741591Ssklower
59841591Ssklower /*
59941591Ssklower * Receiver Not Ready received. Packets up to the P(R) can be
60041591Ssklower * be sent. Condition is cleared with a RR.
60141591Ssklower */
60241591Ssklower case RNR + DATA_TRANSFER:
60345297Ssklower if (lcp -> lcd_reset_condition ||
60445297Ssklower pk_ack (lcp, PR(xp)) != PACKET_OK) {
60545297Ssklower ptype = DELETE_PACKET;
60641591Ssklower break;
60745297Ssklower }
60841591Ssklower lcp -> lcd_rnr_condition = TRUE;
60941591Ssklower break;
61041591Ssklower
61141591Ssklower /*
61241591Ssklower * Reset packet received. Set state to FLOW_OPEN. The Input and
61341591Ssklower * Output window edges ar set to zero. Both the send and receive
61441591Ssklower * numbers are reset. A confirmation is returned.
61541591Ssklower */
61641591Ssklower case RESET + DATA_TRANSFER:
61741591Ssklower if (lcp -> lcd_reset_condition)
61841591Ssklower /* Reset collision. Just ignore packet. */
61941591Ssklower break;
62041591Ssklower
62141591Ssklower pk_resetcause (pkp, xp);
62241591Ssklower lcp -> lcd_window_condition = lcp -> lcd_rnr_condition =
62341591Ssklower lcp -> lcd_intrconf_pending = FALSE;
62441591Ssklower lcp -> lcd_output_window = lcp -> lcd_input_window =
62541591Ssklower lcp -> lcd_last_transmitted_pr = 0;
62641591Ssklower lcp -> lcd_ssn = 0;
62741591Ssklower lcp -> lcd_rsn = MODULUS - 1;
62841591Ssklower
62941591Ssklower lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_RESET_CONFIRM);
63041591Ssklower pk_output (lcp);
63145297Ssklower
63257957Ssklower pk_flush (lcp);
63345297Ssklower if (so == 0)
63445297Ssklower break;
63545297Ssklower wakeup ((caddr_t) & so -> so_timeo);
63645297Ssklower sorwakeup (so);
63745297Ssklower sowwakeup (so);
63841591Ssklower break;
63941591Ssklower
64041591Ssklower /*
64141591Ssklower * Reset confirmation received.
64241591Ssklower */
64341591Ssklower case RESET_CONF + DATA_TRANSFER:
64441591Ssklower if (lcp -> lcd_reset_condition) {
64541591Ssklower lcp -> lcd_reset_condition = FALSE;
64641591Ssklower pk_output (lcp);
64741591Ssklower }
64841591Ssklower else
64945895Ssklower pk_procerror (RESET, lcp, "unexpected packet", 32);
65041591Ssklower break;
65141591Ssklower
65241591Ssklower case DATA + SENT_CLEAR:
65341591Ssklower ptype = DELETE_PACKET;
65441591Ssklower case RR + SENT_CLEAR:
65541591Ssklower case RNR + SENT_CLEAR:
65641591Ssklower case INTERRUPT + SENT_CLEAR:
65741591Ssklower case INTERRUPT_CONF + SENT_CLEAR:
65841591Ssklower case RESET + SENT_CLEAR:
65941591Ssklower case RESET_CONF + SENT_CLEAR:
66045297Ssklower /* Just ignore p if we have sent a CLEAR already.
66141591Ssklower */
66241591Ssklower break;
66341591Ssklower
66441591Ssklower /*
66541591Ssklower * Restart sets all the permanent virtual circuits to the "Data
66641591Ssklower * Transfer" stae and all the switched virtual circuits to the
66741591Ssklower * "Ready" state.
66841591Ssklower */
66941591Ssklower case RESTART + READY:
67041591Ssklower switch (pkp -> pk_state) {
67141591Ssklower case DTE_SENT_RESTART:
67257024Ssklower /*
67357024Ssklower * Restart collision.
67457024Ssklower * If case the restart cause is "DTE originated" we
67557024Ssklower * have a DTE-DTE situation and are trying to resolve
67657024Ssklower * who is going to play DTE/DCE [ISO 8208:4.2-4.5]
67757024Ssklower */
67857024Ssklower if (RESTART_DTE_ORIGINATED(xp)) {
67957024Ssklower pk_restart (pkp, X25_RESTART_DTE_ORIGINATED);
68057024Ssklower pk_message (0, pkp -> pk_xcp,
68157024Ssklower "RESTART collision");
68257024Ssklower if ((pkp -> pk_restartcolls++) > MAXRESTARTCOLLISIONS) {
68357024Ssklower pk_message (0, pkp -> pk_xcp,
68457024Ssklower "excessive RESTART collisions");
68557024Ssklower pkp -> pk_restartcolls = 0;
68657024Ssklower }
68757024Ssklower break;
68857024Ssklower }
68941591Ssklower pkp -> pk_state = DTE_READY;
69057024Ssklower pkp -> pk_dxerole |= DTE_PLAYDTE;
69157024Ssklower pkp -> pk_dxerole &= ~DTE_PLAYDCE;
69241591Ssklower pk_message (0, pkp -> pk_xcp,
69341591Ssklower "Packet level operational");
69457024Ssklower pk_message (0, pkp -> pk_xcp,
69557024Ssklower "Assuming DTE role");
69657024Ssklower if (pkp -> pk_dxerole & DTE_CONNECTPENDING)
69757957Ssklower pk_callcomplete (pkp);
69841591Ssklower break;
69941591Ssklower
70041591Ssklower default:
70141591Ssklower pk_restart (pkp, -1);
70241591Ssklower pk_restartcause (pkp, xp);
70341591Ssklower pkp -> pk_chan[0] -> lcd_template = pk_template (0,
70441591Ssklower X25_RESTART_CONFIRM);
70541591Ssklower pk_output (pkp -> pk_chan[0]);
70657024Ssklower pkp -> pk_state = DTE_READY;
70757024Ssklower pkp -> pk_dxerole |= RESTART_DTE_ORIGINATED(xp) ? DTE_PLAYDCE :
70857024Ssklower DTE_PLAYDTE;
70957024Ssklower if (pkp -> pk_dxerole & DTE_PLAYDTE) {
71057024Ssklower pkp -> pk_dxerole &= ~DTE_PLAYDCE;
71157024Ssklower pk_message (0, pkp -> pk_xcp,
71257024Ssklower "Assuming DTE role");
71357024Ssklower } else {
71457024Ssklower pkp -> pk_dxerole &= ~DTE_PLAYDTE;
71557024Ssklower pk_message (0, pkp -> pk_xcp,
71657024Ssklower "Assuming DCE role");
71757024Ssklower }
71857024Ssklower if (pkp -> pk_dxerole & DTE_CONNECTPENDING)
71957957Ssklower pk_callcomplete (pkp);
72041591Ssklower }
72141591Ssklower break;
72241591Ssklower
72341591Ssklower /*
72441591Ssklower * Restart confirmation received. All logical channels are set
72541591Ssklower * to READY.
72641591Ssklower */
72741591Ssklower case RESTART_CONF + READY:
72841591Ssklower switch (pkp -> pk_state) {
72941591Ssklower case DTE_SENT_RESTART:
73041591Ssklower pkp -> pk_state = DTE_READY;
73157024Ssklower pkp -> pk_dxerole |= DTE_PLAYDTE;
73257024Ssklower pkp -> pk_dxerole &= ~DTE_PLAYDCE;
73341591Ssklower pk_message (0, pkp -> pk_xcp,
73457024Ssklower "Packet level operational");
73557957Ssklower pk_message (0, pkp -> pk_xcp,
73657024Ssklower "Assuming DTE role");
73757024Ssklower if (pkp -> pk_dxerole & DTE_CONNECTPENDING)
73857957Ssklower pk_callcomplete (pkp);
73941591Ssklower break;
74041591Ssklower
74141591Ssklower default:
74241591Ssklower /* Restart local procedure error. */
74341591Ssklower pk_restart (pkp, X25_RESTART_LOCAL_PROCEDURE_ERROR);
74441591Ssklower pkp -> pk_state = DTE_SENT_RESTART;
74557024Ssklower pkp -> pk_dxerole &= ~(DTE_PLAYDTE | DTE_PLAYDCE);
74641591Ssklower }
74741591Ssklower break;
74841591Ssklower
74941591Ssklower default:
75041591Ssklower if (lcp) {
75145895Ssklower pk_procerror (CLEAR, lcp, "unknown packet error", 33);
75241591Ssklower pk_message (lcn, pkp -> pk_xcp,
75341591Ssklower "\"%s\" unexpected in \"%s\" state",
75441591Ssklower pk_name[ptype/MAXSTATES], pk_state[lcdstate]);
75545895Ssklower } else
75645573Ssklower pk_message (lcn, pkp -> pk_xcp,
75741591Ssklower "packet arrived on unassigned lcn");
75841591Ssklower break;
75941591Ssklower }
76049252Ssklower if (so == 0 && lcp && lcp -> lcd_upper && lcdstate == DATA_TRANSFER) {
76145895Ssklower if (ptype != DATA && ptype != INTERRUPT)
76245895Ssklower MCHTYPE(m, MT_CONTROL);
76345297Ssklower lcp -> lcd_upper (lcp, m);
76445895Ssklower } else if (ptype != DATA && ptype != INTERRUPT)
76541591Ssklower m_freem (m);
76641591Ssklower }
76741591Ssklower
76849930Ssklower static
prune_dnic(from,to,dnicname,xcp)76957957Ssklower prune_dnic (from, to, dnicname, xcp)
77049930Ssklower char *from, *to, *dnicname;
77149930Ssklower register struct x25config *xcp;
77249930Ssklower {
77349930Ssklower register char *cp1 = from, *cp2 = from;
77457957Ssklower if (xcp -> xc_prepnd0 && *cp1 == '0') {
77549930Ssklower from = ++cp1;
77649930Ssklower goto copyrest;
77749930Ssklower }
77857957Ssklower if (xcp -> xc_nodnic) {
77949930Ssklower for (cp1 = dnicname; *cp2 = *cp1++;)
78049930Ssklower cp2++;
78149930Ssklower cp1 = from;
78249930Ssklower }
78349930Ssklower copyrest:
78449930Ssklower for (cp1 = dnicname; *cp2 = *cp1++;)
78549930Ssklower cp2++;
78649930Ssklower }
78749930Ssklower /* static */
pk_simple_bsd(from,to,lower,len)78849930Ssklower pk_simple_bsd (from, to, lower, len)
78949930Ssklower register octet *from, *to;
79049930Ssklower register len, lower;
79149930Ssklower {
79249930Ssklower register int c;
79349930Ssklower while (--len >= 0) {
79449930Ssklower c = *from;
79549930Ssklower if (lower & 0x01)
79649930Ssklower *from++;
79749930Ssklower else
79849930Ssklower c >>= 4;
79949930Ssklower c &= 0x0f; c |= 0x30; *to++ = c; lower++;
80049930Ssklower }
80149930Ssklower *to = 0;
80249930Ssklower }
80341591Ssklower
80449930Ssklower /*static octet * */
pk_from_bcd(a,iscalling,sa,xcp)80549930Ssklower pk_from_bcd (a, iscalling, sa, xcp)
80649930Ssklower register struct x25_calladdr *a;
80749930Ssklower register struct sockaddr_x25 *sa;
80849930Ssklower register struct x25config *xcp;
80949930Ssklower {
81049930Ssklower octet buf[MAXADDRLN+1];
81149930Ssklower octet *cp;
81249930Ssklower unsigned count;
81349930Ssklower
81457957Ssklower bzero ((caddr_t) sa, sizeof (*sa));
81549930Ssklower sa -> x25_len = sizeof (*sa);
81649930Ssklower sa -> x25_family = AF_CCITT;
81749930Ssklower if (iscalling) {
81857024Ssklower cp = a -> address_field + (X25GBITS(a -> addrlens, called_addrlen) / 2);
81957024Ssklower count = X25GBITS(a -> addrlens, calling_addrlen);
82057024Ssklower pk_simple_bsd (cp, buf, X25GBITS(a -> addrlens, called_addrlen), count);
82149930Ssklower } else {
82257024Ssklower count = X25GBITS(a -> addrlens, called_addrlen);
82349930Ssklower pk_simple_bsd (a -> address_field, buf, 0, count);
82449930Ssklower }
82557957Ssklower if (xcp -> xc_addr.x25_net && (xcp -> xc_nodnic || xcp -> xc_prepnd0)) {
82657957Ssklower octet dnicname[sizeof (long) * NBBY/3 + 2];
82749930Ssklower
82857024Ssklower sprintf ((char *) dnicname, "%d", xcp -> xc_addr.x25_net);
82957957Ssklower prune_dnic ((char *) buf, sa -> x25_addr, dnicname, xcp);
83049930Ssklower } else
83157957Ssklower bcopy ((caddr_t) buf, (caddr_t) sa -> x25_addr, count + 1);
83249930Ssklower }
83349930Ssklower
83449930Ssklower static
83557957Ssklower save_extra (m0, fp, so)
83649930Ssklower struct mbuf *m0;
83749930Ssklower octet *fp;
83849930Ssklower struct socket *so;
83949930Ssklower {
84049930Ssklower register struct mbuf *m;
84149930Ssklower struct cmsghdr cmsghdr;
84252449Ssklower if (m = m_copy (m, 0, (int)M_COPYALL)) {
84349930Ssklower int off = fp - mtod (m0, octet *);
84457957Ssklower int len = m -> m_pkthdr.len - off + sizeof (cmsghdr);
84549930Ssklower cmsghdr.cmsg_len = len;
84649930Ssklower cmsghdr.cmsg_level = AF_CCITT;
84749930Ssklower cmsghdr.cmsg_type = PK_FACILITIES;
84849930Ssklower m_adj (m, off);
84957957Ssklower M_PREPEND (m, sizeof (cmsghdr), M_DONTWAIT);
85049930Ssklower if (m == 0)
85149930Ssklower return;
85249930Ssklower bcopy ((caddr_t)&cmsghdr, mtod (m, caddr_t), sizeof (cmsghdr));
85349930Ssklower MCHTYPE(m, MT_CONTROL);
85457957Ssklower sbappendrecord (&so -> so_rcv, m);
85549930Ssklower }
85649930Ssklower }
85749930Ssklower
85841591Ssklower /*
85941591Ssklower * This routine handles incoming call packets. It matches the protocol
86041591Ssklower * field on the Call User Data field (usually the first four bytes) with
86141591Ssklower * sockets awaiting connections.
86241591Ssklower */
86341591Ssklower
86449593Ssklower pk_incoming_call (pkp, m0)
86545895Ssklower struct mbuf *m0;
86641591Ssklower struct pkcb *pkp;
86741591Ssklower {
86842277Ssklower register struct pklcd *lcp = 0, *l;
86941591Ssklower register struct sockaddr_x25 *sa;
87041591Ssklower register struct x25_calladdr *a;
87142277Ssklower register struct socket *so = 0;
87257957Ssklower struct x25_packet *xp = mtod (m0, struct x25_packet *);
87349930Ssklower struct mbuf *m;
87449930Ssklower struct x25config *xcp = pkp -> pk_xcp;
87557957Ssklower int len = m0 -> m_pkthdr.len;
87649930Ssklower unsigned udlen;
87749930Ssklower char *errstr = "server unavailable";
87845895Ssklower octet *u, *facp;
87945573Ssklower int lcn = LCN(xp);
88041591Ssklower
88149930Ssklower /* First, copy the data from the incoming call packet to a X25 address
88249930Ssklower descriptor. It is to be regretted that you have
88349930Ssklower to parse the facilities into a sockaddr to determine
88449930Ssklower if reverse charging is being requested */
88549930Ssklower if ((m = m_get (M_DONTWAIT, MT_SONAME)) == 0)
88641591Ssklower return;
88741591Ssklower sa = mtod (m, struct sockaddr_x25 *);
88849930Ssklower a = (struct x25_calladdr *) &xp -> packet_data;
88949930Ssklower facp = u = (octet *) (a -> address_field +
89057024Ssklower ((X25GBITS(a -> addrlens, called_addrlen) + X25GBITS(a -> addrlens, calling_addrlen) + 1) / 2));
89149930Ssklower u += *u + 1;
89257957Ssklower udlen = min (16, ((octet *) xp) + len - u);
89349930Ssklower if (udlen < 0)
89449930Ssklower udlen = 0;
89549930Ssklower pk_from_bcd (a, 1, sa, pkp -> pk_xcp); /* get calling address */
89650426Ssklower pk_parse_facilities (facp, sa);
89757957Ssklower bcopy ((caddr_t) u, sa -> x25_udata, udlen);
89849930Ssklower sa -> x25_udlen = udlen;
89941591Ssklower
90041591Ssklower /*
90150426Ssklower * Now, loop through the listen sockets looking for a match on the
90250426Ssklower * PID. That is the first few octets of the user data field.
90350426Ssklower * This is the closest thing to a port number for X.25 packets.
90450426Ssklower * It does provide a way of multiplexing services at the user level.
90541591Ssklower */
90641591Ssklower
90741591Ssklower for (l = pk_listenhead; l; l = l -> lcd_listen) {
90841591Ssklower struct sockaddr_x25 *sxp = l -> lcd_ceaddr;
90941591Ssklower
91057957Ssklower if (bcmp (sxp -> x25_udata, u, sxp -> x25_udlen))
91141591Ssklower continue;
91245165Ssklower if (sxp -> x25_net &&
91349930Ssklower sxp -> x25_net != xcp -> xc_addr.x25_net)
91441591Ssklower continue;
91541591Ssklower /*
91649930Ssklower * don't accept incoming calls with the D-Bit on
91749930Ssklower * unless the server agrees
91849930Ssklower */
91957024Ssklower if (X25GBITS(xp -> bits, d_bit) && !(sxp -> x25_opts.op_flags & X25_DBIT)) {
92049930Ssklower errstr = "incoming D-Bit mismatch";
92149930Ssklower break;
92249930Ssklower }
92349930Ssklower /*
92441591Ssklower * don't accept incoming collect calls unless
92541591Ssklower * the server sets the reverse charging option.
92641591Ssklower */
92741591Ssklower if ((sxp -> x25_opts.op_flags & (X25_OLDSOCKADDR|X25_REVERSE_CHARGE)) == 0 &&
92841591Ssklower sa -> x25_opts.op_flags & X25_REVERSE_CHARGE) {
92941591Ssklower errstr = "incoming collect call refused";
93041591Ssklower break;
93141591Ssklower }
93242277Ssklower if (l -> lcd_so) {
93345165Ssklower if (so = sonewconn (l -> lcd_so, SS_ISCONNECTED))
93442277Ssklower lcp = (struct pklcd *) so -> so_pcb;
93542277Ssklower } else
93657957Ssklower lcp = pk_attach ((struct socket *) 0);
93742277Ssklower if (lcp == 0) {
93841591Ssklower /*
93941591Ssklower * Insufficient space or too many unaccepted
94041591Ssklower * connections. Just throw the call away.
94141591Ssklower */
94241591Ssklower errstr = "server malfunction";
94341591Ssklower break;
94441591Ssklower }
94543361Ssklower lcp -> lcd_upper = l -> lcd_upper;
94643361Ssklower lcp -> lcd_upnext = l -> lcd_upnext;
94741591Ssklower lcp -> lcd_lcn = lcn;
94841591Ssklower lcp -> lcd_state = RECEIVED_CALL;
94950020Ssklower sa -> x25_opts.op_flags |= (sxp -> x25_opts.op_flags &
95050020Ssklower ~X25_REVERSE_CHARGE) | l -> lcd_flags;
95141591Ssklower pk_assoc (pkp, lcp, sa);
95249930Ssklower lcp -> lcd_faddr = *sa;
95349930Ssklower lcp -> lcd_laddr.x25_udlen = sxp -> x25_udlen;
95457957Ssklower lcp -> lcd_craddr = &lcp -> lcd_faddr;
95541591Ssklower lcp -> lcd_template = pk_template (lcp -> lcd_lcn, X25_CALL_ACCEPTED);
95645573Ssklower if (lcp -> lcd_flags & X25_DBIT) {
95757024Ssklower if (X25GBITS(xp -> bits, d_bit))
95857957Ssklower X25SBITS(mtod (lcp -> lcd_template,
95957024Ssklower struct x25_packet *) -> bits, d_bit, 1);
96045573Ssklower else
96145573Ssklower lcp -> lcd_flags &= ~X25_DBIT;
96245573Ssklower }
96343361Ssklower if (so) {
96443361Ssklower pk_output (lcp);
96542277Ssklower soisconnected (so);
96645895Ssklower if (so -> so_options & SO_OOBINLINE)
96757957Ssklower save_extra (m0, facp, so);
96845895Ssklower } else if (lcp -> lcd_upper) {
96949930Ssklower (*lcp -> lcd_upper) (lcp, m0);
97045895Ssklower }
97149930Ssklower (void) m_free (m);
97241591Ssklower return;
97341591Ssklower }
97441591Ssklower
97541591Ssklower /*
97641591Ssklower * If the call fails for whatever reason, we still need to build a
97741591Ssklower * skeleton LCD in order to be able to properly receive the CLEAR
97841591Ssklower * CONFIRMATION.
97941591Ssklower */
98041591Ssklower #ifdef WATERLOO /* be explicit */
98157957Ssklower if (l == 0 && bcmp (sa -> x25_udata, "ean", 3) == 0)
98241591Ssklower pk_message (lcn, pkp -> pk_xcp, "host=%s ean%c: %s",
98357957Ssklower sa -> x25_addr, sa -> x25_udata[3] & 0xff, errstr);
98457957Ssklower else if (l == 0 && bcmp (sa -> x25_udata, "\1\0\0\0", 4) == 0)
98541591Ssklower pk_message (lcn, pkp -> pk_xcp, "host=%s x29d: %s",
98657957Ssklower sa -> x25_addr, errstr);
98741591Ssklower else
98841591Ssklower #endif
98941591Ssklower pk_message (lcn, pkp -> pk_xcp, "host=%s pid=%x %x %x %x: %s",
99041591Ssklower sa -> x25_addr, sa -> x25_udata[0] & 0xff,
99141591Ssklower sa -> x25_udata[1] & 0xff, sa -> x25_udata[2] & 0xff,
99241591Ssklower sa -> x25_udata[3] & 0xff, errstr);
99357957Ssklower if ((lcp = pk_attach ((struct socket *)0)) == 0) {
99445297Ssklower (void) m_free (m);
99541591Ssklower return;
99641591Ssklower }
99741591Ssklower lcp -> lcd_lcn = lcn;
99841591Ssklower lcp -> lcd_state = RECEIVED_CALL;
99941591Ssklower pk_assoc (pkp, lcp, sa);
100045297Ssklower (void) m_free (m);
100145895Ssklower pk_clear (lcp, 0, 1);
100241591Ssklower }
100341591Ssklower
100449593Ssklower pk_call_accepted (lcp, m)
100541591Ssklower struct pklcd *lcp;
100649252Ssklower struct mbuf *m;
100741591Ssklower {
100841591Ssklower register struct x25_calladdr *ap;
100941591Ssklower register octet *fcp;
101049252Ssklower struct x25_packet *xp = mtod (m, struct x25_packet *);
101149252Ssklower int len = m -> m_len;
101241591Ssklower
101341591Ssklower lcp -> lcd_state = DATA_TRANSFER;
101445297Ssklower if (lcp -> lcd_so)
101545297Ssklower soisconnected (lcp -> lcd_so);
101657024Ssklower if ((lcp -> lcd_flags & X25_DBIT) && (X25GBITS(xp -> bits, d_bit) == 0))
101745573Ssklower lcp -> lcd_flags &= ~X25_DBIT;
101841591Ssklower if (len > 3) {
101941591Ssklower ap = (struct x25_calladdr *) &xp -> packet_data;
102057024Ssklower fcp = (octet *) ap -> address_field + (X25GBITS(ap -> addrlens, calling_addrlen) +
102157024Ssklower X25GBITS(ap -> addrlens, called_addrlen) + 1) / 2;
102257957Ssklower if (fcp + *fcp <= ((octet *) xp) + len)
102349593Ssklower pk_parse_facilities (fcp, lcp -> lcd_ceaddr);
102441591Ssklower }
102541591Ssklower pk_assoc (lcp -> lcd_pkp, lcp, lcp -> lcd_ceaddr);
102649252Ssklower if (lcp -> lcd_so == 0 && lcp -> lcd_upper)
102757957Ssklower lcp -> lcd_upper (lcp, m);
102841591Ssklower }
102941591Ssklower
pk_parse_facilities(fcp,sa)103049593Ssklower pk_parse_facilities (fcp, sa)
103141591Ssklower register octet *fcp;
103241591Ssklower register struct sockaddr_x25 *sa;
103341591Ssklower {
103441591Ssklower register octet *maxfcp;
103541591Ssklower
103641591Ssklower maxfcp = fcp + *fcp;
103741591Ssklower fcp++;
103841591Ssklower while (fcp < maxfcp) {
103941591Ssklower /*
104041591Ssklower * Ignore national DCE or DTE facilities
104141591Ssklower */
104241591Ssklower if (*fcp == 0 || *fcp == 0xff)
104341591Ssklower break;
104441591Ssklower switch (*fcp) {
104541591Ssklower case FACILITIES_WINDOWSIZE:
104641591Ssklower sa -> x25_opts.op_wsize = fcp[1];
104741591Ssklower fcp += 3;
104841591Ssklower break;
104941591Ssklower
105041591Ssklower case FACILITIES_PACKETSIZE:
105141591Ssklower sa -> x25_opts.op_psize = fcp[1];
105241591Ssklower fcp += 3;
105341591Ssklower break;
105441591Ssklower
105541591Ssklower case FACILITIES_THROUGHPUT:
105641591Ssklower sa -> x25_opts.op_speed = fcp[1];
105741591Ssklower fcp += 2;
105841591Ssklower break;
105941591Ssklower
106041591Ssklower case FACILITIES_REVERSE_CHARGE:
106141591Ssklower if (fcp[1] & 01)
106241591Ssklower sa -> x25_opts.op_flags |= X25_REVERSE_CHARGE;
106341591Ssklower /*
106441591Ssklower * Datapac specific: for a X.25(1976) DTE, bit 2
106541591Ssklower * indicates a "hi priority" (eg. international) call.
106641591Ssklower */
106741591Ssklower if (fcp[1] & 02 && sa -> x25_opts.op_psize == 0)
106841591Ssklower sa -> x25_opts.op_psize = X25_PS128;
106941591Ssklower fcp += 2;
107041591Ssklower break;
107141591Ssklower
107241591Ssklower default:
107341591Ssklower /*printf("unknown facility %x, class=%d\n", *fcp, (*fcp & 0xc0) >> 6);*/
107441591Ssklower switch ((*fcp & 0xc0) >> 6) {
107541591Ssklower case 0: /* class A */
107641591Ssklower fcp += 2;
107741591Ssklower break;
107841591Ssklower
107941591Ssklower case 1:
108041591Ssklower fcp += 3;
108141591Ssklower break;
108241591Ssklower
108341591Ssklower case 2:
108441591Ssklower fcp += 4;
108541591Ssklower break;
108641591Ssklower
108741591Ssklower case 3:
108841591Ssklower fcp++;
108941591Ssklower fcp += *fcp;
109041591Ssklower }
109141591Ssklower }
109241591Ssklower }
109341591Ssklower }
1094