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

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

unix.superglobalmegacorp.com

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