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

Cache object: fed5669bea514283763fc92a580cd74c


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