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

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

unix.superglobalmegacorp.com

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