Annotation of researchv9/ipc/src/internet/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/in.h>
        !             8: #include <sys/inet/ip_var.h>
        !             9: #include <sys/inet/udp_user.h>
        !            10: #include "config.h"
        !            11: 
        !            12: #define IPDEVICE "/dev/ip16"   /* device for getting ip info from */
        !            13: #define RPORT 520
        !            14: 
        !            15: int udpfd, ipfd, verbose, trace, quiet;
        !            16: extern errno;
        !            17: extern char *in_ntoa();
        !            18: extern u_short cksum();
        !            19: 
        !            20: struct udppacket {
        !            21:        struct udpaddr addr;
        !            22:        char buf[4096];
        !            23: };
        !            24: 
        !            25: main(argc, argv)
        !            26: char *argv[];
        !            27: {
        !            28:        int n, i;
        !            29:        struct udppacket packet;
        !            30: 
        !            31:        for(i = 1; i < argc; i++){
        !            32:                if(strcmp(argv[i], "-v") == 0)
        !            33:                        verbose++;
        !            34:                else if(strcmp(argv[i], "-q") == 0)
        !            35:                        quiet++;
        !            36:                else if(strcmp(argv[i], "-t") == 0)
        !            37:                        trace++;
        !            38:                else
        !            39:                        recsafe(argv[i]);
        !            40:        }
        !            41: 
        !            42:        if ((udpfd = udp_datagram(RPORT)) < 0) {
        !            43:                printf("udp route daemon: no connection\n");
        !            44:                exit(1);
        !            45:        }
        !            46:        if ((ipfd = open(IPDEVICE, 2)) < 0) {
        !            47:                perror(IPDEVICE);
        !            48:                exit(1);
        !            49:        }
        !            50: 
        !            51:        readgateways();
        !            52:        timer();
        !            53: 
        !            54: again:
        !            55:        while((n = read(udpfd, &packet, sizeof(struct udppacket))) > 0) {
        !            56:                if(packet.addr.port == RPORT)
        !            57:                        routed(&packet, n - sizeof(struct udpaddr));
        !            58:                else
        !            59:                        fprintf(stderr, "routed: %s %s masquerading as routed\n",
        !            60:                                in_host(packet.addr.host), packet.addr.port);
        !            61:        }
        !            62:        if(n < 0 && errno == EINTR)
        !            63:                goto again;
        !            64: }
        !            65: 
        !            66: 
        !            67: /*     protocol.h      4.10    83/08/11        */
        !            68: /*
        !            69:  * Routing Information Protocol
        !            70:  *
        !            71:  * Derived from Xerox NS Routing Information Protocol
        !            72:  * by changing 32-bit net numbers to sockaddr's and
        !            73:  * padding stuff to 32-bit boundaries.
        !            74:  */
        !            75: #define        RIPVERSION      1
        !            76: #define AF_INET                2
        !            77: 
        !            78: struct sockaddr{
        !            79:        short sin_family;
        !            80:        u_short sin_port;
        !            81:        u_long sin_addr;
        !            82:        char sin_zero[8];
        !            83: };
        !            84: struct netinfo {
        !            85:        struct  sockaddr rip_dst;       /* destination net/host */
        !            86:        int     rip_metric;             /* cost of route */
        !            87: };
        !            88: 
        !            89: struct rip {
        !            90:        u_char  rip_cmd;                /* request/response */
        !            91:        u_char  rip_vers;               /* protocol version # */
        !            92:        u_char  rip_res1[2];            /* pad to 32-bit boundary */
        !            93:        union {
        !            94:                struct  netinfo ru_nets[1];     /* variable length... */
        !            95:                char    ru_tracefile[1];        /* ditto ... */
        !            96:        } ripun;
        !            97: #define        rip_nets        ripun.ru_nets
        !            98: #define        rip_tracefile   ripun.ru_tracefile
        !            99: };
        !           100:  
        !           101: /*
        !           102:  * Packet types.
        !           103:  */
        !           104: #define        RIPCMD_REQUEST          1       /* want info */
        !           105: #define        RIPCMD_RESPONSE         2       /* responding to request */
        !           106: #define        RIPCMD_TRACEON          3       /* turn tracing on */
        !           107: #define        RIPCMD_TRACEOFF         4       /* turn it off */
        !           108: 
        !           109: #define        RIPCMD_MAX              5
        !           110: #ifdef RIPCMDS
        !           111: char *ripcmds[RIPCMD_MAX] =
        !           112:   { "#0", "REQUEST", "RESPONSE", "TRACEON", "TRACEOFF" };
        !           113: #endif
        !           114: 
        !           115: #define        HOPCNT_INFINITY         16      /* per Xerox NS */
        !           116: #define        MAXPACKETSIZE           512     /* max broadcast size */
        !           117: #define MAXROUTESPERPACKET     (MAXPACKETSIZE-4)/sizeof(struct netinfo)
        !           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: #define NIFS 20
        !           134: u_long ifs[2*NIFS];            /* interface network/address pairs */
        !           135: 
        !           136: routed(up, len)
        !           137:        struct udppacket *up;
        !           138:        u_int len;
        !           139: {
        !           140:        struct rip *rip;
        !           141:        struct sockaddr *sin;
        !           142:        struct netinfo *np;
        !           143: 
        !           144:        rip = (struct rip *)(up->buf);
        !           145:        if(rip->rip_cmd != RIPCMD_RESPONSE || rip->rip_vers != RIPVERSION)
        !           146:                return;
        !           147:        if(myaddr(up->addr.host))
        !           148:                return;
        !           149:        np = rip->rip_nets;
        !           150:        if(trace)
        !           151:                printf("%s\n", in_ntoa(up->addr.host));
        !           152:        while(np < (struct netinfo *)(&(up->buf[len]))){
        !           153:                sin = &(np->rip_dst);
        !           154:                np->rip_metric = ntohl(np->rip_metric);
        !           155:                sin->sin_port = ntohs(sin->sin_port);
        !           156:                sin->sin_addr = ntohl(sin->sin_addr);
        !           157:                if(trace) {
        !           158:                        printf(" %s %d\n", in_ntoa(sin->sin_addr), np->rip_metric);
        !           159:                        fflush(stdout);
        !           160:                }
        !           161:                if (np->rip_metric > 0 && saferoute(sin->sin_addr) == 0)
        !           162:                        rtinstall(sin->sin_addr, up->addr.host, np->rip_metric, 0);
        !           163:                np++;
        !           164:        }
        !           165: }
        !           166: 
        !           167: struct route{
        !           168:        u_long dst;
        !           169:        u_long gate;
        !           170:        int metric;
        !           171:        int age;
        !           172: };
        !           173: #define NROUTES 150
        !           174: struct route routes[NROUTES];
        !           175: 
        !           176: rtinstall(dst, gate, metric, age)
        !           177: u_long dst, gate;
        !           178: {
        !           179:        struct route *rp, *save = 0;
        !           180: 
        !           181:        if(metric >= HOPCNT_INFINITY)
        !           182:                return;
        !           183:        for(rp = routes; rp < &routes[NROUTES]; rp++){
        !           184:                if(rp->dst == dst)
        !           185:                        break;
        !           186:                if(rp->dst == 0 && save == 0)
        !           187:                        save = rp;
        !           188:        }
        !           189:        if(rp >= &routes[NROUTES] && (rp = save) == 0){
        !           190:                printf("routed: out of routes?\n");
        !           191:                return;
        !           192:        }
        !           193:        if(rp->dst == 0)
        !           194:                rp->metric = HOPCNT_INFINITY + 1;
        !           195:        if(gate != rp->gate && rp->age > 1){
        !           196:                /* let it age some more to avoid loops */
        !           197:                return;
        !           198:        }
        !           199:        if(metric < rp->metric
        !           200:           || (gate == rp->gate && metric != rp->metric)
        !           201:           || (gate == rp->gate && age != rp->age)){
        !           202:                rp->metric = metric;
        !           203:                rp->age = age;
        !           204:                if(rp->dst != dst || rp->gate != gate){
        !           205:                        if(verbose){
        !           206:                                printf("%s ", in_host(gate));
        !           207:                                printf("installing as route to %s, metric %d\n",
        !           208:                                        in_host(dst), metric);
        !           209:                                fflush(stdout);
        !           210:                        }
        !           211:                        rp->dst = dst;
        !           212:                        rp->gate = gate;
        !           213:                        if(ioctl(ipfd, IPIOROUTE, rp) < 0)
        !           214:                                perror("IPIOROUTE");
        !           215:                } else {
        !           216:                        if(verbose > 1){
        !           217:                                printf("%s ", in_host(gate));
        !           218:                                printf("confirmed as route to %s, metric %d\n",
        !           219:                                        in_host(dst), metric);
        !           220:                                fflush(stdout);
        !           221:                        }
        !           222:                        rp->dst = dst;
        !           223:                        rp->gate = gate;
        !           224:                }
        !           225:        }
        !           226: }
        !           227: 
        !           228: /*
        !           229:  * keep a list of routes
        !           230:  * that belong to us;
        !           231:  * don't let anyone claim them
        !           232:  */
        !           233: 
        !           234: #define        NSAFE   20
        !           235: 
        !           236: u_long safer[NSAFE];
        !           237: int nsafe = 0;
        !           238: 
        !           239: recsafe(s)
        !           240: char *s;
        !           241: {
        !           242:        if (nsafe < NSAFE)
        !           243:                safer[nsafe++] = in_address(s);
        !           244: }
        !           245: 
        !           246: saferoute(dst)
        !           247: u_long dst;
        !           248: {
        !           249:        register int i;
        !           250: 
        !           251:        for (i = 0; i < nsafe; i++)
        !           252:                if (dst == safer[i])
        !           253:                        return (1);
        !           254:        return (0);
        !           255: }
        !           256: 
        !           257: readgateways()
        !           258: {
        !           259:        FILE *fp;
        !           260:        char buf[512];
        !           261:        char net[32], gateway[32], which[32];
        !           262:        u_long dst, gate;
        !           263:        int metric;
        !           264: 
        !           265:        if((fp = fopen(GATEWAYS, "r")) == 0)
        !           266:                return;
        !           267:        while(fgets(buf, sizeof(buf), fp)){
        !           268:                if(sscanf(buf, "%s %s gateway %s metric %d",
        !           269:                          which, net, gateway, &metric) != 4)
        !           270:                        continue;
        !           271:                dst = in_address(net);
        !           272:                gate = in_address(gateway);
        !           273:                rtinstall(dst, gate, metric, -1);
        !           274:        }
        !           275: }
        !           276: 
        !           277: 
        !           278: timer()
        !           279: {
        !           280:        int i,j;
        !           281:        struct route *rp;
        !           282:        struct ipif ipif;
        !           283: 
        !           284:        signal(SIGALRM, SIG_IGN);
        !           285:        alarm(0);
        !           286: 
        !           287:        for(j=i=0; j<2*NIFS; i++){
        !           288:                *(int *)&ipif = i;
        !           289:                if(ioctl(ipfd, IPIOGETIFS, &ipif) < 0)
        !           290:                        break;
        !           291:                if(ipif.flags&IFF_UP) {
        !           292:                        ifs[j++] = ipif.that;
        !           293:                        ifs[j++] = ipif.thishost;
        !           294:                }
        !           295:        }
        !           296:        ifs[j]=0;
        !           297:        for(i = 0; ifs[i]; i+= 2)
        !           298:                if(ifs[i] != ifs[i+1] && ifs[i] != 0x7f000000)
        !           299:                        rtinstall(in_netof(ifs[i]), in_netof(ifs[i]), 0, 0);
        !           300: 
        !           301:        for(rp = routes; rp < &routes[NROUTES]; rp++){
        !           302:                if(rp->dst == 0)
        !           303:                        continue;
        !           304:                if(rp->age > 0 && rp->metric < HOPCNT_INFINITY)
        !           305:                        rp->metric = HOPCNT_INFINITY - 1;
        !           306:        }
        !           307: 
        !           308:        broadcast();
        !           309: 
        !           310:        for(rp = routes; rp < &routes[NROUTES]; rp++){
        !           311:                if(rp->dst == 0)
        !           312:                        continue;
        !           313:                if(rp->age > 10){
        !           314:                        rtdelete(rp);
        !           315:                } else if(rp->age >= 0){
        !           316:                        rp->age++;
        !           317:                }
        !           318:        }
        !           319: 
        !           320:        fflush(stdout);
        !           321:        alarm(60);
        !           322:        signal(SIGALRM, timer);
        !           323: }
        !           324: 
        !           325: broadcast()
        !           326: {
        !           327:        struct route *rp;
        !           328:        struct rip *rip;
        !           329:        struct netinfo *np;
        !           330:        struct sockaddr *sin;
        !           331:        struct udppacket p;
        !           332: 
        !           333:        rip = (struct rip *)p.buf;
        !           334:        rip->rip_cmd = RIPCMD_RESPONSE;
        !           335:        rip->rip_vers = RIPVERSION;
        !           336:        np = rip->rip_nets;
        !           337:        if(trace)
        !           338:                printf("BROADCAST:\n");
        !           339: 
        !           340:        /* first send info about directly connected networks */
        !           341:        for(rp = routes; rp < &routes[NROUTES]; rp++){
        !           342:                if(rp->dst == 0 || rp->metric > 0)
        !           343:                        continue;
        !           344:                bzero(np, sizeof(struct netinfo));
        !           345:                sin = &(np->rip_dst);
        !           346:                np->rip_metric = htonl(rp->metric + 1);
        !           347:                sin->sin_port = 0;
        !           348:                sin->sin_addr = htonl(rp->dst);
        !           349:                sin->sin_family = htons((u_short)AF_INET);
        !           350:                if(trace)
        !           351:                        printf(" %s %d\n",
        !           352:                                in_ntoa(ntohl(sin->sin_addr)), ntohl(np->rip_metric));
        !           353:                np++;
        !           354:                if (np-rip->rip_nets == MAXROUTESPERPACKET) {
        !           355:                        pbroadcast(&p, (char *)np);
        !           356:                        np = rip->rip_nets;
        !           357:                }
        !           358:        }
        !           359: 
        !           360:        /* now send info about the rest */
        !           361:        for(rp = routes; rp < &routes[NROUTES]; rp++){
        !           362:                if(rp->dst==0 || rp->metric>=HOPCNT_INFINITY || rp->metric<=0) 
        !           363:                        continue;
        !           364:                bzero(np, sizeof(struct netinfo));
        !           365:                sin = &(np->rip_dst);
        !           366:                np->rip_metric = htonl(rp->metric + 1);
        !           367:                sin->sin_port = 0;
        !           368:                sin->sin_addr = htonl(rp->dst);
        !           369:                sin->sin_family = htons((u_short)AF_INET);
        !           370:                if(trace)
        !           371:                        printf(" %s %d\n",
        !           372:                                in_ntoa(ntohl(sin->sin_addr)), ntohl(np->rip_metric));
        !           373:                np++;
        !           374:                if (np-rip->rip_nets == MAXROUTESPERPACKET) {
        !           375:                        pbroadcast(&p, (char *)np);
        !           376:                        np = rip->rip_nets;
        !           377:                }
        !           378:        }
        !           379:        if (np > rip->rip_nets)
        !           380:                pbroadcast(&p, (char *)np);
        !           381: }
        !           382: 
        !           383: /* broadcast one routing packet everywhere */
        !           384: pbroadcast(pp, cp)
        !           385:        struct udppacket *pp;
        !           386:        char *cp;
        !           387: {
        !           388:        int len=sizeof(struct udpaddr)+cp-(char *)pp;
        !           389:        int i;
        !           390: 
        !           391:        if(quiet)
        !           392:                return;
        !           393:        pp->addr.port = 520;
        !           394:        for(i = 0; ifs[i]; i += 2){
        !           395:                if (trace) {
        !           396:                        printf("on ifs[%d]\n", i);
        !           397:                        fflush(stdout);
        !           398:                }
        !           399:                if(ifs[i]!=0 && ifs[i]!=ifs[i+1] && ifs[i]!=0x7f000000) {
        !           400:                        pp->addr.host = ifs[i];
        !           401:                        if (write(udpfd, pp, len) !=len)
        !           402:                                perror("udp write");
        !           403:                }
        !           404:        }
        !           405: }
        !           406: 
        !           407: myaddr(x)
        !           408: u_long x;
        !           409: {
        !           410:        int i;
        !           411: 
        !           412:        for(i = 0; ifs[i]; i += 2)
        !           413:                if(ifs[i+1] == x)
        !           414:                        return(1);
        !           415:        return(0);
        !           416: }
        !           417: 
        !           418: rtdelete(rp)
        !           419: struct route *rp;
        !           420: {
        !           421:        if(verbose) {
        !           422:                printf("deleting %s %d\n", in_ntoa(rp->dst), rp->metric);
        !           423:                fflush(stdout);
        !           424:        }
        !           425:        if(rp->gate != rp->dst){
        !           426:                rp->gate = 0;
        !           427:                if(ioctl(ipfd, IPIOROUTE, rp) < 0)
        !           428:                        perror("IPIOROUTE");
        !           429:        }
        !           430:        rp->gate = rp->dst = 0;
        !           431:        rp->age = rp->metric = 0;
        !           432: }

unix.superglobalmegacorp.com

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