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/tp_iso.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: tp_iso.c,v 1.17 2003/09/30 00:01:18 christos 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  *      @(#)tp_iso.c    8.2 (Berkeley) 9/22/94
   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  * Here is where you find the iso-dependent code.  We've tried keep all
   62  * net-level and (primarily) address-family-dependent stuff out of the tp
   63  * source, and everthing here is reached indirectly through a switch table
   64  * (struct nl_protosw *) tpcb->tp_nlproto (see tp_pcb.c). The routines here
   65  * are: iso_getsufx: gets transport suffix out of an isopcb structure.
   66  * iso_putsufx: put transport suffix into an isopcb structure.
   67  * iso_putnetaddr: put a whole net addr into an isopcb. iso_getnetaddr: get a
   68  * whole net addr from an isopcb. iso_cmpnetaddr: compare a whole net addr
   69  * from an isopcb. iso_recycle_suffix: clear suffix for reuse in isopcb
   70  * tpclnp_ctlinput: handle ER CNLPdu : icmp-like stuff tpclnp_mtu: figure out
   71  * what size tpdu to use tpclnp_input: take a pkt from clnp, strip off its
   72  * clnp header, give to tp tpclnp_output_dg: package a pkt for clnp given 2
   73  * addresses & some data tpclnp_output: package a pkt for clnp given an
   74  * isopcb & some data
   75  */
   76 
   77 #include <sys/cdefs.h>
   78 __KERNEL_RCSID(0, "$NetBSD: tp_iso.c,v 1.17 2003/09/30 00:01:18 christos Exp $");
   79 
   80 #include "opt_iso.h"
   81 #ifdef ISO
   82 
   83 #include <sys/param.h>
   84 #include <sys/socket.h>
   85 #include <sys/socketvar.h>
   86 #include <sys/domain.h>
   87 #include <sys/malloc.h>
   88 #include <sys/mbuf.h>
   89 #include <sys/errno.h>
   90 #include <sys/time.h>
   91 #include <sys/protosw.h>
   92 #include <sys/systm.h>
   93 #include <sys/kernel.h>
   94 
   95 #include <net/if.h>
   96 #include <net/route.h>
   97 
   98 #include <netiso/argo_debug.h>
   99 #include <netiso/tp_param.h>
  100 #include <netiso/tp_stat.h>
  101 #include <netiso/tp_pcb.h>
  102 #include <netiso/tp_trace.h>
  103 #include <netiso/tp_stat.h>
  104 #include <netiso/tp_tpdu.h>
  105 #include <netiso/tp_clnp.h>
  106 #include <netiso/tp_var.h>
  107 #include <netiso/cltp_var.h>
  108 #include <netiso/idrp_var.h>
  109 
  110 #include <machine/stdarg.h>
  111 
  112 /*
  113  * CALLED FROM:
  114  *      pr_usrreq() on PRU_BIND, PRU_CONNECT, PRU_ACCEPT, and PRU_PEERADDR
  115  * FUNCTION, ARGUMENTS:
  116  *      The argument (which) takes the value TP_LOCAL or TP_FOREIGN.
  117  */
  118 
  119 void
  120 iso_getsufx(v, lenp, data_out, which)
  121         void           *v;
  122         u_short        *lenp;
  123         caddr_t         data_out;
  124         int             which;
  125 {
  126         struct isopcb  *isop = v;
  127         struct sockaddr_iso *addr = 0;
  128 
  129         switch (which) {
  130         case TP_LOCAL:
  131                 addr = isop->isop_laddr;
  132                 break;
  133 
  134         case TP_FOREIGN:
  135                 addr = isop->isop_faddr;
  136         }
  137         if (addr)
  138                 bcopy(TSEL(addr), data_out, (*lenp = addr->siso_tlen));
  139 }
  140 
  141 /*
  142  * CALLED FROM: tp_newsocket(); i.e., when a connection is being established
  143  * by an incoming CR_TPDU.
  144  *
  145  * FUNCTION, ARGUMENTS: Put a transport suffix (found in name) into an isopcb
  146  * structure (isop). The argument (which) takes the value TP_LOCAL or
  147  * TP_FOREIGN.
  148  */
  149 void
  150 iso_putsufx(v, sufxloc, sufxlen, which)
  151         void           *v;
  152         caddr_t         sufxloc;
  153         int             sufxlen, which;
  154 {
  155         struct isopcb  *isop = v;
  156         struct sockaddr_iso **dst, *backup;
  157         struct sockaddr_iso *addr;
  158         struct mbuf    *m;
  159         int             len;
  160 
  161         switch (which) {
  162         default:
  163                 return;
  164 
  165         case TP_LOCAL:
  166                 dst = &isop->isop_laddr;
  167                 backup = &isop->isop_sladdr;
  168                 break;
  169 
  170         case TP_FOREIGN:
  171                 dst = &isop->isop_faddr;
  172                 backup = &isop->isop_sfaddr;
  173         }
  174         if ((addr = *dst) == 0) {
  175                 addr = *dst = backup;
  176                 addr->siso_nlen = 0;
  177                 addr->siso_slen = 0;
  178                 addr->siso_plen = 0;
  179                 printf("iso_putsufx on un-initialized isopcb\n");
  180         }
  181         len = sufxlen + addr->siso_nlen +
  182                 (sizeof(*addr) - sizeof(addr->siso_data));
  183         if (addr == backup) {
  184                 if (len > sizeof(*addr)) {
  185                         m = m_getclr(M_DONTWAIT, MT_SONAME);
  186                         if (m == 0)
  187                                 return;
  188                         addr = *dst = mtod(m, struct sockaddr_iso *);
  189                         *addr = *backup;
  190                         m->m_len = len;
  191                 }
  192         }
  193         bcopy(sufxloc, TSEL(addr), sufxlen);
  194         addr->siso_tlen = sufxlen;
  195         addr->siso_len = len;
  196 }
  197 
  198 /*
  199  * CALLED FROM:
  200  *      tp.trans whenever we go into REFWAIT state.
  201  * FUNCTION and ARGUMENT:
  202  *       Called when a ref is frozen, to allow the suffix to be reused.
  203  *      (isop) is the net level pcb.  This really shouldn't have to be
  204  *      done in a NET level pcb but... for the internet world that just
  205  *      the way it is done in BSD...
  206  *      The alternative is to have the port unusable until the reference
  207  *      timer goes off.
  208  */
  209 void
  210 iso_recycle_tsuffix(v)
  211         void *v;
  212 {
  213         struct isopcb *isop = v;
  214         isop->isop_laddr->siso_tlen = isop->isop_faddr->siso_tlen = 0;
  215 }
  216 
  217 /*
  218  * CALLED FROM:
  219  *      tp_newsocket(); i.e., when a connection is being established by an
  220  *      incoming CR_TPDU.
  221  *
  222  * FUNCTION and ARGUMENTS:
  223  *      Copy a whole net addr from a struct sockaddr (name).
  224  *      into an isopcb (isop).
  225  *      The argument (which) takes values TP_LOCAL or TP_FOREIGN
  226  */
  227 void
  228 iso_putnetaddr(v, nm, which)
  229         void *v;
  230         struct sockaddr *nm;
  231         int             which;
  232 {
  233         struct isopcb *isop = v;
  234         struct sockaddr_iso *name = (struct sockaddr_iso *) nm;
  235         struct sockaddr_iso **sisop, *backup;
  236         struct sockaddr_iso *siso;
  237 
  238         switch (which) {
  239         default:
  240                 printf("iso_putnetaddr: should panic\n");
  241                 return;
  242         case TP_LOCAL:
  243                 sisop = &isop->isop_laddr;
  244                 backup = &isop->isop_sladdr;
  245                 break;
  246         case TP_FOREIGN:
  247                 sisop = &isop->isop_faddr;
  248                 backup = &isop->isop_sfaddr;
  249         }
  250         siso = ((*sisop == 0) ? (*sisop = backup) : *sisop);
  251 #ifdef ARGO_DEBUG
  252         if (argo_debug[D_TPISO]) {
  253                 printf("ISO_PUTNETADDR\n");
  254                 dump_isoaddr(isop->isop_faddr);
  255         }
  256 #endif
  257         siso->siso_addr = name->siso_addr;
  258 }
  259 
  260 /*
  261  * CALLED FROM:
  262  *      tp_input() when a connection is being established by an
  263  *      incoming CR_TPDU, and considered for interception.
  264  *
  265  * FUNCTION and ARGUMENTS:
  266  *      compare a whole net addr from a struct sockaddr (name),
  267  *      with that implicitly stored in an isopcb (isop).
  268  *      The argument (which) takes values TP_LOCAL or TP_FOREIGN.
  269  */
  270 int
  271 iso_cmpnetaddr(v, nm, which)
  272         void *v;
  273         struct sockaddr *nm;
  274         int             which;
  275 {
  276         struct isopcb *isop = v;
  277         struct sockaddr_iso *name = (struct sockaddr_iso *) nm;
  278         struct sockaddr_iso **sisop, *backup;
  279         struct sockaddr_iso *siso;
  280 
  281         switch (which) {
  282         default:
  283                 printf("iso_cmpnetaddr: should panic\n");
  284                 return 0;
  285         case TP_LOCAL:
  286                 sisop = &isop->isop_laddr;
  287                 backup = &isop->isop_sladdr;
  288                 break;
  289         case TP_FOREIGN:
  290                 sisop = &isop->isop_faddr;
  291                 backup = &isop->isop_sfaddr;
  292         }
  293         siso = ((*sisop == 0) ? (*sisop = backup) : *sisop);
  294 #ifdef ARGO_DEBUG
  295         if (argo_debug[D_TPISO]) {
  296                 printf("ISO_CMPNETADDR\n");
  297                 dump_isoaddr(siso);
  298         }
  299 #endif
  300         if (name->siso_tlen && bcmp(TSEL(name), TSEL(siso), name->siso_tlen))
  301                 return (0);
  302         return (bcmp((caddr_t) name->siso_data,
  303                      (caddr_t) siso->siso_data, name->siso_nlen) == 0);
  304 }
  305 
  306 /*
  307  * CALLED FROM:
  308  *  pr_usrreq() PRU_SOCKADDR, PRU_ACCEPT, PRU_PEERADDR
  309  * FUNCTION and ARGUMENTS:
  310  *      Copy a whole net addr from an isopcb (isop) into
  311  *      a struct sockaddr (name).
  312  *      The argument (which) takes values TP_LOCAL or TP_FOREIGN.
  313  */
  314 
  315 void
  316 iso_getnetaddr(v, name, which)
  317         void *v;
  318         struct mbuf    *name;
  319         int             which;
  320 {
  321         struct inpcb *inp = v;
  322         struct isopcb *isop = (struct isopcb *) inp;
  323         struct sockaddr_iso *siso =
  324         (which == TP_LOCAL ? isop->isop_laddr : isop->isop_faddr);
  325         if (siso)
  326                 bcopy((caddr_t) siso, mtod(name, caddr_t),
  327                       (unsigned) (name->m_len = siso->siso_len));
  328         else
  329                 name->m_len = 0;
  330 }
  331 /*
  332  * NAME:        tpclnp_mtu()
  333  *
  334  * CALLED FROM:
  335  *  tp_route_to() on incoming CR, CC, and pr_usrreq() for PRU_CONNECT
  336  *
  337  * FUNCTION, ARGUMENTS, and RETURN VALUE:
  338  *
  339  * Perform subnetwork dependent part of determining MTU information.
  340  * It appears that setting a double pointer to the rtentry associated with
  341  * the destination, and returning the header size for the network protocol
  342  * suffices.
  343  *
  344  * SIDE EFFECTS:
  345  * Sets tp_routep pointer in pcb.
  346  *
  347  * NOTES:
  348  */
  349 int
  350 tpclnp_mtu(v)
  351         void *v;
  352 {
  353         struct tp_pcb *tpcb = v;
  354         struct isopcb  *isop = (struct isopcb *) tpcb->tp_npcb;
  355 
  356 #ifdef ARGO_DEBUG
  357         if (argo_debug[D_CONN]) {
  358                 printf("tpclnp_mtu(tpcb %p)\n", tpcb);
  359         }
  360 #endif
  361         tpcb->tp_routep = &(isop->isop_route.ro_rt);
  362         if (tpcb->tp_netservice == ISO_CONS)
  363                 return 0;
  364         else
  365                 return (sizeof(struct clnp_fixed) + sizeof(struct clnp_segment) +
  366                         2 * sizeof(struct iso_addr));
  367 
  368 }
  369 
  370 /*
  371  * CALLED FROM:
  372  *  tp_emit()
  373  * FUNCTION and ARGUMENTS:
  374  *  Take a packet(m0) from tp and package it so that clnp will accept it.
  375  *  This means prepending space for the clnp header and filling in a few
  376  *  of the fields.
  377  *  isop is the isopcb structure; datalen is the length of the data in the
  378  *  mbuf string m0.
  379  * RETURN VALUE:
  380  *  whatever (E*) is returned form the net layer output routine.
  381  */
  382 
  383 int
  384 #if __STDC__
  385 tpclnp_output(struct mbuf *m0, ...)
  386 #else
  387 tpclnp_output(m0, va_alist)
  388         struct mbuf    *m0;
  389         va_dcl
  390 #endif
  391 {
  392         int             datalen;
  393         struct isopcb  *isop;
  394         int             nochksum;
  395         va_list ap;
  396 
  397         va_start(ap, m0);
  398         datalen = va_arg(ap, int);
  399         isop = va_arg(ap, struct isopcb *);
  400         nochksum = va_arg(ap, int);
  401         va_end(ap);
  402 
  403         IncStat(ts_tpdu_sent);
  404 
  405 #ifdef ARGO_DEBUG
  406         if (argo_debug[D_TPISO]) {
  407                 struct tpdu    *hdr = mtod(m0, struct tpdu *);
  408 
  409                 printf(
  410                        "abt to call clnp_output: datalen 0x%x, hdr.li 0x%x, hdr.dutype 0x%x nocsum x%x dst addr:\n",
  411                        datalen,
  412                        (int) hdr->tpdu_li, (int) hdr->tpdu_type, nochksum);
  413                 dump_isoaddr(isop->isop_faddr);
  414                 printf("\nsrc addr:\n");
  415                 dump_isoaddr(isop->isop_laddr);
  416                 dump_mbuf(m0, "at tpclnp_output");
  417         }
  418 #endif
  419 
  420         return
  421                 clnp_output(m0, isop, datalen, /* flags */ nochksum ? CLNP_NO_CKSUM : 0);
  422 }
  423 
  424 /*
  425  * CALLED FROM:
  426  *  tp_error_emit()
  427  * FUNCTION and ARGUMENTS:
  428  *  This is a copy of tpclnp_output that takes the addresses
  429  *  instead of a pcb.  It's used by the tp_error_emit, when we
  430  *  don't have an iso_pcb with which to call the normal output rtn.
  431  * RETURN VALUE:
  432  *  ENOBUFS or
  433  *  whatever (E*) is returned form the net layer output routine.
  434  */
  435 
  436 int
  437 #if __STDC__
  438 tpclnp_output_dg(struct mbuf *m0, ...)
  439 #else
  440 tpclnp_output_dg(m0, va_alist)
  441         struct mbuf    *m0;
  442         va_dcl
  443 #endif
  444 {
  445         struct isopcb   tmppcb;
  446         int             err;
  447         int             flags;
  448         int             datalen;
  449         struct iso_addr *laddr, *faddr;
  450         struct route   *ro;
  451         int             nochksum;
  452         va_list         ap;
  453 
  454         va_start(ap, m0);
  455         datalen = va_arg(ap, int);
  456         laddr = va_arg(ap, struct iso_addr *);
  457         faddr = va_arg(ap, struct iso_addr *);
  458         ro = va_arg(ap, struct route *);
  459         nochksum = va_arg(ap, int);
  460         va_end(ap);
  461 
  462 #ifdef ARGO_DEBUG
  463         if (argo_debug[D_TPISO]) {
  464                 printf("tpclnp_output_dg  datalen 0x%x m0 %p\n", datalen, m0);
  465         }
  466 #endif
  467 
  468         /*
  469          *      Fill in minimal portion of isopcb so that clnp can send the
  470          *      packet.
  471          */
  472         bzero((caddr_t) & tmppcb, sizeof(tmppcb));
  473         tmppcb.isop_laddr = &tmppcb.isop_sladdr;
  474         tmppcb.isop_laddr->siso_addr = *laddr;
  475         tmppcb.isop_faddr = &tmppcb.isop_sfaddr;
  476         tmppcb.isop_faddr->siso_addr = *faddr;
  477 
  478 #ifdef ARGO_DEBUG
  479         if (argo_debug[D_TPISO]) {
  480                 printf("tpclnp_output_dg  faddr: \n");
  481                 dump_isoaddr(&tmppcb.isop_sfaddr);
  482                 printf("\ntpclnp_output_dg  laddr: \n");
  483                 dump_isoaddr(&tmppcb.isop_sladdr);
  484                 printf("\n");
  485         }
  486 #endif
  487 
  488         /*
  489          *      Do not use packet cache since this is a one shot error packet
  490          */
  491         flags = (CLNP_NOCACHE | (nochksum ? CLNP_NO_CKSUM : 0));
  492 
  493         IncStat(ts_tpdu_sent);
  494 
  495         err = clnp_output(m0, &tmppcb, datalen, flags);
  496 
  497         /*
  498          *      Free route allocated by clnp (if the route was indeed allocated)
  499          */
  500         if (tmppcb.isop_route.ro_rt)
  501                 RTFREE(tmppcb.isop_route.ro_rt);
  502 
  503         return (err);
  504 }
  505 /*
  506  * CALLED FROM:
  507  *      clnp's input routine, indirectly through the protosw.
  508  * FUNCTION and ARGUMENTS:
  509  * Take a packet (m) from clnp, strip off the clnp header and give it to tp
  510  * No return value.
  511  */
  512 void
  513 #if __STDC__
  514 tpclnp_input(struct mbuf *m, ...)
  515 #else
  516 tpclnp_input(m, va_alist)
  517         struct mbuf *m;
  518         va_dcl
  519 #endif
  520 {
  521         struct sockaddr_iso *src, *dst;
  522         int             clnp_len, ce_bit;
  523         void            (*input) __P((struct mbuf *, ...)) = tp_input;
  524         va_list         ap;
  525 
  526         va_start(ap, m);
  527         src = va_arg(ap, struct sockaddr_iso *);
  528         dst = va_arg(ap, struct sockaddr_iso *);
  529         clnp_len = va_arg(ap, int);
  530         ce_bit = va_arg(ap, int);
  531         va_end(ap);
  532 
  533         IncStat(ts_pkt_rcvd);
  534 
  535 #ifdef ARGO_DEBUG
  536         if (argo_debug[D_TPINPUT]) {
  537                 printf("tpclnp_input: m %p clnp_len 0x%x\n", m, clnp_len);
  538                 dump_mbuf(m, "at tpclnp_input");
  539         }
  540 #endif
  541         /*
  542          * CLNP gives us an mbuf chain WITH the clnp header pulled up,
  543          * and the length of the clnp header.
  544          * First, strip off the Clnp header. leave the mbuf there for the
  545          * pullup that follows.
  546          */
  547         m->m_len -= clnp_len;
  548         m->m_data += clnp_len;
  549         m->m_pkthdr.len -= clnp_len;
  550         /* XXXX: should probably be in clnp_input */
  551         switch (dst->siso_data[dst->siso_nlen - 1]) {
  552         case 0:
  553                 if (m->m_len == 0 && (m = m_pullup(m, 1)) == 0)
  554                         return;
  555                 if (*(mtod(m, u_char *)) == ISO10747_IDRP) {
  556                         idrp_input(m, src, dst);
  557                         return;
  558                 }
  559         }
  560         m = tp_inputprep(m);
  561         if (m == 0)
  562                 return;
  563         if (mtod(m, u_char *)[1] == UD_TPDU_type)
  564                 input = cltp_input;
  565 
  566 #ifdef ARGO_DEBUG
  567         if (argo_debug[D_TPINPUT]) {
  568                 dump_mbuf(m, "after tpclnp_input both pullups");
  569         }
  570 #endif
  571 
  572 #ifdef ARGO_DEBUG
  573         if (argo_debug[D_TPISO]) {
  574                 printf("calling %sinput : src %p, dst %p, src addr:\n",
  575                        (input == tp_input ? "tp_" : "clts_"), src, dst);
  576                 dump_isoaddr(src);
  577                 printf(" dst addr:\n");
  578                 dump_isoaddr(dst);
  579         }
  580 #endif
  581 
  582         (*input) (m, (struct sockaddr *) src, (struct sockaddr *) dst, 0,
  583                   tpclnp_output_dg, ce_bit);
  584 
  585 #ifdef ARGO_DEBUG
  586         if (argo_debug[D_QUENCH]) {{
  587                         if (time.tv_usec & 0x4 && time.tv_usec & 0x40) {
  588                                 printf("tpclnp_input: FAKING %s\n",
  589                                        tp_stat.ts_pkt_rcvd & 0x1 ? "QUENCH" : "QUENCH2");
  590                                 if (tp_stat.ts_pkt_rcvd & 0x1)
  591                                         tpclnp_ctlinput(PRC_QUENCH, 
  592                                                         (struct sockaddr *)
  593                                                         &src, NULL);
  594                                 else
  595                                         tpclnp_ctlinput(PRC_QUENCH2,
  596                                                         (struct sockaddr *)
  597                                                         &src, NULL);
  598                         }
  599         }
  600         }
  601 #endif
  602 }
  603 
  604 /*ARGSUSED*/
  605 void
  606 iso_rtchange(pcb)
  607         struct isopcb *pcb;
  608 {
  609 
  610 }
  611 
  612 /*
  613  * CALLED FROM:
  614  *  tpclnp_ctlinput()
  615  * FUNCTION and ARGUMENTS:
  616  *  find the tpcb pointer and pass it to tp_quench
  617  */
  618 void
  619 tpiso_decbit(isop)
  620         struct isopcb  *isop;
  621 {
  622         tp_quench((struct inpcb *) isop->isop_socket->so_pcb, PRC_QUENCH2);
  623 }
  624 /*
  625  * CALLED FROM:
  626  *  tpclnp_ctlinput()
  627  * FUNCTION and ARGUMENTS:
  628  *  find the tpcb pointer and pass it to tp_quench
  629  */
  630 void
  631 tpiso_quench(isop)
  632         struct isopcb  *isop;
  633 {
  634         tp_quench((struct inpcb *) isop->isop_socket->so_pcb, PRC_QUENCH);
  635 }
  636 
  637 /*
  638  * CALLED FROM:
  639  *  The network layer through the protosw table.
  640  * FUNCTION and ARGUMENTS:
  641  *      When clnp an ICMP-like msg this gets called.
  642  *      It either returns an error status to the user or
  643  *      it causes all connections on this address to be aborted
  644  *      by calling the appropriate xx_notify() routine.
  645  *      (cmd) is the type of ICMP error.
  646  *      (siso) is the address of the guy who sent the ER CLNPDU
  647  */
  648 void *
  649 tpclnp_ctlinput(cmd, saddr, dummy)
  650         int             cmd;
  651         struct sockaddr *saddr;
  652         void *dummy;
  653 {
  654         struct sockaddr_iso *siso = (struct sockaddr_iso *) saddr;
  655         extern u_char   inetctlerrmap[];
  656 
  657 #ifdef ARGO_DEBUG
  658         if (argo_debug[D_TPINPUT]) {
  659                 printf("tpclnp_ctlinput1: cmd 0x%x addr: \n", cmd);
  660                 dump_isoaddr(siso);
  661         }
  662 #endif
  663 
  664         if ((unsigned)cmd >= PRC_NCMDS)
  665                 return NULL;
  666         if (siso->siso_family != AF_ISO)
  667                 return NULL;
  668         switch (cmd) {
  669 
  670         case PRC_QUENCH2:
  671                 iso_pcbnotify(&tp_isopcb, siso, 0, tpiso_decbit);
  672                 break;
  673 
  674         case PRC_QUENCH:
  675                 iso_pcbnotify(&tp_isopcb, siso, 0, tpiso_quench);
  676                 break;
  677 
  678         case PRC_TIMXCEED_REASS:
  679         case PRC_ROUTEDEAD:
  680                 iso_pcbnotify(&tp_isopcb, siso, 0, tpiso_reset);
  681                 break;
  682 
  683         case PRC_HOSTUNREACH:
  684         case PRC_UNREACH_NET:
  685         case PRC_IFDOWN:
  686         case PRC_HOSTDEAD:
  687                 iso_pcbnotify(&tp_isopcb, siso,
  688                               (int) inetctlerrmap[cmd], iso_rtchange);
  689                 break;
  690 
  691         default:
  692                 /*
  693                 case    PRC_MSGSIZE:
  694                 case    PRC_UNREACH_HOST:
  695                 case    PRC_UNREACH_PROTOCOL:
  696                 case    PRC_UNREACH_PORT:
  697                 case    PRC_UNREACH_NEEDFRAG:
  698                 case    PRC_UNREACH_SRCFAIL:
  699                 case    PRC_REDIRECT_NET:
  700                 case    PRC_REDIRECT_HOST:
  701                 case    PRC_REDIRECT_TOSNET:
  702                 case    PRC_REDIRECT_TOSHOST:
  703                 case    PRC_TIMXCEED_INTRANS:
  704                 case    PRC_PARAMPROB:
  705                 */
  706                 iso_pcbnotify(&tp_isopcb, siso, (int) inetctlerrmap[cmd], tpiso_abort);
  707                 break;
  708         }
  709         return NULL;
  710 }
  711 /*
  712  * XXX - Variant which is called by clnp_er.c with an isoaddr rather
  713  * than a sockaddr_iso.
  714  */
  715 
  716 static struct sockaddr_iso siso = {sizeof(siso), AF_ISO};
  717 void
  718 tpclnp_ctlinput1(cmd, isoa)
  719         int             cmd;
  720         struct iso_addr *isoa;
  721 {
  722         bzero((caddr_t) & siso.siso_addr, sizeof(siso.siso_addr));
  723         bcopy((caddr_t) isoa, (caddr_t) & siso.siso_addr, isoa->isoa_len);
  724         tpclnp_ctlinput(cmd, (struct sockaddr *) &siso, NULL);
  725 }
  726 
  727 /*
  728  * These next 2 routines are
  729  * CALLED FROM:
  730  *      xxx_notify() from tp_ctlinput() when
  731  *  net level gets some ICMP-equiv. type event.
  732  * FUNCTION and ARGUMENTS:
  733  *  Cause the connection to be aborted with some sort of error
  734  *  reason indicating that the network layer caused the abort.
  735  *  Fakes an ER TPDU so we can go through the driver.
  736  *  abort always aborts the TP connection.
  737  *  reset may or may not, depending on the TP class that's in use.
  738  */
  739 void
  740 tpiso_abort(isop)
  741         struct isopcb  *isop;
  742 {
  743         struct tp_event e;
  744 
  745 #ifdef ARGO_DEBUG
  746         if (argo_debug[D_CONN]) {
  747                 printf("tpiso_abort %p\n", isop);
  748         }
  749 #endif
  750         e.ev_number = ER_TPDU;
  751         e.TPDU_ATTR(ER).e_reason = ECONNABORTED;
  752         tp_driver((struct tp_pcb *) isop->isop_socket->so_pcb, &e);
  753 }
  754 
  755 void
  756 tpiso_reset(isop)
  757         struct isopcb  *isop;
  758 {
  759         struct tp_event e;
  760 
  761         e.ev_number = T_NETRESET;
  762         tp_driver((struct tp_pcb *) isop->isop_socket->so_pcb, &e);
  763 
  764 }
  765 
  766 #endif                          /* ISO */

Cache object: ca04339800beef23e0d1bc0696408c7e


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