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_subr.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_subr.c,v 1.31 2008/01/14 04:17:35 dyoung 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_subr.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_subr.c,v 1.31 2008/01/14 04:17:35 dyoung Exp $");
   63 
   64 #include "opt_iso.h"
   65 
   66 #ifdef ISO
   67 
   68 #include <sys/param.h>
   69 #include <sys/mbuf.h>
   70 #include <sys/domain.h>
   71 #include <sys/protosw.h>
   72 #include <sys/socket.h>
   73 #include <sys/socketvar.h>
   74 #include <sys/errno.h>
   75 #include <sys/time.h>
   76 #include <sys/systm.h>
   77 
   78 #include <net/if.h>
   79 #include <net/route.h>
   80 #include <net/if_dl.h>
   81 
   82 #include <netiso/iso.h>
   83 #include <netiso/iso_var.h>
   84 #include <netiso/iso_pcb.h>
   85 #include <netiso/iso_snpac.h>
   86 #include <netiso/clnp.h>
   87 #include <netiso/clnp_stat.h>
   88 #include <netiso/argo_debug.h>
   89 #include <netiso/esis.h>
   90 
   91 /*
   92  * FUNCTION:            clnp_data_ck
   93  *
   94  * PURPOSE:             Check that the amount of data in the mbuf chain is
   95  *                      at least as much as the clnp header would have us
   96  *                      expect. Trim mbufs if longer than expected, drop
   97  *                      packet if shorter than expected.
   98  *
   99  * RETURNS:             success - ptr to mbuf chain
  100  *                      failure - 0
  101  *
  102  * SIDE EFFECTS:
  103  *
  104  * NOTES:
  105  */
  106 struct mbuf    *
  107 clnp_data_ck(
  108         struct mbuf *m,         /* ptr to mbuf chain containing hdr & data */
  109         int     length)         /* length (in bytes) of packet */
  110 {
  111         int    len;             /* length of data */
  112         struct mbuf *mhead;     /* ptr to head of chain */
  113 
  114         len = -length;
  115         mhead = m;
  116         for (;;) {
  117                 len += m->m_len;
  118                 if (m->m_next == 0)
  119                         break;
  120                 m = m->m_next;
  121         }
  122         if (len != 0) {
  123                 if (len < 0) {
  124                         INCSTAT(cns_toosmall);
  125                         clnp_discard(mhead, GEN_INCOMPLETE);
  126                         return 0;
  127                 }
  128                 if (len <= m->m_len)
  129                         m->m_len -= len;
  130                 else
  131                         m_adj(mhead, -len);
  132         }
  133         return mhead;
  134 }
  135 
  136 #ifdef notdef
  137 /*
  138  * FUNCTION:            clnp_extract_addr
  139  *
  140  * PURPOSE:             Extract the source and destination address from the
  141  *                      supplied buffer. Place them in the supplied address buffers.
  142  *                      If insufficient data is supplied, then fail.
  143  *
  144  * RETURNS:             success - Address of first byte in the packet past
  145  *                      the address part.
  146  *                      failure - 0
  147  *
  148  * SIDE EFFECTS:
  149  *
  150  * NOTES:
  151  */
  152 void *
  153 clnp_extract_addr(
  154         void *        bufp,     /* ptr to buffer containing addresses */
  155         int             buflen, /* length of buffer */
  156         struct iso_addr *srcp,  /* ptr to source address buffer */
  157         struct iso_addr *destp) /* ptr to destination address
  158                                                  * buffer */
  159 {
  160         size_t             len; /* argument to memcpy */
  161 
  162         /*
  163          * check that we have enough data. Plus1 is for length octet
  164          */
  165         len = (u_char)*bufp++;
  166         if (len > buflen)
  167                 return NULL;
  168         destp->isoa_len = len;
  169         (void)memcpy(destp, bufp, len);
  170         buflen -= len;
  171         bufp += len;
  172 
  173         /*
  174          * check that we have enough data. Plus1 is for length octet
  175          */
  176         len = (u_char)*bufp++;
  177         if (len > buflen)
  178                 return NULL;
  179         srcp->isoa_len = len;
  180         (void)memcpy(srcp, bufp, len);
  181         bufp += len;
  182 
  183         /*
  184          *      Insure that the addresses make sense
  185          */
  186         if (iso_ck_addr(srcp) && iso_ck_addr(destp))
  187                 return bufp;
  188         else
  189                 return NULL;
  190 }
  191 #endif                          /* notdef */
  192 
  193 /*
  194  * FUNCTION:            clnp_ours
  195  *
  196  * PURPOSE:             Decide whether the supplied packet is destined for
  197  *                      us, or that it should be forwarded on.
  198  *
  199  * RETURNS:             packet is for us - 1
  200  *                      packet is not for us - 0
  201  *
  202  * SIDE EFFECTS:
  203  *
  204  * NOTES:
  205  */
  206 int
  207 clnp_ours(
  208         struct iso_addr *dst)   /* ptr to destination address */
  209 {
  210         struct iso_ifaddr *ia;  /* scan through interface addresses */
  211 
  212         for (ia = iso_ifaddr.tqh_first; ia != 0; ia = ia->ia_list.tqe_next) {
  213 #ifdef ARGO_DEBUG
  214                 if (argo_debug[D_ROUTE]) {
  215                         printf("clnp_ours: ia_sis %p, dst %p\n",
  216                             &ia->ia_addr, dst);
  217                 }
  218 #endif
  219                 /*
  220                  * XXX Warning:
  221                  * We are overloading siso_tlen in the if's address, as an nsel length.
  222                  */
  223                 if (dst->isoa_len == ia->ia_addr.siso_nlen &&
  224                     bcmp((void *) ia->ia_addr.siso_addr.isoa_genaddr,
  225                          (void *) dst->isoa_genaddr,
  226                          ia->ia_addr.siso_nlen - ia->ia_addr.siso_tlen) == 0)
  227                         return 1;
  228         }
  229         return 0;
  230 }
  231 
  232 /* Dec bit set if ifp qlen is greater than congest_threshold */
  233 int             congest_threshold = 0;
  234 
  235 /*
  236  * FUNCTION:            clnp_forward
  237  *
  238  * PURPOSE:             Forward the datagram passed
  239  *                      clnpintr guarantees that the header will be
  240  *                      contigious (a cluster mbuf will be used if necessary).
  241  *
  242  *                      If oidx is NULL, no options are present.
  243  *
  244  * RETURNS:             nothing
  245  *
  246  * SIDE EFFECTS:
  247  *
  248  * NOTES:
  249  */
  250 void
  251 clnp_forward(
  252         struct mbuf    *m,              /* pkt to forward */
  253         int             len,            /* length of pkt */
  254         struct iso_addr *dst,           /* destination address */
  255         struct clnp_optidx *oidx,       /* option index */
  256         int             seg_off,        /* offset of segmentation part */
  257         struct snpa_hdr *inbound_shp)   /* subnetwork header of inbound
  258                                          * packet */
  259 {
  260         struct clnp_fixed *clnp;        /* ptr to fixed part of header */
  261         int             error;          /* return value of route function */
  262         const struct sockaddr *next_hop;        /* next hop for dgram */
  263         struct ifnet   *ifp;            /* ptr to outgoing interface */
  264         struct iso_ifaddr *ia = 0;      /* ptr to iso name for ifp */
  265         struct route route;             /* filled in by clnp_route */
  266         struct rtentry *rt;
  267         extern int      iso_systype;
  268 
  269         clnp = mtod(m, struct clnp_fixed *);
  270         bzero((void *) & route, sizeof(route)); /* MUST be done before
  271                                                          * "bad:" */
  272 
  273         /*
  274          *      Don't forward multicast or broadcast packets
  275          */
  276         if ((inbound_shp) && (IS_MULTICAST(inbound_shp->snh_dhost))) {
  277 #ifdef ARGO_DEBUG
  278                 if (argo_debug[D_FORWARD]) {
  279                         printf("clnp_forward: dropping multicast packet\n");
  280                 }
  281 #endif
  282                 clnp->cnf_type &= ~CNF_ERR_OK;  /* so we don't generate an ER */
  283                 clnp_discard(m, 0);
  284                 INCSTAT(cns_cantforward);
  285                 goto done;
  286         }
  287 #ifdef ARGO_DEBUG
  288         if (argo_debug[D_FORWARD]) {
  289                 printf("clnp_forward: %d bytes, to %s, options %p\n", len,
  290                        clnp_iso_addrp(dst), oidx);
  291         }
  292 #endif
  293 
  294         /*
  295          *      Decrement ttl, and if zero drop datagram
  296          *      Can't compare ttl as less than zero 'cause its a unsigned
  297          */
  298         if ((clnp->cnf_ttl == 0) || (--clnp->cnf_ttl == 0)) {
  299 #ifdef ARGO_DEBUG
  300                 if (argo_debug[D_FORWARD]) {
  301                         printf("clnp_forward: discarding datagram because ttl is zero\n");
  302                 }
  303 #endif
  304                 INCSTAT(cns_ttlexpired);
  305                 clnp_discard(m, TTL_EXPTRANSIT);
  306                 goto done;
  307         }
  308         /*
  309          *      Route packet; special case for source rt
  310          */
  311         if CLNPSRCRT_VALID
  312                 (oidx) {
  313                 /*
  314                  *      Update src route first
  315                  */
  316                 clnp_update_srcrt(m, oidx);
  317                 error = clnp_srcroute(m, oidx, &route, &next_hop, &ia, dst);
  318         } else {
  319                 error = clnp_route(dst, &route, 0, &next_hop, &ia);
  320         }
  321         if (error || ia == 0) {
  322 #ifdef ARGO_DEBUG
  323                 if (argo_debug[D_FORWARD]) {
  324                         printf("clnp_forward: can't route packet (errno %d)\n", error);
  325                 }
  326 #endif
  327                 clnp_discard(m, ADDR_DESTUNREACH);
  328                 INCSTAT(cns_cantforward);
  329                 goto done;
  330         }
  331         ifp = ia->ia_ifp;
  332 
  333 #ifdef ARGO_DEBUG
  334         if (argo_debug[D_FORWARD]) {
  335                 printf("clnp_forward: packet routed to %s\n",
  336                        clnp_iso_addrp(&satocsiso(next_hop)->siso_addr));
  337         }
  338 #endif
  339 
  340         INCSTAT(cns_forward);
  341 
  342         /*
  343          *      If we are an intermediate system and
  344          *      we are routing outbound on the same ifp that the packet
  345          *      arrived upon, and we know the next hop snpa,
  346          *      then generate a redirect request
  347          */
  348         if ((iso_systype & SNPA_IS) && (inbound_shp) &&
  349             (ifp == inbound_shp->snh_ifp))
  350                 esis_rdoutput(inbound_shp, m, oidx, dst, rtcache_validate(&route));
  351         /*
  352          *      If options are present, update them
  353          */
  354         if (oidx) {
  355                 struct iso_addr *mysrc = &ia->ia_addr.siso_addr;
  356                 if (mysrc == NULL) {
  357                         clnp_discard(m, ADDR_DESTUNREACH);
  358                         INCSTAT(cns_cantforward);
  359                         clnp_stat.cns_forward--;
  360                         goto done;
  361                 } else {
  362                         (void) clnp_dooptions(m, oidx, ifp, mysrc);
  363                 }
  364         }
  365 #ifdef  DECBIT
  366         if (ifp->if_snd.ifq_len > congest_threshold) {
  367                 /*
  368                  *      Congestion! Set the Dec Bit and thank Dave Oran
  369                  */
  370 #ifdef ARGO_DEBUG
  371                 if (argo_debug[D_FORWARD]) {
  372                         printf("clnp_forward: congestion experienced\n");
  373                 }
  374 #endif
  375                 if ((oidx) && (oidx->cni_qos_formatp)) {
  376                         char *         qosp = CLNP_OFFTOOPT(m, oidx->cni_qos_formatp);
  377                         u_char          qos = *qosp;
  378 #ifdef ARGO_DEBUG
  379                         if (argo_debug[D_FORWARD]) {
  380                                 printf("clnp_forward: setting congestion bit (qos x%x)\n", qos);
  381                         }
  382 #endif
  383                         if ((qos & CLNPOVAL_GLOBAL) == CLNPOVAL_GLOBAL) {
  384                                 qos |= CLNPOVAL_CONGESTED;
  385                                 INCSTAT(cns_congest_set);
  386                                 *qosp = qos;
  387                         }
  388                 }
  389         }
  390 #endif                          /* DECBIT */
  391 
  392         /*
  393          *      Dispatch the datagram if it is small enough, otherwise fragment
  394          */
  395         if ((rt = rtcache_validate(&route)) == NULL)
  396                 ;
  397         else if (len <= SN_MTU(ifp, rt)) {
  398                 iso_gen_csum(m, CLNP_CKSUM_OFF, (int) clnp->cnf_hdr_len);
  399                 (void) (*ifp->if_output) (ifp, m, next_hop, rt);
  400         } else {
  401                 (void) clnp_fragment(ifp, m, next_hop, len, seg_off, /* flags */ 0, rt);
  402         }
  403 
  404 done:
  405         /*
  406          *      Free route
  407          */
  408         rtcache_free(&route);
  409 }
  410 
  411 #ifdef  notdef
  412 /*
  413  * FUNCTION:            clnp_insert_addr
  414  *
  415  * PURPOSE:                     Insert the address part into a clnp datagram.
  416  *
  417  * RETURNS:                     Address of first byte after address part in datagram.
  418  *
  419  * SIDE EFFECTS:
  420  *
  421  * NOTES:                       Assume that there is enough space for the address part.
  422  */
  423 void *
  424 clnp_insert_addr(
  425         void *        bufp,     /* address of where addr part goes */
  426         struct iso_addr *srcp,  /* ptr to src addr */
  427         struct iso_addr *dstp)  /* ptr to dst addr */
  428 {
  429         *bufp++ = dstp->isoa_len;
  430         (void)memcpy(bufp, dstp, dstp->isoa_len);
  431         bufp += dstp->isoa_len;
  432 
  433         *bufp++ = srcp->isoa_len;
  434         (void)memcpy(bufp, srcp, srcp->isoa_len);
  435         bufp += srcp->isoa_len;
  436 
  437         return bufp;
  438 }
  439 
  440 #endif                          /* notdef */
  441 
  442 /*
  443  * FUNCTION:            clnp_route
  444  *
  445  * PURPOSE:             Route a clnp datagram to the first hop toward its
  446  *                      destination. In many cases, the first hop will be
  447  *                      the destination. The address of a route
  448  *                      is specified. If a routing entry is present in
  449  *                      that route, and it is still up to the same destination,
  450  *                      then no further action is necessary. Otherwise, a
  451  *                      new routing entry will be allocated.
  452  *
  453  * RETURNS:             route found - 0
  454  *                      unix error code
  455  *
  456  * SIDE EFFECTS:
  457  *
  458  * NOTES:               It is up to the caller to free the routing entry
  459  *                      allocated in route.
  460  */
  461 int
  462 clnp_route(
  463         struct iso_addr *dst,           /* ptr to datagram destination */
  464         struct route *ro,               /* existing route structure */
  465         int             flags,          /* flags for routing */
  466         const struct sockaddr **first_hop,      /* result: fill in with ptr to
  467                                                  * firsthop */
  468         struct iso_ifaddr **ifa)        /* result: fill in with ptr to ifa */
  469 {
  470         struct rtentry *rt;
  471         int rc;
  472         union {
  473                 struct sockaddr         dst;
  474                 struct sockaddr_iso     dsti;
  475         } u;
  476 
  477         if (flags & SO_DONTROUTE) {
  478                 struct iso_ifaddr *ia;
  479 
  480                 if ((rc = sockaddr_iso_init(&u.dsti, dst)) != 0)
  481                         return rc;
  482                 rtcache_setdst(ro, &u.dst);
  483 
  484                 if (rtcache_getdst(ro) == NULL)
  485                         return EADDRNOTAVAIL;
  486                 ia = iso_localifa(satocsiso(rtcache_getdst(ro)));
  487                 if (ia == NULL)
  488                         return EADDRNOTAVAIL;
  489                 if (ifa != NULL)
  490                         *ifa = ia;
  491                 if (first_hop != NULL)
  492                         *first_hop = rtcache_getdst(ro);
  493                 return 0;
  494         }
  495 
  496         /* set up new route structure */
  497         if ((rc = sockaddr_iso_init(&u.dsti, dst)) != 0)
  498                 return rc;
  499         if ((rt = rtcache_lookup(ro, &u.dst)) == NULL) {
  500                 rtcache_free(ro);
  501                 return ENETUNREACH;
  502         }
  503         rt->rt_use++;
  504         if (ifa != NULL)
  505                 if ((*ifa = (struct iso_ifaddr *)rt->rt_ifa) == NULL)
  506                         panic("clnp_route");
  507         if (first_hop != NULL) {
  508                 if (rt->rt_flags & RTF_GATEWAY)
  509                         *first_hop = rt->rt_gateway;
  510                 else
  511                         *first_hop = rtcache_getdst(ro);
  512         }
  513         return 0;
  514 }
  515 
  516 /*
  517  * FUNCTION:            clnp_srcroute
  518  *
  519  * PURPOSE:             Source route the datagram. If complete source
  520  *                      routing is specified but not possible, then
  521  *                      return an error. If src routing is terminated, then
  522  *                      try routing on destination.
  523  *                      Usage of first_hop,
  524  *                      ifp, and error return is identical to clnp_route.
  525  *
  526  * RETURNS:             0 or unix error code
  527  *
  528  * SIDE EFFECTS:
  529  *
  530  * NOTES:               Remember that option index pointers are really
  531  *                      offsets from the beginning of the mbuf.
  532  */
  533 int
  534 clnp_srcroute(
  535         struct mbuf *options,           /* ptr to options */
  536         struct clnp_optidx *oidx,       /* index to options */
  537         struct route *ro,               /* route structure */
  538         const struct sockaddr **first_hop,      /* RETURN: fill in with ptr to
  539                                                  * firsthop */
  540         struct iso_ifaddr **ifa,        /* RETURN: fill in with ptr to ifa */
  541         struct iso_addr *final_dst)     /* final destination */
  542 {
  543         struct iso_addr dst;    /* first hop specified by src rt */
  544         int             error = 0;      /* return code */
  545 
  546         /*
  547          *      Check if we have run out of routes
  548          *      If so, then try to route on destination.
  549          */
  550         if CLNPSRCRT_TERM
  551                 (oidx, options) {
  552                 dst.isoa_len = final_dst->isoa_len;
  553                 if (sizeof(dst.isoa_genaddr) < (size_t)dst.isoa_len)
  554                         return EINVAL;
  555                 (void)memcpy(dst.isoa_genaddr, final_dst->isoa_genaddr,
  556                     (size_t)dst.isoa_len);
  557         } else {
  558                 /*
  559                  * setup dst based on src rt specified
  560                  */
  561                 dst.isoa_len = CLNPSRCRT_CLEN(oidx, options);
  562                 if (sizeof(dst.isoa_genaddr) < (unsigned)dst.isoa_len)
  563                         return EINVAL;
  564                 (void)memcpy(dst.isoa_genaddr, CLNPSRCRT_CADDR(oidx, options),
  565                     (size_t)dst.isoa_len);
  566         }
  567 
  568         /*
  569          *      try to route it
  570          */
  571         error = clnp_route(&dst, ro, 0, first_hop, ifa);
  572         if (error != 0)
  573                 return error;
  574 
  575         /*
  576          *      If complete src rt, first hop must be equal to dst
  577          */
  578         if ((CLNPSRCRT_TYPE(oidx, options) == CLNPOVAL_COMPRT) &&
  579             (!iso_addrmatch1(&satocsiso(*first_hop)->siso_addr, &dst))) {
  580 #ifdef ARGO_DEBUG
  581                 if (argo_debug[D_OPTIONS]) {
  582                         printf("clnp_srcroute: complete src route failed\n");
  583                 }
  584 #endif
  585                 return EHOSTUNREACH;    /* RAH? would like ESRCRTFAILED */
  586         }
  587         return error;
  588 }
  589 
  590 /*
  591  * FUNCTION:            clnp_echoreply
  592  *
  593  * PURPOSE:                     generate an echo reply packet and transmit
  594  *
  595  * RETURNS:                     result of clnp_output
  596  *
  597  * SIDE EFFECTS:
  598  */
  599 int
  600 clnp_echoreply(
  601     struct mbuf    *ec_m,               /* echo request */
  602     int             ec_len,             /* length of ec */
  603     struct sockaddr_iso *ec_src,        /* src of ec */
  604     struct sockaddr_iso *ec_dst,        /* destination of ec (i.e., us) */
  605     struct clnp_optidx *ec_oidxp) /* options index to ec packet */
  606 {
  607         struct isopcb   isopcb;
  608         int             flags = CLNP_NOCACHE | CLNP_ECHOR;
  609         int             ret;
  610 
  611         /* fill in fake isopcb to pass to output function */
  612         bzero(&isopcb, sizeof(isopcb));
  613         isopcb.isop_laddr = ec_dst;
  614         isopcb.isop_faddr = ec_src;
  615 
  616         /*
  617          * forget copying the options for now. If implemented, need only copy
  618          * record route option, but it must be reset to zero length
  619          */
  620 
  621         ret = clnp_output(ec_m, &isopcb, ec_len, flags);
  622 
  623 #ifdef ARGO_DEBUG
  624         if (argo_debug[D_OUTPUT]) {
  625                 printf("clnp_echoreply: output returns %d\n", ret);
  626         }
  627 #endif
  628         return ret;
  629 }
  630 
  631 /*
  632  * FUNCTION:            clnp_badmtu
  633  *
  634  * PURPOSE:             print notice of route with mtu not initialized.
  635  *
  636  * RETURNS:             mtu of ifp.
  637  *
  638  * SIDE EFFECTS:        prints notice, slows down system.
  639  */
  640 int
  641 clnp_badmtu(
  642         struct ifnet   *ifp,    /* outgoing interface */
  643         struct rtentry *rt,     /* dst route */
  644         int             line,   /* where the dirty deed occurred */
  645         const char     *file)   /* where the dirty deed occurred */
  646 {
  647         printf("sending on route %p with no mtu, line %d of file %s\n",
  648             rt, line, file);
  649 #ifdef ARGO_DEBUG
  650         printf("route dst is ");
  651         dump_isoaddr(satocsiso(rt_getkey(rt)));
  652 #endif
  653         return ifp->if_mtu;
  654 }
  655 
  656 /*
  657  * FUNCTION:            clnp_ypocb - backwards bcopy
  658  *
  659  * PURPOSE:             bcopy starting at end of src rather than beginning.
  660  *
  661  * RETURNS:             none
  662  *
  663  * SIDE EFFECTS:
  664  *
  665  * NOTES:               No attempt has been made to make this efficient
  666  */
  667 void
  668 clnp_ypocb(
  669         void *        from,     /* src buffer */
  670         void *        to,       /* dst buffer */
  671         u_int           len)    /* number of bytes */
  672 {
  673         while (len--)
  674                 *((char *)to + len) = *((char *)from + len);
  675 }
  676 #endif                          /* ISO */

Cache object: 77360be3e64bb0f8c488e1ba8f52017d


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