Annotation of 43BSDReno/sbin/route/route.c, revision 1.1.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.