Annotation of researchv9/ipc/src/internet/routed.c, revision 1.1.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.