Annotation of researchv8dc/cmd/inet/etc/routed.c, revision 1.1

1.1     ! root        1: #include <stdio.h>
        !             2: #include <signal.h>
        !             3: #include <errno.h>
        !             4: #include <sys/param.h>
        !             5: #include <sys/types.h>
        !             6: #include <sgtty.h>
        !             7: #include <sys/inet/udp_user.h>
        !             8: #include "config.h"
        !             9: 
        !            10: #define IPDEVICE "/dev/ip16"   /* device for getting ip info from */
        !            11: 
        !            12: int udpfd, ipfd, verbose, trace, quiet;
        !            13: struct in_service *servp;
        !            14: extern errno;
        !            15: extern char *in_ntoa();
        !            16: extern u_short cksum();
        !            17: 
        !            18: struct udppacket {
        !            19:        struct udpaddr addr;
        !            20:        char buf[4096];
        !            21: };
        !            22: 
        !            23: main(argc, argv)
        !            24: char *argv[];
        !            25: {
        !            26:        int n, i;
        !            27:        struct udppacket packet;
        !            28: 
        !            29:        for(i = 1; i < argc; i++){
        !            30:                if(strcmp(argv[i], "-v") == 0)
        !            31:                        verbose++;
        !            32:                else if(strcmp(argv[i], "-q") == 0)
        !            33:                        quiet++;
        !            34:                else if(strcmp(argv[i], "-t") == 0)
        !            35:                        trace++;
        !            36:        }
        !            37: 
        !            38:        servp = in_service("route", "udp", 0);
        !            39:        if (servp == NULL) {
        !            40:                printf("route service not in table\n");
        !            41:                exit(1);
        !            42:        }
        !            43:        if ((udpfd = udp_datagram(servp->port)) < 0) {
        !            44:                printf("udp route daemon: no connection\n");
        !            45:                exit(1);
        !            46:        }
        !            47:        if ((ipfd = open(IPDEVICE, 2)) < 0) {
        !            48:                perror(IPDEVICE);
        !            49:                exit(1);
        !            50:        }
        !            51: 
        !            52:        readgateways();
        !            53:        timer();
        !            54: 
        !            55: again:
        !            56:        while((n = read(udpfd, &packet, sizeof(struct udppacket))) > 0) {
        !            57:                if(packet.addr.port == servp->port)
        !            58:                        routed(&packet, n - sizeof(struct udpaddr));
        !            59:                else
        !            60:                        fprintf(stderr, "routed: %s %s masquerading as routed\n",
        !            61:                                in_host(packet.addr.host), packet.addr.port);
        !            62:        }
        !            63:        if(n < 0 && errno == EINTR)
        !            64:                goto again;
        !            65: }
        !            66: 
        !            67: 
        !            68: /*     protocol.h      4.10    83/08/11        */
        !            69: /*
        !            70:  * Routing Information Protocol
        !            71:  *
        !            72:  * Derived from Xerox NS Routing Information Protocol
        !            73:  * by changing 32-bit net numbers to sockaddr's and
        !            74:  * padding stuff to 32-bit boundaries.
        !            75:  */
        !            76: #define        RIPVERSION      1
        !            77: #define AF_INET                2
        !            78: 
        !            79: struct sockaddr{
        !            80:        short sin_family;
        !            81:        u_short sin_port;
        !            82:        u_long sin_addr;
        !            83:        char sin_zero[8];
        !            84: };
        !            85: struct netinfo {
        !            86:        struct  sockaddr rip_dst;       /* destination net/host */
        !            87:        int     rip_metric;             /* cost of route */
        !            88: };
        !            89: 
        !            90: struct rip {
        !            91:        u_char  rip_cmd;                /* request/response */
        !            92:        u_char  rip_vers;               /* protocol version # */
        !            93:        u_char  rip_res1[2];            /* pad to 32-bit boundary */
        !            94:        union {
        !            95:                struct  netinfo ru_nets[1];     /* variable length... */
        !            96:                char    ru_tracefile[1];        /* ditto ... */
        !            97:        } ripun;
        !            98: #define        rip_nets        ripun.ru_nets
        !            99: #define        rip_tracefile   ripun.ru_tracefile
        !           100: };
        !           101:  
        !           102: /*
        !           103:  * Packet types.
        !           104:  */
        !           105: #define        RIPCMD_REQUEST          1       /* want info */
        !           106: #define        RIPCMD_RESPONSE         2       /* responding to request */
        !           107: #define        RIPCMD_TRACEON          3       /* turn tracing on */
        !           108: #define        RIPCMD_TRACEOFF         4       /* turn it off */
        !           109: 
        !           110: #define        RIPCMD_MAX              5
        !           111: #ifdef RIPCMDS
        !           112: char *ripcmds[RIPCMD_MAX] =
        !           113:   { "#0", "REQUEST", "RESPONSE", "TRACEON", "TRACEOFF" };
        !           114: #endif
        !           115: 
        !           116: #define        HOPCNT_INFINITY         16      /* per Xerox NS */
        !           117: #define        MAXPACKETSIZE           512     /* max broadcast size */
        !           118: 
        !           119: /*
        !           120:  * Timer values used in managing the routing table.
        !           121:  * Every update forces an entry's timer to be reset.  After
        !           122:  * EXPIRE_TIME without updates, the entry is marked invalid,
        !           123:  * but held onto until GARBAGE_TIME so that others may
        !           124:  * see it "be deleted".
        !           125:  */
        !           126: #define        TIMER_RATE              30      /* alarm clocks every 30 seconds */
        !           127: 
        !           128: #define        SUPPLY_INTERVAL         30      /* time to supply tables */
        !           129: 
        !           130: #define        EXPIRE_TIME             180     /* time to mark entry invalid */
        !           131: #define        GARBAGE_TIME            240     /* time to garbage collect */
        !           132: 
        !           133: u_long ifs[50];                /* interface network/address pairs */
        !           134: 
        !           135: routed(up, len)
        !           136:        struct udppacket *up;
        !           137:        u_int len;
        !           138: {
        !           139:        struct rip *rip;
        !           140:        struct sockaddr *sin;
        !           141:        struct netinfo *np;
        !           142: 
        !           143:        rip = (struct rip *)(up->buf);
        !           144:        if(rip->rip_cmd != RIPCMD_RESPONSE || rip->rip_vers != RIPVERSION)
        !           145:                return;
        !           146:        if(myaddr(up->addr.host))
        !           147:                return;
        !           148:        np = rip->rip_nets;
        !           149:        if(trace)
        !           150:                printf("%s\n", in_ntoa(up->addr.host));
        !           151:        while(np < (struct netinfo *)(&(up->buf[len]))){
        !           152:                sin = &(np->rip_dst);
        !           153:                np->rip_metric = ntohl(np->rip_metric);
        !           154:                sin->sin_port = ntohs(sin->sin_port);
        !           155:                sin->sin_addr = ntohl(sin->sin_addr);
        !           156:                if(trace) {
        !           157:                        printf(" %s %d\n", in_ntoa(sin->sin_addr), np->rip_metric);
        !           158:                        fflush(stdout);
        !           159:                }
        !           160:                rtinstall(sin->sin_addr, up->addr.host, np->rip_metric, 0);
        !           161:                np++;
        !           162:        }
        !           163: }
        !           164: 
        !           165: struct route{
        !           166:        u_long dst;
        !           167:        u_long gate;
        !           168:        int metric;
        !           169:        int age;
        !           170: };
        !           171: #define NROUTES 50
        !           172: struct route routes[NROUTES];
        !           173: 
        !           174: rtinstall(dst, gate, metric, age)
        !           175: u_long dst, gate;
        !           176: {
        !           177:        struct route *rp, *save = 0;
        !           178: 
        !           179:        if(metric >= HOPCNT_INFINITY)
        !           180:                return;
        !           181:        for(rp = routes; rp < &routes[NROUTES]; rp++){
        !           182:                if(rp->dst == dst)
        !           183:                        break;
        !           184:                if(rp->dst == 0 && save == 0)
        !           185:                        save = rp;
        !           186:        }
        !           187:        if(rp >= &routes[NROUTES] && (rp = save) == 0){
        !           188:                printf("routed: out of routes?\n");
        !           189:                return;
        !           190:        }
        !           191:        if(rp->dst == 0)
        !           192:                rp->metric = HOPCNT_INFINITY + 1;
        !           193:        if(gate != rp->gate && rp->age > 1){
        !           194:                /* let it age some more to avoid loops */
        !           195:                return;
        !           196:        }
        !           197:        if(metric < rp->metric
        !           198:           || (gate == rp->gate && metric != rp->metric)
        !           199:           || (gate == rp->gate && age != rp->age)){
        !           200:                rp->metric = metric;
        !           201:                rp->age = age;
        !           202:                if(dst != gate
        !           203:                   && (rp->dst != dst || rp->gate != gate)){
        !           204:                        if(verbose){
        !           205:                                printf("%s ", in_host(gate));
        !           206:                                printf("installing as route to %s, metric %d\n",
        !           207:                                        in_host(dst), metric);
        !           208:                                fflush(stdout);
        !           209:                        }
        !           210:                        rp->dst = dst;
        !           211:                        rp->gate = gate;
        !           212:                        if(ioctl(ipfd, IPIOROUTE, rp) < 0)
        !           213:                                perror("IPIOROUTE");
        !           214:                } else {
        !           215:                        if(verbose > 1){
        !           216:                                printf("%s ", in_host(gate));
        !           217:                                printf("confirmed as route to %s, metric %d\n",
        !           218:                                        in_host(dst), metric);
        !           219:                                fflush(stdout);
        !           220:                        }
        !           221:                        rp->dst = dst;
        !           222:                        rp->gate = gate;
        !           223:                }
        !           224:        }
        !           225: }
        !           226: 
        !           227: readgateways()
        !           228: {
        !           229:        FILE *fp;
        !           230:        char buf[512];
        !           231:        char net[32], gateway[32], which[32];
        !           232:        u_long dst, gate;
        !           233:        int metric;
        !           234: 
        !           235:        if((fp = fopen(GATEWAYS, "r")) == 0)
        !           236:                return;
        !           237:        while(fgets(buf, sizeof(buf), fp)){
        !           238:                if(sscanf(buf, "%s %s gateway %s metric %d",
        !           239:                          which, net, gateway, &metric) != 4)
        !           240:                        continue;
        !           241:                dst = in_address(net);
        !           242:                gate = in_address(gateway);
        !           243:                rtinstall(dst, gate, metric, -1);
        !           244:        }
        !           245: }
        !           246: 
        !           247: 
        !           248: timer()
        !           249: {
        !           250:        int i;
        !           251:        struct route *rp;
        !           252: 
        !           253:        signal(SIGALRM, SIG_IGN);
        !           254:        alarm(0);
        !           255: 
        !           256: 
        !           257:        ifs[0] = 0;
        !           258:        if(ioctl(ipfd, IPIOGETIFS, ifs) < 0){
        !           259:                perror("IPIOGETIFS");
        !           260:                exit(1);
        !           261:        }
        !           262:        for(i = 0; ifs[i]; i+= 2)
        !           263:                if(ifs[i] != ifs[i+1] && ifs[i] != 0x7f000000)
        !           264:                        rtinstall(ifs[i], ifs[i], 0, 0);
        !           265: 
        !           266:        for(rp = routes; rp < &routes[NROUTES]; rp++){
        !           267:                if(rp->dst == 0)
        !           268:                        continue;
        !           269:                if(rp->age > 0 && rp->metric < HOPCNT_INFINITY)
        !           270:                        rp->metric = HOPCNT_INFINITY - 1;
        !           271:        }
        !           272: 
        !           273:        broadcast();
        !           274: 
        !           275:        for(rp = routes; rp < &routes[NROUTES]; rp++){
        !           276:                if(rp->dst == 0)
        !           277:                        continue;
        !           278:                if(rp->age > 10){
        !           279:                        rtdelete(rp);
        !           280:                } else if(rp->age >= 0){
        !           281:                        rp->age++;
        !           282:                }
        !           283:        }
        !           284: 
        !           285:        fflush(stdout);
        !           286:        alarm(60);
        !           287:        signal(SIGALRM, timer);
        !           288: }
        !           289: 
        !           290: broadcast()
        !           291: {
        !           292:        int i;
        !           293:        struct route *rp;
        !           294:        u_char buf[2000];
        !           295:        struct rip *rip;
        !           296:        struct netinfo *np;
        !           297:        struct sockaddr *sin;
        !           298: 
        !           299:        rip = (struct rip *)buf;
        !           300:        rip->rip_cmd = RIPCMD_RESPONSE;
        !           301:        rip->rip_vers = RIPVERSION;
        !           302:        np = rip->rip_nets;
        !           303:        if(trace)
        !           304:                printf("BROADCAST:\n");
        !           305:        for(rp = routes; rp < &routes[NROUTES]; rp++){
        !           306:                if(rp->dst == 0 || rp->metric >= HOPCNT_INFINITY)
        !           307:                        continue;
        !           308:                bzero(np, sizeof(struct netinfo));
        !           309:                sin = &(np->rip_dst);
        !           310:                np->rip_metric = htonl(rp->metric + 1);
        !           311:                sin->sin_port = 0;
        !           312:                sin->sin_addr = htonl(rp->dst);
        !           313:                sin->sin_family = htons((u_short)AF_INET);
        !           314:                if(trace)
        !           315:                        printf(" %s %d\n",
        !           316:                                in_ntoa(ntohl(sin->sin_addr)), ntohl(np->rip_metric));
        !           317:                np++;
        !           318:        }
        !           319:        if(quiet)
        !           320:                return;
        !           321:        for(i = 0; ifs[i]; i += 2){
        !           322:                if (trace) {
        !           323:                        printf("on ifs[%d]\n", i);
        !           324:                        fflush(stdout);
        !           325:                }
        !           326:                if(ifs[i] != ifs[i+1] && ifs[i] != 0x7f000000)
        !           327:                        udp_output(rip, (u_char *)np - (u_char *)rip,
        !           328:                                   ifs[i+1], 520, ifs[i], 520);
        !           329:        }
        !           330: }
        !           331: 
        !           332: udp_output(buf, len, src, sport, dst, dport)
        !           333: u_char *buf;
        !           334: u_long src, dst;
        !           335: {
        !           336:        struct udppacket packet;
        !           337: 
        !           338:        if (dst == 0)
        !           339:                return;
        !           340:        bcopy(buf, packet.buf, len);
        !           341:        packet.addr.host = dst;
        !           342:        packet.addr.port = dport;
        !           343:        if (write(udpfd, &packet, sizeof(struct udpaddr) + len) < 0)
        !           344:                perror("udp write");
        !           345: }
        !           346: 
        !           347: myaddr(x)
        !           348: u_long x;
        !           349: {
        !           350:        int i;
        !           351: 
        !           352:        for(i = 0; ifs[i]; i += 2)
        !           353:                if(ifs[i+1] == x)
        !           354:                        return(1);
        !           355:        return(0);
        !           356: }
        !           357: 
        !           358: rtdelete(rp)
        !           359: struct route *rp;
        !           360: {
        !           361:        if(verbose) {
        !           362:                printf("deleting %s %d\n", in_ntoa(rp->dst), rp->metric);
        !           363:                fflush(stdout);
        !           364:        }
        !           365:        if(rp->gate != rp->dst){
        !           366:                rp->gate = 0;
        !           367:                if(ioctl(ipfd, IPIOROUTE, rp) < 0)
        !           368:                        perror("IPIOROUTE");
        !           369:        }
        !           370:        rp->gate = rp->dst = 0;
        !           371:        rp->age = rp->metric = 0;
        !           372: }

unix.superglobalmegacorp.com

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