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

Cache object: 00be230f00f3b220d2985c993628920e


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