Annotation of Net2/netiso/tp_inet.c, revision 1.1.1.2

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

unix.superglobalmegacorp.com

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