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_inet.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: tp_inet.c,v 1.36 2007/12/20 19:53: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  *      @(#)tp_inet.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  * Here is where you find the inet-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: in_getsufx: gets transport suffix out of an inpcb structure.
   66  * in_putsufx: put transport suffix into an inpcb structure. in_putnetaddr:
   67  * put a whole net addr into an inpcb. in_getnetaddr: get a whole net addr
   68  * from an inpcb. in_cmpnetaddr: compare a whole net addr from an isopcb.
   69  * in_recycle_suffix: clear suffix for reuse in inpcb tpip_mtu: figure out
   70  * what size tpdu to use tpip_input: take a pkt from ip, strip off its ip
   71  * header, give to tp tpip_output_dg: package a pkt for ip given 2 addresses
   72  * & some data tpip_output: package a pkt for ip given an inpcb & some data
   73  */
   74 
   75 #include <sys/cdefs.h>
   76 __KERNEL_RCSID(0, "$NetBSD: tp_inet.c,v 1.36 2007/12/20 19:53:35 dyoung Exp $");
   77 
   78 #include "opt_inet.h"
   79 #include "opt_iso.h"
   80 
   81 #ifdef INET
   82 
   83 #include <sys/param.h>
   84 #include <sys/socket.h>
   85 #include <sys/socketvar.h>
   86 #include <sys/mbuf.h>
   87 #include <sys/errno.h>
   88 #include <sys/time.h>
   89 #include <sys/systm.h>
   90 
   91 #include <net/if.h>
   92 
   93 #include <netiso/tp_param.h>
   94 #include <netiso/argo_debug.h>
   95 #include <netiso/tp_stat.h>
   96 #include <netiso/tp_ip.h>
   97 #include <netiso/tp_pcb.h>
   98 #include <netiso/tp_trace.h>
   99 #include <netiso/tp_tpdu.h>
  100 #include <netiso/tp_var.h>
  101 #include <netinet/in_var.h>
  102 
  103 #ifndef ISO
  104 #include <netiso/iso_chksum.c>
  105 #endif
  106 
  107 #include <machine/stdarg.h>
  108 
  109 /*
  110  * NAME:                in_getsufx()
  111  *
  112  * CALLED FROM:         pr_usrreq() on PRU_BIND,
  113  *                      PRU_CONNECT, PRU_ACCEPT, and PRU_PEERADDR
  114  *
  115  * FUNCTION, ARGUMENTS, and RETURN VALUE:
  116  *      Get a transport suffix from an inpcb structure (inp).
  117  *      The argument (which) takes the value TP_LOCAL or TP_FOREIGN.
  118  *
  119  * RETURNS:             internet port / transport suffix
  120  *                      (CAST TO AN INT)
  121  *
  122  * SIDE EFFECTS:
  123  *
  124  * NOTES:
  125  */
  126 void
  127 in_getsufx(void *v, u_short *lenp, void *data_out, int which)
  128 {
  129         struct inpcb   *inp = v;
  130         *lenp = sizeof(u_short);
  131         switch (which) {
  132         case TP_LOCAL:
  133                 *(u_short *) data_out = inp->inp_lport;
  134                 return;
  135 
  136         case TP_FOREIGN:
  137                 *(u_short *) data_out = inp->inp_fport;
  138         }
  139 
  140 }
  141 
  142 /*
  143  * NAME:        in_putsufx()
  144  *
  145  * CALLED FROM: tp_newsocket(); i.e., when a connection
  146  *              is being established by an incoming CR_TPDU.
  147  *
  148  * FUNCTION, ARGUMENTS:
  149  *      Put a transport suffix (found in name) into an inpcb structure (inp).
  150  *      The argument (which) takes the value TP_LOCAL or TP_FOREIGN.
  151  *
  152  * RETURNS:     Nada
  153  *
  154  * SIDE EFFECTS:
  155  *
  156  * NOTES:
  157  */
  158 /* ARGSUSED */
  159 void
  160 in_putsufx(void *v, void *sufxloc, int sufxlen, int which)
  161 {
  162         struct inpcb   *inp = v;
  163         if (which == TP_FOREIGN) {
  164                 bcopy(sufxloc, (void *) & inp->inp_fport, sizeof(inp->inp_fport));
  165         }
  166 }
  167 
  168 /*
  169  * NAME:        in_recycle_tsuffix()
  170  *
  171  * CALLED FROM: tp.trans whenever we go into REFWAIT state.
  172  *
  173  * FUNCTION and ARGUMENT:
  174  *       Called when a ref is frozen, to allow the suffix to be reused.
  175  *      (inp) is the net level pcb.
  176  *
  177  * RETURNS:                     Nada
  178  *
  179  * SIDE EFFECTS:
  180  *
  181  * NOTES:       This really shouldn't have to be done in a NET level pcb
  182  *      but... for the internet world that just the way it is done in BSD...
  183  *      The alternative is to have the port unusable until the reference
  184  *      timer goes off.
  185  */
  186 void
  187 in_recycle_tsuffix(void *v)
  188 {
  189         struct inpcb   *inp = v;
  190         inp->inp_fport = inp->inp_lport = 0;
  191 }
  192 
  193 /*
  194  * NAME:        in_putnetaddr()
  195  *
  196  * CALLED FROM:
  197  *      tp_newsocket(); i.e., when a connection is being established by an
  198  *      incoming CR_TPDU.
  199  *
  200  * FUNCTION and ARGUMENTS:
  201  *      Copy a whole net addr from a struct sockaddr (name).
  202  *      into an inpcb (inp).
  203  *      The argument (which) takes values TP_LOCAL or TP_FOREIGN
  204  *
  205  * RETURNS:             Nada
  206  *
  207  * SIDE EFFECTS:
  208  *
  209  * NOTES:
  210  */
  211 void
  212 in_putnetaddr(void *v, struct sockaddr *nm, int which)
  213 {
  214         struct inpcb *inp = v;
  215         struct sockaddr_in *name = (struct sockaddr_in *) nm;
  216         switch (which) {
  217         case TP_LOCAL:
  218                 bcopy((void *) & name->sin_addr,
  219                       (void *) & inp->inp_laddr, sizeof(struct in_addr));
  220                 /* won't work if the dst address (name) is INADDR_ANY */
  221 
  222                 break;
  223         case TP_FOREIGN:
  224                 if (name != (struct sockaddr_in *) 0) {
  225                         bcopy((void *) & name->sin_addr,
  226                         (void *) & inp->inp_faddr, sizeof(struct in_addr));
  227                 }
  228         }
  229 }
  230 
  231 /*
  232  * NAME:        in_cmpnetaddr()
  233  *
  234  * CALLED FROM:
  235  *      tp_input() when a connection is being established by an
  236  *      incoming CR_TPDU, and considered for interception.
  237  *
  238  * FUNCTION and ARGUMENTS:
  239  *      Compare a whole net addr from a struct sockaddr (name),
  240  *      with that implicitly stored in an inpcb (inp).
  241  *      The argument (which) takes values TP_LOCAL or TP_FOREIGN
  242  *
  243  * RETURNS:             Nada
  244  *
  245  * SIDE EFFECTS:
  246  *
  247  * NOTES:
  248  */
  249 int
  250 in_cmpnetaddr(void *v, struct sockaddr *nm, int which)
  251 {
  252         struct inpcb *inp = v;
  253         struct sockaddr_in *name = (struct sockaddr_in *) nm;
  254         if (which == TP_LOCAL) {
  255                 if (name->sin_port && name->sin_port != inp->inp_lport)
  256                         return 0;
  257                 return (name->sin_addr.s_addr == inp->inp_laddr.s_addr);
  258         }
  259         if (name->sin_port && name->sin_port != inp->inp_fport)
  260                 return 0;
  261         return (name->sin_addr.s_addr == inp->inp_faddr.s_addr);
  262 }
  263 
  264 /*
  265  * NAME:        in_getnetaddr()
  266  *
  267  * CALLED FROM:
  268  *  pr_usrreq() PRU_SOCKADDR, PRU_ACCEPT, PRU_PEERADDR
  269  * FUNCTION and ARGUMENTS:
  270  *      Copy a whole net addr from an inpcb (inp) into
  271  *      an mbuf (name);
  272  *      The argument (which) takes values TP_LOCAL or TP_FOREIGN.
  273  *
  274  * RETURNS:             Nada
  275  *
  276  * SIDE EFFECTS:
  277  *
  278  * NOTES:
  279  */
  280 
  281 void
  282 in_getnetaddr(void *v, struct mbuf *name, int which)
  283 {
  284         struct inpcb   *inp = v;
  285         struct sockaddr_in *sin = mtod(name, struct sockaddr_in *);
  286         bzero((void *) sin, sizeof(*sin));
  287         switch (which) {
  288         case TP_LOCAL:
  289                 sin->sin_addr = inp->inp_laddr;
  290                 sin->sin_port = inp->inp_lport;
  291                 break;
  292         case TP_FOREIGN:
  293                 sin->sin_addr = inp->inp_faddr;
  294                 sin->sin_port = inp->inp_fport;
  295                 break;
  296         default:
  297                 return;
  298         }
  299         name->m_len = sin->sin_len = sizeof(*sin);
  300         sin->sin_family = AF_INET;
  301 }
  302 
  303 /*
  304  * NAME:        tpip_mtu()
  305  *
  306  * CALLED FROM:
  307  *  tp_route_to() on incoming CR, CC, and pr_usrreq() for PRU_CONNECT
  308  *
  309  * FUNCTION, ARGUMENTS, and RETURN VALUE:
  310  *
  311  * Perform subnetwork dependent part of determining MTU information.
  312  * It appears that setting a double pointer to the rtentry associated with
  313  * the destination, and returning the header size for the network protocol
  314  * suffices.
  315  *
  316  * SIDE EFFECTS:
  317  * Sets tp_route in pcb.
  318  *
  319  * NOTES:
  320  */
  321 int
  322 tpip_mtu(void *v)
  323 {
  324         struct tp_pcb *tpcb = v;
  325         struct inpcb   *inp = (struct inpcb *) tpcb->tp_npcb;
  326 
  327 #ifdef ARGO_DEBUG
  328         if (argo_debug[D_CONN]) {
  329                 printf("tpip_mtu(tpcb %p)\n", tpcb);
  330                 printf("tpip_mtu routing to addr 0x%x\n", inp->inp_faddr.s_addr);
  331         }
  332 #endif
  333         tpcb->tp_routep = &inp->inp_route;
  334         return sizeof(struct ip);
  335 
  336 }
  337 
  338 /*
  339  * NAME:        tpip_output()
  340  *
  341  * CALLED FROM:  tp_emit()
  342  *
  343  * FUNCTION and ARGUMENTS:
  344  *  Take a packet(m0) from tp and package it so that ip will accept it.
  345  *  This means prepending space for the ip header and filling in a few
  346  *  of the fields.
  347  *  inp is the inpcb structure; datalen is the length of the data in the
  348  *  mbuf string m0.
  349  * RETURNS:
  350  *  whatever (E*) is returned form the net layer output routine.
  351  *
  352  * SIDE EFFECTS:
  353  *
  354  * NOTES:
  355  */
  356 
  357 int
  358 tpip_output(struct mbuf *m0, ...)
  359 {
  360         int             datalen;
  361         struct inpcb   *inp;
  362         int             nochksum;
  363         va_list         ap;
  364 
  365         va_start(ap, m0);
  366         datalen = va_arg(ap, int);
  367         inp = va_arg(ap, struct inpcb *);
  368         nochksum = va_arg(ap, int);
  369         va_end(ap);
  370 
  371         return tpip_output_dg(m0, datalen, &inp->inp_laddr, &inp->inp_faddr,
  372                               &inp->inp_route, nochksum);
  373 }
  374 
  375 /*
  376  * NAME:        tpip_output_dg()
  377  *
  378  * CALLED FROM:  tp_error_emit()
  379  *
  380  * FUNCTION and ARGUMENTS:
  381  *  This is a copy of tpip_output that takes the addresses
  382  *  instead of a pcb.  It's used by the tp_error_emit, when we
  383  *  don't have an in_pcb with which to call the normal output rtn.
  384  *
  385  * RETURNS:      ENOBUFS or  whatever (E*) is
  386  *      returned form the net layer output routine.
  387  *
  388  * SIDE EFFECTS:
  389  *
  390  * NOTES:
  391  */
  392 
  393 /* ARGSUSED */
  394 int
  395 tpip_output_dg(struct mbuf *m0, ...)
  396 {
  397         int             datalen;
  398         struct in_addr *laddr, *faddr;
  399         struct route   *ro;
  400         int             nochksum;
  401         struct mbuf *m;
  402         struct ip *ip;
  403         int             error;
  404         va_list ap;
  405 
  406         va_start(ap, m0);
  407         datalen = va_arg(ap, int);
  408         laddr = va_arg(ap, struct in_addr *);
  409         faddr = va_arg(ap, struct in_addr *);
  410         ro = va_arg(ap, struct route *);
  411         nochksum = va_arg(ap, int);
  412         va_end(ap);
  413 
  414 #ifdef ARGO_DEBUG
  415         if (argo_debug[D_EMIT]) {
  416                 printf("tpip_output_dg  datalen 0x%x m0 %p\n", datalen, m0);
  417         }
  418 #endif
  419 
  420 
  421         MGETHDR(m, M_DONTWAIT, TPMT_IPHDR);
  422         if (m == 0) {
  423                 error = ENOBUFS;
  424                 goto bad;
  425         }
  426         m->m_next = m0;
  427         MH_ALIGN(m, sizeof(struct ip));
  428         m->m_len = sizeof(struct ip);
  429 
  430         ip = mtod(m, struct ip *);
  431         bzero((void *) ip, sizeof *ip);
  432 
  433         ip->ip_p = IPPROTO_TP;
  434         if (sizeof(struct ip) + datalen > IP_MAXPACKET) {
  435                 error = EMSGSIZE;
  436                 goto bad;
  437         }
  438         m->m_pkthdr.len = sizeof(struct ip) + datalen;
  439         ip->ip_len = htons(sizeof(struct ip) + datalen);
  440         ip->ip_ttl = MAXTTL;
  441         /*
  442          * don't know why you need to set ttl; overlay doesn't even make this
  443          * available
  444          */
  445 
  446         ip->ip_src = *laddr;
  447         ip->ip_dst = *faddr;
  448 
  449         IncStat(ts_tpdu_sent);
  450 #ifdef ARGO_DEBUG
  451         if (argo_debug[D_EMIT]) {
  452                 dump_mbuf(m, "tpip_output_dg before ip_output\n");
  453         }
  454 #endif
  455 
  456         error = ip_output(m, (struct mbuf *) 0, ro, IP_ALLOWBROADCAST,
  457             (struct ip_moptions *)NULL, (struct socket *)NULL);
  458 
  459 #ifdef ARGO_DEBUG
  460         if (argo_debug[D_EMIT]) {
  461                 printf("tpip_output_dg after ip_output\n");
  462         }
  463 #endif
  464 
  465         return error;
  466 
  467 bad:
  468         m_freem(m);
  469         IncStat(ts_send_drop);
  470         return error;
  471 }
  472 
  473 /*
  474  * NAME:  tpip_input()
  475  *
  476  * CALLED FROM:
  477  *      ip's input routine, indirectly through the protosw.
  478  *
  479  * FUNCTION and ARGUMENTS:
  480  * Take a packet (m) from ip, strip off the ip header and give it to tp
  481  *
  482  * RETURNS:  No return value.
  483  *
  484  * SIDE EFFECTS:
  485  *
  486  * NOTES:
  487  */
  488 void
  489 tpip_input(struct mbuf *m, ...)
  490 {
  491         int             iplen;
  492         struct sockaddr_in src, dst;
  493         struct ip *ip;
  494         int             s = splsoftnet(), hdrlen;
  495         va_list ap;
  496 
  497         va_start(ap, m);
  498         iplen = va_arg(ap, int);
  499         va_end(ap);
  500 
  501         IncStat(ts_pkt_rcvd);
  502 
  503         /*
  504          * IP layer has already pulled up the IP header,
  505          * but the first byte after the IP header may not be there,
  506          * e.g. if you came in via loopback, so you have to do an
  507          * m_pullup to before you can even look to see how much you
  508          * really need.  The good news is that m_pullup will round
  509          * up to almost the next mbuf's worth.
  510          */
  511 
  512 
  513         if ((m = m_pullup(m, iplen + 1)) == NULL)
  514                 goto discard;
  515         CHANGE_MTYPE(m, TPMT_DATA);
  516 
  517         /*
  518          * Now pull up the whole tp header:
  519          * Unfortunately, there may be IP options to skip past so we
  520          * just fetch it as an unsigned char.
  521          */
  522         hdrlen = iplen + 1 + mtod(m, u_char *)[iplen];
  523 
  524         if (m->m_len < hdrlen) {
  525                 if ((m = m_pullup(m, hdrlen)) == NULL) {
  526 #ifdef ARGO_DEBUG
  527                         if (argo_debug[D_TPINPUT]) {
  528                                 printf("tp_input, pullup 2!\n");
  529                         }
  530 #endif
  531                         goto discard;
  532                 }
  533         }
  534         /*
  535          * cannot use tp_inputprep() here 'cause you don't have quite the
  536          * same situation
  537          */
  538 
  539 #ifdef ARGO_DEBUG
  540         if (argo_debug[D_TPINPUT]) {
  541                 dump_mbuf(m, "after tpip_input both pullups");
  542         }
  543 #endif
  544         /*
  545          * m_pullup may have returned a different mbuf
  546          */
  547         ip = mtod(m, struct ip *);
  548 
  549         /*
  550          * drop the ip header from the front of the mbuf
  551          * this is necessary for the tp checksum
  552          */
  553         m->m_len -= iplen;
  554         m->m_data += iplen;
  555 
  556         src.sin_addr = *(struct in_addr *) & (ip->ip_src);
  557         src.sin_family = AF_INET;
  558         src.sin_len = sizeof(src);
  559         dst.sin_addr = *(struct in_addr *) & (ip->ip_dst);
  560         dst.sin_family = AF_INET;
  561         dst.sin_len = sizeof(dst);
  562 
  563         tp_input(m, sintosa(&src), sintosa(&dst), 0, tpip_output_dg, 0);
  564         return;
  565 
  566 discard:
  567 #ifdef ARGO_DEBUG
  568         if (argo_debug[D_TPINPUT]) {
  569                 printf("tpip_input DISCARD\n");
  570         }
  571 #endif
  572 #ifdef TPPT
  573         if (tp_traceflags[D_TPINPUT]) {
  574                 tptrace(TPPTmisc, "tpip_input DISCARD m", m, 0, 0, 0);
  575         }
  576 #endif
  577                 m_freem(m);
  578         IncStat(ts_recv_drop);
  579         splx(s);
  580 }
  581 
  582 
  583 #include <sys/protosw.h>
  584 #include <netinet/ip_icmp.h>
  585 
  586 /*
  587  * NAME:        tpin_quench()
  588  *
  589  * CALLED FROM: tpip_ctlinput()
  590  *
  591  * FUNCTION and ARGUMENTS:  find the tpcb pointer and pass it to tp_quench
  592  *
  593  * RETURNS:     Nada
  594  *
  595  * SIDE EFFECTS:
  596  *
  597  * NOTES:
  598  */
  599 
  600 void
  601 tpin_quench(struct inpcb *inp, int dummy)
  602 {
  603         tp_quench((struct inpcb *) inp->inp_socket->so_pcb, PRC_QUENCH);
  604 }
  605 
  606 /*
  607  * NAME:        tpip_ctlinput()
  608  *
  609  * CALLED FROM:
  610  *  The network layer through the protosw table.
  611  *
  612  * FUNCTION and ARGUMENTS:
  613  *      When clnp gets an ICMP msg this gets called.
  614  *      It either returns an error status to the user or
  615  *      causes all connections on this address to be aborted
  616  *      by calling the appropriate xx_notify() routine.
  617  *      (cmd) is the type of ICMP error.
  618  *      (sa) the address of the sender
  619  *
  620  * RETURNS:      Nothing
  621  *
  622  * SIDE EFFECTS:
  623  *
  624  * NOTES:
  625  */
  626 void *
  627 tpip_ctlinput(int cmd, const struct sockaddr *sa, void *dummy)
  628 {
  629         void            (*notify)(struct inpcb *, int);
  630         int             errno;
  631 
  632         if ((unsigned)cmd >= PRC_NCMDS)
  633                 return NULL;
  634         errno = inetctlerrmap[cmd];
  635         switch (cmd) {
  636 
  637         case PRC_QUENCH:
  638                 notify = tp_quench;
  639                 break;
  640 
  641         case PRC_ROUTEDEAD:
  642         case PRC_HOSTUNREACH:
  643         case PRC_UNREACH_NET:
  644         case PRC_IFDOWN:
  645         case PRC_HOSTDEAD:
  646                 notify = in_rtchange;
  647                 break;
  648 
  649         default:
  650                 /*
  651                 case    PRC_MSGSIZE:
  652                 case    PRC_UNREACH_HOST:
  653                 case    PRC_UNREACH_PROTOCOL:
  654                 case    PRC_UNREACH_PORT:
  655                 case    PRC_UNREACH_NEEDFRAG:
  656                 case    PRC_UNREACH_SRCFAIL:
  657                 case    PRC_REDIRECT_NET:
  658                 case    PRC_REDIRECT_HOST:
  659                 case    PRC_REDIRECT_TOSNET:
  660                 case    PRC_REDIRECT_TOSHOST:
  661                 case    PRC_TIMXCEED_INTRANS:
  662                 case    PRC_TIMXCEED_REASS:
  663                 case    PRC_PARAMPROB:
  664                 */
  665                 notify = tpin_abort;
  666                 break;
  667         }
  668         in_pcbnotifyall(&tp_inpcb, satocsin(sa)->sin_addr, errno, notify);
  669         return NULL;
  670 }
  671 
  672 /*
  673  * NAME:        tpin_abort()
  674  *
  675  * CALLED FROM:
  676  *      xxx_notify() from tp_ctlinput() when
  677  *  net level gets some ICMP-equiv. type event.
  678  *
  679  * FUNCTION and ARGUMENTS:
  680  *  Cause the connection to be aborted with some sort of error
  681  *  reason indicating that the network layer caused the abort.
  682  *  Fakes an ER TPDU so we can go through the driver.
  683  *
  684  * RETURNS:      Nothing
  685  *
  686  * SIDE EFFECTS:
  687  *
  688  * NOTES:
  689  */
  690 
  691 void
  692 tpin_abort(struct inpcb *inp, int n)
  693 {
  694         struct tp_event e;
  695 
  696         e.ev_number = ER_TPDU;
  697         e.TPDU_ATTR(ER).e_reason = ENETRESET;
  698         tp_driver((struct tp_pcb *) inp->inp_ppcb, &e);
  699 }
  700 
  701 #ifdef ARGO_DEBUG
  702 void
  703 dump_inaddr(struct sockaddr_in *addr)
  704 {
  705         printf("INET: port 0x%x; addr 0x%x\n", addr->sin_port, addr->sin_addr.s_addr);
  706 }
  707 #endif  /* ARGO_DEBUG */
  708 #endif  /* INET */

Cache object: af0e38a1e5b27f79d48faeae029ecf35


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