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/net/if_spppfr.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 /*-
    2  * Synchronous Frame Relay link level subroutines.
    3  * ANSI T1.617-compaible link management signaling
    4  * implemented for Frame Relay mode.
    5  * Cisco-type Frame Relay framing added, thanks Alex Tutubalin.
    6  * Only one DLCI per channel for now.
    7  *
    8  * Copyright (C) 1994-2000 Cronyx Engineering.
    9  * Author: Serge Vakulenko, <vak@cronyx.ru>
   10  *
   11  * Copyright (C) 1999-2004 Cronyx Engineering.
   12  * Author: Kurakin Roman, <rik@cronyx.ru>
   13  *
   14  * This software is distributed with NO WARRANTIES, not even the implied
   15  * warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
   16  *
   17  * Authors grant any other persons or organisations a permission to use,
   18  * modify and redistribute this software in source and binary forms,
   19  * as long as this message is kept with the software, all derivative
   20  * works or modified versions.
   21  *
   22  * $Cronyx Id: if_spppfr.c,v 1.1.2.10 2004/06/29 09:02:30 rik Exp $
   23  * $FreeBSD: releng/12.0/sys/net/if_spppfr.c 271867 2014-09-19 10:39:58Z glebius $
   24  */
   25 
   26 #include <sys/param.h>
   27 
   28 #if defined(__FreeBSD__)
   29 #include "opt_inet.h"
   30 #include "opt_inet6.h"
   31 #endif
   32 
   33 #ifdef NetBSD1_3
   34 #  if NetBSD1_3 > 6
   35 #      include "opt_inet.h"
   36 #      include "opt_inet6.h"
   37 #      include "opt_iso.h"
   38 #  endif
   39 #endif
   40 
   41 #include <sys/systm.h>
   42 #include <sys/kernel.h>
   43 #include <sys/module.h>
   44 #include <sys/sockio.h>
   45 #include <sys/socket.h>
   46 #include <sys/syslog.h>
   47 #if defined(__FreeBSD__)
   48 #include <sys/random.h>
   49 #endif
   50 #include <sys/malloc.h>
   51 #include <sys/mbuf.h>
   52 
   53 #if defined (__OpenBSD__)
   54 #include <sys/md5k.h>
   55 #else
   56 #include <sys/md5.h>
   57 #endif
   58 
   59 #include <net/if.h>
   60 #include <net/if_var.h>
   61 #include <net/netisr.h>
   62 #include <net/if_types.h>
   63 #include <net/route.h>
   64 #include <netinet/in.h>
   65 #include <netinet/in_systm.h>
   66 #include <netinet/ip.h>
   67 #include <net/slcompress.h>
   68 
   69 #if defined (__NetBSD__) || defined (__OpenBSD__)
   70 #include <machine/cpu.h> /* XXX for softnet */
   71 #endif
   72 
   73 #include <machine/stdarg.h>
   74 
   75 #include <netinet/in_var.h>
   76 #ifdef INET
   77 #include <netinet/ip.h>
   78 #include <netinet/tcp.h>
   79 #endif
   80 
   81 #if defined (__FreeBSD__) || defined (__OpenBSD__)
   82 #  include <netinet/if_ether.h>
   83 #else
   84 #  include <net/ethertypes.h>
   85 #endif
   86 
   87 #include <net/if_sppp.h>
   88 
   89 /*
   90  * Frame Relay.
   91  */
   92 #define FR_UI           0x03    /* Unnumbered Information */
   93 #define FR_IP           0xCC    /* IP protocol identifier */
   94 #define FR_PADDING      0x00    /* NLPID padding */
   95 #define FR_SIGNALING    0x08    /* Q.933/T1.617 signaling identifier */
   96 #define FR_SNAP         0x80    /* NLPID snap */
   97 
   98 /*
   99  * Header flags.
  100  */
  101 #define FR_DE           0x02    /* discard eligibility */
  102 #define FR_FECN         0x04    /* forward notification */
  103 #define FR_BECN         0x08    /* backward notification */
  104 
  105 /*
  106  * Signaling message types.
  107  */
  108 #define FR_MSG_ENQUIRY  0x75    /* status enquiry */
  109 #define FR_MSG_STATUS   0x7d    /* status */
  110 
  111 #define FR_ENQUIRY_SIZE 14
  112 
  113 /*
  114  * Message field types.
  115  */
  116 #define FR_FLD_RTYPE    0x01    /* report type */
  117 #define FR_FLD_VERIFY   0x03    /* link verification */
  118 #define FR_FLD_PVC      0x07    /* PVC status */
  119 #define FR_FLD_LSHIFT5  0x95    /* locking shift 5 */
  120 
  121 /*
  122  * Report types.
  123  */
  124 #define FR_RTYPE_FULL   0       /* full status */
  125 #define FR_RTYPE_SHORT  1       /* link verification only */
  126 #define FR_RTYPE_SINGLE 2       /* single PVC status */
  127 
  128 /* PVC status field. */
  129 #define FR_DLCI_DELETE  0x04    /* PVC is deleted */
  130 #define FR_DLCI_ACTIVE  0x02    /* PVC is operational */
  131 #define FR_DLCI_NEW     0x08    /* PVC is new */
  132 
  133 struct arp_req {
  134         unsigned short  htype;          /* hardware type = ARPHRD_FRELAY */
  135         unsigned short  ptype;          /* protocol type = ETHERTYPE_IP */
  136         unsigned char   halen;          /* hardware address length = 2 */
  137         unsigned char   palen;          /* protocol address length = 4 */
  138         unsigned short  op;             /* ARP/RARP/InARP request/reply */
  139         unsigned short  hsource;        /* hardware source address */
  140         unsigned short  psource1;       /* protocol source */
  141         unsigned short  psource2;
  142         unsigned short  htarget;        /* hardware target address */
  143         unsigned short  ptarget1;       /* protocol target */
  144         unsigned short  ptarget2;
  145 } __packed;
  146 
  147 #if defined(__FreeBSD__) && __FreeBSD_version < 501113
  148 #define SPP_FMT         "%s%d: "
  149 #define SPP_ARGS(ifp)   (ifp)->if_name, (ifp)->if_unit
  150 #else
  151 #define SPP_FMT         "%s: "
  152 #define SPP_ARGS(ifp)   (ifp)->if_xname
  153 #endif
  154 
  155 /* almost every function needs these */
  156 #define STDDCL                                                  \
  157         struct ifnet *ifp = SP2IFP(sp);                         \
  158         int debug = ifp->if_flags & IFF_DEBUG
  159 
  160 static void sppp_fr_arp (struct sppp *sp, struct arp_req *req, u_short addr);
  161 static void sppp_fr_signal (struct sppp *sp, unsigned char *h, int len);
  162 
  163 void sppp_fr_input (struct sppp *sp, struct mbuf *m)
  164 {
  165         STDDCL;
  166         u_char *h = mtod (m, u_char*);
  167         int isr = -1;
  168         int dlci, hlen, proto;
  169 
  170         /* Get the DLCI number. */
  171         if (m->m_pkthdr.len < 10) {
  172 bad:            m_freem (m);
  173                 return;
  174         }
  175         dlci = (h[0] << 2 & 0x3f0) | (h[1] >> 4 & 0x0f);
  176 
  177         /* Process signaling packets. */
  178         if (dlci == 0) {
  179                 sppp_fr_signal (sp, h, m->m_pkthdr.len);
  180                 m_freem (m);
  181                 return;
  182         }
  183 
  184         if (dlci != sp->fr_dlci) {
  185                 if (debug)
  186                         printf (SPP_FMT "Received packet from invalid DLCI %d\n",
  187                                 SPP_ARGS(ifp), dlci);
  188                 goto bad;
  189         }
  190 
  191         /* Process the packet. */
  192         if (ntohs (*(short*) (h+2)) == ETHERTYPE_IP) {
  193                 /* Prehistoric IP framing? */
  194                 h[2] = FR_UI;
  195                 h[3] = FR_IP;
  196         }
  197         if (h[2] != FR_UI) {
  198                 if (debug)
  199                         printf (SPP_FMT "Invalid frame relay header flag 0x%02x\n",
  200                                 SPP_ARGS(ifp), h[2]);
  201                 goto bad;
  202         }
  203         switch (h[3]) {
  204         default:
  205                 if (debug)
  206                         printf (SPP_FMT "Unsupported NLPID 0x%02x\n",
  207                                 SPP_ARGS(ifp), h[3]);
  208                 goto bad;
  209 
  210         case FR_PADDING:
  211                 if (h[4] != FR_SNAP) {
  212                         if (debug)
  213                                 printf (SPP_FMT "Bad NLPID 0x%02x\n",
  214                                         SPP_ARGS(ifp), h[4]);
  215                         goto bad;
  216                 }
  217                 if (h[5] || h[6] || h[7]) {
  218                         if (debug)
  219                                 printf (SPP_FMT "Bad OID 0x%02x-0x%02x-0x%02x\n",
  220                                         SPP_ARGS(ifp),
  221                                         h[5], h[6], h[7]);
  222                         goto bad;
  223                 }
  224                 proto = ntohs (*(short*) (h+8));
  225                 if (proto == ETHERTYPE_ARP) {
  226                         /* Process the ARP request. */
  227                         if (m->m_pkthdr.len != 10 + sizeof (struct arp_req)) {
  228                                 if (debug)
  229                                         printf (SPP_FMT "Bad ARP request size = %d bytes\n",
  230                                                 SPP_ARGS(ifp),
  231                                                 m->m_pkthdr.len);
  232                                 goto bad;
  233                         }
  234                         sppp_fr_arp (sp, (struct arp_req*) (h + 10),
  235                                 h[0] << 8 | h[1]);
  236                         m_freem (m);
  237                         return;
  238                 }
  239                 hlen = 10;
  240                 break;
  241 
  242         case FR_IP:
  243                 proto = ETHERTYPE_IP;
  244                 hlen = 4;
  245                 break;
  246         }
  247 
  248         /* Remove frame relay header. */
  249         m_adj (m, hlen);
  250 
  251         switch (proto) {
  252         default:
  253                 if_inc_counter(ifp, IFCOUNTER_NOPROTO, 1);
  254 drop:           if_inc_counter(ifp, IFCOUNTER_IERRORS, 1);
  255                 if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1);
  256                 m_freem (m);
  257                 return;
  258 #ifdef INET
  259         case ETHERTYPE_IP:
  260                 isr = NETISR_IP;
  261                 break;
  262 #endif
  263         }
  264 
  265         if (! (ifp->if_flags & IFF_UP))
  266                 goto drop;
  267 
  268         M_SETFIB(m, ifp->if_fib);
  269 
  270         /* Check queue. */
  271         if (netisr_queue(isr, m)) {     /* (0) on success. */
  272                 if (debug)
  273                         log(LOG_DEBUG, SPP_FMT "protocol queue overflow\n",
  274                                 SPP_ARGS(ifp));
  275         }
  276 }
  277 
  278 /*
  279  * Add the frame relay header to the packet.
  280  * For IP the header length is 4 bytes,
  281  * for all other protocols - 10 bytes (RFC 1490).
  282  */
  283 struct mbuf *sppp_fr_header (struct sppp *sp, struct mbuf *m,
  284         int family)
  285 {
  286         STDDCL;
  287         u_char *h;
  288         int type, hlen;
  289 
  290         /* Prepend the space for Frame Relay header. */
  291         hlen = (family == AF_INET) ? 4 : 10;
  292         M_PREPEND (m, hlen, M_NOWAIT);
  293         if (! m)
  294                 return 0;
  295         h = mtod (m, u_char*);
  296 
  297         /* Fill the header. */
  298         h[0] = sp->fr_dlci >> 2 & 0xfc;
  299         h[1] = sp->fr_dlci << 4 | 1;
  300         h[2] = FR_UI;
  301 
  302         switch (family) {
  303         default:
  304                 if (debug)
  305                         printf (SPP_FMT "Cannot handle address family %d\n",
  306                                 SPP_ARGS(ifp), family);
  307                 m_freem (m);
  308                 return 0;
  309 #ifdef INET
  310         case AF_INET:
  311 #if 0 /* Crashes on fragmented packets */
  312                 /*
  313                  * Set the discard eligibility bit, if:
  314                  * 1) no fragmentation
  315                  * 2) length > 400 bytes
  316                  * 3a) the protocol is UDP or
  317                  * 3b) TCP data (no control bits)
  318                  */
  319                 {
  320                 struct ip *ip = (struct ip*) (h + hlen);
  321                 struct tcphdr *tcp = (struct tcphdr*) ((long*)ip + ip->ip_hl);
  322 
  323                 if (! (ip->ip_off & ~IP_DF) && ip->ip_len > 400 &&
  324                     (ip->ip_p == IPPROTO_UDP ||
  325                     ip->ip_p == IPPROTO_TCP && ! tcp->th_flags))
  326                         h[1] |= FR_DE;
  327                 }
  328 #endif
  329                 h[3] = FR_IP;
  330                 return m;
  331 #endif
  332 #ifdef NS
  333         case AF_NS:
  334                 type = 0x8137;
  335                 break;
  336 #endif
  337         }
  338         h[3] = FR_PADDING;
  339         h[4] = FR_SNAP;
  340         h[5] = 0;
  341         h[6] = 0;
  342         h[7] = 0;
  343         *(short*) (h+8) = htons(type);
  344         return m;
  345 }
  346 
  347 /*
  348  * Send periodical frame relay link verification messages via DLCI 0.
  349  * Called every 10 seconds (default value of T391 timer is 10 sec).
  350  * Every 6-th message is a full status request
  351  * (default value of N391 counter is 6).
  352  */
  353 void sppp_fr_keepalive (struct sppp *sp)
  354 {
  355         STDDCL;
  356         unsigned char *h, *p;
  357         struct mbuf *m;
  358 
  359         MGETHDR (m, M_NOWAIT, MT_DATA);
  360         if (! m)
  361                 return;
  362         m->m_pkthdr.rcvif = 0;
  363 
  364         h = mtod (m, u_char*);
  365         p = h;
  366         *p++ = 0;                       /* DLCI = 0 */
  367         *p++ = 1;
  368         *p++ = FR_UI;
  369         *p++ = FR_SIGNALING;            /* NLPID = UNI call control */
  370 
  371         *p++ = 0;                       /* call reference length = 0 */
  372         *p++ = FR_MSG_ENQUIRY;          /* message type = status enquiry */
  373 
  374         *p++ = FR_FLD_LSHIFT5;          /* locking shift 5 */
  375 
  376         *p++ = FR_FLD_RTYPE;            /* report type field */
  377         *p++ = 1;                       /* report type length = 1 */
  378         if (sp->pp_seq[IDX_LCP] % 6)
  379                 *p++ = FR_RTYPE_SHORT;  /* link verification only */
  380         else
  381                 *p++ = FR_RTYPE_FULL;   /* full status needed */
  382 
  383         if (sp->pp_seq[IDX_LCP] >= 255)
  384                 sp->pp_seq[IDX_LCP] = 0;
  385         *p++ = FR_FLD_VERIFY;           /* link verification type field */
  386         *p++ = 2;                       /* link verification field length = 2 */
  387         *p++ = ++sp->pp_seq[IDX_LCP];   /* our sequence number */
  388         *p++ = sp->pp_rseq[IDX_LCP];    /* last received sequence number */
  389 
  390         m->m_pkthdr.len = m->m_len = p - h;
  391         if (debug)
  392                 printf (SPP_FMT "send lmi packet, seq=%d, rseq=%d\n",
  393                         SPP_ARGS(ifp), (u_char) sp->pp_seq[IDX_LCP],
  394                         (u_char) sp->pp_rseq[IDX_LCP]);
  395 
  396         if (! IF_HANDOFF_ADJ(&sp->pp_cpq, m, ifp, 3))
  397                 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
  398 }
  399 
  400 /*
  401  * Process the frame relay Inverse ARP request.
  402  */
  403 static void sppp_fr_arp (struct sppp *sp, struct arp_req *req,
  404         u_short his_hardware_address)
  405 {
  406         STDDCL;
  407         struct mbuf *m;
  408         struct arp_req *reply;
  409         u_char *h;
  410         u_short my_hardware_address;
  411         u_long his_ip_address, my_ip_address;
  412 
  413         if ((ntohs (req->htype) != ARPHRD_FRELAY ||
  414             ntohs (req->htype) != 16) || /* for BayNetworks routers */
  415             ntohs (req->ptype) != ETHERTYPE_IP) {
  416                 if (debug)
  417                         printf (SPP_FMT "Invalid ARP hardware/protocol type = 0x%x/0x%x\n",
  418                                 SPP_ARGS(ifp),
  419                                 ntohs (req->htype), ntohs (req->ptype));
  420                 return;
  421         }
  422         if (req->halen != 2 || req->palen != 4) {
  423                 if (debug)
  424                         printf (SPP_FMT "Invalid ARP hardware/protocol address length = %d/%d\n",
  425                                 SPP_ARGS(ifp),
  426                                 req->halen, req->palen);
  427                 return;
  428         }
  429         switch (ntohs (req->op)) {
  430         default:
  431                 if (debug)
  432                         printf (SPP_FMT "Invalid ARP op = 0x%x\n",
  433                                 SPP_ARGS(ifp), ntohs (req->op));
  434                 return;
  435 
  436         case ARPOP_INVREPLY:
  437                 /* Ignore. */
  438                 return;
  439 
  440         case ARPOP_INVREQUEST:
  441                 my_hardware_address = ntohs (req->htarget);
  442                 his_ip_address = ntohs (req->psource1) << 16 |
  443                         ntohs (req->psource2);
  444                 my_ip_address = ntohs (req->ptarget1) << 16 |
  445                         ntohs (req->ptarget2);
  446                 break;
  447         }
  448         if (debug)
  449                 printf (SPP_FMT "got ARP request, source=0x%04x/%d.%d.%d.%d, target=0x%04x/%d.%d.%d.%d\n",
  450                         SPP_ARGS(ifp), ntohs (req->hsource),
  451                         (unsigned char) (his_ip_address >> 24),
  452                         (unsigned char) (his_ip_address >> 16),
  453                         (unsigned char) (his_ip_address >> 8),
  454                         (unsigned char) his_ip_address,
  455                         my_hardware_address,
  456                         (unsigned char) (my_ip_address >> 24),
  457                         (unsigned char) (my_ip_address >> 16),
  458                         (unsigned char) (my_ip_address >> 8),
  459                         (unsigned char) my_ip_address);
  460 
  461         sppp_get_ip_addrs (sp, &my_ip_address, 0, 0);
  462         if (! my_ip_address)
  463                 return;         /* nothing to reply */
  464 
  465         if (debug)
  466                 printf (SPP_FMT "send ARP reply, source=0x%04x/%d.%d.%d.%d, target=0x%04x/%d.%d.%d.%d\n",
  467                         SPP_ARGS(ifp), my_hardware_address,
  468                         (unsigned char) (my_ip_address >> 24),
  469                         (unsigned char) (my_ip_address >> 16),
  470                         (unsigned char) (my_ip_address >> 8),
  471                         (unsigned char) my_ip_address,
  472                         his_hardware_address,
  473                         (unsigned char) (his_ip_address >> 24),
  474                         (unsigned char) (his_ip_address >> 16),
  475                         (unsigned char) (his_ip_address >> 8),
  476                         (unsigned char) his_ip_address);
  477 
  478         /* Send the Inverse ARP reply. */
  479         MGETHDR (m, M_NOWAIT, MT_DATA);
  480         if (! m)
  481                 return;
  482         m->m_pkthdr.len = m->m_len = 10 + sizeof (*reply);
  483         m->m_pkthdr.rcvif = 0;
  484 
  485         h = mtod (m, u_char*);
  486         reply = (struct arp_req*) (h + 10);
  487 
  488         h[0] = his_hardware_address >> 8;
  489         h[1] = his_hardware_address;
  490         h[2] = FR_UI;
  491         h[3] = FR_PADDING;
  492         h[4] = FR_SNAP;
  493         h[5] = 0;
  494         h[6] = 0;
  495         h[7] = 0;
  496         *(short*) (h+8) = htons (ETHERTYPE_ARP);
  497 
  498         reply->htype    = htons (ARPHRD_FRELAY);
  499         reply->ptype    = htons (ETHERTYPE_IP);
  500         reply->halen    = 2;
  501         reply->palen    = 4;
  502         reply->op       = htons (ARPOP_INVREPLY);
  503         reply->hsource  = htons (my_hardware_address);
  504         reply->psource1 = htonl (my_ip_address);
  505         reply->psource2 = htonl (my_ip_address) >> 16;
  506         reply->htarget  = htons (his_hardware_address);
  507         reply->ptarget1 = htonl (his_ip_address);
  508         reply->ptarget2 = htonl (his_ip_address) >> 16;
  509 
  510         if (! IF_HANDOFF_ADJ(&sp->pp_cpq, m, ifp, 3))
  511                 if_inc_counter(ifp, IFCOUNTER_OERRORS, 1);
  512 }
  513 
  514 /*
  515  * Process the input signaling packet (DLCI 0).
  516  * The implemented protocol is ANSI T1.617 Annex D.
  517  */
  518 static void sppp_fr_signal (struct sppp *sp, unsigned char *h, int len)
  519 {
  520         STDDCL;
  521         u_char *p;
  522         int dlci;
  523 
  524         if (h[2] != FR_UI || h[3] != FR_SIGNALING || h[4] != 0) {
  525                 if (debug)
  526                         printf (SPP_FMT "Invalid signaling header\n",
  527                                 SPP_ARGS(ifp));
  528 bad:            if (debug) {
  529                         printf ("%02x", *h++);
  530                         while (--len > 0)
  531                                 printf ("-%02x", *h++);
  532                         printf ("\n");
  533                 }
  534                 return;
  535         }
  536         if (h[5] == FR_MSG_ENQUIRY) {
  537                 if (len == FR_ENQUIRY_SIZE &&
  538                     h[12] == (u_char) sp->pp_seq[IDX_LCP]) {
  539                         sp->pp_seq[IDX_LCP] = random();
  540                         printf (SPP_FMT "loopback detected\n",
  541                                 SPP_ARGS(ifp));
  542                 }
  543                 return;
  544         }
  545         if (h[5] != FR_MSG_STATUS) {
  546                 if (debug)
  547                         printf (SPP_FMT "Unknown signaling message: 0x%02x\n",
  548                                 SPP_ARGS(ifp), h[5]);
  549                 goto bad;
  550         }
  551 
  552         /* Parse message fields. */
  553         for (p=h+6; p<h+len; ) {
  554                 switch (*p) {
  555                 default:
  556                         if (debug)
  557                                 printf (SPP_FMT "Unknown signaling field 0x%x\n",
  558                                         SPP_ARGS(ifp), *p);
  559                         break;
  560                 case FR_FLD_LSHIFT5:
  561                 case FR_FLD_RTYPE:
  562                         /* Ignore. */
  563                         break;
  564                 case FR_FLD_VERIFY:
  565                         if (p[1] != 2) {
  566                                 if (debug)
  567                                         printf (SPP_FMT "Invalid signaling verify field length %d\n",
  568                                                 SPP_ARGS(ifp), p[1]);
  569                                 break;
  570                         }
  571                         sp->pp_rseq[IDX_LCP] = p[2];
  572                         if (debug) {
  573                                 printf (SPP_FMT "got lmi reply rseq=%d, seq=%d",
  574                                         SPP_ARGS(ifp), p[2], p[3]);
  575                                 if (p[3] != (u_char) sp->pp_seq[IDX_LCP])
  576                                         printf (" (really %d)",
  577                                                 (u_char) sp->pp_seq[IDX_LCP]);
  578                                 printf ("\n");
  579                         }
  580                         break;
  581                 case FR_FLD_PVC:
  582                         if (p[1] < 3) {
  583                                 if (debug)
  584                                         printf (SPP_FMT "Invalid PVC status length %d\n",
  585                                                 SPP_ARGS(ifp), p[1]);
  586                                 break;
  587                         }
  588                         dlci = (p[2] << 4 & 0x3f0) | (p[3] >> 3 & 0x0f);
  589                         if (! sp->fr_dlci)
  590                                 sp->fr_dlci = dlci;
  591                         if (sp->fr_status != p[4])
  592                                 printf (SPP_FMT "DLCI %d %s%s\n",
  593                                         SPP_ARGS(ifp), dlci,
  594                                         p[4] & FR_DLCI_DELETE ? "deleted" :
  595                                         p[4] & FR_DLCI_ACTIVE ? "active" : "passive",
  596                                         p[4] & FR_DLCI_NEW ? ", new" : "");
  597                         sp->fr_status = p[4];
  598                         break;
  599                 }
  600                 if (*p & 0x80)
  601                         ++p;
  602                 else if (p < h+len+1 && p[1])
  603                         p += 2 + p[1];
  604                 else {
  605                         if (debug)
  606                                 printf (SPP_FMT "Invalid signaling field 0x%x\n",
  607                                         SPP_ARGS(ifp), *p);
  608                         goto bad;
  609                 }
  610         }
  611 }

Cache object: 074dd94198741cfa1a62ef81cea8bfd2


[ 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.