]> git.ozlabs.org Git - ppp.git/blobdiff - pppd/ipv6cp.c
pppd: add experimental support for PEAP protocol, an extension of EAP
[ppp.git] / pppd / ipv6cp.c
index 11be07d5636691266d33e03e04abd4b440a2d7db..8ab440a95f683015bcc2226c8a759173369c203c 100644 (file)
  *   since SVR4 && (SNI || __USLC__) didn't work properly)
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
@@ -239,9 +243,9 @@ static option_t ipv6cp_option_list[] = {
     { "-ipv6", o_bool, &ipv6cp_protent.enabled_flag,
       "Disable IPv6 and IPv6CP", OPT_PRIOSUB | OPT_ALIAS },
 
-    { "ipv6cp-accept-local", o_bool, &ipv6cp_allowoptions[0].accept_local,
+    { "ipv6cp-accept-local", o_bool, &ipv6cp_wantoptions[0].accept_local,
       "Accept peer's interface identifier for us", 1 },
-    { "ipv6cp-accept-remote", o_bool, &ipv6cp_allowoptions[0].accept_remote,
+    { "ipv6cp-accept-remote", o_bool, &ipv6cp_wantoptions[0].accept_remote,
       "Accept peer's interface identifier for itself", 1 },
 
     { "defaultroute6", o_bool, &ipv6cp_wantoptions[0].default_route,
@@ -720,7 +724,9 @@ ipv6cp_nakci(fsm *f, u_char *p, int len, int treat_as_reject)
     NAKCIIFACEID(CI_IFACEID, neg_ifaceid,
                 if (treat_as_reject) {
                     try.neg_ifaceid = 0;
-                } else if (go->accept_local) {
+                } else if (go->accept_local && !eui64_iszero(ifaceid) && !eui64_equals(ifaceid, go->hisid)) {
+                    try.ourid = ifaceid;
+                } else if (eui64_iszero(ifaceid) && !go->opt_local) {
                     while (eui64_iszero(ifaceid) || 
                            eui64_equals(ifaceid, go->hisid)) /* bad luck */
                         eui64_magic(ifaceid);
@@ -772,11 +778,15 @@ ipv6cp_nakci(fsm *f, u_char *p, int len, int treat_as_reject)
                goto bad;
            try.neg_ifaceid = 1;
            eui64_get(ifaceid, p);
-           if (go->accept_local) {
+           if (go->accept_local && !eui64_iszero(ifaceid) && !eui64_equals(ifaceid, go->hisid)) {
+               try.ourid = ifaceid;
+           } else if (eui64_iszero(ifaceid) && !go->opt_local) {
                while (eui64_iszero(ifaceid) || 
                       eui64_equals(ifaceid, go->hisid)) /* bad luck */
                    eui64_magic(ifaceid);
                try.ourid = ifaceid;
+           } else {
+               try.neg_ifaceid = 0;
            }
            no.neg_ifaceid = 1;
            break;
@@ -943,8 +953,7 @@ ipv6cp_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree)
                break;
            }
            if (!eui64_iszero(wo->hisid) && !wo->accept_remote &&
-               !eui64_equals(ifaceid, wo->hisid) && 
-               eui64_iszero(go->hisid)) {
+               !eui64_equals(ifaceid, wo->hisid)) {
                    
                orc = CONFNAK;
                ifaceid = wo->hisid;
@@ -956,9 +965,17 @@ ipv6cp_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree)
                orc = CONFNAK;
                if (eui64_iszero(go->hisid))    /* first time, try option */
                    ifaceid = wo->hisid;
-               while (eui64_iszero(ifaceid) || 
-                      eui64_equals(ifaceid, go->ourid)) /* bad luck */
-                   eui64_magic(ifaceid);
+               if (eui64_equals(ifaceid, go->ourid)) /* bad luck */
+                   eui64_zero(ifaceid);
+               if (eui64_iszero(ifaceid)) {
+                   if (wo->opt_remote)
+                       ifaceid = wo->hisid;
+                   else {
+                       while (eui64_iszero(ifaceid) ||
+                              eui64_equals(ifaceid, go->ourid)) /* bad luck */
+                           eui64_magic(ifaceid);
+                   }
+               }
                go->hisid = ifaceid;
                DECPTR(sizeof(ifaceid), p);
                eui64_put(ifaceid, p);
@@ -1070,7 +1087,7 @@ ether_to_eui64(eui64_t *p_eui64)
 {
     u_char addr[6];
 
-    if (get_if_hwaddr(addr, devnam) < 0 || get_first_ether_hwaddr(addr) < 0) {
+    if (get_if_hwaddr(addr, devnam) < 0 && get_first_ether_hwaddr(addr) < 0) {
         error("ipv6cp: no persistent id can be found");
         return 0;
     }
@@ -1107,7 +1124,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
@@ -1200,6 +1217,12 @@ ipv6cp_up(fsm *f)
     /*
      * We must have a non-zero LL address for both ends of the link.
      */
+
+    if (!eui64_iszero(wo->hisid) && !wo->accept_remote && (!ho->neg_ifaceid || !eui64_equals(ho->hisid, wo->hisid))) {
+       error("Peer refused to agree to his interface identifier");
+       ipv6cp_close(f->unit, "Refused his interface identifier");
+       return;
+    }
     if (!ho->neg_ifaceid)
        ho->hisid = wo->hisid;