Annotation of 43BSDTahoe/etc/route.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1983 Regents of the University of California.
                      3:  * All rights reserved.  The Berkeley software License Agreement
                      4:  * specifies the terms and conditions for redistribution.
                      5:  */
                      6: 
                      7: #ifndef lint
                      8: char copyright[] =
                      9: "@(#) Copyright (c) 1983 Regents of the University of California.\n\
                     10:  All rights reserved.\n";
                     11: #endif not lint
                     12: 
                     13: #ifndef lint
                     14: static char sccsid[] = "@(#)route.c    5.9 (Berkeley) 12/26/87";
                     15: #endif not lint
                     16: 
                     17: #include <sys/param.h>
                     18: #include <sys/socket.h>
                     19: #include <sys/ioctl.h>
                     20: #include <sys/mbuf.h>
                     21: 
                     22: #include <net/route.h>
                     23: #include <netinet/in.h>
                     24: #include <netns/ns.h>
                     25: 
                     26: #include <stdio.h>
                     27: #include <errno.h>
                     28: #include <ctype.h>
                     29: #include <netdb.h>
                     30: 
                     31: struct rtentry route;
                     32: int    s;
                     33: int    forcehost, forcenet, doflush, nflag;
                     34: struct sockaddr_in sin = { AF_INET };
                     35: struct in_addr inet_makeaddr();
                     36: char   *malloc();
                     37: 
                     38: main(argc, argv)
                     39:        int argc;
                     40:        char *argv[];
                     41: {
                     42: 
                     43:        if (argc < 2)
                     44:                printf("usage: route [ -n ] [ -f ] [ cmd [ net | host ] args ]\n"),
                     45:                exit(1);
                     46:        s = socket(AF_INET, SOCK_RAW, 0);
                     47:        if (s < 0) {
                     48:                perror("route: socket");
                     49:                exit(1);
                     50:        }
                     51:        argc--, argv++;
                     52:        for (; argc >  0 && argv[0][0] == '-'; argc--, argv++) {
                     53:                for (argv[0]++; *argv[0]; argv[0]++)
                     54:                        switch (*argv[0]) {
                     55:                        case 'f':
                     56:                                doflush++;
                     57:                                break;
                     58:                        case 'n':
                     59:                                nflag++;
                     60:                                break;
                     61:                        }
                     62:        }
                     63:        if (doflush)
                     64:                flushroutes();
                     65:        if (argc > 0) {
                     66:                if (strcmp(*argv, "add") == 0)
                     67:                        newroute(argc, argv);
                     68:                else if (strcmp(*argv, "delete") == 0)
                     69:                        newroute(argc, argv);
                     70:                else if (strcmp(*argv, "change") == 0)
                     71:                        changeroute(argc-1, argv+1);
                     72:                else
                     73:                        printf("%s: huh?\n", *argv);
                     74:        }
                     75: }
                     76: 
                     77: /*
                     78:  * Purge all entries in the routing tables not
                     79:  * associated with network interfaces.
                     80:  */
                     81: #include <nlist.h>
                     82: 
                     83: struct nlist nl[] = {
                     84: #define        N_RTHOST        0
                     85:        { "_rthost" },
                     86: #define        N_RTNET         1
                     87:        { "_rtnet" },
                     88: #define N_RTHASHSIZE   2
                     89:        { "_rthashsize" },
                     90:        "",
                     91: };
                     92: 
                     93: flushroutes()
                     94: {
                     95:        struct mbuf mb;
                     96:        register struct rtentry *rt;
                     97:        register struct mbuf *m;
                     98:        struct mbuf **routehash;
                     99:        int rthashsize, i, doinghost = 1, kmem;
                    100:        char *routename(), *netname();
                    101: 
                    102:        nlist("/vmunix", nl);
                    103:        if (nl[N_RTHOST].n_value == 0) {
                    104:                printf("route: \"rthost\", symbol not in namelist\n");
                    105:                exit(1);
                    106:        }
                    107:        if (nl[N_RTNET].n_value == 0) {
                    108:                printf("route: \"rtnet\", symbol not in namelist\n");
                    109:                exit(1);
                    110:        }
                    111:        if (nl[N_RTHASHSIZE].n_value == 0) {
                    112:                printf("route: \"rthashsize\", symbol not in namelist\n");
                    113:                exit(1);
                    114:        }
                    115:        kmem = open("/dev/kmem", 0);
                    116:        if (kmem < 0) {
                    117:                perror("route: /dev/kmem");
                    118:                exit(1);
                    119:        }
                    120:        lseek(kmem, nl[N_RTHASHSIZE].n_value, 0);
                    121:        read(kmem, &rthashsize, sizeof (rthashsize));
                    122:        routehash = (struct mbuf **)malloc(rthashsize*sizeof (struct mbuf *));
                    123: 
                    124:        lseek(kmem, nl[N_RTHOST].n_value, 0);
                    125:        read(kmem, routehash, rthashsize*sizeof (struct mbuf *));
                    126:        printf("Flushing routing tables:\n");
                    127: again:
                    128:        for (i = 0; i < rthashsize; i++) {
                    129:                if (routehash[i] == 0)
                    130:                        continue;
                    131:                m = routehash[i];
                    132:                while (m) {
                    133:                        lseek(kmem, m, 0);
                    134:                        read(kmem, &mb, sizeof (mb));
                    135:                        rt = mtod(&mb, struct rtentry *);
                    136:                        if (rt->rt_flags & RTF_GATEWAY) {
                    137:                                printf("%-20.20s ", doinghost ?
                    138:                                    routename(&rt->rt_dst) :
                    139:                                    netname(&rt->rt_dst));
                    140:                                printf("%-20.20s ", routename(&rt->rt_gateway));
                    141:                                if (ioctl(s, SIOCDELRT, (caddr_t)rt) < 0)
                    142:                                        error("delete");
                    143:                                else
                    144:                                        printf("done\n");
                    145:                        }
                    146:                        m = mb.m_next;
                    147:                }
                    148:        }
                    149:        if (doinghost) {
                    150:                lseek(kmem, nl[N_RTNET].n_value, 0);
                    151:                read(kmem, routehash, rthashsize*sizeof (struct mbuf *));
                    152:                doinghost = 0;
                    153:                goto again;
                    154:        }
                    155:        close(kmem);
                    156:        free(routehash);
                    157: }
                    158: 
                    159: char *
                    160: routename(sa)
                    161:        struct sockaddr *sa;
                    162: {
                    163:        register char *cp;
                    164:        static char line[50];
                    165:        struct hostent *hp;
                    166:        static char domain[MAXHOSTNAMELEN + 1];
                    167:        static int first = 1;
                    168:        char *index();
                    169:        char *ns_print();
                    170: 
                    171:        if (first) {
                    172:                first = 0;
                    173:                if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
                    174:                    (cp = index(domain, '.')))
                    175:                        (void) strcpy(domain, cp + 1);
                    176:                else
                    177:                        domain[0] = 0;
                    178:        }
                    179:        switch (sa->sa_family) {
                    180: 
                    181:        case AF_INET:
                    182:            {   struct in_addr in;
                    183:                in = ((struct sockaddr_in *)sa)->sin_addr;
                    184: 
                    185:                cp = 0;
                    186:                if (in.s_addr == INADDR_ANY)
                    187:                        cp = "default";
                    188:                if (cp == 0 && !nflag) {
                    189:                        hp = gethostbyaddr(&in, sizeof (struct in_addr),
                    190:                                AF_INET);
                    191:                        if (hp) {
                    192:                                if ((cp = index(hp->h_name, '.')) &&
                    193:                                    !strcmp(cp + 1, domain))
                    194:                                        *cp = 0;
                    195:                                cp = hp->h_name;
                    196:                        }
                    197:                }
                    198:                if (cp)
                    199:                        strcpy(line, cp);
                    200:                else {
                    201: #define C(x)   ((x) & 0xff)
                    202:                        in.s_addr = ntohl(in.s_addr);
                    203:                        (void)sprintf(line, "%u.%u.%u.%u", C(in.s_addr >> 24),
                    204:                           C(in.s_addr >> 16), C(in.s_addr >> 8), C(in.s_addr));
                    205:                }
                    206:                break;
                    207:            }
                    208: 
                    209:        case AF_NS:
                    210:                return (ns_print((struct sockaddr_ns *)sa));
                    211: 
                    212:        default:
                    213:            {   u_short *s = (u_short *)sa->sa_data;
                    214: 
                    215:                (void)sprintf(line, "af %d: %x %x %x %x %x %x %x",
                    216:                    sa->sa_family, s[0], s[1], s[2], s[3], s[4], s[5], s[6]);
                    217:                break;
                    218:            }
                    219:        }
                    220:        return (line);
                    221: }
                    222: 
                    223: /*
                    224:  * Return the name of the network whose address is given.
                    225:  * The address is assumed to be that of a net or subnet, not a host.
                    226:  */
                    227: char *
                    228: netname(sa)
                    229:        struct sockaddr *sa;
                    230: {
                    231:        char *cp = 0;
                    232:        static char line[50];
                    233:        struct netent *np = 0;
                    234:        u_long net, mask;
                    235:        register u_long i;
                    236:        int subnetshift;
                    237:        char *ns_print();
                    238: 
                    239:        switch (sa->sa_family) {
                    240: 
                    241:        case AF_INET:
                    242:            {   struct in_addr in;
                    243:                in = ((struct sockaddr_in *)sa)->sin_addr;
                    244: 
                    245:                i = in.s_addr = ntohl(in.s_addr);
                    246:                if (in.s_addr == 0)
                    247:                        cp = "default";
                    248:                else if (!nflag) {
                    249:                        if (IN_CLASSA(i)) {
                    250:                                mask = IN_CLASSA_NET;
                    251:                                subnetshift = 8;
                    252:                        } else if (IN_CLASSB(i)) {
                    253:                                mask = IN_CLASSB_NET;
                    254:                                subnetshift = 8;
                    255:                        } else {
                    256:                                mask = IN_CLASSC_NET;
                    257:                                subnetshift = 4;
                    258:                        }
                    259:                        /*
                    260:                         * If there are more bits than the standard mask
                    261:                         * would suggest, subnets must be in use.
                    262:                         * Guess at the subnet mask, assuming reasonable
                    263:                         * width subnet fields.
                    264:                         */
                    265:                        while (in.s_addr &~ mask)
                    266:                                mask = (long)mask >> subnetshift;
                    267:                        net = in.s_addr & mask;
                    268:                        while ((mask & 1) == 0)
                    269:                                mask >>= 1, net >>= 1;
                    270:                        np = getnetbyaddr(net, AF_INET);
                    271:                        if (np)
                    272:                                cp = np->n_name;
                    273:                }
                    274:                if (cp)
                    275:                        strcpy(line, cp);
                    276:                else if ((in.s_addr & 0xffffff) == 0)
                    277:                        (void)sprintf(line, "%u", C(in.s_addr >> 24));
                    278:                else if ((in.s_addr & 0xffff) == 0)
                    279:                        (void)sprintf(line, "%u.%u", C(in.s_addr >> 24),
                    280:                            C(in.s_addr >> 16));
                    281:                else if ((in.s_addr & 0xff) == 0)
                    282:                        (void)sprintf(line, "%u.%u.%u", C(in.s_addr >> 24),
                    283:                            C(in.s_addr >> 16), C(in.s_addr >> 8));
                    284:                else
                    285:                        (void)sprintf(line, "%u.%u.%u.%u", C(in.s_addr >> 24),
                    286:                            C(in.s_addr >> 16), C(in.s_addr >> 8),
                    287:                            C(in.s_addr));
                    288:                break;
                    289:            }
                    290: 
                    291:        case AF_NS:
                    292:                return (ns_print((struct sockaddr_ns *)sa));
                    293:                break;
                    294: 
                    295:        default:
                    296:            {   u_short *s = (u_short *)sa->sa_data;
                    297: 
                    298:                (void)sprintf(line, "af %d: %x %x %x %x %x %x %x",
                    299:                    sa->sa_family, s[0], s[1], s[2], s[3], s[4], s[5], s[6]);
                    300:                break;
                    301:            }
                    302:        }
                    303:        return (line);
                    304: }
                    305: 
                    306: newroute(argc, argv)
                    307:        int argc;
                    308:        char *argv[];
                    309: {
                    310:        struct sockaddr_in *sin;
                    311:        char *cmd, *dest, *gateway;
                    312:        int ishost, metric = 0, ret, attempts, oerrno;
                    313:        struct hostent *hp;
                    314:        extern int errno;
                    315: 
                    316:        cmd = argv[0];
                    317:        if ((strcmp(argv[1], "host")) == 0) {
                    318:                forcehost++;
                    319:                argc--, argv++;
                    320:        } else if ((strcmp(argv[1], "net")) == 0) {
                    321:                forcenet++;
                    322:                argc--, argv++;
                    323:        }
                    324:        if (*cmd == 'a') {
                    325:                if (argc != 4) {
                    326:                        printf("usage: %s destination gateway metric\n", cmd);
                    327:                        printf("(metric of 0 if gateway is this host)\n");
                    328:                        return;
                    329:                }
                    330:                metric = atoi(argv[3]);
                    331:        } else {
                    332:                if (argc < 3) {
                    333:                        printf("usage: %s destination gateway\n", cmd);
                    334:                        return;
                    335:                }
                    336:        }
                    337:        sin = (struct sockaddr_in *)&route.rt_dst;
                    338:        ishost = getaddr(argv[1], &route.rt_dst, &hp, &dest, forcenet);
                    339:        if (forcehost)
                    340:                ishost = 1;
                    341:        if (forcenet)
                    342:                ishost = 0;
                    343:        sin = (struct sockaddr_in *)&route.rt_gateway;
                    344:        (void) getaddr(argv[2], &route.rt_gateway, &hp, &gateway, 0);
                    345:        route.rt_flags = RTF_UP;
                    346:        if (ishost)
                    347:                route.rt_flags |= RTF_HOST;
                    348:        if (metric > 0)
                    349:                route.rt_flags |= RTF_GATEWAY;
                    350:        for (attempts = 1; ; attempts++) {
                    351:                errno = 0;
                    352:                if ((ret = ioctl(s, *cmd == 'a' ? SIOCADDRT : SIOCDELRT,
                    353:                     (caddr_t)&route)) == 0)
                    354:                        break;
                    355:                if (errno != ENETUNREACH && errno != ESRCH)
                    356:                        break;
                    357:                if (hp && hp->h_addr_list[1]) {
                    358:                        hp->h_addr_list++;
                    359:                        bcopy(hp->h_addr_list[0], (caddr_t)&sin->sin_addr,
                    360:                            hp->h_length);
                    361:                } else
                    362:                        break;
                    363:        }
                    364:        oerrno = errno;
                    365:        printf("%s %s %s: gateway %s", cmd, ishost? "host" : "net",
                    366:                dest, gateway);
                    367:        if (attempts > 1 && ret == 0)
                    368:            printf(" (%s)",
                    369:                inet_ntoa(((struct sockaddr_in *)&route.rt_gateway)->sin_addr));
                    370:        if (ret == 0)
                    371:                printf("\n");
                    372:        else {
                    373:                printf(": ");
                    374:                fflush(stdout);
                    375:                errno = oerrno;
                    376:                error(0);
                    377:        }
                    378: }
                    379: 
                    380: changeroute(argc, argv)
                    381:        int argc;
                    382:        char *argv[];
                    383: {
                    384:        printf("not supported\n");
                    385: }
                    386: 
                    387: error(cmd)
                    388:        char *cmd;
                    389: {
                    390:        extern int errno;
                    391: 
                    392:        switch(errno) {
                    393:        case ESRCH:
                    394:                fprintf(stderr, "not in table\n");
                    395:                break;
                    396:        case EBUSY:
                    397:                fprintf(stderr, "entry in use\n");
                    398:                break;
                    399:        case ENOBUFS:
                    400:                fprintf(stderr, "routing table overflow\n");
                    401:                break;
                    402:        default:
                    403:                perror(cmd);
                    404:        }
                    405: }
                    406: 
                    407: char *
                    408: savestr(s)
                    409:        char *s;
                    410: {
                    411:        char *sav;
                    412: 
                    413:        sav = malloc(strlen(s) + 1);
                    414:        if (sav == NULL) {
                    415:                fprintf("route: out of memory\n");
                    416:                exit(1);
                    417:        }
                    418:        strcpy(sav, s);
                    419:        return (sav);
                    420: }
                    421: 
                    422: /*
                    423:  * Interpret an argument as a network address of some kind,
                    424:  * returning 1 if a host address, 0 if a network address.
                    425:  */
                    426: getaddr(s, sin, hpp, name, isnet)
                    427:        char *s;
                    428:        struct sockaddr_in *sin;
                    429:        struct hostent **hpp;
                    430:        char **name;
                    431:        int isnet;
                    432: {
                    433:        struct hostent *hp;
                    434:        struct netent *np;
                    435:        u_long val;
                    436: 
                    437:        *hpp = 0;
                    438:        if (strcmp(s, "default") == 0) {
                    439:                sin->sin_family = AF_INET;
                    440:                sin->sin_addr = inet_makeaddr(0, INADDR_ANY);
                    441:                *name = "default";
                    442:                return(0);
                    443:        }
                    444:        sin->sin_family = AF_INET;
                    445:        if (isnet == 0) {
                    446:                val = inet_addr(s);
                    447:                if (val != -1) {
                    448:                        sin->sin_addr.s_addr = val;
                    449:                        *name = s;
                    450:                        return(inet_lnaof(sin->sin_addr) != INADDR_ANY);
                    451:                }
                    452:        }
                    453:        val = inet_network(s);
                    454:        if (val != -1) {
                    455:                sin->sin_addr = inet_makeaddr(val, INADDR_ANY);
                    456:                *name = s;
                    457:                return(0);
                    458:        }
                    459:        np = getnetbyname(s);
                    460:        if (np) {
                    461:                sin->sin_family = np->n_addrtype;
                    462:                sin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY);
                    463:                *name = savestr(np->n_name);
                    464:                return(0);
                    465:        }
                    466:        hp = gethostbyname(s);
                    467:        if (hp) {
                    468:                *hpp = hp;
                    469:                sin->sin_family = hp->h_addrtype;
                    470:                bcopy(hp->h_addr, &sin->sin_addr, hp->h_length);
                    471:                *name = savestr(hp->h_name);
                    472:                return(1);
                    473:        }
                    474:        fprintf(stderr, "%s: bad value\n", s);
                    475:        exit(1);
                    476: }
                    477: 
                    478: short ns_nullh[] = {0,0,0};
                    479: short ns_bh[] = {-1,-1,-1};
                    480: 
                    481: char *
                    482: ns_print(sns)
                    483: struct sockaddr_ns *sns;
                    484: {
                    485:        struct ns_addr work;
                    486:        union { union ns_net net_e; u_long long_e; } net;
                    487:        u_short port;
                    488:        static char mybuf[50], cport[10], chost[25];
                    489:        char *host = "";
                    490:        register char *p; register u_char *q; u_char *q_lim;
                    491: 
                    492:        work = sns->sns_addr;
                    493:        port = ntohs(work.x_port);
                    494:        work.x_port = 0;
                    495:        net.net_e  = work.x_net;
                    496:        if (ns_nullhost(work) && net.long_e == 0) {
                    497:                if (port ) {
                    498:                        (void)sprintf(mybuf, "*.%xH", port);
                    499:                        upHex(mybuf);
                    500:                } else
                    501:                        (void)sprintf(mybuf, "*.*");
                    502:                return (mybuf);
                    503:        }
                    504: 
                    505:        if (bcmp(ns_bh, work.x_host.c_host, 6) == 0) { 
                    506:                host = "any";
                    507:        } else if (bcmp(ns_nullh, work.x_host.c_host, 6) == 0) {
                    508:                host = "*";
                    509:        } else {
                    510:                q = work.x_host.c_host;
                    511:                (void)sprintf(chost, "%02x%02x%02x%02x%02x%02xH",
                    512:                        q[0], q[1], q[2], q[3], q[4], q[5]);
                    513:                for (p = chost; *p == '0' && p < chost + 12; p++);
                    514:                host = p;
                    515:        }
                    516:        if (port)
                    517:                (void)sprintf(cport, ".%xH", htons(port));
                    518:        else
                    519:                *cport = 0;
                    520: 
                    521:        (void)sprintf(mybuf,"%xH.%s%s", ntohl(net.long_e), host, cport);
                    522:        upHex(mybuf);
                    523:        return(mybuf);
                    524: }
                    525: 
                    526: upHex(p0)
                    527: char *p0;
                    528: {
                    529:        register char *p = p0;
                    530:        for (; *p; p++) switch (*p) {
                    531: 
                    532:        case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
                    533:                *p += ('A' - 'a');
                    534:        }
                    535: }

unix.superglobalmegacorp.com

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