]> git.ozlabs.org Git - ppp.git/blobdiff - pppd/ipv6cp.c
pppd: Fix SIGSEGV in EAP-TLS code when TLS verify method is not specified
[ppp.git] / pppd / ipv6cp.c
index dec6cfea7568f75e808077f937633ea730f87ed7..d80ae216814e9017e65e629aaf15d038d61e4c39 100644 (file)
@@ -528,7 +528,8 @@ ipv6cp_resetci(fsm *f)
     
     if (!wo->opt_local) {
        wo->accept_local = 1;
-       eui64_magic_nz(wo->ourid);
+       if (!demand)
+           eui64_magic_nz(wo->ourid);
     }
     if (!wo->opt_remote)
        wo->accept_remote = 1;
@@ -1055,6 +1056,41 @@ endswitch:
 }
 
 
+/*
+ * ether_to_eui64 - Convert 48-bit Ethernet address into 64-bit EUI
+ *
+ * walks the list of valid ethernet interfaces, starting with devnam
+ * (for PPPoE it is ethernet interface), and convert the first
+ * found 48-bit MAC address into EUI 64. caller also assumes that
+ * the system has a properly configured Ethernet interface for this
+ * function to return non-zero.
+ */
+static int
+ether_to_eui64(eui64_t *p_eui64)
+{
+    u_char addr[6];
+
+    if (get_if_hwaddr(addr, devnam) < 0 && get_first_ether_hwaddr(addr) < 0) {
+        error("ipv6cp: no persistent id can be found");
+        return 0;
+    }
+
+    /*
+     * And convert the EUI-48 into EUI-64, per RFC 2472 [sec 4.1]
+     */
+    p_eui64->e8[0] = addr[0] | 0x02;
+    p_eui64->e8[1] = addr[1];
+    p_eui64->e8[2] = addr[2];
+    p_eui64->e8[3] = 0xFF;
+    p_eui64->e8[4] = 0xFE;
+    p_eui64->e8[5] = addr[3];
+    p_eui64->e8[6] = addr[4];
+    p_eui64->e8[7] = addr[5];
+
+    return 1;
+}
+
+
 /*
  * ipv6_check_options - check that any IP-related options are OK,
  * and assign appropriate defaults.
@@ -1071,7 +1107,7 @@ ipv6_check_options(void)
      * Persistent link-local id is only used when user has not explicitly
      * configure/hard-code the id
      */
-    if ((wo->use_persistent) && (!wo->opt_local) && (!wo->opt_remote)) {
+    if ((wo->use_persistent) && (!wo->opt_local)) {
 
        /* 
         * On systems where there are no Ethernet interfaces used, there
@@ -1105,11 +1141,6 @@ ipv6_check_options(void)
                wo->opt_remote = 1;
        }
     }
-
-    if (demand && (eui64_iszero(wo->ourid) || eui64_iszero(wo->hisid))) {
-       option_error("local/remote LL address required for demand-dialling\n");
-       exit(EXIT_OPTION_ERROR);
-    }
 }
 
 
@@ -1122,6 +1153,15 @@ ipv6_demand_conf(int u)
 {
     ipv6cp_options *wo = &ipv6cp_wantoptions[u];
 
+    if (eui64_iszero(wo->hisid)) {
+       /* make up an arbitrary identifier for the peer */
+       eui64_magic_nz(wo->hisid);
+    }
+    if (eui64_iszero(wo->ourid)) {
+       /* make up an arbitrary identifier for us */
+       eui64_magic_nz(wo->ourid);
+    }
+
     if (!sif6up(u))
        return 0;
     if (!sif6addr(u, wo->ourid, wo->hisid))
@@ -1136,7 +1176,6 @@ ipv6_demand_conf(int u)
        if (sif6defaultroute(u, wo->ourid, wo->hisid))
            default_route_set[u] = 1;
 
-    notice("ipv6_demand_conf");
     notice("local  LL address %s", llv6_ntoa(wo->ourid));
     notice("remote LL address %s", llv6_ntoa(wo->hisid));
 
@@ -1203,7 +1242,7 @@ ipv6cp_up(fsm *f)
            if (! eui64_equals(ho->hisid, wo->hisid))
                warn("Remote LL address changed to %s", 
                     llv6_ntoa(ho->hisid));
-           ipv6cp_clear_addrs(f->unit, go->ourid, ho->hisid);
+           ipv6cp_clear_addrs(f->unit, wo->ourid, wo->hisid);
 
            /* Set the interface to the new addresses */
            if (!sif6addr(f->unit, go->ourid, ho->hisid)) {