[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

ppp link-local persistant addresses



I have attached a patch I wrote for pppd to make it use persistant IP 
addresses, I copied the algorithm from the Solaris code and the 
implementation details (how to get the MAC) from the ifconfig source.

This code works for me.  I run pppd with "+ipv6 ipv6cp-use-persistent" and I 
get the same addresses all the time.

Now I was wondering whether the ppp interface should have an ipv6 address in 
global scope (this patch only does link-scope).  If so I'll have a go at 
writing support for that too.


Where can I find good docs on the IPv6 APIs in Linux?  I want to add IPv6 
support to Portslave, also I might end up adding IPv6 support to freeradius 
(got no way of testing Portslave otherwise).

-- 
http://www.coker.com.au/bonnie++/     Bonnie++ hard drive benchmark
http://www.coker.com.au/postal/       Postal SMTP/POP benchmark
http://www.coker.com.au/projects.html Projects I am working on
http://www.coker.com.au/~russell/     My home page
diff -ru ppp-2.4.1.uus.orig/pppd/ipv6cp.c ppp-2.4.1.uus.patched/pppd/ipv6cp.c
--- ppp-2.4.1.uus.orig/pppd/ipv6cp.c	Fri Mar 23 12:23:54 2001
+++ ppp-2.4.1.uus.patched/pppd/ipv6cp.c	Wed Nov 14 19:33:37 2001
@@ -193,7 +193,7 @@
     { "ipv6cp-use-ipaddr", o_bool, &ipv6cp_allowoptions[0].use_ip,
       "Use (default) IPv4 address as interface identifier", 1 },
 
-#if defined(SOL2)
+#if defined(SOL2) || defined(__linux__)
     { "ipv6cp-use-persistent", o_bool, &ipv6cp_wantoptions[0].use_persistent,
       "Use uniquely-available persistent value for link local address", 1 },
 #endif /* defined(SOL2) */
@@ -330,6 +330,8 @@
     return 1;
 }
 
+char *llv6_ntoa(eui64_t ifaceid);
+
 static void
 printifaceid(opt, printer, arg)
     option_t *opt;
@@ -1027,7 +1029,7 @@
     if (!ipv6cp_protent.enabled_flag)
 	return;
 
-#if defined(SOL2)
+#if defined(SOL2) || defined(__linux__)
     /*
      * Persistent link-local id is only used when user has not explicitly
      * configure/hard-code the id
@@ -1475,7 +1477,7 @@
  */
 #define IP6_HDRLEN	40	/* bytes */
 #define IP6_NHDR_FRAG	44	/* fragment IPv6 header */
-#define IPPROTO_TCP	6
+/* #define IPPROTO_TCP	6 */
 #define TCP_HDRLEN	20
 #define TH_FIN		0x01
 
diff -ru ppp-2.4.1.uus.orig/pppd/ipv6cp.h ppp-2.4.1.uus.patched/pppd/ipv6cp.h
--- ppp-2.4.1.uus.orig/pppd/ipv6cp.h	Sat Aug  5 08:46:47 2000
+++ ppp-2.4.1.uus.patched/pppd/ipv6cp.h	Wed Nov 14 19:08:36 2001
@@ -109,7 +109,7 @@
     int opt_local;		/* ourtoken set by option */
     int opt_remote;		/* histoken set by option */
     int use_ip;			/* use IP as interface identifier */
-#if defined(SOL2)
+#if defined(SOL2) | defined(__linux__)
     int use_persistent;		/* use uniquely persistent value for address */
 #endif /* defined(SOL2) */
     int neg_vj;			/* Van Jacobson Compression? */
diff -ru ppp-2.4.1.uus.orig/pppd/sys-linux.c ppp-2.4.1.uus.patched/pppd/sys-linux.c
--- ppp-2.4.1.uus.orig/pppd/sys-linux.c	Wed Nov 14 19:05:54 2001
+++ ppp-2.4.1.uus.patched/pppd/sys-linux.c	Wed Nov 14 19:44:36 2001
@@ -2750,3 +2750,51 @@
     }
     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 = 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

Reply to: