Annotation of 43BSDReno/sbin/route/route.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1983, 1989 The Regents of the University of California.
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * Redistribution and use in source and binary forms are permitted provided
        !             6:  * that: (1) source distributions retain this entire copyright notice and
        !             7:  * comment, and (2) distributions including binaries display the following
        !             8:  * acknowledgement:  ``This product includes software developed by the
        !             9:  * University of California, Berkeley and its contributors'' in the
        !            10:  * documentation or other materials provided with the distribution and in
        !            11:  * all advertising materials mentioning features or use of this software.
        !            12:  * Neither the name of the University nor the names of its contributors may
        !            13:  * be used to endorse or promote products derived from this software without
        !            14:  * specific prior written permission.
        !            15:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
        !            16:  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
        !            17:  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        !            18:  */
        !            19: 
        !            20: #ifndef lint
        !            21: char copyright[] =
        !            22: "@(#) Copyright (c) 1983 The Regents of the University of California.\n\
        !            23:  All rights reserved.\n";
        !            24: #endif /* not lint */
        !            25: 
        !            26: #ifndef lint
        !            27: static char sccsid[] = "@(#)route.c    5.27 (Berkeley) 6/22/90";
        !            28: #endif /* not lint */
        !            29: 
        !            30: #include <sys/param.h>
        !            31: #include <sys/socket.h>
        !            32: #include <sys/ioctl.h>
        !            33: #include <sys/file.h>
        !            34: #include <sys/mbuf.h>
        !            35: #include <sys/kinfo.h>
        !            36: 
        !            37: #include <net/route.h>
        !            38: #include <net/if_dl.h>
        !            39: #include <netinet/in.h>
        !            40: #include <netns/ns.h>
        !            41: #include <netiso/iso.h>
        !            42: 
        !            43: #include <netdb.h>
        !            44: #include <stdio.h>
        !            45: #include <errno.h>
        !            46: #include <ctype.h>
        !            47: #include <paths.h>
        !            48: 
        !            49: struct keytab {
        !            50:        char    *kt_cp;
        !            51:        int     kt_i;
        !            52: } keywords[] = {
        !            53: #include "keywords.h"
        !            54: {0, 0}
        !            55: };
        !            56: 
        !            57: struct ortentry route;
        !            58: union  sockunion {
        !            59:        struct  sockaddr sa;
        !            60:        struct  sockaddr_in sin;
        !            61:        struct  sockaddr_ns sns;
        !            62:        struct  sockaddr_iso siso;
        !            63:        struct  sockaddr_dl sdl;
        !            64: } so_dst, so_gate, so_mask, so_genmask, so_ifa, so_ifp, *so_addrs[] =
        !            65: { &so_dst, &so_gate, &so_mask, &so_genmask, &so_ifa, &so_ifp, 0}; 
        !            66: typedef union sockunion *sup;
        !            67: int    pid, rtm_addrs;
        !            68: int    s;
        !            69: int    forcehost, forcenet, doflush, nflag, af, qflag, Cflag, keyword();
        !            70: int    iflag, verbose, aflen = sizeof (struct sockaddr_in);
        !            71: int    locking, lockrest, debugonly;
        !            72: struct sockaddr_in sin = { sizeof(sin), AF_INET };
        !            73: struct rt_metrics rt_metrics;
        !            74: u_long  rtm_inits;
        !            75: struct in_addr inet_makeaddr();
        !            76: char   *malloc(), *routename(), *netname();
        !            77: extern char *iso_ntoa(), *link_ntoa();
        !            78: #define kget(p, d) \
        !            79:        (lseek(kmem, (off_t)(p), 0), read(kmem, (char *)&(d), sizeof (d)))
        !            80: 
        !            81: usage(cp)
        !            82: char *cp;
        !            83: {
        !            84:        fprintf(stderr,
        !            85:            "usage: route [ -nqCv ]  cmd [[ -<qualifers> ] args ]\n");
        !            86:        if (cp) fprintf(stderr, "(botched keyword: %s)\n", cp);
        !            87: 
        !            88:        exit(1);
        !            89: }
        !            90: 
        !            91: main(argc, argv)
        !            92:        int argc;
        !            93:        char *argv[];
        !            94: {
        !            95: 
        !            96:        char *argvp;
        !            97:        if (argc < 2)
        !            98:                usage((char *)0);
        !            99:        argc--, argv++;
        !           100:        for (; argc >  0 && argv[0][0] == '-'; argc--, argv++) {
        !           101:                for (argvp = argv[0]++; *argvp; argvp++)
        !           102:                        switch (*argv[0]) {
        !           103:                        case 'n':
        !           104:                                nflag++;
        !           105:                                break;
        !           106:                        case 'q':
        !           107:                                qflag++;
        !           108:                                break;
        !           109:                        case 'C':
        !           110:                                Cflag++; /* Use old ioctls */
        !           111:                                break;
        !           112:                        case 'v':
        !           113:                                verbose++;
        !           114:                        }
        !           115:        }
        !           116:        pid = getpid();
        !           117:        if (Cflag)
        !           118:                s = socket(AF_INET, SOCK_RAW, 0);
        !           119:        else
        !           120:                s = socket(PF_ROUTE, SOCK_RAW, 0);
        !           121:        if (s < 0) {
        !           122:                perror("route: socket");
        !           123:                exit(1);
        !           124:        }
        !           125:        if (argc > 0) switch (keyword(*argv)) {
        !           126:                case K_ADD:
        !           127:                case K_CHANGE:
        !           128:                case K_DELETE:
        !           129:                        newroute(argc, argv);
        !           130:                case K_MONITOR:
        !           131:                        monitor();
        !           132:                case K_FLUSH:
        !           133:                        flushroutes(argc, argv);
        !           134:        }
        !           135:        usage(*argv);
        !           136: }
        !           137: 
        !           138: /*
        !           139:  * Purge all entries in the routing tables not
        !           140:  * associated with network interfaces.
        !           141:  */
        !           142: flushroutes(argc, argv)
        !           143: char *argv[];
        !           144: {
        !           145:        int bufsize, needed, seqno, rlen;
        !           146:        char *buf, *next, *lim;
        !           147:        register struct rt_msghdr *rtm;
        !           148:        struct {
        !           149:                struct rt_msghdr m_rtm;
        !           150:                union {
        !           151:                        char u_saddrs[200];
        !           152:                        struct sockaddr u_sa;
        !           153:                } m_u;
        !           154:        } m;
        !           155: 
        !           156:        shutdown(s, 0); /* Don't want to read back our messages */
        !           157:        if (argc > 1) {
        !           158:                argv++;
        !           159:                if (argc == 2 && **argv == '-') switch (keyword(1 + *argv)) {
        !           160:                        case K_INET:    af = AF_INET;   break;
        !           161:                        case K_XNS:     af = AF_NS;     break;
        !           162:                        case K_LINK:    af = AF_LINK;   break;
        !           163:                        case K_ISO: case K_OSI: af = AF_ISO; break;
        !           164:                        default: goto bad;
        !           165:                } else
        !           166:                        bad: usage(*argv);
        !           167:        }
        !           168:        if ((needed = getkerninfo(KINFO_RT_DUMP, 0, 0, 0)) < 0)
        !           169:                { perror("route-getkerninfo-estimate"); exit(1);}
        !           170:        if ((buf = malloc(needed)) == 0)
        !           171:                { printf("out of space\n");; exit(1);}
        !           172:        if ((rlen = getkerninfo(KINFO_RT_DUMP, buf, &needed, 0)) < 0)
        !           173:                { perror("actual retrieval of routing table"); exit(1);}
        !           174:        lim = buf + rlen;
        !           175:        for (next = buf; next < lim; next += rtm->rtm_msglen) {
        !           176:                rtm = (struct rt_msghdr *)next;
        !           177:                if ((rtm->rtm_flags & RTF_GATEWAY) == 0)
        !           178:                        continue;
        !           179:                if (af) {
        !           180:                        struct sockaddr *sa = (struct sockaddr *)(rtm + 1);
        !           181:                        if (sa->sa_family != af)
        !           182:                                continue;
        !           183:                }
        !           184:                rtm->rtm_type = RTM_DELETE;
        !           185:                rtm->rtm_seq = seqno;
        !           186:                if ((rlen = write(s, next, rtm->rtm_msglen)) < 0) {
        !           187:                        perror("writing to routing socket");
        !           188:                        printf("got only %d for rlen\n", rlen);
        !           189:                        break;
        !           190:                }
        !           191:                seqno++;
        !           192:                if (qflag)
        !           193:                        continue;
        !           194:                if (verbose) {
        !           195:                        print_rtmsg(rtm, rlen);
        !           196:                } else {
        !           197:                        struct sockaddr *sa = &m.m_u.u_sa;
        !           198:                        printf("%-20.20s ", (rtm->rtm_flags & RTF_HOST) ?
        !           199:                            routename(sa) : netname(sa));
        !           200:                        sa = (struct sockaddr *)(sa->sa_len + (char *)sa);
        !           201:                        printf("%-20.20s ", routename(sa));
        !           202:                        printf("done\n");
        !           203:                }
        !           204:        }
        !           205:        exit(0);
        !           206: }
        !           207:        
        !           208: char *
        !           209: routename(sa)
        !           210:        struct sockaddr *sa;
        !           211: {
        !           212:        register char *cp;
        !           213:        static char line[50];
        !           214:        struct hostent *hp;
        !           215:        static char domain[MAXHOSTNAMELEN + 1];
        !           216:        static int first = 1;
        !           217:        char *index();
        !           218:        char *ns_print();
        !           219: 
        !           220:        if (first) {
        !           221:                first = 0;
        !           222:                if (gethostname(domain, MAXHOSTNAMELEN) == 0 &&
        !           223:                    (cp = index(domain, '.')))
        !           224:                        (void) strcpy(domain, cp + 1);
        !           225:                else
        !           226:                        domain[0] = 0;
        !           227:        }
        !           228:        switch (sa->sa_family) {
        !           229: 
        !           230:        case AF_INET:
        !           231:            {   struct in_addr in;
        !           232:                in = ((struct sockaddr_in *)sa)->sin_addr;
        !           233: 
        !           234:                cp = 0;
        !           235:                if (in.s_addr == INADDR_ANY)
        !           236:                        cp = "default";
        !           237:                if (cp == 0 && !nflag) {
        !           238:                        hp = gethostbyaddr(&in, sizeof (struct in_addr),
        !           239:                                AF_INET);
        !           240:                        if (hp) {
        !           241:                                if ((cp = index(hp->h_name, '.')) &&
        !           242:                                    !strcmp(cp + 1, domain))
        !           243:                                        *cp = 0;
        !           244:                                cp = hp->h_name;
        !           245:                        }
        !           246:                }
        !           247:                if (cp)
        !           248:                        strcpy(line, cp);
        !           249:                else {
        !           250: #define C(x)   ((x) & 0xff)
        !           251:                        in.s_addr = ntohl(in.s_addr);
        !           252:                        (void)sprintf(line, "%u.%u.%u.%u", C(in.s_addr >> 24),
        !           253:                           C(in.s_addr >> 16), C(in.s_addr >> 8), C(in.s_addr));
        !           254:                }
        !           255:                break;
        !           256:            }
        !           257: 
        !           258:        case AF_NS:
        !           259:                return (ns_print((struct sockaddr_ns *)sa));
        !           260: 
        !           261:        case AF_LINK:
        !           262:                return (link_ntoa((struct sockaddr_dl *)sa));
        !           263: 
        !           264:        case AF_ISO:
        !           265:                (void) sprintf(line, "iso %s",
        !           266:                    iso_ntoa(&((struct sockaddr_iso *)sa)->siso_addr));
        !           267:                break;
        !           268: 
        !           269:        default:
        !           270:            {   u_short *s = (u_short *)sa->sa_data;
        !           271:                u_short *slim = s + ((sa->sa_len + 1)>>1);
        !           272:                char *cp = line + sprintf(line, "(%d)", sa->sa_family);
        !           273:                int n;
        !           274: 
        !           275:                while (s < slim) {
        !           276:                        n = sprintf(cp, " %x", *s);
        !           277:                        s++; cp += n;
        !           278:                }
        !           279:                break;
        !           280:            }
        !           281:        }
        !           282:        return (line);
        !           283: }
        !           284: 
        !           285: /*
        !           286:  * Return the name of the network whose address is given.
        !           287:  * The address is assumed to be that of a net or subnet, not a host.
        !           288:  */
        !           289: char *
        !           290: netname(sa)
        !           291:        struct sockaddr *sa;
        !           292: {
        !           293:        char *cp = 0;
        !           294:        static char line[50];
        !           295:        struct netent *np = 0;
        !           296:        u_long net, mask;
        !           297:        register u_long i;
        !           298:        int subnetshift;
        !           299:        char *ns_print();
        !           300: 
        !           301:        switch (sa->sa_family) {
        !           302: 
        !           303:        case AF_INET:
        !           304:            {   struct in_addr in;
        !           305:                in = ((struct sockaddr_in *)sa)->sin_addr;
        !           306: 
        !           307:                i = in.s_addr = ntohl(in.s_addr);
        !           308:                if (in.s_addr == 0)
        !           309:                        cp = "default";
        !           310:                else if (!nflag) {
        !           311:                        if (IN_CLASSA(i)) {
        !           312:                                mask = IN_CLASSA_NET;
        !           313:                                subnetshift = 8;
        !           314:                        } else if (IN_CLASSB(i)) {
        !           315:                                mask = IN_CLASSB_NET;
        !           316:                                subnetshift = 8;
        !           317:                        } else {
        !           318:                                mask = IN_CLASSC_NET;
        !           319:                                subnetshift = 4;
        !           320:                        }
        !           321:                        /*
        !           322:                         * If there are more bits than the standard mask
        !           323:                         * would suggest, subnets must be in use.
        !           324:                         * Guess at the subnet mask, assuming reasonable
        !           325:                         * width subnet fields.
        !           326:                         */
        !           327:                        while (in.s_addr &~ mask)
        !           328:                                mask = (long)mask >> subnetshift;
        !           329:                        net = in.s_addr & mask;
        !           330:                        while ((mask & 1) == 0)
        !           331:                                mask >>= 1, net >>= 1;
        !           332:                        np = getnetbyaddr(net, AF_INET);
        !           333:                        if (np)
        !           334:                                cp = np->n_name;
        !           335:                }
        !           336:                if (cp)
        !           337:                        strcpy(line, cp);
        !           338:                else if ((in.s_addr & 0xffffff) == 0)
        !           339:                        (void)sprintf(line, "%u", C(in.s_addr >> 24));
        !           340:                else if ((in.s_addr & 0xffff) == 0)
        !           341:                        (void)sprintf(line, "%u.%u", C(in.s_addr >> 24),
        !           342:                            C(in.s_addr >> 16));
        !           343:                else if ((in.s_addr & 0xff) == 0)
        !           344:                        (void)sprintf(line, "%u.%u.%u", C(in.s_addr >> 24),
        !           345:                            C(in.s_addr >> 16), C(in.s_addr >> 8));
        !           346:                else
        !           347:                        (void)sprintf(line, "%u.%u.%u.%u", C(in.s_addr >> 24),
        !           348:                            C(in.s_addr >> 16), C(in.s_addr >> 8),
        !           349:                            C(in.s_addr));
        !           350:                break;
        !           351:            }
        !           352: 
        !           353:        case AF_NS:
        !           354:                return (ns_print((struct sockaddr_ns *)sa));
        !           355:                break;
        !           356: 
        !           357:        case AF_LINK:
        !           358:                return (link_ntoa((struct sockaddr_dl *)sa));
        !           359: 
        !           360:        case AF_ISO:
        !           361:                (void) sprintf(line, "iso %s",
        !           362:                    iso_ntoa(&((struct sockaddr_iso *)sa)->siso_addr));
        !           363:                break;
        !           364: 
        !           365:        default:
        !           366:            {   u_short *s = (u_short *)sa->sa_data;
        !           367:                u_short *slim = s + ((sa->sa_len + 1)>>1);
        !           368:                char *cp = line + sprintf(line, "af %d:", sa->sa_family);
        !           369:                int n;
        !           370: 
        !           371:                while (s < slim) {
        !           372:                        n = sprintf(cp, " %x", *s);
        !           373:                        s++; cp += n;
        !           374:                }
        !           375:                break;
        !           376:            }
        !           377:        }
        !           378:        return (line);
        !           379: }
        !           380: 
        !           381: set_metric(value, key)
        !           382: char *value;
        !           383: {
        !           384:        int flag = 0; 
        !           385:        u_long noval, *valp = &noval;
        !           386: 
        !           387:        switch (key) {
        !           388: #define caseof(x, y, z)        case x: valp = &rt_metrics.z; flag = y; break
        !           389:        caseof(K_MTU, RTV_MTU, rmx_mtu);
        !           390:        caseof(K_HOPCOUNT, RTV_HOPCOUNT, rmx_hopcount);
        !           391:        caseof(K_EXPIRE, RTV_EXPIRE, rmx_expire);
        !           392:        caseof(K_RECVPIPE, RTV_RPIPE, rmx_recvpipe);
        !           393:        caseof(K_SENDPIPE, RTV_SPIPE, rmx_sendpipe);
        !           394:        caseof(K_SSTHRESH, RTV_SSTHRESH, rmx_ssthresh);
        !           395:        caseof(K_RTT, RTV_RTT, rmx_rtt);
        !           396:        caseof(K_RTTVAR, RTV_RTTVAR, rmx_rttvar);
        !           397:        }
        !           398:        rtm_inits |= flag;
        !           399:        if (lockrest || locking)
        !           400:                rt_metrics.rmx_locks |= flag;
        !           401:        if (locking)
        !           402:                locking = 0;
        !           403:        *valp = atoi(value);
        !           404: }
        !           405: 
        !           406: newroute(argc, argv)
        !           407:        int argc;
        !           408:        register char **argv;
        !           409: {
        !           410:        struct sockaddr_in *sin;
        !           411:        char *cmd, *dest, *gateway, *mask;
        !           412:        int ishost, metric = 0, ret, attempts, oerrno, flags = 0, next;
        !           413:        int key;
        !           414:        struct hostent *hp = 0;
        !           415:        extern int errno;
        !           416: 
        !           417:        shutdown(s, 0); /* Don't want to read back our messages */
        !           418:        cmd = argv[0];
        !           419:        while (--argc > 0) {
        !           420:                if (**(++argv)== '-') {
        !           421:                        switch(key = keyword(1 + *argv)) {
        !           422:                        case K_LINK:
        !           423:                                af = AF_LINK;
        !           424:                                aflen = sizeof(struct sockaddr_dl);
        !           425:                                break;
        !           426:                        case K_OSI:
        !           427:                        case K_ISO:
        !           428:                                af = AF_ISO;
        !           429:                                aflen = sizeof(struct sockaddr_iso);
        !           430:                                break;
        !           431:                        case K_INET:
        !           432:                                af = AF_INET;
        !           433:                                aflen = sizeof(struct sockaddr_in);
        !           434:                                break;
        !           435:                        case K_XNS:
        !           436:                                af = AF_NS;
        !           437:                                aflen = sizeof(struct sockaddr_ns);
        !           438:                                break;
        !           439:                        case K_IFACE:
        !           440:                        case K_INTERFACE:
        !           441:                                iflag++;
        !           442:                                break;
        !           443:                        case K_LOCK:
        !           444:                                locking = 1;
        !           445:                                break;
        !           446:                        case K_LOCKREST:
        !           447:                                lockrest = 1;
        !           448:                                break;
        !           449:                        case K_HOST:
        !           450:                                forcehost++;
        !           451:                                break;
        !           452:                        case K_NETMASK:
        !           453:                                argc--;
        !           454:                                (void) getaddr(RTA_NETMASK, *++argv, 0);
        !           455:                                /* FALLTHROUGH */
        !           456:                        case K_NET:
        !           457:                                forcenet++;
        !           458:                                break;
        !           459:                        case K_CLONING:
        !           460:                                flags |= RTF_CLONING;
        !           461:                                break;
        !           462:                        case K_XRESOLVE:
        !           463:                                flags |= RTF_XRESOLVE;
        !           464:                                break;
        !           465:                        case K_GENMASK:
        !           466:                                argc--;
        !           467:                                (void) getaddr(RTA_GENMASK, *++argv, 0);
        !           468:                                break;
        !           469:                        case K_MTU:
        !           470:                        case K_HOPCOUNT:
        !           471:                        case K_EXPIRE:
        !           472:                        case K_RECVPIPE:
        !           473:                        case K_SENDPIPE:
        !           474:                        case K_SSTHRESH:
        !           475:                        case K_RTT:
        !           476:                        case K_RTTVAR:
        !           477:                                argc--;
        !           478:                                set_metric(*++argv, key);
        !           479:                                break;
        !           480:                        default:
        !           481:                                usage(1+*argv);
        !           482:                        }
        !           483:                } else {
        !           484:                        if ((rtm_addrs & RTA_DST) == 0) {
        !           485:                                dest = *argv;
        !           486:                                ishost = getaddr(RTA_DST, *argv, &hp);
        !           487:                        } else if ((rtm_addrs & RTA_GATEWAY) == 0) {
        !           488:                                gateway = *argv;
        !           489:                                (void) getaddr(RTA_GATEWAY, *argv, &hp);
        !           490:                        } else {
        !           491:                                int ret = atoi(*argv);
        !           492:                                if (ret == 0) {
        !           493:                                    printf("%s,%s", "old usage of trailing 0",
        !           494:                                           "assuming route to if\n");
        !           495:                                    iflag = 1;
        !           496:                                    continue;
        !           497:                                } else if (ret > 0 && ret < 10) {
        !           498:                                    printf("old usage of trailing digit, ");
        !           499:                                    printf("assuming route via gateway\n");
        !           500:                                    iflag = 0;
        !           501:                                    continue;
        !           502:                                }
        !           503:                                (void) getaddr(RTA_NETMASK, *argv, 0);
        !           504:                        }
        !           505:                }
        !           506:        }
        !           507:        if (forcehost)
        !           508:                ishost = 1;
        !           509:        if (forcenet)
        !           510:                ishost = 0;
        !           511:        flags |= RTF_UP;
        !           512:        if (ishost)
        !           513:                flags |= RTF_HOST;
        !           514:        if (iflag == 0)
        !           515:                flags |= RTF_GATEWAY;
        !           516:        for (attempts = 1; ; attempts++) {
        !           517:                errno = 0;
        !           518:                if (Cflag && (af == AF_INET || af == AF_NS)) {
        !           519:                        route.rt_flags = flags;
        !           520:                        route.rt_dst = so_dst.sa;
        !           521:                        route.rt_gateway = so_gate.sa;
        !           522:                        if ((ret = ioctl(s, *cmd == 'a' ? SIOCADDRT : SIOCDELRT,
        !           523:                             (caddr_t)&route)) == 0)
        !           524:                                break;
        !           525:                } else {
        !           526:                    if ((ret = rtmsg(*cmd, flags)) == 0);
        !           527:                                break;
        !           528:                }
        !           529:                if (errno != ENETUNREACH && errno != ESRCH)
        !           530:                        break;
        !           531:                if (hp && hp->h_addr_list[1]) {
        !           532:                        hp->h_addr_list++;
        !           533:                        bcopy(hp->h_addr_list[0], (caddr_t)&so_dst.sin.sin_addr,
        !           534:                            hp->h_length);
        !           535:                } else
        !           536:                        break;
        !           537:        }
        !           538:        oerrno = errno;
        !           539:        printf("%s %s %s: gateway %s", cmd, ishost? "host" : "net",
        !           540:                dest, gateway);
        !           541:        if (attempts > 1 && ret == 0)
        !           542:            printf(" (%s)",
        !           543:                inet_ntoa(((struct sockaddr_in *)&route.rt_gateway)->sin_addr));
        !           544:        if (ret == 0)
        !           545:                printf("\n");
        !           546:        else {
        !           547:                printf(": ");
        !           548:                fflush(stdout);
        !           549:                errno = oerrno;
        !           550:                error("");
        !           551:        }
        !           552:        exit(0);
        !           553: }
        !           554: 
        !           555: error(cmd)
        !           556:        char *cmd;
        !           557: {
        !           558:        extern int errno;
        !           559: 
        !           560:        switch(errno) {
        !           561:        case ESRCH:
        !           562:                printf("not in table\n");
        !           563:                break;
        !           564:        case EBUSY:
        !           565:                printf("entry in use\n");
        !           566:                break;
        !           567:        case ENOBUFS:
        !           568:                printf("routing table overflow\n");
        !           569:                break;
        !           570:        default:
        !           571:                printf("ioctl returns %d\n", errno);
        !           572:                perror(cmd);
        !           573:        }
        !           574:        fflush(stdout);
        !           575:        errno = 0;
        !           576: }
        !           577: 
        !           578: char *
        !           579: savestr(s)
        !           580:        char *s;
        !           581: {
        !           582:        char *sav;
        !           583: 
        !           584:        sav = malloc(strlen(s) + 1);
        !           585:        if (sav == NULL) {
        !           586:                fprintf("route: out of memory\n");
        !           587:                exit(1);
        !           588:        }
        !           589:        strcpy(sav, s);
        !           590:        return (sav);
        !           591: }
        !           592: 
        !           593: inet_makenetandmask(net, sin)
        !           594: u_long net;
        !           595: register struct sockaddr_in *sin;
        !           596: {
        !           597:        u_long addr;
        !           598:        u_long mask = 0;
        !           599:        register char *cp;
        !           600: 
        !           601:        rtm_addrs |= RTA_NETMASK;
        !           602:        if (net == 0)
        !           603:                mask = addr = 0;
        !           604:        else if (net < 128) {
        !           605:                addr = net << IN_CLASSA_NSHIFT;
        !           606:                mask = IN_CLASSA_NET;
        !           607:        } else if (net < 65536) {
        !           608:                addr = net << IN_CLASSB_NSHIFT;
        !           609:                mask = IN_CLASSB_NET;
        !           610:        } else if (net < 16777216L) {
        !           611:                addr = net << IN_CLASSC_NSHIFT;
        !           612:                mask = IN_CLASSC_NET;
        !           613:        } else {
        !           614:                addr = net;
        !           615:                if ((addr & IN_CLASSA_HOST) == 0)
        !           616:                        mask =  IN_CLASSA_NET;
        !           617:                else if ((addr & IN_CLASSB_HOST) == 0)
        !           618:                        mask =  IN_CLASSB_NET;
        !           619:                else if ((addr & IN_CLASSC_HOST) == 0)
        !           620:                        mask =  IN_CLASSC_NET;
        !           621:                else
        !           622:                        mask = -1;
        !           623:        }
        !           624:        sin->sin_addr.s_addr = htonl(addr);
        !           625:        sin = &so_mask.sin;
        !           626:        sin->sin_addr.s_addr = htonl(mask);
        !           627:        sin->sin_len = 0;
        !           628:        sin->sin_family = 0;
        !           629:        cp = (char *)(1 + &(sin->sin_addr));
        !           630:        while (*--cp == 0 && cp > (char *)sin)
        !           631:                ;
        !           632:        sin->sin_len = 1 + cp - (char *)sin;
        !           633: }
        !           634: 
        !           635: /*
        !           636:  * Interpret an argument as a network address of some kind,
        !           637:  * returning 1 if a host address, 0 if a network address.
        !           638:  */
        !           639: getaddr(which, s, hpp)
        !           640:        char *s;
        !           641:        struct hostent **hpp;
        !           642: {
        !           643:        register union sockunion *su;
        !           644:        struct  ns_addr ns_addr();
        !           645:        struct iso_addr *iso_addr();
        !           646:        struct hostent *hp;
        !           647:        struct netent *np;
        !           648:        u_long val;
        !           649: 
        !           650:        if (af == 0) {
        !           651:                af = AF_INET;
        !           652:                aflen = sizeof(struct sockaddr_in);
        !           653:        }
        !           654:        rtm_addrs |= which;
        !           655:        switch (which) {
        !           656:        case RTA_DST:           su = so_addrs[0]; su->sa.sa_family = af; break;
        !           657:        case RTA_GATEWAY:       su = so_addrs[1]; su->sa.sa_family = af; break;
        !           658:        case RTA_NETMASK:       su = so_addrs[2]; break;
        !           659:        case RTA_GENMASK:       su = so_addrs[3]; break;
        !           660:        default:                usage("Internal Error"); /*NOTREACHED*/
        !           661:        }
        !           662:        su->sa.sa_len = aflen;
        !           663:        if (strcmp(s, "default") == 0) {
        !           664:                switch (which) {
        !           665:                case RTA_DST:
        !           666:                        forcenet++;
        !           667:                        getaddr(RTA_NETMASK, s, 0);
        !           668:                        break;
        !           669:                case RTA_NETMASK:
        !           670:                case RTA_GENMASK:
        !           671:                        su->sa.sa_len = 0;
        !           672:                }
        !           673:                return 0;
        !           674:        }
        !           675:        if (af == AF_NS)
        !           676:                goto do_xns;
        !           677:        if (af == AF_OSI)
        !           678:                goto do_osi;
        !           679:        if (af == AF_LINK)
        !           680:                goto do_link;
        !           681:        if (hpp == 0) hpp = &hp;
        !           682:        *hpp = 0;
        !           683:        if (((val = inet_addr(s)) != -1) &&
        !           684:            (which != RTA_DST || forcenet == 0)) {
        !           685:                su->sin.sin_addr.s_addr = val;
        !           686:                if (inet_lnaof(su->sin.sin_addr) != INADDR_ANY)
        !           687:                        return (1);
        !           688:                else {
        !           689:                        val = ntohl(val);
        !           690:                out:    if (which == RTA_DST)
        !           691:                                inet_makenetandmask(val, &su->sin);
        !           692:                        return (0);
        !           693:                }
        !           694:        }
        !           695:        val = inet_network(s);
        !           696:        if (val != -1) {
        !           697:                goto out;
        !           698:        }
        !           699:        np = getnetbyname(s);
        !           700:        if (np) {
        !           701:                val = np->n_net;
        !           702:                goto out;
        !           703:        }
        !           704:        hp = gethostbyname(s);
        !           705:        if (hp) {
        !           706:                *hpp = hp;
        !           707:                su->sin.sin_family = hp->h_addrtype;
        !           708:                bcopy(hp->h_addr, &su->sin.sin_addr, hp->h_length);
        !           709:                return (1);
        !           710:        }
        !           711:        fprintf(stderr, "%s: bad value\n", s);
        !           712:        exit(1);
        !           713: do_xns:
        !           714:        if (val == 0)
        !           715:                return(0);
        !           716:        if (which == RTA_DST) {
        !           717:                extern short ns_bh[3];
        !           718:                struct sockaddr_ns *sms = &(so_mask.sns);
        !           719:                bzero((char *)sms, sizeof(*sms));
        !           720:                sms->sns_family = 0;
        !           721:                sms->sns_len = 6;
        !           722:                sms->sns_addr.x_net = *(union ns_net *)ns_bh;
        !           723:                rtm_addrs |= RTA_NETMASK;
        !           724:        }
        !           725:        su->sns.sns_addr = ns_addr(s);
        !           726:        return (!ns_nullhost(su->sns.sns_addr));
        !           727: do_osi:
        !           728:        su->siso.siso_addr = *iso_addr(s);
        !           729:        if (which == RTA_NETMASK || which == RTA_GENMASK) {
        !           730:                register char *cp = (char *)TSEL(&su->siso);
        !           731:                su->siso.siso_nlen = 0;
        !           732:                do {--cp ;} while ((cp > (char *)su) && (*cp == 0));
        !           733:                su->siso.siso_len = 1 + cp - (char *)su;
        !           734:        }
        !           735:        return (1);
        !           736: do_link:
        !           737:        link_addr(s, &su->sdl);
        !           738:        return (1);
        !           739: }
        !           740: 
        !           741: short ns_nullh[] = {0,0,0};
        !           742: short ns_bh[] = {-1,-1,-1};
        !           743: 
        !           744: char *
        !           745: ns_print(sns)
        !           746: struct sockaddr_ns *sns;
        !           747: {
        !           748:        struct ns_addr work;
        !           749:        union { union ns_net net_e; u_long long_e; } net;
        !           750:        u_short port;
        !           751:        static char mybuf[50], cport[10], chost[25];
        !           752:        char *host = "";
        !           753:        register char *p; register u_char *q; u_char *q_lim;
        !           754: 
        !           755:        work = sns->sns_addr;
        !           756:        port = ntohs(work.x_port);
        !           757:        work.x_port = 0;
        !           758:        net.net_e  = work.x_net;
        !           759:        if (ns_nullhost(work) && net.long_e == 0) {
        !           760:                if (port ) {
        !           761:                        (void)sprintf(mybuf, "*.%xH", port);
        !           762:                        upHex(mybuf);
        !           763:                } else
        !           764:                        (void)sprintf(mybuf, "*.*");
        !           765:                return (mybuf);
        !           766:        }
        !           767: 
        !           768:        if (bcmp(ns_bh, work.x_host.c_host, 6) == 0) { 
        !           769:                host = "any";
        !           770:        } else if (bcmp(ns_nullh, work.x_host.c_host, 6) == 0) {
        !           771:                host = "*";
        !           772:        } else {
        !           773:                q = work.x_host.c_host;
        !           774:                (void)sprintf(chost, "%02x%02x%02x%02x%02x%02xH",
        !           775:                        q[0], q[1], q[2], q[3], q[4], q[5]);
        !           776:                for (p = chost; *p == '0' && p < chost + 12; p++);
        !           777:                host = p;
        !           778:        }
        !           779:        if (port)
        !           780:                (void)sprintf(cport, ".%xH", htons(port));
        !           781:        else
        !           782:                *cport = 0;
        !           783: 
        !           784:        (void)sprintf(mybuf,"%xH.%s%s", ntohl(net.long_e), host, cport);
        !           785:        upHex(mybuf);
        !           786:        return(mybuf);
        !           787: }
        !           788: 
        !           789: upHex(p0)
        !           790: char *p0;
        !           791: {
        !           792:        register char *p = p0;
        !           793:        for (; *p; p++) switch (*p) {
        !           794: 
        !           795:        case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
        !           796:                *p += ('A' - 'a');
        !           797:        }
        !           798: }
        !           799: 
        !           800: monitor()
        !           801: {
        !           802:        int n;
        !           803:        char msg[2048];
        !           804:        verbose = 1;
        !           805:        for(;;) {
        !           806:                n = read(s, msg, 2048);
        !           807:                printf("got message of size %d\n", n);
        !           808:                print_rtmsg((struct rt_msghdr *)msg);
        !           809:        }
        !           810: }
        !           811: 
        !           812: struct {
        !           813:        struct  rt_msghdr m_rtm;
        !           814:        char m_space[512];
        !           815: } m_rtmsg;
        !           816: 
        !           817: rtmsg(cmd, flags)
        !           818: {
        !           819:        static int seq;
        !           820:        int rlen;
        !           821:        extern int errno;
        !           822:        register char *cp = m_rtmsg.m_space;
        !           823:        register int l;
        !           824: 
        !           825:        errno = 0;
        !           826:        bzero((char *)&m_rtmsg, sizeof(m_rtmsg));
        !           827:        if (cmd == 'a')
        !           828:                cmd = RTM_ADD;
        !           829:        else if (cmd == 'c')
        !           830:                cmd = RTM_CHANGE;
        !           831:        else
        !           832:                cmd = RTM_DELETE;
        !           833:        m_rtmsg.m_rtm.rtm_flags = flags;
        !           834:        m_rtmsg.m_rtm.rtm_version = RTM_VERSION;
        !           835:        m_rtmsg.m_rtm.rtm_seq = ++seq;
        !           836:        m_rtmsg.m_rtm.rtm_addrs = rtm_addrs;
        !           837:        m_rtmsg.m_rtm.rtm_rmx = rt_metrics;
        !           838:        m_rtmsg.m_rtm.rtm_inits = rtm_inits;
        !           839: 
        !           840: #define ROUND(a) (1 + (((a) - 1) | (sizeof(long) - 1)))
        !           841: #define NEXTADDR(w, u) { if (rtm_addrs & (w)) {l = (u).sa.sa_len;\
        !           842:        if(verbose)sodump(&(u),"u");if(l == 0) l = sizeof(int); l = ROUND(l);\
        !           843:                bcopy((char *)&(u), cp, l); cp += l;}}
        !           844: 
        !           845:        NEXTADDR(RTA_DST, so_dst);
        !           846:        NEXTADDR(RTA_GATEWAY, so_gate);
        !           847:        NEXTADDR(RTA_NETMASK, so_mask);
        !           848:        NEXTADDR(RTA_GENMASK, so_genmask);
        !           849:        m_rtmsg.m_rtm.rtm_msglen = l = cp - (char *)&m_rtmsg;
        !           850:        m_rtmsg.m_rtm.rtm_type = cmd;
        !           851:        if (verbose)
        !           852:                print_rtmsg(&m_rtmsg.m_rtm, l);
        !           853:        if (debugonly)
        !           854:                return 0;
        !           855:        if ((rlen = write(s, (char *)&m_rtmsg, l)) < 0) {
        !           856:                perror("writing to routing socket");
        !           857:                printf("got only %d for rlen\n", rlen);
        !           858:                return (-1);
        !           859:        }
        !           860:        return (0);
        !           861: }
        !           862: 
        !           863: char *msgtypes[] = {
        !           864: "",
        !           865: "RTM_ADD: Add Route",
        !           866: "RTM_DELETE: Delete Route",
        !           867: "RTM_CHANGE: Change Metrics or flags",
        !           868: "RTM_GET: Report Metrics",
        !           869: "RTM_LOSING: Kernel Suspects Partitioning",
        !           870: "RTM_REDIRECT: Told to use different route",
        !           871: "RTM_MISS: Lookup failed on this address",
        !           872: "RTM_LOCK: fix specified metrics",
        !           873: "RTM_OLDADD: caused by SIOCADDRT",
        !           874: "RTM_OLDDEL: caused by SIOCDELRT",
        !           875: 0, };
        !           876: 
        !           877: char metricnames[] =
        !           878: "\010rttvar\7rtt\6ssthresh\5sendpipe\4recvpipe\3expire\2hopcount\1mtu";
        !           879: char routeflags[] = 
        !           880: "\1UP\2GATEWAY\3HOST\5DYNAMIC\6MODIFIED\7DONE\010MASK_PRESENT\011CLONING\012XRESOLVE";
        !           881: 
        !           882: #define ROUNDUP(a) ((char *)(1 + (((((int)a)) - 1) | (sizeof(long) - 1))))
        !           883: 
        !           884: print_rtmsg(rtm, n)
        !           885: register struct rt_msghdr *rtm;
        !           886: {
        !           887:        char *cp;
        !           888:        register struct sockaddr *sa;
        !           889:        int i;
        !           890: 
        !           891:        if (verbose == 0)
        !           892:                return;
        !           893:        if (rtm->rtm_version != RTM_VERSION) {
        !           894:            printf("routing message version %d not understood\n",
        !           895:                                                        rtm->rtm_version);
        !           896:        } else {
        !           897:            printf("%s\npid: %d, len %d, seq %d, errno %d, flags:",
        !           898:                    msgtypes[rtm->rtm_type], rtm->rtm_pid, rtm->rtm_msglen,
        !           899:                    rtm->rtm_seq, rtm->rtm_errno); 
        !           900:            bprintf(stdout, rtm->rtm_flags, routeflags);
        !           901:            printf("\nlocks: "); bprintf(stdout, rtm->rtm_rmx.rmx_locks, metricnames);
        !           902:            printf(" inits: "); bprintf(stdout, rtm->rtm_inits, metricnames);
        !           903:            printf("\nsockaddrs: ");
        !           904:            bprintf(stdout, rtm->rtm_addrs,
        !           905:                "\1DST\2GATEWAY\3NETMASK\4GENMASK\5IFP\6IFA\7AUTHOR");
        !           906:            putchar('\n');
        !           907:            cp = ((char *)(rtm + 1));
        !           908:            if (rtm->rtm_addrs)
        !           909:                for (i = 1; i; i <<= 1)
        !           910:                    if (i & rtm->rtm_addrs) {
        !           911:                            sa = (struct sockaddr *)cp;
        !           912:                            printf(" %s", routename(sa));
        !           913:                            cp = ROUNDUP(cp + sa->sa_len);
        !           914:                    }
        !           915:            putchar('\n');
        !           916:        }
        !           917:        fflush(stdout);
        !           918: }
        !           919: 
        !           920: bprintf(fp, b, s)
        !           921: register FILE *fp;
        !           922: register int b;
        !           923: register u_char *s;
        !           924: {
        !           925:        register int i;
        !           926:        int gotsome = 0;
        !           927: 
        !           928:        if (b == 0)
        !           929:                return;
        !           930:        while (i = *s++) {
        !           931:                if (b & (1 << (i-1))) {
        !           932:                        if (gotsome == 0) i = '<'; else i = ',';
        !           933:                        putc(i, fp);
        !           934:                        gotsome = 1;
        !           935:                        for (; (i = *s) > 32; s++)
        !           936:                                putc(i, fp);
        !           937:                } else
        !           938:                        while (*s > 32)
        !           939:                                s++;
        !           940:        }
        !           941:        if (gotsome)
        !           942:                putc('>', fp);
        !           943: }
        !           944: int
        !           945: keyword(cp)
        !           946: char *cp;
        !           947: {
        !           948:        register struct keytab *kt = keywords;
        !           949:        while (kt->kt_cp && strcmp(kt->kt_cp, cp))
        !           950:                kt++;
        !           951:        return kt->kt_i;
        !           952: }
        !           953: 
        !           954: sodump(su, which)
        !           955: register union sockunion *su;
        !           956: char *which;
        !           957: {
        !           958:        switch (su->sa.sa_family) {
        !           959:        case AF_LINK:
        !           960:                printf("%s: link %s; ", which, link_ntoa(&su->sdl));
        !           961:                break;
        !           962:        case AF_ISO:
        !           963:                printf("%s: iso %s; ", which, iso_ntoa(&su->siso.siso_addr));
        !           964:                break;
        !           965:        case AF_INET:
        !           966:                printf("%s: inet %s; ", which, inet_ntoa(su->sin.sin_addr));
        !           967:                break;
        !           968:        case AF_NS:
        !           969:                printf("%s: xns %s; ", which, ns_ntoa(&su->sns.sns_addr));
        !           970:                break;
        !           971:        }
        !           972:        fflush(stdout);
        !           973: }

unix.superglobalmegacorp.com

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