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

  1. /*
  2.  * Copyright (c) University of British Columbia, 1984
  3.  * Copyright (c) 1990 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.  *    @(#)hd_subr.c    7.6 (Berkeley) 5/29/91
  39.  */
  40.  
  41. #include "param.h"
  42. #include "systm.h"
  43. #include "mbuf.h"
  44. #include "domain.h"
  45. #include "socket.h"
  46. #include "protosw.h"
  47. #include "errno.h"
  48. #include "time.h"
  49. #include "kernel.h"
  50.  
  51. #include "../net/if.h"
  52.  
  53. #include "hdlc.h"
  54. #include "hd_var.h"
  55. #include "x25.h"
  56.  
  57. hd_init ()
  58. {
  59.  
  60.     hdintrq.ifq_maxlen = IFQ_MAXLEN;
  61. }
  62.  
  63. hd_ctlinput (prc, addr)
  64. struct sockaddr *addr;
  65. {
  66.     register struct x25config *xcp = (struct x25config *)addr;
  67.     register struct hdcb *hdp;
  68.     register struct ifaddr *ifa;
  69.     struct ifnet *ifp;
  70.     caddr_t pk_newlink();
  71.  
  72.     if (addr->sa_family != AF_CCITT)
  73.         return (EAFNOSUPPORT);
  74.     if (xcp->xc_lptype != HDLCPROTO_LAPB)
  75.         return (EPROTONOSUPPORT);
  76.     ifa = ifa_ifwithaddr(addr);
  77.     if (ifa == 0 || ifa->ifa_addr->sa_family != AF_CCITT ||
  78.         (ifp = ifa->ifa_ifp) == 0)
  79.         panic ("hd_ctlinput");
  80.     for (hdp = hdcbhead; hdp; hdp = hdp->hd_next)
  81.         if (hdp->hd_ifp == ifp)
  82.             break;
  83.  
  84.     if (hdp == 0) {        /* new interface */
  85.         int error, hd_ifoutput(), hd_output();
  86.  
  87.         /* an hdcb is now too big to fit in an mbuf */
  88.         MALLOC(hdp, struct hdcb *, sizeof (*hdp), M_PCB, M_DONTWAIT);
  89.         if (hdp == 0)
  90.             return (ENOBUFS);
  91.         bzero((caddr_t)hdp, sizeof(*hdp));
  92.         hdp->hd_pkp =
  93.             pk_newlink ((struct x25_ifaddr *)ifa, (caddr_t)hdp);
  94.         if (hdp -> hd_pkp == 0) {
  95.             free(hdp, M_PCB);
  96.             return (ENOBUFS);
  97.         }
  98.         hdp->hd_ifp = ifp;
  99.         hdp->hd_ifa = ifa;
  100.         hdp->hd_xcp = xcp;
  101.         hdp->hd_state = INIT;
  102.         hdp->hd_output = hd_ifoutput;
  103.         hdp->hd_next = hdcbhead;
  104.         hdcbhead = hdp;
  105.     }
  106.  
  107.     switch (prc) {
  108.     case PRC_IFUP:
  109.         if (xcp->xc_lwsize == 0 ||
  110.             xcp->xc_lwsize > MAX_WINDOW_SIZE)
  111.                 xcp->xc_lwsize = MAX_WINDOW_SIZE;
  112.         if (hdp->hd_state == INIT)
  113.             SET_TIMER (hdp);
  114.         break;
  115.  
  116.     case PRC_IFDOWN:
  117.         if (hdp->hd_state == ABM)
  118.             hd_message (hdp, "Operator shutdown: link closed");
  119.         (void) pk_ctlinput (PRC_LINKDOWN, hdp->hd_pkp);
  120.         hd_writeinternal (hdp, DISC, POLLON);
  121.         hdp->hd_state = DISC_SENT;
  122.         SET_TIMER (hdp);
  123.     }
  124.     return (0);
  125. }
  126.  
  127. hd_initvars (hdp)
  128. register struct hdcb *hdp;
  129. {
  130.     register struct mbuf *m;
  131.     register int i;
  132.  
  133.     /* Clear Transmit queue. */
  134.     while ((m = hd_remove (&hdp->hd_txq)) != NULL)
  135.         m_freem (m);
  136.  
  137.     /* Clear Retransmit queue. */
  138.     i = hdp->hd_lastrxnr;
  139.     while (i != hdp->hd_retxqi) {
  140.         m_freem (hdp->hd_retxq[i]);
  141.         i = (i + 1) % MODULUS;
  142.     }
  143.     hdp->hd_retxqi = 0;
  144.  
  145.     hdp->hd_vs = hdp->hd_vr = 0;
  146.     hdp->hd_lasttxnr = hdp->hd_lastrxnr = 0;
  147.     hdp->hd_rrtimer = 0;
  148.     KILL_TIMER(hdp);
  149.     hdp->hd_retxcnt = 0;
  150.     hdp->hd_condition = 0;
  151. }
  152.  
  153. hd_decode (hdp, frame)
  154. register struct hdcb *hdp;
  155. struct Hdlc_frame *frame;
  156. {
  157.     register int frametype = ILLEGAL;
  158.     register struct Hdlc_iframe *iframe = (struct Hdlc_iframe *) frame;
  159.     register struct Hdlc_sframe *sframe = (struct Hdlc_sframe *) frame;
  160.     register struct Hdlc_uframe *uframe = (struct Hdlc_uframe *) frame;
  161.  
  162.     if (iframe -> hdlc_0 == 0) {
  163.         frametype = IFRAME;
  164.         hdp->hd_iframes_in++;
  165.     }
  166.  
  167.     else if (sframe -> hdlc_01 == 1) {
  168.         /* Supervisory format. */
  169.         switch (sframe -> s2) {
  170.         case 0: 
  171.             frametype = RR;
  172.             hdp->hd_rrs_in++;
  173.             break;
  174.  
  175.         case 1: 
  176.             frametype = RNR;
  177.             hdp->hd_rnrs_in++;
  178.             break;
  179.  
  180.         case 2: 
  181.             frametype = REJ;
  182.             hdp->hd_rejs_in++;
  183.         }
  184.     }
  185.     else if (uframe -> hdlc_11 == 3) {
  186.         /* Unnumbered format. */
  187.         switch (uframe -> m3) {
  188.         case 0: 
  189.             frametype = DM;
  190.             break;
  191.  
  192.         case 1: 
  193.             frametype = SABM;
  194.             break;
  195.  
  196.         case 2: 
  197.             frametype = DISC;
  198.             break;
  199.  
  200.         case 3: 
  201.             frametype = UA;
  202.             break;
  203.  
  204.         case 4: 
  205.             frametype = FRMR;
  206.             hdp->hd_frmrs_in++;
  207.         }
  208.     }
  209.     return (frametype);
  210. }
  211.  
  212. /* 
  213.  *  This routine is called when the HDLC layer internally  generates a
  214.  *  command or  response  for  the remote machine ( eg. RR, UA etc. ). 
  215.  *  Only supervisory or unnumbered frames are processed.
  216.  */
  217.  
  218. hd_writeinternal (hdp, frametype, pf)
  219. register struct hdcb *hdp;
  220. register int frametype, pf;
  221. {
  222.     register struct mbuf *buf;
  223.     struct Hdlc_frame *frame;
  224.     register struct Hdlc_sframe *sframe;
  225.     register struct Hdlc_uframe *uframe;
  226.  
  227.     MGETHDR (buf, M_DONTWAIT, MT_HEADER);
  228.     if (buf == 0)
  229.         return;
  230.     frame = mtod (buf, struct Hdlc_frame *);
  231.     sframe = mtod (buf, struct Hdlc_sframe *);
  232.     uframe = mtod (buf, struct Hdlc_uframe *);
  233.  
  234.     /* Assume a response - address structure for DTE */
  235.     frame -> address = ADDRESS_A;
  236.     buf -> m_len = 2;
  237.     buf -> m_act = buf -> m_next = NULL;
  238.  
  239.     switch (frametype) {
  240.     case RR: 
  241.         frame -> control = RR_CONTROL;
  242.         hdp->hd_rrs_out++;
  243.         break;
  244.  
  245.     case RNR: 
  246.         frame -> control = RNR_CONTROL;
  247.         hdp->hd_rnrs_out++;
  248.         break;
  249.  
  250.     case REJ: 
  251.         frame -> control = REJ_CONTROL;
  252.         hdp->hd_rejs_out++;
  253.         break;
  254.  
  255.     case SABM: 
  256.         frame -> control = SABM_CONTROL;
  257.         frame -> address = ADDRESS_B;
  258.         break;
  259.  
  260.     case DISC: 
  261.         if ((hdp->hd_ifp->if_flags & IFF_UP) == 0) {
  262.             hdp->hd_state = DISCONNECTED;
  263.             (void) m_freem (buf);
  264.             hd_flush (hdp->hd_ifp);
  265.             return;
  266.         }
  267.         frame -> control = DISC_CONTROL;
  268.         frame -> address = ADDRESS_B;
  269.         break;
  270.  
  271.     case DM: 
  272.         frame -> control = DM_CONTROL;
  273.         break;
  274.  
  275.     case UA: 
  276.         frame -> control = UA_CONTROL;
  277.         break;
  278.  
  279.     case FRMR: 
  280.         frame -> control = FRMR_CONTROL;
  281.         bcopy ((caddr_t)&hd_frmr, (caddr_t)frame -> info, 3);
  282.         buf -> m_len = 5;
  283.         hdp->hd_frmrs_out++;
  284.  
  285.     }
  286.  
  287.     if (sframe -> hdlc_01 == 1) {
  288.         /* Supervisory format - RR, REJ, or RNR. */
  289.         sframe -> nr = hdp->hd_vr;
  290.         sframe -> pf = pf;
  291.         hdp->hd_lasttxnr = hdp->hd_vr;
  292.         hdp->hd_rrtimer = 0;
  293.     }
  294.     else
  295.         uframe -> pf = pf;
  296.  
  297.     hd_trace (hdp, TX, frame);
  298.     buf -> m_pkthdr.len = buf -> m_len;
  299.     (*hdp->hd_output) (hdp, buf);
  300. }
  301.  
  302. struct mbuf *
  303. hd_remove (q)
  304. struct hdtxq *q;
  305. {
  306.     register struct mbuf *m;
  307.  
  308.     m = q -> head;
  309.     if (m) {
  310.         if ((q -> head = m -> m_act) == NULL)
  311.             q -> tail = NULL;
  312.         m -> m_act = 0;
  313.     }
  314.     return (m);
  315. }
  316.  
  317. hd_append (q, m)
  318. register struct hdtxq *q;
  319. register struct mbuf *m;
  320. {
  321.  
  322.     m -> m_act = NULL;
  323.     if (q -> tail == NULL)
  324.         q -> head = m;
  325.     else
  326.         q -> tail -> m_act = m;
  327.     q -> tail = m;
  328. }
  329.  
  330. hd_flush (ifp)
  331. struct ifnet *ifp;
  332. {
  333.     register struct mbuf *m;
  334.     register int s;
  335.  
  336.     while (1) {
  337.         s = splimp ();
  338.         IF_DEQUEUE (&ifp->if_snd, m);
  339.         splx (s);
  340.         if (m == 0)
  341.             break;
  342.         m_freem (m);
  343.     }
  344. }
  345.  
  346. hd_message (hdp, msg)
  347. struct hdcb *hdp;
  348. char *msg;
  349. {
  350.     char *format_ntn ();
  351.  
  352.     if (hdcbhead -> hd_next)
  353.         printf ("HDLC(%s): %s\n", format_ntn (hdp->hd_xcp), msg);
  354.     else
  355.         printf ("HDLC: %s\n", msg);
  356. }
  357.  
  358. #ifdef HDLCDEBUG
  359. hd_status (hdp)
  360. struct hdcb *hdp;
  361. {
  362.     printf ("HDLC STATUS:\n V(S)=%d, V(R)=%d, retxqi=%d,\n",
  363.         hdp->hd_vs, hdp->hd_vr, hdp->hd_retxqi);
  364.  
  365.     printf ("Last_rx_nr=%d, Last_tx_nr=%d,\n Condition=%d, Xx=%d\n",
  366.         hdp->hd_lastrxnr, hdp->hd_lasttxnr, hdp->hd_condition, hdp->hd_xx);
  367. }
  368. #endif
  369.