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

unix.superglobalmegacorp.com

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