Annotation of 43BSDReno/sys/netiso/tp_inet.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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