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/netiso/clnp_input.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: clnp_input.c,v 1.31.2.2 2006/12/18 22:58:25 tron Exp $ */
    2 
    3 /*-
    4  * Copyright (c) 1991, 1993
    5  *      The Regents of the University of California.  All rights reserved.
    6  *
    7  * Redistribution and use in source and binary forms, with or without
    8  * modification, are permitted provided that the following conditions
    9  * are met:
   10  * 1. Redistributions of source code must retain the above copyright
   11  *    notice, this list of conditions and the following disclaimer.
   12  * 2. Redistributions in binary form must reproduce the above copyright
   13  *    notice, this list of conditions and the following disclaimer in the
   14  *    documentation and/or other materials provided with the distribution.
   15  * 3. Neither the name of the University nor the names of its contributors
   16  *    may be used to endorse or promote products derived from this software
   17  *    without specific prior written permission.
   18  *
   19  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   20  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   23  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   24  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   25  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   26  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   27  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   28  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   29  * SUCH DAMAGE.
   30  *
   31  *      @(#)clnp_input.c        8.1 (Berkeley) 6/10/93
   32  */
   33 
   34 /***********************************************************
   35                 Copyright IBM Corporation 1987
   36 
   37                       All Rights Reserved
   38 
   39 Permission to use, copy, modify, and distribute this software and its
   40 documentation for any purpose and without fee is hereby granted,
   41 provided that the above copyright notice appear in all copies and that
   42 both that copyright notice and this permission notice appear in
   43 supporting documentation, and that the name of IBM not be
   44 used in advertising or publicity pertaining to distribution of the
   45 software without specific, written prior permission.
   46 
   47 IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
   48 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
   49 IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
   50 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
   51 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
   52 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
   53 SOFTWARE.
   54 
   55 ******************************************************************/
   56 
   57 /*
   58  * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
   59  */
   60 
   61 #include <sys/cdefs.h>
   62 __KERNEL_RCSID(0, "$NetBSD: clnp_input.c,v 1.31.2.2 2006/12/18 22:58:25 tron Exp $");
   63 
   64 #include "opt_iso.h"
   65 
   66 #include <sys/param.h>
   67 #include <sys/mbuf.h>
   68 #include <sys/domain.h>
   69 #include <sys/protosw.h>
   70 #include <sys/socket.h>
   71 #include <sys/socketvar.h>
   72 #include <sys/errno.h>
   73 #include <sys/time.h>
   74 #include <sys/systm.h>
   75 
   76 #include <net/if.h>
   77 #include <net/if_types.h>
   78 #include <net/route.h>
   79 
   80 #include <net/if_ether.h>
   81 #include <net/if_fddi.h>
   82 
   83 #include <net/if_llc.h>
   84 
   85 #include <netiso/iso.h>
   86 #include <netiso/iso_var.h>
   87 #include <netiso/iso_snpac.h>
   88 #include <netiso/clnp.h>
   89 #include <netiso/clnl.h>
   90 #include <netiso/esis.h>
   91 #include <netinet/in_systm.h>
   92 #include <netinet/ip.h>
   93 #include <netiso/eonvar.h>
   94 #include <netiso/clnp_stat.h>
   95 #include <netiso/argo_debug.h>
   96 
   97 #include <machine/stdarg.h>
   98 
   99 #ifdef ISO
  100 u_char          clnp_protox[ISOPROTO_MAX];
  101 struct clnl_protosw clnl_protox[256];
  102 int             clnpqmaxlen = IFQ_MAXLEN;       /* RAH? why is this a
  103                                                  * variable */
  104 #ifdef  ISO_X25ESIS
  105 #if 0
  106 void            x25esis_input();
  107 #endif
  108 #endif                          /* ISO_X25ESIS */
  109 struct iso_ifaddrhead iso_ifaddr = TAILQ_HEAD_INITIALIZER(iso_ifaddr);
  110 struct ifqueue  clnlintrq;
  111 struct clnp_stat clnp_stat;
  112 
  113 /*
  114  * FUNCTION:            clnp_init
  115  *
  116  * PURPOSE:             clnp initialization. Fill in clnp switch tables.
  117  *
  118  * RETURNS:             none
  119  *
  120  * SIDE EFFECTS:        fills in clnp_protox table with correct offsets into
  121  *                      the isosw table.
  122  *
  123  * NOTES:
  124  */
  125 void
  126 clnp_init(void)
  127 {
  128         const struct protosw *pr;
  129 
  130         /*
  131          * CLNP protox initialization
  132          */
  133         if ((pr = pffindproto(PF_ISO, ISOPROTO_RAW, SOCK_RAW)) == 0)
  134                 printf("clnl_init: no raw CLNP\n");
  135         else
  136                 clnp_protox[ISOPROTO_RAW] = pr - isosw;
  137 
  138         if ((pr = pffindproto(PF_ISO, ISOPROTO_TP, SOCK_SEQPACKET)) == 0)
  139                 printf("clnl_init: no tp/clnp\n");
  140         else
  141                 clnp_protox[ISOPROTO_TP] = pr - isosw;
  142 
  143         /*
  144          *      CLNL protox initialization
  145          */
  146         clnl_protox[ISO8473_CLNP].clnl_input = clnp_input;
  147 
  148         clnlintrq.ifq_maxlen = clnpqmaxlen;
  149 }
  150 
  151 /*
  152  * FUNCTION:            clnlintr
  153  *
  154  * PURPOSE:             Process a packet on the clnl input queue
  155  *
  156  * RETURNS:             nothing.
  157  *
  158  * SIDE EFFECTS:
  159  *
  160  * NOTES:
  161  */
  162 void
  163 clnlintr()
  164 {
  165         struct mbuf *m;/* ptr to first mbuf of pkt */
  166         struct clnl_fixed *clnl;        /* ptr to fixed part of clnl
  167                                                  * hdr */
  168         int             s;      /* save and restore priority */
  169         struct clnl_protosw *clnlsw;    /* ptr to protocol switch */
  170         struct snpa_hdr sh;     /* subnetwork hdr */
  171 
  172         /*
  173          *      Get next datagram off clnl input queue
  174          */
  175 next:
  176         s = splnet();
  177         /* IF_DEQUEUESNPAHDR(&clnlintrq, m, sh); */
  178         IF_DEQUEUE(&clnlintrq, m);
  179         splx(s);
  180 
  181 
  182         if (m == 0)             /* nothing to do */
  183                 return;
  184         if ((m->m_flags & M_PKTHDR) == 0 || m->m_pkthdr.rcvif == 0) {
  185                 m_freem(m);
  186                 goto next;
  187         }
  188         bzero((caddr_t) & sh, sizeof(sh));
  189         sh.snh_flags = m->m_flags & (M_MCAST | M_BCAST);
  190         switch ((sh.snh_ifp = m->m_pkthdr.rcvif)->if_type) {
  191         case IFT_EON:
  192                 bcopy(mtod(m, caddr_t), (caddr_t) sh.snh_dhost, sizeof(u_long));
  193                 bcopy(sizeof(u_long) + mtod(m, caddr_t),
  194                       (caddr_t) sh.snh_shost, sizeof(u_long));
  195                 sh.snh_dhost[4] = mtod(m, u_char *)[sizeof(struct ip) +
  196                                      offsetof(struct eon_hdr, eonh_class)];
  197                 m->m_data += EONIPLEN;
  198                 m->m_len -= EONIPLEN;
  199                 m->m_pkthdr.len -= EONIPLEN;
  200                 break;
  201         case IFT_ETHER:
  202                 bcopy((caddr_t) (mtod(m, struct ether_header *)->ether_dhost),
  203                   (caddr_t) sh.snh_dhost, 2 * sizeof(sh.snh_dhost));
  204                 m_adj(m, sizeof(struct ether_header) + LLC_UFRAMELEN);
  205                 break;
  206         case IFT_FDDI:
  207                 bcopy((caddr_t) (mtod(m, struct fddi_header *)->fddi_dhost),
  208                   (caddr_t) sh.snh_dhost, 2 * sizeof(sh.snh_dhost));
  209                 m_adj(m, sizeof(struct fddi_header) + LLC_UFRAMELEN);
  210                 break;
  211         case IFT_PTPSERIAL:
  212         case IFT_GIF:
  213                 /* nothing extra to get from the mbuf */
  214                 bzero((caddr_t)sh.snh_dhost, sizeof(sh.snh_dhost));
  215                 bzero((caddr_t)sh.snh_shost, sizeof(sh.snh_shost));
  216                 break;
  217         default:
  218                 break;
  219         }
  220 #ifdef ARGO_DEBUG
  221         if (argo_debug[D_INPUT]) {
  222                 int             i;
  223                 printf("clnlintr: src:");
  224                 for (i = 0; i < 6; i++)
  225                         printf("%x%c", sh.snh_shost[i] & 0xff,
  226                             (i < 5) ? ':' : ' ');
  227                 printf(" dst:");
  228                 for (i = 0; i < 6; i++)
  229                         printf("%x%c", sh.snh_dhost[i] & 0xff,
  230                             (i < 5) ? ':' : ' ');
  231                 printf("\n");
  232         }
  233 #endif
  234 
  235         /*
  236          * Get the fixed part of the clnl header into the first mbuf.
  237          * Drop the packet if this fails.
  238          * Do not call m_pullup if we have a cluster mbuf or the
  239          * data is not there.
  240          */
  241         if ((IS_CLUSTER(m) || (m->m_len < sizeof(struct clnl_fixed))) &&
  242             ((m = m_pullup(m, sizeof(struct clnl_fixed))) == 0)) {
  243                 INCSTAT(cns_toosmall);  /* TODO: use clnl stats */
  244                 goto next;      /* m_pullup discards mbuf */
  245         }
  246         clnl = mtod(m, struct clnl_fixed *);
  247 
  248         /*
  249          * Drop packet if the length of the header is not reasonable.
  250          */
  251         if ((clnl->cnf_hdr_len < CLNP_HDR_MIN) ||
  252             (clnl->cnf_hdr_len > CLNP_HDR_MAX)) {
  253                 INCSTAT(cns_badhlen);   /* TODO: use clnl stats */
  254                 m_freem(m);
  255                 goto next;
  256         }
  257         /*
  258          *      If the header is not contained in this mbuf, make it so.
  259          *      Drop packet if this fails.
  260          *      Note: m_pullup will allocate a cluster mbuf if necessary
  261          */
  262         if (clnl->cnf_hdr_len > m->m_len) {
  263                 if ((m = m_pullup(m, (int) clnl->cnf_hdr_len)) == 0) {
  264                         INCSTAT(cns_badhlen);   /* TODO: use clnl stats */
  265                         goto next;      /* m_pullup discards mbuf */
  266                 }
  267                 clnl = mtod(m, struct clnl_fixed *);
  268         }
  269         clnlsw = &clnl_protox[clnl->cnf_proto_id];
  270 
  271 
  272         if (clnlsw->clnl_input)
  273                 (*clnlsw->clnl_input) (m, &sh);
  274         else
  275                 m_freem(m);
  276 
  277         goto next;
  278 }
  279 
  280 /*
  281  * FUNCTION:            clnp_input
  282  *
  283  * PURPOSE:             process an incoming clnp packet
  284  *
  285  * RETURNS:             nothing
  286  *
  287  * SIDE EFFECTS:        increments fields of clnp_stat structure.
  288  *
  289  * NOTES:
  290  *      TODO: I would like to make seg_part a pointer into the mbuf, but
  291  *      will it be correctly aligned?
  292  */
  293 void
  294 clnp_input(struct mbuf *m, ...)
  295 {
  296         struct snpa_hdr *shp;   /* subnetwork header */
  297         struct ifaddr *ifa;
  298         struct clnp_fixed *clnp;        /* ptr to fixed part of
  299                                                  * header */
  300         struct sockaddr_iso source;     /* source address of pkt */
  301         struct sockaddr_iso target;     /* destination address of pkt */
  302 #define src     source.siso_addr
  303 #define dst     target.siso_addr
  304         caddr_t         hoff;   /* current offset in packet */
  305         caddr_t         hend;   /* address of end of header info */
  306         struct clnp_segment seg_part;   /* segment part of hdr */
  307         int             seg_off = 0;    /* offset of segment part of hdr */
  308         int             seg_len;/* length of packet data&hdr in bytes */
  309         struct clnp_optidx oidx, *oidxp = NULL; /* option index */
  310         extern int      iso_systype;    /* used by ESIS config resp */
  311         extern struct sockaddr_iso blank_siso;  /* used for initializing */
  312         int             need_afrin = 0;
  313         /* true if congestion experienced */
  314         /* which means you need afrin nose */
  315         /* spray. How clever! */
  316         va_list ap;
  317 
  318         va_start(ap, m);
  319         shp = va_arg(ap, struct snpa_hdr *);
  320         va_end(ap);
  321 
  322         /*
  323          * make sure this interface has a ISO address
  324          */
  325         for (ifa = shp->snh_ifp->if_addrlist.tqh_first; ifa != 0;
  326              ifa = ifa->ifa_list.tqe_next)
  327                 if (ifa->ifa_addr->sa_family == AF_ISO)
  328                         break;
  329         if (ifa == 0) {
  330                 clnp_discard(m, ADDR_DESTUNREACH);
  331                 return;
  332         }
  333 
  334 #ifdef ARGO_DEBUG
  335         if (argo_debug[D_INPUT]) {
  336                 printf(
  337                     "clnp_input: processing dg; First mbuf m_len %d, m_type x%x, %s\n",
  338                     m->m_len, m->m_type, IS_CLUSTER(m) ? "cluster" : "normal");
  339         }
  340 #endif
  341         need_afrin = 0;
  342 
  343         /*
  344          *      If no iso addresses have been set, there is nothing
  345          *      to do with the packet.
  346          */
  347         if (iso_ifaddr.tqh_first == 0) {
  348                 clnp_discard(m, ADDR_DESTUNREACH);
  349                 return;
  350         }
  351         INCSTAT(cns_total);
  352         clnp = mtod(m, struct clnp_fixed *);
  353 
  354 #ifdef ARGO_DEBUG
  355         if (argo_debug[D_DUMPIN]) {
  356                 struct mbuf    *mhead;
  357                 int             total_len = 0;
  358                 printf("clnp_input: clnp header:\n");
  359                 dump_buf(mtod(m, caddr_t), clnp->cnf_hdr_len);
  360                 printf("clnp_input: mbuf chain:\n");
  361                 for (mhead = m; mhead != NULL; mhead = mhead->m_next) {
  362                         printf("m %p, len %d\n", mhead, mhead->m_len);
  363                         total_len += mhead->m_len;
  364                 }
  365                 printf("clnp_input: total length of mbuf chain %d:\n",
  366                 total_len);
  367         }
  368 #endif
  369 
  370         /*
  371          *      Compute checksum (if necessary) and drop packet if
  372          *      checksum does not match
  373          */
  374         if (CKSUM_REQUIRED(clnp) &&
  375             iso_check_csum(m, (int) clnp->cnf_hdr_len)) {
  376                 INCSTAT(cns_badcsum);
  377                 clnp_discard(m, GEN_BADCSUM);
  378                 return;
  379         }
  380         if (clnp->cnf_vers != ISO8473_V1) {
  381                 INCSTAT(cns_badvers);
  382                 clnp_discard(m, DISC_UNSUPPVERS);
  383                 return;
  384         }
  385         /* check mbuf data length: clnp_data_ck will free mbuf upon error */
  386         CTOH(clnp->cnf_seglen_msb, clnp->cnf_seglen_lsb, seg_len);
  387         if ((m = clnp_data_ck(m, seg_len)) == 0)
  388                 return;
  389 
  390         clnp = mtod(m, struct clnp_fixed *);
  391         hend = (caddr_t) clnp + clnp->cnf_hdr_len;
  392 
  393         /*
  394          * extract the source and destination address drop packet on failure
  395          */
  396         source = target = blank_siso;
  397 
  398         hoff = (caddr_t) clnp + sizeof(struct clnp_fixed);
  399         CLNP_EXTRACT_ADDR(dst, hoff, hend);
  400         if (hoff == (caddr_t) 0) {
  401                 INCSTAT(cns_badaddr);
  402                 clnp_discard(m, GEN_INCOMPLETE);
  403                 return;
  404         }
  405         CLNP_EXTRACT_ADDR(src, hoff, hend);
  406         if (hoff == (caddr_t) 0) {
  407                 INCSTAT(cns_badaddr);
  408                 clnp_discard(m, GEN_INCOMPLETE);
  409                 return;
  410         }
  411 #ifdef ARGO_DEBUG
  412         if (argo_debug[D_INPUT]) {
  413                 printf("clnp_input: from %s", clnp_iso_addrp(&src));
  414                 printf(" to %s\n", clnp_iso_addrp(&dst));
  415         }
  416 #endif
  417 
  418         /*
  419          * extract the segmentation information, if it is present.
  420          * drop packet on failure
  421          */
  422         if (((clnp->cnf_type & CNF_TYPE) != CLNP_ER) &&
  423             (clnp->cnf_type & CNF_SEG_OK)) {
  424                 if (hoff + sizeof(struct clnp_segment) > hend) {
  425                         INCSTAT(cns_noseg);
  426                         clnp_discard(m, GEN_INCOMPLETE);
  427                         return;
  428                 } else {
  429                         (void) bcopy(hoff, (caddr_t) & seg_part,
  430                                      sizeof(struct clnp_segment));
  431                         /* make sure segmentation fields are in host order */
  432                         seg_part.cng_id = ntohs(seg_part.cng_id);
  433                         seg_part.cng_off = ntohs(seg_part.cng_off);
  434                         seg_part.cng_tot_len = ntohs(seg_part.cng_tot_len);
  435                         seg_off = hoff - (caddr_t) clnp;
  436                         hoff += sizeof(struct clnp_segment);
  437                 }
  438         }
  439         /*
  440          * process options if present. If clnp_opt_sanity returns
  441          * false (indicating an error was found in the options) or
  442          * an unsupported option was found
  443          * then drop packet and emit an ER.
  444          */
  445         if (hoff < hend) {
  446                 int             errcode;
  447 
  448                 oidxp = &oidx;
  449                 errcode = clnp_opt_sanity(m, hoff, hend - hoff, oidxp);
  450 
  451                 /* we do not support security */
  452                 if ((errcode == 0) && (oidxp->cni_securep))
  453                         errcode = DISC_UNSUPPSECURE;
  454 
  455                 /* the er option is valid with ER pdus only */
  456                 if ((errcode == 0) && (oidxp->cni_er_reason != ER_INVALREAS) &&
  457                     ((clnp->cnf_type & CNF_TYPE) != CLNP_ER))
  458                         errcode = DISC_UNSUPPOPT;
  459 
  460 #ifdef  DECBIT
  461                 /* check if the congestion experienced bit is set */
  462                 if (oidxp->cni_qos_formatp) {
  463                         caddr_t         qosp = CLNP_OFFTOOPT(m, oidxp->cni_qos_formatp);
  464                         u_char          qos = *qosp;
  465 
  466                         need_afrin = ((qos & (CLNPOVAL_GLOBAL | CLNPOVAL_CONGESTED)) ==
  467                                     (CLNPOVAL_GLOBAL | CLNPOVAL_CONGESTED));
  468                         if (need_afrin)
  469                                 INCSTAT(cns_congest_rcvd);
  470                 }
  471 #endif                          /* DECBIT */
  472 
  473                 if (errcode != 0) {
  474                         clnp_discard(m, (char) errcode);
  475 #ifdef ARGO_DEBUG
  476                         if (argo_debug[D_INPUT]) {
  477                                 printf(
  478                                     "clnp_input: dropped (err x%x) due to bad options\n",
  479                                     errcode);
  480                         }
  481 #endif
  482                         return;
  483                 }
  484         }
  485         /*
  486          *      check if this packet is for us. if not, then forward
  487          */
  488         if (clnp_ours(&dst) == 0) {
  489 #ifdef ARGO_DEBUG
  490                 if (argo_debug[D_INPUT]) {
  491                         printf("clnp_input: forwarding packet not for us\n");
  492                 }
  493 #endif
  494                 clnp_forward(m, seg_len, &dst, oidxp, seg_off, shp);
  495                 return;
  496         }
  497         /*
  498          *      ESIS Configuration Response Function
  499          *
  500          *      If the packet received was sent to the multicast address
  501          *      all end systems, then send an esh to the source
  502          */
  503         if ((shp->snh_flags & M_MCAST) && (iso_systype == SNPA_ES)) {
  504                 extern short    esis_holding_time;
  505 
  506                 esis_shoutput(shp->snh_ifp, ESIS_ESH, esis_holding_time,
  507                               shp->snh_shost, 6, &dst);
  508         }
  509         /*
  510          * If this is a fragment, then try to reassemble it. If clnp_reass
  511          * returns non NULL, the packet has been reassembled, and should
  512          * be give to TP. Otherwise the fragment has been delt with
  513          * by the reassembly code (either stored or deleted). In either case
  514          * we should have nothing more to do with it.
  515          */
  516         if (((clnp->cnf_type & CNF_TYPE) != CLNP_ER) &&
  517             (clnp->cnf_type & CNF_SEG_OK) &&
  518             (seg_len != seg_part.cng_tot_len)) {
  519                 struct mbuf    *m0;
  520 
  521                 if ((m0 = clnp_reass(m, &src, &dst, &seg_part)) != NULL) {
  522                         m = m0;
  523                         clnp = mtod(m, struct clnp_fixed *);
  524                         INCSTAT(cns_reassembled);
  525                 } else {
  526                         return;
  527                 }
  528         }
  529         /*
  530          *      give the packet to the higher layer
  531          *
  532          *      Note: the total length of packet
  533          *      is the total length field of the segmentation part,
  534          *      or, if absent, the segment length field of the
  535          *      header.
  536          */
  537         INCSTAT(cns_delivered);
  538         switch (clnp->cnf_type & CNF_TYPE) {
  539         case CLNP_ER:
  540                 /*
  541                  *      This ER must have the er option.
  542                  *      If the option is not present, discard datagram.
  543                  */
  544                 if (oidxp == NULL || oidxp->cni_er_reason == ER_INVALREAS) {
  545                         clnp_discard(m, GEN_HDRSYNTAX);
  546                 } else {
  547                         clnp_er_input(m, &src, oidxp->cni_er_reason);
  548                 }
  549                 break;
  550         case CLNP_DT:
  551                 (*isosw[clnp_protox[ISOPROTO_TP]].pr_input)(m, &source, &target,
  552                                              clnp->cnf_hdr_len, need_afrin);
  553                 break;
  554         case CLNP_RAW:
  555         case CLNP_ECR:
  556 #ifdef ARGO_DEBUG
  557                 if (argo_debug[D_INPUT]) {
  558                         printf("clnp_input: raw input of %d bytes\n",
  559                             clnp->cnf_type & CNF_SEG_OK ?
  560                             seg_part.cng_tot_len : seg_len);
  561                 }
  562 #endif
  563                 (*isosw[clnp_protox[ISOPROTO_RAW]].pr_input)(m, &source,
  564                                                              &target,
  565                                                          clnp->cnf_hdr_len);
  566                 break;
  567 
  568         case CLNP_EC:
  569 #ifdef ARGO_DEBUG
  570                 if (argo_debug[D_INPUT]) {
  571                         printf("clnp_input: echoing packet\n");
  572                 }
  573 #endif
  574                 (void) clnp_echoreply(m, (clnp->cnf_type & CNF_SEG_OK ?
  575                                       (int) seg_part.cng_tot_len : seg_len),
  576                                       &source, &target, oidxp);
  577                 break;
  578 
  579         default:
  580                 printf("clnp_input: unknown clnp pkt type %d\n",
  581                     clnp->cnf_type & CNF_TYPE);
  582                 clnp_stat.cns_delivered--;
  583                 clnp_stat.cns_noproto++;
  584                 clnp_discard(m, GEN_HDRSYNTAX);
  585                 break;
  586         }
  587 }
  588 #endif                          /* ISO */

Cache object: f3e49a437eb87ef04529f83fa3ced056


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