Annotation of XNU/bsd/netiso/tp_inet.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
                      3:  *
                      4:  * @APPLE_LICENSE_HEADER_START@
                      5:  * 
                      6:  * The contents of this file constitute Original Code as defined in and
                      7:  * are subject to the Apple Public Source License Version 1.1 (the
                      8:  * "License").  You may not use this file except in compliance with the
                      9:  * License.  Please obtain a copy of the License at
                     10:  * http://www.apple.com/publicsource and read it before using this file.
                     11:  * 
                     12:  * This Original Code and all software distributed under the License are
                     13:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
                     14:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
                     15:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
                     16:  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
                     17:  * License for the specific language governing rights and limitations
                     18:  * under the License.
                     19:  * 
                     20:  * @APPLE_LICENSE_HEADER_END@
                     21:  */
                     22: /*-
                     23:  * Copyright (c) 1991, 1993
                     24:  *     The Regents of the University of California.  All rights reserved.
                     25:  *
                     26:  * Redistribution and use in source and binary forms, with or without
                     27:  * modification, are permitted provided that the following conditions
                     28:  * are met:
                     29:  * 1. Redistributions of source code must retain the above copyright
                     30:  *    notice, this list of conditions and the following disclaimer.
                     31:  * 2. Redistributions in binary form must reproduce the above copyright
                     32:  *    notice, this list of conditions and the following disclaimer in the
                     33:  *    documentation and/or other materials provided with the distribution.
                     34:  * 3. All advertising materials mentioning features or use of this software
                     35:  *    must display the following acknowledgement:
                     36:  *     This product includes software developed by the University of
                     37:  *     California, Berkeley and its contributors.
                     38:  * 4. Neither the name of the University nor the names of its contributors
                     39:  *    may be used to endorse or promote products derived from this software
                     40:  *    without specific prior written permission.
                     41:  *
                     42:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     43:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     44:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     45:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     46:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     47:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     48:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     49:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     50:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     51:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     52:  * SUCH DAMAGE.
                     53:  *
                     54:  *     @(#)tp_inet.c   8.1 (Berkeley) 6/10/93
                     55:  */
                     56: 
                     57: /***********************************************************
                     58:                Copyright IBM Corporation 1987
                     59: 
                     60:                       All Rights Reserved
                     61: 
                     62: Permission to use, copy, modify, and distribute this software and its 
                     63: documentation for any purpose and without fee is hereby granted, 
                     64: provided that the above copyright notice appear in all copies and that
                     65: both that copyright notice and this permission notice appear in 
                     66: supporting documentation, and that the name of IBM not be
                     67: used in advertising or publicity pertaining to distribution of the
                     68: software without specific, written prior permission.  
                     69: 
                     70: IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
                     71: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
                     72: IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
                     73: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
                     74: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
                     75: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
                     76: SOFTWARE.
                     77: 
                     78: ******************************************************************/
                     79: 
                     80: /*
                     81:  * ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
                     82:  */
                     83: /* 
                     84:  * ARGO TP
                     85:  *
                     86:  * Here is where you find the inet-dependent code.  We've tried
                     87:  * keep all net-level and (primarily) address-family-dependent stuff
                     88:  * out of the tp source, and everthing here is reached indirectly
                     89:  * through a switch table (struct nl_protosw *) tpcb->tp_nlproto 
                     90:  * (see tp_pcb.c). 
                     91:  * The routines here are:
                     92:  *     in_getsufx: gets transport suffix out of an inpcb structure.
                     93:  *     in_putsufx: put transport suffix into an inpcb structure.
                     94:  *     in_putnetaddr: put a whole net addr into an inpcb.
                     95:  *     in_getnetaddr: get a whole net addr from an inpcb.
                     96:  *     in_cmpnetaddr: compare a whole net addr from an isopcb.
                     97:  *     in_recycle_suffix: clear suffix for reuse in inpcb
                     98:  *     tpip_mtu: figure out what size tpdu to use
                     99:  *     tpip_input: take a pkt from ip, strip off its ip header, give to tp
                    100:  *     tpip_output_dg: package a pkt for ip given 2 addresses & some data
                    101:  *     tpip_output: package a pkt for ip given an inpcb & some data
                    102:  */
                    103: 
                    104: #if INET
                    105: 
                    106: #include <sys/param.h>
                    107: #include <sys/socket.h>
                    108: #include <sys/socketvar.h>
                    109: #include <sys/mbuf.h>
                    110: #include <sys/errno.h>
                    111: #include <sys/time.h>
                    112: 
                    113: #include <net/if.h>
                    114: 
                    115: #include <netiso/tp_param.h>
                    116: #include <netiso/argo_debug.h>
                    117: #include <netiso/tp_stat.h>
                    118: #include <netiso/tp_ip.h>
                    119: #include <netiso/tp_pcb.h>
                    120: #include <netiso/tp_trace.h>
                    121: #include <netiso/tp_stat.h>
                    122: #include <netiso/tp_tpdu.h>
                    123: #include <netinet/in_var.h>
                    124: 
                    125: #ifndef ISO
                    126: #include <netiso/iso_chksum.c>
                    127: #endif
                    128: 
                    129: /*
                    130:  * NAME:                       in_getsufx()
                    131: 
                    132:  * CALLED FROM:        pr_usrreq() on PRU_BIND, 
                    133:  *                                     PRU_CONNECT, PRU_ACCEPT, and PRU_PEERADDR
                    134:  *
                    135:  * FUNCTION, ARGUMENTS, and RETURN VALUE:
                    136:  *     Get a transport suffix from an inpcb structure (inp).
                    137:  *     The argument (which) takes the value TP_LOCAL or TP_FOREIGN.
                    138:  *
                    139:  * RETURNS:            internet port / transport suffix
                    140:  *                     (CAST TO AN INT)
                    141:  *
                    142:  * SIDE EFFECTS:       
                    143:  *
                    144:  * NOTES:                      
                    145:  */
                    146: in_getsufx(inp, lenp, data_out, which)
                    147:        struct inpcb *inp;
                    148:        u_short *lenp;
                    149:        caddr_t data_out;
                    150:        int which;
                    151: {
                    152:        *lenp = sizeof(u_short);
                    153:        switch (which) {
                    154:        case TP_LOCAL:
                    155:                *(u_short *)data_out = inp->inp_lport;
                    156:                return;
                    157: 
                    158:        case TP_FOREIGN:
                    159:                *(u_short *)data_out = inp->inp_fport;
                    160:        }
                    161: 
                    162: }
                    163: 
                    164: /*
                    165:  * NAME:               in_putsufx()
                    166:  *
                    167:  * CALLED FROM: tp_newsocket(); i.e., when a connection 
                    168:  *             is being established by an incoming CR_TPDU.
                    169:  *
                    170:  * FUNCTION, ARGUMENTS:
                    171:  *     Put a transport suffix (found in name) into an inpcb structure (inp).
                    172:  *     The argument (which) takes the value TP_LOCAL or TP_FOREIGN.
                    173:  *
                    174:  * RETURNS:            Nada
                    175:  *
                    176:  * SIDE EFFECTS:       
                    177:  *
                    178:  * NOTES:                      
                    179:  */
                    180: /*ARGSUSED*/
                    181: void
                    182: in_putsufx(inp, sufxloc, sufxlen, which)
                    183:        struct inpcb *inp;
                    184:        caddr_t sufxloc;
                    185:        int which;
                    186: {
                    187:        if (which == TP_FOREIGN) {
                    188:                bcopy(sufxloc, (caddr_t)&inp->inp_fport, sizeof(inp->inp_fport));
                    189:        }
                    190: }
                    191: 
                    192: /*
                    193:  * NAME:       in_recycle_tsuffix()    
                    194:  *
                    195:  * CALLED FROM:        tp.trans whenever we go into REFWAIT state.
                    196:  *
                    197:  * FUNCTION and ARGUMENT:
                    198:  *      Called when a ref is frozen, to allow the suffix to be reused. 
                    199:  *     (inp) is the net level pcb.  
                    200:  *
                    201:  * RETURNS:                    Nada
                    202:  *
                    203:  * SIDE EFFECTS:       
                    204:  *
                    205:  * NOTES:      This really shouldn't have to be done in a NET level pcb 
                    206:  *     but... for the internet world that just the way it is done in BSD...
                    207:  *     The alternative is to have the port unusable until the reference
                    208:  *     timer goes off.
                    209:  */
                    210: void
                    211: in_recycle_tsuffix(inp)
                    212:        struct inpcb    *inp;
                    213: {
                    214:        inp->inp_fport = inp->inp_lport = 0;
                    215: }
                    216: 
                    217: /*
                    218:  * NAME:       in_putnetaddr()
                    219:  *
                    220:  * CALLED FROM:
                    221:  *     tp_newsocket(); i.e., when a connection is being established by an
                    222:  *     incoming CR_TPDU.
                    223:  *
                    224:  * FUNCTION and ARGUMENTS:
                    225:  *     Copy a whole net addr from a struct sockaddr (name).
                    226:  *     into an inpcb (inp).
                    227:  *     The argument (which) takes values TP_LOCAL or TP_FOREIGN
                    228:  *
                    229:  * RETURNS:            Nada
                    230:  *
                    231:  * SIDE EFFECTS:       
                    232:  *
                    233:  * NOTES:                      
                    234:  */ 
                    235: void
                    236: in_putnetaddr(inp, name, which)
                    237:        register struct inpcb   *inp;
                    238:        struct sockaddr_in      *name;
                    239:        int which;
                    240: {
                    241:        switch (which) {
                    242:        case TP_LOCAL:
                    243:                bcopy((caddr_t)&name->sin_addr, 
                    244:                        (caddr_t)&inp->inp_laddr, sizeof(struct in_addr));
                    245:                        /* won't work if the dst address (name) is INADDR_ANY */
                    246: 
                    247:                break;
                    248:        case TP_FOREIGN:
                    249:                if( name != (struct sockaddr_in *)0 ) {
                    250:                        bcopy((caddr_t)&name->sin_addr, 
                    251:                                (caddr_t)&inp->inp_faddr, sizeof(struct in_addr));
                    252:                }
                    253:        }
                    254: }
                    255: 
                    256: /*
                    257:  * NAME:       in_putnetaddr()
                    258:  *
                    259:  * CALLED FROM:
                    260:  *     tp_input() when a connection is being established by an
                    261:  *     incoming CR_TPDU, and considered for interception.
                    262:  *
                    263:  * FUNCTION and ARGUMENTS:
                    264:  *     Compare a whole net addr from a struct sockaddr (name),
                    265:  *     with that implicitly stored in an inpcb (inp).
                    266:  *     The argument (which) takes values TP_LOCAL or TP_FOREIGN
                    267:  *
                    268:  * RETURNS:            Nada
                    269:  *
                    270:  * SIDE EFFECTS:       
                    271:  *
                    272:  * NOTES:                      
                    273:  */ 
                    274: in_cmpnetaddr(inp, name, which)
                    275:        register struct inpcb   *inp;
                    276:        register struct sockaddr_in     *name;
                    277:        int which;
                    278: {
                    279:        if (which == TP_LOCAL) {
                    280:                if (name->sin_port && name->sin_port != inp->inp_lport)
                    281:                        return 0;
                    282:                return (name->sin_addr.s_addr == inp->inp_laddr.s_addr);
                    283:        }
                    284:        if (name->sin_port && name->sin_port != inp->inp_fport)
                    285:                return 0;
                    286:        return (name->sin_addr.s_addr == inp->inp_faddr.s_addr);
                    287: }
                    288: 
                    289: /*
                    290:  * NAME:       in_getnetaddr()
                    291:  *
                    292:  * CALLED FROM:
                    293:  *  pr_usrreq() PRU_SOCKADDR, PRU_ACCEPT, PRU_PEERADDR
                    294:  * FUNCTION and ARGUMENTS:
                    295:  *     Copy a whole net addr from an inpcb (inp) into
                    296:  *     an mbuf (name);
                    297:  *     The argument (which) takes values TP_LOCAL or TP_FOREIGN.
                    298:  *
                    299:  * RETURNS:            Nada
                    300:  *
                    301:  * SIDE EFFECTS:       
                    302:  *
                    303:  * NOTES:                      
                    304:  */ 
                    305: 
                    306: void
                    307: in_getnetaddr( inp, name, which)
                    308:        register struct mbuf *name;
                    309:        struct inpcb *inp;
                    310:        int which;
                    311: {
                    312:        register struct sockaddr_in *sin = mtod(name, struct sockaddr_in *);
                    313:        bzero((caddr_t)sin, sizeof(*sin));
                    314:        switch (which) {
                    315:        case TP_LOCAL:
                    316:                sin->sin_addr = inp->inp_laddr;
                    317:                sin->sin_port = inp->inp_lport;
                    318:                break;
                    319:        case TP_FOREIGN:
                    320:                sin->sin_addr = inp->inp_faddr;
                    321:                sin->sin_port = inp->inp_fport;
                    322:                break;
                    323:        default:
                    324:                return;
                    325:        }
                    326:        name->m_len = sin->sin_len = sizeof (*sin);
                    327:        sin->sin_family = AF_INET;
                    328: }
                    329: 
                    330: /*
                    331:  * NAME:       tpip_mtu()
                    332:  *
                    333:  * CALLED FROM:
                    334:  *  tp_route_to() on incoming CR, CC, and pr_usrreq() for PRU_CONNECT
                    335:  *
                    336:  * FUNCTION, ARGUMENTS, and RETURN VALUE:
                    337:  *
                    338:  * Perform subnetwork dependent part of determining MTU information.
                    339:  * It appears that setting a double pointer to the rtentry associated with
                    340:  * the destination, and returning the header size for the network protocol
                    341:  * suffices.
                    342:  * 
                    343:  * SIDE EFFECTS:
                    344:  * Sets tp_routep pointer in pcb.
                    345:  *
                    346:  * NOTES:
                    347:  */
                    348: 
                    349: tpip_mtu(tpcb)
                    350: register struct tp_pcb *tpcb;
                    351: {
                    352:        struct inpcb                    *inp = (struct inpcb *)tpcb->tp_npcb;
                    353: 
                    354:        IFDEBUG(D_CONN)
                    355:                printf("tpip_mtu(tpcb)\n", tpcb);
                    356:                printf("tpip_mtu routing to addr 0x%x\n", inp->inp_faddr.s_addr);
                    357:        ENDDEBUG
                    358:        tpcb->tp_routep = &(inp->inp_route.ro_rt);
                    359:        return (sizeof (struct ip));
                    360: 
                    361: }
                    362: 
                    363: /*
                    364:  * NAME:       tpip_output()
                    365:  *
                    366:  * CALLED FROM:  tp_emit()
                    367:  *
                    368:  * FUNCTION and ARGUMENTS:
                    369:  *  Take a packet(m0) from tp and package it so that ip will accept it.
                    370:  *  This means prepending space for the ip header and filling in a few
                    371:  *  of the fields.
                    372:  *  inp is the inpcb structure; datalen is the length of the data in the
                    373:  *  mbuf string m0.
                    374:  * RETURNS:                    
                    375:  *  whatever (E*) is returned form the net layer output routine.
                    376:  *
                    377:  * SIDE EFFECTS:       
                    378:  *
                    379:  * NOTES:                      
                    380:  */
                    381: 
                    382: int
                    383: tpip_output(inp, m0, datalen, nochksum)
                    384:        struct inpcb            *inp;
                    385:        struct mbuf             *m0;
                    386:        int                             datalen;
                    387:        int                                     nochksum;
                    388: {
                    389:        return tpip_output_dg( &inp->inp_laddr, &inp->inp_faddr, m0, datalen,
                    390:                &inp->inp_route, nochksum);
                    391: }
                    392: 
                    393: /*
                    394:  * NAME:       tpip_output_dg()
                    395:  *
                    396:  * CALLED FROM:  tp_error_emit()
                    397:  *
                    398:  * FUNCTION and ARGUMENTS:
                    399:  *  This is a copy of tpip_output that takes the addresses
                    400:  *  instead of a pcb.  It's used by the tp_error_emit, when we
                    401:  *  don't have an in_pcb with which to call the normal output rtn.
                    402:  *
                    403:  * RETURNS:     ENOBUFS or  whatever (E*) is 
                    404:  *     returned form the net layer output routine.
                    405:  *
                    406:  * SIDE EFFECTS:       
                    407:  *
                    408:  * NOTES:                      
                    409:  */
                    410: 
                    411: /*ARGSUSED*/
                    412: int
                    413: tpip_output_dg(laddr, faddr, m0, datalen, ro, nochksum)
                    414:        struct in_addr          *laddr, *faddr;
                    415:        struct mbuf             *m0;
                    416:        int                             datalen;
                    417:        struct route            *ro;
                    418:        int                                     nochksum;
                    419: {
                    420:        register struct mbuf    *m;
                    421:        register struct ip *ip;
                    422:        int                                     error;
                    423: 
                    424:        IFDEBUG(D_EMIT)
                    425:                printf("tpip_output_dg  datalen 0x%x m0 0x%x\n", datalen, m0);
                    426:        ENDDEBUG
                    427: 
                    428: 
                    429:        MGETHDR(m, M_DONTWAIT, TPMT_IPHDR);
                    430:        if (m == 0) {
                    431:                error = ENOBUFS;
                    432:                goto bad;
                    433:        }
                    434:        m->m_next = m0;
                    435:        MH_ALIGN(m, sizeof(struct ip));
                    436:        m->m_len = sizeof(struct ip);
                    437: 
                    438:        ip = mtod(m, struct ip *);
                    439:        bzero((caddr_t)ip, sizeof *ip);
                    440: 
                    441:        ip->ip_p = IPPROTO_TP;
                    442:        m->m_pkthdr.len = ip->ip_len = sizeof(struct ip) + datalen;
                    443:        ip->ip_ttl = MAXTTL;    
                    444:                /* don't know why you need to set ttl;
                    445:                 * overlay doesn't even make this available
                    446:                 */
                    447: 
                    448:        ip->ip_src = *laddr;
                    449:        ip->ip_dst = *faddr;
                    450: 
                    451:        IncStat(ts_tpdu_sent);
                    452:        IFDEBUG(D_EMIT)
                    453:                dump_mbuf(m, "tpip_output_dg before ip_output\n");
                    454:        ENDDEBUG
                    455: 
                    456:        error = ip_output(m, (struct mbuf *)0, ro, IP_ALLOWBROADCAST, NULL);
                    457: 
                    458:        IFDEBUG(D_EMIT)
                    459:                printf("tpip_output_dg after ip_output\n");
                    460:        ENDDEBUG
                    461: 
                    462:        return error;
                    463: 
                    464: bad:
                    465:        m_freem(m);
                    466:        IncStat(ts_send_drop);
                    467:        return error;
                    468: }
                    469: 
                    470: /*
                    471:  * NAME:  tpip_input()
                    472:  *
                    473:  * CALLED FROM:
                    474:  *     ip's input routine, indirectly through the protosw.
                    475:  *
                    476:  * FUNCTION and ARGUMENTS:
                    477:  * Take a packet (m) from ip, strip off the ip header and give it to tp
                    478:  *
                    479:  * RETURNS:  No return value.  
                    480:  * 
                    481:  * SIDE EFFECTS:
                    482:  *
                    483:  * NOTES:
                    484:  */
                    485: ProtoHook
                    486: tpip_input(m, iplen)
                    487:        struct mbuf *m;
                    488:        int iplen;
                    489: {
                    490:        struct sockaddr_in      src, dst;
                    491:        register struct ip              *ip;
                    492:        int                                             s = splnet(), hdrlen;
                    493: 
                    494:        IncStat(ts_pkt_rcvd);
                    495: 
                    496:        /*
                    497:         * IP layer has already pulled up the IP header,
                    498:         * but the first byte after the IP header may not be there,
                    499:         * e.g. if you came in via loopback, so you have to do an
                    500:         * m_pullup to before you can even look to see how much you
                    501:         * really need.  The good news is that m_pullup will round
                    502:         * up to almost the next mbuf's worth.
                    503:         */
                    504: 
                    505: 
                    506:        if((m = m_pullup(m, iplen + 1)) == MNULL)
                    507:                goto discard;
                    508:        CHANGE_MTYPE(m, TPMT_DATA);
                    509:        
                    510:        /*
                    511:         * Now pull up the whole tp header:
                    512:         * Unfortunately, there may be IP options to skip past so we
                    513:         * just fetch it as an unsigned char.
                    514:         */
                    515:        hdrlen = iplen + 1 + mtod(m, u_char *)[iplen];
                    516: 
                    517:        if( m->m_len < hdrlen ) {
                    518:                if((m = m_pullup(m, hdrlen)) == MNULL){
                    519:                        IFDEBUG(D_TPINPUT)
                    520:                                printf("tp_input, pullup 2!\n");
                    521:                        ENDDEBUG
                    522:                        goto discard;
                    523:                }
                    524:        }
                    525:        /* 
                    526:         * cannot use tp_inputprep() here 'cause you don't 
                    527:         * have quite the same situation
                    528:         */
                    529: 
                    530:        IFDEBUG(D_TPINPUT)
                    531:                dump_mbuf(m, "after tpip_input both pullups");
                    532:        ENDDEBUG
                    533:        /* 
                    534:         * m_pullup may have returned a different mbuf
                    535:         */
                    536:        ip = mtod(m, struct ip *);
                    537: 
                    538:        /*
                    539:         * drop the ip header from the front of the mbuf
                    540:         * this is necessary for the tp checksum
                    541:         */
                    542:        m->m_len -= iplen;
                    543:        m->m_data += iplen;
                    544: 
                    545:        src.sin_addr = *(struct in_addr *)&(ip->ip_src);
                    546:        src.sin_family  = AF_INET;
                    547:        src.sin_len  = sizeof(src);
                    548:        dst.sin_addr = *(struct in_addr *)&(ip->ip_dst);
                    549:        dst.sin_family  = AF_INET; 
                    550:        dst.sin_len  = sizeof(dst);
                    551: 
                    552:        (void) tp_input(m, (struct sockaddr *)&src, (struct sockaddr *)&dst,
                    553:                                0, tpip_output_dg, 0);
                    554:        return 0;
                    555: 
                    556: discard:
                    557:        IFDEBUG(D_TPINPUT)
                    558:                printf("tpip_input DISCARD\n");
                    559:        ENDDEBUG
                    560:        IFTRACE(D_TPINPUT)
                    561:                tptrace(TPPTmisc, "tpip_input DISCARD m",  m,0,0,0);
                    562:        ENDTRACE
                    563:        m_freem(m);
                    564:        IncStat(ts_recv_drop);
                    565:        splx(s);
                    566:        return 0;
                    567: }
                    568: 
                    569: 
                    570: #include <sys/protosw.h>
                    571: #include <netinet/ip_icmp.h>
                    572: 
                    573: extern void tp_quench();
                    574: /*
                    575:  * NAME:       tpin_quench()
                    576:  *
                    577:  * CALLED FROM: tpip_ctlinput()
                    578:  *
                    579:  * FUNCTION and ARGUMENTS:  find the tpcb pointer and pass it to tp_quench
                    580:  *
                    581:  * RETURNS:    Nada
                    582:  *
                    583:  * SIDE EFFECTS:       
                    584:  *
                    585:  * NOTES:                      
                    586:  */
                    587: 
                    588: void
                    589: tpin_quench(inp)
                    590:        struct inpcb *inp;
                    591: {
                    592:        tp_quench((struct tp_pcb *)inp->inp_socket->so_pcb, PRC_QUENCH);
                    593: }
                    594: 
                    595: /*
                    596:  * NAME:       tpip_ctlinput()
                    597:  *
                    598:  * CALLED FROM:
                    599:  *  The network layer through the protosw table.
                    600:  *
                    601:  * FUNCTION and ARGUMENTS:
                    602:  *     When clnp gets an ICMP msg this gets called.
                    603:  *     It either returns an error status to the user or
                    604:  *     causes all connections on this address to be aborted
                    605:  *     by calling the appropriate xx_notify() routine.
                    606:  *     (cmd) is the type of ICMP error.   
                    607:  *     (sa) the address of the sender
                    608:  *
                    609:  * RETURNS:     Nothing
                    610:  *
                    611:  * SIDE EFFECTS:       
                    612:  *
                    613:  * NOTES:                      
                    614:  */
                    615: ProtoHook
                    616: tpip_ctlinput(cmd, sin)
                    617:        int cmd;
                    618:        struct sockaddr_in *sin;
                    619: {
                    620:        extern u_char inetctlerrmap[];
                    621:        extern struct in_addr zeroin_addr;
                    622:        void tp_quench __P((struct inpcb *,int));
                    623:        void tpin_abort __P((struct inpcb *,int));
                    624: 
                    625:        if (sin->sin_family != AF_INET && sin->sin_family != AF_IMPLINK)
                    626:                return 0;
                    627:        if (sin->sin_addr.s_addr == INADDR_ANY)
                    628:                return 0;
                    629:        if (cmd < 0 || cmd > PRC_NCMDS)
                    630:                return 0;
                    631:        switch (cmd) {
                    632: 
                    633:                case    PRC_QUENCH:
                    634:                        in_pcbnotify(&tp_inpcb, (struct sockaddr *)sin, 0,
                    635:                                zeroin_addr, 0, cmd, tp_quench);
                    636:                        break;
                    637: 
                    638:                case    PRC_ROUTEDEAD:
                    639:                case    PRC_HOSTUNREACH:
                    640:                case    PRC_UNREACH_NET:
                    641:                case    PRC_IFDOWN:
                    642:                case    PRC_HOSTDEAD:
                    643:                        in_pcbnotify(&tp_inpcb, (struct sockaddr *)sin, 0,
                    644:                                zeroin_addr, 0, cmd, in_rtchange);
                    645:                        break;
                    646: 
                    647:                default:
                    648:                /*
                    649:                case    PRC_MSGSIZE:
                    650:                case    PRC_UNREACH_HOST:
                    651:                case    PRC_UNREACH_PROTOCOL:
                    652:                case    PRC_UNREACH_PORT:
                    653:                case    PRC_UNREACH_NEEDFRAG:
                    654:                case    PRC_UNREACH_SRCFAIL:
                    655:                case    PRC_REDIRECT_NET:
                    656:                case    PRC_REDIRECT_HOST:
                    657:                case    PRC_REDIRECT_TOSNET:
                    658:                case    PRC_REDIRECT_TOSHOST:
                    659:                case    PRC_TIMXCEED_INTRANS:
                    660:                case    PRC_TIMXCEED_REASS:
                    661:                case    PRC_PARAMPROB:
                    662:                */
                    663:                in_pcbnotify(&tp_inpcb, (struct sockaddr *)sin, 0,
                    664:                        zeroin_addr, 0, cmd, tpin_abort);
                    665:        }
                    666:        return 0;
                    667: }
                    668: 
                    669: /*
                    670:  * NAME:       tpin_abort()
                    671:  *
                    672:  * CALLED FROM:
                    673:  *     xxx_notify() from tp_ctlinput() when
                    674:  *  net level gets some ICMP-equiv. type event.
                    675:  *
                    676:  * FUNCTION and ARGUMENTS:
                    677:  *  Cause the connection to be aborted with some sort of error
                    678:  *  reason indicating that the network layer caused the abort.
                    679:  *  Fakes an ER TPDU so we can go through the driver.
                    680:  *
                    681:  * RETURNS:     Nothing
                    682:  *
                    683:  * SIDE EFFECTS:       
                    684:  *
                    685:  * NOTES:                      
                    686:  */
                    687: 
                    688: ProtoHook
                    689: tpin_abort(inp)
                    690:        struct inpcb *inp;
                    691: {
                    692:        struct tp_event e;
                    693: 
                    694:        e.ev_number = ER_TPDU;
                    695:        e.ATTR(ER_TPDU).e_reason = ENETRESET;
                    696:        (void) tp_driver((struct tp_pcb *)inp->inp_ppcb, &e);
                    697:        return 0;
                    698: }
                    699: 
                    700: #ifdef ARGO_DEBUG
                    701: dump_inaddr(addr)
                    702:        register struct sockaddr_in *addr;
                    703: {
                    704:        printf("INET: port 0x%x; addr 0x%x\n", addr->sin_port, addr->sin_addr);
                    705: }
                    706: #endif /* ARGO_DEBUG */
                    707: #endif /* INET */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.