# 2.11BSD#431 - /usr/src/sbin/routed/startup.c

##### Functions

    addrouteforif     X
    gethostnameornumberX
    getnetorhostname  X
    gwkludge          X
    ifinit            X

##### Variables

    externalinterfacesX
    ifnet             X
    lookforinterfaces X

##### Macros

    readentry         X

       1: /*
       2:  * Copyright (c) 1983 Regents of the University of California.
       3:  * All rights reserved.  The Berkeley software License Agreement
       4:  * specifies the terms and conditions for redistribution.
       5:  */
       6:
       7: #if !defined(lint) && defined(DOSCCS)
       8: static char sccsid[] = "@(#)startup.c	5.7.1 (2.11BSD) 1996/11/19";
       9: #endif not lint
      10:
      11: /*
      12:  * Routing Table Management Daemon
      13:  */
      14: #include "defs.h"
      15: #include <sys/ioctl.h>
      16: #include <net/if.h>
      17: #include <syslog.h>
      18:
      19: struct  interface *ifnet;
      20: int lookforinterfaces = 1;
      21: int externalinterfaces = 0;     /* # of remote and local interfaces */
      22:
      23: /*
      24:  * Find the network interfaces which have configured themselves.
      25:  * If the interface is present but not yet up (for example an
      26:  * ARPANET IMP), set the lookforinterfaces flag so we'll
      27:  * come back later and look again.
      28:  */
      29: ifinit()
      30: {
      31:     struct interface ifs, *ifp;
      32:     int s, n;
      33:     char buf[BUFSIZ];
      34:         struct ifconf ifc;
      35:         struct ifreq ifreq, *ifr;
      36:         struct sockaddr_in *sin;
      37:     u_long i;
      38:
      39:     if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
      40:         syslog(LOG_ERR, "socket: %m");
      41:         exit(1);
      42:     }
      43:         ifc.ifc_len = sizeof (buf);
      44:         ifc.ifc_buf = buf;
      45:         if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) {
      46:                 syslog(LOG_ERR, "ioctl (get interface configuration)");
      47:         close(s);
      48:                 return (0);
      49:         }
      50:         ifr = ifc.ifc_req;
      51:     lookforinterfaces = 0;
      52:         for (n = ifc.ifc_len / sizeof (struct ifreq); n > 0; n--, ifr++) {
      53:         bzero((char *)&ifs, sizeof(ifs));
      54:         ifs.int_addr = ifr->ifr_addr;
      55:         ifreq = *ifr;
      56:                 if (ioctl(s, SIOCGIFFLAGS, (char *)&ifreq) < 0) {
      57:                         syslog(LOG_ERR, "ioctl (get interface flags)");
      58:                         continue;
      59:                 }
      60:         ifs.int_flags = ifreq.ifr_flags | IFF_INTERFACE;
      61:         /* no one cares about software loopback interfaces */
      62:         if (ifs.int_flags & IFF_LOOPBACK)
      63:             continue;
      64:         if ((ifs.int_flags & IFF_UP) == 0 ||
      65:             ifr->ifr_addr.sa_family == AF_UNSPEC) {
      66:             lookforinterfaces = 1;
      67:             continue;
      68:         }
      69:         /* already known to us? */
      70:         if (if_ifwithaddr(&ifs.int_addr))
      71:             continue;
      72:         /* argh, this'll have to change sometime */
      73:         if (ifs.int_addr.sa_family != AF_INET)
      74:             continue;
      75:                 if (ifs.int_flags & IFF_POINTOPOINT) {
      76:                         if (ioctl(s, SIOCGIFDSTADDR, (char *)&ifreq) < 0) {
      77:                                 syslog(LOG_ERR, "ioctl (get dstaddr)");
      78:                                 continue;
      79:             }
      80:             ifs.int_dstaddr = ifreq.ifr_dstaddr;
      81:         }
      82:                 if (ifs.int_flags & IFF_BROADCAST) {
      83:                         if (ioctl(s, SIOCGIFBRDADDR, (char *)&ifreq) < 0) {
      84:                                 syslog(LOG_ERR, "ioctl (get broadaddr)");
      85:                                 continue;
      86:                         }
      87:             ifs.int_broadaddr = ifreq.ifr_broadaddr;
      88:         }
      89:         if (ioctl(s, SIOCGIFMETRIC, (char *)&ifreq) < 0)
      90:             syslog(LOG_ERR, "ioctl (get metric)");
      91:         else
      92:             ifs.int_metric = ifreq.ifr_metric;
      93:         if (ioctl(s, SIOCGIFNETMASK, (char *)&ifreq) < 0) {
      94:             syslog(LOG_ERR, "ioctl (get netmask)");
      95:             continue;
      96:         }
      97:         sin = (struct sockaddr_in *)&ifreq.ifr_addr;
      98:         ifs.int_subnetmask = ntohl(sin->sin_addr.s_addr);
      99:         sin = (struct sockaddr_in *)&ifs.int_addr;
     100:         i = ntohl(sin->sin_addr.s_addr);
     101:         if (IN_CLASSA(i))
     102:             ifs.int_netmask = IN_CLASSA_NET;
     103:         else if (IN_CLASSB(i))
     104:             ifs.int_netmask = IN_CLASSB_NET;
     105:         else
     106:             ifs.int_netmask = IN_CLASSC_NET;
     107:         ifs.int_net = i & ifs.int_netmask;
     108:         ifs.int_subnet = i & ifs.int_subnetmask;
     109:         if (ifs.int_subnetmask != ifs.int_netmask)
     110:             ifs.int_flags |= IFF_SUBNET;
     111:         ifp = (struct interface *)malloc(sizeof (struct interface));
     112:         if (ifp == 0) {
     113:             printf("routed: out of memory\n");
     114:             break;
     115:         }
     116:         *ifp = ifs;
     117:         /*
     118: 		 * Count the # of directly connected networks
     119: 		 * and point to point links which aren't looped
     120: 		 * back to ourself.  This is used below to
     121: 		 * decide if we should be a routing ``supplier''.
     122: 		 */
     123:         if ((ifs.int_flags & IFF_POINTOPOINT) == 0 ||
     124:             if_ifwithaddr(&ifs.int_dstaddr) == 0)
     125:             externalinterfaces++;
     126:         /*
     127: 		 * If we have a point-to-point link, we want to act
     128: 		 * as a supplier even if it's our only interface,
     129: 		 * as that's the only way our peer on the other end
     130: 		 * can tell that the link is up.
     131: 		 */
     132:         if ((ifs.int_flags & IFF_POINTOPOINT) && supplier < 0)
     133:             supplier = 1;
     134:         ifp->int_name = malloc(strlen(ifr->ifr_name) + 1);
     135:         if (ifp->int_name == 0) {
     136:             fprintf(stderr, "routed: ifinit: out of memory\n");
     137:             goto bad;       /* ??? */
     138:         }
     139:         strcpy(ifp->int_name, ifr->ifr_name);
     140:         ifp->int_next = ifnet;
     141:         ifnet = ifp;
     142:         traceinit(ifp);
     143:         addrouteforif(ifp);
     144:     }
     145:     if (externalinterfaces > 1 && supplier < 0)
     146:         supplier = 1;
     147:     close(s);
     148:     return;
     149: bad:
     150:     sleep(60);
     151:     close(kmem), close(s);
     152:     execv("/sbin/routed", argv0);
     153:     _exit(0177);
     154: }
     155:
     156: /*
     157:  * Add route for interface if not currently installed.
     158:  * Create route to other end if a point-to-point link,
     159:  * otherwise a route to this (sub)network.
     160:  * INTERNET SPECIFIC.
     161:  */
     162: addrouteforif(ifp)
     163:     struct interface *ifp;
     164: {
     165:     struct sockaddr_in net;
     166:     struct sockaddr *dst;
     167:     struct rt_entry *rt;
     168:
     169:     if (ifp->int_flags & IFF_POINTOPOINT)
     170:         dst = &ifp->int_dstaddr;
     171:     else {
     172:         bzero((char *)&net, sizeof (net));
     173:         net.sin_family = AF_INET;
     174:         net.sin_addr = inet_makeaddr(ifp->int_subnet, INADDR_ANY);
     175:         dst = (struct sockaddr *)&net;
     176:     }
     177:     rt = rtfind(dst);
     178:     if (rt &&
     179:         (rt->rt_state & (RTS_INTERFACE | RTS_INTERNAL)) == RTS_INTERFACE)
     180:         return;
     181:     if (rt)
     182:         rtdelete(rt);
     183:     /*
     184: 	 * If interface on subnetted network,
     185: 	 * install route to network as well.
     186: 	 * This is meant for external viewers.
     187: 	 */
     188:     if ((ifp->int_flags & (IFF_SUBNET|IFF_POINTOPOINT)) == IFF_SUBNET) {
     189:         net.sin_addr = inet_makeaddr(ifp->int_net, INADDR_ANY);
     190:         rt = rtfind(dst);
     191:         if (rt == 0)
     192:             rtadd(dst, &ifp->int_addr, ifp->int_metric,
     193:                 ((ifp->int_flags & (IFF_INTERFACE|IFF_REMOTE)) |
     194:                 RTS_PASSIVE | RTS_INTERNAL | RTS_SUBNET));
     195:         net.sin_addr = inet_makeaddr(ifp->int_subnet, INADDR_ANY);
     196:     }
     197:     if (ifp->int_transitions++ > 0)
     198:         syslog(LOG_ERR, "re-installing interface %s", ifp->int_name);
     199:     rtadd(dst, &ifp->int_addr, ifp->int_metric,
     200:         ifp->int_flags & (IFF_INTERFACE|IFF_PASSIVE|IFF_REMOTE|IFF_SUBNET));
     201:
     202: }
     203:
     204: /*
     205:  * As a concession to the ARPANET we read a list of gateways
     206:  * from /etc/gateways and add them to our tables.  This file
     207:  * exists at each ARPANET gateway and indicates a set of ``remote''
     208:  * gateways (i.e. a gateway which we can't immediately determine
     209:  * if it's present or not as we can do for those directly connected
     210:  * at the hardware level).  If a gateway is marked ``passive''
     211:  * in the file, then we assume it doesn't have a routing process
     212:  * of our design and simply assume it's always present.  Those
     213:  * not marked passive are treated as if they were directly
     214:  * connected -- they're added into the interface list so we'll
     215:  * send them routing updates.
     216:  */
     217: gwkludge()
     218: {
     219:     struct sockaddr_in dst, gate;
     220:     FILE *fp;
     221:     char *type, *dname, *gname, *qual, buf[BUFSIZ];
     222:     struct interface *ifp;
     223:     int metric, n;
     224:     struct rt_entry route;
     225:
     226:     fp = fopen("/etc/gateways", "r");
     227:     if (fp == NULL)
     228:         return;
     229:     qual = buf;
     230:     dname = buf + 64;
     231:     gname = buf + ((BUFSIZ - 64) / 3);
     232:     type = buf + (((BUFSIZ - 64) * 2) / 3);
     233:     bzero((char *)&dst, sizeof (dst));
     234:     bzero((char *)&gate, sizeof (gate));
     235:     bzero((char *)&route, sizeof(route));
     236:     /* format: {net | host} XX gateway XX metric DD [passive]\n */
     237: #define readentry(fp) \
     238:     fscanf((fp), "%s %s gateway %s metric %d %s\n", \
     239:         type, dname, gname, &metric, qual)
     240:     for (;;) {
     241:         if ((n = readentry(fp)) == EOF)
     242:             break;
     243:         if (!getnetorhostname(type, dname, &dst))
     244:             continue;
     245:         if (!gethostnameornumber(gname, &gate))
     246:             continue;
     247:         if (strcmp(qual, "passive") == 0) {
     248:             /*
     249: 			 * Passive entries aren't placed in our tables,
     250: 			 * only the kernel's, so we don't copy all of the
     251: 			 * external routing information within a net.
     252: 			 * Internal machines should use the default
     253: 			 * route to a suitable gateway (like us).
     254: 			 */
     255:             route.rt_dst = *(struct sockaddr *) &dst;
     256:             route.rt_router = *(struct sockaddr *) &gate;
     257:             route.rt_flags = RTF_UP;
     258:             if (strcmp(type, "host") == 0)
     259:                 route.rt_flags |= RTF_HOST;
     260:             if (metric)
     261:                 route.rt_flags |= RTF_GATEWAY;
     262:             (void) ioctl(s, SIOCADDRT, (char *)&route.rt_rt);
     263:             continue;
     264:         }
     265:         if (strcmp(qual, "external") == 0) {
     266:             /*
     267: 			 * Entries marked external are handled
     268: 			 * by other means, e.g. EGP,
     269: 			 * and are placed in our tables only
     270: 			 * to prevent overriding them
     271: 			 * with something else.
     272: 			 */
     273:             rtadd(&dst, &gate, metric, RTS_EXTERNAL|RTS_PASSIVE);
     274:             continue;
     275:         }
     276:         /* assume no duplicate entries */
     277:         externalinterfaces++;
     278:         ifp = (struct interface *)malloc(sizeof (*ifp));
     279:         bzero((char *)ifp, sizeof (*ifp));
     280:         ifp->int_flags = IFF_REMOTE;
     281:         /* can't identify broadcast capability */
     282:         ifp->int_net = inet_netof(dst.sin_addr);
     283:         if (strcmp(type, "host") == 0) {
     284:             ifp->int_flags |= IFF_POINTOPOINT;
     285:             ifp->int_dstaddr = *((struct sockaddr *)&dst);
     286:         }
     287:         ifp->int_addr = *((struct sockaddr *)&gate);
     288:         ifp->int_metric = metric;
     289:         ifp->int_next = ifnet;
     290:         ifnet = ifp;
     291:         addrouteforif(ifp);
     292:     }
     293:     fclose(fp);
     294: }
     295:
     296: getnetorhostname(type, name, sin)
     297:     char *type, *name;
     298:     struct sockaddr_in *sin;
     299: {
     300:
     301:     if (strcmp(type, "net") == 0) {
     302:         struct netent *np = getnetbyname(name);
     303:         u_long n;
     304:
     305:         if (np == 0)
     306:             n = inet_network(name);
     307:         else {
     308:             if (np->n_addrtype != AF_INET)
     309:                 return (0);
     310:             n = np->n_net;
     311:             /*
     312: 			 * getnetbyname returns right-adjusted value.
     313: 			 */
     314:             if (n < 128)
     315:                 n <<= IN_CLASSA_NSHIFT;
     316:             else if (n < 65536)
     317:                 n <<= IN_CLASSB_NSHIFT;
     318:             else
     319:                 n <<= IN_CLASSC_NSHIFT;
     320:         }
     321:         sin->sin_family = AF_INET;
     322:         sin->sin_addr = inet_makeaddr(n, INADDR_ANY);
     323:         return (1);
     324:     }
     325:     if (strcmp(type, "host") == 0) {
     326:         struct hostent *hp = gethostbyname(name);
     327:
     328:         if (hp == 0)
     329:             sin->sin_addr.s_addr = inet_addr(name);
     330:         else {
     331:             if (hp->h_addrtype != AF_INET)
     332:                 return (0);
     333:             bcopy(hp->h_addr, &sin->sin_addr, hp->h_length);
     334:         }
     335:         sin->sin_family = AF_INET;
     336:         return (1);
     337:     }
     338:     return (0);
     339: }
     340:
     341: gethostnameornumber(name, sin)
     342:     char *name;
     343:     struct sockaddr_in *sin;
     344: {
     345:     struct hostent *hp;
     346:
     347:     hp = gethostbyname(name);
     348:     if (hp) {
     349:         bcopy(hp->h_addr, &sin->sin_addr, hp->h_length);
     350:         sin->sin_family = hp->h_addrtype;
     351:         return (1);
     352:     }
     353:     sin->sin_addr.s_addr = inet_addr(name);
     354:     sin->sin_family = AF_INET;
     355:     return (sin->sin_addr.s_addr != -1);
     356: }

#### Defined functions

addrouteforif defined in line 162; used 4 times

- in line 143, 291
- in /usr/src/sbin/routed/input.c line 117, 131

gethostnameornumber defined in line 341; used 1 times

- in line 245

getnetorhostname defined in line 296; used 1 times

- in line 243

gwkludge defined in line 217; used 1 times

- in /usr/src/sbin/routed/main.c line 122

ifinit defined in line 29; used 2 times

- in /usr/src/sbin/routed/main.c line 123
- in /usr/src/sbin/routed/timer.c line 32

#### Defined variables

externalinterfaces defined in line 21; used 3 times

- in line 125, 145, 277

ifnet defined in line 19; used 12 times

- in line 140-141(2), 289-290(2)
- in /usr/src/sbin/routed/if.c line 29, 52, 76, 104
- in /usr/src/sbin/routed/inet.c line 36, 68, 100, 133

lookforinterfaces defined in line 20; used 2 times

- in line 51, 66

sccsid defined in line 8; never used

#### Defined macros

readentry defined in line 237; used 1 times

- in line 241

Last modified: 1996-11-20 Generated: 2016-12-26 | Generated by src2html V0.67 page hit count: 1852 |