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_er.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_er.c,v 1.25 2009/03/14 21:04:25 dsl 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_er.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_er.c,v 1.25 2009/03/14 21:04:25 dsl Exp $");
   63 
   64 #include <sys/param.h>
   65 #include <sys/mbuf.h>
   66 #include <sys/domain.h>
   67 #include <sys/protosw.h>
   68 #include <sys/socket.h>
   69 #include <sys/socketvar.h>
   70 #include <sys/errno.h>
   71 #include <sys/systm.h>
   72 
   73 #include <net/if.h>
   74 #include <net/route.h>
   75 
   76 #include <netiso/iso.h>
   77 #include <netiso/iso_var.h>
   78 #include <netiso/iso_pcb.h>
   79 #define CLNP_ER_CODES
   80 #include <netiso/clnp.h>
   81 #include <netiso/clnp_stat.h>
   82 #include <netiso/argo_debug.h>
   83 #include <netiso/tp_param.h>
   84 #include <netiso/tp_var.h>
   85 
   86 static const struct clnp_fixed er_template = {
   87         ISO8473_CLNP,           /* network identifier */
   88         0,                      /* length */
   89         ISO8473_V1,             /* version */
   90         CLNP_TTL,               /* ttl */
   91         CLNP_ER,                /* type */
   92         0,                      /* segment length msb */
   93         0,                      /* segment length lsb */
   94         0,                      /* checksum msb */
   95         0,                      /* checksum lmsb */
   96 };
   97 
   98 /*
   99  * FUNCTION:            clnp_er_input
  100  *
  101  * PURPOSE:                     Process an ER pdu.
  102  *
  103  * RETURNS:
  104  *
  105  * SIDE EFFECTS:
  106  *
  107  * NOTES:
  108  */
  109 void
  110 clnp_er_input(
  111         struct mbuf    *m,      /* ptr to packet itself */
  112         struct iso_addr *src,   /* ptr to src of er */
  113         u_int           reason) /* reason code of er */
  114 {
  115         int             cmd = -1;
  116 
  117 #ifdef ARGO_DEBUG
  118         if (argo_debug[D_CTLINPUT]) {
  119                 printf("clnp_er_input: m %p, src %s, reason x%x\n",
  120                     m, clnp_iso_addrp(src), reason);
  121         }
  122 #endif
  123 
  124         INCSTAT(cns_er_inhist[clnp_er_index(reason)]);
  125         switch (reason) {
  126         case GEN_NOREAS:
  127         case GEN_PROTOERR:
  128                 break;
  129         case GEN_BADCSUM:
  130                 cmd = PRC_PARAMPROB;
  131                 break;
  132         case GEN_CONGEST:
  133                 cmd = PRC_QUENCH;
  134                 break;
  135         case GEN_HDRSYNTAX:
  136                 cmd = PRC_PARAMPROB;
  137                 break;
  138         case GEN_SEGNEEDED:
  139                 cmd = PRC_MSGSIZE;
  140                 break;
  141         case GEN_INCOMPLETE:
  142                 cmd = PRC_PARAMPROB;
  143                 break;
  144         case GEN_DUPOPT:
  145                 cmd = PRC_PARAMPROB;
  146                 break;
  147         case ADDR_DESTUNREACH:
  148                 cmd = PRC_UNREACH_HOST;
  149                 break;
  150         case ADDR_DESTUNKNOWN:
  151                 cmd = PRC_UNREACH_PROTOCOL;
  152                 break;
  153         case SRCRT_UNSPECERR:
  154         case SRCRT_SYNTAX:
  155         case SRCRT_UNKNOWNADDR:
  156         case SRCRT_BADPATH:
  157                 cmd = PRC_UNREACH_SRCFAIL;
  158                 break;
  159         case TTL_EXPTRANSIT:
  160                 cmd = PRC_TIMXCEED_INTRANS;
  161                 break;
  162         case TTL_EXPREASS:
  163                 cmd = PRC_TIMXCEED_REASS;
  164                 break;
  165         case DISC_UNSUPPOPT:
  166         case DISC_UNSUPPVERS:
  167         case DISC_UNSUPPSECURE:
  168         case DISC_UNSUPPSRCRT:
  169         case DISC_UNSUPPRECRT:
  170                 cmd = PRC_PARAMPROB;
  171                 break;
  172         case REASS_INTERFERE:
  173                 cmd = PRC_TIMXCEED_REASS;
  174                 break;
  175         }
  176 
  177         /*
  178          *      tpclnp_ctlinput1 is called directly so that we don't
  179          *      have to build an iso_sockaddr out of src.
  180          */
  181         if (cmd >= 0)
  182                 tpclnp_ctlinput1(cmd, src);
  183 
  184         m_freem(m);
  185 }
  186 
  187 /*
  188  * FUNCTION:            clnp_discard
  189  *
  190  * PURPOSE:             Discard a clnp datagram
  191  *
  192  * RETURNS:             nothing
  193  *
  194  * SIDE EFFECTS:        Will emit an ER pdu if possible
  195  *
  196  * NOTES:               This code assumes that we have previously tried to pull
  197  *                      up the header of the datagram into one mbuf.
  198  */
  199 void
  200 clnp_discard(struct mbuf *m, u_int reason)
  201         /* m:    header of packet to discard */
  202         /* reason:       reason for discard */
  203 {
  204 #ifdef ARGO_DEBUG
  205         if (argo_debug[D_DISCARD]) {
  206                 printf("clnp_discard: m %p, reason x%x\n", m, reason);
  207         }
  208 #endif
  209 
  210         if (m != NULL) {
  211                 if (m->m_len >= sizeof(struct clnp_fixed)) {
  212                         struct clnp_fixed *clnp =
  213                                 mtod(m, struct clnp_fixed *);
  214 
  215                         if (((clnp->cnf_type & CNF_TYPE) != CLNP_ER) &&
  216                             (clnp->cnf_type & CNF_ERR_OK)) {
  217                                 clnp_emit_er(m, reason);
  218                                 return;
  219                         }
  220                 }
  221                 m_freem(m);
  222         }
  223 }
  224 
  225 /*
  226  * FUNCTION:            clnp_emit_er
  227  *
  228  * PURPOSE:             Send an ER pdu.
  229  *                      The src of the of the ER pdu is the host that is sending
  230  *                      the ER (ie. us), *not* the original destination of the
  231  *                      packet.
  232  *
  233  * RETURNS:             nothing
  234  *
  235  * SIDE EFFECTS:
  236  *
  237  * NOTES:               Takes responsibility for freeing mbuf passed
  238  *                      This function may be called with a packet that
  239  *                      was created by us; in this case, do not send
  240  *                      an ER.
  241  */
  242 void
  243 clnp_emit_er(struct mbuf *m, u_int reason)
  244         /* m:    header of packet to discard */
  245         /* reason:       reason for discard */
  246 {
  247         struct clnp_fixed *clnp = mtod(m, struct clnp_fixed *);
  248         struct clnp_fixed *er;
  249         struct route route;
  250         struct ifnet   *ifp;
  251         const struct sockaddr *first_hop;
  252         struct iso_addr src, dst, *our_addr;
  253         char *hoff, *hend;
  254         int total_len;  /* total len of dg */
  255         struct iso_ifaddr *ia = 0;
  256 
  257 #ifdef ARGO_DEBUG
  258         if (argo_debug[D_DISCARD]) {
  259                 printf("clnp_emit_er: m %p, hdr len %d\n",
  260                        m, clnp->cnf_hdr_len);
  261         }
  262 #endif
  263 
  264         memset(&route, 0, sizeof(route));
  265 
  266         /*
  267          * If header length is incorrect, or entire header is not contained
  268          * in this mbuf, we punt
  269          */
  270         if ((clnp->cnf_hdr_len < CLNP_HDR_MIN) ||
  271             (clnp->cnf_hdr_len > CLNP_HDR_MAX) ||
  272             (clnp->cnf_hdr_len > m->m_len))
  273                 goto bad;
  274 
  275         /* extract src, dest address */
  276         hend = (char *)clnp + clnp->cnf_hdr_len;
  277         hoff = (char *)clnp + sizeof(struct clnp_fixed);
  278         CLNP_EXTRACT_ADDR(dst, hoff, hend);
  279         if (hoff == (void *) 0) {
  280                 goto bad;
  281         }
  282         CLNP_EXTRACT_ADDR(src, hoff, hend);
  283         if (hoff == (void *) 0) {
  284                 goto bad;
  285         }
  286         /*
  287          * Do not send ER if we generated the packet.
  288          */
  289         if (clnp_ours(&src))
  290                 goto bad;
  291 
  292         /*
  293          * Trim mbuf to hold only the header. This mbuf will be the 'data' of
  294          * the er pdu
  295          */
  296         if (m->m_next != NULL) {
  297                 m_freem(m->m_next);
  298                 m->m_next = NULL;
  299         }
  300         if (m->m_len > clnp->cnf_hdr_len)
  301                 m_adj(m, (int) -(m->m_len - (int) clnp->cnf_hdr_len));
  302 
  303         /* route er pdu: note we send pkt to src of original packet  */
  304         if (clnp_route(&src, &route, /* flags */ 0, &first_hop, &ia) != 0)
  305                 goto bad;
  306 
  307         /* compute our address based upon firsthop/ifp */
  308         if (ia)
  309                 our_addr = &ia->ia_addr.siso_addr;
  310         else
  311                 goto bad;
  312         ifp = ia->ia_ifp;
  313 
  314 #ifdef ARGO_DEBUG
  315         if (argo_debug[D_DISCARD]) {
  316                 printf("clnp_emit_er: to %s", clnp_iso_addrp(&src));
  317                 printf(" from %s\n", clnp_iso_addrp(our_addr));
  318         }
  319 #endif
  320 
  321 #ifdef ARGO_DEBUG
  322         if (argo_debug[D_DISCARD]) {
  323                 printf("clnp_emit_er: packet routed to %s\n",
  324                     clnp_iso_addrp(&satocsiso(first_hop)->siso_addr));
  325         }
  326 #endif
  327 
  328         /* allocate mbuf for er pdu header: punt on no space */
  329         /*
  330          * fixed part, two addresses and their length bytes, and a
  331          * 4-byte option
  332          */
  333 
  334         M_PREPEND(m, sizeof(struct clnp_fixed) + 4 + 1 + 1 +
  335                         src.isoa_len + our_addr->isoa_len, M_DONTWAIT);
  336         if (m == 0)
  337                 goto bad;
  338 
  339         er = mtod(m, struct clnp_fixed *);
  340         *er = er_template;
  341 
  342         /* setup src/dst on er pdu */
  343         /* NOTE REVERSAL OF SRC/DST */
  344         hoff = (char *)er + sizeof(struct clnp_fixed);
  345         CLNP_INSERT_ADDR(hoff, src);
  346         CLNP_INSERT_ADDR(hoff, *our_addr);
  347 
  348         /*
  349          *      TODO: if complete src rt was specified, then reverse path, and
  350          *      copy into er as option.
  351          */
  352 
  353         /* add er option */
  354         *hoff++ = CLNPOVAL_ERREAS;      /* code */
  355         *hoff++ = 2;            /* length */
  356         *hoff++ = reason;       /* discard reason */
  357         *hoff++ = 0;            /* error localization = not specified */
  358 
  359         /* set length */
  360         er->cnf_hdr_len = (u_char) (hoff - (char *)er);
  361         total_len = m->m_pkthdr.len;
  362         HTOC(er->cnf_seglen_msb, er->cnf_seglen_lsb, total_len);
  363 
  364         /* compute checksum (on header only) */
  365         iso_gen_csum(m, CLNP_CKSUM_OFF, (int) er->cnf_hdr_len);
  366 
  367         /* trim packet if too large for interface */
  368         if (total_len > ifp->if_mtu)
  369                 m_adj(m, -(total_len - ifp->if_mtu));
  370 
  371         /* send packet */
  372         INCSTAT(cns_er_outhist[clnp_er_index(reason)]);
  373         (void) (*ifp->if_output) (ifp, m, first_hop, rtcache_validate(&route));
  374         goto done;
  375 
  376 bad:
  377         m_freem(m);
  378 
  379 done:
  380         /* free route if it is a temp */
  381         rtcache_free(&route);
  382 }
  383 
  384 int
  385 clnp_er_index(u_int p)
  386 {
  387         u_char *cp = clnp_er_codes + CLNP_ERRORS;
  388         while (cp > clnp_er_codes) {
  389                 cp--;
  390                 if (*cp == p)
  391                         return (cp - clnp_er_codes);
  392         }
  393         return (CLNP_ERRORS + 1);
  394 }

Cache object: c6a2b6f6a14bf3ce9dbb9caa4ab3edd0


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