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.15.2.1 2007/03/29 08:57:16 ghen 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.15.2.1 2007/03/29 08:57:16 ghen 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(m, length)
  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 caddr_t
  153 clnp_extract_addr(bufp, buflen, srcp, destp)
  154         caddr_t         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(dst)
  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((caddr_t) ia->ia_addr.siso_addr.isoa_genaddr,
  225                          (caddr_t) 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(m, len, dst, oidx, seg_off, inbound_shp)
  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         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_iso route; /* filled in by clnp_route */
  266         extern int      iso_systype;
  267 
  268         clnp = mtod(m, struct clnp_fixed *);
  269         bzero((caddr_t) & route, sizeof(route));        /* MUST be done before
  270                                                          * "bad:" */
  271 
  272         /*
  273          *      Don't forward multicast or broadcast packets
  274          */
  275         if ((inbound_shp) && (IS_MULTICAST(inbound_shp->snh_dhost))) {
  276 #ifdef ARGO_DEBUG
  277                 if (argo_debug[D_FORWARD]) {
  278                         printf("clnp_forward: dropping multicast packet\n");
  279                 }
  280 #endif
  281                 clnp->cnf_type &= ~CNF_ERR_OK;  /* so we don't generate an ER */
  282                 clnp_discard(m, 0);
  283                 INCSTAT(cns_cantforward);
  284                 goto done;
  285         }
  286 #ifdef ARGO_DEBUG
  287         if (argo_debug[D_FORWARD]) {
  288                 printf("clnp_forward: %d bytes, to %s, options %p\n", len,
  289                        clnp_iso_addrp(dst), oidx);
  290         }
  291 #endif
  292 
  293         /*
  294          *      Decrement ttl, and if zero drop datagram
  295          *      Can't compare ttl as less than zero 'cause its a unsigned
  296          */
  297         if ((clnp->cnf_ttl == 0) || (--clnp->cnf_ttl == 0)) {
  298 #ifdef ARGO_DEBUG
  299                 if (argo_debug[D_FORWARD]) {
  300                         printf("clnp_forward: discarding datagram because ttl is zero\n");
  301                 }
  302 #endif
  303                 INCSTAT(cns_ttlexpired);
  304                 clnp_discard(m, TTL_EXPTRANSIT);
  305                 goto done;
  306         }
  307         /*
  308          *      Route packet; special case for source rt
  309          */
  310         if CLNPSRCRT_VALID
  311                 (oidx) {
  312                 /*
  313                  *      Update src route first
  314                  */
  315                 clnp_update_srcrt(m, oidx);
  316                 error = clnp_srcroute(m, oidx, &route, &next_hop, &ia, dst);
  317         } else {
  318                 error = clnp_route(dst, &route, 0, &next_hop, &ia);
  319         }
  320         if (error || ia == 0) {
  321 #ifdef ARGO_DEBUG
  322                 if (argo_debug[D_FORWARD]) {
  323                         printf("clnp_forward: can't route packet (errno %d)\n", error);
  324                 }
  325 #endif
  326                 clnp_discard(m, ADDR_DESTUNREACH);
  327                 INCSTAT(cns_cantforward);
  328                 goto done;
  329         }
  330         ifp = ia->ia_ifp;
  331 
  332 #ifdef ARGO_DEBUG
  333         if (argo_debug[D_FORWARD]) {
  334                 printf("clnp_forward: packet routed to %s\n",
  335                        clnp_iso_addrp(&satosiso(next_hop)->siso_addr));
  336         }
  337 #endif
  338 
  339         INCSTAT(cns_forward);
  340 
  341         /*
  342          *      If we are an intermediate system and
  343          *      we are routing outbound on the same ifp that the packet
  344          *      arrived upon, and we know the next hop snpa,
  345          *      then generate a redirect request
  346          */
  347         if ((iso_systype & SNPA_IS) && (inbound_shp) &&
  348             (ifp == inbound_shp->snh_ifp))
  349                 esis_rdoutput(inbound_shp, m, oidx, dst, route.ro_rt);
  350         /*
  351          *      If options are present, update them
  352          */
  353         if (oidx) {
  354                 struct iso_addr *mysrc = &ia->ia_addr.siso_addr;
  355                 if (mysrc == NULL) {
  356                         clnp_discard(m, ADDR_DESTUNREACH);
  357                         INCSTAT(cns_cantforward);
  358                         clnp_stat.cns_forward--;
  359                         goto done;
  360                 } else {
  361                         (void) clnp_dooptions(m, oidx, ifp, mysrc);
  362                 }
  363         }
  364 #ifdef  DECBIT
  365         if (ifp->if_snd.ifq_len > congest_threshold) {
  366                 /*
  367                  *      Congestion! Set the Dec Bit and thank Dave Oran
  368                  */
  369 #ifdef ARGO_DEBUG
  370                 if (argo_debug[D_FORWARD]) {
  371                         printf("clnp_forward: congestion experienced\n");
  372                 }
  373 #endif
  374                 if ((oidx) && (oidx->cni_qos_formatp)) {
  375                         caddr_t         qosp = CLNP_OFFTOOPT(m, oidx->cni_qos_formatp);
  376                         u_char          qos = *qosp;
  377 #ifdef ARGO_DEBUG
  378                         if (argo_debug[D_FORWARD]) {
  379                                 printf("clnp_forward: setting congestion bit (qos x%x)\n", qos);
  380                         }
  381 #endif
  382                         if ((qos & CLNPOVAL_GLOBAL) == CLNPOVAL_GLOBAL) {
  383                                 qos |= CLNPOVAL_CONGESTED;
  384                                 INCSTAT(cns_congest_set);
  385                                 *qosp = qos;
  386                         }
  387                 }
  388         }
  389 #endif                          /* DECBIT */
  390 
  391         /*
  392          *      Dispatch the datagram if it is small enough, otherwise fragment
  393          */
  394         if (len <= SN_MTU(ifp, route.ro_rt)) {
  395                 iso_gen_csum(m, CLNP_CKSUM_OFF, (int) clnp->cnf_hdr_len);
  396                 (void) (*ifp->if_output) (ifp, m, next_hop, route.ro_rt);
  397         } else {
  398                 (void) clnp_fragment(ifp, m, next_hop, len, seg_off, /* flags */ 0, route.ro_rt);
  399         }
  400 
  401 done:
  402         /*
  403          *      Free route
  404          */
  405         if (route.ro_rt != NULL) {
  406                 RTFREE(route.ro_rt);
  407         }
  408 }
  409 
  410 #ifdef  notdef
  411 /*
  412  * FUNCTION:            clnp_insert_addr
  413  *
  414  * PURPOSE:                     Insert the address part into a clnp datagram.
  415  *
  416  * RETURNS:                     Address of first byte after address part in datagram.
  417  *
  418  * SIDE EFFECTS:
  419  *
  420  * NOTES:                       Assume that there is enough space for the address part.
  421  */
  422 caddr_t
  423 clnp_insert_addr(bufp, srcp, dstp)
  424         caddr_t         bufp;   /* address of where addr part goes */
  425         struct iso_addr *srcp;  /* ptr to src addr */
  426         struct iso_addr *dstp;  /* ptr to dst addr */
  427 {
  428         *bufp++ = dstp->isoa_len;
  429         (void)memcpy(bufp, dstp, dstp->isoa_len);
  430         bufp += dstp->isoa_len;
  431 
  432         *bufp++ = srcp->isoa_len;
  433         (void)memcpy(bufp, srcp, srcp->isoa_len);
  434         bufp += srcp->isoa_len;
  435 
  436         return bufp;
  437 }
  438 
  439 #endif                          /* notdef */
  440 
  441 /*
  442  * FUNCTION:            clnp_route
  443  *
  444  * PURPOSE:             Route a clnp datagram to the first hop toward its
  445  *                      destination. In many cases, the first hop will be
  446  *                      the destination. The address of a route
  447  *                      is specified. If a routing entry is present in
  448  *                      that route, and it is still up to the same destination,
  449  *                      then no further action is necessary. Otherwise, a
  450  *                      new routing entry will be allocated.
  451  *
  452  * RETURNS:             route found - 0
  453  *                      unix error code
  454  *
  455  * SIDE EFFECTS:
  456  *
  457  * NOTES:               It is up to the caller to free the routing entry
  458  *                      allocated in route.
  459  */
  460 int
  461 clnp_route(dst, ro, flags, first_hop, ifa)
  462         struct iso_addr *dst;   /* ptr to datagram destination */
  463         struct route_iso *ro;   /* existing route structure */
  464         int             flags;  /* flags for routing */
  465         struct sockaddr **first_hop;    /* result: fill in with ptr to
  466                                          * firsthop */
  467         struct iso_ifaddr **ifa;/* result: fill in with ptr to interface */
  468 {
  469         if (flags & SO_DONTROUTE) {
  470                 struct iso_ifaddr *ia;
  471                 size_t len = 1 + (unsigned)dst->isoa_len;
  472 
  473                 if (ro->ro_rt) {
  474                         RTFREE(ro->ro_rt);
  475                         ro->ro_rt = 0;
  476                 }
  477                 if (sizeof(ro->ro_dst.siso_addr) < len)
  478                     return EINVAL;
  479                 (void)memset(&ro->ro_dst, 0, sizeof(ro->ro_dst));
  480                 (void)memcpy(&ro->ro_dst.siso_addr, dst, len);
  481                 ro->ro_dst.siso_family = AF_ISO;
  482                 ro->ro_dst.siso_len = sizeof(ro->ro_dst);
  483                 ia = iso_localifa(&ro->ro_dst);
  484                 if (ia == 0)
  485                         return EADDRNOTAVAIL;
  486                 if (ifa)
  487                         *ifa = ia;
  488                 if (first_hop)
  489                         *first_hop = sisotosa(&ro->ro_dst);
  490                 return 0;
  491         }
  492         /*
  493          *      If there is a cached route, check that it is still up and to
  494          *      the same destination. If not, free it and try again.
  495          */
  496         if (ro->ro_rt && ((ro->ro_rt->rt_flags & RTF_UP) == 0 ||
  497           (Bcmp(ro->ro_dst.siso_data, dst->isoa_genaddr, dst->isoa_len)))) {
  498 #ifdef ARGO_DEBUG
  499                 if (argo_debug[D_ROUTE]) {
  500                         printf("clnp_route: freeing old route: ro->ro_rt %p\n",
  501                             ro->ro_rt);
  502                         printf("clnp_route: old route refcnt: 0x%x\n",
  503                             ro->ro_rt->rt_refcnt);
  504                 }
  505 #endif
  506 
  507                 /* free old route entry */
  508                 RTFREE(ro->ro_rt);
  509                 ro->ro_rt = (struct rtentry *) 0;
  510         } else {
  511 #ifdef ARGO_DEBUG
  512                 if (argo_debug[D_ROUTE]) {
  513                         printf("clnp_route: OK route exists\n");
  514                 }
  515 #endif
  516         }
  517 
  518         if (ro->ro_rt == 0) {
  519                 size_t len = 1 + (unsigned)dst->isoa_len;
  520 
  521                 /* set up new route structure */
  522                 if (sizeof(ro->ro_dst.siso_addr) < len)
  523                     return EINVAL;
  524                 (void)memset(&ro->ro_dst, 0, sizeof(ro->ro_dst));
  525                 ro->ro_dst.siso_len = sizeof(ro->ro_dst);
  526                 ro->ro_dst.siso_family = AF_ISO;
  527                 (void)memcpy(&ro->ro_dst.siso_addr, dst, len);
  528                 /* allocate new route */
  529 #ifdef ARGO_DEBUG
  530                 if (argo_debug[D_ROUTE]) {
  531                         printf("clnp_route: allocating new route to %s\n",
  532                             clnp_iso_addrp(dst));
  533                 }
  534 #endif
  535                 rtalloc((struct route *) ro);
  536         }
  537         if (ro->ro_rt == 0)
  538                 return (ENETUNREACH);   /* rtalloc failed */
  539         ro->ro_rt->rt_use++;
  540         if (ifa)
  541                 if ((*ifa = (struct iso_ifaddr *) ro->ro_rt->rt_ifa) == 0)
  542                         panic("clnp_route");
  543         if (first_hop) {
  544                 if (ro->ro_rt->rt_flags & RTF_GATEWAY)
  545                         *first_hop = ro->ro_rt->rt_gateway;
  546                 else
  547                         *first_hop = sisotosa(&ro->ro_dst);
  548         }
  549         return (0);
  550 }
  551 
  552 /*
  553  * FUNCTION:            clnp_srcroute
  554  *
  555  * PURPOSE:             Source route the datagram. If complete source
  556  *                      routing is specified but not possible, then
  557  *                      return an error. If src routing is terminated, then
  558  *                      try routing on destination.
  559  *                      Usage of first_hop,
  560  *                      ifp, and error return is identical to clnp_route.
  561  *
  562  * RETURNS:             0 or unix error code
  563  *
  564  * SIDE EFFECTS:
  565  *
  566  * NOTES:               Remember that option index pointers are really
  567  *                      offsets from the beginning of the mbuf.
  568  */
  569 int
  570 clnp_srcroute(options, oidx, ro, first_hop, ifa, final_dst)
  571         struct mbuf    *options;/* ptr to options */
  572         struct clnp_optidx *oidx;       /* index to options */
  573         struct route_iso *ro;   /* route structure */
  574         struct sockaddr **first_hop;    /* RETURN: fill in with ptr to
  575                                          * firsthop */
  576         struct iso_ifaddr **ifa;/* RETURN: fill in with ptr to interface */
  577         struct iso_addr *final_dst;     /* final destination */
  578 {
  579         struct iso_addr dst;    /* first hop specified by src rt */
  580         int             error = 0;      /* return code */
  581 
  582         /*
  583          *      Check if we have run out of routes
  584          *      If so, then try to route on destination.
  585          */
  586         if CLNPSRCRT_TERM
  587                 (oidx, options) {
  588                 dst.isoa_len = final_dst->isoa_len;
  589                 if (sizeof(dst.isoa_genaddr) < (size_t)dst.isoa_len)
  590                     return EINVAL;
  591                 (void)memcpy(dst.isoa_genaddr, final_dst->isoa_genaddr,
  592                     (size_t)dst.isoa_len);
  593         } else {
  594                 /*
  595                  * setup dst based on src rt specified
  596                  */
  597                 dst.isoa_len = CLNPSRCRT_CLEN(oidx, options);
  598                 if (sizeof(dst.isoa_genaddr) < (unsigned)dst.isoa_len)
  599                     return EINVAL;
  600                 (void)memcpy(dst.isoa_genaddr, CLNPSRCRT_CADDR(oidx, options),
  601                     (size_t)dst.isoa_len);
  602         }
  603 
  604         /*
  605          *      try to route it
  606          */
  607         error = clnp_route(&dst, ro, 0, first_hop, ifa);
  608         if (error != 0)
  609                 return error;
  610 
  611         /*
  612          *      If complete src rt, first hop must be equal to dst
  613          */
  614         if ((CLNPSRCRT_TYPE(oidx, options) == CLNPOVAL_COMPRT) &&
  615             (!iso_addrmatch1(&satosiso(*first_hop)->siso_addr, &dst))) {
  616 #ifdef ARGO_DEBUG
  617                 if (argo_debug[D_OPTIONS]) {
  618                         printf("clnp_srcroute: complete src route failed\n");
  619                 }
  620 #endif
  621                 return EHOSTUNREACH;    /* RAH? would like ESRCRTFAILED */
  622         }
  623         return error;
  624 }
  625 
  626 /*
  627  * FUNCTION:            clnp_echoreply
  628  *
  629  * PURPOSE:                     generate an echo reply packet and transmit
  630  *
  631  * RETURNS:                     result of clnp_output
  632  *
  633  * SIDE EFFECTS:
  634  */
  635 int
  636 clnp_echoreply(ec_m, ec_len, ec_src, ec_dst, ec_oidxp)
  637         struct mbuf    *ec_m;   /* echo request */
  638         int             ec_len; /* length of ec */
  639         struct sockaddr_iso *ec_src;    /* src of ec */
  640         struct sockaddr_iso *ec_dst;    /* destination of ec (i.e., us) */
  641         struct clnp_optidx *ec_oidxp;   /* options index to ec packet */
  642 {
  643         struct isopcb   isopcb;
  644         int             flags = CLNP_NOCACHE | CLNP_ECHOR;
  645         int             ret;
  646 
  647         /* fill in fake isopcb to pass to output function */
  648         bzero(&isopcb, sizeof(isopcb));
  649         isopcb.isop_laddr = ec_dst;
  650         isopcb.isop_faddr = ec_src;
  651 
  652         /*
  653          * forget copying the options for now. If implemented, need only copy
  654          * record route option, but it must be reset to zero length
  655          */
  656 
  657         ret = clnp_output(ec_m, &isopcb, ec_len, flags);
  658 
  659 #ifdef ARGO_DEBUG
  660         if (argo_debug[D_OUTPUT]) {
  661                 printf("clnp_echoreply: output returns %d\n", ret);
  662         }
  663 #endif
  664         return ret;
  665 }
  666 
  667 /*
  668  * FUNCTION:            clnp_badmtu
  669  *
  670  * PURPOSE:             print notice of route with mtu not initialized.
  671  *
  672  * RETURNS:             mtu of ifp.
  673  *
  674  * SIDE EFFECTS:        prints notice, slows down system.
  675  */
  676 int
  677 clnp_badmtu(ifp, rt, line, file)
  678         struct ifnet   *ifp;    /* outgoing interface */
  679         struct rtentry *rt;     /* dst route */
  680         int             line;   /* where the dirty deed occurred */
  681         char           *file;   /* where the dirty deed occurred */
  682 {
  683         printf("sending on route %p with no mtu, line %d of file %s\n",
  684             rt, line, file);
  685 #ifdef ARGO_DEBUG
  686         printf("route dst is ");
  687         dump_isoaddr((struct sockaddr_iso *) rt_key(rt));
  688 #endif
  689         return ifp->if_mtu;
  690 }
  691 
  692 /*
  693  * FUNCTION:            clnp_ypocb - backwards bcopy
  694  *
  695  * PURPOSE:             bcopy starting at end of src rather than beginning.
  696  *
  697  * RETURNS:             none
  698  *
  699  * SIDE EFFECTS:
  700  *
  701  * NOTES:               No attempt has been made to make this efficient
  702  */
  703 void
  704 clnp_ypocb(from, to, len)
  705         caddr_t         from;   /* src buffer */
  706         caddr_t         to;     /* dst buffer */
  707         u_int           len;    /* number of bytes */
  708 {
  709         while (len--)
  710                 *(to + len) = *(from + len);
  711 }
  712 #endif                          /* ISO */

Cache object: 7e5876a5c556b655b168faff4e400975


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