I've done some work on getting openvpn to tunnel ipv6 without having to
use TAP tunnels.  I think to get ipv6 tunneling to work on other platforms
it may require changes in the tunnel driver.  But I figure I'll post this
here as it might be of use to somebody.

Regards,

Aaron



Index: Makefile.in
===================================================================
RCS file: /cvsroot/openvpn/openvpn/Makefile.in,v
retrieving revision 1.6
diff -u -r1.6 Makefile.in
--- Makefile.in 25 Jun 2002 06:56:16 -0000      1.6
+++ Makefile.in 27 Sep 2002 22:41:09 -0000
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.6.1 from Makefile.am.
+# Makefile.in generated by automake 1.6.3 from Makefile.am.
 # @configure_input@

 # Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
@@ -74,6 +74,7 @@
 INSTALL_DATA = @INSTALL_DATA@
 install_sh_DATA = $(install_sh) -c -m 644
 install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_HEADER = $(INSTALL_DATA)
 transform = @program_transform_name@
@@ -170,6 +171,9 @@

 .SUFFIXES:
 .SUFFIXES: .c .o .obj
+
+am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
+ configure.lineno
 $(srcdir)/Makefile.in:  Makefile.am  $(top_srcdir)/configure.ac $(ACLOCAL_M4)
        cd $(top_srcdir) && \
          $(AUTOMAKE) --gnu  Makefile
@@ -199,7 +203,7 @@
        touch $(srcdir)/config.h.in

 distclean-hdr:
-       -rm -f config.h
+       -rm -f config.h stamp-h1
 sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
 install-sbinPROGRAMS: $(sbin_PROGRAMS)
        @$(NORMAL_INSTALL)
@@ -208,8 +212,7 @@
          p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
          if test -f $$p \
          ; then \
-           p1=`echo "$$p1" | sed -e 's,^.*/,,'`; \
-           f=`echo $$p1|sed '$(transform);s/$$/$(EXEEXT)/'`; \
+           f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
           echo " $(INSTALL_PROGRAM_ENV) $(sbinPROGRAMS_INSTALL) $$p 
$(DESTDIR)$(sbindir)/$$f"; \
           $(INSTALL_PROGRAM_ENV) $(sbinPROGRAMS_INSTALL) $$p 
$(DESTDIR)$(sbindir)/$$f; \
          else :; fi; \
@@ -218,8 +221,7 @@
 uninstall-sbinPROGRAMS:
        @$(NORMAL_UNINSTALL)
        @list='$(sbin_PROGRAMS)'; for p in $$list; do \
-         f=`echo $$p|sed 's/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
-         f=`echo "$$f" | sed -e 's,^.*/,,'`; \
+         f=`echo "$$p" | sed 
's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
          echo " rm -f $(DESTDIR)$(sbindir)/$$f"; \
          rm -f $(DESTDIR)$(sbindir)/$$f; \
        done
@@ -286,6 +288,10 @@
          if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
          else file=$$i; fi; \
          ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+         case "$$ext" in \
+           8*) ;; \
+           *) ext='8' ;; \
+         esac; \
          inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
          inst=`echo $$inst | sed -e 's/^.*\///'`; \
          inst=`echo $$inst | sed '$(transform)'`.$$ext; \
@@ -361,7 +367,7 @@
 distdir: $(DISTFILES)
        $(am__remove_distdir)
        mkdir $(distdir)
-       @for file in $(DISTFILES); do \
+       @list='$(DISTFILES)'; for file in $$list; do \
          if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
          dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
          if test "$$dir" != "$$file" && test "$$dir" != "."; then \
@@ -459,7 +465,7 @@
 clean-generic:

 distclean-generic:
-       -rm -f Makefile $(CONFIG_CLEAN_FILES) stamp-h stamp-h[0-9]*
+       -rm -f Makefile $(CONFIG_CLEAN_FILES)

 maintainer-clean-generic:
        @echo "This command is intended for maintainers to use"
@@ -469,7 +475,7 @@
 clean-am: clean-generic clean-sbinPROGRAMS mostlyclean-am

 distclean: distclean-am
-       -rm -f config.status config.cache config.log
+       -rm -f $(am__CONFIG_DISTCLEAN_FILES)
 distclean-am: clean-am distclean-compile distclean-depend \
        distclean-generic distclean-hdr distclean-tags

@@ -492,7 +498,8 @@
 installcheck-am:

 maintainer-clean: maintainer-clean-am
-
+       -rm -f $(am__CONFIG_DISTCLEAN_FILES)
+       -rm -rf autom4te.cache
 maintainer-clean-am: distclean-am maintainer-clean-generic

 mostlyclean: mostlyclean-am
Index: aclocal.m4
===================================================================
RCS file: /cvsroot/openvpn/openvpn/aclocal.m4,v
retrieving revision 1.31
diff -u -r1.31 aclocal.m4
--- aclocal.m4  14 Sep 2002 21:54:10 -0000      1.31
+++ aclocal.m4  27 Sep 2002 22:41:11 -0000
@@ -1,4 +1,4 @@
-# aclocal.m4 generated automatically by aclocal 1.6.1 -*- Autoconf -*-
+# aclocal.m4 generated automatically by aclocal 1.6.3 -*- Autoconf -*-

 # Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002
 # Free Software Foundation, Inc.
@@ -96,7 +96,7 @@
 dnl macros posted by AFC to the autoconf macro repository.  We are also
 dnl grateful for the helpful feedback of numerous users.
 dnl
-dnl @version $Id: aclocal.m4,v 1.31 2002/09/14 21:54:10 jimyonan Exp $
+dnl @version $Id: acinclude.m4,v 1.1 2002/05/30 00:04:45 jimyonan Exp $
 dnl @author Steven G. Johnson <stev...@alum.mit.edu> and Alejandro Forero 
Cuervo <bac...@bachue.com>

 AC_DEFUN([ACX_PTHREAD], [
@@ -490,7 +490,7 @@
 # Call AM_AUTOMAKE_VERSION so it can be traced.
 # This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
 AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-        [AM_AUTOMAKE_VERSION([1.6.1])])
+        [AM_AUTOMAKE_VERSION([1.6.3])])

 # Helper functions for option handling.                    -*- Autoconf -*-

@@ -822,7 +822,7 @@

 ifelse([$1], CC,   [depcc="$CC"   am_compiler_list=],
        [$1], CXX,  [depcc="$CXX"  am_compiler_list=],
-       [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc']
+       [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
        [$1], GCJ,  [depcc="$GCJ"  am_compiler_list='gcc3 gcc'],
                    [depcc="$$1"   am_compiler_list=])

@@ -947,7 +947,13 @@
 [for mf in $CONFIG_FILES; do
   # Strip MF so we end up with the name of the file.
   mf=`echo "$mf" | sed -e 's/:.*$//'`
-  if (sed 1q $mf | fgrep 'generated by automake') > /dev/null 2>&1; then
+  # Check whether this is an Automake generated Makefile or not.
+  # We used to match only the files named `Makefile.in', but
+  # some people rename them; so instead we look at the file content.
+  # Grep'ing the first line is not enough: some people post-process
+  # each Makefile.in and add a new line on top of each file to say so.
+  # So let's grep whole file.
+  if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then
     dirpart=`AS_DIRNAME("$mf")`
   else
     continue
Index: config.h.in
===================================================================
RCS file: /cvsroot/openvpn/openvpn/config.h.in,v
retrieving revision 1.6
diff -u -r1.6 config.h.in
--- config.h.in 28 Jul 2002 07:54:57 -0000      1.6
+++ config.h.in 27 Sep 2002 22:41:12 -0000
@@ -78,6 +78,9 @@
 /* Define to 1 if you have the <netdb.h> header file. */
 #undef HAVE_NETDB_H

+/* Define to 1 if you have the <netinet/if_ether.h> header file. */
+#undef HAVE_NETINET_IF_ETHER_H
+
 /* Define to 1 if you have the <netinet/in.h> header file. */
 #undef HAVE_NETINET_IN_H

Index: configure
===================================================================
RCS file: /cvsroot/openvpn/openvpn/configure,v
retrieving revision 1.37
diff -u -r1.37 configure
--- configure   14 Sep 2002 21:54:10 -0000      1.37
+++ configure   27 Sep 2002 22:41:39 -0000
@@ -6759,6 +6759,120 @@
 done


+for ac_header in netinet/if_ether.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+  # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+#include "confdefs.h"
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } &&
+         { ac_try='test -s conftest.$ac_objext'
+  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+  (eval $ac_try) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+cat conftest.$ac_ext >&5
+ac_header_compiler=no
+fi
+rm -f conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+#line $LINENO "configure"
+#include "confdefs.h"
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+  (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+  ac_status=$?
+  egrep -v '^ *\+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null; then
+  if test -s conftest.err; then
+    ac_cpp_err=$ac_c_preproc_warn_flag
+  else
+    ac_cpp_err=
+  fi
+else
+  ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc in
+  yes:no )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, 
rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the 
preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the 
preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" 
>&2;};;
+  no:yes )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be 
compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing 
prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" 
>&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the 
preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" 
>&2;};;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
 for ac_header in netinet/tcp.h
 do
 as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
@@ -12646,7 +12760,13 @@
     depfiles ) test x"$AMDEP_TRUE" != x"" || for mf in $CONFIG_FILES; do
   # Strip MF so we end up with the name of the file.
   mf=`echo "$mf" | sed -e 's/:.*$//'`
-  if (sed 1q $mf | fgrep 'generated by automake') > /dev/null 2>&1; then
+  # Check whether this is an Automake generated Makefile or not.
+  # We used to match only the files named `Makefile.in', but
+  # some people rename them; so instead we look at the file content.
+  # Grep'ing the first line is not enough: some people post-process
+  # each Makefile.in and add a new line on top of each file to say so.
+  # So let's grep whole file.
+  if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then
     dirpart=`(dirname "$mf") 2>/dev/null ||
 $as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
          X"$mf" : 'X\(//\)[^/]' \| \
Index: configure.ac
===================================================================
RCS file: /cvsroot/openvpn/openvpn/configure.ac,v
retrieving revision 1.37
diff -u -r1.37 configure.ac
--- configure.ac        14 Sep 2002 21:54:10 -0000      1.37
+++ configure.ac        27 Sep 2002 22:41:39 -0000
@@ -169,6 +169,7 @@
 AC_CHECK_HEADERS(netinet/in.h)
 AC_CHECK_HEADERS(netinet/in_systm.h)
 AC_CHECK_HEADERS(netinet/ip.h)
+AC_CHECK_HEADERS(netinet/if_ether.h)
 AC_CHECK_HEADERS(netinet/tcp.h)
 AC_CHECK_HEADERS(resolv.h)
 AC_CHECK_HEADERS(arpa/inet.h)
Index: syshead.h
===================================================================
RCS file: /cvsroot/openvpn/openvpn/syshead.h,v
retrieving revision 1.10
diff -u -r1.10 syshead.h
--- syshead.h   28 Jul 2002 07:54:57 -0000      1.10
+++ syshead.h   27 Sep 2002 22:41:40 -0000
@@ -141,8 +141,16 @@

 #ifdef TARGET_LINUX

+#ifdef HAVE_NETINET_IF_ETHER_H
+#include <netinet/if_ether.h>
+#endif
+
 #ifdef HAVE_LINUX_IF_TUN_H
 #include <linux/if_tun.h>
+#endif
+
+#ifdef HAVE_NETINET_IP_H
+#include <netinet/ip.h>
 #endif

 #endif /* TARGET_LINUX */
Index: tun.c
===================================================================
RCS file: /cvsroot/openvpn/openvpn/tun.c,v
retrieving revision 1.17
diff -u -r1.17 tun.c
--- tun.c       28 Jul 2002 07:54:57 -0000      1.17
+++ tun.c       27 Sep 2002 22:41:41 -0000
@@ -277,7 +277,6 @@
        msg (M_ERR, "Cannot open tun/tap dev %s", dev_node);

       CLEAR (ifr);
-      ifr.ifr_flags = IFF_NO_PI;

       if (is_dev_type (dev, dev_type, "tun"))
        {
@@ -339,13 +338,43 @@
 int
 write_tun (struct tuntap* tt, uint8_t *buf, int len)
 {
-  return write (tt->fd, buf, len);
+  struct tun_pi pi;
+  struct iphdr *iph;
+  struct iovec vect[2];
+  int ret;
+
+  iph = (struct iphdr *)buf;
+
+  pi.flags = 0;
+
+  if(iph->version == 6)
+    pi.proto = htons(ETH_P_IPV6);
+  else
+    pi.proto = htons(ETH_P_IP);
+
+  vect[0].iov_len = sizeof(pi);
+  vect[0].iov_base = &pi;
+  vect[1].iov_len = len;
+  vect[1].iov_base = buf;
+
+  ret = writev(tt->fd, vect, 2);
+  return(ret - sizeof(pi));
 }

 int
 read_tun (struct tuntap* tt, uint8_t *buf, int len)
 {
-  return read (tt->fd, buf, len);
+  struct iovec vect[2];
+  struct tun_pi pi;
+  int ret;
+
+  vect[0].iov_len = sizeof(pi);
+  vect[0].iov_base = &pi;
+  vect[1].iov_len = len;
+  vect[1].iov_base = buf;
+
+  ret = readv(tt->fd, vect, 2);
+  return(ret - sizeof(pi));
 }

 #elif defined(TARGET_SOLARIS)


Reply via email to