Annotation of 42BSD/etc/routed/startup.c, revision 1.1

1.1     ! root        1: #ifndef lint
        !             2: static char sccsid[] = "@(#)startup.c  4.4 (Berkeley) 5/25/83";
        !             3: #endif
        !             4: 
        !             5: /*
        !             6:  * Routing Table Management Daemon
        !             7:  */
        !             8: #include "defs.h"
        !             9: #include <net/if.h>
        !            10: #include <nlist.h>
        !            11: 
        !            12: struct interface *ifnet;
        !            13: int    kmem = -1;
        !            14: int    lookforinterfaces = 1;
        !            15: int    performnlist = 1;
        !            16: int    externalinterfaces = 0;         /* # of remote and local interfaces */
        !            17: 
        !            18: struct nlist nl[] = {
        !            19: #define        N_IFNET         0
        !            20:        { "_ifnet" },
        !            21:        { "" },
        !            22: };
        !            23: 
        !            24: /*
        !            25:  * Probe the kernel through /dev/kmem to find the network
        !            26:  * interfaces which have configured themselves.  If the
        !            27:  * interface is present but not yet up (for example an
        !            28:  * ARPANET IMP), set the lookforinterfaces flag so we'll
        !            29:  * come back later and look again.
        !            30:  */
        !            31: ifinit()
        !            32: {
        !            33:        struct interface *ifp;
        !            34:        struct ifnet ifs, *next;
        !            35:        char name[32], *cp, *index();
        !            36: 
        !            37:        if (performnlist) {
        !            38:                nlist("/vmunix", nl);
        !            39:                if (nl[N_IFNET].n_value == 0) {
        !            40:                        printf("ifnet: not in namelist\n");
        !            41:                        goto bad;
        !            42:                }
        !            43:                performnlist = 0;
        !            44:        }
        !            45:        if (kmem < 0) {
        !            46:                kmem = open("/dev/kmem", 0);
        !            47:                if (kmem < 0) {
        !            48:                        perror("/dev/kmem");
        !            49:                        goto bad;
        !            50:                }
        !            51:        }
        !            52:        if (lseek(kmem, (long)nl[N_IFNET].n_value, 0) == -1 ||
        !            53:            read(kmem, (char *)&next, sizeof (next)) != sizeof (next)) {
        !            54:                printf("ifnet: error reading kmem\n");
        !            55:                goto bad;
        !            56:        }
        !            57:        lookforinterfaces = 0;
        !            58:        while (next) {
        !            59:                if (lseek(kmem, (long)next, 0) == -1 ||
        !            60:                    read(kmem, (char *)&ifs, sizeof (ifs)) != sizeof (ifs)) {
        !            61:                        perror("read");
        !            62:                        goto bad;
        !            63:                }
        !            64:                next = ifs.if_next;
        !            65:                if ((ifs.if_flags & IFF_UP) == 0) {
        !            66:                        lookforinterfaces = 1;
        !            67:                        continue;
        !            68:                }
        !            69:                /* already known to us? */
        !            70:                if (if_ifwithaddr(&ifs.if_addr))
        !            71:                        continue;
        !            72:                /* argh, this'll have to change sometime */
        !            73:                if (ifs.if_addr.sa_family != AF_INET)
        !            74:                        continue;
        !            75:                /* no one cares about software loopback interfaces */
        !            76:                if (ifs.if_net == LOOPBACKNET)
        !            77:                        continue;
        !            78:                ifp = (struct interface *)malloc(sizeof (struct interface));
        !            79:                if (ifp == 0) {
        !            80:                        printf("routed: out of memory\n");
        !            81:                        break;
        !            82:                }
        !            83:                /*
        !            84:                 * Count the # of directly connected networks
        !            85:                 * and point to point links which aren't looped
        !            86:                 * back to ourself.  This is used below to
        !            87:                 * decide if we should be a routing ``supplier''.
        !            88:                 */
        !            89:                if ((ifs.if_flags & IFF_POINTOPOINT) == 0 ||
        !            90:                    if_ifwithaddr(&ifs.if_dstaddr) == 0)
        !            91:                        externalinterfaces++;
        !            92:                lseek(kmem, ifs.if_name, 0);
        !            93:                read(kmem, name, sizeof (name));
        !            94:                name[sizeof (name) - 1] = '\0';
        !            95:                cp = index(name, '\0');
        !            96:                *cp++ = ifs.if_unit + '0';
        !            97:                *cp = '\0';
        !            98:                ifp->int_name = malloc(strlen(name) + 1);
        !            99:                if (ifp->int_name == 0) {
        !           100:                        fprintf(stderr, "routed: ifinit: out of memory\n");
        !           101:                        goto bad;               /* ??? */
        !           102:                }
        !           103:                strcpy(ifp->int_name, name);
        !           104:                ifp->int_addr = ifs.if_addr;
        !           105:                ifp->int_flags = ifs.if_flags | IFF_INTERFACE;
        !           106:                /* this works because broadaddr overlaps dstaddr */
        !           107:                ifp->int_broadaddr = ifs.if_broadaddr;
        !           108:                ifp->int_net = ifs.if_net;
        !           109:                ifp->int_metric = 0;
        !           110:                ifp->int_next = ifnet;
        !           111:                ifnet = ifp;
        !           112:                traceinit(ifp);
        !           113:                addrouteforif(ifp);
        !           114:        }
        !           115:        if (externalinterfaces > 1 && supplier < 0)
        !           116:                supplier = 1;
        !           117:        return;
        !           118: bad:
        !           119:        sleep(60);
        !           120:        close(kmem), close(s);
        !           121:        execv("/etc/routed", argv0);
        !           122:        _exit(0177);
        !           123: }
        !           124: 
        !           125: addrouteforif(ifp)
        !           126:        struct interface *ifp;
        !           127: {
        !           128:        struct sockaddr_in net;
        !           129:        struct sockaddr *dst;
        !           130:        int state, metric;
        !           131:        struct rt_entry *rt;
        !           132: 
        !           133:        if (ifp->int_flags & IFF_POINTOPOINT)
        !           134:                dst = &ifp->int_dstaddr;
        !           135:        else {
        !           136:                bzero((char *)&net, sizeof (net));
        !           137:                net.sin_family = AF_INET;
        !           138:                net.sin_addr = inet_makeaddr(ifp->int_net, INADDR_ANY);
        !           139:                dst = (struct sockaddr *)&net;
        !           140:        }
        !           141:        rt = rtlookup(dst);
        !           142:        rtadd(dst, &ifp->int_addr, ifp->int_metric,
        !           143:                ifp->int_flags & (IFF_INTERFACE|IFF_PASSIVE|IFF_REMOTE));
        !           144:        if (rt)
        !           145:                rtdelete(rt);
        !           146: }
        !           147: 
        !           148: /*
        !           149:  * As a concession to the ARPANET we read a list of gateways
        !           150:  * from /etc/gateways and add them to our tables.  This file
        !           151:  * exists at each ARPANET gateway and indicates a set of ``remote''
        !           152:  * gateways (i.e. a gateway which we can't immediately determine
        !           153:  * if it's present or not as we can do for those directly connected
        !           154:  * at the hardware level).  If a gateway is marked ``passive''
        !           155:  * in the file, then we assume it doesn't have a routing process
        !           156:  * of our design and simply assume it's always present.  Those
        !           157:  * not marked passive are treated as if they were directly
        !           158:  * connected -- they're added into the interface list so we'll
        !           159:  * send them routing updates.
        !           160:  */
        !           161: gwkludge()
        !           162: {
        !           163:        struct sockaddr_in dst, gate;
        !           164:        FILE *fp;
        !           165:        char *type, *dname, *gname, *qual, buf[BUFSIZ];
        !           166:        struct interface *ifp;
        !           167:        int metric;
        !           168: 
        !           169:        fp = fopen("/etc/gateways", "r");
        !           170:        if (fp == NULL)
        !           171:                return;
        !           172:        qual = buf;
        !           173:        dname = buf + 64;
        !           174:        gname = buf + ((BUFSIZ - 64) / 3);
        !           175:        type = buf + (((BUFSIZ - 64) * 2) / 3);
        !           176:        bzero((char *)&dst, sizeof (dst));
        !           177:        bzero((char *)&gate, sizeof (gate));
        !           178:        /* format: {net | host} XX gateway XX metric DD [passive]\n */
        !           179: #define        readentry(fp) \
        !           180:        fscanf((fp), "%s %s gateway %s metric %d %s\n", \
        !           181:                type, dname, gname, &metric, qual)
        !           182:        for (;;) {
        !           183:                if (readentry(fp) == EOF)
        !           184:                        break;
        !           185:                if (!getnetorhostname(type, dname, &dst))
        !           186:                        continue;
        !           187:                if (!gethostnameornumber(gname, &gate))
        !           188:                        continue;
        !           189:                ifp = (struct interface *)malloc(sizeof (*ifp));
        !           190:                bzero((char *)ifp, sizeof (*ifp));
        !           191:                ifp->int_flags = IFF_REMOTE;
        !           192:                /* can't identify broadcast capability */
        !           193:                ifp->int_net = inet_netof(dst.sin_addr);
        !           194:                if (strcmp(type, "host") == 0) {
        !           195:                        ifp->int_flags |= IFF_POINTOPOINT;
        !           196:                        ifp->int_dstaddr = *((struct sockaddr *)&dst);
        !           197:                }
        !           198:                if (strcmp(qual, "passive") == 0)
        !           199:                        ifp->int_flags |= IFF_PASSIVE;
        !           200:                else
        !           201:                        /* assume no duplicate entries */
        !           202:                        externalinterfaces++;
        !           203:                ifp->int_addr = *((struct sockaddr *)&gate);
        !           204:                ifp->int_metric = metric;
        !           205:                ifp->int_next = ifnet;
        !           206:                ifnet = ifp;
        !           207:                addrouteforif(ifp);
        !           208:        }
        !           209:        fclose(fp);
        !           210: }
        !           211: 
        !           212: getnetorhostname(type, name, sin)
        !           213:        char *type, *name;
        !           214:        struct sockaddr_in *sin;
        !           215: {
        !           216: 
        !           217:        if (strcmp(type, "net") == 0) {
        !           218:                struct netent *np = getnetbyname(name);
        !           219:                int n;
        !           220: 
        !           221:                if (np == 0)
        !           222:                        n = inet_network(name);
        !           223:                else {
        !           224:                        if (np->n_addrtype != AF_INET)
        !           225:                                return (0);
        !           226:                        n = np->n_net;
        !           227:                }
        !           228:                sin->sin_family = AF_INET;
        !           229:                sin->sin_addr = inet_makeaddr(n, INADDR_ANY);
        !           230:                return (1);
        !           231:        }
        !           232:        if (strcmp(type, "host") == 0) {
        !           233:                struct hostent *hp = gethostbyname(name);
        !           234: 
        !           235:                if (hp == 0)
        !           236:                        sin->sin_addr.s_addr = inet_addr(name);
        !           237:                else {
        !           238:                        if (hp->h_addrtype != AF_INET)
        !           239:                                return (0);
        !           240:                        bcopy(hp->h_addr, &sin->sin_addr, hp->h_length);
        !           241:                }
        !           242:                sin->sin_family = AF_INET;
        !           243:                return (1);
        !           244:        }
        !           245:        return (0);
        !           246: }
        !           247: 
        !           248: gethostnameornumber(name, sin)
        !           249:        char *name;
        !           250:        struct sockaddr_in *sin;
        !           251: {
        !           252:        struct hostent *hp;
        !           253: 
        !           254:        hp = gethostbyname(name);
        !           255:        if (hp) {
        !           256:                bcopy(hp->h_addr, &sin->sin_addr, hp->h_length);
        !           257:                sin->sin_family = hp->h_addrtype;
        !           258:                return (1);
        !           259:        }
        !           260:        sin->sin_addr.s_addr = inet_addr(name);
        !           261:        sin->sin_family = AF_INET;
        !           262:        return (sin->sin_addr.s_addr != -1);
        !           263: }

unix.superglobalmegacorp.com

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