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

Cache object: 327b5aba2dc6ffe3ee986dfc2e4d65fd


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