fixes
[unix-history] / usr / src / sbin / routed / startup.c
index 55688d1..5f4d244 100644 (file)
@@ -5,7 +5,7 @@
  */
 
 #ifndef lint
  */
 
 #ifndef lint
-static char sccsid[] = "@(#)startup.c  5.2 (Berkeley) %G%";
+static char sccsid[] = "@(#)startup.c  5.4 (Berkeley) %G%";
 #endif not lint
 
 /*
 #endif not lint
 
 /*
@@ -14,12 +14,10 @@ static char sccsid[] = "@(#)startup.c       5.2 (Berkeley) %G%";
 #include "defs.h"
 #include <sys/ioctl.h>
 #include <net/if.h>
 #include "defs.h"
 #include <sys/ioctl.h>
 #include <net/if.h>
-#include <nlist.h>
 #include <syslog.h>
 
 struct interface *ifnet;
 int    lookforinterfaces = 1;
 #include <syslog.h>
 
 struct interface *ifnet;
 int    lookforinterfaces = 1;
-int    performnlist = 1;
 int    externalinterfaces = 0;         /* # of remote and local interfaces */
 
 /*
 int    externalinterfaces = 0;         /* # of remote and local interfaces */
 
 /*
@@ -60,6 +58,9 @@ ifinit()
                         continue;
                 }
                ifs.int_flags = ifreq.ifr_flags | IFF_INTERFACE;
                         continue;
                 }
                ifs.int_flags = ifreq.ifr_flags | IFF_INTERFACE;
+               /* no one cares about software loopback interfaces */
+               if (ifs.int_flags & IFF_LOOPBACK)
+                       continue;
                if ((ifs.int_flags & IFF_UP) == 0 ||
                    ifr->ifr_addr.sa_family == AF_UNSPEC) {
                        lookforinterfaces = 1;
                if ((ifs.int_flags & IFF_UP) == 0 ||
                    ifr->ifr_addr.sa_family == AF_UNSPEC) {
                        lookforinterfaces = 1;
@@ -85,6 +86,10 @@ ifinit()
                         }
                        ifs.int_broadaddr = ifreq.ifr_broadaddr;
                }
                         }
                        ifs.int_broadaddr = ifreq.ifr_broadaddr;
                }
+               if (ioctl(s, SIOCGIFMETRIC, (char *)&ifreq) < 0)
+                       syslog(LOG_ERR, "ioctl (get metric)");
+               else
+                       ifs.int_metric = ifreq.ifr_metric;
                if (ioctl(s, SIOCGIFNETMASK, (char *)&ifreq) < 0) {
                        syslog(LOG_ERR, "ioctl (get netmask)");
                        continue;
                if (ioctl(s, SIOCGIFNETMASK, (char *)&ifreq) < 0) {
                        syslog(LOG_ERR, "ioctl (get netmask)");
                        continue;
@@ -101,9 +106,8 @@ ifinit()
                        ifs.int_netmask = IN_CLASSC_NET;
                ifs.int_net = i & ifs.int_netmask;
                ifs.int_subnet = i & ifs.int_subnetmask;
                        ifs.int_netmask = IN_CLASSC_NET;
                ifs.int_net = i & ifs.int_netmask;
                ifs.int_subnet = i & ifs.int_subnetmask;
-               /* no one cares about software loopback interfaces */
-               if (ifs.int_net == LOOPBACKNET)
-                       continue;
+               if (ifs.int_subnetmask != ifs.int_netmask)
+                       ifs.int_flags |= IFF_SUBNET;
                ifp = (struct interface *)malloc(sizeof (struct interface));
                if (ifp == 0) {
                        printf("routed: out of memory\n");
                ifp = (struct interface *)malloc(sizeof (struct interface));
                if (ifp == 0) {
                        printf("routed: out of memory\n");
@@ -133,7 +137,6 @@ ifinit()
                        goto bad;               /* ??? */
                }
                strcpy(ifp->int_name, ifr->ifr_name);
                        goto bad;               /* ??? */
                }
                strcpy(ifp->int_name, ifr->ifr_name);
-               ifp->int_metric = 0;
                ifp->int_next = ifnet;
                ifnet = ifp;
                traceinit(ifp);
                ifp->int_next = ifnet;
                ifnet = ifp;
                traceinit(ifp);
@@ -150,6 +153,12 @@ bad:
        _exit(0177);
 }
 
        _exit(0177);
 }
 
+/*
+ * Add route for interface if not currently installed.
+ * Create route to other end if a point-to-point link,
+ * otherwise a route to this (sub)network.
+ * INTERNET SPECIFIC.
+ */
 addrouteforif(ifp)
        struct interface *ifp;
 {
 addrouteforif(ifp)
        struct interface *ifp;
 {
@@ -174,7 +183,22 @@ addrouteforif(ifp)
        if (ifp->int_transitions++ > 0)
                syslog(LOG_ERR, "re-installing interface %s", ifp->int_name);
        rtadd(dst, &ifp->int_addr, ifp->int_metric,
        if (ifp->int_transitions++ > 0)
                syslog(LOG_ERR, "re-installing interface %s", ifp->int_name);
        rtadd(dst, &ifp->int_addr, ifp->int_metric,
-               ifp->int_flags & (IFF_INTERFACE|IFF_PASSIVE|IFF_REMOTE));
+           ifp->int_flags & (IFF_INTERFACE|IFF_PASSIVE|IFF_REMOTE|IFF_SUBNET));
+
+       /*
+        * If interface on subnetted network,
+        * install route to network as well.
+        * This is meant for external viewers.
+        */
+       if ((ifp->int_flags & (IFF_SUBNET|IFF_POINTOPOINT)) == IFF_SUBNET) {
+               net.sin_addr = inet_makeaddr(ifp->int_net, INADDR_ANY);
+               rt = rtfind(dst);
+               if (rt && (rt->rt_state & RTS_INTERFACE))
+                       return;
+               rtadd(dst, &ifp->int_addr, ifp->int_metric,
+                   (ifp->int_flags & (IFF_INTERFACE|IFF_PASSIVE|IFF_REMOTE) |
+                       RTS_INTERNAL));
+       }
 }
 
 /*
 }
 
 /*
@@ -238,6 +262,16 @@ gwkludge()
                        (void) ioctl(s, SIOCADDRT, (char *)&route.rt_rt);
                        continue;
                }
                        (void) ioctl(s, SIOCADDRT, (char *)&route.rt_rt);
                        continue;
                }
+               if (strcmp(qual, "external") == 0) {
+                       /*
+                        * Entries marked external are handled
+                        * by other means, e.g. EGP,
+                        * and are placed in our tables only
+                        * to prevent overriding them
+                        * with something else.
+                        */
+                       rtadd(&dst, &gate, metric, RTS_EXTERNAL|RTS_PASSIVE);
+               }
                /* assume no duplicate entries */
                externalinterfaces++;
                ifp = (struct interface *)malloc(sizeof (*ifp));
                /* assume no duplicate entries */
                externalinterfaces++;
                ifp = (struct interface *)malloc(sizeof (*ifp));