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.27 2003/09/26 22:23:58 wiz 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.27 2003/09/26 22:23:58 wiz 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 <netiso/iso.h>
   84 #include <netiso/iso_var.h>
   85 #include <netiso/iso_snpac.h>
   86 #include <netiso/clnp.h>
   87 #include <netiso/clnl.h>
   88 #include <netiso/esis.h>
   89 #include <netinet/in_systm.h>
   90 #include <netinet/ip.h>
   91 #include <netiso/eonvar.h>
   92 #include <netiso/clnp_stat.h>
   93 #include <netiso/argo_debug.h>
   94 
   95 #include <machine/stdarg.h>
   96 
   97 #ifdef ISO
   98 u_char          clnp_protox[ISOPROTO_MAX];
   99 struct clnl_protosw clnl_protox[256];
  100 int             clnpqmaxlen = IFQ_MAXLEN;       /* RAH? why is this a
  101                                                  * variable */
  102 #ifdef  ISO_X25ESIS
  103 #if 0
  104 void            x25esis_input();
  105 #endif
  106 #endif                          /* ISO_X25ESIS */
  107 struct iso_ifaddrhead iso_ifaddr = TAILQ_HEAD_INITIALIZER(iso_ifaddr);
  108 struct ifqueue  clnlintrq;
  109 struct clnp_stat clnp_stat;
  110 
  111 /*
  112  * FUNCTION:            clnp_init
  113  *
  114  * PURPOSE:             clnp initialization. Fill in clnp switch tables.
  115  *
  116  * RETURNS:             none
  117  *
  118  * SIDE EFFECTS:        fills in clnp_protox table with correct offsets into
  119  *                      the isosw table.
  120  *
  121  * NOTES:
  122  */
  123 void
  124 clnp_init()
  125 {
  126         struct protosw *pr;
  127 
  128         /*
  129          * CLNP protox initialization
  130          */
  131         if ((pr = pffindproto(PF_ISO, ISOPROTO_RAW, SOCK_RAW)) == 0)
  132                 printf("clnl_init: no raw CLNP\n");
  133         else
  134                 clnp_protox[ISOPROTO_RAW] = pr - isosw;
  135 
  136         if ((pr = pffindproto(PF_ISO, ISOPROTO_TP, SOCK_SEQPACKET)) == 0)
  137                 printf("clnl_init: no tp/clnp\n");
  138         else
  139                 clnp_protox[ISOPROTO_TP] = pr - isosw;
  140 
  141         /*
  142          *      CLNL protox initialization
  143          */
  144         clnl_protox[ISO8473_CLNP].clnl_input = clnp_input;
  145 
  146         clnlintrq.ifq_maxlen = clnpqmaxlen;
  147 }
  148 
  149 /*
  150  * FUNCTION:            clnlintr
  151  *
  152  * PURPOSE:             Process a packet on the clnl input queue
  153  *
  154  * RETURNS:             nothing.
  155  *
  156  * SIDE EFFECTS:
  157  *
  158  * NOTES:
  159  */
  160 void
  161 clnlintr()
  162 {
  163         struct mbuf *m;/* ptr to first mbuf of pkt */
  164         struct clnl_fixed *clnl;        /* ptr to fixed part of clnl
  165                                                  * hdr */
  166         int             s;      /* save and restore priority */
  167         struct clnl_protosw *clnlsw;    /* ptr to protocol switch */
  168         struct snpa_hdr sh;     /* subnetwork hdr */
  169 
  170         /*
  171          *      Get next datagram off clnl input queue
  172          */
  173 next:
  174         s = splnet();
  175         /* IF_DEQUEUESNPAHDR(&clnlintrq, m, sh); */
  176         IF_DEQUEUE(&clnlintrq, m);
  177         splx(s);
  178 
  179 
  180         if (m == 0)             /* nothing to do */
  181                 return;
  182         if ((m->m_flags & M_PKTHDR) == 0 || m->m_pkthdr.rcvif == 0) {
  183                 m_freem(m);
  184                 goto next;
  185         }
  186         bzero((caddr_t) & sh, sizeof(sh));
  187         sh.snh_flags = m->m_flags & (M_MCAST | M_BCAST);
  188         switch ((sh.snh_ifp = m->m_pkthdr.rcvif)->if_type) {
  189         case IFT_EON:
  190                 bcopy(mtod(m, caddr_t), (caddr_t) sh.snh_dhost, sizeof(u_long));
  191                 bcopy(sizeof(u_long) + mtod(m, caddr_t),
  192                       (caddr_t) sh.snh_shost, sizeof(u_long));
  193                 sh.snh_dhost[4] = mtod(m, u_char *)[sizeof(struct ip) +
  194                                      offsetof(struct eon_hdr, eonh_class)];
  195                 m->m_data += EONIPLEN;
  196                 m->m_len -= EONIPLEN;
  197                 m->m_pkthdr.len -= EONIPLEN;
  198                 break;
  199         case IFT_ETHER:
  200                 bcopy((caddr_t) (mtod(m, struct ether_header *)->ether_dhost),
  201                   (caddr_t) sh.snh_dhost, 2 * sizeof(sh.snh_dhost));
  202                 m->m_data += sizeof(struct ether_header);
  203                 m->m_len -= sizeof(struct ether_header);
  204                 m->m_pkthdr.len -= sizeof(struct ether_header);
  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->m_data += sizeof(struct fddi_header);
  210                 m->m_len -= sizeof(struct fddi_header);
  211                 m->m_pkthdr.len -= sizeof(struct fddi_header);
  212                 break;
  213         case IFT_PTPSERIAL:
  214         case IFT_GIF:
  215                 /* nothing extra to get from the mbuf */
  216                 bzero((caddr_t)sh.snh_dhost, sizeof(sh.snh_dhost));
  217                 bzero((caddr_t)sh.snh_shost, sizeof(sh.snh_shost));
  218                 break;
  219         default:
  220                 break;
  221         }
  222 #ifdef ARGO_DEBUG
  223         if (argo_debug[D_INPUT]) {
  224                 int             i;
  225                 printf("clnlintr: src:");
  226                 for (i = 0; i < 6; i++)
  227                         printf("%x%c", sh.snh_shost[i] & 0xff,
  228                             (i < 5) ? ':' : ' ');
  229                 printf(" dst:");
  230                 for (i = 0; i < 6; i++)
  231                         printf("%x%c", sh.snh_dhost[i] & 0xff,
  232                             (i < 5) ? ':' : ' ');
  233                 printf("\n");
  234         }
  235 #endif
  236 
  237         /*
  238          * Get the fixed part of the clnl header into the first mbuf.
  239          * Drop the packet if this fails.
  240          * Do not call m_pullup if we have a cluster mbuf or the
  241          * data is not there.
  242          */
  243         if ((IS_CLUSTER(m) || (m->m_len < sizeof(struct clnl_fixed))) &&
  244             ((m = m_pullup(m, sizeof(struct clnl_fixed))) == 0)) {
  245                 INCSTAT(cns_toosmall);  /* TODO: use clnl stats */
  246                 goto next;      /* m_pullup discards mbuf */
  247         }
  248         clnl = mtod(m, struct clnl_fixed *);
  249 
  250         /*
  251          * Drop packet if the length of the header is not reasonable.
  252          */
  253         if ((clnl->cnf_hdr_len < CLNP_HDR_MIN) ||
  254             (clnl->cnf_hdr_len > CLNP_HDR_MAX)) {
  255                 INCSTAT(cns_badhlen);   /* TODO: use clnl stats */
  256                 m_freem(m);
  257                 goto next;
  258         }
  259         /*
  260          *      If the header is not contained in this mbuf, make it so.
  261          *      Drop packet if this fails.
  262          *      Note: m_pullup will allocate a cluster mbuf if necessary
  263          */
  264         if (clnl->cnf_hdr_len > m->m_len) {
  265                 if ((m = m_pullup(m, (int) clnl->cnf_hdr_len)) == 0) {
  266                         INCSTAT(cns_badhlen);   /* TODO: use clnl stats */
  267                         goto next;      /* m_pullup discards mbuf */
  268                 }
  269                 clnl = mtod(m, struct clnl_fixed *);
  270         }
  271         clnlsw = &clnl_protox[clnl->cnf_proto_id];
  272 
  273 
  274         if (clnlsw->clnl_input)
  275                 (*clnlsw->clnl_input) (m, &sh);
  276         else
  277                 m_freem(m);
  278 
  279         goto next;
  280 }
  281 
  282 /*
  283  * FUNCTION:            clnp_input
  284  *
  285  * PURPOSE:             process an incoming clnp packet
  286  *
  287  * RETURNS:             nothing
  288  *
  289  * SIDE EFFECTS:        increments fields of clnp_stat structure.
  290  *
  291  * NOTES:
  292  *      TODO: I would like to make seg_part a pointer into the mbuf, but
  293  *      will it be correctly aligned?
  294  */
  295 void
  296 #if __STDC__
  297 clnp_input(struct mbuf *m, ...)
  298 #else
  299 clnp_input(m, va_alist)
  300         struct mbuf    *m;      /* ptr to first mbuf of pkt */
  301         va_dcl
  302 #endif
  303 {
  304         struct snpa_hdr *shp;   /* subnetwork header */
  305         struct ifaddr *ifa;
  306         struct clnp_fixed *clnp;        /* ptr to fixed part of
  307                                                  * header */
  308         struct sockaddr_iso source;     /* source address of pkt */
  309         struct sockaddr_iso target;     /* destination address of pkt */
  310 #define src     source.siso_addr
  311 #define dst     target.siso_addr
  312         caddr_t         hoff;   /* current offset in packet */
  313         caddr_t         hend;   /* address of end of header info */
  314         struct clnp_segment seg_part;   /* segment part of hdr */
  315         int             seg_off = 0;    /* offset of segment part of hdr */
  316         int             seg_len;/* length of packet data&hdr in bytes */
  317         struct clnp_optidx oidx, *oidxp = NULL; /* option index */
  318         extern int      iso_systype;    /* used by ESIS config resp */
  319         extern struct sockaddr_iso blank_siso;  /* used for initializing */
  320         int             need_afrin = 0;
  321         /* true if congestion experienced */
  322         /* which means you need afrin nose */
  323         /* spray. How clever! */
  324         va_list ap;
  325 
  326         va_start(ap, m);
  327         shp = va_arg(ap, struct snpa_hdr *);
  328         va_end(ap);
  329 
  330         /*
  331          * make sure this interface has a ISO address
  332          */
  333         for (ifa = shp->snh_ifp->if_addrlist.tqh_first; ifa != 0;
  334              ifa = ifa->ifa_list.tqe_next)
  335                 if (ifa->ifa_addr->sa_family == AF_ISO)
  336                         break;
  337         if (ifa == 0) {
  338                 clnp_discard(m, ADDR_DESTUNREACH);
  339                 return;
  340         }
  341 
  342 #ifdef ARGO_DEBUG
  343         if (argo_debug[D_INPUT]) {
  344                 printf(
  345                     "clnp_input: processing dg; First mbuf m_len %d, m_type x%x, %s\n",
  346                     m->m_len, m->m_type, IS_CLUSTER(m) ? "cluster" : "normal");
  347         }
  348 #endif
  349         need_afrin = 0;
  350 
  351         /*
  352          *      If no iso addresses have been set, there is nothing
  353          *      to do with the packet.
  354          */
  355         if (iso_ifaddr.tqh_first == 0) {
  356                 clnp_discard(m, ADDR_DESTUNREACH);
  357                 return;
  358         }
  359         INCSTAT(cns_total);
  360         clnp = mtod(m, struct clnp_fixed *);
  361 
  362 #ifdef ARGO_DEBUG
  363         if (argo_debug[D_DUMPIN]) {
  364                 struct mbuf    *mhead;
  365                 int             total_len = 0;
  366                 printf("clnp_input: clnp header:\n");
  367                 dump_buf(mtod(m, caddr_t), clnp->cnf_hdr_len);
  368                 printf("clnp_input: mbuf chain:\n");
  369                 for (mhead = m; mhead != NULL; mhead = mhead->m_next) {
  370                         printf("m %p, len %d\n", mhead, mhead->m_len);
  371                         total_len += mhead->m_len;
  372                 }
  373                 printf("clnp_input: total length of mbuf chain %d:\n",
  374                 total_len);
  375         }
  376 #endif
  377 
  378         /*
  379          *      Compute checksum (if necessary) and drop packet if
  380          *      checksum does not match
  381          */
  382         if (CKSUM_REQUIRED(clnp) &&
  383             iso_check_csum(m, (int) clnp->cnf_hdr_len)) {
  384                 INCSTAT(cns_badcsum);
  385                 clnp_discard(m, GEN_BADCSUM);
  386                 return;
  387         }
  388         if (clnp->cnf_vers != ISO8473_V1) {
  389                 INCSTAT(cns_badvers);
  390                 clnp_discard(m, DISC_UNSUPPVERS);
  391                 return;
  392         }
  393         /* check mbuf data length: clnp_data_ck will free mbuf upon error */
  394         CTOH(clnp->cnf_seglen_msb, clnp->cnf_seglen_lsb, seg_len);
  395         if ((m = clnp_data_ck(m, seg_len)) == 0)
  396                 return;
  397 
  398         clnp = mtod(m, struct clnp_fixed *);
  399         hend = (caddr_t) clnp + clnp->cnf_hdr_len;
  400 
  401         /*
  402          * extract the source and destination address drop packet on failure
  403          */
  404         source = target = blank_siso;
  405 
  406         hoff = (caddr_t) clnp + sizeof(struct clnp_fixed);
  407         CLNP_EXTRACT_ADDR(dst, hoff, hend);
  408         if (hoff == (caddr_t) 0) {
  409                 INCSTAT(cns_badaddr);
  410                 clnp_discard(m, GEN_INCOMPLETE);
  411                 return;
  412         }
  413         CLNP_EXTRACT_ADDR(src, hoff, hend);
  414         if (hoff == (caddr_t) 0) {
  415                 INCSTAT(cns_badaddr);
  416                 clnp_discard(m, GEN_INCOMPLETE);
  417                 return;
  418         }
  419 #ifdef ARGO_DEBUG
  420         if (argo_debug[D_INPUT]) {
  421                 printf("clnp_input: from %s", clnp_iso_addrp(&src));
  422                 printf(" to %s\n", clnp_iso_addrp(&dst));
  423         }
  424 #endif
  425 
  426         /*
  427          * extract the segmentation information, if it is present.
  428          * drop packet on failure
  429          */
  430         if (((clnp->cnf_type & CNF_TYPE) != CLNP_ER) &&
  431             (clnp->cnf_type & CNF_SEG_OK)) {
  432                 if (hoff + sizeof(struct clnp_segment) > hend) {
  433                         INCSTAT(cns_noseg);
  434                         clnp_discard(m, GEN_INCOMPLETE);
  435                         return;
  436                 } else {
  437                         (void) bcopy(hoff, (caddr_t) & seg_part,
  438                                      sizeof(struct clnp_segment));
  439                         /* make sure segmentation fields are in host order */
  440                         seg_part.cng_id = ntohs(seg_part.cng_id);
  441                         seg_part.cng_off = ntohs(seg_part.cng_off);
  442                         seg_part.cng_tot_len = ntohs(seg_part.cng_tot_len);
  443                         seg_off = hoff - (caddr_t) clnp;
  444                         hoff += sizeof(struct clnp_segment);
  445                 }
  446         }
  447         /*
  448          * process options if present. If clnp_opt_sanity returns
  449          * false (indicating an error was found in the options) or
  450          * an unsupported option was found
  451          * then drop packet and emit an ER.
  452          */
  453         if (hoff < hend) {
  454                 int             errcode;
  455 
  456                 oidxp = &oidx;
  457                 errcode = clnp_opt_sanity(m, hoff, hend - hoff, oidxp);
  458 
  459                 /* we do not support security */
  460                 if ((errcode == 0) && (oidxp->cni_securep))
  461                         errcode = DISC_UNSUPPSECURE;
  462 
  463                 /* the er option is valid with ER pdus only */
  464                 if ((errcode == 0) && (oidxp->cni_er_reason != ER_INVALREAS) &&
  465                     ((clnp->cnf_type & CNF_TYPE) != CLNP_ER))
  466                         errcode = DISC_UNSUPPOPT;
  467 
  468 #ifdef  DECBIT
  469                 /* check if the congestion experienced bit is set */
  470                 if (oidxp->cni_qos_formatp) {
  471                         caddr_t         qosp = CLNP_OFFTOOPT(m, oidxp->cni_qos_formatp);
  472                         u_char          qos = *qosp;
  473 
  474                         need_afrin = ((qos & (CLNPOVAL_GLOBAL | CLNPOVAL_CONGESTED)) ==
  475                                     (CLNPOVAL_GLOBAL | CLNPOVAL_CONGESTED));
  476                         if (need_afrin)
  477                                 INCSTAT(cns_congest_rcvd);
  478                 }
  479 #endif                          /* DECBIT */
  480 
  481                 if (errcode != 0) {
  482                         clnp_discard(m, (char) errcode);
  483 #ifdef ARGO_DEBUG
  484                         if (argo_debug[D_INPUT]) {
  485                                 printf(
  486                                     "clnp_input: dropped (err x%x) due to bad options\n",
  487                                     errcode);
  488                         }
  489 #endif
  490                         return;
  491                 }
  492         }
  493         /*
  494          *      check if this packet is for us. if not, then forward
  495          */
  496         if (clnp_ours(&dst) == 0) {
  497 #ifdef ARGO_DEBUG
  498                 if (argo_debug[D_INPUT]) {
  499                         printf("clnp_input: forwarding packet not for us\n");
  500                 }
  501 #endif
  502                 clnp_forward(m, seg_len, &dst, oidxp, seg_off, shp);
  503                 return;
  504         }
  505         /*
  506          *      ESIS Configuration Response Function
  507          *
  508          *      If the packet received was sent to the multicast address
  509          *      all end systems, then send an esh to the source
  510          */
  511         if ((shp->snh_flags & M_MCAST) && (iso_systype == SNPA_ES)) {
  512                 extern short    esis_holding_time;
  513 
  514                 esis_shoutput(shp->snh_ifp, ESIS_ESH, esis_holding_time,
  515                               shp->snh_shost, 6, &dst);
  516         }
  517         /*
  518          * If this is a fragment, then try to reassemble it. If clnp_reass
  519          * returns non NULL, the packet has been reassembled, and should
  520          * be give to TP. Otherwise the fragment has been delt with
  521          * by the reassembly code (either stored or deleted). In either case
  522          * we should have nothing more to do with it.
  523          */
  524         if (((clnp->cnf_type & CNF_TYPE) != CLNP_ER) &&
  525             (clnp->cnf_type & CNF_SEG_OK) &&
  526             (seg_len != seg_part.cng_tot_len)) {
  527                 struct mbuf    *m0;
  528 
  529                 if ((m0 = clnp_reass(m, &src, &dst, &seg_part)) != NULL) {
  530                         m = m0;
  531                         clnp = mtod(m, struct clnp_fixed *);
  532                         INCSTAT(cns_reassembled);
  533                 } else {
  534                         return;
  535                 }
  536         }
  537         /*
  538          *      give the packet to the higher layer
  539          *
  540          *      Note: the total length of packet
  541          *      is the total length field of the segmentation part,
  542          *      or, if absent, the segment length field of the
  543          *      header.
  544          */
  545         INCSTAT(cns_delivered);
  546         switch (clnp->cnf_type & CNF_TYPE) {
  547         case CLNP_ER:
  548                 /*
  549                  *      This ER must have the er option.
  550                  *      If the option is not present, discard datagram.
  551                  */
  552                 if (oidxp == NULL || oidxp->cni_er_reason == ER_INVALREAS) {
  553                         clnp_discard(m, GEN_HDRSYNTAX);
  554                 } else {
  555                         clnp_er_input(m, &src, oidxp->cni_er_reason);
  556                 }
  557                 break;
  558         case CLNP_DT:
  559                 (*isosw[clnp_protox[ISOPROTO_TP]].pr_input)(m, &source, &target,
  560                                              clnp->cnf_hdr_len, need_afrin);
  561                 break;
  562         case CLNP_RAW:
  563         case CLNP_ECR:
  564 #ifdef ARGO_DEBUG
  565                 if (argo_debug[D_INPUT]) {
  566                         printf("clnp_input: raw input of %d bytes\n",
  567                             clnp->cnf_type & CNF_SEG_OK ?
  568                             seg_part.cng_tot_len : seg_len);
  569                 }
  570 #endif
  571                 (*isosw[clnp_protox[ISOPROTO_RAW]].pr_input)(m, &source,
  572                                                              &target,
  573                                                          clnp->cnf_hdr_len);
  574                 break;
  575 
  576         case CLNP_EC:
  577 #ifdef ARGO_DEBUG
  578                 if (argo_debug[D_INPUT]) {
  579                         printf("clnp_input: echoing packet\n");
  580                 }
  581 #endif
  582                 (void) clnp_echoreply(m, (clnp->cnf_type & CNF_SEG_OK ?
  583                                       (int) seg_part.cng_tot_len : seg_len),
  584                                       &source, &target, oidxp);
  585                 break;
  586 
  587         default:
  588                 printf("clnp_input: unknown clnp pkt type %d\n",
  589                     clnp->cnf_type & CNF_TYPE);
  590                 clnp_stat.cns_delivered--;
  591                 clnp_stat.cns_noproto++;
  592                 clnp_discard(m, GEN_HDRSYNTAX);
  593                 break;
  594         }
  595 }
  596 #endif                          /* ISO */

Cache object: 8b7e36ed9ca16de737f98e66a91631ec


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