home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / sys / netccitt / pk_input.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-08-05  |  24.2 KB  |  951 lines

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