The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/netccitt/hd_subr.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: hd_subr.c,v 1.16 2003/08/07 16:33:00 agc Exp $ */
    2 
    3 /*
    4  * Copyright (c) 1990, 1993
    5  *      The Regents of the University of California.  All rights reserved.
    6  *
    7  * This code is derived from software contributed to Berkeley by
    8  * the Laboratory for Computation Vision and the Computer Science Department
    9  * of the University of British Columbia.
   10  *
   11  * Redistribution and use in source and binary forms, with or without
   12  * modification, are permitted provided that the following conditions
   13  * are met:
   14  * 1. Redistributions of source code must retain the above copyright
   15  *    notice, this list of conditions and the following disclaimer.
   16  * 2. Redistributions in binary form must reproduce the above copyright
   17  *    notice, this list of conditions and the following disclaimer in the
   18  *    documentation and/or other materials provided with the distribution.
   19  * 3. Neither the name of the University nor the names of its contributors
   20  *    may be used to endorse or promote products derived from this software
   21  *    without specific prior written permission.
   22  *
   23  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   33  * SUCH DAMAGE.
   34  *
   35  *      @(#)hd_subr.c   8.1 (Berkeley) 6/10/93
   36  */
   37 
   38 /*
   39  * Copyright (c) 1984 University of British Columbia.
   40  *
   41  * This code is derived from software contributed to Berkeley by
   42  * the Laboratory for Computation Vision and the Computer Science Department
   43  * of the University of British Columbia.
   44  *
   45  * Redistribution and use in source and binary forms, with or without
   46  * modification, are permitted provided that the following conditions
   47  * are met:
   48  * 1. Redistributions of source code must retain the above copyright
   49  *    notice, this list of conditions and the following disclaimer.
   50  * 2. Redistributions in binary form must reproduce the above copyright
   51  *    notice, this list of conditions and the following disclaimer in the
   52  *    documentation and/or other materials provided with the distribution.
   53  * 3. All advertising materials mentioning features or use of this software
   54  *    must display the following acknowledgement:
   55  *      This product includes software developed by the University of
   56  *      California, Berkeley and its contributors.
   57  * 4. Neither the name of the University nor the names of its contributors
   58  *    may be used to endorse or promote products derived from this software
   59  *    without specific prior written permission.
   60  *
   61  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   62  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   63  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   64  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   65  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   66  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   67  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   68  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   69  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   70  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   71  * SUCH DAMAGE.
   72  *
   73  *      @(#)hd_subr.c   8.1 (Berkeley) 6/10/93
   74  */
   75 
   76 #include <sys/cdefs.h>
   77 __KERNEL_RCSID(0, "$NetBSD: hd_subr.c,v 1.16 2003/08/07 16:33:00 agc Exp $");
   78 
   79 #include <sys/param.h>
   80 #include <sys/systm.h>
   81 #include <sys/mbuf.h>
   82 #include <sys/domain.h>
   83 #include <sys/socket.h>
   84 #include <sys/socketvar.h>
   85 #include <sys/protosw.h>
   86 #include <sys/errno.h>
   87 #include <sys/time.h>
   88 #include <sys/kernel.h>
   89 
   90 #include <net/if.h>
   91 
   92 #include <netccitt/hdlc.h>
   93 #include <netccitt/hd_var.h>
   94 #include <netccitt/x25.h>
   95 #include <netccitt/pk_var.h>
   96 #include <netccitt/pk_extern.h>
   97 
   98 void
   99 hd_init()
  100 {
  101 
  102         hdintrq.ifq_maxlen = IFQ_MAXLEN;
  103 }
  104 
  105 void *
  106 hd_ctlinput(prc, addr, ext)
  107         int             prc;
  108         struct sockaddr *addr;
  109         void           *ext;
  110 {
  111         struct x25config *xcp = (struct x25config *) addr;
  112         struct hdcb *hdp;
  113         struct ifaddr *ifa;
  114         struct ifnet   *ifp;
  115 
  116         if (addr->sa_family != AF_CCITT)
  117                 return (void *) (EAFNOSUPPORT);
  118         if (xcp->xc_lptype != HDLCPROTO_LAPB)
  119                 return (void *) (EPROTONOSUPPORT);
  120         ifa = ifa_ifwithaddr(addr);
  121         if (ifa == 0 || ifa->ifa_addr->sa_family != AF_CCITT ||
  122             (ifp = ifa->ifa_ifp) == 0)
  123                 panic("hd_ctlinput");
  124         for (hdp = hdcbhead; hdp; hdp = hdp->hd_next)
  125                 if (hdp->hd_ifp == ifp)
  126                         break;
  127 
  128         if (hdp == 0) {         /* new interface */
  129 
  130                 /* an hdcb is now too big to fit in an mbuf */
  131                 MALLOC(hdp, struct hdcb *, sizeof(*hdp), M_PCB, M_DONTWAIT);
  132                 if (hdp == 0)
  133                         return (void *) (ENOBUFS);
  134                 bzero((caddr_t) hdp, sizeof(*hdp));
  135                 hdp->hd_pkp =
  136                         (caddr_t) pk_newlink((struct x25_ifaddr *) ifa,
  137                                              (caddr_t) hdp);
  138                 ((struct x25_ifaddr *) ifa)->ia_pkcb =
  139                         (struct pkcb *) hdp->hd_pkp;
  140                 if (hdp->hd_pkp == 0) {
  141                         free(hdp, M_PCB);
  142                         return (void *) (ENOBUFS);
  143                 }
  144                 hdp->hd_ifp = ifp;
  145                 IFAREF(ifa);
  146                 hdp->hd_ifa = ifa;
  147                 hdp->hd_xcp = xcp;
  148                 hdp->hd_state = INIT;
  149                 hdp->hd_output = hd_ifoutput;
  150                 hdp->hd_next = hdcbhead;
  151                 hdcbhead = hdp;
  152         } else if (hdp->hd_pkp == 0) {  /* interface got reconfigured */
  153                 hdp->hd_pkp =
  154                         (caddr_t) pk_newlink((struct x25_ifaddr *) ifa,
  155                                              (caddr_t) hdp);
  156                 ((struct x25_ifaddr *) ifa)->ia_pkcb =
  157                         (struct pkcb *) hdp->hd_pkp;
  158                 if (hdp->hd_pkp == 0) {
  159                         free(hdp, M_PCB);
  160                         return (void *) (ENOBUFS);
  161                 }
  162         }
  163         switch (prc) {
  164         case PRC_IFUP:
  165                 if (xcp->xc_lwsize == 0 ||
  166                     xcp->xc_lwsize > MAX_WINDOW_SIZE)
  167                         xcp->xc_lwsize = MAX_WINDOW_SIZE;
  168                 if (hdp->hd_state == INIT)
  169                         SET_TIMER(hdp);
  170                 break;
  171 
  172         case PRC_IFDOWN:
  173                 if (hdp->hd_state == ABM)
  174                         hd_message(hdp, "Operator shutdown: link closed");
  175                 (void) pk_ctlinput(PRC_LINKDOWN,
  176                                    (struct sockaddr *) hdp->hd_pkp, NULL);
  177 
  178                 /* fall thru to ... */
  179 
  180         case PRC_DISCONNECT_REQUEST:
  181                 /* drop reference to pkcb --- it's dead meat */
  182                 hdp->hd_pkp = (caddr_t) 0;
  183                 ((struct x25_ifaddr *) ifa)->ia_pkcb = (struct pkcb *) 0;
  184 
  185                 hd_writeinternal(hdp, DISC, POLLON);
  186                 hdp->hd_state = DISC_SENT;
  187                 SET_TIMER(hdp);
  188         }
  189         return (void *) (0);
  190 }
  191 
  192 void
  193 hd_initvars(hdp)
  194         struct hdcb *hdp;
  195 {
  196         struct mbuf *m;
  197         int    i;
  198 
  199         /* Clear Transmit queue. */
  200         while ((m = hd_remove(&hdp->hd_txq)) != NULL)
  201                 m_freem(m);
  202 
  203         /* Clear Retransmit queue. */
  204         i = hdp->hd_lastrxnr;
  205         while (i != hdp->hd_retxqi) {
  206                 m_freem(hdp->hd_retxq[i]);
  207                 i = (i + 1) % MODULUS;
  208         }
  209         hdp->hd_retxqi = 0;
  210 
  211         hdp->hd_vs = hdp->hd_vr = 0;
  212         hdp->hd_lasttxnr = hdp->hd_lastrxnr = 0;
  213         hdp->hd_rrtimer = 0;
  214         KILL_TIMER(hdp);
  215         hdp->hd_retxcnt = 0;
  216         hdp->hd_condition = 0;
  217 }
  218 
  219 int
  220 hd_decode(hdp, frame)
  221         struct hdcb *hdp;
  222         struct Hdlc_frame *frame;
  223 {
  224         int    frametype = ILLEGAL;
  225         struct Hdlc_iframe *iframe = (struct Hdlc_iframe *) frame;
  226         struct Hdlc_sframe *sframe = (struct Hdlc_sframe *) frame;
  227         struct Hdlc_uframe *uframe = (struct Hdlc_uframe *) frame;
  228 
  229         if (iframe->hdlc_0 == 0) {
  230                 frametype = IFRAME;
  231                 hdp->hd_iframes_in++;
  232         } else if (sframe->hdlc_01 == 1) {
  233                 /* Supervisory format. */
  234                 switch (sframe->s2) {
  235                 case 0:
  236                         frametype = RR;
  237                         hdp->hd_rrs_in++;
  238                         break;
  239 
  240                 case 1:
  241                         frametype = RNR;
  242                         hdp->hd_rnrs_in++;
  243                         break;
  244 
  245                 case 2:
  246                         frametype = REJ;
  247                         hdp->hd_rejs_in++;
  248                 }
  249         } else if (uframe->hdlc_11 == 3) {
  250                 /* Unnumbered format. */
  251                 switch (uframe->m3) {
  252                 case 0:
  253                         frametype = DM;
  254                         break;
  255 
  256                 case 1:
  257                         frametype = SABM;
  258                         break;
  259 
  260                 case 2:
  261                         frametype = DISC;
  262                         break;
  263 
  264                 case 3:
  265                         frametype = UA;
  266                         break;
  267 
  268                 case 4:
  269                         frametype = FRMR;
  270                         hdp->hd_frmrs_in++;
  271                 }
  272         }
  273         return (frametype);
  274 }
  275 
  276 /*
  277  * This routine is called when the HDLC layer internally  generates a command
  278  * or  response  for  the remote machine ( eg. RR, UA etc. ). Only
  279  * supervisory or unnumbered frames are processed.
  280  */
  281 
  282 void
  283 hd_writeinternal(hdp, frametype, pf)
  284         struct hdcb *hdp;
  285         int    frametype, pf;
  286 {
  287         struct mbuf *buf;
  288         struct Hdlc_frame *frame;
  289         struct Hdlc_sframe *sframe;
  290         struct Hdlc_uframe *uframe;
  291 
  292         MGETHDR(buf, M_DONTWAIT, MT_HEADER);
  293         if (buf == 0)
  294                 return;
  295         frame = mtod(buf, struct Hdlc_frame *);
  296         sframe = mtod(buf, struct Hdlc_sframe *);
  297         uframe = mtod(buf, struct Hdlc_uframe *);
  298 
  299         /* Assume a response - address structure for DTE */
  300         frame->address = ADDRESS_A;
  301         buf->m_len = 2;
  302         buf->m_nextpkt = buf->m_next = NULL;
  303 
  304         switch (frametype) {
  305         case RR:
  306                 frame->control = RR_CONTROL;
  307                 hdp->hd_rrs_out++;
  308                 break;
  309 
  310         case RNR:
  311                 frame->control = RNR_CONTROL;
  312                 hdp->hd_rnrs_out++;
  313                 break;
  314 
  315         case REJ:
  316                 frame->control = REJ_CONTROL;
  317                 hdp->hd_rejs_out++;
  318                 break;
  319 
  320         case SABM:
  321                 frame->control = SABM_CONTROL;
  322                 frame->address = ADDRESS_B;
  323                 break;
  324 
  325         case DISC:
  326                 if ((hdp->hd_ifp->if_flags & IFF_UP) == 0) {
  327                         hdp->hd_state = DISCONNECTED;
  328                         (void) m_freem(buf);
  329                         hd_flush(hdp->hd_ifp);
  330                         return;
  331                 }
  332                 frame->control = DISC_CONTROL;
  333                 frame->address = ADDRESS_B;
  334                 break;
  335 
  336         case DM:
  337                 frame->control = DM_CONTROL;
  338                 break;
  339 
  340         case UA:
  341                 frame->control = UA_CONTROL;
  342                 break;
  343 
  344         case FRMR:
  345                 frame->control = FRMR_CONTROL;
  346                 bcopy((caddr_t) & hd_frmr, (caddr_t) frame->info, 3);
  347                 buf->m_len = 5;
  348                 hdp->hd_frmrs_out++;
  349 
  350         }
  351 
  352         if (sframe->hdlc_01 == 1) {
  353                 /* Supervisory format - RR, REJ, or RNR. */
  354                 sframe->nr = hdp->hd_vr;
  355                 sframe->pf = pf;
  356                 hdp->hd_lasttxnr = hdp->hd_vr;
  357                 hdp->hd_rrtimer = 0;
  358         } else
  359                 uframe->pf = pf;
  360 
  361         hd_trace(hdp, TX, buf);
  362         buf->m_pkthdr.len = buf->m_len;
  363         (*hdp->hd_output) (buf, hdp, NULL);
  364 }
  365 
  366 struct mbuf *
  367 hd_remove(q)
  368         struct hdtxq   *q;
  369 {
  370         struct mbuf *m;
  371 
  372         m = q->head;
  373         if (m) {
  374                 if ((q->head = m->m_nextpkt) == NULL)
  375                         q->tail = NULL;
  376                 m->m_nextpkt = 0;
  377         }
  378         return (m);
  379 }
  380 
  381 void
  382 hd_append(q, m)
  383         struct hdtxq *q;
  384         struct mbuf *m;
  385 {
  386 
  387         m->m_nextpkt = NULL;
  388         if (q->tail == NULL)
  389                 q->head = m;
  390         else
  391                 q->tail->m_nextpkt = m;
  392         q->tail = m;
  393 }
  394 
  395 void
  396 hd_flush(ifp)
  397         struct ifnet   *ifp;
  398 {
  399         struct mbuf *m;
  400         int    s;
  401 
  402         while (1) {
  403                 s = splnet();
  404                 IF_DEQUEUE(&ifp->if_snd, m);
  405                 splx(s);
  406                 if (m == 0)
  407                         break;
  408                 m_freem(m);
  409         }
  410 }
  411 
  412 void
  413 hd_message(hdp, msg)
  414         struct hdcb    *hdp;
  415         char           *msg;
  416 {
  417         if (hdcbhead->hd_next)
  418                 printf("HDLC(%s): %s\n", format_ntn(hdp->hd_xcp), msg);
  419         else
  420                 printf("HDLC: %s\n", msg);
  421 }
  422 
  423 #ifdef HDLCDEBUG
  424 void
  425 hd_status(hdp)
  426         struct hdcb    *hdp;
  427 {
  428         printf("HDLC STATUS:\n V(S)=%d, V(R)=%d, retxqi=%d,\n",
  429             hdp->hd_vs, hdp->hd_vr, hdp->hd_retxqi);
  430 
  431         printf("Last_rx_nr=%d, Last_tx_nr=%d,\n Condition=%d, Xx=%d\n",
  432             hdp->hd_lastrxnr, hdp->hd_lasttxnr, hdp->hd_condition, hdp->hd_xx);
  433 }
  434 #endif

Cache object: 6d787ff4d26c90e00a688cd20e8ca305


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.