]> git.ozlabs.org Git - ppp.git/blobdiff - pppd/sys-linux.c
pppd: Document chapms-strip-domain option in pppd(8) (#203)
[ppp.git] / pppd / sys-linux.c
index 587242bb1ed7a2cb0107061a2109e17ccdde1dd1..8b538f0e4ac4431688ac421b7c622032d3f7589f 100644 (file)
@@ -209,6 +209,8 @@ static int  if_is_up;       /* Interface has been marked up */
 static int     if6_is_up;      /* Interface has been marked up for IPv6, to help differentiate */
 static int     have_default_route;     /* Gateway for default route added */
 static int     have_default_route6;    /* Gateway for default IPv6 route added */
+static struct  rtentry old_def_rt;     /* Old default route */
+static int     default_rt_repl_rest;   /* replace and restore old default rt */
 static u_int32_t proxy_arp_addr;       /* Addr for proxy arp entry added */
 static char proxy_arp_dev[16];         /* Device for proxy arp entry */
 static u_int32_t our_old_addr;         /* for detecting address changes */
@@ -1573,6 +1575,9 @@ static int read_route_table(struct rtentry *rt)
        p = NULL;
     }
 
+    SET_SA_FAMILY (rt->rt_dst,     AF_INET);
+    SET_SA_FAMILY (rt->rt_gateway, AF_INET);
+
     SIN_ADDR(rt->rt_dst) = strtoul(cols[route_dest_col], NULL, 16);
     SIN_ADDR(rt->rt_gateway) = strtoul(cols[route_gw_col], NULL, 16);
     SIN_ADDR(rt->rt_genmask) = strtoul(cols[route_mask_col], NULL, 16);
@@ -1645,20 +1650,53 @@ int have_route_to(u_int32_t addr)
 /********************************************************************
  *
  * sifdefaultroute - assign a default route through the address given.
+ *
+ * If the global default_rt_repl_rest flag is set, then this function
+ * already replaced the original system defaultroute with some other
+ * route and it should just replace the current defaultroute with
+ * another one, without saving the current route. Use: demand mode,
+ * when pppd sets first a defaultroute it it's temporary ppp0 addresses
+ * and then changes the temporary addresses to the addresses for the real
+ * ppp connection when it has come up.
  */
 
-int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
+int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway, bool replace)
 {
-    struct rtentry rt;
+    struct rtentry rt, tmp_rt;
+    struct rtentry *del_rt = NULL;
 
-    if (defaultroute_exists(&rt, dfl_route_metric) && strcmp(rt.rt_dev, ifname) != 0) {
-       if (rt.rt_flags & RTF_GATEWAY)
-           error("not replacing existing default route via %I with metric %d",
-                 SIN_ADDR(rt.rt_gateway), dfl_route_metric);
-       else
-           error("not replacing existing default route through %s with metric %d",
-                 rt.rt_dev, dfl_route_metric);
-       return 0;
+    if (default_rt_repl_rest) {
+       /* We have already replaced the original defaultroute, if we
+        * are called again, we will delete the current default route
+        * and set the new default route in this function.
+        * - this is normally only the case the doing demand: */
+       if (defaultroute_exists(&tmp_rt, -1))
+           del_rt = &tmp_rt;
+    } else if (defaultroute_exists(&old_def_rt, -1           ) &&
+                           strcmp( old_def_rt.rt_dev, ifname) != 0) {
+       /*
+        * We did not yet replace an existing default route, let's
+        * check if we should save and replace a default route:
+        */
+       u_int32_t old_gateway = SIN_ADDR(old_def_rt.rt_gateway);
+
+       if (old_gateway != gateway) {
+           if (!replace) {
+               error("not replacing default route to %s [%I]",
+                       old_def_rt.rt_dev, old_gateway);
+               return 0;
+           } else {
+               /* we need to copy rt_dev because we need it permanent too: */
+               char * tmp_dev = malloc(strlen(old_def_rt.rt_dev)+1);
+               strcpy(tmp_dev, old_def_rt.rt_dev);
+               old_def_rt.rt_dev = tmp_dev;
+
+               notice("replacing old default route to %s [%I]",
+                       old_def_rt.rt_dev, old_gateway);
+               default_rt_repl_rest = 1;
+               del_rt = &old_def_rt;
+           }
+       }
     }
 
     memset (&rt, 0, sizeof (rt));
@@ -1678,6 +1716,12 @@ int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
            error("default route ioctl(SIOCADDRT): %m");
        return 0;
     }
+    if (default_rt_repl_rest && del_rt)
+       if (ioctl(sock_fd, SIOCDELRT, del_rt) < 0) {
+           if ( ! ok_error ( errno ))
+               error("del old default route ioctl(SIOCDELRT): %m(%d)", errno);
+           return 0;
+       }
 
     have_default_route = 1;
     return 1;
@@ -1716,6 +1760,16 @@ int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
            return 0;
        }
     }
+    if (default_rt_repl_rest) {
+       notice("restoring old default route to %s [%I]",
+                       old_def_rt.rt_dev, SIN_ADDR(old_def_rt.rt_gateway));
+       if (ioctl(sock_fd, SIOCADDRT, &old_def_rt) < 0) {
+           if ( ! ok_error ( errno ))
+               error("restore default route ioctl(SIOCADDRT): %m(%d)", errno);
+           return 0;
+       }
+       default_rt_repl_rest = 0;
+    }
 
     return 1;
 }
@@ -3147,54 +3201,6 @@ sys_check_options(void)
     return 1;
 }
 
-#ifdef INET6
-/*
- * ether_to_eui64 - Convert 48-bit Ethernet address into 64-bit EUI
- *
- * convert the 48-bit MAC address of eth0 into EUI 64. caller also assumes
- * that the system has a properly configured Ethernet interface for this
- * function to return non-zero.
- */
-int
-ether_to_eui64(eui64_t *p_eui64)
-{
-    struct ifreq ifr;
-    int skfd;
-    const unsigned char *ptr;
-
-    skfd = socket(PF_INET6, SOCK_DGRAM, 0);
-    if(skfd == -1)
-    {
-        warn("could not open IPv6 socket");
-        return 0;
-    }
-
-    strcpy(ifr.ifr_name, "eth0");
-    if(ioctl(skfd, SIOCGIFHWADDR, &ifr) < 0)
-    {
-        close(skfd);
-        warn("could not obtain hardware address for eth0");
-        return 0;
-    }
-    close(skfd);
-
-    /*
-     * And convert the EUI-48 into EUI-64, per RFC 2472 [sec 4.1]
-     */
-    ptr = (unsigned char *) ifr.ifr_hwaddr.sa_data;
-    p_eui64->e8[0] = ptr[0] | 0x02;
-    p_eui64->e8[1] = ptr[1];
-    p_eui64->e8[2] = ptr[2];
-    p_eui64->e8[3] = 0xFF;
-    p_eui64->e8[4] = 0xFE;
-    p_eui64->e8[5] = ptr[3];
-    p_eui64->e8[6] = ptr[4];
-    p_eui64->e8[7] = ptr[5];
-
-    return 1;
-}
-#endif
-
 /********************************************************************
  *
  * get_time - Get current time, monotonic if possible.