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-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

    1 /*      $NetBSD: clnp_input.c,v 1.37 2009/03/18 10:22:44 cegger 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.37 2009/03/18 10:22:44 cegger 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(void)
  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         memset(&sh, 0, 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                 (void)memcpy(sh.snh_dhost, mtod(m, char *), sizeof(u_long));
  193                 (void)memcpy(sh.snh_shost, sizeof(u_long) + mtod(m, char *),
  194                      sizeof(u_long));
  195                 sh.snh_dhost[4] = mtod(m, u_char *)[sizeof(struct ip) +
  196                                      offsetof(struct eon_hdr, eonh_class)];
  197                 m_adj(m, EONIPLEN);
  198                 break;
  199         case IFT_ETHER:
  200                 (void)memcpy(sh.snh_dhost,
  201                     mtod(m, struct ether_header *)->ether_dhost,
  202                     2 * sizeof(sh.snh_dhost));
  203                 m_adj(m, sizeof(struct ether_header) + LLC_UFRAMELEN);
  204                 break;
  205         case IFT_FDDI:
  206                 (void)memcpy(sh.snh_dhost,
  207                     mtod(m, struct fddi_header *)->fddi_dhost,
  208                     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                 memset(sh.snh_dhost, 0, sizeof(sh.snh_dhost));
  215                 memset(sh.snh_shost, 0, 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         char *hoff;     /* current offset in packet */
  305         char *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         IFADDR_FOREACH(ifa, shp->snh_ifp)
  326                 if (ifa->ifa_addr->sa_family == AF_ISO)
  327                         break;
  328         if (ifa == 0) {
  329                 clnp_discard(m, ADDR_DESTUNREACH);
  330                 return;
  331         }
  332 
  333 #ifdef ARGO_DEBUG
  334         if (argo_debug[D_INPUT]) {
  335                 printf(
  336                     "clnp_input: processing dg; First mbuf m_len %d, m_type x%x, %s\n",
  337                     m->m_len, m->m_type, IS_CLUSTER(m) ? "cluster" : "normal");
  338         }
  339 #endif
  340         need_afrin = 0;
  341 
  342         /*
  343          *      If no iso addresses have been set, there is nothing
  344          *      to do with the packet.
  345          */
  346         if (iso_ifaddr.tqh_first == 0) {
  347                 clnp_discard(m, ADDR_DESTUNREACH);
  348                 return;
  349         }
  350         INCSTAT(cns_total);
  351         clnp = mtod(m, struct clnp_fixed *);
  352 
  353 #ifdef ARGO_DEBUG
  354         if (argo_debug[D_DUMPIN]) {
  355                 struct mbuf    *mhead;
  356                 int             total_len = 0;
  357                 printf("clnp_input: clnp header:\n");
  358                 dump_buf(mtod(m, void *), clnp->cnf_hdr_len);
  359                 printf("clnp_input: mbuf chain:\n");
  360                 for (mhead = m; mhead != NULL; mhead = mhead->m_next) {
  361                         printf("m %p, len %d\n", mhead, mhead->m_len);
  362                         total_len += mhead->m_len;
  363                 }
  364                 printf("clnp_input: total length of mbuf chain %d:\n",
  365                 total_len);
  366         }
  367 #endif
  368 
  369         /*
  370          *      Compute checksum (if necessary) and drop packet if
  371          *      checksum does not match
  372          */
  373         if (CKSUM_REQUIRED(clnp) &&
  374             iso_check_csum(m, (int) clnp->cnf_hdr_len)) {
  375                 INCSTAT(cns_badcsum);
  376                 clnp_discard(m, GEN_BADCSUM);
  377                 return;
  378         }
  379         if (clnp->cnf_vers != ISO8473_V1) {
  380                 INCSTAT(cns_badvers);
  381                 clnp_discard(m, DISC_UNSUPPVERS);
  382                 return;
  383         }
  384         /* check mbuf data length: clnp_data_ck will free mbuf upon error */
  385         CTOH(clnp->cnf_seglen_msb, clnp->cnf_seglen_lsb, seg_len);
  386         if ((m = clnp_data_ck(m, seg_len)) == 0)
  387                 return;
  388 
  389         clnp = mtod(m, struct clnp_fixed *);
  390         hend = (char *) clnp + clnp->cnf_hdr_len;
  391 
  392         /*
  393          * extract the source and destination address drop packet on failure
  394          */
  395         source = target = blank_siso;
  396 
  397         hoff = (char *)clnp + sizeof(struct clnp_fixed);
  398         CLNP_EXTRACT_ADDR(dst, hoff, hend);
  399         if (hoff == NULL) {
  400                 INCSTAT(cns_badaddr);
  401                 clnp_discard(m, GEN_INCOMPLETE);
  402                 return;
  403         }
  404         CLNP_EXTRACT_ADDR(src, hoff, hend);
  405         if (hoff == NULL) {
  406                 INCSTAT(cns_badaddr);
  407                 clnp_discard(m, GEN_INCOMPLETE);
  408                 return;
  409         }
  410 #ifdef ARGO_DEBUG
  411         if (argo_debug[D_INPUT]) {
  412                 printf("clnp_input: from %s", clnp_iso_addrp(&src));
  413                 printf(" to %s\n", clnp_iso_addrp(&dst));
  414         }
  415 #endif
  416 
  417         /*
  418          * extract the segmentation information, if it is present.
  419          * drop packet on failure
  420          */
  421         if (((clnp->cnf_type & CNF_TYPE) != CLNP_ER) &&
  422             (clnp->cnf_type & CNF_SEG_OK)) {
  423                 if (hoff + sizeof(struct clnp_segment) > hend) {
  424                         INCSTAT(cns_noseg);
  425                         clnp_discard(m, GEN_INCOMPLETE);
  426                         return;
  427                 } else {
  428                         (void)memcpy(&seg_part, hoff,
  429                             sizeof(struct clnp_segment));
  430                         /* make sure segmentation fields are in host order */
  431                         seg_part.cng_id = ntohs(seg_part.cng_id);
  432                         seg_part.cng_off = ntohs(seg_part.cng_off);
  433                         seg_part.cng_tot_len = ntohs(seg_part.cng_tot_len);
  434                         seg_off = hoff - (char *)clnp;
  435                         hoff += sizeof(struct clnp_segment);
  436                 }
  437         }
  438         /*
  439          * process options if present. If clnp_opt_sanity returns
  440          * false (indicating an error was found in the options) or
  441          * an unsupported option was found
  442          * then drop packet and emit an ER.
  443          */
  444         if (hoff < hend) {
  445                 int             errcode;
  446 
  447                 oidxp = &oidx;
  448                 errcode = clnp_opt_sanity(m, hoff, hend - hoff, oidxp);
  449 
  450                 /* we do not support security */
  451                 if ((errcode == 0) && (oidxp->cni_securep))
  452                         errcode = DISC_UNSUPPSECURE;
  453 
  454                 /* the er option is valid with ER pdus only */
  455                 if ((errcode == 0) && (oidxp->cni_er_reason != ER_INVALREAS) &&
  456                     ((clnp->cnf_type & CNF_TYPE) != CLNP_ER))
  457                         errcode = DISC_UNSUPPOPT;
  458 
  459 #ifdef  DECBIT
  460                 /* check if the congestion experienced bit is set */
  461                 if (oidxp->cni_qos_formatp) {
  462                         char *         qosp = CLNP_OFFTOOPT(m, oidxp->cni_qos_formatp);
  463                         u_char          qos = *qosp;
  464 
  465                         need_afrin = ((qos & (CLNPOVAL_GLOBAL | CLNPOVAL_CONGESTED)) ==
  466                                     (CLNPOVAL_GLOBAL | CLNPOVAL_CONGESTED));
  467                         if (need_afrin)
  468                                 INCSTAT(cns_congest_rcvd);
  469                 }
  470 #endif                          /* DECBIT */
  471 
  472                 if (errcode != 0) {
  473                         clnp_discard(m, (char) errcode);
  474 #ifdef ARGO_DEBUG
  475                         if (argo_debug[D_INPUT]) {
  476                                 printf(
  477                                     "clnp_input: dropped (err x%x) due to bad options\n",
  478                                     errcode);
  479                         }
  480 #endif
  481                         return;
  482                 }
  483         }
  484         /*
  485          *      check if this packet is for us. if not, then forward
  486          */
  487         if (clnp_ours(&dst) == 0) {
  488 #ifdef ARGO_DEBUG
  489                 if (argo_debug[D_INPUT]) {
  490                         printf("clnp_input: forwarding packet not for us\n");
  491                 }
  492 #endif
  493                 clnp_forward(m, seg_len, &dst, oidxp, seg_off, shp);
  494                 return;
  495         }
  496         /*
  497          *      ESIS Configuration Response Function
  498          *
  499          *      If the packet received was sent to the multicast address
  500          *      all end systems, then send an esh to the source
  501          */
  502         if ((shp->snh_flags & M_MCAST) && (iso_systype == SNPA_ES)) {
  503                 extern short    esis_holding_time;
  504 
  505                 esis_shoutput(shp->snh_ifp, ESIS_ESH, esis_holding_time,
  506                               shp->snh_shost, 6, &dst);
  507         }
  508         /*
  509          * If this is a fragment, then try to reassemble it. If clnp_reass
  510          * returns non NULL, the packet has been reassembled, and should
  511          * be give to TP. Otherwise the fragment has been delt with
  512          * by the reassembly code (either stored or deleted). In either case
  513          * we should have nothing more to do with it.
  514          */
  515         if (((clnp->cnf_type & CNF_TYPE) != CLNP_ER) &&
  516             (clnp->cnf_type & CNF_SEG_OK) &&
  517             (seg_len != seg_part.cng_tot_len)) {
  518                 struct mbuf    *m0;
  519 
  520                 if ((m0 = clnp_reass(m, &src, &dst, &seg_part)) != NULL) {
  521                         m = m0;
  522                         clnp = mtod(m, struct clnp_fixed *);
  523                         INCSTAT(cns_reassembled);
  524                 } else {
  525                         return;
  526                 }
  527         }
  528         /*
  529          *      give the packet to the higher layer
  530          *
  531          *      Note: the total length of packet
  532          *      is the total length field of the segmentation part,
  533          *      or, if absent, the segment length field of the
  534          *      header.
  535          */
  536         INCSTAT(cns_delivered);
  537         switch (clnp->cnf_type & CNF_TYPE) {
  538         case CLNP_ER:
  539                 /*
  540                  *      This ER must have the er option.
  541                  *      If the option is not present, discard datagram.
  542                  */
  543                 if (oidxp == NULL || oidxp->cni_er_reason == ER_INVALREAS) {
  544                         clnp_discard(m, GEN_HDRSYNTAX);
  545                 } else {
  546                         clnp_er_input(m, &src, oidxp->cni_er_reason);
  547                 }
  548                 break;
  549         case CLNP_DT:
  550                 (*isosw[clnp_protox[ISOPROTO_TP]].pr_input)(m, &source, &target,
  551                                              clnp->cnf_hdr_len, need_afrin);
  552                 break;
  553         case CLNP_RAW:
  554         case CLNP_ECR:
  555 #ifdef ARGO_DEBUG
  556                 if (argo_debug[D_INPUT]) {
  557                         printf("clnp_input: raw input of %d bytes\n",
  558                             clnp->cnf_type & CNF_SEG_OK ?
  559                             seg_part.cng_tot_len : seg_len);
  560                 }
  561 #endif
  562                 (*isosw[clnp_protox[ISOPROTO_RAW]].pr_input)(m, &source,
  563                                                              &target,
  564                                                          clnp->cnf_hdr_len);
  565                 break;
  566 
  567         case CLNP_EC:
  568 #ifdef ARGO_DEBUG
  569                 if (argo_debug[D_INPUT]) {
  570                         printf("clnp_input: echoing packet\n");
  571                 }
  572 #endif
  573                 (void) clnp_echoreply(m, (clnp->cnf_type & CNF_SEG_OK ?
  574                                       (int) seg_part.cng_tot_len : seg_len),
  575                                       &source, &target, oidxp);
  576                 break;
  577 
  578         default:
  579                 printf("clnp_input: unknown clnp pkt type %d\n",
  580                     clnp->cnf_type & CNF_TYPE);
  581                 clnp_stat.cns_delivered--;
  582                 clnp_stat.cns_noproto++;
  583                 clnp_discard(m, GEN_HDRSYNTAX);
  584                 break;
  585         }
  586 }
  587 #endif                          /* ISO */

Cache object: a1e6141c3d51d888b8d7381e77bc9e59


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