[Pkg-privacy-commits] [onioncat] 218/241: - configure.ac refined - OC now compiles and runs on Solaris 10 using the Universal TUN/TAP driver version 1.1 (http://vtun.sourceforge.net/tun/index.html) - ocathosts.[ch] added. It reads IPv6 addresses from /etc/hosts - /etc/hosts reverse lookup for I2P .b32 names added
Intrigeri
intrigeri at moszumanska.debian.org
Wed Aug 26 16:17:13 UTC 2015
This is an automated email from the git hooks/post-receive script.
intrigeri pushed a commit to branch upstream-master
in repository onioncat.
commit af3acdb39f296430d3121f87a37a90e99255010f
Author: eagle <eagle at 58e1ccc2-750e-0410-8d0d-f93ca75ab447>
Date: Mon Apr 26 11:29:15 2010 +0000
- configure.ac refined
- OC now compiles and runs on Solaris 10 using the Universal TUN/TAP driver
version 1.1 (http://vtun.sourceforge.net/tun/index.html)
- ocathosts.[ch] added. It reads IPv6 addresses from /etc/hosts
- /etc/hosts reverse lookup for I2P .b32 names added
git-svn-id: https://www.cypherpunk.at/svn/onioncat/trunk@547 58e1ccc2-750e-0410-8d0d-f93ca75ab447
---
ChangeLog | 5 +
TODO | 2 +
config.h.in | 27 ++
configure | 609 ++++++++++++++++++++++++++++++++++++--
configure.ac | 80 ++++-
src/Makefile.am | 4 +-
src/Makefile.in | 7 +-
src/ocat.c | 15 +-
src/ocat.h | 53 +++-
src/ocat_netdesc.h | 8 +
src/ocatcompat.c | 2 +
src/ocateth.c | 30 +-
src/ocatfdbuf.c | 5 +-
src/ocathosts.c | 271 +++++++++++++++++
src/{ocatcompat.c => ocathosts.h} | 43 ++-
src/ocatroute.c | 47 ++-
src/ocatsetup.c | 50 +++-
src/ocatsocks.c | 31 +-
src/ocattun.c | 73 ++---
src/ocatv6conv.c | 2 +-
20 files changed, 1229 insertions(+), 135 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index d430407..9395bba 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,9 @@
* version 0.2.2
+ - configure.ac refined
+ - OC now compiles and runs on Solaris 10 using the Universal TUN/TAP driver
+ version 1.1 (http://vtun.sourceforge.net/tun/index.html)
+ - ocathosts.[ch] added. It reads IPv6 addresses from /etc/hosts
+ - /etc/hosts reverse lookup for I2P .b32 names added
- debian directory included into source package.
- freebsd directory included into source package.
- acx_pthread.m4 replaced by newer ax_pthread.m4 for autoconf.
diff --git a/TODO b/TODO
index 05b8b24..6e33b61 100644
--- a/TODO
+++ b/TODO
@@ -1,3 +1,5 @@
+* Solaris: tunnel device should be unplumbed on program exit
+* Solaris TAP device untestet
* OpenBSD TAP device might not work (see OpenBSD man page tun(4))
* finish SOCKS5 code for I2P
* work on header compression (start at RFC2507 or 3095)
diff --git a/config.h.in b/config.h.in
index cf7ba80..02f79e8 100644
--- a/config.h.in
+++ b/config.h.in
@@ -12,18 +12,27 @@
/* Define to 1 if you have the <endian.h> header file. */
#undef HAVE_ENDIAN_H
+/* Do we have ether_header.ether_dhost.ether_addr_octet */
+#undef HAVE_ETHER_ADDR_OCTET
+
/* Define to 1 if you have the `ether_ntoa' function. */
#undef HAVE_ETHER_NTOA
/* Define to 1 if you have the `ether_ntoa_r' function. */
#undef HAVE_ETHER_NTOA_R
+/* Define to 1 if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
/* Define to 1 if you have the <linux/if_tun.h> header file. */
#undef HAVE_LINUX_IF_TUN_H
/* Define to 1 if you have the <linux/sockios.h> header file. */
#undef HAVE_LINUX_SOCKIOS_H
+/* Define to 1 if you have the <netdb.h> header file. */
+#undef HAVE_NETDB_H
+
/* Define to 1 if you have the <netinet/ether.h> header file. */
#undef HAVE_NETINET_ETHER_H
@@ -63,6 +72,12 @@
/* Do we have sockaddr_in.sin_len? */
#undef HAVE_SIN_LEN
+/* Do we have stat.st_mtim? */
+#undef HAVE_STAT_ST_MTIM
+
+/* Do we have stat.st_mtimespec? */
+#undef HAVE_STAT_ST_MTIMESPEC
+
/* Define to 1 if you have the `strlcat' function. */
#undef HAVE_STRLCAT
@@ -81,15 +96,24 @@
/* Define to 1 if you have the <sys/endian.h> header file. */
#undef HAVE_SYS_ENDIAN_H
+/* Define to 1 if you have the <sys/ethernet.h> header file. */
+#undef HAVE_SYS_ETHERNET_H
+
/* Define to 1 if you have the <sys/socket.h> header file. */
#undef HAVE_SYS_SOCKET_H
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <sys/wait.h> header file. */
#undef HAVE_SYS_WAIT_H
+/* Define to 1 if you have the <time.h> header file. */
+#undef HAVE_TIME_H
+
/* enable RTT measurement */
#undef MEASURE_RTT
@@ -127,5 +151,8 @@
/* Version number of package */
#undef VERSION
+/* exclude tunnel device code */
+#undef WITHOUT_TUN
+
/* Define to empty if `const' does not conform to ANSI C. */
#undef const
diff --git a/configure b/configure
index c243da4..f2c32aa 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.62 for onioncat 0.2.2.r546.
+# Generated by GNU Autoconf 2.62 for onioncat 0.2.2.r547.
#
# Report bugs to <rahra at cypherpunk.at>.
#
@@ -596,8 +596,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
# Identity of this package.
PACKAGE_NAME='onioncat'
PACKAGE_TARNAME='onioncat'
-PACKAGE_VERSION='0.2.2.r546'
-PACKAGE_STRING='onioncat 0.2.2.r546'
+PACKAGE_VERSION='0.2.2.r547'
+PACKAGE_STRING='onioncat 0.2.2.r547'
PACKAGE_BUGREPORT='rahra at cypherpunk.at'
ac_subst_vars='SHELL
@@ -699,6 +699,7 @@ enable_handle_http
enable_packet_queue
enable_check_ipsrc
enable_rtt
+enable_tundev
enable_dependency_tracking
'
ac_precious_vars='build_alias
@@ -1261,7 +1262,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures onioncat 0.2.2.r546 to adapt to many kinds of systems.
+\`configure' configures onioncat 0.2.2.r547 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1331,7 +1332,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of onioncat 0.2.2.r546:";;
+ short | recursive ) echo "Configuration of onioncat 0.2.2.r547:";;
esac
cat <<\_ACEOF
@@ -1345,6 +1346,7 @@ Optional Features:
--enable-packet-queue enable queueuing of packets while connecting setup
--disable-check-ipsrc disable source ip checking before forwarding
--enable-rtt enable inband RTT measurement
+ --disable-tundev compile without tunnel device code
--disable-dependency-tracking speeds up one-time build
--enable-dependency-tracking do not reject slow dependency extractors
@@ -1423,7 +1425,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-onioncat configure 0.2.2.r546
+onioncat configure 0.2.2.r547
generated by GNU Autoconf 2.62
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1437,7 +1439,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by onioncat $as_me 0.2.2.r546, which was
+It was created by onioncat $as_me 0.2.2.r547, which was
generated by GNU Autoconf 2.62. Invocation command line was
$ $0 $@
@@ -2086,7 +2088,7 @@ fi
# Define the identity of the package.
PACKAGE='onioncat'
- VERSION='0.2.2.r546'
+ VERSION='0.2.2.r547'
cat >>confdefs.h <<_ACEOF
@@ -2237,22 +2239,22 @@ ac_config_headers="$ac_config_headers config.h"
cat >>confdefs.h <<\_ACEOF
-#define SVN_REVISION "546"
+#define SVN_REVISION "547"
_ACEOF
-CFLAGS="-Wall -O2"
-
# Check whether --enable-debug was given.
if test "${enable_debug+set}" = set; then
enableval=$enable_debug;
cat >>confdefs.h <<\_ACEOF
-#define DEBUG /**/
+#define DEBUG 1
_ACEOF
+
fi
+
# Check whether --enable-packet-log was given.
if test "${enable_packet_log+set}" = set; then
enableval=$enable_packet_log;
@@ -2262,6 +2264,7 @@ _ACEOF
fi
+
# Check whether --enable-handle-http was given.
if test "${enable_handle_http+set}" = set; then
enableval=$enable_handle_http;
@@ -2271,6 +2274,7 @@ _ACEOF
fi
+
# Check whether --enable-packet-queue was given.
if test "${enable_packet_queue+set}" = set; then
enableval=$enable_packet_queue;
@@ -2280,25 +2284,46 @@ _ACEOF
fi
+
# Check whether --enable-check-ipsrc was given.
if test "${enable_check_ipsrc+set}" = set; then
enableval=$enable_check_ipsrc;
cat >>confdefs.h <<\_ACEOF
-#define CHECK_IPSRC /**/
+#define CHECK_IPSRC 1
_ACEOF
fi
+
# Check whether --enable-rtt was given.
if test "${enable_rtt+set}" = set; then
enableval=$enable_rtt;
cat >>confdefs.h <<\_ACEOF
-#define MEASURE_RTT /**/
+#define MEASURE_RTT 1
_ACEOF
fi
+# Check whether --enable-tundev was given.
+if test "${enable_tundev+set}" = set; then
+ enableval=$enable_tundev;
+cat >>confdefs.h <<\_ACEOF
+#define WITHOUT_TUN 1
+_ACEOF
+
+fi
+
+
+
+if test "${enable_debug+set}" = set ; then
+ CFLAGS="-Wall -g -D_POSIX_PTHREAD_SEMANTICS"
+
+else
+ CFLAGS="-Wall -O2 -D_POSIX_PTHREAD_SEMANTICS"
+
+fi
+
# Checks for programs.
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
@@ -4099,6 +4124,181 @@ CC="$PTHREAD_CC"
#AC_CHECK_LIB([rt], [clock_gettime])
#AC_CHECK_LIB([readline], [main])
+{ $as_echo "$as_me:$LINENO: checking for library containing bind" >&5
+$as_echo_n "checking for library containing bind... " >&6; }
+if test "${ac_cv_search_bind+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char bind ();
+int
+main ()
+{
+return bind ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' socket; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ ac_cv_search_bind=$ac_res
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext
+ if test "${ac_cv_search_bind+set}" = set; then
+ break
+fi
+done
+if test "${ac_cv_search_bind+set}" = set; then
+ :
+else
+ ac_cv_search_bind=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_search_bind" >&5
+$as_echo "$ac_cv_search_bind" >&6; }
+ac_res=$ac_cv_search_bind
+if test "$ac_res" != no; then
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+{ $as_echo "$as_me:$LINENO: checking for library containing inet_ntop" >&5
+$as_echo_n "checking for library containing inet_ntop... " >&6; }
+if test "${ac_cv_search_inet_ntop+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char inet_ntop ();
+int
+main ()
+{
+return inet_ntop ();
+ ;
+ return 0;
+}
+_ACEOF
+for ac_lib in '' nsl; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_link") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ $as_test_x conftest$ac_exeext
+ }; then
+ ac_cv_search_inet_ntop=$ac_res
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+ conftest$ac_exeext
+ if test "${ac_cv_search_inet_ntop+set}" = set; then
+ break
+fi
+done
+if test "${ac_cv_search_inet_ntop+set}" = set; then
+ :
+else
+ ac_cv_search_inet_ntop=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_search_inet_ntop" >&5
+$as_echo "$ac_cv_search_inet_ntop" >&6; }
+ac_res=$ac_cv_search_inet_ntop
+if test "$ac_res" != no; then
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+
+fi
+
+
# Checks for header files.
#AC_HEADER_STDC
@@ -4119,7 +4319,12 @@ CC="$PTHREAD_CC"
-for ac_header in sys/types.h sys/wait.h sys/socket.h netinet/in.h netinet/in_systm.h netinet/ip.h netinet/ip6.h netinet/in6.h net/if.h net/if_tun.h linux/if_tun.h linux/sockios.h endian.h sys/endian.h netinet/icmp6.h net/ethernet.h netinet/if_ether.h netinet/ether.h
+
+
+
+
+
+for ac_header in sys/types.h sys/wait.h sys/socket.h sys/stat.h netdb.h netinet/in.h netinet/in_systm.h netinet/ip.h netinet/ip6.h netinet/in6.h net/if.h net/if_tun.h linux/if_tun.h linux/sockios.h endian.h sys/endian.h netinet/icmp6.h net/ethernet.h netinet/if_ether.h netinet/ether.h sys/ethernet.h fcntl.h time.h
do
as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
{ $as_echo "$as_me:$LINENO: checking for $ac_header" >&5
@@ -4716,8 +4921,12 @@ cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
+#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
+#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
@@ -4763,8 +4972,12 @@ cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
+#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
+#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
@@ -4822,6 +5035,368 @@ _ACEOF
fi
+{ $as_echo "$as_me:$LINENO: checking for struct stat.st_mtim" >&5
+$as_echo_n "checking for struct stat.st_mtim... " >&6; }
+if test "${ac_cv_member_struct_stat_st_mtim+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+
+int
+main ()
+{
+static struct stat ac_aggr;
+if (ac_aggr.st_mtim)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_member_struct_stat_st_mtim=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+
+int
+main ()
+{
+static struct stat ac_aggr;
+if (sizeof ac_aggr.st_mtim)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_member_struct_stat_st_mtim=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_member_struct_stat_st_mtim=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_member_struct_stat_st_mtim" >&5
+$as_echo "$ac_cv_member_struct_stat_st_mtim" >&6; }
+if test $ac_cv_member_struct_stat_st_mtim = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_STAT_ST_MTIM 1
+_ACEOF
+
+else
+
+{ $as_echo "$as_me:$LINENO: checking for struct stat.st_mtimespec" >&5
+$as_echo_n "checking for struct stat.st_mtimespec... " >&6; }
+if test "${ac_cv_member_struct_stat_st_mtimespec+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+
+int
+main ()
+{
+static struct stat ac_aggr;
+if (ac_aggr.st_mtimespec)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_member_struct_stat_st_mtimespec=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+
+
+int
+main ()
+{
+static struct stat ac_aggr;
+if (sizeof ac_aggr.st_mtimespec)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_member_struct_stat_st_mtimespec=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_member_struct_stat_st_mtimespec=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_member_struct_stat_st_mtimespec" >&5
+$as_echo "$ac_cv_member_struct_stat_st_mtimespec" >&6; }
+if test $ac_cv_member_struct_stat_st_mtimespec = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_STAT_ST_MTIMESPEC 1
+_ACEOF
+
+fi
+
+
+fi
+
+
+{ $as_echo "$as_me:$LINENO: checking for struct ether_header.ether_dhost.ether_addr_octet" >&5
+$as_echo_n "checking for struct ether_header.ether_dhost.ether_addr_octet... " >&6; }
+if test "${ac_cv_member_struct_ether_header_ether_dhost_ether_addr_octet+set}" = set; then
+ $as_echo_n "(cached) " >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_ETHERNET_H
+#include <sys/ethernet.h>
+#endif
+
+
+int
+main ()
+{
+static struct ether_header ac_aggr;
+if (ac_aggr.ether_dhost.ether_addr_octet)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_member_struct_ether_header_ether_dhost_ether_addr_octet=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_ETHERNET_H
+#include <sys/ethernet.h>
+#endif
+
+
+int
+main ()
+{
+static struct ether_header ac_aggr;
+if (sizeof ac_aggr.ether_dhost.ether_addr_octet)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+ (eval "$ac_compile") 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then
+ ac_cv_member_struct_ether_header_ether_dhost_ether_addr_octet=yes
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_cv_member_struct_ether_header_ether_dhost_ether_addr_octet=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_member_struct_ether_header_ether_dhost_ether_addr_octet" >&5
+$as_echo "$ac_cv_member_struct_ether_header_ether_dhost_ether_addr_octet" >&6; }
+if test $ac_cv_member_struct_ether_header_ether_dhost_ether_addr_octet = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_ETHER_ADDR_OCTET 1
+_ACEOF
+
+fi
+
+
# Checks for library functions.
#AC_PROG_GCC_TRADITIONAL
#AC_FUNC_MALLOC
@@ -5369,7 +5944,7 @@ exec 6>&1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by onioncat $as_me 0.2.2.r546, which was
+This file was extended by onioncat $as_me 0.2.2.r547, which was
generated by GNU Autoconf 2.62. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -5422,7 +5997,7 @@ Report bugs to <bug-autoconf at gnu.org>."
_ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_version="\\
-onioncat config.status 0.2.2.r546
+onioncat config.status 0.2.2.r547
configured by $0, generated by GNU Autoconf 2.62,
with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
diff --git a/configure.ac b/configure.ac
index e6e2d49..0e9065f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -7,14 +7,35 @@ AC_CONFIG_HEADERS([config.h])
AC_DEFINE(SVN_REVISION, "svnversion", [SVN Revision])
-AC_SUBST([CFLAGS], [["-Wall -O2"]])
-AC_ARG_ENABLE([debug], AS_HELP_STRING([--enable-debug],[enable debugging]), AC_DEFINE([DEBUG], [], [enable debugging]))
-AC_ARG_ENABLE([packet-log], AS_HELP_STRING([--enable-packet-log],[enable packet logging]), AC_DEFINE([PACKET_LOG], [], [enable packet logging]))
-AC_ARG_ENABLE([handle-http], AS_HELP_STRING([--enable-handle-http],[enable handling of accidental HTTP requests]), AC_DEFINE([HANDLE_HTTP], [], [enable handling of accidental HTTP requests]))
-AC_ARG_ENABLE([packet-queue], AS_HELP_STRING([--enable-packet-queue],[enable queueuing of packets while connecting setup]), AC_DEFINE([PACKET_QUEUE], [], [enable packet queue]))
-AC_ARG_ENABLE([check-ipsrc], AS_HELP_STRING([--disable-check-ipsrc],[disable source ip checking before forwarding]), AC_DEFINE([CHECK_IPSRC], [], [disable source ip checking]))
-AC_ARG_ENABLE([rtt], AS_HELP_STRING([--enable-rtt],[enable inband RTT measurement]), AC_DEFINE([MEASURE_RTT], [], [enable RTT measurement]))
+AC_ARG_ENABLE([debug], AS_HELP_STRING([--enable-debug],[enable debugging]),
+ AC_DEFINE([DEBUG], [1], [enable debugging])
+ )
+
+AC_ARG_ENABLE([packet-log], AS_HELP_STRING([--enable-packet-log],[enable packet logging]),
+ AC_DEFINE([PACKET_LOG], [], [enable packet logging]))
+
+AC_ARG_ENABLE([handle-http], AS_HELP_STRING([--enable-handle-http],[enable handling of accidental HTTP requests]),
+ AC_DEFINE([HANDLE_HTTP], [], [enable handling of accidental HTTP requests]))
+
+AC_ARG_ENABLE([packet-queue], AS_HELP_STRING([--enable-packet-queue],[enable queueuing of packets while connecting setup]),
+ AC_DEFINE([PACKET_QUEUE], [], [enable packet queue]))
+
+AC_ARG_ENABLE([check-ipsrc], AS_HELP_STRING([--disable-check-ipsrc],[disable source ip checking before forwarding]),
+ AC_DEFINE([CHECK_IPSRC], [1], [disable source ip checking]))
+
+AC_ARG_ENABLE([rtt], AS_HELP_STRING([--enable-rtt],[enable inband RTT measurement]),
+ AC_DEFINE([MEASURE_RTT], [1], [enable RTT measurement]))
+
+AC_ARG_ENABLE([tundev], AS_HELP_STRING([--disable-tundev],[compile without tunnel device code]),
+ AC_DEFINE([WITHOUT_TUN], [1], [exclude tunnel device code]))
+
+
+if test "${enable_debug+set}" = set ; then
+ AC_SUBST([CFLAGS], [["-Wall -g -D_POSIX_PTHREAD_SEMANTICS"]])
+else
+ AC_SUBST([CFLAGS], [["-Wall -O2 -D_POSIX_PTHREAD_SEMANTICS"]])
+fi
# Checks for programs.
AC_PROG_CC
@@ -34,9 +55,12 @@ CC="$PTHREAD_CC"
#AC_CHECK_LIB([rt], [clock_gettime])
#AC_CHECK_LIB([readline], [main])
+AC_SEARCH_LIBS([bind], [socket])
+AC_SEARCH_LIBS([inet_ntop], [nsl])
+
# Checks for header files.
#AC_HEADER_STDC
-AC_CHECK_HEADERS([sys/types.h sys/wait.h sys/socket.h netinet/in.h netinet/in_systm.h netinet/ip.h netinet/ip6.h netinet/in6.h net/if.h net/if_tun.h linux/if_tun.h linux/sockios.h endian.h sys/endian.h netinet/icmp6.h net/ethernet.h netinet/if_ether.h netinet/ether.h], [], [],
+AC_CHECK_HEADERS([sys/types.h sys/wait.h sys/socket.h sys/stat.h netdb.h netinet/in.h netinet/in_systm.h netinet/ip.h netinet/ip6.h netinet/in6.h net/if.h net/if_tun.h linux/if_tun.h linux/sockios.h endian.h sys/endian.h netinet/icmp6.h net/ethernet.h netinet/if_ether.h netinet/ether.h sys/ethernet.h fcntl.h time.h], [], [],
[[
#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
@@ -116,13 +140,53 @@ AC_CHECK_MEMBER([struct sockaddr_in.sin_len],
[ AC_DEFINE(HAVE_SIN_LEN, 1, [Do we have sockaddr_in.sin_len?]) ],
[],
[
+#ifdef HAVE_SYS_TYPES_H
#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
+#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
])
+AC_CHECK_MEMBER([struct stat.st_mtim],
+ [AC_DEFINE(HAVE_STAT_ST_MTIM, 1, [Do we have stat.st_mtim?])],
+ [
+AC_CHECK_MEMBER([struct stat.st_mtimespec],
+ [AC_DEFINE(HAVE_STAT_ST_MTIMESPEC, 1, [Do we have stat.st_mtimespec?])],
+ [],
+ [
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+ ])
+ ],
+ [
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+ ])
+
+AC_CHECK_MEMBER([struct ether_header.ether_dhost.ether_addr_octet],
+ [AC_DEFINE(HAVE_ETHER_ADDR_OCTET, 1, [Do we have ether_header.ether_dhost.ether_addr_octet])],
+ [],
+ [
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_ETHERNET_H
+#include <sys/ethernet.h>
+#endif
+])
+
# Checks for library functions.
#AC_PROG_GCC_TRADITIONAL
#AC_FUNC_MALLOC
diff --git a/src/Makefile.am b/src/Makefile.am
index 7d21e59..2415d07 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,6 +1,6 @@
bin_PROGRAMS = ocat
-ocat_SOURCES = ocat.c ocatlog.c ocatroute.c ocatthread.c ocattun.c ocatv6conv.c ocatcompat.c ocatpeer.c ocatsetup.c ocatipv4route.c ocateth.c ocatsocks.c ocatlibe.c ocatctrl.c ocatipv6route.c ocaticmp.c ocat_wintuntap.c ocat_netdesc.c
-noinst_HEADERS = ocat.h ocat_netdesc.h strlcpy.c strlcat.c
+ocat_SOURCES = ocat.c ocatlog.c ocatroute.c ocatthread.c ocattun.c ocatv6conv.c ocatcompat.c ocatpeer.c ocatsetup.c ocatipv4route.c ocateth.c ocatsocks.c ocatlibe.c ocatctrl.c ocatipv6route.c ocaticmp.c ocat_wintuntap.c ocat_netdesc.c ocathosts.c
+noinst_HEADERS = ocat.h ocat_netdesc.h strlcpy.c strlcat.c ocathosts.h
AM_CFLAGS = -DSYSCONFDIR=\"$(sysconfdir)\"
install-exec-hook:
diff --git a/src/Makefile.in b/src/Makefile.in
index 427404f..8055335 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -58,7 +58,7 @@ am_ocat_OBJECTS = ocat.$(OBJEXT) ocatlog.$(OBJEXT) ocatroute.$(OBJEXT) \
ocatipv4route.$(OBJEXT) ocateth.$(OBJEXT) ocatsocks.$(OBJEXT) \
ocatlibe.$(OBJEXT) ocatctrl.$(OBJEXT) ocatipv6route.$(OBJEXT) \
ocaticmp.$(OBJEXT) ocat_wintuntap.$(OBJEXT) \
- ocat_netdesc.$(OBJEXT)
+ ocat_netdesc.$(OBJEXT) ocathosts.$(OBJEXT)
ocat_OBJECTS = $(am_ocat_OBJECTS)
ocat_LDADD = $(LDADD)
DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
@@ -163,8 +163,8 @@ sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
-ocat_SOURCES = ocat.c ocatlog.c ocatroute.c ocatthread.c ocattun.c ocatv6conv.c ocatcompat.c ocatpeer.c ocatsetup.c ocatipv4route.c ocateth.c ocatsocks.c ocatlibe.c ocatctrl.c ocatipv6route.c ocaticmp.c ocat_wintuntap.c ocat_netdesc.c
-noinst_HEADERS = ocat.h ocat_netdesc.h strlcpy.c strlcat.c
+ocat_SOURCES = ocat.c ocatlog.c ocatroute.c ocatthread.c ocattun.c ocatv6conv.c ocatcompat.c ocatpeer.c ocatsetup.c ocatipv4route.c ocateth.c ocatsocks.c ocatlibe.c ocatctrl.c ocatipv6route.c ocaticmp.c ocat_wintuntap.c ocat_netdesc.c ocathosts.c
+noinst_HEADERS = ocat.h ocat_netdesc.h strlcpy.c strlcat.c ocathosts.h
AM_CFLAGS = -DSYSCONFDIR=\"$(sysconfdir)\"
all: all-am
@@ -238,6 +238,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ocatcompat.Po at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ocatctrl.Po at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ocateth.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ocathosts.Po at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ocaticmp.Po at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ocatipv4route.Po at am__quote@
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/ocatipv6route.Po at am__quote@
diff --git a/src/ocat.c b/src/ocat.c
index 11fda8e..7578716 100644
--- a/src/ocat.c
+++ b/src/ocat.c
@@ -29,6 +29,7 @@ void usage(const char *s)
" -b daemonize (default = %d)\n"
" -B do not daemonize (default = %d)\n"
" -h display usage message\n"
+ " -H ignore /etc/hosts while in GarliCat mode\n"
" -C disable local controller interface\n"
" -d <n> set debug level to n, default = %d\n"
" -f <config_file> read config from config_file (default = %s)\n"
@@ -101,7 +102,7 @@ int mk_pid_file(void)
return -1;
}
- fprintf(f, "%d\n", getpid());
+ fprintf(f, "%d\n", (int) getpid());
fclose(f);
log_debug("pid_file %s created, pid = %d", CNF(pid_file), getpid());
@@ -299,7 +300,7 @@ void parse_opt_early(int argc, char *argv_orig[])
opterr = 0;
while ((c = getopt(argc, argv, "f:I")) != -1)
{
- log_debug("getopt(): c = %c, optind = %d, opterr = %d, optarg = \"%s\"", c, optind, opterr, optarg);
+ log_debug("getopt(): c = %c, optind = %d, opterr = %d, optarg = \"%s\"", c, optind, opterr, SSTR(optarg));
switch (c)
{
case 'f':
@@ -325,9 +326,9 @@ int parse_opt(int argc, char *argv[])
log_debug("parse_opt_early()");
opterr = 1;
optind = 1;
- while ((c = getopt(argc, argv, "f:IabBCd:hrRiopl:t:T:s:u:4L:P:")) != -1)
+ while ((c = getopt(argc, argv, "f:IabBCd:hHrRiopl:t:T:s:u:4L:P:")) != -1)
{
- log_debug("getopt(): c = %c, optind = %d, opterr = %d, optarg = \"%s\"", c, optind, opterr, optarg);
+ log_debug("getopt(): c = %c, optind = %d, opterr = %d, optarg = \"%s\"", c, optind, opterr, SSTR(optarg));
switch (c)
{
// those options are parsed in parse_opt_early()
@@ -363,6 +364,10 @@ int parse_opt(int argc, char *argv[])
usage(argv[0]);
exit(1);
+ case 'H':
+ CNF(hosts_lookup) = 0;
+ break;
+
case 'l':
add_listener(optarg);
break;
@@ -513,7 +518,7 @@ int main(int argc, char *argv[])
}
// copy onion-URL from command line
- log_debug("argv[%d] = \"%s\"", optind, argv[optind]);
+ log_debug("argv[%d] = \"%s\"", optind, SSTR(argv[optind]));
if (!CNF(rand_addr))
strncpy(CNF(onion_url), argv[optind], NDESC(name_size));
// ...or generate a random one
diff --git a/src/ocat.h b/src/ocat.h
index 089868e..29bfe25 100644
--- a/src/ocat.h
+++ b/src/ocat.h
@@ -18,7 +18,9 @@
#ifndef OCAT_H
#define OCAT_H
+#ifdef HAVE_CONFIG_H
#include "config.h"
+#endif
#include <stdio.h>
#include <stdlib.h>
@@ -55,6 +57,9 @@
#ifdef HAVE_SYS_WAIT_H
#include <sys/wait.h>
#endif
+#ifdef HAVE_SYS_ETHERNET_H
+#include <sys/ethernet.h>
+#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
@@ -103,6 +108,23 @@
#define ETHERTYPE_IPV6 0x86dd
#endif
+#ifndef ETHER_ADDR_LEN
+#ifdef ETHERADDRL
+#define ETHER_ADDR_LEN ETHERADDRL
+#endif
+#endif
+
+// At least on Solaris the Ethernet addresses are defined as struct containing
+// an array of bytes. This is different from most other OSes which define the
+// addresses directly as array.
+#ifdef HAVE_ETHER_ADDR_OCTET
+#define ether_dst ether_dhost.ether_addr_octet
+#define ether_src ether_shost.ether_addr_octet
+#else
+#define ether_dst ether_dhost
+#define ether_src ether_shost
+#endif
+
#define IP6HLEN sizeof(struct ip6_hdr)
//! Length of an .onion-URL (without ".onion" and '\0')
#define ONION_URL_LEN 16
@@ -226,6 +248,18 @@
#define SYSCONFDIR "/etc"
#endif
+// this macro returns a constains string if a buffer points to NULL.
+#define SSTR(x) (x != NULL ? x : "(nil)")
+
+// Solaris and the Windows OpenVPN tunnel driver do not send a 4 byte tunnel
+// header thus we adjust reads and writes.
+#if defined(__sun__) || defined(__CYGWIN__)
+#define BUF_OFF 4
+#else
+#define BUF_OFF 0
+#endif
+
+
struct OcatSetup
{
//! frame header of local OS in network byte order
@@ -305,6 +339,7 @@ struct OcatSetup
//! pipe filedescriptors for pid deletion process
int pid_fd[2];
int sig_usr1, clear_stats;
+ int hosts_lookup;
};
#ifdef PACKET_QUEUE
@@ -467,14 +502,16 @@ typedef struct OcatCtrlHdr
#ifndef WITHOUT_TUN
-#ifdef __FreeBSD__
-#define TUN_DEV "/dev/tun0"
-#elif __OpenBSD__
-#define TUN_DEV "/dev/tun0"
-#else
+#ifdef __sun__
+#define TUN_DEV "/dev/tun"
+#elif __linux__
#define TUN_DEV "/dev/net/tun"
+#else
+#define TUN_DEV "/dev/tun0"
#endif
extern char *tun_dev_;
+#else
+#define TUN_DEV "STDIO"
#endif
extern pthread_mutex_t thread_mutex_;
@@ -613,7 +650,13 @@ int win_open_tun(char *, int);
int win_close_tun(void);
int win_read_tun(char *, int);
int win_write_tun(const char *, int);
+#define tun_read(x,y,z) win_read_tun(y,z)
+#define tun_write(x,y,z) win_write_tun(y,z)
+#else
+#define tun_read(x,y,z) read(x,y,z)
+#define tun_write(x,y,z) write(x,y,z)
#endif
+
#endif
diff --git a/src/ocat_netdesc.h b/src/ocat_netdesc.h
index 27050ee..59cea41 100644
--- a/src/ocat_netdesc.h
+++ b/src/ocat_netdesc.h
@@ -52,10 +52,18 @@ extern const struct NetDesc netdesc_[2];
#define TOR_PREFIX {{{0xfd,0x87,0xd8,0x7e,0xeb,0x43,0,0,0,0,0,0,0,0,0,0}}}
#define TOR_PREFIX_LEN 48
#if BYTE_ORDER == LITTLE_ENDIAN
+#ifdef __sun__
+#define TOR_PREFIX4 {{{0x0000000a}}}
+#else
#define TOR_PREFIX4 {0x0000000a}
+#endif
#define TOR_PREFIX4_MASK 0x000000ff
#else
+#ifdef __sun__
+#define TOR_PREFIX4 {{{0x0a000000}}}
+#else
#define TOR_PREFIX4 {0x0a000000}
+#endif
#define TOR_PREFIX4_MASK 0xff000000
#endif
//! internal domain
diff --git a/src/ocatcompat.c b/src/ocatcompat.c
index ebdbfde..2979a15 100644
--- a/src/ocatcompat.c
+++ b/src/ocatcompat.c
@@ -15,7 +15,9 @@
* along with OnionCat. If not, see <http://www.gnu.org/licenses/>.
*/
+#ifdef HAVE_CONFIG_H
#include "config.h"
+#endif
#ifndef HAVE_STRLCAT
#include "strlcat.c"
diff --git a/src/ocateth.c b/src/ocateth.c
index f6c76f3..2c72137 100644
--- a/src/ocateth.c
+++ b/src/ocateth.c
@@ -252,10 +252,10 @@ int ndp_solicit(const struct in6_addr *src, const struct in6_addr *dst)
set_tunheader(buf, htonl(CNF(fhd_key[IPV6_KEY])));
// ethernet header
- ndp6->eth.ether_dhost[0] = 0x33;
- ndp6->eth.ether_dhost[1] = 0x33;
- memcpy(&ndp6->eth.ether_dhost[2], ((char*) &mcastd) + 12, 4);
- memcpy(ndp6->eth.ether_shost, CNF(ocat_hwaddr), ETHER_ADDR_LEN);
+ ndp6->eth.ether_dst[0] = 0x33;
+ ndp6->eth.ether_dst[1] = 0x33;
+ memcpy(&ndp6->eth.ether_dst[2], ((char*) &mcastd) + 12, 4);
+ memcpy(ndp6->eth.ether_src, CNF(ocat_hwaddr), ETHER_ADDR_LEN);
ndp6->eth.ether_type = htons(ETHERTYPE_IPV6);
// ipv6 header
@@ -275,7 +275,7 @@ int ndp_solicit(const struct in6_addr *src, const struct in6_addr *dst)
// icmpv6 ndp option
ohd->nd_opt_type = ND_OPT_SOURCE_LINKADDR;
ohd->nd_opt_len = 1;
- memcpy(ohd + 1, ndp6->eth.ether_shost, ETHER_ADDR_LEN);
+ memcpy(ohd + 1, ndp6->eth.ether_src, ETHER_ADDR_LEN);
// calculate checksum
ckb = malloc_ckbuf(&ndp6->ip6.ip6_src, &ndp6->ip6.ip6_dst, ntohs(ndp6->ip6.ip6_plen), IPPROTO_ICMPV6, &ndp6->icmp6);
@@ -310,12 +310,12 @@ int ndp_soladv(char *buf, int rlen)
char hw[20];
#endif
- if (ndp6->eth.ether_dhost[0] & 1)
+ if (ndp6->eth.ether_dst[0] & 1)
{
// check for right multicast destination on ethernet
- if (ndp6->eth.ether_dhost[2] != 0xff)
+ if (ndp6->eth.ether_dst[2] != 0xff)
{
- log_debug("ethernet multicast destination %s cannot be solicited node address", ether_ntoa_r((struct ether_addr*) ndp6->eth.ether_dhost, hw));
+ log_debug("ethernet multicast destination %s cannot be solicited node address", ether_ntoa_r((struct ether_addr*) ndp6->eth.ether_dst, hw));
return -1;
}
@@ -354,16 +354,16 @@ int ndp_soladv(char *buf, int rlen)
log_debug("generating response");
// add source MAC to table
- if (mac_set(&ndp6->ip6.ip6_src, ndp6->eth.ether_shost) == -1)
- if (mac_add_entry(ndp6->eth.ether_shost, &ndp6->ip6.ip6_src) == -1)
+ if (mac_set(&ndp6->ip6.ip6_src, ndp6->eth.ether_src) == -1)
+ if (mac_add_entry(ndp6->eth.ether_src, &ndp6->ip6.ip6_src) == -1)
{
log_msg(LOG_ERR, "MAC table full");
return -1;
}
// set MAC addresses for response
- memcpy(ndp6->eth.ether_dhost, ndp6->eth.ether_shost, ETHER_ADDR_LEN);
- memcpy(ndp6->eth.ether_shost, CNF(ocat_hwaddr), ETHER_ADDR_LEN);
+ memcpy(ndp6->eth.ether_dst, ndp6->eth.ether_src, ETHER_ADDR_LEN);
+ memcpy(ndp6->eth.ether_src, CNF(ocat_hwaddr), ETHER_ADDR_LEN);
// init ip6 header
memcpy(&ndp6->ip6.ip6_dst, &ndp6->ip6.ip6_src, sizeof(struct in6_addr));
@@ -405,8 +405,8 @@ int ndp_recadv(char *buf, int len)
ndp6_t *ndp6 = (ndp6_t*) (buf + 4);
// add source MAC to table
- if (mac_set(&ndp6->ip6.ip6_src, ndp6->eth.ether_shost) == -1)
- if (mac_add_entry(ndp6->eth.ether_shost, &ndp6->ip6.ip6_src) == -1)
+ if (mac_set(&ndp6->ip6.ip6_src, ndp6->eth.ether_src) == -1)
+ if (mac_add_entry(ndp6->eth.ether_src, &ndp6->ip6.ip6_src) == -1)
{
log_msg(LOG_ERR, "MAC table full");
return -1;
@@ -449,7 +449,7 @@ int eth_check(char *buf, int len)
}
// check ethernet destination
- if ((ndp6->eth.ether_dhost[0] != 0x33) && (ndp6->eth.ether_dhost[1] != 0x33) && memcmp(ndp6->eth.ether_dhost, CNF(ocat_hwaddr), ETHER_ADDR_LEN))
+ if ((ndp6->eth.ether_dst[0] != 0x33) && (ndp6->eth.ether_dst[1] != 0x33) && memcmp(ndp6->eth.ether_dst, CNF(ocat_hwaddr), ETHER_ADDR_LEN))
{
log_debug("unknown destination MAC");
return E_ETH_ILLDEST;
diff --git a/src/ocatfdbuf.c b/src/ocatfdbuf.c
index a5244dd..7ca3e78 100644
--- a/src/ocatfdbuf.c
+++ b/src/ocatfdbuf.c
@@ -29,8 +29,9 @@
* it must be freed again with fdf_free().
* @param fd File descriptor if open file.
* @param delim Delimiting character.
- * @return Pointer to fdFile_t structure.
- */
+ * @return Pointer to fdFile_t structure or NULL in case of error.
+ * In the latter case errno is set appropriately.
+ **/
fdFile_t* fdf_init(int fd, char delim)
{
fdFile_t *fdf;
diff --git a/src/ocathosts.c b/src/ocathosts.c
new file mode 100644
index 0000000..fc94447
--- /dev/null
+++ b/src/ocathosts.c
@@ -0,0 +1,271 @@
+/* Copyright 2008-2010 Bernhard R. Fischer.
+ *
+ * This file is part of OnionCat.
+ *
+ * OnionCat is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, version 3 of the License.
+ *
+ * OnionCat is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with OnionCat. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+// For testing compile this file with
+// gcc -DINC_MAIN -Wall -DHAVE_CONFIG_H -I.. -o ocathosts -lpthread ocathosts.c strlcpy.c
+#ifndef INC_MAIN
+#include "ocat.h"
+#else
+#define log_msg(x,y...) fprintf(stderr, ## y),fprintf(stderr, "\n")
+#define log_debug(x...) log_msg(LOG_DEBUG, ## x)
+#endif
+#include "ocathosts.h"
+
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <pthread.h>
+#include <errno.h>
+
+#ifdef HAVE_TIME_H
+#include <time.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_SYS_STAT_H
+#include <sys/stat.h>
+#endif
+#ifdef HAVE_SYS_SOCKET_H
+#include <sys/socket.h>
+#endif
+#ifdef HAVE_FCNTL_H
+#include <fcntl.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+
+static struct hosts_info hosts_ = {{0, 0}, -1, NULL, 0, ""};
+static char *path_hosts_ = NULL;
+static pthread_mutex_t hosts_mutex_ = PTHREAD_MUTEX_INITIALIZER;
+
+
+/*! Test if modification time changed.
+ * @param fd File descriptor of file to test;
+ * @param ts Pointer to buffer of old timespec.
+ * @return 0 if nothing changed, -1 on error (i.e. file
+ * might have changed) and 1 if mtime changed. In the latter case
+ * ts will be updated.
+ **/
+int hosts_file_modified_r(struct timespec *ts)
+{
+ struct stat st;
+
+ log_debug("checking if file \"%s\" was modified", path_hosts_);
+ if (stat(path_hosts_, &st) == -1)
+ {
+ log_debug("stat on \"%s\" failed: \"%s\"", path_hosts_, strerror(errno));
+ return -1;
+ }
+
+#ifdef HAVE_STAT_ST_MTIM
+ if ((st.st_mtim.tv_sec == ts->tv_sec) && (st.st_mtim.tv_nsec == ts->tv_nsec))
+#elif HAVE_STAT_ST_MTIMESPEC
+ if ((st.st_mtimespec.tv_sec == ts->tv_sec) && (st.st_mtimespec.tv_nsec == ts->tv_nsec))
+#else
+ if (st.st_mtime == ts->tv_sec)
+#endif
+ return 0;
+
+ log_debug("%s modified", path_hosts_);
+#ifdef HAVE_STAT_ST_MTIM
+ *ts = st.st_mtim;
+#elif HAVE_STAT_ST_MTIMESPEC
+ *ts = st.st_mtimespec;
+#else
+ ts.tv_sec = st.st_mtime;
+#endif
+ return 1;
+}
+
+
+int hosts_read(struct hosts_ent **hent)
+{
+ int e, n = 0, c;
+ char buf[HOSTS_LINE_LENGTH + 1], *s;
+ struct addrinfo hints, *res;
+ struct hosts_ent *h;
+ FILE *f;
+
+ if ((f = fopen(path_hosts_, "r")) == NULL)
+ {
+ log_debug("fopen(\"%s\"...) failed: \"%s\"", path_hosts_, strerror(errno));
+ return -1;
+ }
+
+ pthread_mutex_lock(&hosts_mutex_);
+ if (*hent)
+ {
+ free(*hent);
+ *hent = NULL;
+ }
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_INET6;
+ hints.ai_flags = AI_NUMERICHOST;
+ while (fgets(buf, HOSTS_LINE_LENGTH, f) != NULL)
+ {
+ if ((s = strtok(buf, " \t\r\n")) == NULL)
+ continue;
+
+ // skip comments
+ if (s[0] == '#')
+ continue;
+
+ if ((e = getaddrinfo(s, NULL, &hints, &res)) != 0)
+ {
+ log_debug("getaddrinfo(\"%s\"...) failed: \"%s\"", s, gai_strerror(e));
+ continue;
+ }
+
+ // to be on the safe side check address family
+ if (res->ai_family != AF_INET6)
+ {
+ // this should never happen
+ log_debug("ai_family = %d (!= AF_INET6)", res->ai_family);
+ freeaddrinfo(res);
+ continue;
+ }
+
+ // parse all hostnames behind IPv6 address
+ for (c = 0; (s = strtok(NULL, " \t\r\n")); c++)
+ {
+ // copy hostname if it ends with "${hdom_}"
+ if ((strlen(s) > strlen(hosts_.hdom)) && !strcasecmp(s + (strlen(s) - strlen(hosts_.hdom)), hosts_.hdom))
+ {
+ if ((*hent = realloc(*hent, ++n * sizeof(struct hosts_ent))) == NULL)
+ {
+ log_msg(LOG_ERR, "realloc failed: \"%s\"", strerror(errno));
+ n--;
+ break;
+ }
+
+ h = (*hent) + n - 1;
+ h->addr = ((struct sockaddr_in6*) res->ai_addr)->sin6_addr;
+ strlcpy(h->name, s, NI_MAXHOST);
+ break;
+ }
+ }
+ freeaddrinfo(res);
+ }
+
+ pthread_mutex_unlock(&hosts_mutex_);
+ (void) fclose(f);
+
+ log_debug("found %d valid IPv6 records in %s", n, path_hosts_);
+
+ return n;
+}
+
+
+/*! Open hosts file and read IPv6 records.
+ * @return -1 on error and 0 on success.
+ */
+int hosts_check(void)
+{
+#ifdef __CYGWIN__
+ static char path_hosts[1024] = {'\0'};
+ char *s;
+#endif
+
+ if (path_hosts_ == NULL)
+ {
+#ifdef __CYGWIN__
+ if ((s = getenv("WINDIR")) != NULL)
+ {
+ snprintf(path_hosts, sizeof(path_hosts), "%s\\system32\\drivers\\etc\\hosts", s);
+ path_hosts_ = path_hosts;
+ }
+#else
+ path_hosts_ = _PATH_HOSTS;
+#endif
+ }
+
+ if (hosts_file_modified_r(&hosts_.hosts_ts))
+ hosts_.hosts_ent_cnt = hosts_read(&hosts_.hosts_ent);
+
+ return 0;
+}
+
+
+/*! Return name for IPv6 address.
+ * @return 0 on success, -1 on error.
+ **/
+int hosts_get_name(const struct in6_addr *addr, char *buf, int s)
+{
+ int i;
+ struct hosts_ent *h;
+
+ log_debug("looking up name");
+ pthread_mutex_lock(&hosts_mutex_);
+ for (i = hosts_.hosts_ent_cnt - 1, h = hosts_.hosts_ent; i >= 0; i--, h++)
+ if (IN6_ARE_ADDR_EQUAL(addr, &h->addr))
+ {
+ strlcpy(buf, h->name, s);
+ log_debug("name \"%s\" found", buf);
+ break;
+ }
+ pthread_mutex_unlock(&hosts_mutex_);
+
+ if (i < 0)
+ return -1;
+
+ return 0;
+}
+
+
+void hosts_init(const char *dom)
+{
+ hosts_.hdom = dom;
+}
+
+
+#ifdef INC_MAIN
+int main()
+{
+ int i;
+ struct hosts_ent *h;
+ struct in6_addr addr = IN6ADDR_LOOPBACK_INIT;
+ char buf[NI_MAXHOST];
+
+ hosts_init(".b32.i2p");
+ hosts_check();
+
+ h = hosts_.hosts_ent;
+ for (i = 0; i < hosts_.hosts_ent_cnt; i++, h++)
+ {
+ printf("%s\n", h->name);
+ }
+
+ if (!hosts_get_name(&addr, buf, NI_MAXHOST))
+ printf("loopname = \"%s\"\n", buf);
+
+ return 0;
+}
+#endif
+
diff --git a/src/ocatcompat.c b/src/ocathosts.h
similarity index 50%
copy from src/ocatcompat.c
copy to src/ocathosts.h
index ebdbfde..20e6323 100644
--- a/src/ocatcompat.c
+++ b/src/ocathosts.h
@@ -1,4 +1,4 @@
-/* Copyright 2008 Bernhard R. Fischer, Daniel Haslinger.
+/* Copyright 2008-2010 Bernhard R. Fischer.
*
* This file is part of OnionCat.
*
@@ -15,12 +15,43 @@
* along with OnionCat. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "config.h"
+#ifndef OCATHOSTS_H
+#define OCATHOSTS_H
-#ifndef HAVE_STRLCAT
-#include "strlcat.c"
+#ifdef HAVE_TIME_H
+#include <time.h>
#endif
-#ifndef HAVE_STRLCPY
-#include "strlcpy.c"
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+#ifdef HAVE_NETINET_IN_H
+#include <netinet/in.h>
+#endif
+
+
+#define HOSTS_LINE_LENGTH 1024
+
+struct hosts_ent
+{
+ struct in6_addr addr;
+ char name[NI_MAXHOST];
+};
+
+struct hosts_info
+{
+ struct timespec hosts_ts;
+ int hosts_fd;
+ struct hosts_ent *hosts_ent;
+ int hosts_ent_cnt;
+ const char *hdom;
+};
+
+int hosts_check(void);
+int hosts_get_name(const struct in6_addr*, char*, int);
+void hosts_init(const char*);
+
#endif
diff --git a/src/ocatroute.c b/src/ocatroute.c
index c347a82..7d00d4f 100644
--- a/src/ocatroute.c
+++ b/src/ocatroute.c
@@ -507,9 +507,9 @@ void *socket_receiver(void *p)
// write directly on TUN device
if (!CNF(use_tap))
{
- log_debug("writing to tun %d framesize %d + 4", CNF(tunfd[1]), len);
- if (write(CNF(tunfd[1]), peer->tunhdr, len + 4) != (len + 4))
- log_msg(LOG_ERR, "could not write %d bytes to tunnel %d", len + 4, CNF(tunfd[1]));
+ log_debug("writing to tun %d framesize %d + %d", CNF(tunfd[1]), len, 4 - BUF_OFF);
+ if (tun_write(CNF(tunfd[1]), ((char*) peer->tunhdr) + BUF_OFF, len + 4 - BUF_OFF) != (len + 4 - BUF_OFF))
+ log_msg(LOG_ERR, "could not write %d bytes to tunnel %d", len + 4 - BUF_OFF, CNF(tunfd[1]));
}
// create ethernet header and handle MAC on TAP device
else if (*peer->tunhdr == CNF(fhd_key[IPV6_KEY]))
@@ -517,8 +517,8 @@ void *socket_receiver(void *p)
log_debug("creating ethernet header");
// FIXME: should differentiate between IPv6 and IP!!
- memset(eh->ether_dhost, 0, ETHER_ADDR_LEN);
- if (mac_set(&((struct ip6_hdr*)peer->fragbuf)->ip6_dst, eh->ether_dhost) == -1)
+ memset(eh->ether_dst, 0, ETHER_ADDR_LEN);
+ if (mac_set(&((struct ip6_hdr*)peer->fragbuf)->ip6_dst, eh->ether_dst) == -1)
{
log_debug("dest MAC unknown, resolving");
ndp_solicit(&((struct ip6_hdr*)peer->fragbuf)->ip6_src, &((struct ip6_hdr*)peer->fragbuf)->ip6_dst);
@@ -527,20 +527,15 @@ void *socket_receiver(void *p)
{
set_tunheader(buf, *peer->tunhdr);
memcpy(buf + 4 + sizeof(struct ether_header), peer->fragbuf, len);
- memcpy(eh->ether_shost, CNF(ocat_hwaddr), ETHER_ADDR_LEN);
+ memcpy(eh->ether_src, CNF(ocat_hwaddr), ETHER_ADDR_LEN);
if (*peer->tunhdr == CNF(fhd_key[IPV6_KEY]))
eh->ether_type = htons(ETHERTYPE_IPV6);
else if (*peer->tunhdr == CNF(fhd_key[IPV4_KEY]))
eh->ether_type = htons(ETHERTYPE_IP);
-#ifdef __CYGWIN__
- if (win_write_tun(buf + 4, len + sizeof(struct ether_header)) != (len + sizeof(struct ether_header)))
- log_msg(LOG_ERR, "could not write %d bytes to WinTAP", len + sizeof(struct ether_header));
-#else
- if (write(CNF(tunfd[1]), buf, len + 4 + sizeof(struct ether_header)) != (len + 4 + sizeof(struct ether_header)))
- log_msg(LOG_ERR, "could not write %d bytes to tunnel %d", len + 4 + sizeof(struct ether_header), CNF(tunfd[1]));
-#endif
+ if (tun_write(CNF(tunfd[1]), buf + BUF_OFF, len + 4 + sizeof(struct ether_header) - BUF_OFF) != (len + 4 + sizeof(struct ether_header) - BUF_OFF))
+ log_msg(LOG_ERR, "could not write %d bytes to tunnel %d", len + 4 + sizeof(struct ether_header) - BUF_OFF, CNF(tunfd[1]));
}
}
else
@@ -811,21 +806,12 @@ void packet_forwarder(void)
if (term_req())
break;
-#ifdef __CYGWIN__
- log_debug("reading from WinTAP");
- if ((rlen = win_read_tun(buf + 4, FRAME_SIZE - 4)) == -1)
- {
- log_debug("win_read_tun failed. restarting");
- continue;
- }
- rlen += 4;
-#else
#ifdef __OpenBSD__
// workaround for OpenBSD userland threads
fcntl(CNF(tunfd[0]), F_SETFL, fcntl(CNF(tunfd[0]), F_GETFL) & ~O_NONBLOCK);
#endif
log_debug("reading from tunfd[0] = %d", CNF(tunfd[0]));
- if ((rlen = read(CNF(tunfd[0]), buf, FRAME_SIZE)) == -1)
+ if ((rlen = tun_read(CNF(tunfd[0]), buf + BUF_OFF, FRAME_SIZE - BUF_OFF)) == -1)
{
rlen = errno;
log_debug("read from tun %d returned on error: \"%s\"", CNF(tunfd[0]), strerror(rlen));
@@ -849,9 +835,9 @@ void packet_forwarder(void)
log_debug("restarting");
continue;
}
-#endif
+ rlen += BUF_OFF;
- log_debug("received on tunfd %d, framesize %d + 4", CNF(tunfd[0]), rlen - 4);
+ log_debug("received on tunfd %d, framesize %d + %d", CNF(tunfd[0]), rlen - 4, 4 - BUF_OFF);
#ifdef PACKET_LOG
if ((pktlog != -1) && (write(pktlog, buf, rlen) == -1))
@@ -877,6 +863,17 @@ void packet_forwarder(void)
memmove(eh, eh + 1, rlen - 4);
}
+#if defined(__sun__) || defined(__CYGWIN__)
+ // Solaris tunnel driver does not send tunnel
+ // header thus we guess and set it manually
+ if ((buf[BUF_OFF] & 0xf0) == 0x60)
+ set_tunheader(buf, CNF(fhd_key[IPV6_KEY]));
+ else if ((buf[BUF_OFF] & 0xf0) == 0x40)
+ set_tunheader(buf, CNF(fhd_key[IPV4_KEY]));
+ else
+ set_tunheader(buf, -1);
+#endif
+
if (get_tunheader(buf) == CNF(fhd_key[IPV6_KEY]))
{
if (((rlen - 4) < IP6HLEN))
diff --git a/src/ocatsetup.c b/src/ocatsetup.c
index a632e8a..0719c47 100644
--- a/src/ocatsetup.c
+++ b/src/ocatsetup.c
@@ -25,15 +25,17 @@
#include "ocat.h"
#include "ocat_netdesc.h"
+#include "ocathosts.h"
static struct sockaddr_in6 socks_dst6_;
static struct sockaddr_in ctrl_listen_;
static struct sockaddr_in6 ctrl_listen6_;
static struct sockaddr *ctrl_listen_ptr_[] =
- {(struct sockaddr*) &ctrl_listen_,
+{
+ (struct sockaddr*) &ctrl_listen_,
#ifndef __CYGWIN__
- (struct sockaddr*) &ctrl_listen6_,
+ (struct sockaddr*) &ctrl_listen6_,
#endif
NULL};
static int ctrl_fd_[2] = {-1, -1};
@@ -104,7 +106,7 @@ struct OcatSetup setup_ =
// oc_listen_fd
ctrl_fd_,
// oc_listen_cnt
-#ifdef __CYGWIN__
+#if defined(__CYGWIN__)
1
#else
2
@@ -119,7 +121,9 @@ struct OcatSetup setup_ =
// pid_fd
{-1, -1},
// sig_usr1, clear_stats
- 0, 0
+ 0, 0,
+ // hosts_lookup
+ 1
};
@@ -129,6 +133,7 @@ struct OcatSetup setup_ =
void init_setup(void)
{
struct timeval tv;
+ const uint32_t loop_ = htonl(INADDR_LOOPBACK);
// seeding PRNG rand()
if (gettimeofday(&tv, NULL) == -1)
@@ -139,16 +144,32 @@ void init_setup(void)
setup_.uptime = time(NULL);
memset(&socks_dst6_, 0, sizeof(socks_dst6_));
setup_.socks_dst->sin_family = AF_INET;
- setup_.socks_dst->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ //setup_.socks_dst->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ memcpy(&setup_.socks_dst->sin_addr, &loop_, sizeof(setup_.socks_dst->sin_addr));
#ifdef HAVE_SIN_LEN
setup_.socks_dst->sin_len = SOCKADDR_SIZE(setup_.socks_dst);
#endif
+
+ memset(&ctrl_listen_, 0, sizeof(ctrl_listen_));
+ memset(&ctrl_listen6_, 0, sizeof(ctrl_listen6_));
+
+ hosts_init(".b32.i2p");
+
+#ifdef __linux__
+ CNF(fhd_key[IPV6_KEY]) = htonl(ETHERTYPE_IPV6);
+ CNF(fhd_key[IPV4_KEY]) = htonl(ETHERTYPE_IP);
+#else
+ CNF(fhd_key[IPV6_KEY]) = htonl(AF_INET6);
+ CNF(fhd_key[IPV4_KEY]) = htonl(AF_INET);
+#endif
}
void post_init_setup(void)
{
size_t l;
+ const uint32_t loop_ = htonl(INADDR_LOOPBACK);
+
setup_.ocat_addr4 = NDESC(prefix4);
setup_.ocat_addr4_mask = NDESC(addr4_mask);
setup_.ocat_dest_port = NDESC(vdest_port);
@@ -165,7 +186,8 @@ void post_init_setup(void)
ctrl_listen_.sin_family = AF_INET;
ctrl_listen_.sin_port = htons(setup_.ocat_ctrl_port);
- ctrl_listen_.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ //ctrl_listen_.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+ memcpy(&ctrl_listen_.sin_addr, &loop_, sizeof(ctrl_listen_.sin_addr));
#ifdef HAVE_SIN_LEN
ctrl_listen_.sin_len = sizeof(ctrl_listen_);
#endif
@@ -247,6 +269,8 @@ void print_setup_struct(FILE *f)
"ctrl_active = %d\n"
"pid_fd[2] = {%d, %d}\n"
"clear_stats = %d\n"
+ "ctrl_listen_cnt = %d\n"
+ "hosts_lookup = %d\n"
,
IPV4_KEY, ntohl(setup_.fhd_key[IPV4_KEY]), IPV6_KEY, ntohl(setup_.fhd_key[IPV6_KEY]),
setup_.fhd_key_len,
@@ -273,7 +297,7 @@ void print_setup_struct(FILE *f)
setup_.use_tap,
hw,
setup_.pid_file,
- setup_.logfn,
+ SSTR(setup_.logfn),
logf,
setup_.daemon,
t / (3600 * 24), t / 3600 % 24, t / 60 % 60,
@@ -283,7 +307,9 @@ void print_setup_struct(FILE *f)
setup_.net_type, setup_.net_type == NTYPE_TOR ? "NTYPE_TOR" : setup_.net_type == NTYPE_I2P ? "NTYPE_I2P" : "unknown",
setup_.max_ctrl, setup_.ctrl_active,
setup_.pid_fd[0], setup_.pid_fd[1],
- setup_.clear_stats
+ setup_.clear_stats,
+ setup_.ctrl_listen_cnt,
+ setup_.hosts_lookup
);
#ifdef CONNECT_ROOT_PEERS
@@ -314,6 +340,14 @@ void print_setup_struct(FILE *f)
log_msg(LOG_WARNING, "could not convert struct sockaddr: \"%s\"", strerror(errno));
fprintf(f, "oc_listen_fd[%d] = %d\n", i, CNF(oc_listen_fd)[i]);
}
+
+ for (i = 0; i < CNF(ctrl_listen_cnt); i++)
+ {
+ if (inet_ntops(ctrl_listen_ptr_[i], &sas))
+ fprintf(f, "ctrl_listen_ptr_[%d] = %s:%d (0x%04x)\n", i, sas.sstr_addr, ntohs(sas.sstr_port), sas.sstr_family);
+ else
+ log_msg(LOG_WARNING, "could not convert struct sockaddr: \"%s\"", strerror(errno));
+ }
}
diff --git a/src/ocatsocks.c b/src/ocatsocks.c
index 3a8f56c..1ff0fc9 100644
--- a/src/ocatsocks.c
+++ b/src/ocatsocks.c
@@ -26,6 +26,7 @@
#include "ocat.h"
#include "ocat_netdesc.h"
+#include "ocathosts.h"
// SOCKS connector queue vars
@@ -36,13 +37,33 @@ static SocksQueue_t *socks_queue_ = NULL;
int socks_send_request(const SocksQueue_t *sq)
{
- int len, ret;
- char buf[SOCKS_BUFLEN], onion[NDESC(name_size)];
+ int len, ret = -1;
+ char buf[SOCKS_BUFLEN], onion[NI_MAXHOST];
SocksHdr_t *shdr = (SocksHdr_t*) buf;
- ipv6tonion(&sq->addr, onion);
- strlcat(onion, NDESC(domain), sizeof(onion));
- log_msg(LOG_INFO, "trying to connect to \"%s\" [%s]", onion, inet_ntop(AF_INET6, &sq->addr, buf, SOCKS_BUFLEN));
+ // Do a hostname lookup if network type is I2P.
+ // This is done in order to be able to retrieve a 256 bit base32
+ // host from e.g. /etc/hosts.
+ if ((CNF(net_type) == NTYPE_I2P) && CNF(hosts_lookup))
+ {
+ hosts_check();
+ ret = hosts_get_name(&sq->addr, onion, sizeof(onion));
+ }
+
+ // If no hostname was found above or network type is Tor
+ // do usual OnionCat name transformation.
+ if (ret == -1)
+ {
+ ipv6tonion(&sq->addr, onion);
+ strlcat(onion, NDESC(domain), sizeof(onion));
+ }
+
+ if (inet_ntop(AF_INET6, &sq->addr, buf, sizeof(buf)) == NULL)
+ {
+ log_msg(LOG_WARNING, "inet_ntop failed: \"%s\"", strerror(errno));
+ buf[0] = '\0';
+ }
+ log_msg(LOG_INFO, "trying to connect to \"%s\" [%s] on %d", onion, buf, sq->fd);
log_debug("doing SOCKS4a handshake");
shdr->ver = 4;
diff --git a/src/ocattun.c b/src/ocattun.c
index 6869fcd..509c68b 100644
--- a/src/ocattun.c
+++ b/src/ocattun.c
@@ -22,28 +22,44 @@
* @version 2008/02/03-01
*/
-#ifndef WITHOUT_TUN
#include "ocat.h"
#include "ocat_netdesc.h"
+#ifndef WITHOUT_TUN
char *tun_dev_ = TUN_DEV;
#define IFCBUF 1024
+
+void system_w(const char *s)
+{
+ int e;
+
+ log_debug("running command \"%s\"", s);
+ if ((e = system(s)) == -1)
+ log_msg(LOG_ERR, "could not exec \"%s\": \"%s\"", s, strerror(errno));
+ log_debug("exit status = %d", WEXITSTATUS(e));
+}
+
+
int tun_alloc(char *dev, int dev_s, struct in6_addr addr)
{
#ifdef __linux__
struct ifreq ifr;
#endif
+#ifdef __sun__
+ int ppa = -1;
+#endif
int fd;
char astr[INET6_ADDRSTRLEN];
char astr4[INET_ADDRSTRLEN];
char buf[IFCBUF];
- struct in_addr netmask = {CNF(ocat_addr4_mask)};
+ struct in_addr netmask;// = {CNF(ocat_addr4_mask)};
+ memcpy(&netmask, &CNF(ocat_addr4_mask), sizeof(netmask));
inet_ntop(AF_INET6, &addr, astr, INET6_ADDRSTRLEN);
inet_ntop(AF_INET, &CNF(ocat_addr4), astr4, INET_ADDRSTRLEN);
@@ -57,14 +73,10 @@ int tun_alloc(char *dev, int dev_s, struct in6_addr addr)
// 183 // % netsh interface ipv6 add route fd87:d87e:eb43::/48 "LAN-Verbindung 2"
snprintf(buf, sizeof(buf), "netsh interface ipv6 add address \"%s\" %s", dev, astr);
- log_debug("setting IP on tun: \"%s\"", buf);
- if (system(buf) == -1)
- log_msg(LOG_ERR, "could not exec \"%s\": \"%s\"", buf, strerror(errno));
+ system_w(buf);
snprintf(buf, sizeof(buf), "netsh interface ipv6 add route %s/%d \"%s\"", astr, NDESC(prefix_len), dev);
- log_debug("setting IP routing: \"%s\"", buf);
- if (system(buf) == -1)
- log_msg(LOG_ERR, "could not exec \"%s\": \"%s\"", buf, strerror(errno));
+ system_w(buf);
return 0;
#endif
@@ -93,9 +105,7 @@ int tun_alloc(char *dev, int dev_s, struct in6_addr addr)
if (!CNF(use_tap))
{
snprintf(buf, sizeof(buf), "ifconfig %s add %s/%d up", dev, astr, NDESC(prefix_len));
- log_msg(LOG_INFO, "configuring tun IP: \"%s\"", buf);
- if (system(buf) == -1)
- log_msg(LOG_ERR, "could not exec \"%s\": \"%s\"", buf, strerror(errno));
+ system_w(buf);
}
// according to drivers/net/tun.c only IFF_MULTICAST and IFF_PROMISC are supported.
@@ -104,16 +114,8 @@ int tun_alloc(char *dev, int dev_s, struct in6_addr addr)
log_msg(LOG_ERR, "could not set interface flags: \"%s\"", strerror(errno));
*/
- // set tun frame header to ethertype IPv6
- CNF(fhd_key[IPV6_KEY]) = htonl(ETHERTYPE_IPV6);
- CNF(fhd_key[IPV4_KEY]) = htonl(ETHERTYPE_IP);
-
#else
- // set tun frame header to address family AF_INET6 (FreeBSD = 0x1c, OpenBSD = 0x18)
- CNF(fhd_key[IPV6_KEY]) = htonl(AF_INET6);
- CNF(fhd_key[IPV4_KEY]) = htonl(AF_INET);
-
// get interface name
if (!CNF(use_tap))
{
@@ -165,27 +167,36 @@ int tun_alloc(char *dev, int dev_s, struct in6_addr addr)
#endif /* __linux__ */
+#ifdef __sun__
+ if( (ppa = ioctl(fd, TUNNEWPPA, ppa)) == -1)
+ log_msg(LOG_ERR, "Can't assign new interface");
+ else
+ snprintf(dev, dev_s, "%s%d", dev, ppa);
+
+#endif
if (!CNF(use_tap))
{
#ifdef __OpenBSD__
snprintf(buf, sizeof(buf), "ifconfig %s inet6 %s prefixlen %d up", dev, astr, NDESC(prefix_len));
+#elif __sun__
+ snprintf(buf, sizeof(buf), "ifconfig %s inet6 plumb %s/%d %s up", dev, astr, NDESC(prefix_len), astr);
#else
snprintf(buf, sizeof(buf), "ifconfig %s inet6 %s/%d up", dev, astr, NDESC(prefix_len));
#endif
- log_debug("setting IP on tun: \"%s\"", buf);
- if (system(buf) == -1)
- log_msg(LOG_ERR, "could not exec \"%s\": \"%s\"", buf, strerror(errno));
+ system_w(buf);
+ // some OSes require routes to be set manually
#ifdef __APPLE__
-
// MacOSX requires the route to be set up manually
// FIXME: the prefix shouldn't be hardcoded here
snprintf(buf, sizeof(buf), "route add -inet6 -net fd87:d87e:eb43:: -prefixlen %d -gateway %s", NDESC(prefix_len), astr);
- log_msg(LOG_INFO, "setup routing: \"%s\"", buf);
- if (system(buf) == -1)
- log_msg(LOG_ERR, "could not exec \"%s\": \"%s\"", buf, strerror(errno));
-
+ system_w(buf);
+#elif __sun__
+ // Solaris requires the route to be set up manually
+ // FIXME: the prefix shouldn't be hardcoded here
+ snprintf(buf, sizeof(buf), "route add -inet6 fd87:d87e:eb43::/%d %s -iface", NDESC(prefix_len), astr);
+ system_w(buf);
#endif
}
@@ -196,18 +207,14 @@ int tun_alloc(char *dev, int dev_s, struct in6_addr addr)
if (CNF(ipv4_enable) && !CNF(use_tap))
{
snprintf(buf, sizeof(buf), "ifconfig %s %s netmask %s", dev, astr4, inet_ntoa(netmask));
- log_msg(LOG_INFO, "configuring tun IP: \"%s\"", buf);
- if (system(buf) == -1)
- log_msg(LOG_ERR, "could not exec \"%s\": \"%s\"", buf, strerror(errno));
+ system_w(buf);
}
// bring up tap device
if (CNF(use_tap))
{
snprintf(buf, sizeof(buf), "ifconfig %s up", dev);
- log_msg(LOG_INFO, "bringing up TAP device \"%s\"", buf);
- if (system(buf) == -1)
- log_msg(LOG_ERR, "could not exec \"%s\": \"%s\"", buf, strerror(errno));
+ system_w(buf);
}
return fd;
diff --git a/src/ocatv6conv.c b/src/ocatv6conv.c
index b31dc24..df09f0e 100644
--- a/src/ocatv6conv.c
+++ b/src/ocatv6conv.c
@@ -80,7 +80,7 @@ int oniontipv6(const char *onion, struct in6_addr *ip6)
for (i = 0; i < 16; i++)
{
shl5((char*) ip6);
- j = toupper(onion[i]);
+ j = toupper((int) onion[i]);
if ((j < '2') || (j > 'Z'))
return -1;
if ((j = deBASE32_[j - '2']) == -1)
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-privacy/packages/onioncat.git
More information about the Pkg-privacy-commits
mailing list