Annotation of researchv8dc/cmd/inet/etc/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/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.