--- /dev/null
+# /**********************************************************
+# SixXS - Automatic IPv6 Connectivity Configuration Utility
+# ***********************************************************
+# Copyright 2003-2005 SixXS - http://www.sixxs.net
+# ***********************************************************
+# Packaging Makefile
+# ***********************************************************
+# $Author: jeroen $
+# $Id: Makefile,v 1.22 2007-01-11 00:29:33 jeroen Exp $
+# $Date: 2007-01-11 00:29:33 $
+# **********************************************************/
+#
+# Note for BSD people: use GNU Make (gmake)
+
+PROJECT=aiccu
+PROJECT_DESC="Automatic IPv6 Connectivity Configuration Utility"
+PROJECT_VERSION=$(shell grep "AICCU_VER" common/aiccu.h | head -n 1 | awk '{print $$3}' | tr -d \")
+
+# Misc bins
+RM=@rm -f
+MAKE:=@${MAKE}
+CP=@echo [Copy]; cp
+RPMBUILD=@echo [RPMBUILD]; rpmbuild
+RPMBUILD_SILENCE=>/dev/null 2>/dev/null
+
+# Excludes for limited source release
+EXCLUDES=--exclude "${PROJECT}/windows-*" --exclude "${PROJECT}/common/aiccu_win32.c" --exclude CVS --exclude "${PROJECT}/common/tsp*" --exclude "${PROJECT}/common/teepee*"
+DEBEXCL=-Iwindows-* -Icommon/aiccu_win32.c -I*CVS* -Icommon/tsp* -Icommon/teepee*
+
+# Change this if you want to install into another dirtree
+# Required for eg the Debian Package builder
+DESTDIR=
+export DESTDIR
+
+# This may be updated by RPM's for instance
+CFLAGS=${RPM_OPT_FLAGS}
+
+# Destination Paths (relative to DESTDIR)
+dirsbin=/usr/sbin/
+dirbin=/usr/bin/
+diretc=/etc/
+dirdoc=/usr/share/doc/${PROJECT}/
+
+# Make sure the lower makefile also knows these
+export PROJECT
+export PROJECT_DESC
+export PROJECT_VERSION
+export PROJECT_COPYRIGHT
+export DESTDIR
+export RM
+export MV
+export CC
+export CP
+export MAKE
+export dirsbin
+export dirbin
+export diretc
+export dirdoc
+export RPM_OPT_FLAGS
+export CFLAGS
+
+####################
+## Makefile Targets
+####################
+
+all: Makefile unix-console/
+ @echo "Building : $(PROJECT) - $(PROJECT_DESC)"
+ @echo "Copyright : SixXS"
+ @echo "Version : $(PROJECT_VERSION)"
+ $(MAKE) -C unix-console all
+ @echo "Building done"
+
+install: aiccu
+ @echo "Installing into ${DESTDIR}..."
+ @echo "Binaries..."
+ @mkdir -p ${DESTDIR}${dirsbin}
+ $(MAKE) -C unix-console install
+ @mkdir -p ${DESTDIR}${dirdoc}
+ @echo "Configuration..."
+ @mkdir -p ${DESTDIR}${diretc}
+ifeq ($(shell echo "A${RPM_BUILD_ROOT}"),A)
+ $(shell [ -f ${DESTDIR}${diretc}${PROJECT}.conf ] || cp -R doc/${PROJECT}.conf ${DESTDIR}${diretc}${PROJECT}.conf)
+ @echo "Documentation..."
+ @cp doc/README ${DESTDIR}${dirdoc}
+ @cp doc/LICENSE ${DESTDIR}${dirdoc}
+ @cp doc/HOWTO ${DESTDIR}${dirdoc}
+ @echo "Installing Debian-style init.d"
+ @mkdir -p ${DESTDIR}${diretc}init.d
+ @cp doc/${PROJECT}.init.debian ${DESTDIR}${diretc}init.d/${PROJECT}
+else
+ @echo "Installing Redhat-style init.d"
+ @mkdir -p ${DESTDIR}${diretc}init.d
+ @cp doc/${PROJECT}.init.rpm ${DESTDIR}${diretc}init.d/${PROJECT}
+ @cp doc/${PROJECT}.conf ${DESTDIR}${diretc}${PROJECT}.conf
+endif
+ @echo "Installation into ${DESTDIR}/ completed"
+
+help:
+ @echo "$(PROJECT) - $(PROJECT_DESC)"
+ @echo
+ @echo "Makefile targets:"
+ @echo "all : Build everything"
+ @echo "help : This little text"
+ @echo "install : Build & Install into ${DESTDIR}/"
+ @echo "clean : Clean the dirs to be pristine in bondage"
+ @echo
+ @echo "Distribution targets:"
+ @echo "dist : Make all distribution targets (except rpm's)"
+ @echo "tar : Make source tarball (tar.gz)"
+ @echo "bz2 : Make source tarball (tar.bz2)"
+ @echo "deb : Make Debian binary package (.deb)"
+ @echo "debsrc : Make Debian source packages"
+ @echo "rpm : Make RPM package (.rpm)"
+ @echo "rpmsrc : Make RPM source packages"
+ @echo
+ @echo "SixXS targets:"
+ @echo "tarfull : Full tar including Windows directories"
+ @echo "bz2full : Full bz2 including Windows directories"
+
+aiccu: doc unix-console/
+ $(MAKE) -C unix-console all
+
+doc: doc/aiccu.1
+
+doc/aiccu.1: doc/aiccu.sgml
+ docbook-to-man doc/aiccu.sgml >doc/aiccu.1
+
+clean: debclean rpmclean
+ $(MAKE) -C unix-console clean
+ -${RM} -r windows-gui/Debug
+ -${RM} -r windows-gui/Release
+ -${RM} windows-gui/AICCU.APS
+ -${RM} windows-gui/AICCU.ncb
+ -${RM} -r windows-console/Debug
+ -${RM} -r windows-console/Release
+ -${RM} windows-console/AICCU.APS
+ -${RM} windows-console/AICCU.ncb
+
+# Generate Distribution files
+dist: tar bz2 deb
+
+# tar.gz
+tar: clean
+ -${RM} ../${PROJECT}_${PROJECT_VERSION}.tar.gz
+ tar -zco -C .. ${EXCLUDES} -f ../${PROJECT}_${PROJECT_VERSION}.tar.gz ${PROJECT}
+
+# tar.gz (full)
+tarfull: clean
+ -${RM} ../${PROJECT}_${PROJECT_VERSION}.tar.gz
+ tar -zco -C .. -f ../${PROJECT}_${PROJECT_VERSION}-full.tar.gz ${PROJECT}
+
+# tar.bz2
+bz2: clean
+ -${RM} ../${PROJECT}_${PROJECT_VERSION}.tar.bz2
+ tar -jco -C .. ${EXCLUDES} -f ../${PROJECT}_${PROJECT_VERSION}.tar.bz2 ${PROJECT}
+
+# tar.bz2 (full)
+bz2full: clean
+ -${RM} ../${PROJECT}_${PROJECT_VERSION}.tar.bz2
+ tar -jco -C .. -f ../${PROJECT}_${PROJECT_VERSION}-full.tar.bz2 ${PROJECT}
+
+# .deb
+deb: clean
+ # Copy the changelog
+ ${CP} doc/changelog debian/changelog
+ ${CP} doc/${PROJECT}.init.debian debian/${PROJECT}.init
+ dpkg-buildpackage $(DEBEXCL) -rfakeroot
+ ${MAKE} clean
+
+# Cleanup after debian
+debclean:
+ -${RM} debian/${PROJECT}.init debian/${PROJECT}.conffiles
+ if [ -f build-stamp ]; then debian/rules clean; fi
+
+# RPM
+rpm: clean tar
+ -${RM} /usr/src/redhat/RPMS/i386/${PROJECT}-*.rpm
+ ${RPMBUILD} -tb --define '${PROJECT}_version ${PROJECT_VERSION}' ../${PROJECT}_${PROJECT_VERSION}.tar.gz ${RPMBUILD_SILENCE}
+ @if [ -d /usr/src/redhat/RPMS/i386/ ]; then mv /usr/src/redhat/RPMS/i386/${PROJECT}-*.rpm ../; fi
+ @if [ -d /usr/src/rpm/RPMS/i386/ ]; then mv /usr/src/rpm/RPMS/i386/${PROJECT}-*.rpm ../; fi
+ @echo "Resulting RPM's:"
+ @ls -l ../${PROJECT}-*.rpm
+ ${MAKE} clean
+ @echo "RPMBuild done"
+
+rpmsrc: clean tar
+ -${RM} /usr/src/redhat/RPMS/i386/${PROJECT}-*src.rpm
+ ${RPMBUILD} -ts --define '${PROJECT}_version ${PROJECT_VERSION}' ../${PROJECT}_${PROJECT_VERSION}.tar.gz ${RPMBUILD_SILENCE}
+ @if [ -d /usr/src/redhat/RPMS/i386/ ]; then mv /usr/src/redhat/RPMS/i386/${PROJECT}-*.src.rpm ../; fi
+ @if [ -d /usr/src/rpm/RPMS/i386/ ]; then mv /usr/src/rpm/RPMS/i386/${PROJECT}-*.src.rpm ../; fi
+ @echo "Resulting RPM's:"
+ @ls -l ../${PROJECT}-*.rpm
+ ${MAKE} clean
+ @echo "RPMBuild-src done"
+
+rpmclean:
+ -${RM} ../${PROJECT}_${PROJECT_VERSION}.tar.gz
+
+# Mark targets as phony
+.PHONY : all install help clean dist tar bz2 deb debclean rpm rpmsrc
+
--- /dev/null
+/**********************************************************
+ SixXS - Automatic IPv6 Connectivity Configuration Utility
+***********************************************************
+ Copyright 2003-2005 SixXS - http://www.sixxs.net
+***********************************************************
+ common/aiccu.c - AICCU Abstracted functions
+***********************************************************
+ $Author: jeroen $
+ $Id: aiccu.c,v 1.20 2007-01-15 12:02:10 jeroen Exp $
+ $Date: 2007-01-15 12:02:10 $
+**********************************************************/
+
+#include "aiccu.h"
+
+struct AICCU_conf *g_aiccu = NULL;
+
+/* Config */
+struct pl_rule aiccu_conf_rules[] =
+{
+ /* Configuration */
+ {"username", PLRT_STRING, offsetof(struct AICCU_conf, username)},
+ {"password", PLRT_STRING, offsetof(struct AICCU_conf, password)},
+ {"protocol", PLRT_STRING, offsetof(struct AICCU_conf, protocol)},
+ {"server", PLRT_STRING, offsetof(struct AICCU_conf, server)},
+ {"ipv6_interface", PLRT_STRING, offsetof(struct AICCU_conf, ipv6_interface)},
+ {"tunnel_id", PLRT_STRING, offsetof(struct AICCU_conf, tunnel_id)},
+ {"local_ipv4_override", PLRT_STRING, offsetof(struct AICCU_conf, local_ipv4_override)},
+
+ /* Post Setup script path */
+ {"setupscript", PLRT_STRING, offsetof(struct AICCU_conf, setupscript)},
+
+ /* Automatic */
+ {"automatic", PLRT_BOOL, offsetof(struct AICCU_conf, automatic)},
+
+ /* Operational options */
+ {"daemonize", PLRT_BOOL, offsetof(struct AICCU_conf, daemonize)},
+ {"verbose", PLRT_BOOL, offsetof(struct AICCU_conf, verbose)},
+ {"behindnat", PLRT_BOOL, offsetof(struct AICCU_conf, behindnat)},
+ {"requiretls", PLRT_BOOL, offsetof(struct AICCU_conf, requiretls)},
+ {"noconfigure", PLRT_BOOL, offsetof(struct AICCU_conf, noconfigure)},
+ {"makebeats", PLRT_BOOL, offsetof(struct AICCU_conf, makebeats)},
+ {"defaultroute", PLRT_BOOL, offsetof(struct AICCU_conf, defaultroute)},
+ {"pidfile", PLRT_STRING, offsetof(struct AICCU_conf, pidfile)},
+ {NULL, PLRT_END, 0},
+};
+
+#ifdef AICCU_GNUTLS
+void aiccu_tls_log(int level, const char *message);
+void aiccu_tls_log(int level, const char *message)
+{
+ dolog(level, "[GNUTLS] %s\n", message);
+}
+#endif
+
+bool aiccu_InitConfig()
+{
+#ifdef AICCU_GNUTLS
+ int ret;
+#define CAFILE "ca.pem"
+#endif
+ /* Allocate & Initialize */
+ g_aiccu = (struct AICCU_conf *)malloc(sizeof(*g_aiccu));
+ if (!g_aiccu) return false;
+ memset(g_aiccu, 0, sizeof(*g_aiccu));
+ g_aiccu->tic = (struct TIC_conf *)malloc(sizeof(*g_aiccu->tic));
+ memset(g_aiccu->tic, 0, sizeof(*g_aiccu->tic));
+
+ /* Initialize config to defaults */
+ g_aiccu->running = true;
+ g_aiccu->tunrunning = false;
+ g_aiccu->daemonize = 0;
+ g_aiccu->verbose = false;
+ g_aiccu->requiretls = false; /* Not mandatory yet */
+ g_aiccu->noconfigure = false;
+ g_aiccu->makebeats = true;
+ g_aiccu->defaultroute = true;
+ g_aiccu->ipv6_interface = strdup("aiccu");
+ if (!g_aiccu->ipv6_interface) return false;
+ g_aiccu->protocol = strdup("tic");
+ if (!g_aiccu->protocol) return false;
+ g_aiccu->server = strdup("tic.sixxs.net");
+ if (!g_aiccu->server) return false;
+ g_aiccu->pidfile = strdup(AICCU_PID);
+ if (!g_aiccu->pidfile) return false;
+
+#ifdef AICCU_GNUTLS
+ /* Initialize GNUTLS */
+ ret = gnutls_global_init();
+ if (ret != 0)
+ {
+ dolog(LOG_ERR, "GNUTLS failed to initialize: %s (%d)\n", gnutls_strerror(ret), ret);
+ return false;
+ }
+
+ /* X509 credentials */
+ ret = gnutls_certificate_allocate_credentials(&g_aiccu->tls_cred);
+ if (ret != 0)
+ {
+ dolog(LOG_ERR, "GNUTLS failed to initialize: %s (%d)\n", gnutls_strerror(ret), ret);
+ return false;
+ }
+
+ /* For the time being don't load the PEM as it is not there... */
+
+#if 0
+ /* Sets the trusted cas file */
+ ret = gnutls_certificate_set_x509_trust_file(g_aiccu->tls_cred, CAFILE, GNUTLS_X509_FMT_PEM);
+ if (ret < 0)
+ {
+ dolog(LOG_ERR, "GNUTLS failed to initialize: %s (%d)\n", gnutls_strerror(ret), ret);
+ return false;
+ }
+#endif
+
+ /* Configure GNUTLS logging to happen using our own logging interface */
+ gnutls_global_set_log_function(aiccu_tls_log);
+
+#ifdef DEBUG
+ /* Show some GNUTLS debugging information */
+ gnutls_global_set_log_level(5);
+#endif
+
+#endif /* AICCU_GNUTLS */
+
+ return true;
+}
+
+/* Locate where the configfile is stored */
+void aiccu_LocateFile(const char *what, char *filename, unsigned int length);
+void aiccu_LocateFile(const char *what, char *filename, unsigned int length)
+{
+ memset(filename, 0, length);
+#ifdef _WIN32
+ /* Figure out the "C:\Windows" location */
+ /* as that is where we store our configuration */
+ GetWindowsDirectory(filename, length);
+ strncat(filename, "\\", length);
+ strncat(filename, what, length);
+#else
+ /* Use the default location */
+ strncat(filename, what, length);
+#endif
+}
+
+/* configure this client */
+bool aiccu_LoadConfig(const char *filename)
+{
+ FILE *f;
+ char buf[1000];
+ char filenames[256];
+ unsigned int line = 0;
+
+ if (!filename)
+ {
+ aiccu_LocateFile(AICCU_CONFIG, filenames, sizeof(filenames));
+ filename = filenames;
+ }
+
+ f = fopen(filename, "r");
+ if (!f)
+ {
+ dolog(LOG_ERR, "Could not open config file \"%s\"\n", filename);
+ return false;
+ }
+
+ while (fgets(buf, sizeof(buf), f))
+ {
+ line++;
+ if (parseline(buf, " ", aiccu_conf_rules, g_aiccu)) continue;
+
+ dolog(LOG_WARNING, "Unknown configuration statement on line %u of %s: \"%s\"\n", line, filename, buf);
+ }
+ fclose(f);
+
+ return true;
+}
+
+/* Save the configuration */
+bool aiccu_SaveConfig(const char *filename)
+{
+ FILE *f;
+ char filenames[512];
+
+ if (!filename)
+ {
+ aiccu_LocateFile(AICCU_CONFIG, filenames, sizeof(filenames));
+ filename = filenames;
+ }
+
+ f = fopen(filename, "w");
+ if (!f)
+ {
+ dolog(LOG_ERR, "Could not open config file \"%s\" for writing\n", filename);
+ return false;
+ }
+
+ fprintf(f, "# AICCU Configuration (Saved by AICCU %s)\n", AICCU_VER);
+ fprintf(f, "\n");
+ fprintf(f, "# Login information\n");
+ fprintf(f, "username %s\n", g_aiccu->username);
+ fprintf(f, "password %s\n", g_aiccu->password);
+ fprintf(f, "protocol %s\n", g_aiccu->protocol);
+ fprintf(f, "server %s\n", g_aiccu->server);
+ fprintf(f, "\n");
+ fprintf(f, "# Interface names to use\n");
+ fprintf(f, "ipv6_interface %s\n", g_aiccu->ipv6_interface);
+ fprintf(f, "\n");
+ fprintf(f, "# The tunnel_id to use\n");
+ fprintf(f, "# (only required when there are multiple tunnels in the list)\n");
+ fprintf(f, "tunnel_id %s\n", g_aiccu->tunnel_id);
+ fprintf(f, "\n");
+ fprintf(f, "# Try to automatically login and setup the tunnel?\n");
+ fprintf(f, "automatic %s\n", g_aiccu->automatic ? "true" : "false");
+ fprintf(f, "\n");
+ fprintf(f, "# Script to run after setting up the interfaces (default: none)\n");
+ fprintf(f, "%ssetupscript %s\n", g_aiccu->setupscript ? "" : "#", g_aiccu->setupscript ? g_aiccu->setupscript : "<path>");
+ fprintf(f, "\n");
+ fprintf(f, "# TLS Required?\n");
+ fprintf(f, "requiretls %s\n", g_aiccu->requiretls ? "true" : "false");
+ fprintf(f, "\n");
+ fprintf(f, "# Be verbose?\n");
+ fprintf(f, "verbose %s\n", g_aiccu->verbose ? "true" : "false");
+ fprintf(f, "\n");
+ fprintf(f, "# Daemonize?\n");
+ fprintf(f, "daemonize %s\n", g_aiccu->daemonize ? "true" : "false");
+ fprintf(f, "\n");
+ fprintf(f, "# Behind NAT (default: false)\n");
+ fprintf(f, "# Notify the user that a NAT-kind network is detected\n");
+ fprintf(f, "behindnat %s\n", g_aiccu->behindnat ? "true" : "false");
+ fprintf(f, "\n");
+ fprintf(f, "# PID File\n");
+ fprintf(f, "pidfile %s\n", g_aiccu->pidfile);
+ fprintf(f, "\n");
+ fprintf(f, "# Make heartbeats (default true)\n");
+ fprintf(f, "# In general you don't want to turn this off\n");
+ fprintf(f, "# Of course only applies to AYIYA and heartbeat tunnels not to static ones\n");
+ fprintf(f, "makebeats %s\n", g_aiccu->makebeats ? "true" : "false");
+ fprintf(f, "\n");
+ fprintf(f, "# Add a default route (default: true)\n");
+ fprintf(f, "defaultroute %s\n", g_aiccu->defaultroute ? "true" : "false");
+ fprintf(f, "\n");
+ fprintf(f, "# Don't configure anything (default: false)\n");
+ fprintf(f, "noconfigure %s\n", g_aiccu->noconfigure ? "true" : "false");
+ fclose(f);
+ return true;
+}
+
+void aiccu_FreeConfig()
+{
+ if (!g_aiccu) return;
+
+#ifdef AICCU_GNUTLS
+ gnutls_certificate_free_credentials(g_aiccu->tls_cred);
+ gnutls_global_deinit();
+#endif
+
+ if (g_aiccu->username) { free(g_aiccu->username); g_aiccu->username = NULL; }
+ if (g_aiccu->password) { free(g_aiccu->password); g_aiccu->password = NULL; }
+ if (g_aiccu->ipv6_interface) { free(g_aiccu->ipv6_interface);g_aiccu->ipv6_interface = NULL; }
+ if (g_aiccu->tunnel_id) { free(g_aiccu->tunnel_id); g_aiccu->tunnel_id = NULL; }
+ if (g_aiccu->tic) { free(g_aiccu->tic); g_aiccu->tic = NULL; }
+ if (g_aiccu->setupscript) { free(g_aiccu->setupscript); g_aiccu->setupscript = NULL; }
+ if (g_aiccu->pidfile) { free(g_aiccu->pidfile); g_aiccu->pidfile = NULL; }
+
+ free(g_aiccu);
+ g_aiccu = NULL;
+}
+
+/* Make sure the OS understands IPv6 */
+void aiccu_install(void)
+{
+ D(dolog(LOG_DEBUG, "aiccu_install()\n");)
+ aiccu_os_install();
+}
+
+bool aiccu_setup(struct TIC_Tunnel *hTunnel, bool firstrun)
+{
+ bool ret = false;
+
+ D(dolog(LOG_DEBUG, "aiccu_setup(%s, %s)\n", hTunnel->sIPv6_Local, firstrun ? "first" : "other");)
+
+ /* AYIYA calls aiccu_setup(hTunnel,false) after preparing the tunnel interface */
+ if (firstrun && strcasecmp(hTunnel->sType, "ayiya") == 0)
+ {
+ ret = ayiya(hTunnel);
+ }
+#ifdef NEWSTUFF_TEEPEE
+ else if (firstrun && strcasecmp(hTunnel->sType, "l2tp") == 0)
+ {
+ ret = teepee(hTunnel);
+ }
+#endif
+ else
+ {
+ ret = aiccu_os_setup(hTunnel);
+ }
+
+ /* Beat for the first time */
+ if (ret) aiccu_beat(hTunnel);
+
+ return ret;
+}
+
+void aiccu_beat(struct TIC_Tunnel *hTunnel)
+{
+ if (!g_aiccu->makebeats)
+ {
+ D(dolog(LOG_DEBUG, "aiccu_beat() - Beating disabled\n"));
+ return;
+ }
+
+ D(dolog(LOG_DEBUG, "aiccu_beat() - Beating %s...\n", hTunnel->sType));
+
+ if (strcasecmp(hTunnel->sType, "6in4-heartbeat") == 0)
+ {
+ heartbeat_beat(hTunnel);
+ }
+ else if (strcasecmp(hTunnel->sType, "ayiya") == 0)
+ {
+ ayiya_beat();
+ }
+ else
+ {
+ D(dolog(LOG_DEBUG, "aiccu_beat() - No beat for %s!?\n", hTunnel->sType));
+ }
+
+ /* L2TP Hello's are handled inside TeePee */
+}
+
+void aiccu_reconfig(struct TIC_Tunnel *hTunnel)
+{
+ D(dolog(LOG_DEBUG, "aiccu_reconfig(%s)\n", hTunnel->sIPv6_Local);)
+ if (!g_aiccu->noconfigure) aiccu_os_reconfig(hTunnel);
+}
+
+void aiccu_delete(struct TIC_Tunnel *hTunnel)
+{
+ D(dolog(LOG_DEBUG, "aiccu_delete(%s)\n", hTunnel->sIPv6_Local);)
+ if (!g_aiccu->noconfigure) aiccu_os_delete(hTunnel);
+}
+
+void aiccu_test(struct TIC_Tunnel *hTunnel, bool automatic)
+{
+ D(dolog(LOG_DEBUG, "aiccu_test()\n"));
+ aiccu_os_test(hTunnel, automatic);
+}
+
+bool aiccu_exec(const char *fmt, ...)
+{
+#ifndef _WIN32
+ char buf[1024];
+ int ret;
+ va_list ap;
+
+ va_start(ap, fmt);
+ vsnprintf(buf,sizeof(buf),fmt,ap);
+ D(dolog(LOG_DEBUG, "aiccu_os_exec(\"%s\")\n", buf));
+ ret = system(buf);
+ if (ret == -1) dolog(LOG_WARNING, "Execution of \"%s\" failed!? (Please check if the command is available)\n", buf);
+ va_end(ap);
+#endif
+ return true;
+}
+
+#define SIXXS_LICENSE_PART1 "\
+The SixXS License - http://www.sixxs.net/\n\
+\n\
+Copyright (C) SixXS Staff <info@sixxs.net>\n\
+All rights reserved.\n\
+\n\
+Redistribution and use in source and binary forms, with or without\n\
+modification, are permitted provided that the following conditions\n\
+are met:\n\
+1. Redistributions of source code must retain the above copyright\n\
+ notice, this list of conditions and the following disclaimer.\n"
+
+#define SIXXS_LICENSE_PART2 "\
+2. Redistributions in binary form must reproduce the above copyright\n\
+ notice, this list of conditions and the following disclaimer in the\n\
+ documentation and/or other materials provided with the distribution.\n\
+3. Neither the name of SixXS nor the names of its contributors\n\
+ may be used to endorse or promote products derived from this software\n\
+ without specific prior permission.\n\
+\n\
+\n"
+
+#define SIXXS_LICENSE_PART3 "\
+THIS SOFTWARE IS PROVIDED BY SIXXS AND CONTRIBUTORS ``AS IS'' AND\n\
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n\
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n\
+ARE DISCLAIMED. IN NO EVENT SHALL SIXXS OR CONTRIBUTORS BE LIABLE\n\
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n\
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n"
+
+#define SIXXS_LICENSE_PART4 "\
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n\
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n\
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n\
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n\
+SUCH DAMAGE.\n"
+
+const char *aiccu_license()
+{
+#ifndef NOPEDANTIC
+ /*
+ * Pedantic doesn't allow this long strings, thus we will
+ * play nice and malloc it, copy them in separately and
+ * then return the buffer.
+ * What we don't do for compliancy....
+ */
+ static char *license = NULL;
+ if (!license)
+ {
+ /*
+ * Make one big block out of it
+ * too bad that the \0's get inserted,
+ * remove them and tada one big text...
+ */
+ static char
+ l1[] = SIXXS_LICENSE_PART1,
+ l2[] = SIXXS_LICENSE_PART2,
+ l3[] = SIXXS_LICENSE_PART3,
+ l4[] = SIXXS_LICENSE_PART4;
+ size_t
+ a = strlen(l1),
+ b = strlen(l2),
+ c = strlen(l3),
+ d = strlen(l4);
+
+ /* Create the 'long' string our selves then */
+ license = (char *)malloc(a+b+c+d+1);
+ if (!license) return NULL;
+
+ memset(license, 0, a+b+c+d+1);
+ memcpy(license , l1, a);
+ memcpy(license + a, l2, b);
+ memcpy(license + a + b, l3, c);
+ memcpy(license + a + b + c, l4, d);
+ }
+ return license;
+#else
+ return SIXXS_LICENSE_PART1 SIXXS_LICENSE_PART2 SIXXS_LICENSE_PART3 SIXXS_LICENSE_PART4;
+#endif
+}
--- /dev/null
+/**********************************************************
+ SixXS - Automatic IPv6 Connectivity Configuration Utility
+***********************************************************
+ Copyright 2003-2005 SixXS - http://www.sixxs.net
+***********************************************************
+ common/aiccu.h - Abstracted Functions and Configuration
+ All compile-time configurable items are in this file
+***********************************************************
+ $Author: jeroen $
+ $Id: aiccu.h,v 1.23 2007-01-15 12:01:43 jeroen Exp $
+ $Date: 2007-01-15 12:01:43 $
+**********************************************************/
+
+#ifndef AICCU_H
+#define AICCU_H "H5K7:W3NDY5UU5N1K1N1C0l3"
+
+#include "common.h"
+#include "tic.h"
+#include "heartbeat.h"
+#include "ayiya.h"
+#include "resolver.h"
+
+#ifdef NEWSTUFF_TSP
+#include "tsp.h"
+#endif
+#ifdef NEWSTUFF_TSP
+#include "teepee.h"
+#endif
+
+/* AICCU Version */
+#define AICCU_VER "2007.01.15"
+#define AICCU_VERSION_NUM 2007,01,15,0
+/* _NUM = required for Windows Resources */
+
+#ifdef _WIN32
+#define AICCU_TYPE "win32"
+#endif
+
+/* Append -gui or -console? */
+#ifndef AICCU_CONSOLE
+#ifdef AICCU_TYPE
+#define AICCU_VERSION AICCU_VER "-gui-" AICCU_TYPE
+#else
+#define AICCU_VERSION AICCU_VER "-gui"
+#endif
+#else
+#ifdef AICCU_TYPE
+#define AICCU_VERSION AICCU_VER "-console-" AICCU_TYPE
+#else
+#define AICCU_VERSION AICCU_VER "-console"
+#endif
+#endif
+
+/* Needed for TIC */
+#define TIC_CLIENT_NAME "AICCU"
+#define TIC_CLIENT_VERSION AICCU_VERSION
+
+/* Needed for TSP */
+#define TSP_CLIENT_NAME TIC_CLIENT_NAME
+#define TSP_CLIENT_VERSION TIC_CLIENT_VERSION
+
+/*
+ * AICCU configuration Cache
+ * allows reconnects even when we don't update
+ * the data. Could be useful in the event
+ * where we can't make contact to the main server
+ */
+#define AICCU_CACHE "/var/cache/aiccu.cache"
+
+/* The PID we are running as when daemonized */
+#define AICCU_PID "/var/run/aiccu.pid"
+
+/* AICCU Configuration file */
+#ifdef _WIN32
+/* GetWindowsDirectory() is used to figure out the directory to store the config */
+#define AICCU_CONFIG "aiccu.conf"
+#else
+#define AICCU_CONFIG "/etc/aiccu.conf"
+#endif
+
+/* Inbound listen queue */
+#define LISTEN_QUEUE 128
+
+#ifndef UNUSED
+#ifdef _AIX
+#define UNUSED
+#else
+#define UNUSED __attribute__ ((__unused__))
+#endif
+#endif
+
+/* AICCU Configuration */
+struct AICCU_conf
+{
+ /* Only for AICCU */
+ char *username; /* Username */
+ char *password; /* Password */
+ char *protocol; /* TIC/TSP/L2TP */
+ char *server; /* TIC/TSP etc server */
+ char *ipv6_interface; /* IPv6 interface (tunnel interface: sit0, tun0 etc) */
+ char *tunnel_id; /* ID of the tunnel to use */
+ char *local_ipv4_override; /* Local IPv4 override, for behind-NAT scenario's */
+ char *setupscript; /* Script to run after having set up the tunnel */
+ char *pidfile; /* File to store the PID */
+
+ /* used by other parts */
+
+ struct TIC_conf *tic; /* TIC Structure */
+#ifdef NEWSTUFF_TSP
+ struct TSP_conf *tsp; /* TSP Structure */
+#endif
+
+#ifdef AICCU_GNUTLS
+ gnutls_certificate_credentials tls_cred; /* GNUTLS credentials */
+#endif
+
+ bool daemonize; /* Daemonize? */
+ bool verbose; /* Verbosity */
+ bool running; /* Still running? */
+ bool tunrunning; /* Is the tundev running? */
+
+ bool automatic; /* Try to be totally automatic? */
+ bool behindnat; /* Behind a NAT */
+ bool requiretls; /* Require TLS for TIC? */
+ bool makebeats; /* Make heartbeats? */
+ bool noconfigure; /* No configuration (used to only send heartbeats) */
+ bool defaultroute; /* Configure a default route */
+};
+
+/* Global configuration */
+extern struct AICCU_conf *g_aiccu;
+
+/* AICCU Abstracted Functions */
+bool aiccu_InitConfig(void);
+bool aiccu_LoadConfig(const char *filename);
+bool aiccu_SaveConfig(const char *filename);
+void aiccu_FreeConfig(void);
+
+void aiccu_install(void);
+bool aiccu_setup(struct TIC_Tunnel *hTunnel, bool firstrun);
+void aiccu_beat(struct TIC_Tunnel *hTunnel);
+void aiccu_reconfig(struct TIC_Tunnel *hTunnel);
+void aiccu_delete(struct TIC_Tunnel *hTunnel);
+void aiccu_test(struct TIC_Tunnel *hTunnel, bool automatic);
+bool aiccu_exec(const char *fmt, ...);
+const char *aiccu_license(void);
+
+/* OS Specific */
+bool aiccu_os_install(void);
+bool aiccu_os_setup(struct TIC_Tunnel *hTunnel);
+void aiccu_os_reconfig(struct TIC_Tunnel *hTunnel);
+void aiccu_os_delete(struct TIC_Tunnel *hTunnel);
+void aiccu_os_test(struct TIC_Tunnel *hTunnel, bool automatic);
+
+#ifdef _WIN32
+void aiccu_win32_rename_adapter(const char *orig);
+#endif
+
+#endif /* AICCU_H */
--- /dev/null
+/**********************************************************
+ SixXS - Automatic IPv6 Connectivity Configuration Utility
+***********************************************************
+ Copyright 2003-2005 SixXS - http://www.sixxs.net
+***********************************************************
+ common/aiccu_aix.c - AIX
+
+ ipv6_interface has to be eg cti0
+***********************************************************
+ $Author: jeroen $
+ $Id: aiccu_aix.c,v 1.3 2006-07-23 14:13:57 jeroen Exp $
+ $Date: 2006-07-23 14:13:57 $
+**********************************************************/
+
+#include "aiccu.h"
+
+bool aiccu_os_install()
+{
+ /* Define the CTI (Configured Tunnel Interface) by executing the deftunnel configuration method */
+ return aiccu_exec("/usr/lib/methods/deftunnel -c if -s CTI -t cti");
+}
+
+bool aiccu_os_setup(struct TIC_Tunnel *hTunnel)
+{
+ if (hTunnel->uses_tundev == 0)
+ {
+ /* Build a normal SIT tunnel */
+ aiccu_exec(
+ "/usr/sbin/ifconfig %s inet6 ::%s/128 ::%s",
+ g_aiccu->ipv6_interface,
+ strcmp(hTunnel->sIPv4_Local, "heartbeat") == 0 ? "0.0.0.0" : hTunnel->sIPv4_Local,
+ hTunnel->sIPv4_POP);
+
+ /* Remove the local endpoint, the remote stays though :) */
+ aiccu_exec(
+ "/usr/sbin/ifconfig %s inet6 ::%s delete",
+ g_aiccu->ipv6_interface,
+ strcmp(hTunnel->sIPv4_Local, "heartbeat") == 0 ? "0.0.0.0" : hTunnel->sIPv4_Local);
+
+ /* Add the addresses */
+ aiccu_exec(
+ "ifconfig %s inet6 %s %s",
+ g_aiccu->ipv6_interface,
+ hTunnel->sIPv6_Local,
+ hTunnel->sIPv6_POP);
+ }
+ else
+ {
+ dolog(LOG_DEBUG, "There is no AIX support for tun-devices yet");
+ exit(-1);
+ }
+
+ if (g_aiccu->defaultroute)
+ {
+ aiccu_exec(
+ "route add -inet6 %s %s",
+ "default",
+ hTunnel->sIPv6_POP);
+ }
+
+ return true;
+}
+
+void aiccu_os_reconfig(struct TIC_Tunnel *hTunnel)
+{
+ if (hTunnel->uses_tundev == 0)
+ {
+ /* Build a normal SIT tunnel */
+ aiccu_exec(
+ "/usr/sbin/ifconfig %s inet6 ::%s/128 ::%s",
+ g_aiccu->ipv6_interface,
+ strcmp(hTunnel->sIPv4_Local, "heartbeat") == 0 ? "0.0.0.0" : hTunnel->sIPv4_Local,
+ hTunnel->sIPv4_POP);
+
+ /* Remove the local endpoint, the remote stays */
+ aiccu_exec(
+ "/usr/sbin/ifconfig %s inet6 ::%s delete",
+ g_aiccu->ipv6_interface,
+ strcmp(hTunnel->sIPv4_Local, "heartbeat") == 0 ? "0.0.0.0" : hTunnel->sIPv4_Local);
+ }
+}
+
+void aiccu_os_delete(struct TIC_Tunnel *hTunnel)
+{
+ hTunnel = hTunnel;
+ aiccu_exec(
+ "ifconfig %s down",
+ g_aiccu->ipv6_interface);
+}
+
--- /dev/null
+/**********************************************************
+ SixXS - Automatic IPv6 Connectivity Configuration Utility
+***********************************************************
+ Copyright 2003-2005 SixXS - http://www.sixxs.net
+***********************************************************
+ common/aiccu_darwin.c - Darwin
+***********************************************************
+ $Author: jeroen $
+ $Id: aiccu_darwin.c,v 1.11 2007-01-07 17:02:11 jeroen Exp $
+ $Date: 2007-01-07 17:02:11 $
+**********************************************************/
+
+#include "aiccu.h"
+
+bool aiccu_os_install(void)
+{
+ return true;
+}
+
+bool aiccu_os_setup(struct TIC_Tunnel *hTunnel)
+{
+ if (hTunnel->uses_tundev == 0)
+ {
+ aiccu_exec(
+ "/sbin/ifconfig %s tunnel %s %s",
+ g_aiccu->ipv6_interface,
+ strcmp(hTunnel->sIPv4_Local, "heartbeat") == 0 ? "0.0.0.0" : hTunnel->sIPv4_Local,
+ hTunnel->sIPv4_POP);
+ }
+
+ /* Bring the interface up */
+ aiccu_exec(
+ "ifconfig %s up",
+ g_aiccu->ipv6_interface);
+
+ /* Configure the MTU */
+ aiccu_exec(
+ "ifconfig %s mtu %u",
+ g_aiccu->ipv6_interface,
+ hTunnel->nMTU);
+
+ /* PtP link, so we can use the PtP syntax */
+ aiccu_exec(
+ "ifconfig %s inet6 %s %s prefixlen 128 alias",
+ g_aiccu->ipv6_interface,
+ hTunnel->sIPv6_Local,
+ hTunnel->sIPv6_POP);
+
+ /* Configure a path to the other side */
+ if (g_aiccu->defaultroute)
+ {
+ aiccu_exec(
+ "route add -inet6 %s %s",
+ "default",
+ hTunnel->sIPv6_POP);
+ }
+
+ return true;
+}
+
+void aiccu_os_reconfig(struct TIC_Tunnel *hTunnel)
+{
+ if (hTunnel->uses_tundev == 0)
+ {
+ aiccu_exec(
+ "/sbin/ifconfig %s tunnel %s %s",
+ g_aiccu->ipv6_interface,
+ hTunnel->sIPv4_Local,
+ hTunnel->sIPv4_POP);
+ }
+}
+
+void aiccu_os_delete(struct TIC_Tunnel *hTunnel)
+{
+ hTunnel = hTunnel;
+ aiccu_exec(
+ "ifconfig %s down",
+ g_aiccu->ipv6_interface);
+
+ if (hTunnel->uses_tundev == 0)
+ {
+ aiccu_exec(
+ "ifconfig %s deletetunnel",
+ g_aiccu->ipv6_interface);
+ }
+}
+
--- /dev/null
+/**********************************************************
+ SixXS - Automatic IPv6 Connectivity Configuration Utility
+***********************************************************
+ Copyright 2003-2005 SixXS - http://www.sixxs.net
+***********************************************************
+ common/aiccu_freebsd4.c - FreeBSD 3.x/4.x
+***********************************************************
+ $Author: jeroen $
+ $Id: aiccu_freebsd4.c,v 1.11 2007-01-07 17:05:23 jeroen Exp $
+ $Date: 2007-01-07 17:05:23 $
+**********************************************************/
+
+#include "aiccu.h"
+
+bool aiccu_os_install(void)
+{
+ return true;
+}
+
+bool aiccu_os_setup(struct TIC_Tunnel *hTunnel)
+{
+ if (hTunnel->uses_tundev == 0)
+ {
+ /* Create the tunnel device */
+ aiccu_exec(
+ "/sbin/ifconfig %s create",
+ g_aiccu->ipv6_interface);
+
+ /* Configure the endpoint */
+ aiccu_exec(
+ "/sbin/ifconfig %s tunnel %s %s",
+ g_aiccu->ipv6_interface,
+ strcmp(hTunnel->sIPv4_Local, "heartbeat") == 0 ? "0.0.0.0" : hTunnel->sIPv4_Local,
+ hTunnel->sIPv4_POP);
+ }
+
+ /* Mark the interface up */
+ aiccu_exec(
+ "ifconfig %s up",
+ g_aiccu->ipv6_interface);
+
+ /* Configure the MTU */
+ aiccu_exec(
+ "ifconfig %s mtu %u",
+ g_aiccu->ipv6_interface,
+ hTunnel->nMTU);
+
+ if (hTunnel->uses_tundev == 1)
+ {
+ /* Give it a link local address */
+ aiccu_exec(
+ "ifconfig %s inet6 %s prefixlen 64 alias",
+ g_aiccu->ipv6_interface,
+ hTunnel->sIPv6_LinkLocal);
+ }
+
+ /* Local side of the tunnel */
+ aiccu_exec(
+ "ifconfig %s inet6 %s prefixlen 128 alias",
+ g_aiccu->ipv6_interface,
+ hTunnel->sIPv6_Local);
+
+ /* Route to the remote side of the tunnel */
+ aiccu_exec(
+ "route add -inet6 %s -prefixlen 128 %s",
+ hTunnel->sIPv6_POP,
+ hTunnel->sIPv6_Local);
+
+ if (g_aiccu->defaultroute)
+ {
+ /* Add a default route */
+ aiccu_exec(
+ "route add -inet6 %s %s",
+ "default",
+ hTunnel->sIPv6_POP);
+ }
+
+ return true;
+}
+
+void aiccu_os_reconfig(struct TIC_Tunnel *hTunnel)
+{
+ if (hTunnel->uses_tundev == 0)
+ {
+ /* Change the endpoints of the tunnel */
+ aiccu_exec(
+ "/sbin/ifconfig %s tunnel %s %s",
+ g_aiccu->ipv6_interface,
+ hTunnel->sIPv4_Local,
+ hTunnel->sIPv4_POP);
+ }
+}
+
+void aiccu_os_delete(struct TIC_Tunnel *hTunnel)
+{
+ hTunnel = hTunnel;
+
+ /* Mark the interface down */
+ aiccu_exec(
+ "ifconfig %s down",
+ g_aiccu->ipv6_interface);
+
+ if (hTunnel->uses_tundev == 0)
+ {
+ /* Destroy the tunnel */
+ aiccu_exec(
+ "ifconfig %s destroy",
+ g_aiccu->ipv6_interface);
+ }
+}
+
--- /dev/null
+/**********************************************************
+ SixXS - Automatic IPv6 Connectivity Configuration Utility
+***********************************************************
+ Copyright 2003-2005 SixXS - http://www.sixxs.net
+***********************************************************
+ common/aiccu_kame.c - NetBSD + FreeBSD 5.x+
+***********************************************************
+ $Author: jeroen $
+ $Id: aiccu_kame.c,v 1.15 2007-01-11 15:11:27 jeroen Exp $
+ $Date: 2007-01-11 15:11:27 $
+**********************************************************/
+
+#include "aiccu.h"
+
+bool aiccu_os_install(void)
+{
+ return true;
+}
+
+bool aiccu_os_setup(struct TIC_Tunnel *hTunnel)
+{
+ if (hTunnel->uses_tundev == 0)
+ {
+ aiccu_exec(
+ "/sbin/ifconfig %s create",
+ g_aiccu->ipv6_interface);
+
+ aiccu_exec(
+ "/sbin/ifconfig %s tunnel %s %s",
+ g_aiccu->ipv6_interface,
+ strcmp(hTunnel->sIPv4_Local, "heartbeat") == 0 ? "0.0.0.0" : hTunnel->sIPv4_Local,
+ hTunnel->sIPv4_POP);
+ }
+
+ aiccu_exec(
+ "ifconfig %s up",
+ g_aiccu->ipv6_interface);
+
+ aiccu_exec(
+ "ifconfig %s mtu %u",
+ g_aiccu->ipv6_interface,
+ hTunnel->nMTU);
+
+ if (hTunnel->uses_tundev == 1)
+ {
+ /* Configure a generated linklocal address */
+ aiccu_exec(
+ "ifconfig %s inet6 %s prefixlen 64 alias",
+ g_aiccu->ipv6_interface,
+ hTunnel->sIPv6_LinkLocal);
+ }
+
+ /* PtP link, so we can use the PtP syntax */
+ aiccu_exec(
+ "ifconfig %s inet6 %s %s prefixlen 128 alias",
+ g_aiccu->ipv6_interface,
+ hTunnel->sIPv6_Local,
+ hTunnel->sIPv6_POP);
+
+ if (g_aiccu->defaultroute)
+ {
+ aiccu_exec(
+ "route add -inet6 %s %s",
+ "default",
+ hTunnel->sIPv6_POP);
+ }
+
+ return true;
+}
+
+void aiccu_os_reconfig(struct TIC_Tunnel *hTunnel)
+{
+ if (hTunnel->uses_tundev == 0)
+ {
+ aiccu_exec(
+ "/sbin/ifconfig %s tunnel %s %s",
+ g_aiccu->ipv6_interface,
+ hTunnel->sIPv4_Local,
+ hTunnel->sIPv4_POP);
+ }
+}
+
+void aiccu_os_delete(struct TIC_Tunnel *hTunnel)
+{
+ hTunnel = hTunnel;
+ aiccu_exec(
+ "ifconfig %s down",
+ g_aiccu->ipv6_interface);
+
+ if (hTunnel->uses_tundev == 0)
+ {
+ aiccu_exec(
+ "ifconfig %s deletetunnel",
+ g_aiccu->ipv6_interface);
+ }
+}
+
--- /dev/null
+/**********************************************************
+ SixXS - Automatic IPv6 Connectivity Configuration Utility
+***********************************************************
+ Copyright 2003-2005 SixXS - http://www.sixxs.net
+***********************************************************
+ common/aiccu_linux.c - AICCU Linux Abstracted functions
+***********************************************************
+ $Author: jeroen $
+ $Id: aiccu_linux.c,v 1.15 2007-01-15 12:18:58 jeroen Exp $
+ $Date: 2007-01-15 12:18:58 $
+**********************************************************/
+
+#include "aiccu.h"
+
+bool aiccu_os_install(void)
+{
+ /* Check if IPv6 support is available */
+ if (access("/proc/net/if_inet6", F_OK))
+ {
+ /* Doing the modprobe doesn't guarantee success unfortunately */
+ (void)system("modprobe -q ipv6 2>/dev/null >/dev/null");
+
+ /* Thus test it again */
+ if (access("/proc/net/if_inet6", F_OK))
+ {
+ dolog(LOG_ERR, "No IPv6 Stack found! Please check your kernel and module configuration\n");
+ return false;
+ }
+ }
+
+ /* Try to load modules (SIT tunnel, TUN/TAP)
+ * They can be kernel builtins and there is no easy
+ * way to check if they are loaded/built except for
+ * trying to use them and fail at that point
+ */
+ (void)system("modprobe -q sit 2>/dev/null >/dev/null");
+ (void)system("modprobe -q tun 2>/dev/null >/dev/null");
+
+ return true;
+}
+
+bool aiccu_os_setup(struct TIC_Tunnel *hTunnel)
+{
+ if (hTunnel->uses_tundev == 0)
+ {
+ aiccu_exec(
+ "ip tunnel add %s mode sit %s%s remote %s",
+ g_aiccu->ipv6_interface,
+ strcmp(hTunnel->sIPv4_Local, "heartbeat") == 0 ? "" : "local ",
+ strcmp(hTunnel->sIPv4_Local, "heartbeat") == 0 ? "" : hTunnel->sIPv4_Local,
+ hTunnel->sIPv4_POP);
+ }
+
+ aiccu_exec(
+ "ip link set %s up",
+ g_aiccu->ipv6_interface);
+
+ aiccu_exec(
+ "ip link set mtu %u dev %s",
+ hTunnel->nMTU,
+ g_aiccu->ipv6_interface);
+
+ if (hTunnel->uses_tundev == 0)
+ {
+ aiccu_exec(
+ "ip tunnel change %s ttl 64",
+ g_aiccu->ipv6_interface);
+ }
+ else
+ {
+ /* Add a LinkLocal address for AYIYA tunnels */
+ aiccu_exec(
+ "ip -6 addr add %s/%u dev %s",
+ hTunnel->sIPv6_LinkLocal,
+ 64,
+ g_aiccu->ipv6_interface);
+ }
+
+ aiccu_exec(
+ "ip -6 addr add %s/%u dev %s",
+ hTunnel->sIPv6_Local,
+ hTunnel->nIPv6_PrefixLength,
+ g_aiccu->ipv6_interface);
+
+ if (g_aiccu->defaultroute)
+ {
+ aiccu_exec(
+ "ip -6 ro add %s via %s dev %s",
+ "default",
+ hTunnel->sIPv6_POP,
+ g_aiccu->ipv6_interface);
+ }
+
+ return true;
+}
+
+void aiccu_os_reconfig(struct TIC_Tunnel *hTunnel)
+{
+ if (hTunnel->uses_tundev == 0)
+ {
+ aiccu_exec(
+ "ip tunnel change %s local %s",
+ g_aiccu->ipv6_interface,
+ hTunnel->sIPv4_Local);
+ }
+}
+
+void aiccu_os_delete(struct TIC_Tunnel *hTunnel)
+{
+ hTunnel = hTunnel;
+ aiccu_exec(
+ "ip link set %s down",
+ g_aiccu->ipv6_interface);
+
+ if (hTunnel->uses_tundev == 0)
+ {
+ aiccu_exec(
+ "ip tunnel del %s",
+ g_aiccu->ipv6_interface);
+ }
+}
+
--- /dev/null
+/**********************************************************
+ SixXS - Automatic IPv6 Connectivity Configuration Utility
+***********************************************************
+ Copyright 2003-2005 SixXS - http://www.sixxs.net
+***********************************************************
+ common/aiccu_openbsd.c - OpenBSD
+***********************************************************
+ $Author: jeroen $
+ $Id: aiccu_openbsd.c,v 1.11 2007-01-07 16:37:50 jeroen Exp $
+ $Date: 2007-01-07 16:37:50 $
+**********************************************************/
+
+#include "aiccu.h"
+
+bool aiccu_os_install(void)
+{
+ return true;
+}
+
+bool aiccu_os_setup(struct TIC_Tunnel *hTunnel)
+{
+ if (hTunnel->uses_tundev == 0)
+ {
+ aiccu_exec(
+ "/sbin/ifconfig %s tunnel %s %s",
+ g_aiccu->ipv6_interface,
+ strcmp(hTunnel->sIPv4_Local, "heartbeat") == 0 ? "0.0.0.0" : hTunnel->sIPv4_Local,
+ hTunnel->sIPv4_POP);
+ }
+
+ aiccu_exec(
+ "ifconfig %s up",
+ g_aiccu->ipv6_interface);
+
+ aiccu_exec(
+ "ifconfig %s mtu %u",
+ g_aiccu->ipv6_interface,
+ hTunnel->nMTU);
+
+ if (hTunnel->uses_tundev == 1)
+ {
+ aiccu_exec(
+ "ifconfig %s inet6 %s prefixlen 64 alias",
+ g_aiccu->ipv6_interface,
+ hTunnel->sIPv6_LinkLocal);
+ }
+
+ aiccu_exec(
+ "ifconfig %s inet6 %s %s prefixlen 128 alias",
+ g_aiccu->ipv6_interface,
+ hTunnel->sIPv6_Local,
+ hTunnel->sIPv6_POP);
+
+ if (g_aiccu->defaultroute)
+ {
+ aiccu_exec(
+ "route add -inet6 %s %s",
+ "default",
+ hTunnel->sIPv6_POP);
+ }
+
+ return true;
+}
+
+void aiccu_os_reconfig(struct TIC_Tunnel *hTunnel)
+{
+ aiccu_exec(
+ "/sbin/ifconfig %s tunnel %s %s",
+ g_aiccu->ipv6_interface,
+ hTunnel->sIPv4_Local,
+ hTunnel->sIPv4_POP);
+}
+
+void aiccu_os_delete(struct TIC_Tunnel *hTunnel)
+{
+ hTunnel = hTunnel;
+ aiccu_exec(
+ "ifconfig %s down",
+ g_aiccu->ipv6_interface);
+
+ if (hTunnel->uses_tundev == 0)
+ {
+ aiccu_exec(
+ "ifconfig %s deletetunnel",
+ g_aiccu->ipv6_interface);
+ }
+}
+
--- /dev/null
+/**********************************************************
+ SixXS - Automatic IPv6 Connectivity Configuration Utility
+***********************************************************
+ Copyright 2003-2005 SixXS - http://www.sixxs.net
+***********************************************************
+ common/aiccu_openbsd2.c - OpenBSD 2.7-2.9
+***********************************************************
+ $Author: jeroen $
+ $Id: aiccu_openbsd2.c,v 1.7 2007-01-07 16:37:50 jeroen Exp $
+ $Date: 2007-01-07 16:37:50 $
+
+ Original version provided by Wouter Van Hemel
+**********************************************************/
+
+#include "aiccu.h"
+
+bool aiccu_os_install(void)
+{
+ return true;
+}
+
+bool aiccu_os_setup(struct TIC_Tunnel *hTunnel)
+{
+ if (hTunnel->uses_tundev == 0)
+ {
+ aiccu_exec(
+ "/sbin/ifconfig %s giftunnel %s %s",
+ g_aiccu->ipv6_interface,
+ strcmp(hTunnel->sIPv4_Local, "heartbeat") == 0 ? "0.0.0.0" : hTunnel->sIPv4_Local,
+ hTunnel->sIPv4_POP);
+ }
+
+ aiccu_exec(
+ "ifconfig %s up",
+ g_aiccu->ipv6_interface);
+
+ aiccu_exec(
+ "ifconfig %s mtu %u",
+ g_aiccu->ipv6_interface,
+ hTunnel->nMTU);
+
+ if (hTunnel->uses_tundev == 1)
+ {
+ aiccu_exec(
+ "ifconfig %s inet6 %s prefixlen 64 alias",
+ g_aiccu->ipv6_interface,
+ hTunnel->sIPv6_LinkLocal);
+ }
+
+ aiccu_exec(
+ "ifconfig %s inet6 %s %s prefixlen 128 alias",
+ g_aiccu->ipv6_interface,
+ hTunnel->sIPv6_Local,
+ hTunnel->sIPv6_POP);
+
+ if (g_aiccu->defaultroute)
+ {
+ aiccu_exec(
+ "route add -inet6 %s %s",
+ "default",
+ hTunnel->sIPv6_POP);
+ }
+
+ return true;
+}
+
+void aiccu_os_reconfig(struct TIC_Tunnel *hTunnel)
+{
+ aiccu_exec(
+ "/sbin/ifconfig %s giftunnel %s %s",
+ g_aiccu->ipv6_interface,
+ hTunnel->sIPv4_Local,
+ hTunnel->sIPv4_POP);
+}
+
+void aiccu_os_delete(struct TIC_Tunnel *hTunnel)
+{
+ hTunnel = hTunnel;
+ aiccu_exec(
+ "ifconfig %s down",
+ g_aiccu->ipv6_interface);
+
+ aiccu_exec(
+ "ifconfig %s inet6 %s %s prefixlen 128 -alias",
+ g_aiccu->ipv6_interface,
+ hTunnel->sIPv6_Local,
+ hTunnel->sIPv6_POP);
+
+}
+
--- /dev/null
+/**********************************************************
+ SixXS - Automatic IPv6 Connectivity Configuration Utility
+***********************************************************
+ Copyright 2003-2005 SixXS - http://www.sixxs.net
+***********************************************************
+ common/aiccu_sunos.c - Sun Solaris / SunOS
+
+ ipv6_interface has to be eg ip.tun0
+***********************************************************
+ $Author: jeroen $
+ $Id: aiccu_sunos.c,v 1.3 2006-07-23 14:13:57 jeroen Exp $
+ $Date: 2006-07-23 14:13:57 $
+**********************************************************/
+
+#include "aiccu.h"
+
+bool aiccu_os_install(void)
+{
+ return true;
+}
+
+bool aiccu_os_setup(struct TIC_Tunnel *hTunnel)
+{
+ if (hTunnel->uses_tundev == 0)
+ {
+ aiccu_exec(
+ "/sbin/ifconfig %s inet6 plumb tsrc %s tdst %s up",
+ g_aiccu->ipv6_interface,
+ strcmp(hTunnel->sIPv4_Local, "heartbeat") == 0 ? "0.0.0.0" : hTunnel->sIPv4_Local,
+ hTunnel->sIPv4_POP);
+
+ aiccu_exec(
+ "ifconfig %s inet6 addif %s %s up",
+ g_aiccu->ipv6_interface,
+ hTunnel->sIPv6_Local,
+ hTunnel->sIPv6_POP);
+ }
+ else
+ {
+ dolog(LOG_DEBUG, "There is no Solaris support for tun-devices yet");
+ exit(-1);
+ }
+
+ if (g_aiccu->defaultroute)
+ {
+ aiccu_exec(
+ "route add -inet6 %s %s",
+ "default",
+ hTunnel->sIPv6_POP);
+ }
+
+ return true;
+}
+
+void aiccu_os_reconfig(struct TIC_Tunnel *hTunnel)
+{
+ if (hTunnel->uses_tundev == 0)
+ {
+ aiccu_exec(
+ "/sbin/ifconfig %s inet6 plumb tsrc %s tdst %s up",
+ g_aiccu->ipv6_interface,
+ strcmp(hTunnel->sIPv4_Local, "heartbeat") == 0 ? "0.0.0.0" : hTunnel->sIPv4_Local,
+ hTunnel->sIPv4_POP);
+ }
+}
+
+void aiccu_os_delete(struct TIC_Tunnel *hTunnel)
+{
+ hTunnel = hTunnel;
+ aiccu_exec(
+ "ifconfig %s down",
+ g_aiccu->ipv6_interface);
+}
+
--- /dev/null
+/**********************************************************
+ SixXS - Automatic IPv6 Connectivity Configuration Utility
+***********************************************************
+ Copyright 2003-2005 SixXS - http://www.sixxs.net
+***********************************************************
+ common/aiccu_test.c - AICCU Test function
+***********************************************************
+ $Author: jeroen $
+ $Id: aiccu_test.c,v 1.9 2007-01-15 12:00:46 jeroen Exp $
+ $Date: 2007-01-15 12:00:46 $
+**********************************************************/
+
+#include "aiccu.h"
+
+#ifndef _WIN32
+#define PING4 "ping -c %d -v %s 2>&1"
+#define PING6 "ping6 -c %d -v %s 2>&1"
+#define TRACEROUTE4 "traceroute %s 2>&1"
+#define TRACEROUTE6 "traceroute6 %s 2>&1"
+#else
+#define PING4 "ping -4 -n %d %s"
+#define PING6 "ping -6 -n %d %s"
+#define TRACEROUTE4 "tracert %s"
+#define TRACEROUTE6 "tracert6 %s"
+#endif
+
+void system_arg(const char *fmt, ...);
+void system_arg(const char *fmt, ...)
+{
+ char buf[1024];
+ int ret;
+ va_list ap;
+
+ va_start(ap, fmt);
+ vsnprintf(buf, sizeof(buf), fmt, ap);
+ va_end(ap);
+
+ fflush(stdout);
+ ret = system(buf);
+ if (ret == -1) dolog(LOG_WARNING, "Execution of \"%s\" failed!? (Please check if the command is available)\n", buf);
+}
+
+#define PINGCOUNT 3
+
+bool test_ask(bool automatic);
+bool test_ask(bool automatic)
+{
+ char buf[100];
+
+ if (!g_aiccu->running) return false;
+
+ printf("\n######\n");
+ printf("\n");
+
+ if (automatic) return true;
+
+ printf("Did this work? [Y/n] ");
+
+ if (fgets(buf, sizeof(buf), stdin) == NULL) return false;
+
+ printf("\n");
+
+ return (buf[0] == 'N' || buf[0] == 'n' ? false : true);
+}
+
+void aiccu_os_test(struct TIC_Tunnel *hTunnel, bool automatic)
+{
+ unsigned int t = 1;
+ unsigned int tottests = 8;
+
+ /* Make sure we have a correct local IPv4 address for some tests */
+ if (strcmp(hTunnel->sType, "6in4-static") != 0)
+ {
+ heartbeat_socket(NULL, 0, "",
+ &hTunnel->sIPv4_Local,
+ hTunnel->sIPv4_POP,
+ NULL);
+ }
+
+ if (!g_aiccu->running) return;
+
+ printf("#######\n");
+ printf("####### AICCU Quick Connectivity Test\n");
+ printf("#######\n\n");
+
+ printf("####### [%u/%u] Ping the IPv4 Local/Your Outer Endpoint (%s)\n",
+ t++, tottests, hTunnel->sIPv4_Local);
+ printf("### This should return so called 'echo replies'\n");
+ printf("### If it doesn't then check your firewall settings\n");
+ printf("### Your local endpoint should always be pingable\n");
+ printf("### It could also indicate problems with your IPv4 stack\n");
+ printf("\n");
+ system_arg(PING4, PINGCOUNT, hTunnel->sIPv4_Local);
+ if (!test_ask(automatic) || !g_aiccu->running) return;
+
+ printf("####### [%u/%u] Ping the IPv4 Remote/PoP Outer Endpoint (%s)\n",
+ t++, tottests, hTunnel->sIPv4_POP);
+ printf("### These pings should reach the PoP and come back to you\n");
+ printf("### In case there are problems along the route between your\n");
+ printf("### host and the PoP this could not return replies\n");
+ printf("### Check your firewall settings if problems occur\n");
+ printf("\n");
+ system_arg(PING4, PINGCOUNT, hTunnel->sIPv4_POP);
+ if (!test_ask(automatic) || !g_aiccu->running) return;
+
+ printf("####### [%u/%u] Traceroute to the PoP (%s) over IPv4\n",
+ t++, tottests, hTunnel->sIPv4_POP);
+ printf("### This traceroute should reach the PoP\n");
+ printf("### In case this traceroute fails then you have no connectivity\n");
+ printf("### to the PoP and this is most probably the problem\n");
+ printf("\n");
+ system_arg(TRACEROUTE4, hTunnel->sIPv4_POP);
+ if (!test_ask(automatic) || !g_aiccu->running) return;
+
+ printf("###### [%u/%u] Checking if we can ping IPv6 localhost (::1)\n",
+ t++, tottests);
+ printf("### This confirms if your IPv6 is working\n");
+ printf("### If ::1 doesn't reply then something is wrong with your IPv6 stack\n");
+ printf("\n");
+ system_arg(PING6, PINGCOUNT, "::1");
+ if (!test_ask(automatic) || !g_aiccu->running) return;
+
+ printf("###### [%u/%u] Ping the IPv6 Local/Your Inner Tunnel Endpoint (%s)\n",
+ t++, tottests, hTunnel->sIPv6_Local);
+ printf("### This confirms that your tunnel is configured\n");
+ printf("### If it doesn't reply then check your interface and routing tables\n");
+ printf("\n");
+ system_arg(PING6, PINGCOUNT, hTunnel->sIPv6_Local);
+ if (!test_ask(automatic) || !g_aiccu->running) return;
+
+ printf("###### [%u/%u] Ping the IPv6 Remote/PoP Inner Tunnel Endpoint (%s)\n",
+ t++, tottests, hTunnel->sIPv6_POP);
+ printf("### This confirms the reachability of the other side of the tunnel\n");
+ printf("### If it doesn't reply then check your interface and routing tables\n");
+ printf("### Don't forget to check your firewall of course\n");
+ printf("### If the previous test was succesful then this could be both\n");
+ printf("### a firewalling and a routing/interface problem\n");
+ printf("\n");
+ system_arg(PING6, PINGCOUNT, hTunnel->sIPv6_POP);
+ if (!test_ask(automatic) || !g_aiccu->running) return;
+
+ printf("###### [%u/%u] Traceroute6 to the central SixXS machine (noc.sixxs.net)\n",
+ t++, tottests);
+ printf("### This confirms that you can reach the central machine of SixXS\n");
+ printf("### If that one is reachable you should be able to reach most IPv6 destinations\n");
+ printf("### Also check http://www.sixxs.net/ipv6calc/ which should show an IPv6 connection\n");
+ printf("### If your browser supports IPv6 and uses it of course.\n");
+ printf("\n");
+ system_arg(TRACEROUTE6, "noc.sixxs.net");
+ if (!test_ask(automatic) || !g_aiccu->running) return;
+
+ printf("###### [%u/%u] Traceroute6 to (www.kame.net)\n",
+ t++, tottests);
+ printf("### This confirms that you can reach a Japanese IPv6 destination\n");
+ printf("### If that one is reachable you should be able to reach most IPv6 destinations\n");
+ printf("### You should also check http://www.kame.net which should display\n");
+ printf("### a animated kame (turtle), of course only when your browser supports and uses IPv6\n");
+ printf("\n");
+ system_arg(TRACEROUTE6, "www.kame.net");
+ if (!test_ask(automatic) || !g_aiccu->running) return;
+
+ printf("###### ACCU Quick Connectivity Test (done)\n\n");
+
+ printf("### Either the above all works and gives no problems\n");
+ printf("### or it shows you where what goes wrong\n");
+ printf("### Check the SixXS FAQ (http://www.sixxs.net/faq/\n");
+ printf("### for more information and possible solutions or hints\n");
+ printf("### Don't forget to check the Forums (http://www.sixxs.net/forum/)\n");
+ printf("### for a helping hand.\n");
+ printf("### Passing the output of 'aiccu autotest >aiccu.log' is a good idea.\n");
+
+ if (!automatic)
+ {
+ /* Wait for a keypress */
+ printf("\n\n*** press a key to continue ***\n");
+ getchar();
+ }
+}
+
--- /dev/null
+/**********************************************************
+ SixXS - Automatic IPv6 Connectivity Configuration Utility
+***********************************************************
+ Copyright 2003-2005 SixXS - http://www.sixxs.net
+***********************************************************
+ common/ayiya.c - AYIYA - Anything In Anything
+***********************************************************
+ $Author: jeroen $
+ $Id: ayiya.c,v 1.15 2007-01-07 16:17:48 jeroen Exp $
+ $Date: 2007-01-07 16:17:48 $
+**********************************************************/
+
+#include "aiccu.h"
+#include "ayiya.h"
+#include "tic.h"
+#include "tun.h"
+
+struct pseudo_ayh
+{
+ struct ayiyahdr ayh;
+ struct in6_addr identity;
+ sha1_byte hash[SHA1_DIGEST_LENGTH];
+ char payload[2048];
+};
+
+struct in_addr ayiya_ipv4_pop; /* IPv4 remote endpoint */
+struct in6_addr ayiya_ipv6_local, /* IPv6 local endpoint */
+ ayiya_ipv6_pop; /* IPv6 remote endpoint */
+sha1_byte ayiya_hash[SHA1_DIGEST_LENGTH]; /* SHA1 Hash of the shared secret. */
+
+TLSSOCKET ayiya_socket = NULL;
+
+static const char reader_name[] = "tundev->tun";
+static const char writer_name[] = "tun->tundev";
+static const char beat_name[] = "beat";
+
+void ayiya_log(int level, const char *what, struct sockaddr_storage *clientaddr, socklen_t addrlen, const char *fmt, ...);
+void ayiya_log(int level, const char *what, struct sockaddr_storage *clientaddr, socklen_t addrlen, const char *fmt, ...)
+{
+ char buf[1024];
+ char clienthost[NI_MAXHOST];
+ char clientservice[NI_MAXSERV];
+ va_list ap;
+
+ /* Clear them just in case */
+ memset(buf, 0, sizeof(buf));
+ memset(clienthost, 0, sizeof(clienthost));
+ memset(clientservice, 0, sizeof(clientservice));
+
+ if (clientaddr)
+ {
+ int ret;
+ ret = getnameinfo((struct sockaddr *)clientaddr, addrlen,
+ clienthost, sizeof(clienthost),
+ clientservice, sizeof(clientservice),
+ NI_NUMERICHOST|NI_NUMERICSERV);
+ if (ret != 0)
+ {
+ dolog(LOG_ERR, "ayiya_log() getnameinfo() ret: %d, errno: %u, %s\n", ret, errno, strerror(errno));
+ }
+ }
+
+ /* Print the host+port this is coming from */
+ snprintf(buf, sizeof(buf), "[AYIYA-%s]%s%s%s%s : ",
+ what,
+ clientaddr ? " [" : "",
+ clientaddr ? clienthost : "" ,
+ clientaddr ? "]:" : "",
+ clientservice ? clientservice : "");
+
+ /* Print the log message behind it */
+ va_start(ap, fmt);
+ vsnprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), fmt, ap);
+ va_end(ap);
+
+ /* Actually Log it */
+ dolog(level, buf);
+}
+
+/* Tun -> Socket */
+void ayiya_reader(char *buf, unsigned int length);
+void ayiya_reader(char *buf, unsigned int length)
+{
+ struct pseudo_ayh *s = (struct pseudo_ayh *)buf, s2;
+ int lenout;
+ SHA_CTX sha1;
+ sha1_byte hash[SHA1_DIGEST_LENGTH];
+ struct sockaddr_in target;
+
+ /* We tunnel over IPv4 */
+ memcpy(&target.sin_addr, &ayiya_ipv4_pop, sizeof(target.sin_addr));
+ target.sin_family = AF_INET;
+ target.sin_port = htons(atoi(AYIYA_PORT));
+
+ /* Prefill some standard AYIYA values */
+ memset(&s, 0, sizeof(s));
+ s2.ayh.ayh_idlen = 4; /* 2^4 = 16 bytes = 128 bits (IPv6 address) */
+ s2.ayh.ayh_idtype = ayiya_id_integer;
+ s2.ayh.ayh_siglen = 5; /* 5*4 = 20 bytes = 160 bits (SHA1) */
+ s2.ayh.ayh_hshmeth = ayiya_hash_sha1;
+ s2.ayh.ayh_autmeth = ayiya_auth_sharedsecret;
+ s2.ayh.ayh_opcode = ayiya_op_forward;
+ s2.ayh.ayh_nextheader = IPPROTO_IPV6;
+
+ /* Our IPv6 side of this tunnel */
+ memcpy(&s2.identity, &ayiya_ipv6_local, sizeof(s2.identity));
+
+ /* The payload */
+ memcpy(&s2.payload, buf, length);
+
+ /* Fill in the current time */
+ s2.ayh.ayh_epochtime = htonl((u_long)time(NULL));
+
+ /*
+ * The hash of the shared secret needs to be in the
+ * spot where we later put the complete hash
+ */
+ memcpy(&s2.hash, ayiya_hash, sizeof(s2.hash));
+
+ /* Generate a SHA1 */
+ SHA1_Init(&sha1);
+ /* Hash the complete AYIYA packet */
+ SHA1_Update(&sha1, (sha1_byte *)&s2, sizeof(s2)-sizeof(s2.payload)+length);
+ /* Store the hash in the packets hash */
+ SHA1_Final(hash, &sha1);
+
+ /* Store the hash in the actual packet */
+ memcpy(&s2.hash, &hash, sizeof(s2.hash));
+
+ /* Send it onto the network */
+ length = sizeof(s2)-sizeof(s2.payload)+length;
+#if defined(_FREEBSD) || defined(_DFBSD) || defined(_OPENBSD) || defined(_DARWIN) || defined(_NETBSD)
+ lenout = send(ayiya_socket->socket, (const char *)&s2, length, 0);
+#else
+ lenout = sendto(ayiya_socket->socket, (const char *)&s2, length, 0, (struct sockaddr *)&target, sizeof(target));
+#endif
+ if (lenout < 0)
+ {
+ ayiya_log(LOG_ERR, reader_name, NULL, 0, "Error (%d) while sending %u bytes to network: %s (%d)\n", lenout, length, strerror(errno), errno);
+ }
+ else if (length != (unsigned int)lenout)
+ {
+ ayiya_log(LOG_ERR, reader_name, NULL, 0, "Only %u of %u bytes sent to network: %s (%s)\n", lenout, length, strerror(errno), errno);
+ }
+}
+
+struct tun_reader ayiya_tun = { (TUN_PROCESS)ayiya_reader };
+
+/* Socket -> Tun */
+#ifndef _WIN32
+void *ayiya_writer(void UNUSED *arg);
+void *ayiya_writer(void UNUSED *arg)
+#else
+DWORD WINAPI ayiya_writer(LPVOID arg);
+DWORD WINAPI ayiya_writer(LPVOID arg)
+#endif
+{
+ unsigned char buf[2048];
+ struct pseudo_ayh *s = (struct pseudo_ayh *)buf;
+ struct sockaddr_storage ci;
+ socklen_t cl;
+ int i, n;
+ unsigned int payloadlen = 0;
+ SHA_CTX sha1;
+ sha1_byte their_hash[SHA1_DIGEST_LENGTH],
+ our_hash[SHA1_DIGEST_LENGTH];
+
+ ayiya_log(LOG_INFO, writer_name, NULL, 0, "(Socket to TUN) started\n");
+
+ /* Tun/TAP device is now running */
+ g_aiccu->tunrunning = true;
+
+ while (true)
+ {
+ cl = sizeof(ci);
+ memset(buf, 0, sizeof(buf));
+ n = recvfrom(ayiya_socket->socket, (char *)buf, sizeof(buf), 0, (struct sockaddr *)&ci, &cl);
+
+ if (n < 0) continue;
+
+ if (n < (int)sizeof(struct ayiyahdr))
+ {
+ ayiya_log(LOG_WARNING, writer_name, &ci, cl, "Received packet is too short");
+ continue;
+ }
+
+ if ( s->ayh.ayh_idlen != 4 ||
+ s->ayh.ayh_idtype != ayiya_id_integer ||
+ s->ayh.ayh_siglen != 5 ||
+ s->ayh.ayh_hshmeth != ayiya_hash_sha1 ||
+ s->ayh.ayh_autmeth != ayiya_auth_sharedsecret ||
+ (s->ayh.ayh_nextheader != IPPROTO_IPV6 &&
+ s->ayh.ayh_nextheader != IPPROTO_NONE) ||
+ (s->ayh.ayh_opcode != ayiya_op_forward &&
+ s->ayh.ayh_opcode != ayiya_op_echo_request &&
+ s->ayh.ayh_opcode != ayiya_op_echo_request_forward))
+ {
+ /* Invalid AYIYA packet */
+ ayiya_log(LOG_ERR, writer_name, &ci, cl, "Dropping invalid AYIYA packet\n");
+ ayiya_log(LOG_ERR, writer_name, &ci, cl, "idlen: %u != %u\n", s->ayh.ayh_idlen, 4);
+ ayiya_log(LOG_ERR, writer_name, &ci, cl, "idtype: %u != %u\n", s->ayh.ayh_idtype, ayiya_id_integer);
+ ayiya_log(LOG_ERR, writer_name, &ci, cl, "siglen: %u != %u\n", s->ayh.ayh_siglen, 5);
+ ayiya_log(LOG_ERR, writer_name, &ci, cl, "hshmeth: %u != %u\n", s->ayh.ayh_hshmeth, ayiya_hash_sha1);
+ ayiya_log(LOG_ERR, writer_name, &ci, cl, "autmeth: %u != %u\n", s->ayh.ayh_autmeth, ayiya_auth_sharedsecret);
+ ayiya_log(LOG_ERR, writer_name, &ci, cl, "nexth : %u != %u || %u\n", s->ayh.ayh_nextheader, IPPROTO_IPV6, IPPROTO_NONE);
+ ayiya_log(LOG_ERR, writer_name, &ci, cl, "opcode : %u != %u || %u || %u\n", s->ayh.ayh_opcode, ayiya_op_forward, ayiya_op_echo_request, ayiya_op_echo_request_forward);
+ continue;
+ }
+
+ if (memcmp(&s->identity, &ayiya_ipv6_pop, sizeof(s->identity)) != 0)
+ {
+ memset(buf, 0, sizeof(buf));
+ inet_ntop(AF_INET6, &s->identity, (char *)&buf, sizeof(buf));
+ ayiya_log(LOG_WARNING, writer_name, &ci, cl, "Received packet from a wrong identity \"%s\"\n", buf);
+ continue;
+ }
+
+ /* Verify the epochtime */
+ i = tic_checktime(ntohl(s->ayh.ayh_epochtime));
+ if (i != 0)
+ {
+ memset(buf, 0, sizeof(buf));
+ inet_ntop(AF_INET6, &s->identity, (char *)&buf, sizeof(buf));
+ ayiya_log(LOG_WARNING, writer_name, &ci, cl, "Time is %d seconds off for %s\n", i, buf);
+ continue;
+ }
+
+ /* How long is the payload? */
+ payloadlen = n - (sizeof(*s) - sizeof(s->payload));
+
+ /* Save their hash */
+ memcpy(&their_hash, &s->hash, sizeof(their_hash));
+
+ /* Copy in our SHA1 hash */
+ memcpy(&s->hash, &ayiya_hash, sizeof(s->hash));
+
+ /* Generate a SHA1 of the header + identity + shared secret */
+ SHA1_Init(&sha1);
+ /* Hash the Packet */
+ SHA1_Update(&sha1, (sha1_byte *)s, n);
+ /* Store the hash */
+ SHA1_Final(our_hash, &sha1);
+
+ memcpy(&s->hash, &our_hash, sizeof(s->hash));
+
+ /* Compare the SHA1's */
+ if (memcmp(&their_hash, &our_hash, sizeof(their_hash)) != 0)
+ {
+ ayiya_log(LOG_WARNING, writer_name, &ci, cl, "Incorrect Hash received\n");
+ continue;
+ }
+
+ if (s->ayh.ayh_nextheader == IPPROTO_IPV6)
+ {
+ /* Verify that this is really IPv6 */
+ if (s->payload[0] >> 4 != 6)
+ {
+ ayiya_log(LOG_ERR, writer_name, &ci, cl, "Received packet didn't start with a 6, thus is not IPv6\n");
+ continue;
+ }
+
+ /* Forward the packet to the kernel */
+ tun_write(s->payload, payloadlen);
+ }
+ }
+
+ /* Tun/TAP device is not running anymore */
+ g_aiccu->tunrunning = false;
+
+#ifndef _WIN32
+ return NULL;
+#else
+ return 0;
+#endif
+}
+
+/* Construct a beat and send it outwards */
+void ayiya_beat(void)
+{
+ SHA_CTX sha1;
+ sha1_byte hash[SHA1_DIGEST_LENGTH];
+ struct sockaddr_in target;
+ struct pseudo_ayh s;
+ int lenout, n;
+
+ /* We tunnel over IPv4 */
+ memcpy(&target.sin_addr, &ayiya_ipv4_pop, sizeof(target.sin_addr));
+ target.sin_family = AF_INET;
+ target.sin_port = htons(atoi(AYIYA_PORT));
+
+ /* Prefill some standard AYIYA values */
+ memset(&s, 0, sizeof(s));
+ s.ayh.ayh_idlen = 4; /* 2^4 = 16 bytes = 128 bits (IPv6 address) */
+ s.ayh.ayh_idtype = ayiya_id_integer;
+ s.ayh.ayh_siglen = 5; /* 5*4 = 20 bytes = 160 bits (SHA1) */
+ s.ayh.ayh_hshmeth = ayiya_hash_sha1;
+ s.ayh.ayh_autmeth = ayiya_auth_sharedsecret;
+ s.ayh.ayh_opcode = ayiya_op_noop;
+ s.ayh.ayh_nextheader = IPPROTO_NONE;
+
+ /* Our IPv6 side of this tunnel */
+ memcpy(&s.identity, &ayiya_ipv6_local, sizeof(s.identity));
+
+ /* No Payload */
+
+ /* Fill in the current time */
+ s.ayh.ayh_epochtime = htonl((u_long)time(NULL));
+
+ /* Our IPv6 side of this tunnel */
+ memcpy(&s.identity, &ayiya_ipv6_local, sizeof(s.identity));
+
+ /*
+ * The hash of the shared secret needs to be in the
+ * spot where we later put the complete hash
+ */
+ memcpy(&s.hash, ayiya_hash, sizeof(s.hash));
+
+ /* Generate a SHA1 */
+ SHA1_Init(&sha1);
+ /* Hash the complete AYIYA packet */
+ SHA1_Update(&sha1, (sha1_byte *)&s, sizeof(s)-sizeof(s.payload));
+ /* Store the hash in the packets hash */
+ SHA1_Final(hash, &sha1);
+
+ /* Store the hash in the actual packet */
+ memcpy(&s.hash, &hash, sizeof(s.hash));
+
+ /* Send it onto the network */
+ n = sizeof(s)-sizeof(s.payload);
+#if defined(_FREEBSD) || defined(_DFBSD) || defined(_OPENBSD) || defined(_DARWIN) || defined(_NETBSD)
+ lenout = send(ayiya_socket->socket, (const char *)&s, (unsigned int)n, 0);
+#else
+ lenout = sendto(ayiya_socket->socket, (const char *)&s, (unsigned int)n, 0, (struct sockaddr *)&target, sizeof(target));
+#endif
+ if (lenout < 0)
+ {
+ ayiya_log(LOG_ERR, beat_name, NULL, 0, "Error (%d) while sending %u bytes sent to network: %s (%d)\n", lenout, n, strerror(errno), errno);
+ }
+ else if (n != lenout)
+ {
+ ayiya_log(LOG_ERR, beat_name, NULL, 0, "Only %u of %u bytes sent to network: %s (%d)\n", lenout, n, strerror(errno), errno);
+ }
+}
+
+bool ayiya(struct TIC_Tunnel *hTunnel)
+{
+ SHA_CTX sha1;
+ struct addrinfo hints, *res, *ressave;
+#ifndef _WIN32
+ pthread_t thread;
+#else
+ DWORD pID;
+ HANDLE h;
+#endif
+
+ /* Setup the tunnel */
+ if (!tun_start(&ayiya_tun)) return false;
+
+ /* Resolve hTunnel entries */
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = SOCK_DGRAM;
+
+ if (getaddrinfo(hTunnel->sIPv4_POP, AYIYA_PORT, &hints, &res) != 0)
+ {
+ dolog(LOG_ERR, "Couldn't resolve PoP IPv4 %s\n", hTunnel->sIPv4_POP);
+ return false;
+ }
+ ressave = res;
+ while (res)
+ {
+ if (res->ai_family != AF_INET)
+ {
+ res = res->ai_next;
+ continue;
+ }
+ memcpy(&ayiya_ipv4_pop, &((struct sockaddr_in *)res->ai_addr)->sin_addr, 4);
+ break;
+ }
+ freeaddrinfo(ressave);
+ if (res == NULL)
+ {
+ dolog(LOG_ERR, "No valid IPv4 address for PoP address %s could be found\n", hTunnel->sIPv4_POP);
+ return false;
+ }
+
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = AF_INET6;
+ if (getaddrinfo(hTunnel->sIPv6_Local, NULL, &hints, &res) != 0)
+ {
+ dolog(LOG_ERR, "Couldn't resolve Local IPv6 %s\n", hTunnel->sIPv6_Local);
+ return false;
+ }
+ ressave = res;
+ while (res)
+ {
+ if (res->ai_family != AF_INET6)
+ {
+ res = res->ai_next;
+ continue;
+ }
+ memcpy(&ayiya_ipv6_local, &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr, 16);
+ break;
+ }
+ freeaddrinfo(ressave);
+ if (res == NULL)
+ {
+ dolog(LOG_ERR, "No valid IPv6 address for Local IPv6 address %s could be found\n", hTunnel->sIPv6_Local);
+ return false;
+ }
+
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = AF_INET6;
+ if (getaddrinfo(hTunnel->sIPv6_POP, NULL, &hints, &res) != 0)
+ {
+ dolog(LOG_ERR, "Couldn't resolve Local IPv6 %s\n", hTunnel->sIPv6_POP);
+ return false;
+ }
+ ressave = res;
+ while (res)
+ {
+ if (res->ai_family != AF_INET6)
+ {
+ res = res->ai_next;
+ continue;
+ }
+ memcpy(&ayiya_ipv6_pop, &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr, 16);
+ break;
+ }
+ freeaddrinfo(ressave);
+ if (res == NULL)
+ {
+ dolog(LOG_ERR, "No valid IPv6 address for POP IPv6 address %s could be found\n", hTunnel->sIPv6_POP);
+ return false;
+ }
+
+ if (!hTunnel->sPassword)
+ {
+ dolog(LOG_ERR, "A password is required for using AYIYA tunnels\n");
+ return false;
+ }
+
+ /* Generate a SHA1 of the shared secret */
+ SHA1_Init(&sha1);
+ SHA1_Update(&sha1, (const sha1_byte *)hTunnel->sPassword, (unsigned int)strlen(hTunnel->sPassword));
+ SHA1_Final(ayiya_hash, &sha1);
+
+ /* Setup listening socket */
+ ayiya_socket = connect_client(hTunnel->sIPv4_POP , AYIYA_PORT, AF_INET, SOCK_DGRAM);
+ if (!ayiya_socket)
+ {
+ ayiya_log(LOG_ERR, "start", NULL, 0, "Connection error:: could not create connection to AYIYA server\n");
+ return false;
+ }
+
+ /* Let AICCU configure the thing */
+ if (!aiccu_setup(hTunnel, false))
+ {
+ return false;
+ }
+
+ /* Show that we have started */
+ ayiya_log(LOG_INFO, "start", NULL, 0, "Anything in Anything (%s)\n", AYIYA_VERSION);
+
+ /* Launch a thread for reader */
+#ifndef _WIN32
+ pthread_create(&thread, NULL, ayiya_writer, (void *)hTunnel);
+#else
+ h = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ayiya_writer, hTunnel, 0, &pID);
+#endif
+
+ return true;
+}
--- /dev/null
+/**********************************************************
+ SixXS - Automatic IPv6 Connectivity Configuration Utility
+***********************************************************
+ Copyright 2003-2005 SixXS - http://www.sixxs.net
+***********************************************************
+ common/ayiya.c - AYIYA - Anything In Anything
+***********************************************************
+ $Author: jeroen $
+ $Id: ayiya.h,v 1.10 2006-07-13 19:33:39 jeroen Exp $
+ $Date: 2006-07-13 19:33:39 $
+**********************************************************/
+
+#ifndef AYIYA_H
+#define AYIYA_H "H5K7:W3NDY5UU5N1K1N1C0l3"
+
+#include "common.h"
+#include "tic.h"
+
+/* Anything In Anything - AYIYA (uses UDP in our case) */
+#define AYIYA_PORT "5072"
+/*#define AYIYA_PORT "8374"*/
+
+/*
+ * AYIYA version (which document this should conform to)
+ * Per draft-massar-v6ops-ayiya-02 (July 2004)
+ */
+#define AYIYA_VERSION "draft-02"
+
+enum ayiya_identities
+{
+ ayiya_id_none = 0x0, /* None */
+ ayiya_id_integer = 0x1, /* Integer */
+ ayiya_id_string = 0x2 /* ASCII String */
+};
+
+enum ayiya_hash
+{
+ ayiya_hash_none = 0x0, /* No hash */
+ ayiya_hash_md5 = 0x1, /* MD5 Signature */
+ ayiya_hash_sha1 = 0x2, /* SHA1 Signature */
+ ayiya_hash_umac = 0x3 /* UMAC Signature (UMAC: Message Authentication Code using Universal Hashing / draft-krovetz-umac-04.txt */
+};
+
+enum ayiya_auth
+{
+ ayiya_auth_none = 0x0, /* No authentication */
+ ayiya_auth_sharedsecret = 0x1, /* Shared Secret */
+ ayiya_auth_pgp = 0x2 /* Public/Private Key */
+};
+
+enum ayiya_opcode
+{
+ ayiya_op_noop = 0x0, /* No Operation */
+ ayiya_op_forward = 0x1, /* Forward */
+ ayiya_op_echo_request = 0x2, /* Echo Request */
+ ayiya_op_echo_request_forward = 0x3, /* Echo Request and Forward */
+ ayiya_op_echo_response = 0x4, /* Echo Response */
+ ayiya_op_motd = 0x5, /* MOTD */
+ ayiya_op_query_request = 0x6, /* Query Request */
+ ayiya_op_query_response = 0x7 /* Query Response */
+};
+
+struct ayiyahdr
+{
+#if BYTE_ORDER == BIG_ENDIAN
+ uint32_t ayh_idlen: 4; /* Identity Length */
+ uint32_t ayh_idtype: 4; /* Identity Type */
+ uint32_t ayh_siglen: 4; /* Signature Length */
+ uint32_t ayh_hshmeth:4; /* Hashing Method */
+ uint32_t ayh_autmeth:4; /* Authentication Method */
+ uint32_t ayh_opcode: 4; /* Operation Code */
+ uint32_t ayh_nextheader:8; /* Next Header (PROTO_*) */
+#elif BYTE_ORDER == LITTLE_ENDIAN
+ uint32_t ayh_idtype: 4; /* Identity Type */
+ uint32_t ayh_idlen: 4; /* Identity Length */
+ uint32_t ayh_hshmeth:4; /* Hashing Method */
+ uint32_t ayh_siglen: 4; /* Signature Length */
+ uint32_t ayh_opcode: 4; /* Operation Code */
+ uint32_t ayh_autmeth:4; /* Authentication Method */
+ uint32_t ayh_nextheader:8; /* Next Header (PROTO_*) */
+#else
+#error unsupported endianness!
+#endif
+ uint32_t ayh_epochtime; /* Time in seconds since "00:00:00 1970-01-01 UTC" */
+};
+
+/* Functions */
+bool ayiya(struct TIC_Tunnel *hTunnel);
+void ayiya_beat(void);
+
+#endif /* AYIYA_H */
+
--- /dev/null
+/**********************************************************
+ SixXS - Automatic IPv6 Connectivity Configuration Utility
+***********************************************************
+ Copyright 2003-2005 SixXS - http://www.sixxs.net
+***********************************************************
+ common/common.c - Common Functions
+***********************************************************
+ $Author: jeroen $
+ $Id: common.c,v 1.14 2006-12-21 14:08:50 jeroen Exp $
+ $Date: 2006-12-21 14:08:50 $
+**********************************************************/
+
+/* Dirty dependency for Windows:GUI version */
+#ifdef _WIN32
+#ifndef AICCU_CONSOLE
+#include "../windows-gui/stdafx.h"
+#include "../windows-gui/AICCUApp.h"
+extern CAICCUApp theApp;
+#endif
+#endif
+
+#include "aiccu.h"
+#include "common.h"
+
+/* getline debugging? */
+/*
+#define E(x) x
+ */
+#define E(x) {}
+
+void dologA(int level, const char *fmt, va_list ap)
+{
+#ifdef _WIN32
+ char buf[1024];
+#endif
+ /* Don't show noise */
+ if (g_aiccu && !g_aiccu->verbose && level == LOG_DEBUG) return;
+
+#ifndef _WIN32
+ if (g_aiccu && g_aiccu->daemonize > 0) vsyslog(LOG_LOCAL7|level, fmt, ap);
+ else
+ {
+ vfprintf(stderr, fmt, ap);
+ fflush(stderr);
+ }
+#else
+ vsnprintf(buf, sizeof(buf), fmt, ap);
+
+#ifndef AICCU_CONSOLE
+ /* Use the debug facility */
+ OutputDebugString(buf);
+
+ /* Store it in a log file if we are running in verbose mode */
+ if (g_aiccu && g_aiccu->verbose)
+ {
+ char logfile[1024];
+ FILE *f;
+
+ /* Figure out the "C:\Windows" location */
+ /* as that is where we store our configuration */
+ GetWindowsDirectory(logfile, sizeof(logfile));
+ strncat(logfile, "\\aiccu.log", sizeof(logfile));
+ f = fopen(logfile, "w+");
+ if (f)
+ {
+ fwrite(buf, strlen(buf), 1, f);
+ fclose(f);
+ }
+ }
+
+ /*
+ * Always store the last message
+ * which can be displayed as errors etc.
+ */
+
+ /* strip the \n */
+ if (strlen(buf) > 0) buf[strlen(buf)-1] = '\0';
+ theApp.m_sMessage = buf;
+#else
+ OutputDebugString("dolog() - ");
+ OutputDebugString(buf);
+ fprintf(stderr, "%s", buf);
+#endif /* AICCU_CONSOLE */
+#endif /* !_WIN32 */
+}
+
+void dolog(int level, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ dologA(level, fmt, ap);
+ va_end(ap);
+}
+
+/*
+ * Check if an address is RFC1918 based
+ * This allows us to warn the user that they are behind a NAT
+ */
+bool is_rfc1918(char *ipv4)
+{
+ unsigned int addr = inet_addr(ipv4);
+ bool ret = false;
+
+
+
+ ret = ( /* 10.0.0.0/8 */
+ ((addr & htonl(0xff000000)) == htonl(0x0a000000)) ||
+ /* 172.16.0.0/12 */
+ ((addr & htonl(0xfff00000)) == htonl(0xac100000)) ||
+ /* 192.168.0.0/16 */
+ ((addr & htonl(0xffff0000)) == htonl(0xc0a80000))) ? true : false;
+
+ dolog(LOG_DEBUG, "is_rfc1918(%s) = %s\n", ipv4, ret ? "yes" : "false");
+
+ return ret;
+}
+
+void sock_printf(TLSSOCKET sock, const char *fmt, ...)
+{
+ char buf[2048];
+ unsigned int len = 0, done = 0;
+ int ret;
+
+ va_list ap;
+ va_start(ap, fmt);
+ /* When not a socket send it to the logs */
+ if (sock == NULL || sock->socket == -1) dologA(LOG_INFO, fmt, ap);
+ else
+ {
+ /* Format the string */
+ len = vsnprintf(buf, sizeof(buf), fmt, ap);
+
+ /* Send the line(s) over the network */
+
+ while (done < len)
+ {
+#ifdef AICCU_GNUTLS
+ if (sock->tls_active) ret = gnutls_record_send(sock->session, &buf[done], len-done);
+ else
+#endif
+ ret = send(sock->socket, &buf[done], len-done, 0);
+
+ if (ret > 0) done+=ret;
+ else break;
+ }
+
+ /* Show this as debug output */
+ if (g_aiccu->verbose)
+ {
+ /* Strip the last \n */
+ len = (int)strlen(buf);
+ if (len > 0) buf[len-1] = '\0';
+ /* dump the information */
+ dolog(LOG_DEBUG, "sock_printf() : \"%s\"\n", buf);
+ }
+ }
+ va_end(ap);
+}
+
+extern char tic_buf[2048];
+
+/*
+ * Read a line from a socket and store it in ubuf
+ * Note: uses internal caching, this should be the only function
+ * used to read from the sock! The internal cache is rbuf.
+ */
+int sock_getline(TLSSOCKET sock, char *rbuf, unsigned int rbuflen, unsigned int *filled, char *ubuf, unsigned int ubuflen)
+{
+ unsigned int i;
+
+ if (!sock) return -1;
+
+ /* A closed socket? -> clear the buffer */
+ if (sock->socket == -1)
+ {
+ memset(rbuf, 0, rbuflen);
+ *filled = 0;
+ return -1;
+ }
+
+ /* Clear the caller supplied buffer, just in case */
+ memset(ubuf, 0, ubuflen);
+
+ for (;;)
+ {
+ E(dolog(LOG_DEBUG, "gl() - Filled %d\n", *filled);)
+
+ /* Did we still have something in the buffer? */
+ if (*filled > 0)
+ {
+ E(dolog(LOG_DEBUG, "gl() - Seeking newline\n");)
+
+ /* Walk to the end or until we reach a \n */
+ for (i=0; (i < (*filled-1)) && (rbuf[i] != '\n'); i++);
+
+ E(dolog(LOG_DEBUG, "gl() - Seeking newline - end\n");)
+
+ /* Did we find a newline? */
+ if (rbuf[i] == '\n')
+ {
+ E(dolog(LOG_DEBUG, "gl() - Found newline at %i\n", i+1);)
+
+ /* Newline with a Linefeed in front of it ? -> remove it */
+ if (rbuf[i] == '\n' && rbuf[i-1] == '\r')
+ {
+ E(dolog(LOG_DEBUG, "gl() - Removing LF\n");)
+ i--;
+ }
+ E(else dolog(LOG_DEBUG, "gl() - No LF\n");)
+
+ /* Copy this over to the caller */
+ memcpy(ubuf, rbuf, i);
+
+ E(dolog(LOG_DEBUG, "gl() - Copied %d bytes from %x to %x\n", i, rbuf, ubuf);)
+
+ /* Count the \r if it is there */
+ if (rbuf[i] == '\r') i++;
+ /* Count the \n */
+ i++;
+
+ /* filled = what is left in the buffer */
+ *filled -= i;
+
+ E(dolog(LOG_DEBUG, "gl() - %d bytes left in the buffer\n", *filled);)
+
+ /* Now move the rest of the buffer to the front */
+ if (*filled > 0) memmove(rbuf, &rbuf[i], *filled);
+ else *filled = 0;
+
+ /* Show this as debug output */
+ if (g_aiccu->verbose) dolog(LOG_DEBUG, "sock_getline() : \"%s\"\n", ubuf);
+
+ /* We got ourselves a line in 'buf' thus return to the caller */
+ return i;
+ }
+ }
+
+ E(dolog(LOG_DEBUG, "gl() - Trying to receive (max=%d)...\n", rbuflen-*filled-10);)
+
+ /* Fill the rest of the buffer */
+#ifdef AICCU_GNUTLS
+ if (sock->tls_active) i = gnutls_record_recv(sock->session, &rbuf[*filled], rbuflen-*filled-10);
+ else
+#endif
+ i = recv(sock->socket, &rbuf[*filled], rbuflen-*filled-10, 0);
+
+ E(dolog(LOG_DEBUG, "gl() - Received %d\n", i);)
+
+ /* Fail on errors */
+ if (i <= 0) return -1;
+
+ /* We got more filled space! */
+ *filled+=i;
+
+ /* Buffer overflow? */
+ if ( *filled >= (rbuflen-10) ||
+ *filled >= (ubuflen-10) )
+ {
+ dolog(LOG_ERR, "Buffer almost flowed over without receiving a newline\n");
+ return -1;
+ }
+
+ /* And try again in this loop ;) */
+ }
+
+ /* Never reached */
+ return -1;
+}
+
+TLSSOCKET sock_alloc(void);
+TLSSOCKET sock_alloc(void)
+{
+#ifdef AICCU_GNUTLS
+ /* Allow connections to servers that have OpenPGP keys as well */
+ const int cert_type_priority[3] = { GNUTLS_CRT_X509, GNUTLS_CRT_OPENPGP, 0 };
+ int ret;
+#endif /* AICCU_GNUTLS*/
+
+ TLSSOCKET sock;
+
+ sock = (TLSSOCKET)malloc(sizeof(*sock));
+ if (!sock) return NULL;
+
+ sock->socket = -1;
+
+#ifdef AICCU_GNUTLS
+ /* TLS is not active yet (use sock_gotls() for that) */
+ sock->tls_active = false;
+
+ /* Initialize TLS session */
+ ret = gnutls_init(&sock->session, GNUTLS_CLIENT);
+ if (ret != 0)
+ {
+ dolog(LOG_ERR, "TLS Init failed: %s (%d)\n", gnutls_strerror(ret), ret);
+ free(sock);
+ return NULL;
+ }
+
+ /* Use default priorities */
+ gnutls_set_default_priority(sock->session);
+ /* XXX: Return value is not documented in GNUTLS documentation! */
+
+ gnutls_certificate_type_set_priority(sock->session, cert_type_priority);
+ /* XXX: Return value is not documented in GNUTLS documentation! */
+
+ /* Configure the x509 credentials for the current session */
+ gnutls_credentials_set(sock->session, GNUTLS_CRD_CERTIFICATE, g_aiccu->tls_cred);
+ /* XXX: Return value is not documented in GNUTLS documentation! */
+
+#endif /* AICCU_GNUTLS*/
+
+ return sock;
+}
+
+void sock_free(TLSSOCKET sock)
+{
+ if (!sock) return;
+
+#ifdef AICCU_GNUTLS
+ if (sock->tls_active)
+ {
+ sock->tls_active = false;
+ gnutls_bye(sock->session, GNUTLS_SHUT_RDWR);
+ }
+#endif /* AICCU_GNUTLS*/
+
+ if (sock->socket >= 0)
+ {
+ /* Stop communications */
+ shutdown(sock->socket, SHUT_RDWR);
+ closesocket(sock->socket);
+ sock->socket = -1;
+ }
+
+#ifdef AICCU_GNUTLS
+ gnutls_deinit(sock->session);
+#endif /* AICCU_GNUTLS*/
+
+ free(sock);
+}
+
+/* Connect this client to a server */
+TLSSOCKET connect_client(const char *hostname, const char *service, int family, int socktype)
+{
+ TLSSOCKET sock;
+ struct addrinfo hints, *res, *ressave;
+
+ sock = sock_alloc();
+ if (!sock) return NULL;
+
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = family;
+ hints.ai_socktype = socktype;
+
+ if (getaddrinfo(hostname, service, &hints, &res) != 0)
+ {
+ dolog(LOG_ERR, "Couldn't resolve host %s, service %s\n", hostname, service);
+ sock_free(sock);
+ return NULL;
+ }
+
+ ressave = res;
+
+ while (res)
+ {
+ sock->socket = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+ if (sock->socket == -1) continue;
+ if (connect(sock->socket, res->ai_addr, (unsigned int)res->ai_addrlen) == 0) break;
+ closesocket(sock->socket);
+ sock->socket = -1;
+ res = res->ai_next;
+ }
+
+ freeaddrinfo(ressave);
+
+ if (sock->socket == -1)
+ {
+ sock_free(sock);
+ sock = NULL;
+ }
+
+ return sock;
+}
+
+TLSSOCKET listen_server(const char *description, const char *hostname, const char *service, int family, int socktype)
+{
+ struct addrinfo hints, *res, *ressave;
+ int n;
+ TLSSOCKET sock;
+ socklen_t on = 1;
+/*
+ D(dolog(LOG_DEBUG, "[%s] Trying to get socket for [%s]:%s over %s (%d) using %s (%d)\n",
+ description, hostname, service,
+ family == AF_INET ? "IPv4" : (family == AF_INET6 ? "IPv6" : "??"),
+ family,
+ socktype == IPPROTO_UDP ? "UDP" : (socktype == IPPROTO_TCP ? "TCP" : "??"),
+ socktype);)
+*/
+ sock = sock_alloc();
+ if (!sock) return NULL;
+
+ memset(&hints, 0, sizeof(struct addrinfo));
+
+ /* AI_PASSIVE flag: the resulting address is used to bind
+ to a socket for accepting incoming connections.
+ So, when the hostname==NULL, getaddrinfo function will
+ return one entry per allowed protocol family containing
+ the unspecified address for that family. */
+
+ hints.ai_flags = AI_PASSIVE;
+ hints.ai_family = family;
+ hints.ai_socktype = socktype;
+
+ n = getaddrinfo(hostname, service, &hints, &res);
+ if (n < 0)
+ {
+ dolog(LOG_ERR, "[%s] listen_server setup: getaddrinfo error: %s\n", description, gai_strerror(n));
+ sock_free(sock);
+ return NULL;
+ }
+
+ ressave=res;
+
+ /* Try to open socket with each address getaddrinfo returned,
+ until we get one valid listening socket. */
+ while (res)
+ {
+ sock->socket = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
+ if (!(sock->socket < 0))
+ {
+ setsockopt(sock->socket, SOL_SOCKET, SO_REUSEADDR, (const char *)&on, sizeof(on));
+ if (bind(sock->socket, res->ai_addr, (unsigned int)res->ai_addrlen) == 0) break;
+ closesocket(sock->socket);
+ sock->socket = -1;
+ }
+ res = res->ai_next;
+ }
+
+ freeaddrinfo(ressave);
+
+ if (sock->socket < 0)
+ {
+ dolog(LOG_ERR, "[%s] listen setup: socket error: could not open socket\n", description);
+ sock_free(sock);
+ return NULL;
+ }
+
+ if (listen(sock->socket, LISTEN_QUEUE) == -1)
+ {
+ dolog(LOG_ERR, "[%s] listen setup: socket error: could not listen on socket\n", description);
+ sock_free(sock);
+ return NULL;
+ }
+
+ dolog(LOG_INFO, "[%s] Listening on [%s]:%s\n", description, hostname, service);
+
+ return sock;
+}
+
+/*
+ * Put a socket into TLS mode
+ */
+#ifdef AICCU_GNUTLS
+bool sock_gotls(TLSSOCKET sock)
+{
+ int ret = 0;
+
+ if (!sock) return false;
+
+ if (sock->tls_active)
+ {
+ dolog(LOG_ERR, "Can't go into TLS mode twice!?\n");
+ return false;
+ }
+
+ /* Set the transport */
+ gnutls_transport_set_ptr(sock->session, (gnutls_transport_ptr)sock->socket);
+
+ /* Perform the TLS handshake */
+ ret = gnutls_handshake(sock->session);
+ if (ret < 0)
+ {
+ dolog(LOG_ERR, "TLS Handshake failed: %s (%d)\n", gnutls_strerror(ret), ret);
+ return false;
+ }
+
+ dolog(LOG_DEBUG, "TLS Handshake completed succesfully\n");
+
+ sock->tls_active = true;
+ return true;
+}
+#endif
+
+/* Count the number of fields in <s> */
+unsigned int countfields(char *s)
+{
+ int n = 1, i;
+ if (s == NULL) return 0;
+ for (i=0; s[i] != '\0'; i++) if (s[i] == ' ') n++;
+ return n;
+}
+
+/*
+ * Copy field <n> of string <s> into <buf> with a maximum of buflen
+ * First field is 1
+ */
+bool copyfield(char *s, unsigned int n, char *buf, unsigned int buflen)
+{
+ unsigned int begin = 0, i=0;
+
+ /* Clear the buffer */
+ memset(buf, 0, buflen);
+
+ while (s[i] != '\0')
+ {
+ n--;
+ begin = i;
+
+ /* Find next delimiter */
+ for (; s[i] != '\0' && s[i] != ' '; i++);
+
+ if (n == 0)
+ {
+ i-=begin;
+ strncpy(buf, s+begin, i > buflen ? buflen : i);
+ /* dolog(LOG_DEBUG, "copyfield() : '%s', begin = %d, len = %d\n", buf, begin, i); */
+ return true;
+ }
+
+ i++;
+ }
+ dolog(LOG_WARNING, "copyfield() - Field %u didn't exist in '%s'\n", n, s);
+ return false;
+}
+
+bool parseline(char *line, const char *split, struct pl_rule *rules, void *data)
+{
+ unsigned int r, len;
+ char *end = NULL, *val = NULL, *p = NULL;
+ void *store;
+
+ /* Chop off \n and \r and white space */
+ p = &line[strlen(line)-1];
+ while ( p >= line && (
+ *p == '\n' ||
+ *p == '\r' ||
+ *p == '\t' ||
+ *p == ' ')) *p-- = '\0';
+
+ /* Ignore comments and emtpy lines */
+ if ( strlen(line) == 0 ||
+ line[0] == '#' ||
+ line[0] == ';' ||
+ (line[0] == '/' && line[1] == '/'))
+ {
+ return true;
+ }
+
+ /* Get the end of the first argument */
+ p = line;
+ end = &line[strlen(line)-1];
+ /* Skip until whitespace */
+ while ( p < end &&
+ strncmp(p, split, strlen(split)) != 0) p++;
+ /* Terminate this argument */
+ *p = '\0';
+ p++;
+
+ /* Skip whitespace */
+ while ( p < end &&
+ *p == ' ' &&
+ *p == '\t') p++;
+
+ /* Start of the value */
+ val = p+(strlen(split)-1);
+
+ /* If starting with quotes, skip until next quote */
+ if (*p == '"' || *p == '\'')
+ {
+ p++;
+ /* Find next quote */
+ while (p <= end &&
+ *p != *val &&
+ *p != '\0') p++;
+ /* Terminate */
+ *p = '\0';
+ /* Skip the first quote */
+ val++;
+ }
+ /* Otherwise it is already terminated above */
+
+ /* Walk through all the rules */
+ for (r = 0; rules[r].type != PLRT_END; r++)
+ {
+ len = (int)strlen(rules[r].title);
+ if (strncmp(line, rules[r].title, len) != 0) continue;
+
+ store = (void *)((char *)data + rules[r].offset);
+
+ switch (rules[r].type)
+ {
+ case PLRT_STRING:
+ if (*((char **)store)) free(*((char **)store));
+ *((char **)store) = strdup(val);
+ break;
+
+ case PLRT_INTEGER:
+ *((uint32_t *)store) = atoi(val);
+ break;
+
+ case PLRT_BOOL:
+ if ( strcmp(val, "yes") == 0 ||
+ strcmp(val, "true") == 0)
+ {
+ *((bool *)store) = true;
+ }
+ else if (strcmp(val, "no") == 0 ||
+ strcmp(val, "false") == 0)
+ {
+ *((bool *)store) = false;
+ }
+ else
+ {
+ dolog(LOG_WARNING, "Unknown boolean value \"%s\" for option \"%s\"\n", val, rules[r].title);
+ }
+ break;
+
+ case PLRT_IPV4:
+ inet_pton(AF_INET, val, store);
+ break;
+
+ case PLRT_IPV6:
+ inet_pton(AF_INET6, val, store);
+ break;
+
+ case PLRT_END:
+ return false;
+ }
+ return true;
+ }
+ return false;
+}
+
+/*
+ * MD5 a string
+ * sSignature's size MUST be 32 bytes!
+ */
+void MD5String(const char *sString, char *sSignature, unsigned int siglen)
+{
+ struct MD5Context md5c;
+ unsigned char signature[16];
+ unsigned int i;
+
+ if (siglen < 32) return;
+
+ /* Initialize MD5 structure */
+ MD5Init(&md5c);
+ /* Calculate MD5 of the string */
+ MD5Update(&md5c, (unsigned char *)sString, (unsigned int)strlen(sString));
+ MD5Final(signature, &md5c);
+
+ memset(sSignature, 0, siglen);
+
+ for (i=0; i < sizeof(signature); i++)
+ {
+ snprintf(&sSignature[i*2], 3, "%02x", signature[i]);
+ }
+}
+
+#ifdef _AIX
+/* AIX doesn't have vsyslog() thus we implement it here */
+void vsyslog(int priority, const char *format, va_list ap)
+{
+ char buf[1024];
+ vsnprintf(buf, sizeof(buf), format, ap);
+ syslog(priority, buf);
+}
+#endif
+
+#ifdef _WIN32
+const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt)
+{
+ if (af == AF_INET)
+ {
+ struct sockaddr_in in;
+ memset(&in, 0, sizeof(in));
+ in.sin_family = AF_INET;
+ memcpy(&in.sin_addr, src, sizeof(struct in_addr));
+ getnameinfo((struct sockaddr *)&in, sizeof(struct sockaddr_in), dst, cnt, NULL, 0, NI_NUMERICHOST);
+ return dst;
+ }
+ else if (af == AF_INET6)
+ {
+ struct sockaddr_in6 in;
+ memset(&in, 0, sizeof(in));
+ in.sin6_family = AF_INET6;
+ memcpy(&in.sin6_addr, src, sizeof(struct in_addr6));
+ getnameinfo((struct sockaddr *)&in, sizeof(struct sockaddr_in6), dst, cnt, NULL, 0, NI_NUMERICHOST);
+ return dst;
+ }
+ return NULL;
+}
+
+int inet_pton(int af, const char *src, void *dst)
+{
+ struct addrinfo hints, *res, *ressave;
+
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = af;
+
+ if (getaddrinfo(src, NULL, &hints, &res) != 0)
+ {
+ dolog(LOG_ERR, "Couldn't resolve host %s\n", src);
+ return -1;
+ }
+
+ ressave = res;
+
+ while (res)
+ {
+ /* Check if AF is correct */
+ if (res->ai_family != af)
+ {
+ res = res->ai_next;
+ continue;
+ }
+
+ /* This is the one we want */
+ memcpy(dst, res->ai_addr, af == AF_INET6 ? sizeof(struct in_addr6) : sizeof(struct in_addr));
+
+ /* We only need one */
+ break;
+ }
+
+ freeaddrinfo(ressave);
+ return 0;
+}
+
+#endif
--- /dev/null
+/**********************************************************
+ SixXS - Automatic IPv6 Connectivity Configuration Utility
+***********************************************************
+ Copyright 2003-2005 SixXS - http://www.sixxs.net
+***********************************************************
+ common/common.h - Common Definitions
+***********************************************************
+ $Author: jeroen $
+ $Id: common.h,v 1.23 2007-01-11 14:50:51 jeroen Exp $
+ $Date: 2007-01-11 14:50:51 $
+**********************************************************/
+
+#ifndef AICCU_COMMON_H
+#define AICCU_COMMON_H "H5K7:W3NDY5UU5N1K1N1C0l3"
+
+#ifdef _DEBUG
+#define D(x) x
+#else
+#define D(x) {}
+#endif
+
+#ifndef _OPENBSD
+#ifndef _SUNOS
+#ifndef _AIX
+#ifndef _XOPEN_SOURCE
+#define _XOPEN_SOURCE
+#endif
+#endif
+#endif
+#endif
+#define __STRICT_ANSI__
+
+/* Don't deprecate strncat etc. */
+#ifdef _WIN32
+#define _CRT_SECURE_NO_DEPRECATE
+#endif
+
+#ifdef _AIX
+#define _H_ARPA_ONAMESER_COMPAT "AICCU workaround"
+#include <net/net_globals.h>
+#endif
+
+#include <stdio.h>
+#include <errno.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <time.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#if defined(_SUNOS) || defined(_AIX) || defined(_DARWIN)
+/* Include this as it knows quite a bit about endianess */
+#include <arpa/nameser_compat.h>
+#else
+#ifndef _WIN32
+#if defined(_OPENBSD) || defined(_DFBSD) || defined(_FREEBSD) || defined(_NETBSD)
+#include <sys/endian.h>
+#else
+#include <endian.h>
+#endif
+#endif
+#endif
+
+/* For MD5 routines */
+#define __USE_BSD 1
+#include <sys/types.h>
+
+#ifndef _WIN32
+ /* Unix Specifics */
+
+#ifndef linux
+ #include <netinet/in_systm.h>
+#endif
+
+#ifdef _DARWIN
+#define _BSD_SOCKLEN_T_
+#endif
+
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #include <netdb.h>
+ #include <unistd.h>
+ #include <strings.h>
+ #include <syslog.h>
+ #include <arpa/inet.h>
+ #include <sys/ioctl.h>
+ #include <sys/select.h>
+
+ #include <net/if.h>
+ #include <netinet/if_ether.h>
+#ifdef linux
+ #include <netpacket/packet.h>
+ #include <linux/if_tun.h>
+#else
+#ifdef _DFBSD
+ #include <net/tun/if_tun.h>
+#else
+#ifdef _DARWIN
+ /*
+ * Darwin doesn't have TUN/TAP support per default
+ * It is available from http://www-user.rhrk.uni-kl.de/~nissler/tuntap/
+ * which is a port made by Mattias Nissler
+ * for compiling convienience we have included the ioctl's here
+ */
+ #define TUNSIFHEAD _IOW('t', 96, int)
+ #define TUNGIFHEAD _IOR('t', 97, int)
+#else
+#ifndef _AIX
+ #include <net/if_tun.h>
+/* endif for !_AIX */
+#endif
+/* endif for _DARWIN else */
+#endif
+/* endif for _DFBSD else */
+#endif
+/* endif for linux else */
+#endif
+ #include <netinet/ip.h>
+ #include <netinet/ip6.h>
+ #include <netinet/icmp6.h>
+ #include <netinet/tcp.h>
+ #include <netinet/udp.h>
+ #include <netinet/ip_icmp.h>
+ #include <sys/ioctl.h>
+
+#if defined(_OPENBSD) || defined(_DARWIN) || defined(_FREEBSD) || defined(_DFBSD)
+ #include <sys/uio.h>
+#endif
+
+ #include <pthread.h>
+
+ /*
+ * Windows abstracts sockets to a different
+ * type, as this is actually pretty nice
+ * we'll do it too
+ */
+ #ifndef SOCKET
+ typedef int SOCKET;
+ #endif
+
+ /* closesocket() -> close() on unices */
+ #define closesocket close
+
+ /*
+ * Expect a BSD style in6_addr who puts
+ * this between a #ifdef _KERNEL...
+ * Probably against people doing stuff in userspace?
+ */
+ #ifndef s6_addr
+ #ifndef _SUNOS
+ #define s6_addr __u6_addr.__u6_addr8
+ #else
+ #define s6_addr _S6_un._S6_u8
+ #endif
+ #endif
+#else
+
+ /* Winsock */
+ #include <winsock2.h>
+ #include <ws2tcpip.h>
+
+ /* Windows Specifics */
+ #include <io.h>
+
+/*
+ * Some weird M$ person thought it was
+ * funny to underscore common functions !?
+ */
+ #define snprintf _snprintf
+ #define vsnprintf _vsnprintf
+ #define strcasecmp _stricmp
+ #define strncasecmp _strnicmp
+ #define strdup _strdup
+
+ /*
+ * Capitalize this one
+ * Sleep() is in milliseconds
+ */
+ #define sleep(x) Sleep(x*1000)
+
+ /* No syslog on Windows */
+ #define LOG_DEBUG 1
+ #define LOG_ERR 2
+ #define LOG_WARNING 3
+ #define LOG_INFO 4
+
+ typedef unsigned long u_int32_t;
+ typedef unsigned long long u_int64_t;
+
+ typedef unsigned char u_int8_t;
+ typedef unsigned __int16 u_int16_t;
+ typedef unsigned __int64 u_int64_t;
+
+ /* Not available in the Winsock2 includes */
+ #define IPPROTO_NONE 59 /* IPv6 no next header */
+
+ #define BIG_ENDIAN 4321
+ #define LITTLE_ENDIAN 1234
+
+ #define __BIG_ENDIAN BIG_ENDIAN
+ #define __LITTLE_ENDIAN LITTLE_ENDIAN
+
+ /* Fix byte order */
+ #define __BYTE_ORDER __LITTLE_ENDIAN
+ #define BYTE_ORDER LITTLE_ENDIAN
+
+ #define s6_addr16 _S6_un.Word
+ #define SHUT_RDWR SD_BOTH
+ #define uint8_t u_int8_t
+ #define uint16_t u_int16_t
+ #define uint32_t u_int32_t
+ #define uint64_t u_int64_t
+
+ struct ether
+ {
+ uint16_t ether_dhost[3];
+ uint16_t ether_shost[3];
+ uint16_t ether_type;
+ };
+
+ /* The IPv6 Header */
+ struct ip6_hdr
+ {
+ union
+ {
+ struct ip6_hdrctl
+ {
+ uint32_t ip6_un1_flow; /* 4 bits version, 8 bits TC, 20 bits flow-ID */
+ uint16_t ip6_un1_plen; /* payload length */
+ uint8_t ip6_un1_nxt; /* next header */
+ uint8_t ip6_un1_hlim; /* hop limit */
+ } ip6_un1;
+ uint8_t ip6_un2_vfc; /* 4 bits version, top 4 bits tclass */
+ } ip6_ctlun;
+ struct in6_addr ip6_src; /* source address */
+ struct in6_addr ip6_dst; /* destination address */
+ };
+
+ /* ICMPv6 */
+ struct icmp6_hdr
+ {
+ uint8_t icmp6_type; /* type field */
+ uint8_t icmp6_code; /* code field */
+ uint16_t icmp6_cksum; /* checksum field */
+ union
+ {
+ uint32_t icmp6_un_data32[1]; /* type-specific field */
+ uint16_t icmp6_un_data16[2]; /* type-specific field */
+ uint8_t icmp6_un_data8[4]; /* type-specific field */
+ } icmp6_dataun;
+ };
+
+ #define ND_NEIGHBOR_SOLICIT 135
+ #define ND_NEIGHBOR_ADVERT 136
+
+ struct nd_neighbor_solicit
+ {
+ struct in6_addr nd_ns_target; /* target address */
+ /* could be followed by options */
+ };
+
+ struct nd_neighbor_advert
+ {
+ struct in6_addr nd_na_target; /* target address */
+ /* could be followed by options */
+ uint8_t nd_no_type; /* Option providing the target MAC address */
+ uint8_t nd_no_len; /* Length (1) */
+ uint8_t nd_no_mac[6]; /* MAC address */
+
+ };
+
+ const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt);
+ int inet_pton(int af, const char *src, void *dst);
+#endif /* WIN32 */
+
+
+#ifndef MSG_NOSIGNAL
+#define MSG_NOSIGNAL 0
+#endif
+
+#ifndef LITTLE_ENDIAN
+#define LITTLE_ENDIAN __LITTLE_ENDIAN
+#endif
+#ifndef BIG_ENDIAN
+#define BIG_ENDIAN __BIG_ENDIAN
+#endif
+#ifndef PDP_ENDIAN
+#define PDP_ENDIAN __PDP_ENDIAN
+#endif
+#ifndef BYTE_ORDER
+#define BYTE_ORDER __BYTE_ORDER
+#endif
+
+/* Boolean support */
+#ifndef bool
+#define bool uint32_t
+#endif
+#ifndef false
+#define false 0
+#endif
+#ifndef true
+#define true (!false)
+#endif
+
+#ifndef offsetof
+#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
+#endif
+
+/* Include MD5 and SHA1 support */
+#include "hash_md5.h"
+#include "hash_sha1.h"
+
+/* Resolver includes */
+#ifndef _WIN32
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+#include <netdb.h>
+#endif
+
+#ifdef AICCU_GNUTLS
+#include <gnutls/gnutls.h>
+#endif
+
+#ifndef NS_GET16SZ
+#define NS_INT32SZ 4 /* #/bytes of data in a u_int32_t */
+#endif
+
+#ifndef NS_GET32SZ
+#define NS_INT16SZ 2 /* #/bytes of data in a u_int16_t */
+#endif
+
+
+#ifndef NS_GET16
+#define NS_GET16(s, cp) do { \
+ register u_char *t_cp = (u_char *)(cp); \
+ (s) = ((u_int16_t)t_cp[0] << 8) \
+ | ((u_int16_t)t_cp[1]) \
+ ; \
+ (cp) += NS_INT16SZ; \
+} while (0)
+#endif
+
+#ifndef NS_GET32
+#define NS_GET32(l, cp) do { \
+ register u_char *t_cp = (u_char *)(cp); \
+ (l) = ((u_int32_t)t_cp[0] << 24) \
+ | ((u_int32_t)t_cp[1] << 16) \
+ | ((u_int32_t)t_cp[2] << 8) \
+ | ((u_int32_t)t_cp[3]) \
+ ; \
+ (cp) += NS_INT32SZ; \
+} while (0)
+#endif
+
+/* parseline() rules */
+enum pl_ruletype
+{
+ PLRT_STRING, /* Offset points to a String (strdup()) */
+ PLRT_INTEGER, /* Offset points to a Integer (unsigned int) */
+ PLRT_BOOL, /* Offset points to a Boolean. */
+ PLRT_IPV4, /* Offset points to a IPv4 address (inet_pton(..., AF_INET)) */
+ PLRT_IPV6, /* Offset points to a IPv6 address (inet_pton(..., AF_INET6)) */
+ PLRT_END /* End of rules */
+};
+
+struct pl_rule
+{
+ const char *title;
+ unsigned int type;
+ unsigned int offset;
+};
+
+
+struct tlssocket
+{
+ SOCKET socket;
+#ifdef AICCU_GNUTLS
+ bool tls_active; /* TLS active? */
+ gnutls_session session; /* The GnuTLS sesision */
+#endif
+};
+
+typedef struct tlssocket * TLSSOCKET;
+
+/* Common Functions */
+void dologA(int level, const char *fmt, va_list ap);
+void dolog(int level, const char *fmt, ...);
+
+#ifdef _AIX
+void vsyslog(int priority, const char *format, va_list ap);
+#endif
+
+/* Networking functions */
+void sock_printf(TLSSOCKET sock, const char *fmt, ...);
+int sock_getline(TLSSOCKET sock, char *rbuf, unsigned int rbuflen, unsigned int *filled, char *ubuf, unsigned int ubuflen);
+TLSSOCKET connect_client(const char *hostname, const char *service, int family, int socktype);
+TLSSOCKET listen_server(const char *description, const char *hostname, const char *service, int family, int socktype);
+void sock_free(TLSSOCKET sock);
+#ifdef AICCU_GNUTLS
+bool sock_gotls(TLSSOCKET sock);
+#endif
+
+/* Parsing functions */
+unsigned int countfields(char *s);
+bool copyfield(char *s, unsigned int n, char *buf, unsigned int buflen);
+bool parseline(char *line, const char *split, struct pl_rule *rules, void *data);
+
+/* Convienience */
+void MD5String(const char *sString, char *sSignature, unsigned int siglen);
+bool is_rfc1918(char *ipv4);
+
+#endif /* AICCU_COMMON_H */
--- /dev/null
+/*
+ * This code implements the MD5 message-digest algorithm.
+ * The algorithm is due to Ron Rivest. This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * To compute the message digest of a chunk of bytes, declare an
+ * MD5Context structure, pass it to MD5Init, call MD5Update as
+ * needed on buffers full of bytes, and then call MD5Final, which
+ * will fill a supplied 16-byte array with the digest.
+ *
+ * Changed so as no longer to depend on Colin Plumb's `usual.h' header
+ * definitions; now uses stuff from dpkg's config.h.
+ * - Ian Jackson <ian@chiark.greenend.org.uk>.
+ * Still in the public domain.
+ */
+
+#include "aiccu.h"
+#include "hash_md5.h"
+
+#include <string.h> /* for memcpy() */
+#include <sys/types.h> /* for stupid systems */
+
+#ifdef WORDS_BIGENDIAN
+void byteSwap(UWORD32 *buf, unsigned words);
+void byteSwap(UWORD32 *buf, unsigned words)
+{
+ md5byte *p = (md5byte *)buf;
+
+ do {
+ *buf++ = (UWORD32)((unsigned)p[3] << 8 | p[2]) << 16 |
+ ((unsigned)p[1] << 8 | p[0]);
+ p += 4;
+ } while (--words);
+}
+#else
+#define byteSwap(buf,words)
+#endif
+
+/*
+ * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
+ * initialization constants.
+ */
+void
+MD5Init(struct MD5Context *ctx)
+{
+ ctx->buf[0] = 0x67452301;
+ ctx->buf[1] = 0xefcdab89;
+ ctx->buf[2] = 0x98badcfe;
+ ctx->buf[3] = 0x10325476;
+
+ ctx->bytes[0] = 0;
+ ctx->bytes[1] = 0;
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void
+MD5Update(struct MD5Context *ctx, md5byte const *buf, unsigned len)
+{
+ UWORD32 t;
+
+ /* Update byte count */
+
+ t = ctx->bytes[0];
+ if ((ctx->bytes[0] = t + len) < t)
+ ctx->bytes[1]++; /* Carry from low to high */
+
+ t = 64 - (t & 0x3f); /* Space available in ctx->in (at least 1) */
+ if (t > len) {
+ memcpy((md5byte *)ctx->in + 64 - t, buf, len);
+ return;
+ }
+ /* First chunk is an odd size */
+ memcpy((md5byte *)ctx->in + 64 - t, buf, t);
+ byteSwap(ctx->in, 16);
+ MD5Transform(ctx->buf, ctx->in);
+ buf += t;
+ len -= t;
+
+ /* Process data in 64-byte chunks */
+ while (len >= 64) {
+ memcpy(ctx->in, buf, 64);
+ byteSwap(ctx->in, 16);
+ MD5Transform(ctx->buf, ctx->in);
+ buf += 64;
+ len -= 64;
+ }
+
+ /* Handle any remaining bytes of data. */
+ memcpy(ctx->in, buf, len);
+}
+
+/*
+ * Final wrapup - pad to 64-byte boundary with the bit pattern
+ * 1 0* (64-bit count of bits processed, MSB-first)
+ */
+void
+MD5Final(md5byte digest[16], struct MD5Context *ctx)
+{
+ int count = ctx->bytes[0] & 0x3f; /* Number of bytes in ctx->in */
+ md5byte *p = (md5byte *)ctx->in + count;
+
+ /* Set the first char of padding to 0x80. There is always room. */
+ *p++ = 0x80;
+
+ /* Bytes of padding needed to make 56 bytes (-8..55) */
+ count = 56 - 1 - count;
+
+ if (count < 0) { /* Padding forces an extra block */
+ memset(p, 0, count + 8);
+ byteSwap(ctx->in, 16);
+ MD5Transform(ctx->buf, ctx->in);
+ p = (md5byte *)ctx->in;
+ count = 56;
+ }
+ memset(p, 0, count);
+ byteSwap(ctx->in, 14);
+
+ /* Append length in bits and transform */
+ ctx->in[14] = ctx->bytes[0] << 3;
+ ctx->in[15] = ctx->bytes[1] << 3 | ctx->bytes[0] >> 29;
+ MD5Transform(ctx->buf, ctx->in);
+
+ byteSwap(ctx->buf, 4);
+ memcpy(digest, ctx->buf, 16);
+ memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
+}
+
+#ifndef ASM_MD5
+
+/* The four core functions - F1 is optimized somewhat */
+
+/* #define F1(x, y, z) (x & y | ~x & z) */
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) F1(z, x, y)
+#define F3(x, y, z) (x ^ y ^ z)
+#define F4(x, y, z) (y ^ (x | ~z))
+
+/* This is the central step in the MD5 algorithm. */
+#define MD5STEP(f,w,x,y,z,in,s) \
+ (w += f(x,y,z) + in, w = (w<<s | w>>(32-s)) + x)
+
+/*
+ * The core of the MD5 algorithm, this alters an existing MD5 hash to
+ * reflect the addition of 16 longwords of new data. MD5Update blocks
+ * the data and converts bytes into longwords for this routine.
+ */
+void
+MD5Transform(UWORD32 buf[4], UWORD32 const in[16])
+{
+ register UWORD32 a, b, c, d;
+
+ a = buf[0];
+ b = buf[1];
+ c = buf[2];
+ d = buf[3];
+
+ MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7);
+ MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12);
+ MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17);
+ MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22);
+ MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7);
+ MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12);
+ MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17);
+ MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22);
+ MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7);
+ MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12);
+ MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
+ MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22);
+ MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7);
+ MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12);
+ MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17);
+ MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22);
+
+ MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5);
+ MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9);
+ MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14);
+ MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20);
+ MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5);
+ MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9);
+ MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
+ MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20);
+ MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5);
+ MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9);
+ MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14);
+ MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20);
+ MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5);
+ MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9);
+ MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14);
+ MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
+
+ MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4);
+ MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11);
+ MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
+ MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23);
+ MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4);
+ MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11);
+ MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16);
+ MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
+ MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4);
+ MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11);
+ MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16);
+ MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23);
+ MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4);
+ MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
+ MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
+ MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23);
+
+ MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6);
+ MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10);
+ MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15);
+ MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21);
+ MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6);
+ MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10);
+ MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15);
+ MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21);
+ MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6);
+ MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
+ MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15);
+ MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
+ MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6);
+ MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10);
+ MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15);
+ MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21);
+
+ buf[0] += a;
+ buf[1] += b;
+ buf[2] += c;
+ buf[3] += d;
+}
+
+#endif
--- /dev/null
+/*
+ * This is the header file for the MD5 message-digest algorithm.
+ * The algorithm is due to Ron Rivest. This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * To compute the message digest of a chunk of bytes, declare an
+ * MD5Context structure, pass it to MD5Init, call MD5Update as
+ * needed on buffers full of bytes, and then call MD5Final, which
+ * will fill a supplied 16-byte array with the digest.
+ *
+ * Changed so as no longer to depend on Colin Plumb's `usual.h'
+ * header definitions; now uses stuff from dpkg's config.h
+ * - Ian Jackson <ian@chiark.greenend.org.uk>.
+ * Still in the public domain.
+ */
+
+#ifndef MD5_H
+#define MD5_H
+
+#include "common.h"
+
+#ifdef _WIN32
+typedef unsigned long uint32;
+#define UWORD32 uint32
+
+#else /* _WIN32 */
+
+#ifdef _SUNOS
+typedef unsigned int uint32;
+#define UWORD32 uint32
+#else
+#define UWORD32 u_int32_t
+#endif /* _SUNOS */
+
+#endif /* _WIN32 */
+
+/* Determine Endianness */
+#if BYTE_ORDER == LITTLE_ENDIAN
+ /* 1234 machines */
+#elif BYTE_ORDER == BIG_ENDIAN
+ /* 4321 machines */
+# define WORDS_BIGENDIAN 1
+#elif BYTE_ORDER == PDP_ENDIAN
+ /* 3412 machines */
+#error PDP endianness not supported yet!
+#else
+#error unknown endianness!
+#endif
+
+#define md5byte unsigned char
+
+struct MD5Context {
+ UWORD32 buf[4];
+ UWORD32 bytes[2];
+ UWORD32 in[16];
+};
+
+void MD5Init(struct MD5Context *context);
+void MD5Update(struct MD5Context *context, md5byte const *buf, unsigned len);
+void MD5Final(unsigned char digest[16], struct MD5Context *context);
+void MD5Transform(UWORD32 buf[4], UWORD32 const in[16]);
+
+#endif /* !MD5_H */
--- /dev/null
+/*
+ * sha1.c
+ *
+ * Originally witten by Steve Reid <steve@edmweb.com>
+ *
+ * Modified by Aaron D. Gifford <agifford@infowest.com>
+ *
+ * NO COPYRIGHT - THIS IS 100% IN THE PUBLIC DOMAIN
+ *
+ * The original unmodified version is available at:
+ * ftp://ftp.funet.fi/pub/crypt/hash/sha/sha1.c
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "hash_sha1.h"
+#include <stdlib.h>
+#include <string.h>
+
+#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
+
+/* blk0() and blk() perform the initial expand. */
+/* I got the idea of expanding during the round function from SSLeay */
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define blk0(i) (block->l[i] = (rol(block->l[i],24)&(sha1_quadbyte)0xFF00FF00) \
+ |(rol(block->l[i],8)&(sha1_quadbyte)0x00FF00FF))
+#else
+#define blk0(i) block->l[i]
+#endif
+
+#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
+ ^block->l[(i+2)&15]^block->l[i&15],1))
+
+/* (SHA_R0+SHA_R1), SHA_R2, SHA_R3, SHA_R4 are the different operations used in SHA1 */
+#define SHA_R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define SHA_R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
+#define SHA_R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
+#define SHA_R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
+#define SHA_R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
+
+typedef union _BYTE64QUAD16 {
+ sha1_byte c[64];
+ sha1_quadbyte l[16];
+} BYTE64QUAD16;
+
+/* Hash a single 512-bit block. This is the core of the algorithm. */
+void SHA1_Transform(sha1_quadbyte state[5], const sha1_byte buffer[64]);
+void SHA1_Transform(sha1_quadbyte state[5], const sha1_byte buffer[64])
+{
+ sha1_quadbyte a, b, c, d, e;
+ BYTE64QUAD16 *block;
+
+ block = (BYTE64QUAD16*)buffer;
+ /* Copy context->state[] to working vars */
+ a = state[0];
+ b = state[1];
+ c = state[2];
+ d = state[3];
+ e = state[4];
+ /* 4 rounds of 20 operations each. Loop unrolled. */
+ SHA_R0(a,b,c,d,e, 0); SHA_R0(e,a,b,c,d, 1); SHA_R0(d,e,a,b,c, 2); SHA_R0(c,d,e,a,b, 3);
+ SHA_R0(b,c,d,e,a, 4); SHA_R0(a,b,c,d,e, 5); SHA_R0(e,a,b,c,d, 6); SHA_R0(d,e,a,b,c, 7);
+ SHA_R0(c,d,e,a,b, 8); SHA_R0(b,c,d,e,a, 9); SHA_R0(a,b,c,d,e,10); SHA_R0(e,a,b,c,d,11);
+ SHA_R0(d,e,a,b,c,12); SHA_R0(c,d,e,a,b,13); SHA_R0(b,c,d,e,a,14); SHA_R0(a,b,c,d,e,15);
+ SHA_R1(e,a,b,c,d,16); SHA_R1(d,e,a,b,c,17); SHA_R1(c,d,e,a,b,18); SHA_R1(b,c,d,e,a,19);
+ SHA_R2(a,b,c,d,e,20); SHA_R2(e,a,b,c,d,21); SHA_R2(d,e,a,b,c,22); SHA_R2(c,d,e,a,b,23);
+ SHA_R2(b,c,d,e,a,24); SHA_R2(a,b,c,d,e,25); SHA_R2(e,a,b,c,d,26); SHA_R2(d,e,a,b,c,27);
+ SHA_R2(c,d,e,a,b,28); SHA_R2(b,c,d,e,a,29); SHA_R2(a,b,c,d,e,30); SHA_R2(e,a,b,c,d,31);
+ SHA_R2(d,e,a,b,c,32); SHA_R2(c,d,e,a,b,33); SHA_R2(b,c,d,e,a,34); SHA_R2(a,b,c,d,e,35);
+ SHA_R2(e,a,b,c,d,36); SHA_R2(d,e,a,b,c,37); SHA_R2(c,d,e,a,b,38); SHA_R2(b,c,d,e,a,39);
+ SHA_R3(a,b,c,d,e,40); SHA_R3(e,a,b,c,d,41); SHA_R3(d,e,a,b,c,42); SHA_R3(c,d,e,a,b,43);
+ SHA_R3(b,c,d,e,a,44); SHA_R3(a,b,c,d,e,45); SHA_R3(e,a,b,c,d,46); SHA_R3(d,e,a,b,c,47);
+ SHA_R3(c,d,e,a,b,48); SHA_R3(b,c,d,e,a,49); SHA_R3(a,b,c,d,e,50); SHA_R3(e,a,b,c,d,51);
+ SHA_R3(d,e,a,b,c,52); SHA_R3(c,d,e,a,b,53); SHA_R3(b,c,d,e,a,54); SHA_R3(a,b,c,d,e,55);
+ SHA_R3(e,a,b,c,d,56); SHA_R3(d,e,a,b,c,57); SHA_R3(c,d,e,a,b,58); SHA_R3(b,c,d,e,a,59);
+ SHA_R4(a,b,c,d,e,60); SHA_R4(e,a,b,c,d,61); SHA_R4(d,e,a,b,c,62); SHA_R4(c,d,e,a,b,63);
+ SHA_R4(b,c,d,e,a,64); SHA_R4(a,b,c,d,e,65); SHA_R4(e,a,b,c,d,66); SHA_R4(d,e,a,b,c,67);
+ SHA_R4(c,d,e,a,b,68); SHA_R4(b,c,d,e,a,69); SHA_R4(a,b,c,d,e,70); SHA_R4(e,a,b,c,d,71);
+ SHA_R4(d,e,a,b,c,72); SHA_R4(c,d,e,a,b,73); SHA_R4(b,c,d,e,a,74); SHA_R4(a,b,c,d,e,75);
+ SHA_R4(e,a,b,c,d,76); SHA_R4(d,e,a,b,c,77); SHA_R4(c,d,e,a,b,78); SHA_R4(b,c,d,e,a,79);
+ /* Add the working vars back into context.state[] */
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+ state[4] += e;
+ /* Wipe variables */
+ a = b = c = d = e = 0;
+}
+
+
+/* SHA1_Init - Initialize new context */
+void SHA1_Init(SHA_CTX* context) {
+ /* SHA1 initialization constants */
+ context->state[0] = 0x67452301;
+ context->state[1] = 0xEFCDAB89;
+ context->state[2] = 0x98BADCFE;
+ context->state[3] = 0x10325476;
+ context->state[4] = 0xC3D2E1F0;
+ context->count[0] = context->count[1] = 0;
+}
+
+/* Run your data through this. */
+void SHA1_Update(SHA_CTX *context, const sha1_byte *d, unsigned int len) {
+ unsigned int i, j;
+
+ /* Make a temporary storage as Transform destroys it */
+ sha1_byte *data = (sha1_byte *)malloc(len);
+ if (!data) exit(-42);
+ memcpy(data, d, len);
+
+ j = (context->count[0] >> 3) & 63;
+ if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++;
+ context->count[1] += (len >> 29);
+ if ((j + len) > 63) {
+ memcpy(&context->buffer[j], data, (i = 64-j));
+ SHA1_Transform(context->state, context->buffer);
+ for ( ; i + 63 < len; i += 64) {
+ SHA1_Transform(context->state, &data[i]);
+ }
+ j = 0;
+ }
+ else i = 0;
+ memcpy(&context->buffer[j], &data[i], len - i);
+
+ /* Free the temporary buffer */
+ free(data);
+}
+
+/* Add padding and return the message digest. */
+void SHA1_Final(sha1_byte digest[SHA1_DIGEST_LENGTH], SHA_CTX *context) {
+ sha1_quadbyte i, j;
+ sha1_byte finalcount[8];
+
+ for (i = 0; i < 8; i++) {
+ finalcount[i] = (sha1_byte)((context->count[(i >= 4 ? 0 : 1)]
+ >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
+ }
+ SHA1_Update(context, (sha1_byte *)"\200", 1);
+ while ((context->count[0] & 504) != 448) {
+ SHA1_Update(context, (sha1_byte *)"\0", 1);
+ }
+ /* Should cause a SHA1_Transform() */
+ SHA1_Update(context, finalcount, 8);
+ for (i = 0; i < SHA1_DIGEST_LENGTH; i++) {
+ digest[i] = (sha1_byte)
+ ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
+ }
+ /* Wipe variables */
+ i = j = 0;
+ memset(context->buffer, 0, SHA1_BLOCK_LENGTH);
+ memset(context->state, 0, SHA1_DIGEST_LENGTH);
+ memset(context->count, 0, 8);
+ memset(&finalcount, 0, 8);
+}
+
--- /dev/null
+/*
+ * sha.h
+ *
+ * Originally taken from the public domain SHA1 implementation
+ * written by by Steve Reid <steve@edmweb.com>
+ *
+ * Modified by Aaron D. Gifford <agifford@infowest.com>
+ *
+ * NO COPYRIGHT - THIS IS 100% IN THE PUBLIC DOMAIN
+ *
+ * The original unmodified version is available at:
+ * ftp://ftp.funet.fi/pub/crypt/hash/sha/sha1.c
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef __SHA1_H__
+#define __SHA1_H__
+
+#include "common.h"
+
+/* Define this if your machine is LITTLE_ENDIAN, otherwise #undef it: */
+/* Is defined in endian.h */
+/*
+#define LITTLE_ENDIAN
+ */
+
+/* Make sure you define these types for your architecture: */
+typedef uint32_t sha1_quadbyte; /* 4 byte type */
+typedef uint8_t sha1_byte; /* single byte type */
+
+/*
+ * Be sure to get the above definitions right. For instance, on my
+ * x86 based FreeBSD box, I define LITTLE_ENDIAN and use the type
+ * "unsigned long" for the quadbyte. On FreeBSD on the Alpha, however,
+ * while I still use LITTLE_ENDIAN, I must define the quadbyte type
+ * as "unsigned int" instead.
+ */
+
+#define SHA1_BLOCK_LENGTH 64
+#define SHA1_DIGEST_LENGTH 20
+
+/* The SHA1 structure: */
+typedef struct _SHA_CTX {
+ sha1_quadbyte state[5];
+ sha1_quadbyte count[2];
+ sha1_byte buffer[SHA1_BLOCK_LENGTH];
+} SHA_CTX;
+
+#ifndef NOPROTO
+void SHA1_Init(SHA_CTX *context);
+void SHA1_Update(SHA_CTX *context, const sha1_byte *data, unsigned int len);
+void SHA1_Final(sha1_byte digest[SHA1_DIGEST_LENGTH], SHA_CTX* context);
+#else
+void SHA1_Init();
+void SHA1_Update();
+void SHA1_Final();
+#endif
+
+#endif
+
--- /dev/null
+/**********************************************************
+ SixXS - Automatic IPv6 Connectivity Configuration Utility
+***********************************************************
+ Copyright 2003-2005 SixXS - http://www.sixxs.net
+***********************************************************
+ common/heartbeat.c - Heartbeat Code
+***********************************************************
+ $Author: jeroen $
+ $Id: heartbeat.c,v 1.9 2006-12-21 14:08:50 jeroen Exp $
+ $Date: 2006-12-21 14:08:50 $
+**********************************************************/
+
+#include "heartbeat.h"
+#include "aiccu.h"
+
+#include <stdio.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <ctype.h>
+#include <time.h>
+#include <signal.h>
+#if defined(SOL_SOCKET) && defined(SO_BINDTODEVICE)
+#include <net/if.h>
+#endif
+
+/**************************************
+ Functions
+**************************************/
+
+/* Get a socket and determine the new IP address */
+SOCKET heartbeat_socket(
+ uint32_t *address_changed,
+ int bStaticTunnel,
+ const char *sIPv4Interface,
+ char **sIPv4Local,
+ const char *sIPv4POP,
+ const char *sIPv4LocalResolve)
+{
+ SOCKET sockfd;
+ struct sockaddr sa;
+ socklen_t socklen;
+ char local_ipv4[NI_MAXHOST];
+#if defined(SOL_SOCKET) && defined(SO_BINDTODEVICE)
+ struct ifreq interface;
+#endif
+ struct addrinfo hints, *res, *ressave;
+
+ D(dolog(LOG_DEBUG, "heartbeat_socket() - Address is %s\n", *sIPv4Local));
+
+ if (address_changed) *address_changed = 0;
+
+ /* Get ourselves a nice IPv4 socket */
+ sockfd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (sockfd < 0)
+ {
+ dolog(LOG_ERR, "Couldn't open a socket for determining current IPv4 address\n");
+ return -1;
+ }
+
+#if defined(SOL_SOCKET) && defined(SO_BINDTODEVICE)
+ /*
+ * We don't have to bind to a device if this
+ * is a static tunnel, this allows running
+ * the heartbeat client as non-root.
+ */
+ if (!bStaticTunnel)
+ {
+ /*
+ * Only allowed as root, but we need root rights anyways
+ * to (re)configure the tunnel
+ */
+
+ /* Bind to the underlying IPv4 device */
+ memset(&interface, 0, sizeof(interface));
+ strncpy(interface.ifr_ifrn.ifrn_name, sIPv4Interface, IFNAMSIZ);
+ if (setsockopt(sockfd, SOL_SOCKET, SO_BINDTODEVICE,
+ (char *)&interface, sizeof(interface)) == -1)
+ {
+ dolog(LOG_ERR, "Couldn't bind to device \"%s\"\n", sIPv4Interface);
+ close(sockfd);
+
+ /* We return a -1, thus the app will keep beating */
+ return -1;
+ }
+ }
+#else
+ /* Make compiler happy and 'use' the param */
+ sIPv4Interface = sIPv4Interface;
+#endif
+
+ /*
+ * connect to the remote port
+ * this causes us to be able to use normal write()
+ * and also gives us the ability to find out the local IP
+ */
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = SOCK_DGRAM;
+
+ /* Get the POP IPv4 into a sockaddr */
+ if (getaddrinfo(sIPv4POP, HEARTBEAT_PORT, &hints, &res) != 0)
+ {
+ dolog(LOG_ERR, "Couldn't resolve POP ip %s\n", sIPv4POP);
+ closesocket(sockfd);
+
+ /* We return a -1, thus the app will keep beating */
+ return -1;
+ }
+
+ ressave = res;
+
+ while (res)
+ {
+ if (connect(sockfd, res->ai_addr, (unsigned int)res->ai_addrlen) == 0) break;
+ res = res->ai_next;
+ }
+ freeaddrinfo(ressave);
+ if (res == NULL)
+ {
+ dolog(LOG_ERR, "Failed to connect() to remote side\n");
+ closesocket(sockfd);
+ /* We return a -1, thus the app will keep beating */
+ return -1;
+ }
+
+ /* Normal operation, find out our local IPv4 address */
+ if (sIPv4LocalResolve == NULL)
+ {
+ /* Figure out our local IP */
+ socklen = sizeof(sa);
+ if (getsockname(sockfd, &sa, &socklen) == -1)
+ {
+ dolog(LOG_WARNING, "Couldn't get local socketaddress\n");
+ closesocket(sockfd);
+ return -1;
+ }
+
+ if (getnameinfo((struct sockaddr *)&sa, sizeof(sa),
+ local_ipv4, sizeof(local_ipv4),
+ NULL, 0,
+ NI_NUMERICHOST) != 0)
+ {
+ dolog(LOG_WARNING, "Couldn't get local IP\n");
+ closesocket(sockfd);
+ return -1;
+ }
+ }
+ else
+ {
+ /*
+ * this causes us to be able to use normal write()
+ * and also gives us the ability to find out the local IP
+ */
+ memset(&hints, 0, sizeof(struct addrinfo));
+ hints.ai_family = AF_INET;
+ hints.ai_socktype = SOCK_DGRAM;
+
+ /* Get the POP IPv4 into a sockaddr */
+ if (getaddrinfo(sIPv4LocalResolve, NULL, &hints, &res) != 0)
+ {
+ dolog(LOG_ERR, "Couldn't resolve POP IPv4 %s\n", sIPv4POP);
+ /* We return a -1, thus the app will keep beating */
+ return -1;
+ }
+ ressave = res;
+ while (res)
+ {
+ if (getnameinfo(res->ai_addr, (socklen_t)res->ai_addrlen,
+ local_ipv4, sizeof(local_ipv4),
+ NULL, 0,
+ NI_NUMERICHOST) == 0)
+ {
+ break;
+ }
+ dolog(LOG_WARNING, "Couldn't get local IP\n");
+ res = res->ai_next;
+ }
+ freeaddrinfo(ressave);
+ }
+
+ /* Did the IPv4 address change? */
+ if (*sIPv4Local == NULL ||
+ strcmp(*sIPv4Local, local_ipv4) != 0)
+ {
+ if (*sIPv4Local) free(*sIPv4Local);
+ *sIPv4Local = strdup(local_ipv4);
+
+ dolog(LOG_DEBUG, "heartbeat_socket() - IPv4 : %s\n", *sIPv4Local);
+
+ if (!bStaticTunnel)
+ {
+ /* Run a script to change the address */
+ if (address_changed) *address_changed = 1;
+ }
+ }
+ D(else dolog(LOG_DEBUG, "heartbeat_socket() - Address stays %s\n", *sIPv4Local));
+
+ /* Return it */
+ return sockfd;
+}
+
+/* Send a heartbeat */
+int heartbeat_send(SOCKET sockfd, char *sIPv4Local, char *sIPv6Local, char *sPassword, bool bBehindNAT)
+{
+ struct MD5Context md5;
+ unsigned char *p, our_digest[20], *pn = our_digest, buf[1000];
+ time_t time_tee;
+ int i;
+
+ time_tee = time(NULL);
+
+ /* Create the string to send including our password */
+ snprintf((char *)buf, sizeof(buf), "HEARTBEAT TUNNEL %s %s %ld %s",
+ sIPv6Local,
+ (bBehindNAT ? "sender" : sIPv4Local),
+ (long int)time_tee, sPassword);
+
+ /* Generate a MD5 */
+ MD5Init(&md5);
+ MD5Update(&md5, buf, (unsigned int)strlen((char *)buf));
+ MD5Final(our_digest, &md5);
+
+ /* Overwrite it without password */
+ p = buf;
+ p += snprintf((char *)buf, sizeof(buf)-17, "HEARTBEAT TUNNEL %s %s %ld ",
+ sIPv6Local,
+ (bBehindNAT == 1 ? "sender" : sIPv4Local),
+ (long int)time_tee);
+
+ /* append the digest */
+ for (i = 0; i < 16; i++)
+ {
+ snprintf((char *)p, 3, (const char *)"%02x", *pn++);
+ p+=2;
+ }
+ *p = '\0';
+
+ /* Send the heartbeat */
+ send(sockfd, (const char *)buf, (unsigned int)strlen((const char *)buf),0);
+
+ dolog(LOG_DEBUG, "[HB] %s\n", buf);
+
+ return 0;
+}
+
+char *heartbeat_getlocalIP(struct TIC_Tunnel *hTunnel)
+{
+ bool address_changed = false;
+ char *ipv4_local = NULL;
+
+ SOCKET sockfd = heartbeat_socket(&address_changed, 0, "",
+ &ipv4_local,
+ hTunnel->sIPv4_POP,
+ NULL);
+ if (sockfd >= 0) closesocket(sockfd);
+
+ dolog(LOG_DEBUG, "Local IPv4 address: %s\n", ipv4_local);
+
+ return ipv4_local;
+}
+
+/*
+ * Other code can call this every once in a while
+ * and it will take care of everything ("everything?" "everything!")
+ */
+void heartbeat_beat(struct TIC_Tunnel *hTunnel)
+{
+ uint32_t address_changed = 0;
+ SOCKET sockfd = -1;
+
+ D(dolog(LOG_DEBUG, "heartbeat_beat() - Beating from %s\n", hTunnel->sIPv4_Local);)
+
+ sockfd = heartbeat_socket(&address_changed, 0, "",
+ &hTunnel->sIPv4_Local,
+ hTunnel->sIPv4_POP,
+ NULL);
+ if (sockfd >= 0)
+ {
+ if (address_changed == 1)
+ {
+ D(dolog(LOG_DEBUG, "heartbeat_beat() - Address changed to %s\n", hTunnel->sIPv4_Local);)
+ aiccu_reconfig(hTunnel);
+ }
+ heartbeat_send(sockfd,
+ hTunnel->sIPv4_Local,
+ hTunnel->sIPv6_Local,
+ hTunnel->sPassword,
+ 1);
+ closesocket(sockfd);
+ sockfd = (SOCKET)-1;
+ }
+}
+
--- /dev/null
+/**********************************************************
+ SixXS - Automatic IPv6 Connectivity Configuration Utility
+***********************************************************
+ Copyright 2003-2005 SixXS - http://www.sixxs.net
+***********************************************************
+ common/heartbeat.h - Heartbeat Definitions
+***********************************************************
+ $Author: jeroen $
+ $Id: heartbeat.h,v 1.6 2006-12-21 14:08:50 jeroen Exp $
+ $Date: 2006-12-21 14:08:50 $
+**********************************************************/
+
+#ifndef HEARTBEAT_H
+#define HEARTBEAT_H "H5K7:W3NDY5UU5N1K1N1C0l3"
+
+#include "common.h"
+#include "tic.h"
+
+/*
+ * SixXS Heartbeat Protocol
+ * port - uses UDP over IPv4
+ */
+#define HEARTBEAT_PORT "3740"
+
+SOCKET heartbeat_socket(
+ uint32_t *address_changed,
+ int bStaticTunnel,
+ const char *sIPv4Interface,
+ char **sIPv4Local,
+ const char *sIPv4POP,
+ const char *sIPv4LocalResolve);
+
+int heartbeat_send(SOCKET sockfd, char *sIPv4Local, char *sIPv6Local, char *sPassword, bool bBehindNAT);
+
+void heartbeat_beat(struct TIC_Tunnel *hTunnel);
+char *heartbeat_getlocalIP(struct TIC_Tunnel *hTunnel);
+
+#endif /* HEARTBEAT_H */
+
--- /dev/null
+/**********************************************************
+ SixXS - Automatic IPv6 Connectivity Configuration Utility
+***********************************************************
+ Copyright 2003-2005 SixXS - http://www.sixxs.net
+***********************************************************
+ common/resolver.c - Simple DNS RR lookup function
+***********************************************************
+ $Author: jeroen $
+ $Id: resolver.c,v 1.3 2006-07-23 14:13:57 jeroen Exp $
+ $Date: 2006-07-23 14:13:57 $
+**********************************************************/
+
+#include <stdlib.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "resolver.h"
+
+#ifndef _WIN32
+#include <unistd.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+#include <netdb.h>
+
+int getrrs(const char *label, int rrtype, void gotrec(unsigned int num, int type, const char *record))
+{
+#ifdef _LINUX
+ struct __res_state res;
+#endif
+ unsigned char answer[8192];
+ HEADER *header = (HEADER *)answer;
+ char buf[2048];
+ int ret, count;
+ unsigned int i,j,k,rrnum = 0;
+ unsigned char *startptr, *endptr, *ptr;
+ uint16_t type = 0, class = 0;
+ uint32_t ttl = 0;
+
+#ifdef _LINUX
+ memset(&res, 0, sizeof(res));
+ res.options = RES_DEBUG;
+ res_ninit(&res);
+#else
+ res_init();
+#endif
+
+ memset(answer, 0, sizeof(answer));
+#ifdef _LINUX
+ ret = res_nquery(&res, label, C_IN, rrtype, answer, sizeof(answer));
+#else
+ ret = res_query(label, C_IN, rrtype, answer, sizeof(answer));
+#endif
+ if (ret < 0) return -1;
+
+ /* Our start and end */
+ startptr = &answer[0];
+ endptr = &answer[ret];
+
+ /* Skip the header */
+ ptr = startptr + HFIXEDSZ;
+
+ /* Skip Query part */
+ for (count = ntohs(header->qdcount); count--; ptr += ret + QFIXEDSZ)
+ {
+ if ((ret = dn_skipname(ptr, endptr)) < 0) return -1;
+ }
+
+ /* Only look at the Answer section */
+ count = ntohs(header->ancount);
+
+ /* Go through all the Answer records */
+ while (ptr < endptr && count > 0)
+ {
+ rrnum++;
+
+ memset(buf, 0, sizeof(buf));
+ ret = dn_expand (startptr, endptr, ptr, buf, sizeof(buf));
+ if (ret < 0) break;
+ ptr += ret;
+
+ if (ptr + INT16SZ + INT16SZ + INT32SZ >= endptr) break;
+
+ /* Get the type */
+ NS_GET16(type, ptr);
+
+ /* Get the class */
+ NS_GET16(class, ptr);
+
+ /* Get the TTL */
+ NS_GET32(ttl, ptr);
+
+ /* Get the RDLength */
+ NS_GET16(ret, ptr);
+
+ memset(buf, 0, sizeof(buf));
+
+ switch (type)
+ {
+ case T_TXT:
+ for (k = ret, j = 0; j < k && &ptr[j] < endptr; j += (i+1))
+ {
+ i = ptr[j];
+ memcpy(buf, &ptr[j+1], i > sizeof(buf) ? sizeof(buf) : i);
+ buf[i > sizeof(buf) ? sizeof(buf) : i] = '\0';
+ if (rrtype == type || rrtype == T_ANY) gotrec(rrnum, type, buf);
+ }
+ break;
+
+ case T_A:
+ inet_ntop(AF_INET, ptr, buf, sizeof(buf));
+ if (rrtype == type || rrtype == T_ANY) gotrec(rrnum, type, buf);
+ break;
+
+ case T_AAAA:
+ inet_ntop(AF_INET6, ptr, buf, sizeof(buf));
+ if (rrtype == type || rrtype == T_ANY) gotrec(rrnum, type, buf);
+ break;
+
+ case T_MX:
+ /* Get the MX preference */
+ NS_GET16(ttl, ptr);
+ ret = dn_expand(startptr, endptr, ptr, buf, sizeof(buf));
+ if (rrtype == type || rrtype == T_ANY) gotrec(rrnum, type, buf);
+ break;
+
+ case T_NS:
+ ret = dn_expand(startptr, endptr, ptr, buf, sizeof(buf));
+ if (rrtype == type || rrtype == T_ANY) gotrec(rrnum, type, buf);
+ break;
+
+ default:
+ /* Unhandled */
+ break;
+ }
+
+ ptr += ret;
+ count--;
+ }
+ return 0;
+}
+#else
+/*
+ * Windows Resolver Code, as per:
+ * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dns/dns/dnsquery.asp
+ * http://support.microsoft.com/default.aspx?scid=kb%3Ben-us%3B831226
+ */
+#include <windns.h>
+
+int getrrs(const char *label, int rrtype, void gotrec(unsigned int num, int type, const char *record))
+{
+ DNS_STATUS status; /* Return value of DnsQuery_A() function */
+ PDNS_RECORD pResult, pRec; /* Pointer to DNS_RECORD structure */
+ unsigned int rrnum = 0, i;
+ uint16_t type;
+
+ status = DnsQuery(label, /* Pointer to OwnerName */
+ rrtype, /* Type of the record to be queried */
+ DNS_QUERY_STANDARD, /* Standard Query */
+ NULL, /* Contains DNS server IP address */
+ &pResult, /* Resource record that contains the response */
+ NULL); /* Reserved for future use */
+
+ if (status) return -1;
+ else
+ {
+ for (pRec = pResult; pRec; pRec = pRec->pNext)
+ {
+ rrnum++;
+ type = pRec->wType;
+
+ if (rrtype != type && rrtype != ns_t_any) continue;
+
+ switch (type)
+ {
+ case ns_t_txt:
+ for (i=0; i < pRec->Data.TXT.dwStringCount; i++)
+ {
+ gotrec(rrnum, type, pRec->Data.TXT.pStringArray[i]);
+ }
+ break;
+
+ case ns_t_a:
+ gotrec(rrnum, type, (const char *)&pRec->Data.A.IpAddress);
+ break;
+
+ case ns_t_aaaa:
+ gotrec(rrnum, type, (const char *)&pRec->Data.AAAA.Ip6Address);
+ break;
+
+ case ns_t_mx:
+ gotrec(rrnum, type, pRec->Data.MX.pNameExchange);
+ break;
+
+ case ns_t_ns:
+ gotrec(rrnum, type, pRec->Data.NS.pNameHost);
+ break;
+ }
+ }
+ }
+
+ /* Free memory allocated for DNS records. */
+ DnsRecordListFree(pResult, DnsFreeRecordListDeep);
+
+ return 0;
+}
+#endif
+
--- /dev/null
+/**********************************************************
+ SixXS - Automatic IPv6 Connectivity Configuration Utility
+***********************************************************
+ Copyright 2003-2005 SixXS - http://www.sixxs.net
+***********************************************************
+ common/resolver.h - Simple DNS RR lookup function
+***********************************************************
+ $Author: jeroen $
+ $Id: resolver.h,v 1.2 2006-07-13 19:33:39 jeroen Exp $
+ $Date: 2006-07-13 19:33:39 $
+**********************************************************/
+
+#ifndef RESOLVER_H
+#define RESOLVER_H "H5K7:W3NDY5UU5N1K1N1C0l3"
+
+#include "common.h"
+
+int getrrs(const char *label, int type, void gotrec(unsigned int num, int type, const char *record));
+
+#ifdef _WIN32
+/*
+ * Windows doesn't have these, there they are named DNS_TYPE_*
+ * but the identical values so we can use them here too.
+ * Looted from arpa/nameser.h which has a BSD license for UC & ISC
+ */
+/*
+ * Currently defined type values for resources and queries.
+ */
+typedef enum __ns_type {
+ ns_t_invalid = 0, /* Cookie. */
+ ns_t_a = 1, /* Host address. */
+ ns_t_ns = 2, /* Authoritative server. */
+ ns_t_md = 3, /* Mail destination. */
+ ns_t_mf = 4, /* Mail forwarder. */
+ ns_t_cname = 5, /* Canonical name. */
+ ns_t_soa = 6, /* Start of authority zone. */
+ ns_t_mb = 7, /* Mailbox domain name. */
+ ns_t_mg = 8, /* Mail group member. */
+ ns_t_mr = 9, /* Mail rename name. */
+ ns_t_null = 10, /* Null resource record. */
+ ns_t_wks = 11, /* Well known service. */
+ ns_t_ptr = 12, /* Domain name pointer. */
+ ns_t_hinfo = 13, /* Host information. */
+ ns_t_minfo = 14, /* Mailbox information. */
+ ns_t_mx = 15, /* Mail routing information. */
+ ns_t_txt = 16, /* Text strings. */
+ ns_t_rp = 17, /* Responsible person. */
+ ns_t_afsdb = 18, /* AFS cell database. */
+ ns_t_x25 = 19, /* X_25 calling address. */
+ ns_t_isdn = 20, /* ISDN calling address. */
+ ns_t_rt = 21, /* Router. */
+ ns_t_nsap = 22, /* NSAP address. */
+ ns_t_nsap_ptr = 23, /* Reverse NSAP lookup (deprecated). */
+ ns_t_sig = 24, /* Security signature. */
+ ns_t_key = 25, /* Security key. */
+ ns_t_px = 26, /* X.400 mail mapping. */
+ ns_t_gpos = 27, /* Geographical position (withdrawn). */
+ ns_t_aaaa = 28, /* Ip6 Address. */
+ ns_t_loc = 29, /* Location Information. */
+ ns_t_nxt = 30, /* Next domain (security). */
+ ns_t_eid = 31, /* Endpoint identifier. */
+ ns_t_nimloc = 32, /* Nimrod Locator. */
+ ns_t_srv = 33, /* Server Selection. */
+ ns_t_atma = 34, /* ATM Address */
+ ns_t_naptr = 35, /* Naming Authority PoinTeR */
+ ns_t_kx = 36, /* Key Exchange */
+ ns_t_cert = 37, /* Certification record */
+ ns_t_a6 = 38, /* IPv6 address (deprecates AAAA) */
+ ns_t_dname = 39, /* Non-terminal DNAME (for IPv6) */
+ ns_t_sink = 40, /* Kitchen sink (experimentatl) */
+ ns_t_opt = 41, /* EDNS0 option (meta-RR) */
+ ns_t_tsig = 250, /* Transaction signature. */
+ ns_t_ixfr = 251, /* Incremental zone transfer. */
+ ns_t_axfr = 252, /* Transfer zone of authority. */
+ ns_t_mailb = 253, /* Transfer mailbox records. */
+ ns_t_maila = 254, /* Transfer mail agent records. */
+ ns_t_any = 255, /* Wildcard match. */
+ ns_t_zxfr = 256, /* BIND-specific, nonstandard. */
+ ns_t_max = 65536
+} ns_type;
+#endif
+
+#endif /* RESOLVER_H */
+
--- /dev/null
+/**********************************************************
+ SixXS - Automatic IPv6 Connectivity Configuration Utility
+***********************************************************
+ Copyright 2003-2005 SixXS - http://www.sixxs.net
+***********************************************************
+ common/tic.c - Tunnel Information & Control Protocol
+***********************************************************
+ $Author: jeroen $
+ $Id: tic.c,v 1.17 2007-01-11 13:41:31 jeroen Exp $
+ $Date: 2007-01-11 13:41:31 $
+**********************************************************/
+
+#include "common.h"
+#include "aiccu.h"
+#include "tic.h"
+
+/* Specific includes only used here */
+#ifndef _WIN32
+#include <sys/utsname.h>
+#endif
+
+/* getline vars */
+char tic_buf[2048];
+unsigned int tic_filled;
+
+/*
+ * epochtime = epochtime as received in the packet
+ * Don't forget to convert byteorder using ntohl()
+ */
+int tic_checktime(time_t epochtime)
+{
+ /* Number of seconds we allow the clock to be off */
+ #define CLOCK_OFF 120
+ int i;
+
+ /* Get the current time */
+ time_t curr_time = time(NULL);
+
+ /* Is one of the times in the loop range? */
+ if ( (curr_time >= -CLOCK_OFF) ||
+ (epochtime >= -CLOCK_OFF))
+ {
+ /* Shift the times out of the loop range */
+ i =(int)(((int)curr_time) + (CLOCK_OFF*2)) -
+ (((int)epochtime) + (CLOCK_OFF*2));
+ }
+ else i = ((int)curr_time) - ((int)epochtime);
+
+ /* The clock may be faster, thus flip the sign */
+ if (i < 0) i = -i;
+
+ /* Compare the clock offset */
+ if (i > CLOCK_OFF)
+ {
+ /* Time is off */
+ return i;
+ }
+
+ /* Time is in the allowed range */
+ return 0;
+}
+
+bool tic_Login(struct TIC_conf *tic, const char *username, const char *password, const char *server)
+{
+ char buf[1024], sSignature[33], sChallenge[1024];
+ int i;
+#ifndef _WIN32
+ struct utsname uts_name;
+#else
+ OSVERSIONINFO osv;
+ OSVERSIONINFOEX osvEx;
+ char *platform = NULL;
+ char version[100];
+#endif
+
+ D(dolog(LOG_DEBUG, "Trying to connect to TIC server %s\n", server));
+
+ /* Connect to the TIC server */
+ tic->sock = connect_client(server, TIC_PORT, AF_INET, SOCK_STREAM);
+ if (!tic->sock)
+ {
+ dolog(LOG_ERR, "Couldn't connect to the TIC server %s\n", server);
+ return false;
+ }
+
+ /* Fetch the welcome */
+ if (sock_getline(tic->sock, tic_buf, sizeof(tic_buf), &tic_filled, buf, sizeof(buf)) == -1)
+ {
+ return false;
+ }
+ if (buf[0] != '2')
+ {
+ dolog(LOG_ERR, "TIC Server is currently not available\n");
+ return false;
+ }
+
+ /* Send our client identification */
+#ifndef _WIN32
+ uname(&uts_name);
+ sock_printf(tic->sock, "client TIC/%s %s/%s %s/%s\n",
+ TIC_VERSION,
+ TIC_CLIENT_NAME, TIC_CLIENT_VERSION,
+ uts_name.sysname, uts_name.release);
+#else
+ osv.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+ osvEx.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
+
+ if (!GetVersionEx(&osv))
+ {
+ platform = "Windows";
+ snprintf(version, sizeof(version), "%s", "Unknown");
+ }
+ else
+ {
+
+ platform = (osv.dwPlatformId == VER_PLATFORM_WIN32s) ? "Win32s" :
+ ((osv.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) ? "Win9x" :
+ ((osv.dwPlatformId == VER_PLATFORM_WIN32_NT) ? "WinNT" :
+ "Windows"));
+
+ if ( osv.dwMajorVersion < 5 ||
+ !GetVersionEx((OSVERSIONINFO *)&osvEx) ||
+ osvEx.wServicePackMajor <= 0)
+ {
+ snprintf(version, sizeof(version), "%d.%d.%d",
+ osv.dwMajorVersion, osv.dwMinorVersion, osv.dwBuildNumber);
+ }
+ else if (osvEx.wServicePackMinor <= 0)
+ {
+ snprintf(version, sizeof(version), "%d.%d.%d-SP%d",
+ osv.dwMajorVersion, osv.dwMinorVersion, osv.dwBuildNumber,
+ osvEx.wServicePackMajor);
+ }
+ else
+ {
+ snprintf(version, sizeof(version), "%d.%d.%d-SP%d.%d",
+ osv.dwMajorVersion, osv.dwMinorVersion, osv.dwBuildNumber,
+ osvEx.wServicePackMajor, osvEx.wServicePackMinor);
+ }
+ }
+ sock_printf(tic->sock, "client TIC/%s %s/%s %s/%s\n",
+ TIC_VERSION,
+ TIC_CLIENT_NAME, TIC_CLIENT_VERSION,
+ platform, version);
+#endif
+
+ /* Fetch the answer */
+ if (sock_getline(tic->sock, tic_buf, sizeof(tic_buf), &tic_filled, buf, sizeof(buf)) == -1)
+ {
+ return false;
+ }
+ if (buf[0] != '2')
+ {
+ dolog(LOG_ERR, "Couldn't pass client information: %s.\n", &buf[4]);
+ return false;
+ }
+
+ /* Request current time */
+ sock_printf(tic->sock, "get unixtime\n");
+
+ /* Fetch the answer */
+ if (sock_getline(tic->sock, tic_buf, sizeof(tic_buf), &tic_filled, buf, sizeof(buf)) == -1)
+ {
+ return false;
+ }
+ if (buf[0] != '2')
+ {
+ dolog(LOG_ERR, "Time not available? %s\n", &buf[4]);
+ return false;
+ }
+
+ /* Check if the time is correct */
+ i = tic_checktime(atoi(&buf[4]));
+ if (i != 0)
+ {
+ char quitmsg[100];
+ dolog(LOG_ERR, "The clock is off by %d seconds, use NTP to sync it!\n", i);
+ snprintf(quitmsg, sizeof(quitmsg), "Aborting: Clock is off by %d seconds\n", i);
+ tic_Logout(tic, quitmsg);
+ return false;
+ }
+
+#ifdef AICCU_GNUTLS
+ /* Upgrade to TLS */
+ sock_printf(tic->sock, "starttls\n");
+
+ /* Fetch the welcome */
+ if (sock_getline(tic->sock, tic_buf, sizeof(tic_buf), &tic_filled, buf, sizeof(buf)) == -1)
+ {
+ return false;
+ }
+ if (buf[0] == '2')
+ {
+ /* Go to TLS mode */
+ if (!sock_gotls(tic->sock)) return false;
+ }
+ else
+ {
+ if (g_aiccu->requiretls)
+ {
+ dolog(LOG_ERR, "TIC Server does not support TLS and TLS is required\n");
+ return false;
+ }
+ if (g_aiccu->verbose) dolog(LOG_WARNING, "TIC Server does not support TLS but TLS is not required, continuing\n");
+ }
+
+#endif
+
+ /* Send our username */
+ sock_printf(tic->sock, "username %s\n", username);
+
+ /* Fetch the answer */
+ if (sock_getline(tic->sock, tic_buf, sizeof(tic_buf), &tic_filled, buf, sizeof(buf)) == -1)
+ {
+ return false;
+ }
+ if (buf[0] != '2')
+ {
+ dolog(LOG_ERR, "Username not accepted: %s.\n", &buf[4]);
+ return false;
+ }
+
+ /* Pick a challenge */
+ sock_printf(tic->sock, "challenge md5\n");
+
+ /* Fetch the answer */
+ if (sock_getline(tic->sock, tic_buf, sizeof(tic_buf), &tic_filled, buf, sizeof(buf)) == -1)
+ {
+ return false;
+ }
+ if (buf[0] != '2')
+ {
+ dolog(LOG_ERR, "Challenge not correct: %s.\n", &buf[4]);
+ return false;
+ }
+
+ /* Send the response */
+ /* sSignature = md5(challenge.md5(password)); */
+ MD5String(password, sSignature, sizeof(sSignature));
+ snprintf(sChallenge, sizeof(sChallenge), "%s%s", &buf[4], sSignature);
+ MD5String(sChallenge, sSignature, sizeof(sSignature));
+
+ sock_printf(tic->sock, "authenticate md5 %s\n", sSignature);
+
+ /* Fetch the answer */
+ if (sock_getline(tic->sock, tic_buf, sizeof(tic_buf), &tic_filled, buf, sizeof(buf)) == -1)
+ {
+ tic_Logout(tic, NULL);
+ return false;
+ }
+ if (buf[0] != '2')
+ {
+ tic_Logout(tic, NULL);
+ dolog(LOG_ERR, "Response not accepted: %s.\n", &buf[4]);
+ return false;
+ }
+
+ /* Connect OK */
+ return true;
+}
+
+void tic_Logout(struct TIC_conf *tic, const char *quitmsg)
+{
+ /* A list of appropriate quit messages */
+ const char *byers[] = {
+ /* Swiss-German form of "Ciao" */
+ "Tschau!",
+
+ /* Dutch for "they who are going, greet you" */
+ "Zij die gaan, groeten u",
+ "See you later alligator",
+ "A bitter thought, but I have to go",
+
+ /* Dutch for "see you later" */
+ "Ajuuu paraplu",
+ "Thank you for the information",
+ "It was lovely talking to you again",
+ "Tschussss...",
+ "Aufwiedersehen",
+ "I'll be back. Ha, you didn't know I was going to say that!",
+ "We will be the only two people left in the world, Yes--Adam and Evil!",
+
+ /* Blutengel */
+ "Stranded",
+ "Die With You",
+ "The End Of Love",
+
+ /* Chamber */
+ "In My Garden",
+ "Set Me Free",
+
+ /* Faithless */
+ "Don't Leave",
+ "Insomnia",
+ "Why Go",
+
+ /* Garbage */
+ "The Trick Is To Keep Breathing",
+
+ /* The Gathering */
+ "We just stopped breating",
+ "Even the spirits are afraid",
+
+ /* Goldfrapp */
+ "Deer Stop",
+
+ /* Hooverphonic */
+ "The Last Thing I Need Is You",
+ "Every Time We Live Together",
+ "My Autumn's Done Come",
+
+ /* Infected Mushroom */
+ "Never Ever Land",
+ "None of this is real",
+ "Nothing Comes Easy",
+ "Illuminaughty",
+
+ /* Nine Inch Nails */
+ "Something I can never have",
+ "And All That Could Have Been...",
+ "That's what I get",
+
+ /* Opeth */
+ "Under the weeping moon",
+ "For Absent Friends",
+
+ /* Portishead */
+ "It Could Be Sweet",
+ "Half Day Closing",
+
+ /* Suicide Commando */
+ "Better Off Dead",
+
+ /* VNV Nation */
+ "Solitary",
+ "Forsaken",
+ "Holding On",
+
+ /* Within Temptation */
+ "This is not our farewell",
+ "Running Down That Hill",
+
+ /* Wumpscut */
+ "Schaltet den schmerz ab",
+ "Down where we belong",
+ };
+
+ /* Already disconnected? */
+ if (!tic->sock) return;
+
+ if (!quitmsg)
+ {
+ /* Stupid random quit messages, got to put some form of easteregg in it :) */
+ srand((unsigned)time(NULL));
+
+ quitmsg = (char *)byers[rand()%(sizeof(byers)/sizeof(char *))];
+ }
+
+ /* Send our bye bye */
+ sock_printf(tic->sock, "QUIT %s\n", quitmsg);
+
+ /* Disconnect */
+ sock_free(tic->sock);
+ tic->sock = NULL;
+}
+
+struct TIC_sTunnel *tic_ListTunnels(struct TIC_conf *tic)
+{
+ char buf[1024], buf2[1024];
+ struct TIC_sTunnel *start = NULL, *last = NULL, *tun = NULL;
+ int i;
+
+/* Request a list of Tunnels */
+ sock_printf(tic->sock, "tunnel list\n");
+
+ /* Fetch the answer */
+ if (sock_getline(tic->sock, tic_buf, sizeof(tic_buf), &tic_filled, buf, sizeof(buf)) == -1)
+ {
+ return NULL;
+ }
+
+ /* 201 (start of list) ? */
+ if (buf[0] != '2' || buf[1] != '0' || buf[2] != '1')
+ {
+ dolog(LOG_ERR, "Couldn't list tunnels: %s.\n", &buf[4]);
+ return NULL;
+ }
+
+ /* Process all the lines */
+ while (sock_getline(tic->sock, tic_buf, sizeof(tic_buf), &tic_filled, buf, sizeof(buf)) != -1)
+ {
+ /* 202 (end of list) ? */
+ if (buf[0] == '2' && buf[1] == '0' && buf[2] == '2') break;
+
+ i = countfields(buf);
+ if (i != 4)
+ {
+ dolog(LOG_ERR, "Wrong field format when listing tunnels\n");
+ break;
+ }
+
+ /* Allocate a new struct */
+ tun = (struct TIC_sTunnel *)malloc(sizeof(*tun));
+ if (!tun)
+ {
+ dolog(LOG_ERR, "Memory problem while listing tunnels\n");
+ break;
+ }
+ memset(tun, 0, sizeof(*tun));
+
+ /* Copy the fields into the struct */
+ if (!copyfield(buf, 1, buf2, sizeof(buf2))) break;
+ tun->sId = strdup(buf2);
+ if (!copyfield(buf, 2, buf2, sizeof(buf2))) break;
+ tun->sIPv6 = strdup(buf2);
+ if (!copyfield(buf, 3, buf2, sizeof(buf2))) break;
+ tun->sIPv4 = strdup(buf2);
+ if (!copyfield(buf, 4, buf2, sizeof(buf2))) break;
+ tun->sPOPId = strdup(buf2);
+
+ /* Add it into the list */
+ if (last)
+ {
+ last->next = tun;
+ last = tun;
+ }
+ else
+ {
+ start = last = tun;
+ }
+ }
+
+ /* All went okay? */
+ if (buf[0] == '2' && buf[1] == '0' && buf[2] == '2')
+ {
+ return start;
+ }
+
+ /* Free the structure, it was broken anyway */
+ tic_Free_sTunnel(start);
+
+ dolog(LOG_ERR, "Tunnel list went wrong: %s\n", &buf[4]);
+ return NULL;
+}
+
+struct TIC_sRoute *tic_ListRoutes(struct TIC_conf *tic)
+{
+ dolog(LOG_ERR, "Not implemented - tic_ListRoutes(%x)\n", tic);
+ return NULL;
+}
+
+struct TIC_sPOP *tic_ListPOPs(struct TIC_conf *tic)
+{
+ dolog(LOG_ERR, "Not implemented - tic_ListPOPs(%x)\n", tic);
+ return NULL;
+}
+
+struct pl_rule tunnel_rules[] =
+{
+ {"TunnelId", PLRT_STRING, offsetof(struct TIC_Tunnel, sId)},
+ {"Type", PLRT_STRING, offsetof(struct TIC_Tunnel, sType)},
+ {"IPv6 Endpoint", PLRT_STRING, offsetof(struct TIC_Tunnel, sIPv6_Local)},
+ {"IPv6 POP", PLRT_STRING, offsetof(struct TIC_Tunnel, sIPv6_POP)},
+ {"IPv6 PrefixLength", PLRT_INTEGER, offsetof(struct TIC_Tunnel, nIPv6_PrefixLength)},
+ {"POP Id", PLRT_STRING, offsetof(struct TIC_Tunnel, sPOP_Id)},
+ {"IPv4 Endpoint", PLRT_STRING, offsetof(struct TIC_Tunnel, sIPv4_Local)},
+ {"IPv4 POP", PLRT_STRING, offsetof(struct TIC_Tunnel, sIPv4_POP)},
+ {"UserState", PLRT_STRING, offsetof(struct TIC_Tunnel, sUserState)},
+ {"AdminState", PLRT_STRING, offsetof(struct TIC_Tunnel, sAdminState)},
+ {"Password", PLRT_STRING, offsetof(struct TIC_Tunnel, sPassword)},
+ {"Heartbeat_Interval", PLRT_INTEGER, offsetof(struct TIC_Tunnel, nHeartbeat_Interval)},
+ {"Tunnel MTU", PLRT_INTEGER, offsetof(struct TIC_Tunnel, nMTU)},
+ {NULL, PLRT_END, 0},
+};
+
+struct TIC_Tunnel *tic_GetTunnel(struct TIC_conf *tic, const char *sId)
+{
+ char buf[1024];
+ struct TIC_Tunnel *tun;
+
+ /* Get a Tunnel */
+ sock_printf(tic->sock, "tunnel show %s\n", sId);
+
+ /* Fetch the answer */
+ if (sock_getline(tic->sock, tic_buf, sizeof(tic_buf), &tic_filled, buf, sizeof(buf)) == -1)
+ {
+ return NULL;
+ }
+
+ /* 201 (start of information) ? */
+ if (buf[0] != '2' || buf[1] != '0' || buf[2] != '1')
+ {
+ dolog(LOG_ERR, "Couldn't show tunnel %s: %s.\n", sId, buf);
+ return NULL;
+ }
+
+ /* Allocate a new struct */
+ tun = (struct TIC_Tunnel *)malloc(sizeof(*tun));
+ if (!tun)
+ {
+ dolog(LOG_ERR, "Memory problem while getting tunnel %s\n", sId);
+ return NULL;
+ }
+ memset(tun, 0, sizeof(*tun));
+
+ /* Gather the information */
+ while (sock_getline(tic->sock, tic_buf, sizeof(tic_buf), &tic_filled, buf, sizeof(buf)) != -1)
+ {
+ /* 202 (end of list) ? */
+ if (buf[0] == '2' && buf[1] == '0' && buf[2] == '2') break;
+
+ parseline(buf, ": ", tunnel_rules, tun);
+ }
+ /* All went okay? */
+ if (buf[0] == '2' && buf[1] == '0' && buf[2] == '2')
+ {
+ struct in6_addr ipv6_ll, ipv6_local;
+ char ll[100];
+
+ /* Log that the fetch was succesful */
+ dolog(LOG_INFO, "Succesfully retrieved tunnel information for %s\n", sId);
+
+ /*
+ * Some TUN/TAP devices don't have any
+ * link local addresses and we want multicast and MLD to work
+ * thus we invent one based on the following:
+ *
+ * ipv6_us = 2001:0db8:1234:5678: : : :0001
+ * ipv6_ll = fe80: : : :0db8:1234:5678:0001
+ *
+ * Thus we ignore the first 16bits, take the following 48 bits
+ * and then add the last 16bits.
+ *
+ * As we are not 100% sure that this LL is unique we clear that bit.
+ */
+
+ inet_pton(AF_INET6, tun->sIPv6_Local, &ipv6_local);
+
+ /* Link Local (fe80::/64) */
+ ipv6_ll.s6_addr[ 0] = 0xfe;
+ ipv6_ll.s6_addr[ 1] = 0x80;
+ ipv6_ll.s6_addr[ 2] = 0x00;
+ ipv6_ll.s6_addr[ 3] = 0x00;
+ ipv6_ll.s6_addr[ 4] = 0x00;
+ ipv6_ll.s6_addr[ 5] = 0x00;
+ ipv6_ll.s6_addr[ 6] = 0x00;
+ ipv6_ll.s6_addr[ 7] = 0x00;
+ ipv6_ll.s6_addr[ 8] = ipv6_local.s6_addr[ 2] & 0xfc; /* Clear the LL Unique Bit */
+ ipv6_ll.s6_addr[ 9] = ipv6_local.s6_addr[ 3];
+ ipv6_ll.s6_addr[10] = ipv6_local.s6_addr[ 4];
+ ipv6_ll.s6_addr[11] = ipv6_local.s6_addr[ 5];
+ ipv6_ll.s6_addr[12] = ipv6_local.s6_addr[ 6];
+ ipv6_ll.s6_addr[13] = ipv6_local.s6_addr[ 7];
+ ipv6_ll.s6_addr[14] = ipv6_local.s6_addr[14];
+ ipv6_ll.s6_addr[15] = ipv6_local.s6_addr[15];
+
+ inet_ntop(AF_INET6, &ipv6_ll, ll, sizeof(ll));
+ if (tun->sIPv6_LinkLocal) free(tun->sIPv6_LinkLocal);
+ tun->sIPv6_LinkLocal = strdup(ll);
+
+ if ( strcmp(tun->sType, "ayiya") == 0 ||
+ strcmp(tun->sType, "l2tp") == 0)
+ {
+ tun->uses_tundev = 1;
+#ifdef NO_IFHEAD
+ dolog(LOG_ERR, "This build doesn't support the Tun/TAP device and thus can't instantiate tunnels of type %s, please fix your OS and recompile\n", tun->sType);
+ tic_Free_Tunnel(tun);
+ return NULL;
+#endif
+ }
+ else tun->uses_tundev = 0;
+
+ /* Need to override the local IPv4 address? */
+ if (g_aiccu->local_ipv4_override)
+ {
+ dolog(LOG_INFO, "Overriding Local IPv4 address from %s to %s\n", tun->sIPv4_Local, g_aiccu->local_ipv4_override);
+ free(tun->sIPv4_Local);
+ tun->sIPv4_Local = strdup(g_aiccu->local_ipv4_override);
+ }
+
+ return tun;
+ }
+
+ /* Free the structure, it is broken anyway */
+ tic_Free_Tunnel(tun);
+
+ dolog(LOG_ERR, "Tunnel Get for %s went wrong: %s\n", sId, buf);
+ return NULL;
+}
+
+struct TIC_Route *tic_GetRoute(struct TIC_conf *tic, const char *sId)
+{
+ dolog(LOG_ERR, "Not implemented - tic_GetRoute(%x, \"%s\")\n", tic, sId);
+ return NULL;
+}
+
+struct pl_rule pop_rules[] =
+{
+ {"POPId", PLRT_STRING, offsetof(struct TIC_POP, sId)},
+ {"City", PLRT_STRING, offsetof(struct TIC_POP, sCity)},
+ {"Country", PLRT_STRING, offsetof(struct TIC_POP, sCountry)},
+ {"IPv4", PLRT_STRING, offsetof(struct TIC_POP, sIPv4)},
+ {"IPv6", PLRT_STRING, offsetof(struct TIC_POP, sIPv6)},
+
+ {"ISP Short", PLRT_STRING, offsetof(struct TIC_POP, sISP_Short)},
+ {"ISP Name", PLRT_STRING, offsetof(struct TIC_POP, sISP_Name)},
+ {"ISP Website", PLRT_STRING, offsetof(struct TIC_POP, sISP_Website)},
+ {"ISP ASN", PLRT_STRING, offsetof(struct TIC_POP, sISP_ASN)},
+ {"ISP LIR", PLRT_STRING, offsetof(struct TIC_POP, sISP_LIR)},
+
+ {NULL, PLRT_END, 0},
+};
+
+struct TIC_POP *tic_GetPOP(struct TIC_conf *tic, const char *sId)
+{
+ char buf[1024];
+ struct TIC_POP *pop;
+
+ /* Get a Tunnel */
+ sock_printf(tic->sock, "pop show %s\n", sId);
+
+ /* Fetch the answer */
+ if (sock_getline(tic->sock, tic_buf, sizeof(tic_buf), &tic_filled, buf, sizeof(buf)) == -1)
+ {
+ return NULL;
+ }
+
+ /* 201 (start of info) ? */
+ if (buf[0] != '2' || buf[1] != '0' || buf[2] != '1')
+ {
+ dolog(LOG_ERR, "Couldn't show POP %s: %s.\n", sId, buf);
+ return NULL;
+ }
+
+ /* Allocate a new struct */
+ pop = (struct TIC_POP *)malloc(sizeof(*pop));
+ if (!pop)
+ {
+ dolog(LOG_ERR, "Memory problem while getting POP\n");
+ return NULL;
+ }
+ memset(pop, 0, sizeof(*pop));
+
+ /* Gather the information */
+ while (sock_getline(tic->sock, tic_buf, sizeof(tic_buf), &tic_filled, buf, sizeof(buf)) != -1)
+ {
+ /* 202 (end of list) ? */
+ if (buf[0] == '2' && buf[1] == '0' && buf[2] == '2') break;
+
+ parseline(buf, ": ", pop_rules, pop);
+ }
+ /* All went okay? */
+ if (buf[0] == '2' && buf[1] == '0' && buf[2] == '2')
+ {
+ dolog(LOG_INFO, "Succesfully retrieved POP information for %s\n", sId);
+ return pop;
+ }
+
+ /* Free the structure, it is broken anyway */
+ tic_Free_POP(pop);
+
+ dolog(LOG_ERR, "POP Get for %s went wrong: %s\n", sId, buf);
+ return NULL;
+}
+
+void tic_Free_sTunnel(struct TIC_sTunnel *tun)
+{
+ struct TIC_sTunnel *next;
+
+ for (; tun; tun = next)
+ {
+ next = tun->next;
+ if (tun->sId) free(tun->sId);
+ if (tun->sIPv6) free(tun->sIPv6);
+ if (tun->sIPv4) free(tun->sIPv4);
+ if (tun->sPOPId) free(tun->sPOPId);
+ free(tun);
+ }
+}
+
+void tic_Free_sRoute(struct TIC_sRoute *rt)
+{
+ struct TIC_sRoute *next;
+
+ for (; rt; rt = next)
+ {
+ next = rt->next;
+ if (rt->sId) free(rt->sId);
+ if (rt->sTunnelId) free(rt->sTunnelId);
+ if (rt->sIPv6) free(rt->sIPv6);
+ free(rt);
+ }
+}
+
+void tic_Free_sPOP(struct TIC_sPOP *pop)
+{
+ struct TIC_sPOP *next;
+
+ for (; pop; pop = next)
+ {
+ next = pop->next;
+ if (pop->sId) free(pop->sId);
+ free(pop);
+ }
+}
+
+void tic_Free_Tunnel(struct TIC_Tunnel *tun)
+{
+ if (tun->sId) { free(tun->sId); tun->sId = NULL; }
+ if (tun->sType) { free(tun->sType); tun->sType = NULL; }
+ if (tun->sPOP_Id) { free(tun->sPOP_Id); tun->sPOP_Id = NULL; }
+ if (tun->sUserState) { free(tun->sUserState); tun->sUserState = NULL; }
+ if (tun->sAdminState) { free(tun->sAdminState); tun->sAdminState = NULL; }
+ if (tun->sPassword) { free(tun->sPassword); tun->sPassword = NULL; }
+ if (tun->sIPv4_Local) { free(tun->sIPv4_Local); tun->sIPv4_Local = NULL; }
+ if (tun->sIPv4_POP) { free(tun->sIPv4_POP); tun->sIPv4_POP = NULL; }
+ if (tun->sIPv6_Local) { free(tun->sIPv6_Local); tun->sIPv6_Local = NULL; }
+ if (tun->sIPv6_POP) { free(tun->sIPv6_POP); tun->sIPv6_POP = NULL; }
+ free(tun);
+ tun = NULL;
+}
+
+void tic_Free_Route(struct TIC_Route *rt)
+{
+ if (rt->sId) free(rt->sId);
+ if (rt->sTunnelId) free(rt->sTunnelId);
+ free(rt);
+}
+
+void tic_Free_POP(struct TIC_POP *pop)
+{
+ if (pop->sId) free(pop->sId);
+ if (pop->sCity) free(pop->sCity);
+ if (pop->sCountry) free(pop->sCountry);
+ if (pop->sIPv4) free(pop->sIPv4);
+ if (pop->sIPv6) free(pop->sIPv6);
+ if (pop->sISP_Short) free(pop->sISP_Short);
+ if (pop->sISP_Name) free(pop->sISP_Name);
+ if (pop->sISP_Website) free(pop->sISP_Website);
+ if (pop->sISP_ASN) free(pop->sISP_ASN);
+ if (pop->sISP_LIR) free(pop->sISP_LIR);
+
+ free(pop);
+}
--- /dev/null
+/**********************************************************
+ SixXS - Automatic IPv6 Connectivity Configuration Utility
+***********************************************************
+ Copyright 2003-2005 SixXS - http://www.sixxs.net
+***********************************************************
+ common/tic.h - Tunnel Information & Control Protocol
+***********************************************************
+ $Author: jeroen $
+ $Id: tic.h,v 1.12 2006-12-21 14:08:50 jeroen Exp $
+ $Date: 2006-12-21 14:08:50 $
+**********************************************************/
+
+#ifndef TIC_H
+#define TIC_H "H5K7:W3NDY5UU5N1K1N1C0l3"
+
+#include "common.h"
+
+/*
+ * Tunnel Information Control Protocol
+ * server
+ */
+/* port - uses TCP over IPv4 */
+#define TIC_PORT "3874"
+
+/* TIC version (which document this should conform to) */
+#define TIC_VERSION "draft-00"
+
+struct TIC_sTunnel
+{
+ struct TIC_sTunnel *next; /* Next in list */
+ char *sId; /* Tunnel Id */
+ char *sIPv6; /* Local IPv6 Endpoint */
+ char *sIPv4; /* Local IPv4 Endpoint */
+ char *sPOPId; /* POP Id */
+};
+
+struct TIC_Tunnel
+{
+ char *sId; /* Tunnel Id */
+ char *sType; /* Tunnel Type */
+
+ /* IPv4 information */
+ char *sIPv4_Local; /* Local endpoint (*) */
+ char *sIPv4_POP; /* POP endpoint */
+
+ /* IPv6 information */
+ char *sIPv6_Local; /* Local endpoint */
+ char *sIPv6_POP; /* POP endpoint */
+ char *sIPv6_LinkLocal; /* Link local address */
+
+ /* POP information */
+ char *sPOP_Id; /* POP's Id */
+
+ /* States */
+ char *sUserState; /* Userstate */
+ char *sAdminState; /* Adminstate */
+
+ /* AYIYA & Heartbeat */
+ char *sPassword; /* Password for the tunnel */
+ uint32_t nHeartbeat_Interval; /* Heartbeat interval */
+
+ /* Misc */
+ uint32_t uses_tundev; /* Uses Tunnel (tun/tap) device? */
+ uint32_t nIPv6_PrefixLength; /* Length of the prefix's */
+ uint32_t nMTU; /* MTU size */
+};
+
+/* * = 0.0.0.0 for all the dynamic tunnels */
+
+struct TIC_sRoute
+{
+ struct TIC_sRoute *next; /* Next in list */
+ char *sId; /* Route Id */
+ char *sTunnelId; /* Tunnel Id */
+ char *sIPv6; /* Prefix */
+};
+
+struct TIC_Route
+{
+ char *sId; /* Route Id */
+ char *sTunnelId; /* Tunnel Id */
+ struct in6_addr xIPv6; /* Prefix */
+ uint32_t nPrefixLength; /* Length of the prefix */
+ uint32_t __pad;
+};
+
+
+struct TIC_sPOP
+{
+ struct TIC_sPOP *next; /* Next in list */
+ char *sId; /* POP's Id */
+};
+
+struct TIC_POP
+{
+ char *sId; /* POP's Id */
+ char *sCity; /* POP's City */
+ char *sCountry; /* POP's Country */
+ char *sIPv4; /* POP's Primary IPv4 address */
+ char *sIPv6; /* POP's Primary IPv6 address */
+
+ char *sISP_Short; /* ISP's Short name */
+ char *sISP_Name; /* ISP's Name */
+ char *sISP_Website; /* ISP's Website */
+ char *sISP_ASN; /* ISP's ASN */
+ char *sISP_LIR; /* ISP's LIR */
+};
+
+/*
+ * This structure makes TIC a bit more abstracted
+ * which makes this cleaner instead of passing 'sock' everywhere
+ */
+struct TIC_conf
+{
+ TLSSOCKET sock; /* The socket to which we are connected */
+};
+
+/**********************************************************
+ TIC Functions
+**********************************************************/
+
+/* Login to/Logout from the TIC Server */
+bool tic_Login(struct TIC_conf *tic, const char *username, const char *password, const char *server);
+void tic_Logout(struct TIC_conf *tic, const char *quitmsg);
+
+/* Check if the time is in range */
+int tic_checktime(time_t epochtime);
+
+/* Get Tunnel/Route/POP List */
+struct TIC_sTunnel *tic_ListTunnels(struct TIC_conf *tic);
+struct TIC_sRoute *tic_ListRoutes(struct TIC_conf *tic);
+struct TIC_sPOP *tic_ListPOPs(struct TIC_conf *tic);
+
+/* Get Tunnel/Route/POP Information */
+struct TIC_Tunnel *tic_GetTunnel(struct TIC_conf *tic, const char *sId);
+struct TIC_Route *tic_GetRoute(struct TIC_conf *tic, const char *sId);
+struct TIC_POP *tic_GetPOP(struct TIC_conf *tic, const char *sId);
+
+/* Free Information structures */
+void tic_Free_sTunnel(struct TIC_sTunnel *tun);
+void tic_Free_sRoute(struct TIC_sRoute *rt);
+void tic_Free_sPOP(struct TIC_sPOP *pop);
+void tic_Free_Tunnel(struct TIC_Tunnel *tun);
+void tic_Free_Route(struct TIC_Route *rt);
+void tic_Free_POP(struct TIC_POP *pop);
+
+#endif /* TIC_H */
--- /dev/null
+/**********************************************************
+ SixXS - Automatic IPv6 Connectivity Configuration Utility
+***********************************************************
+ Copyright 2003-2005 SixXS - http://www.sixxs.net
+***********************************************************
+ common/tun.c - Tunnel Device Handling
+***********************************************************
+ $Author: jeroen $
+ $Id: tun.c,v 1.14 2007-01-11 00:29:18 jeroen Exp $
+ $Date: 2007-01-11 00:29:18 $
+**********************************************************/
+
+#include "tun.h"
+#include "aiccu.h"
+
+/* The tun/tap device HANDLE */
+#ifndef _WIN32
+int tun_fd;
+
+/*
+ * HAS_IFHEAD -> Tunnel Device produces packets with a tun_pi in the front
+ * NEED_IFHEAD -> Tunnel Device produces packets with a tun_pi in the front, but it is not active per default
+ */
+
+#else
+HANDLE device_handle = INVALID_HANDLE_VALUE;
+#define ETH_P_IPV6 0x86dd
+#define ETH_ALEN 6
+struct ether_header
+{
+ uint8_t ether_dhost[ETH_ALEN]; /* destination eth addr */
+ uint8_t ether_shost[ETH_ALEN]; /* source ether addr */
+ uint16_t ether_type; /* packet type ID field */
+};
+
+/* Tap device constants which we use */
+#define TAP_CONTROL_CODE(request,method) CTL_CODE(FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS)
+#define TAP_IOCTL_GET_VERSION TAP_CONTROL_CODE(2, METHOD_BUFFERED)
+#define TAP_IOCTL_CONFIG_POINT_TO_POINT TAP_CONTROL_CODE(5, METHOD_BUFFERED)
+#define TAP_IOCTL_SET_MEDIA_STATUS TAP_CONTROL_CODE(6, METHOD_BUFFERED)
+#define TAP_REGISTRY_KEY "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}"
+#define TAP_ADAPTER_KEY "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}"
+#define TAP_DEVICE_DIR "\\\\.\\Global\\"
+#define TAP_WIN32_MIN_MAJOR 8
+#define TAP_WIN32_MIN_MINOR 1
+#define TAP_COMPONENT_ID1 "tap0801" /* Original Tun/Tap driver ID */
+#define TAP_COMPONENT_ID2 "tap0802" /* Windows Vista marked 801 as broken, thus use another ID */
+
+#endif
+
+void tun_log(int level, const char *what, const char *fmt, ...);
+void tun_log(int level, const char *what, const char *fmt, ...)
+{
+ char buf[1024];
+ va_list ap;
+
+ /* Clear them just in case */
+ memset(buf, 0, sizeof(buf));
+
+ snprintf(buf, sizeof(buf), "[tun-%s] ", what);
+
+ /* Print the log message behind it */
+ va_start(ap, fmt);
+ vsnprintf(buf+strlen(buf), sizeof(buf)-strlen(buf), fmt, ap);
+ va_end(ap);
+
+ /* Actually Log it */
+ dolog(level, buf);
+}
+
+static const char reader_name[] = "tundev->tun";
+static const char writer_name[] = "tun->tundev";
+
+#ifdef _WIN32
+/* Windows doesn't have writev() but does have WSASend */
+int writev(SOCKET sock, const struct iovec *vector, DWORD count)
+{
+ DWORD sent;
+ WSASend(sock, (LPWSABUF)vector, count, &sent, 0, NULL, NULL);
+ return sent;
+}
+
+uint16_t inchksum(const void *data, uint32_t length);
+uint16_t inchksum(const void *data, uint32_t length)
+{
+ register long sum = 0;
+ register const uint16_t *wrd = (const uint16_t *)data;
+ register long slen = (long)length;
+
+ while (slen >= 2)
+ {
+ sum += *wrd++;
+ slen-=2;
+ }
+
+ if (slen > 0) sum+=*(const uint8_t *)wrd;
+
+ while (sum >> 16) sum = (sum & 0xffff) + (sum >> 16);
+
+ return (uint16_t)sum;
+}
+
+uint16_t ipv6_checksum(const struct ip6_hdr *ip6, uint8_t protocol, const void *data, const uint16_t length);
+uint16_t ipv6_checksum(const struct ip6_hdr *ip6, uint8_t protocol, const void *data, const uint16_t length)
+{
+ struct
+ {
+ uint16_t length;
+ uint16_t zero1;
+ uint8_t zero2;
+ uint8_t next;
+ } pseudo;
+ register uint32_t chksum = 0;
+
+ pseudo.length = htons(length);
+ pseudo.zero1 = 0;
+ pseudo.zero2 = 0;
+ pseudo.next = protocol;
+
+ /* IPv6 Source + Dest */
+ chksum = inchksum(&ip6->ip6_src, sizeof(ip6->ip6_src) + sizeof(ip6->ip6_dst));
+ chksum += inchksum(&pseudo, sizeof(pseudo));
+ chksum += inchksum(data, length);
+
+ /* Wrap in the carries to reduce chksum to 16 bits. */
+ chksum = (chksum >> 16) + (chksum & 0xffff);
+ chksum += (chksum >> 16);
+
+ /* Take ones-complement and replace 0 with 0xFFFF. */
+ chksum = (uint16_t) ~chksum;
+ if (chksum == 0UL) chksum = 0xffffUL;
+ return (uint16_t)chksum;
+}
+#endif
+
+/*
+ * Tun -> Socket
+ *
+ * Needs to be started in a separate thread
+ * This gets done by tun_start()
+ *
+ */
+#ifndef _WIN32
+void *tun_reader(void *arg);
+void *tun_reader(void *arg)
+#else
+DWORD WINAPI tun_reader(LPVOID arg);
+DWORD WINAPI tun_reader(LPVOID arg)
+#endif
+{
+ unsigned char buf[2048];
+
+ /* The function that actually does something with the buffer */
+ struct tun_reader *tun = (struct tun_reader *)arg;
+
+#ifdef _WIN32
+ DWORD n, lenin;
+ OVERLAPPED overlapped;
+ unsigned int errcount = 0;
+
+ struct nd_sol
+ {
+ struct ip6_hdr ip;
+ struct icmp6_hdr icmp;
+ struct nd_neighbor_solicit sol;
+ } *solic = (struct nd_sol *)&buf[sizeof(struct ether)];
+
+ struct nd_adv
+ {
+ struct ip6_hdr ip;
+ struct icmp6_hdr icmp;
+ struct nd_neighbor_advert adv;
+ } advert;
+
+ /* Create an event for overlapped results */
+ overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+#else
+ ssize_t n;
+#endif
+
+ /* Forever */
+ while (true)
+ {
+#ifndef _WIN32
+ n = read(tun_fd, buf, sizeof(buf));
+ if (n <= 0)
+ {
+ /* Only report issues when the tunnel is actually up and running */
+ if (g_aiccu->tunrunning) tun_log(LOG_ERR, reader_name, "Read error on Tun Device: %s (%d)\n", strerror(errno), errno);
+ continue;
+ }
+
+#if defined(NEED_IFHEAD) || defined(HAS_IFHEAD)
+ /* get the tun_pi struct out of there */
+ memmove(&buf, &buf[4], n-4);
+ n-=4;
+#endif
+
+ tun->function((char *)buf, (unsigned int)n);
+#else /* Windows */
+ overlapped.Offset = 0;
+ overlapped.OffsetHigh = 0;
+
+ memset(buf,0,sizeof(buf));
+ n = ReadFile(device_handle, buf, sizeof(buf), &lenin, &overlapped);
+ if (!n)
+ {
+ while (!n && GetLastError() == ERROR_IO_PENDING)
+ {
+ if (WaitForSingleObject(overlapped.hEvent, 20000) == WAIT_OBJECT_0)
+ {
+ n = GetOverlappedResult(device_handle, &overlapped, &lenin, FALSE);
+ }
+ }
+
+ if (!n)
+ {
+ tun_log(LOG_ERR, reader_name, "Error reading from device: %u, %s (%d)\n", GetLastError(), strerror(errno), errno);
+ errcount++;
+ if (errcount > 10) break;
+ continue;
+ }
+ }
+
+ /* Check for neighbour discovery packets (ICMPv6, ND_SOL, hop=255)
+ * (XXX: doesn't check for a chain, but ND is usually without)
+ */
+ if ( solic->ip.ip6_ctlun.ip6_un1.ip6_un1_nxt == IPPROTO_ICMPV6 &&
+ solic->icmp.icmp6_type == ND_NEIGHBOR_SOLICIT &&
+ solic->ip.ip6_ctlun.ip6_un1.ip6_un1_hlim == 255)
+ {
+ /* Ignore unspecified ND's as they are used for DAD */
+ if (IN6_IS_ADDR_UNSPECIFIED(&solic->ip.ip6_src)) continue;
+
+ /* Create our reply */
+ memset(&advert, 0, sizeof(advert));
+ advert.ip.ip6_ctlun.ip6_un2_vfc = 6 << 4;
+ advert.ip.ip6_ctlun.ip6_un1.ip6_un1_flow = solic->ip.ip6_ctlun.ip6_un1.ip6_un1_flow;
+ advert.ip.ip6_ctlun.ip6_un1.ip6_un1_plen = htons(sizeof(advert.icmp) + sizeof(advert.adv));
+ advert.ip.ip6_ctlun.ip6_un1.ip6_un1_nxt = IPPROTO_ICMPV6;
+ advert.ip.ip6_ctlun.ip6_un1.ip6_un1_hlim = 255;
+
+ /* Swap src/dst */
+ memcpy(&advert.ip.ip6_src, &solic->sol.nd_ns_target, sizeof(advert.ip.ip6_src));
+ memcpy(&advert.ip.ip6_dst, &solic->ip.ip6_src, sizeof(advert.ip.ip6_dst));
+
+ /* ICMP Neighbour Advertisement */
+ advert.icmp.icmp6_type = ND_NEIGHBOR_ADVERT;
+ advert.icmp.icmp6_code = 0;
+ advert.icmp.icmp6_dataun.icmp6_un_data8[0] = 0xe0;
+ memcpy(&advert.adv.nd_na_target, &solic->sol.nd_ns_target, sizeof(advert.adv.nd_na_target));
+ /* Fake MAC address */
+ advert.adv.nd_no_type = 2;
+ advert.adv.nd_no_len = 1;
+ advert.adv.nd_no_mac[0] = 0x00;
+ advert.adv.nd_no_mac[1] = 0xff;
+ advert.adv.nd_no_mac[2] = 0x25;
+ advert.adv.nd_no_mac[3] = 0x02;
+ advert.adv.nd_no_mac[4] = 0x19;
+ advert.adv.nd_no_mac[5] = 0x78;
+
+ /* ICMP has a checksum */
+ advert.icmp.icmp6_cksum = ipv6_checksum(&advert.ip, IPPROTO_ICMPV6, (uint8_t *)&advert.icmp, sizeof(advert.icmp) + sizeof(advert.adv));
+
+ /* We'll need to answer this back to the TAP device */
+ tun_write((char *)&advert, (unsigned int)sizeof(advert));
+ continue;
+ }
+ tun->function((char *)&buf[sizeof(struct ether)], (unsigned int)lenin - sizeof(struct ether));
+#endif
+ }
+
+ D(dolog(LOG_DEBUG, "TUN Reader stopping\n"));
+#ifndef _WIN32
+ return NULL;
+#else
+ return 0;
+#endif
+}
+
+/* Socket -> Tun */
+void tun_write(char *buf, unsigned int length)
+{
+ unsigned int c = 0;
+#ifndef _WIN32
+#ifdef linux
+ struct iovec dat[2];
+ struct tun_pi pi;
+ memset(&pi, 0, sizeof(pi));
+
+ pi.proto = htons(ETH_P_IPV6);
+
+ dat[0].iov_base = π
+ dat[0].iov_len = sizeof(pi);
+ dat[1].iov_base = buf;
+ dat[1].iov_len = length;
+
+ length += sizeof(pi);
+
+ /* Forward the packet to the kernel */
+ c = writev(tun_fd, dat, 2);
+
+#else /* *BSD/Darwin */
+
+ uint32_t type = htonl(AF_INET6);
+ struct iovec dat[2];
+
+ dat[0].iov_base = (void *)&type;
+ dat[0].iov_len = sizeof(type);
+ dat[1].iov_base = buf;
+ dat[1].iov_len = length;
+
+ length += sizeof(type);
+
+ /* Forward the packet to the kernel */
+ c = writev(tun_fd, dat, 2);
+
+#endif
+
+ if (c != length)
+ {
+ tun_log(LOG_ERR, writer_name, "Error while writing to TUN: %u != %u\n", c, length);
+ }
+
+#else /* Windows */
+ DWORD n, lenout;
+ OVERLAPPED overlapped;
+ unsigned char mbuf[4096];
+
+ struct ether *eth = (struct ether *)mbuf;
+
+ /* Sent the packet outbound */
+ overlapped.Offset = 0;
+ overlapped.OffsetHigh = 0;
+ overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+
+ memset(mbuf,0,sizeof(mbuf));
+ eth->ether_dhost[0] = htons(0x3333);
+ eth->ether_dhost[1] = htons(0xff00);
+ eth->ether_dhost[2] = htons(0x0002);
+ eth->ether_shost[0] = htons(0x00ff);
+ eth->ether_shost[1] = htons(0x5342);
+ eth->ether_shost[2] = htons(0x2768);
+ eth->ether_type = htons(ETH_P_IPV6);
+ memcpy(&mbuf[sizeof(*eth)],buf,length);
+
+ n = WriteFile(device_handle, mbuf, sizeof(*eth)+length, &lenout, &overlapped);
+ if (!n && GetLastError() == ERROR_IO_PENDING)
+ {
+ WaitForSingleObject(overlapped.hEvent, INFINITE);
+ n = GetOverlappedResult(device_handle, &overlapped, &lenout, FALSE);
+ }
+
+ if (!n)
+ {
+ tun_log(LOG_ERR, writer_name, "Error writing to device: %u, %s (%d)\n", GetLastError(), strerror(errno), errno);
+ }
+#endif
+}
+
+#ifdef _WIN32
+
+struct tap_reg
+{
+ char *guid;
+ struct tap_reg *next;
+};
+
+struct panel_reg
+{
+ char *name;
+ char *guid;
+ struct panel_reg *next;
+};
+
+/* Get a working tunnel adapter */
+struct tap_reg *get_tap_reg(void)
+{
+ HKEY adapter_key;
+ LONG status;
+ DWORD len;
+ struct tap_reg *first = NULL;
+ struct tap_reg *last = NULL;
+ int i = 0;
+
+ status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TAP_ADAPTER_KEY, 0, KEY_READ, &adapter_key);
+ if (status != ERROR_SUCCESS)
+ {
+ dolog(LOG_ERR, "Error opening registry key: %s\n", TAP_ADAPTER_KEY);
+ return NULL;
+ }
+
+ while (true)
+ {
+ char enum_name[256];
+ char unit_string[256];
+ HKEY unit_key;
+ char component_id_string[] = "ComponentId";
+ char component_id[256];
+ char net_cfg_instance_id_string[] = "NetCfgInstanceId";
+ char net_cfg_instance_id[256];
+ DWORD data_type;
+
+ len = sizeof(enum_name);
+ status = RegEnumKeyEx(adapter_key, i, enum_name, &len, NULL, NULL, NULL, NULL);
+ if (status == ERROR_NO_MORE_ITEMS) break;
+ else if (status != ERROR_SUCCESS)
+ {
+ dolog(LOG_ERR, "Error enumerating registry subkeys of key: %s (t0)\n", TAP_ADAPTER_KEY);
+ break;
+ }
+
+ snprintf(unit_string, sizeof(unit_string), "%s\\%s", TAP_ADAPTER_KEY, enum_name);
+ status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, unit_string, 0, KEY_READ, &unit_key);
+ if (status != ERROR_SUCCESS)
+ {
+ dolog(LOG_WARNING, "Error opening registry key: %s (t1)\n", unit_string);
+ }
+ else
+ {
+ len = sizeof(component_id);
+ status = RegQueryValueEx(unit_key, component_id_string, NULL, &data_type, (LPBYTE)component_id, &len);
+ if (status != ERROR_SUCCESS || data_type != REG_SZ)
+ {
+ dolog(LOG_WARNING, "Error opening registry key: %s\\%s (t2)\n", unit_string, component_id_string);
+ }
+ else
+ {
+ len = sizeof(net_cfg_instance_id);
+ status = RegQueryValueEx(unit_key, net_cfg_instance_id_string, NULL, &data_type, (LPBYTE)net_cfg_instance_id, &len);
+ if (status == ERROR_SUCCESS && data_type == REG_SZ)
+ {
+ if ( strcmp(component_id, TAP_COMPONENT_ID1) == 0 ||
+ strcmp(component_id, TAP_COMPONENT_ID2) == 0)
+ {
+ struct tap_reg *reg = (struct tap_reg *)malloc(sizeof(*reg));
+ memset(reg, 0, sizeof(*reg));
+ reg->guid = strdup(net_cfg_instance_id);
+
+ if (!first) first = reg;
+ if (last) last->next = reg;
+ last = reg;
+ }
+ }
+ }
+
+ RegCloseKey(unit_key);
+ }
+ i++;
+ }
+
+ RegCloseKey(adapter_key);
+ return first;
+}
+
+void free_tap_reg(struct tap_reg *tap_reg)
+{
+ struct tap_reg *tr, *tr1;
+
+ for (tr = tap_reg; tr != NULL; tr = tr1)
+ {
+ tr1 = tr->next;
+ free(tr->guid);
+ free(tr);
+ }
+}
+
+void free_panel_reg(struct panel_reg *panel_reg)
+{
+ struct panel_reg *pr, *pr1;
+
+ for (pr = panel_reg; pr != NULL; pr = pr1)
+ {
+ pr1 = pr->next;
+ free(pr->guid);
+ free(pr->name);
+ free(pr);
+ }
+}
+
+
+/* Collect GUID's and names of all the Connections that are available */
+struct panel_reg *get_panel_reg(void)
+{
+ LONG status;
+ HKEY network_connections_key;
+ DWORD len;
+ struct panel_reg *first = NULL;
+ struct panel_reg *last = NULL;
+ int i = 0;
+
+ status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, TAP_REGISTRY_KEY, 0, KEY_READ, &network_connections_key);
+
+ if (status != ERROR_SUCCESS)
+ {
+ dolog(LOG_ERR, "Error opening registry key: %s (p0)\n", TAP_REGISTRY_KEY);
+ return NULL;
+ }
+
+ while (true)
+ {
+ char enum_name[256];
+ char connection_string[256];
+ HKEY connection_key;
+ char name_data[256];
+ DWORD name_type;
+ const char name_string[] = "Name";
+
+ len = sizeof(enum_name);
+ status = RegEnumKeyEx(network_connections_key, i, enum_name, &len, NULL, NULL, NULL, NULL);
+ if (status == ERROR_NO_MORE_ITEMS) break;
+ else if (status != ERROR_SUCCESS)
+ {
+ dolog(LOG_ERR, "Error enumerating registry subkeys of key: %s (p1)\n", TAP_REGISTRY_KEY);
+ break;
+ }
+
+ i++;
+
+ if (enum_name[0] != '{') continue;
+
+ snprintf(connection_string, sizeof(connection_string), "%s\\%s\\Connection", TAP_REGISTRY_KEY, enum_name);
+
+ status = RegOpenKeyEx(HKEY_LOCAL_MACHINE, connection_string, 0, KEY_READ, &connection_key);
+ if (status != ERROR_SUCCESS)
+ {
+ dolog(LOG_WARNING, "Error opening registry key: %s (p2)\n", connection_string);
+ }
+ else
+ {
+ len = sizeof(name_data);
+ status = RegQueryValueEx(connection_key, name_string, NULL, &name_type, (LPBYTE)name_data, &len);
+
+ if (status != ERROR_SUCCESS || name_type != REG_SZ)
+ {
+ dolog(LOG_WARNING, "Error opening registry key: %s\\%s\\%s (p3)\n", TAP_REGISTRY_KEY, (LPBYTE)connection_string, name_string);
+ }
+ else
+ {
+ struct panel_reg *reg = (struct panel_reg *)malloc(sizeof(*reg));
+ memset(reg, 0, sizeof(*reg));
+ reg->name = strdup(name_data);
+ reg->guid = strdup(enum_name);
+
+ /* link into return list */
+ if (!first) first = reg;
+ if (last) last->next = reg;
+ last = reg;
+ }
+
+ RegCloseKey(connection_key);
+ }
+ }
+
+ RegCloseKey(network_connections_key);
+
+ return first;
+}
+
+void tun_list_tap_adapters(void)
+{
+ int links;
+ struct tap_reg *tap_reg = get_tap_reg(), *tr, *tr1;
+ struct panel_reg *panel_reg = get_panel_reg(), *pr;
+
+ dolog(LOG_INFO, "Available TAP-WIN32 adapters [name, GUID]:\n");
+
+ /* loop through each TAP-Win32 adapter registry entry */
+ for (tr = tap_reg; tr != NULL; tr = tr->next)
+ {
+ links = 0;
+
+ /* loop through each network connections entry in the control panel */
+ for (pr = panel_reg; pr != NULL; pr = pr->next)
+ {
+ if (strcmp(tr->guid, pr->guid) == 0)
+ {
+ dolog(LOG_INFO, "'%s' %s\n", pr->name, tr->guid);
+ links++;
+ }
+ }
+
+ if (links > 1)
+ {
+ dolog(LOG_WARNING, "*** Adapter with GUID %s has %u links from the Network Connections control panel, it should only be 1\n", tr->guid, links);
+ }
+ else if (links == 0)
+ {
+ dolog(LOG_WARNING, "[NULL] %s\n", tr->guid);
+ dolog(LOG_WARNING, "*** Adapter with GUID %s doesn't have a link from the control panel\n", tr->guid);
+ }
+
+ /* check for TAP-Win32 adapter duplicated GUIDs */
+ for (tr1 = tap_reg; tr1 != NULL; tr1 = tr1->next)
+ {
+ if (tr != tr1 && strcmp(tr->guid, tr1->guid) == 0)
+ {
+ dolog(LOG_WARNING, "*** Duplicate Adapter GUID %s\n", tr->guid);
+ }
+ }
+ }
+
+ free_tap_reg(tap_reg);
+ free_panel_reg(panel_reg);
+}
+
+bool tun_fixup_adapters(void)
+{
+ int links, count = 0, found = 0;
+ struct tap_reg *tap_reg = get_tap_reg(), *tr = NULL, *tr1 = NULL;
+ struct panel_reg *panel_reg = get_panel_reg(), *pr = NULL, *first = NULL, *prf = NULL;
+ bool ok;
+
+ /* loop through each TAP-Win32 adapter registry entry */
+ for (tr = tap_reg; tr != NULL; tr = tr->next)
+ {
+ links = 0;
+ ok = true;
+
+ /* loop through each network connections entry in the control panel */
+ for (pr = panel_reg; pr != NULL; pr = pr->next)
+ {
+ if (strcmp(tr->guid, pr->guid) == 0)
+ {
+ links++;
+ prf = pr;
+
+ /* Is this the one wanted by the user? */
+ if (strcasecmp(g_aiccu->ipv6_interface, pr->name) == 0) found++;
+ }
+ }
+
+ if (links > 1)
+ {
+ dolog(LOG_WARNING, "*** Adapter with GUID %s has %u links from the Network Connections control panel, it should only be 1\n", tr->guid, links);
+ ok = false;
+ }
+ else if (links == 0)
+ {
+ dolog(LOG_WARNING, "[NULL] %s\n", tr->guid);
+ dolog(LOG_WARNING, "*** Adapter with GUID %s doesn't have a link from the control panel\n", tr->guid);
+ ok = false;
+ }
+
+ /* check for TAP-Win32 adapter duplicated GUIDs */
+ for (tr1 = tap_reg; tr1 != NULL; tr1 = tr1->next)
+ {
+ if (tr != tr1 && strcmp(tr->guid, tr1->guid) == 0)
+ {
+ dolog(LOG_WARNING, "*** Duplicate Adapter GUID %s\n", tr->guid);
+ ok = false;
+ }
+ }
+
+ if (ok)
+ {
+ count++;
+ first = prf;
+ }
+ }
+
+ ok = false;
+
+ /* When the user didn't configure us correctly and we find a single TAP interface, just rename it */
+ if (found == 0 && count == 1 && first)
+ {
+ dolog(LOG_INFO, "Renaming adapter '%s' to '%s' and using it\n", first->name, g_aiccu->ipv6_interface);
+ aiccu_win32_rename_adapter(first->name);
+ ok = true;
+ }
+ else if (found == 1 && count == 1)
+ {
+ D(dolog(LOG_DEBUG, "Using configured interface %s\n", g_aiccu->ipv6_interface));
+ ok = true;
+ }
+ else
+ {
+ ok = false;
+ dolog(LOG_WARNING, "Found = %u, Count = %u\n", found, count);
+ }
+
+ free_tap_reg(tap_reg);
+ free_panel_reg(panel_reg);
+
+ return ok;
+}
+
+#endif
+
+bool tun_start(struct tun_reader *tun)
+{
+#ifndef _WIN32
+ pthread_t thread;
+#ifdef linux
+ struct ifreq ifr;
+
+ /* Create a new tap device */
+ tun_fd = open("/dev/net/tun", O_RDWR);
+ if (tun_fd == -1)
+ {
+ tun_log(LOG_ERR, "start", "Couldn't open device %s: %s (%d)\n", "/dev/net/tun", strerror(errno), errno);
+ return false;
+ }
+
+ memset(&ifr, 0, sizeof(ifr));
+ /* Request a TUN device */
+ ifr.ifr_flags = IFF_TUN;
+ /* Set the interface name */
+ strncpy(ifr.ifr_name, g_aiccu->ipv6_interface, sizeof(ifr.ifr_name));
+
+ if (ioctl(tun_fd, TUNSETIFF, &ifr))
+ {
+ tun_log(LOG_ERR, "start", "Couldn't set interface name to %s: %s (%d)\n",
+ g_aiccu->ipv6_interface, strerror(errno), errno);
+ return false;
+ }
+
+#else /* *BSD/Darwin */
+
+ char buf[128];
+ unsigned int i;
+ int mode = IFF_MULTICAST | IFF_POINTOPOINT;
+
+ /* Try the configured interface */
+ tun_log(LOG_DEBUG, "start", "Trying Configured TUN/TAP interface %s...\n", g_aiccu->ipv6_interface);
+ snprintf(buf, sizeof(buf), "/dev/%s", g_aiccu->ipv6_interface);
+ tun_fd = open(buf, O_RDWR);
+ if (tun_fd < 0)
+ {
+ /* Fall back to trying all /dev/tun* devices */
+ for (i = 0; i < 256; ++i)
+ {
+ snprintf(buf, sizeof(buf), "/dev/tun%u", i);
+ tun_log(LOG_DEBUG, "start", "Trying TUN/TAP interface %s...\n", &buf[8]);
+ tun_fd = open(buf, O_RDWR);
+ if (tun_fd >= 0)
+ {
+ /* Copy over the name of the interface so that configging goes okay */
+ if (g_aiccu->ipv6_interface) free(g_aiccu->ipv6_interface);
+ snprintf(buf, sizeof(buf), "tun%u", i);
+ g_aiccu->ipv6_interface = strdup(buf);
+ }
+ break;
+ }
+ }
+
+ if (tun_fd < 0)
+ {
+ tun_log(LOG_ERR, "start", "Couldn't open device %s or /dev/tun*: %s (%d)\n", g_aiccu->ipv6_interface, strerror(errno), errno);
+ return false;
+ }
+
+ tun_log(LOG_DEBUG, "start", "Using TUN/TAP interface %s\n", g_aiccu->ipv6_interface);
+
+#ifndef _FREEBSD
+#ifndef _DARWIN
+#ifndef _AIX
+ tun_log(LOG_DEBUG, "start", "Setting TUNSIFMODE for %s\n", g_aiccu->ipv6_interface);
+ if (ioctl(tun_fd, TUNSIFMODE, &mode, sizeof(mode)) == -1)
+ {
+ tun_log(LOG_ERR, "start", "Couldn't set interface %s's TUNSIFMODE to MULTICAST|POINTOPOINT: %s (%d)\n",
+ g_aiccu->ipv6_interface, strerror(errno), errno);
+ close(tun_fd);
+ tun_fd = -1;
+ return false;
+ }
+#endif
+#endif
+#endif
+
+#ifdef NEED_IFHEAD
+ tun_log(LOG_DEBUG, "start", "Setting TUNSIFHEAD for %s\n", g_aiccu->ipv6_interface);
+ mode = 1;
+ if (ioctl(tun_fd, TUNSIFHEAD, &mode, sizeof(mode)) == -1)
+ {
+ tun_log(LOG_ERR, "start", "Couldn't set interface %s's TUNSIFHEAD to enabled: %s (%d)\n",
+ g_aiccu->ipv6_interface, strerror(errno), errno);
+ close(tun_fd);
+ tun_fd = -1;
+ return false;
+ }
+#endif
+
+#endif /* linux */
+
+
+#else /* Windows */
+
+ HKEY key;
+ DWORD pID;
+ HANDLE h;
+ int i;
+
+ char adapterid[1024];
+ char tapname[1024];
+ DWORD len;
+
+ if (!tun_fixup_adapters())
+ {
+ tun_log(LOG_ERR, "start", "TAP-Win32 Adapter not configured properly...\n");
+ return false;
+ }
+
+ /* Open registry and look for network adapters */
+ if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, TAP_REGISTRY_KEY, 0, KEY_READ, &key))
+ {
+ tun_log(LOG_ERR, "start", "Could not open the networking registry key\n");
+ return false;
+ }
+
+ for (i = 0; device_handle == INVALID_HANDLE_VALUE; i++)
+ {
+ len = sizeof(adapterid);
+ if (RegEnumKeyEx(key, i, adapterid, &len, 0, 0, 0, NULL)) break;
+
+ snprintf(tapname, sizeof(tapname), TAP_DEVICE_DIR "%s.tap", adapterid);
+ tun_log(LOG_DEBUG, "start", "Trying %s\n", tapname);
+ device_handle = CreateFile(tapname, GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0);
+
+ if (device_handle != INVALID_HANDLE_VALUE)
+ {
+ unsigned long status, info[3] = {0,0,0};
+
+ /* get driver version info */
+ if (DeviceIoControl(device_handle, TAP_IOCTL_GET_VERSION, &info, sizeof(info), &info, sizeof(info), &len, NULL))
+ {
+ D(tun_log(LOG_DEBUG, "start", "TAP-Win32 Driver Version %d.%d %s", (int)info[0], (int)info[1], info[2] ? "(DEBUG)" : ""));
+ }
+
+ if (!(info[0] > TAP_WIN32_MIN_MAJOR || (info[0] == TAP_WIN32_MIN_MAJOR && info[1] >= TAP_WIN32_MIN_MINOR)))
+ {
+ tun_log(LOG_ERR, "start", "A TAP-Win32 driver is required that is at least version %d.%d -- If you recently upgraded your Tap32 driver, a reboot is probably required at this point to get Windows to see the new driver.", TAP_WIN32_MIN_MAJOR, TAP_WIN32_MIN_MINOR);
+ CloseHandle(device_handle);
+ device_handle = INVALID_HANDLE_VALUE;
+ continue;
+ }
+
+ /* Note: we use TAP mode on Windows, not TUN */
+
+ /* Try to mark the device as 'up */
+ status = true;
+ DeviceIoControl(device_handle, TAP_IOCTL_SET_MEDIA_STATUS, &status, sizeof(status), &status, sizeof(status), &len, NULL);
+ }
+ }
+
+ RegCloseKey(key);
+
+ if (device_handle == INVALID_HANDLE_VALUE)
+ {
+ tun_log(LOG_ERR, "start", "No working Tap device found!\n");
+ return false;
+ }
+
+#endif /* _WIN32 */
+
+ /* Launch a thread for reader */
+#ifndef _WIN32
+ pthread_create(&thread, NULL, tun_reader, (void *)tun);
+#else
+ h = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)tun_reader, tun, 0, &pID);
+#endif
+
+ /* We now return, the real tunneling tool can call tun_write() when it wants */
+
+ return true;
+}
--- /dev/null
+/**********************************************************
+ SixXS - Automatic IPv6 Connectivity Configuration Utility
+***********************************************************
+ Copyright 2003-2005 SixXS - http://www.sixxs.net
+***********************************************************
+ common/tun.h - Tunnel Device Handling
+***********************************************************
+ $Author: jeroen $
+ $Id: tun.h,v 1.3 2006-07-13 19:33:39 jeroen Exp $
+ $Date: 2006-07-13 19:33:39 $
+**********************************************************/
+
+#ifndef TUN_H
+#define TUN_H "H5K7:W3NDY5UU5N1K1N1C0l3"
+
+#include "common.h"
+
+#ifdef _WIN32
+/* Windows writev() support */
+struct iovec
+{
+ u_long iov_len;
+ char *iov_base;
+};
+
+int writev(SOCKET sock, const struct iovec *vector, DWORD count);
+void tun_list_tap_adapters(void);
+#endif
+
+#ifndef _WIN32
+ typedef void (*TUN_PROCESS)(char *, unsigned int);
+#else
+ typedef void (*TUN_PROCESS)(char *, unsigned int);
+#endif
+
+struct tun_reader
+{
+ TUN_PROCESS function;
+};
+
+void tun_write(char *buf, unsigned int length);
+bool tun_start(struct tun_reader *tun);
+
+#endif /* TUN_H */
+
--- /dev/null
+#!/bin/sh
+
+CONFIGFILE=/etc/aiccu.conf
+TMPCONF=/etc/aiccu.conf.$$.dpkg-tmp
+TMPFILE=/etc/aiccu.temp.$$.dpkg-tmp
+BINARY=/usr/sbin/aiccu
+
+# Note: the two temp files are placed in /etc thus should be symlink-attack safe
+
+if [ ! -x $BINARY ]; then
+ # Can't configure yet as we don't have our binary yet
+ exit 0;
+fi
+
+# Make sure that files we create are not readable by anyone but us (root)
+umask 077
+
+. /usr/share/debconf/confmodule
+
+if [ -e $CONFIGFILE ]; then
+ USERNAME=$(grep ^username $CONFIGFILE | awk '{print $2}')
+ PASSWORD=$(grep ^password $CONFIGFILE | awk '{print $2}')
+ PROTO=$(grep ^protocol $CONFIGFILE | awk '{print $2}')
+ SERVER=$(grep ^server $CONFIGFILE | awk '{print $2}')
+ TUNNEL=$(grep ^tunnel_id $CONFIGFILE | awk '{print $2}')
+
+ if [ "$USERNAME" != "" ]; then
+ db_set aiccu/username "$USERNAME"
+ fi
+
+ if [ "$PASSWORD" != "" ]; then
+ db_set aiccu/password "$PASSWORD"
+ fi
+
+ if [ "$PROTO" != "" -a "$SERVER" != "" ]; then
+ db_set aiccu/brokername "$PROTO://$SERVER"
+ fi
+
+ if [ "$TUNNEL" != "" ]; then
+ db_set aiccu/tunnelname "$TUNNEL"
+ fi
+fi
+
+
+db_reset aiccu/badauth
+
+#
+# State What
+# 1 Get Tunnel Brokername
+# 2 Get User/pass
+# 3 Get Tunnel ID
+# 4 Exit
+
+STATE=1
+while [ $STATE -ge 1 -a $STATE -le 3 ]; do
+
+ case "$STATE" in
+ 1)
+ # Fetch the list of tunnel brokers
+ BROKERS=$($BINARY brokers | sort >$TMPFILE)
+
+ if [ "$?" != "0" ]; then
+ # No TunnelBrokers found
+ db_input high aiccu/nobrokers || true
+ echo "No brokers"
+ else
+ # Found Tunnel brokers, present them to the user
+ BROKERS=$(cat $TMPFILE | cut -f1 -d'|' | awk '{print $0","}')
+ BROKERS=$(echo -n $BROKERS | sed 'N;s/\n//g' | sed 's/,$//g')
+ db_subst aiccu/brokername brokers "$BROKERS"
+ db_fset aiccu/brokername seen false
+ db_input high aiccu/brokername || true
+ db_go || true
+ fi
+
+ # Remove temporary file
+ rm $TMPFILE
+ ;;
+
+ 2)
+ # Request User / Pass
+ db_input high aiccu/username || true
+ db_input high aiccu/password || true
+ db_go || true
+ ;;
+
+ 3)
+ # Reset our temp config file
+ echo "# Temporary AICCU config written by debconf" > $TMPCONF
+ #echo "verbose true" >> $TMPCONF
+
+ # Take the Protocol and server from the Brokername
+ db_get aiccu/brokername
+ URL=$($BINARY brokers | grep "$RET")
+ PROTO=$(echo $URL | cut -f2 -d'|' | cut -f1 -d:)
+ SERVER=$(echo $URL | cut -f2 -d'|' | cut -f3 -d/)
+
+ echo "protocol $PROTO" >> $TMPCONF
+ echo "server $SERVER" >> $TMPCONF
+
+ db_get aiccu/username
+ USERNAME="$RET"
+
+ db_get aiccu/password
+ PASSWORD="$RET"
+
+ # Try to get the tunnels using the provided user/pass
+ if [ "$USERNAME" != "" -a "$PASSWORD" != "" ]; then
+ echo "username $USERNAME" >> $TMPCONF
+ echo "password $PASSWORD" >> $TMPCONF
+
+ TUNNELS=$($BINARY tunnels $TMPCONF >$TMPFILE)
+
+ if [ "$?" != "0" ]; then
+ db_input high aiccu/badauth || true
+ else
+ db_set aiccu/badauth "false"
+
+ TUNNELS=$(cat $TMPFILE | cut -f1 -d' ' | awk '{print $0","}')
+ TUNNELS=$(echo -n $TUNNELS | sed 'N;s/\n//g' | sed 's/,$//g')
+
+ if [ "$TUNNELS" = "" ]; then
+ db_input high aiccu/notunnels || true
+ else
+ db_subst aiccu/tunnelname tunnels "$TUNNELS"
+ db_input high aiccu/tunnelname || true
+ db_go || true
+ fi
+ fi
+
+ # Remove temporary file
+ rm $TMPFILE
+ else
+ db_set aiccu/badauth "false"
+ fi
+
+ # Remove the temporary as we don't need it anymore
+ rm $TMPCONF
+ ;;
+ esac
+
+ db_go
+
+ case "$STATE" in
+ 1)
+ STATE=2
+ ;;
+ 2)
+ STATE=3
+ ;;
+ 3)
+ db_get aiccu/badauth
+
+ # When badly authenticated do it all over
+ if [ "$RET" = "true" ]; then
+ STATE=1
+ db_reset aiccu/brokername
+ db_reset aiccu/username
+ db_reset aiccu/password
+ db_reset aiccu/tunnelname
+ else
+ STATE=4
+ fi
+ db_reset aiccu/badauth
+ ;;
+ esac
+done
+
--- /dev/null
+doc/aiccu.1
--- /dev/null
+#!/bin/sh -e
+
+CONFIGFILE="/etc/aiccu.conf"
+TMPCONF=/etc/aiccu.conf.dpkg-tmp
+EXAMPLE=/usr/share/doc/aiccu/examples/aiccu.conf
+CTLINFO="# Under control from debconf, please use 'dpkg-reconfigure aiccu' to reconfigure"
+BINARY=/usr/sbin/aiccu
+
+. /usr/share/debconf/confmodule
+
+db_get aiccu/username
+USERNAME="$RET"
+
+db_get aiccu/password
+PASSWORD="$RET"
+
+AICCUOUT=$($BINARY brokers)
+
+db_get aiccu/brokername
+URL=$(echo "$AICCUOUT" | grep "$RET")
+PROTO=$(echo $URL | cut -f2 -d'|' | cut -f1 -d:)
+SERVER=$(echo $URL | cut -f2 -d'|' | cut -f3 -d/)
+
+db_get aiccu/tunnelname
+TUNNEL="$RET"
+
+db_stop
+
+if [ "$USERNAME" = "" ]; then
+ # Not configured yet, thus skip
+ exit 0;
+fi
+
+# Defaults when nothing gets chosen
+# This might happen because of broken DNS
+if [ "$PROTO" = "" ]; then
+ PROTO="tic"
+fi
+
+if [ "$SERVER" = "" ]; then
+ SERVER="tic.sixxs.net"
+fi
+
+# Make sure that files we create are not readable by anyone but us (root)
+umask 077
+
+# Check if the /etc/aiccu.conf is actually the example
+if [ diff -q $EXAMPLE $CONFIGFILE 2>/dev/null >/dev/null ]; then
+ DEFAULTCONFIG="true"
+else
+ DEFAULTCONFIG="false"
+fi
+
+# Install a default config when it didn't exist yet or it is the same as the example
+# bash uses '==', dash uses '=', thus use '!=' as that is the same
+if [ "$DEFAULTCONFIG" != "false" -o ! -e "$CONFIGFILE" ]; then
+
+ # Note that it is under debconf control
+ echo $CTLINFO >> $TMPCONF
+
+ # Replace the example lines so that they become normals
+ sed -e "s/^#username .*/username $USERNAME/; s/^#password .*/password $PASSWORD/; s/^#protocol .*/protocol $PROTO/; s/^#server .*/server $SERVER/; s/^#tunnel_id .*/tunnel_id $TUNNEL/;" < $EXAMPLE >> $TMPCONF
+
+# Modify the existing one
+else
+ # Note that it is under debconf control
+ if ! grep -q "^$CTLINFO" $CONFIGFILE; then
+ echo $CTLINFO >> $TMPCONF >>$TMPCONF
+ fi
+
+ # Make sure that all the variables can be stored somewhere
+ if ! grep -q "^username" $CONFIGFILE; then
+ if [ "$USERNAME" != "" ]; then
+ echo "username $USERNAME" >> $TMPCONF
+ fi
+ fi
+
+ if ! grep -q "^password" $CONFIGFILE; then
+ if [ "$PASSWORD" != "" ]; then
+ echo "password $PASSWORD" >> $TMPCONF
+ fi
+ fi
+
+ if ! grep -q "^protocol" $CONFIGFILE; then
+ if [ "$PROTO" != "" ]; then
+ echo "protocol $PROTO" >> $TMPCONF
+ fi
+ fi
+ if ! grep -q "^server" $CONFIGFILE; then
+ if [ "$SERVER" != "" ]; then
+ echo "server $SERVER" >> $TMPCONF
+ fi
+ fi
+
+ if ! grep -q "^tunnel_id" $CONFIGFILE; then
+ if [ "$TUNNEL" != "" ]; then
+ echo "tunnel_id $TUNNEL" >> $TMPCONF
+ fi
+ fi
+
+ sed -e "s/^username .*/username $USERNAME/; s/^password .*/password $PASSWORD/; s/^protocol .*/protocol $PROTO/; s/^server .*/server $SERVER/; s/^tunnel_id .*/tunnel_id $TUNNEL/;" < $CONFIGFILE >> $TMPCONF
+fi
+
+# Move it into place
+mv -f $TMPCONF $CONFIGFILE
+# Just in case, make sure the permissions are perfect and dandy
+chmod 600 $CONFIGFILE
+
--- /dev/null
+#!/bin/sh -e
+
+#DEBHELPER#
--- /dev/null
+aiccu (20070115) stable; urgency=medium
+ * Fixup in Debian init script (based on original patch by Bernhard Schmidt).
+ * Change in redirections so that errors don't show in debconf menu's etc.
+ * NetBSD fixes as there is not always a Tunnel Device that
+ supports IPv6 (thanks to Geert Hendrickx).
+ * Gentoo ebuild update, adding depends and require ntp-client.
+ * RPM spec update, add build-requirement.
+ * Check return values of system commands.
+ * Added a big warning about running AICCU from Daemontools and similar
+ programs which run AICCU in a loop, thus hammering the TIC server.
+ * Be a bit smarter in checking for support of IPv6.
+
+ -- Jeroen Massar <jeroen@sixxs.net> Mon, 15 Jan 2007 11:00:42 +0000
+
+aiccu (20070107) stable; urgency=high
+ * 2007 Edition of AICCU.
+ * License change to standard 3-clause BSD license.
+ With thanks to Theo de Raadt, Marco d'Itri and Philipp Kern for
+ their wise words and reasoning for coming to this decision.
+ * High urgency because of the above and it fixing large problems.
+ * Fixed Mac OS X / Darwin support on the MacBookPro of Pim van Pelt.
+ * Added MTU, from TIC, configuration on most platforms.
+ * Fixed up silly linux bug, adding LL address to tunnels but not to tun/taps.
+ * Removed Win32 Alpha Endianess (reported by Christian Weisgerber).
+ * Fixed up alignment error in parseline() (reported by Christian Weisgerber).
+ * OpenBSD 4.0 support (patch provided by Christian Weisgerber).
+ * OpenBSD AYIYA fixup (patch provided by Pim van Pelt).
+ * Fedora/RPM init script fixup (bash case's don't fall through)
+ reported and patch supplied by Matt Domsch.
+ * NetBSD AYIYA support (noted by Tobias Riediger)
+ Works on NetBSD 4.x, for NetBSD 3.0 one needs to patch tun/tap to
+ support IPv6. Patch is available from the archives.
+ * local_ipv4_override option so one can use AICCU behind a NAT that
+ has been configured correctly to do proto-41 forwarding. This is
+ usually called a DMZ setup.
+
+ -- Jeroen Massar <jeroen@sixxs.net> Sun, 07 Jan 2007 14:00:42 +0000
+
+aiccu (20060806) stable; urgency=low
+ * Changelog version format change as the 'official' (before there where
+ legal issues as they don't understand the word 'SHOULD' which is cleary
+ defined in the IETF and now somebody simply uploaded it anyway it without
+ even asking or notifying us about it) debian packages which are broken,
+ old and unsupported would seem newer and thus this new version would not
+ get updated to even when folks would have the official AICCU repository
+ in their sources.list. This solves that issue.
+ * pidfile fixup and configuration parameter.
+ * Corrected Broker selection in debconf.
+ * Configuration file rewriting by debconf is now done in a 'nice' way.
+
+ -- Jeroen Massar <jeroen@sixxs.net> Sun, 6 Aug 2006 13:56:42 +0100
+
+aiccu (2006-07-25) stable; urgency=low
+ * DragonFlyBSD fix
+
+ -- Jeroen Massar <jeroen@sixxs.net> Tue, 25 Jul 2006 11:22:42 +0100
+
+aiccu (2006-07-23) stable; urgency=low
+ * The Nina'th release.
+ * Verified AYIYA support on Windows, OpenBSD, FreeBSD and Linux ia32/AMD64/armeb.
+ * Disabled TSP and L2TP (Teepee) support as they are not finished.
+ * No more IPv4 interface as it is not used anymore.
+ * On AIX we now compile with xlc_r.
+ * Retrieves Tunnel Brokers from _aiccu.<search path> and from _aiccu.sixxs.net.
+
+ -- Jeroen Massar <jeroen@sixxs.net> Sun, 23 Jul 2006 16:48:42 +0100
+
+aiccu (2006-07-13) stable; urgency=low
+ * Added no-configure and defaultroute options.
+ * AYIYA now forks so that AYIYA heartbeats work.
+ * Ctrl-C handling
+ * Protocol and server can be specified in configuration file
+ * AYIYA fixes: header alignment, Win32 TAP 8.1 support
+ * TAP listing using --listtaps (windows)
+ * Confuration can now be saved using a menu entry in the GUI (windows)
+ * TAP interface renaming when it's the only TAP and name not in the config (windows)
+ * Fedora fixes by Matt Domsch
+
+ -- Jeroen Massar <jeroen@sixxs.net> Thu, 13 Jul 2006 22:42:42 +0100
+
+aiccu (2006-03-10) stable; urgency=low
+ * Changed Debian start/stop priority as noted by Mario 'BitKoenig' Holbe.
+ They now match openvpn/pppd etc.
+
+ -- Jeroen Massar <jeroen@sixxs.net> Fri, 10 Mar 2006 21:24:42 +0100
+
+aiccu (2005-12-05) stable; urgency=low
+ * DragonFlyBSD (uses the FreeBSD4 interface) added as noted by Geert Hendrickx.
+
+ -- Jeroen Massar <jeroen@sixxs.net> Sun, 14 Aug 2005 14:10:42 +0200
+
+aiccu (2005-08-14) stable; urgency=low
+ * Mac OS X typo-fix (reported by Wim Biemolt)
+ * GNUTLS support. TIC will go over TLS avoiding cleartext
+ negotiations where possible.
+ * Heartbeat stop & start per signal (requested by Peter Bieringer)
+ * AYIYA Heartbeating.
+ * L2TPv2 Support.
+ * TSP Support.
+ * Gary Coady's <gary@lyranthe.org> Debian/Ubuntu update:
+ * Use dpkg-buildpackage to generate deb files
+ * Remove configuration checks from Debian init script
+ * Use common print functions in Debian init script
+ * Add 'tunnels' parameter to aiccu, which reports available tunnels
+ * Return non-zero exit code if unable to successfully authenticate
+ to POP
+ * Log to stderr instead of stdout
+ * Send signal 0 to existing aiccu binary instead of SIGHUP
+ * Add debconf support
+ Thanks to Gary for these very nice addons!
+ * Added OpenBSD PortInfo by Thomas Kaschwig
+ * Added Makefile changes to support FreeBSD6, noted by Meno Abels
+ * Added _NETBSD_SOURCE define as mentioned by Maarten Dammers
+ * Changed aiccu_kame to do configuration differently depending
+ if the interface is a proto-41 one or a tun device.
+ * Solaris and AIX support + Endian Fixes.
+ * 'version' option for unix_console.
+ * 64bit fixes + compilation check against a big number of platforms.
+ * Multiple Tunnelbrokers Support using TXT records from _aiccu.sixxs.net DNS.
+ * AYIYA Port number set to 5072 (IANA assigned)
+
+ -- Jeroen Massar <jeroen@sixxs.net> Sun, 14 Aug 2005 14:10:42 +0200
+
+aiccu (2005-01-31) stable; urgency=low
+ * Full integration of AYIYA, thus normal request procedures
+ * Version -gui/-console correction
+ * FreeBSD/Darwin route fixes (reported by Peter van Dijk)
+ * Windows: New POP logos added
+ * Linklocals for AYIYA tunnels making MLD and thus multicast
+ work (reported by Marco d'Itri)
+ * fflush() during non-syslog logging so that AICCU logs
+ correctly when run from daemontools (Peter van Dijk)
+
+ -- Jeroen Massar <jeroen@sixxs.net> Mon, 31 Jan 2005 20:29:42 +0100
+
+aiccu (2005-01-09) stable; urgency=low
+
+ * Mum's birthday release
+ * MacOS X support (Marc Kramis)
+ * DEBUG messages are not logged anymore
+ * OpenBSD 2.x/3.x support (Wouter van Hemel)
+ * Don't overwrite config when doing a 'make install' (Wouter van Hemel)
+ * Manual page (Antonio Ospite)
+ * Windows Configuration directory based on GetWindowsDirectory()
+ (reported by Thomas B. Ruecker)
+ * Windows NAT message fix (reported by Thomas B. Ruecker)
+
+ -- Jeroen Massar <jeroen@sixxs.net> Sun, 9 Jan 2005 09:00:42 +0100
+
+aiccu (2004-09-17-beta2b) stable; urgency=low
+
+ * OpenBSD fixes (AO)
+ * debian/rules debclean - now calls the correct clean (A0)
+ * Debian dependency on iproute (MdI)
+ * Gentoo Port (Thorsten Becker)
+
+ -- Jeroen Massar <jeroen@sixxs.net> Sun, 12 Sep 2004 10:24:42 +0100
+
+aiccu (2004-09-09-beta2a) stable; urgency=low
+
+ * Compile with pendantic, removing C++ "//" comments (AO)
+ * Debian fixes: file permissions, distclean (AO)
+ * rc.d addon (AO)
+ * Remove superfluous CVS dirs (AO)
+ * init script fix specifying 'start' (RS)
+ * RPM_OPT_FLAGS passing (RS)
+ * License fixes, making it more open (PvD & MdI)
+ * RPM package (RS)
+ * FreeBSD 4.x + 5.x port (MA)
+ * Many more fixes and cleanups (JM)
+ Who/what:
+ * AO = Antonio Ospite
+ * RS = Robert Schiele
+ * PvD = Peter van Dijk
+ * MdI = Marco d'Itri
+ * MA = Meno Abels
+ * JM = Jeroen Massar
+
+ -- Jeroen Massar <jeroen@sixxs.net> Thu, 09 Sep 2004 10:24:42 +0100
+
+aiccu (2004-08-30-beta2) stable; urgency=low
+
+ * Updated LICENSE which should now be 100% free(tm)
+ * Local-IP fix when using heartbeat tunnels
+
+ -- Jeroen Massar <jeroen@sixxs.net> Mon, 30 Aug 2004 21:26:42 +0100
+
+aiccu (2004-08-29-beta2) stable; urgency=low
+
+ * Brand spanking new AICCU
+ * Compiles both on Windows and UNIX
+ * Supports:
+ - TIC
+ - 6in4-static
+ - 6in4-heartbeat
+ - AYIYA
+
+ -- Jeroen Massar <jeroen@sixxs.net> Sun, 29 Aug 2004 20:55:42 +0100
--- /dev/null
+Source: aiccu
+Section: net
+Priority: optional
+Maintainer: SixXS Staff <info@sixxs.net>
+Build-Depends: debhelper (>> 3.0.0), libgnutls-dev
+Standards-Version: 3.7.2
+
+Package: aiccu
+Architecture: any
+Depends: ${shlibs:Depends}, iputils-ping, iputils-tracepath, iproute, debconf, lsb-base (>= 1.3-9ubuntu2), gawk | awk, libgnutls13
+Recommends: ntpdate | ntp
+Description: SixXS Automatic IPv6 Connectivity Client Utility
+ This client automatically gives one IPv6 connectivity
+ without having to manually configure interfaces etc.
+ One does need a SixXS account and at least a tunnel. These
+ can be freely & gratis requested from the SixXS website.
+ For more information about SixXS check http://www.sixxs.net
+
--- /dev/null
+usr/sbin
+etc
--- /dev/null
+doc/README
+doc/LICENSE
+doc/HOWTO
--- /dev/null
+# Automatically added by dh_installdebconf
+if [ "$1" = purge ] && [ -e /usr/share/debconf/confmodule ]; then
+ . /usr/share/debconf/confmodule
+ db_purge
+fi
+# End automatically added section
--- /dev/null
+#!/usr/bin/make -f
+# Sample debian/rules that uses debhelper.
+# GNU copyright 1997 to 1999 by Joey Hess.
+# Adjusted by Jeroen Massar <jeroen@sixxs.net> for aiccu
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+# This is the debhelper compatability version to use.
+export DH_COMPAT=4
+
+configure: configure-stamp
+configure-stamp:
+ dh_testdir
+
+ touch configure-stamp
+
+build: build-stamp
+
+build-stamp: configure-stamp
+ dh_testdir
+
+ # Add here commands to compile the package.
+ $(MAKE)
+
+ touch build-stamp
+
+clean:
+ dh_testdir
+ rm -f build-stamp configure-stamp
+
+ # Add here commands to clean up after the build process.
+ -$(MAKE) clean
+
+ dh_clean
+
+install: build
+ dh_testdir
+ dh_testroot
+ dh_clean -k
+ dh_installdirs
+
+ # Add here commands to install the package into debian/aiccu
+ $(MAKE) DESTDIR=`pwd`/debian/aiccu install
+
+# Build architecture-independent files here.
+binary-indep: build install
+# We have nothing to do by default.
+
+# Build architecture-dependent files here.
+binary-arch: build install
+ dh_testdir
+ dh_testroot
+ dh_installdebconf
+ dh_installdocs
+ dh_installexamples doc/aiccu.conf
+ dh_installmenu
+# dh_installlogrotate
+# dh_installemacsen
+# dh_installpam
+# dh_installmime
+ dh_installinit -- defaults 16 80
+ dh_installcron
+ dh_installman
+ dh_installinfo
+# dh_undocumented
+ dh_installchangelogs
+ dh_link
+ dh_strip
+ dh_compress
+ dh_fixperms
+# dh_makeshlibs
+ dh_installdeb
+# dh_perl
+ dh_shlibdeps
+ dh_gencontrol
+ dh_md5sums
+ dh_builddeb
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install configure
+
--- /dev/null
+misc:Depends=debconf (>= 0.5) | debconf-2.0
--- /dev/null
+Template: aiccu/username
+Type: string
+Default:
+Description: Username
+ To successfully connect, you must have a valid username. This is
+ the same as the handle you use to log into the website.
+
+Template: aiccu/password
+Type: password
+Description: Password
+ To successfully connect, you must have a valid password. This is
+ the same password you use to log into the website.
+
+Template: aiccu/brokername
+Type: select
+Choices: ${brokers}
+Description: Tunnel Broker
+ Select the Tunnel Broker you would like to use.
+
+Template: aiccu/tunnelname
+Type: select
+Choices: ${tunnels}
+Description: Tunnel Name
+ If you have more than one tunnel configured in your account, you must
+ specify which tunnel should be activated.
+
+Template: aiccu/badauth
+Type: boolean
+Description: Recheck authentication details?
+ You most likely have given bad authentication details. Try to login through
+ the website of the Tunnel Broker or contact them to ask about problems.
+
+Template: aiccu/nobrokers
+Type: note
+Description: No Tunnel Brokers available
+ No Tunnel Brokers could be retrieved from DNS (_aiccu + _aiccu.sixxs.net)
+ this most likely indicates a DNS configuration problem.
+
+Template: aiccu/notunnels
+Type: note
+Description: No tunnels available
+ You currently have no tunnels available. Please go to the SixXS website
+ at http://www.sixxs.net/ to request a tunnel for your account.
--- /dev/null
+The code for AICCU was written by Jeroen Massar <jeroen@sixxs.net>
+The copyright for this package is owned by SixXS Staff <info@sixxs.net>.
+(C) Copyright SixXS 2003-2007 All Rights Reserved
+
+Website: http://www.sixxs.net/tools/aiccu/
+
--- /dev/null
+Howto AICCU
+~~~~~~~~~~~
+
+For AYIYA support:
+ - Windows & Mac OS X: Install the driver mentioned in the FAQ.
+ at http://www.sixxs.net/faq/
+ - Linux, *BSD: make sure that the tun/tap device is available.
+ NetBSD v3 users - check the IPv6 tun/tap patch on
+ http://www.sixxs.net/archive/sixxs/aiccu/unix/
+
+- Windows GUI client:
+ - Just run and follow the dialogs.
+
+- Window GUI client as a service:
+ - Run the GUI client without options.
+ - Choose all the correct settings and check that
+ the tunnel works.
+ - Select the "Auto Enable" button on the info page.
+ - Select the "Save Configuration" option from the menu.
+ (See screenshots for its location)
+ - Quit the GUI.
+ - Install it as a service using "aiccu /i"
+ - Then use "net start aiccu" or start it from the
+ service control manager (services.msc)
+
+ One can uninstall the service with "aiccu /u" and
+ of course use the start/stop options to start/stop it.
+
+- Unix/Windows console client:
+ - Edit /etc/aiccu.conf and fill in the required values.
+ - Run aiccu test; aiccu start
+
+If there any problems:
+ - read the SixXS FAQ at http://www.sixxs.net/faq/
+ - check the SixXS Forum at http://www.sixxs.net/forum/
+
+If then it still fails, contact the SixXS staff as
+described per http://www.sixxs.net/contact/
+For problem reports please read and use the "Reporting Problems"
+section on that page to determine where the problem occurs.
--- /dev/null
+The SixXS License - http://www.sixxs.net/
+
+Copyright (C) SixXS Staff <info@sixxs.net>
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+3. Neither the name of SixXS nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior permission.
+
+THIS SOFTWARE IS PROVIDED BY SIXXS AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL SIXXS OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+
--- /dev/null
+SixXS AICCU: Automatic IPv6 Connectivity Configuration Utility
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+AICCU makes it very easy for anybody to get IPv6 connectivity
+everywhere they want. It uses the TIC (Tunnel Information & Control)
+protocol to request the information needed to setup a tunnel through
+which the connectivity is created.
+
+AICCU supports the following tunneling protocols:
+ - 6in4 static (RFC 2893)
+ - 6in4 heartbeat (RFC 2893 + draft-massar-v6ops-heartbeat)
+ - AYIYA (draft-massar-v6ops-ayiya)
+
+As AYIYA even works from behind NAT's, thus unless there is a very
+restrictive firewall in place, anybody should be able to get IPv6
+connectivity without problems and everywhere they want.
+
+WARNING: never run AICCU from DaemonTools or a similar automated
+'restart' tool/script. When AICCU does not start, it has a reason
+not to start which it gives on either the stdout or in the (sys)log
+file. The TIC server *will* automatically disable accounts which
+are detected to run in this mode.
+
+The main AICCU page, containing information, screenshots, updates
+and of course the software itself, unix source + binaries/packages
+and Windows binaries, can be downloaded from:
+
+ http://www.sixxs.net/tools/aiccu/
+
+Author
+~~~~~~
+The author of this code is:
+
+Jeroen Massar
+SixXS Staff <info@sixxs.net>
+http://www.sixxs.net/
+
+With patches accepted from other sources as can be found
+in the changelog.
+
+Contact
+~~~~~~~
+In the event that you find bugs or have questions please see:
+ http://www.sixxs.net/contact/
+which contains the contact details of the SixXS Staff.
+
+If you have problems using this tool you should of course first
+check the FAQ at http://www.sixxs.net/faq/ and check the Forum
+which can be found at http://www.sixxs.net/forum/
+
+If you are using this software please notify us of it. We are
+always interrested to hear in what various ways people are
+using our software.
+
+License
+~~~~~~~
+See the LICENSE file in the doc directory
+
+Copyright
+~~~~~~~~~
+Automatic IPv6 Connectivity Configuration Utility
+AICCU (C) Copyright 2003-2007 SixXS Staff <info@sixxs.net>
+
--- /dev/null
+.\" This manpage has been automatically generated by docbook2man
+.\" from a DocBook document. This tool can be found at:
+.\" <http://shell.ipoline.com/~elmert/comp/docbook2X/>
+.\" Please send any bug reports, improvements, comments, patches,
+.\" etc. to Steve Cheng <steve@ggi-project.org>.
+.TH "AICCU" "1" "18 April 2005" "" ""
+
+.SH NAME
+AICCU \- Automatic IPv6 Connectivity Configuration Utility
+.SH SYNOPSIS
+
+\fBaiccu \fR \fB<start|stop|tunnels|test|autotest|license>\fR [ \fB\fIconfig\fB\fR ]
+
+.SH "DESCRIPTION"
+.PP
+AICCU makes it very easy for anybody to get IPv6 connectivity
+everywhere they want. It uses the TIC (Tunnel Information & Control)
+protocol to request the information needed to setup a tunnel through
+which the connectivity is created.
+AICCU supports the following tunneling protocols:
+- 6in4 static (RFC 2893)
+- 6in4 heartbeat (RFC 2893 + draft-massar-v6ops-heartbeat)
+- tinc (http://www.tinc-vpn.org)
+- AYIYA (draft-massar-v6ops-ayiya)
+As AYIYA even works from behind NAT's, thus unless there is a very
+restrictive firewall in place, anybody should be able to get IPv6
+connectivity without problems and everywhere they want.
+.SH "OPTIONS"
+.TP
+\fBstart\fR
+Starts aiccu service.
+.TP
+\fBstop\fR
+Stops aiccu service.
+.TP
+\fBtunnels\fR
+Prints a list of currently available tunnels.
+.TP
+\fBtest\fR
+Builds the connection and runs a simple selftest allowing a user
+to report this back as it should show most obvious problems.
+.TP
+\fBautotest\fR
+Decription here
+.TP
+\fBlicense\fR
+Shows the license aiccu is released under.
+.TP
+\fB\fIconfig\fB\fR
+Read the configuration from \fIconfig\fR file.
+.SH "SEE ALSO"
+.PP
+The AICCU page <URL:http://www.sixxs.net/tools/aiccu/> at sixxs.
+.SH "AUTHOR"
+.PP
+AICCU was written by Jeroen Massar with contributions supplied a number of people as mentioned in the Changelog.
--- /dev/null
+# AICCU Configuration
+
+# Login information (defaults: none)
+#username <your nichandle/username>
+#password <your password>
+
+# Protocol and server to use for setting up the tunnel (defaults: none)
+#protocol <tic|tsp|l2tp>
+#server <server to use>
+
+# Interface names to use (default: aiccu)
+# ipv6_interface is the name of the interface that will be used as a tunnel interface.
+# On *BSD the ipv6_interface should be set to gifX (eg gif0) for proto-41 tunnels
+# or tunX (eg tun0) for AYIYA tunnels.
+ipv6_interface sixxs
+
+# The tunnel_id to use (default: none)
+# (only required when there are multiple tunnels in the list)
+#tunnel_id Txxxx
+
+# Be verbose? (default: false)
+verbose false
+
+# Daemonize? (default: true)
+# Set to false if you want to see any output
+# When true output goes to syslog
+#
+# WARNING: never run AICCU from DaemonTools or a similar automated
+# 'restart' tool/script. When AICCU does not start, it has a reason
+# not to start which it gives on either the stdout or in the (sys)log
+# file. The TIC server *will* automatically disable accounts which
+# are detected to run in this mode.
+#
+daemonize true
+
+# Automatic Login and Tunnel activation?
+automatic true
+
+# Require TLS?
+# When set to true, if TLS is not supported on the server
+# the TIC transaction will fail.
+# When set to false, it will try a starttls, when that is
+# not supported it will continue.
+# In any case if AICCU is build with TLS support it will
+# try to do a 'starttls' to the TIC server to see if that
+# is supported.
+requiretls false
+
+# PID File
+#pidfile /var/run/aiccu.pid
+
+# Add a default route (default: true)
+#defaultroute true
+
+# Script to run after setting up the interfaces (default: none)
+#setupscript /usr/local/etc/aiccu-subnets.sh
+
+# Make heartbeats (default true)
+# In general you don't want to turn this off
+# Of course only applies to AYIYA and heartbeat tunnels not to static ones
+#makebeats true
+
+# Don't configure anything (default: false)
+#noconfigure true
+
+# Behind NAT (default: false)
+# Notify the user that a NAT-kind network is detected
+#behindnat true
+
+# Local IPv4 Override (default: none)
+# Overrides the IPv4 parameter received from TIC
+# This allows one to configure a NAT into "DMZ" mode and then
+# forwarding the proto-41 packets to an internal host.
+#
+# This is only needed for static proto-41 tunnels!
+# AYIYA and heartbeat tunnels don't require this.
+#local_ipv4_override
+
--- /dev/null
+#! /bin/sh
+#
+# /etc/init.d/aiccu: start / stop AICCU
+#
+# Jeroen Massar <jeroen@sixxs.net>
+
+PATH=/sbin:/bin:/usr/sbin:/usr/bin
+NAME=aiccu
+DAEMON=/usr/sbin/${NAME}
+DESC="SixXS Automatic IPv6 Connectivity Client Utility (${NAME})"
+BACKGROUND=true
+
+# Options
+OPTIONS=""
+
+test -x $DAEMON || exit 0
+
+# Verify that the configuration file exists
+if [ ! -f /etc/aiccu.conf ]; then
+ echo "AICCU Configuration file /etc/aiccu.conf doesn't exist"
+ exit 0;
+fi
+
+# Verify that the configuration is correct
+if [ `grep -c "^username" /etc/aiccu.conf 2>/dev/null` -ne 1 ]; then
+ echo "AICCU is not configured, edit /etc/aiccu.conf first"
+ exit 0;
+fi
+
+# Verify that it is in daemonize mode, otherwise it won't ever return
+if [ `grep -c "^daemonize true" /etc/aiccu.conf 2>/dev/null` -ne 1 ]; then
+ echo "AICCU is not configured to daemonize on run"
+ exit 0;
+fi
+
+if [ -f /etc/default/${NAME} ]; then
+ . /etc/default/${NAME}
+fi
+
+if [ "$BACKGROUND" = "false" ]; then
+ exit 0;
+fi
+
+case "$1" in
+ start)
+ echo -n "Starting $DESC: "
+ start-stop-daemon --start --oknodo --quiet --exec $DAEMON -- start $OPTIONS
+ echo "$NAME."
+ ;;
+ stop)
+ echo -n "Stopping $DESC: "
+ start-stop-daemon --stop --oknodo --quiet --exec $DAEMON -- stop
+ echo "$NAME."
+ ;;
+ restart|reload|force-reload)
+ echo -n "Restarting $DESC: "
+ start-stop-daemon --stop --oknodo --quiet --exec $DAEMON -- stop
+ sleep 2
+ start-stop-daemon --start --oknodo --quiet --exec $DAEMON -- start $OPTIONS
+ echo "$NAME."
+ ;;
+ *)
+ echo "Usage: /etc/init.d/$NAME {start|stop|reload|force-reload|restart}" >&2
+ exit 1
+esac
+
+exit 0
+
--- /dev/null
+#! /bin/sh
+#
+# /etc/init.d/aiccu: start / stop AICCU
+#
+# Jeroen Massar <jeroen@sixxs.net>
+
+PATH=/sbin:/bin:/usr/sbin:/usr/bin
+NAME=aiccu
+DAEMON=/usr/sbin/${NAME}
+DESC="SixXS Automatic IPv6 Connectivity Client Utility (${NAME})"
+BACKGROUND=true
+
+# Options
+OPTIONS=""
+
+test -x $DAEMON || exit 0
+
+. /lib/lsb/init-functions
+
+if [ -f /etc/default/${NAME} ]; then
+ . /etc/default/${NAME}
+fi
+
+# Verify that the configuration file exists
+if [ ! -f /etc/aiccu.conf ]; then
+ echo "AICCU Configuration file /etc/aiccu.conf doesn't exist"
+ exit 0;
+fi
+
+# Verify that the configuration is correct
+if [ `grep -c "^username" /etc/aiccu.conf 2>/dev/null` -ne 1 ]; then
+ echo "AICCU is not configured, edit /etc/aiccu.conf first"
+ exit 0;
+fi
+
+# Verify that it is in daemonize mode, otherwise it won't ever return
+if [ `grep -c "^daemonize true" /etc/aiccu.conf 2>/dev/null` -ne 1 ]; then
+ echo "AICCU is not configured to daemonize on run"
+ exit 0;
+fi
+
+if [ "$BACKGROUND" = "false" ]; then
+ exit 0;
+fi
+
+case "$1" in
+ start)
+ log_begin_msg "Starting $DESC..."
+ start-stop-daemon --start --oknodo --quiet --exec $DAEMON -- start $OPTIONS
+ log_end_msg $?
+ ;;
+ stop)
+ log_begin_msg "Stopping $DESC..."
+ start-stop-daemon --stop --oknodo --quiet --exec $DAEMON -- stop
+ log_end_msg $?
+ ;;
+ restart|reload|force-reload)
+ log_begin_msg "Restarting $DESC..."
+ start-stop-daemon --stop --oknodo --quiet --exec $DAEMON -- stop
+ sleep 2
+ start-stop-daemon --start --oknodo --quiet --exec $DAEMON -- start $OPTIONS
+ log_end_msg $?
+ ;;
+ *)
+ echo "Usage: /etc/init.d/$NAME {start|stop|reload|force-reload|restart}" >&2
+ exit 1
+esac
+
+exit 0
--- /dev/null
+#!/bin/sh
+#
+# $FreeBSD$
+#
+
+# PROVIDE: sixxs-aiccu
+# REQUIRE: NETWORKING
+# KEYWORD: FreeBSD
+
+#
+# Add the following lines to /etc/rc.conf to enable sixxs-aiccu:
+#
+#sixxs_aiccu_enable="YES"
+#
+
+. %%RC_SUBR%%
+
+name=sixxs_aiccu
+rcvar=`set_rcvar`
+
+command="%%PREFIX%%/sbin/sixxs-aiccu start"
+command_args=%%PREFIX%%/etc/aiccu.conf
+stop_cmd="%%PREFIX%%/sbin/sixxs-aiccu stop"
+required_files=%%PREFIX%%/etc/aiccu.conf
+
+# set default
+sixxs_aiccu_enable=${sixxs_aiccu_enable:-"NO"}
+
+load_rc_config ${name}
+run_rc_command "$1"
+
--- /dev/null
+#!/sbin/runscript
+
+depend() {
+ need net
+ after ntp-client
+}
+
+checkconfig() {
+ # Verify that the configuration file exists
+ if [ ! -f /etc/aiccu.conf ]; then
+ eerror "AICCU Configuration file /etc/aiccu.conf doesn't exist"
+ return 1
+ fi
+
+ # Verify that the configuration is correct
+ if [ `grep -c "^username" /etc/aiccu.conf 2>/dev/null` -ne 1 ]; then
+ eerror "AICCU is not configured, edit /etc/aiccu.conf first"
+ return 1
+ fi
+}
+
+
+start() {
+ checkconfig || return 1
+ ebegin "Starting aiccu"
+ start-stop-daemon --start --oknodo --quiet --exec /usr/sbin/aiccu -- start
+ eend $?
+}
+
+
+stop() {
+ ebegin "Stopping aiccu"
+ start-stop-daemon --stop --oknodo --quiet --exec /usr/sbin/aiccu -- stop
+ eend $?
+}
+
--- /dev/null
+#!/bin/sh
+#
+# description: Starts and stops the AICCU daemon
+#
+# aiccu: Starts and stops the AICCU daemon
+# description: hearbeat daemon for IPv6-in-IPv4 (Proto-41, AYIYA, Heartbeat) tunnels
+# pidfile: /var/run/aiccu.pid
+# config: /etc/aiccu.conf
+# chkconfig: - 59 73
+# processname: aiccu
+
+# Source function library.
+if [ -f /etc/init.d/functions ] ; then
+ . /etc/init.d/functions
+elif [ -f /etc/rc.d/init.d/functions ] ; then
+ . /etc/rc.d/init.d/functions
+else
+ exit 0
+fi
+
+# Avoid using root's TMPDIR
+unset TMPDIR
+
+# Source networking configuration.
+. /etc/sysconfig/network
+
+# Default options
+OPTIONS=
+
+if [ -f /etc/sysconfig/aiccu ]; then
+ . /etc/sysconfig/aiccu
+fi
+
+# Check that networking is up.
+[ ${NETWORKING} = "no" ] && exit 0
+
+# Check that aiccu.conf exists.
+[ -f /etc/aiccu.conf ] || exit 0
+
+# Verify that the configuration is correct
+if [ `grep -c "^username" /etc/aiccu.conf 2>/dev/null` -ne 1 ]; then
+ echo "AICCU is not configured, edit /etc/aiccu.conf first"
+ exit 0;
+fi
+
+RETVAL=0
+
+KIND="AICCU (Automatic IPv6 Connectivity Configuration Utility)"
+
+start() {
+ echo -n $"Starting $KIND services: "
+ daemon aiccu start $OPTIONS
+ RETVAL=$?
+ echo
+ [ $RETVAL -eq 0 ] && touch /var/lock/subsys/aiccu || \
+ RETVAL=1
+ return $RETVAL
+}
+
+stop() {
+ echo -n $"Shutting down $KIND services: "
+ killproc aiccu
+ RETVAL=$?
+ echo
+ [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/aiccu
+ echo ""
+ return $RETVAL
+}
+
+restart() {
+ stop
+ start
+}
+
+rhstatus() {
+ status aiccu
+}
+
+
+case "$1" in
+ start)
+ start
+ ;;
+ stop)
+ stop
+ ;;
+ restart)
+ restart
+ ;;
+ reload)
+ restart
+ ;;
+ status)
+ rhstatus
+ ;;
+ condrestart)
+ [ -f /var/lock/subsys/aiccu ] && restart || :
+ ;;
+ *)
+ echo $"Usage: $0 {start|stop|restart|reload|status|condrestart}"
+ exit 1
+esac
+
+exit $?
+
--- /dev/null
+<!doctype refentry PUBLIC "-//OASIS//DTD DocBook V4.1//EN" [
+
+<!-- Process this file with docbook-to-man to generate an nroff manual
+ page: `docbook-to-man manpage.sgml > manpage.1'. You may view
+ the manual page with: `docbook-to-man manpage.sgml | nroff -man |
+ less'. A typical entry in a Makefile or Makefile.am is:
+
+manpage.1: manpage.sgml
+ docbook-to-man $< > $@
+ -->
+
+ <!-- Fill in your name for FIRSTNAME and SURNAME. -->
+ <!ENTITY dhfirstname "<firstname>Jeroen</firstname>">
+ <!ENTITY dhsurname "<surname>Massar</surname>">
+ <!-- Please adjust the date whenever revising the manpage. -->
+ <!ENTITY dhdate "<date>January 09, 2005</date>">
+ <!-- SECTION should be 1-8, maybe w/ subsection other parameters are
+ allowed: see man(7), man(1). -->
+ <!ENTITY dhsection "<manvolnum>1</manvolnum>">
+ <!ENTITY dhemail "<email>jeroen@sixxs.net</email>">
+ <!ENTITY dhusername "Jeroen Massar">
+ <!ENTITY dhucpackage "<refentrytitle>AICCU</refentrytitle>">
+ <!ENTITY dhpackage "AICCU">
+
+ <!ENTITY debian "<productname>Debian GNU/Linux</productname>">
+ <!ENTITY gnu "<acronym>GNU</acronym>">
+]>
+
+<refentry>
+ <refentryinfo>
+ <address>
+ &dhemail;
+ </address>
+ <author>
+ &dhfirstname;
+ &dhsurname;
+ </author>
+ <copyright>
+ <year>2005</year>
+ <holder>&dhusername;</holder>
+ </copyright>
+ &dhdate;
+ </refentryinfo>
+ <refmeta>
+ &dhucpackage;
+
+ &dhsection;
+ </refmeta>
+ <refnamediv>
+ <refname>&dhpackage;</refname>
+
+ <refpurpose>Automatic IPv6 Connectivity Configuration Utility</refpurpose>
+ </refnamediv>
+ <refsynopsisdiv>
+ <cmdsynopsis>
+ <command>aiccu </command>
+ <arg choice="req"><start|stop|tunnels|test|autotest|license></arg>
+ <arg choice="opt"><replaceable>config</replaceable></arg>
+
+ </cmdsynopsis>
+ </refsynopsisdiv>
+ <refsect1>
+ <title>DESCRIPTION</title>
+
+ <para>
+AICCU makes it very easy for anybody to get IPv6 connectivity
+everywhere they want. It uses the TIC (Tunnel Information & Control)
+protocol to request the information needed to setup a tunnel through
+which the connectivity is created.
+
+AICCU supports the following tunneling protocols:
+ - 6in4 static (RFC 2893)
+ - 6in4 heartbeat (RFC 2893 + draft-massar-v6ops-heartbeat)
+ - tinc (http://www.tinc-vpn.org)
+ - AYIYA (draft-massar-v6ops-ayiya)
+
+As AYIYA even works from behind NAT's, thus unless there is a very
+restrictive firewall in place, anybody should be able to get IPv6
+connectivity without problems and everywhere they want.
+</para>
+
+ </refsect1>
+ <refsect1>
+ <title>OPTIONS</title>
+
+ <variablelist>
+
+ <varlistentry>
+ <term>start</term>
+ <listitem>
+ <para>
+ Starts aiccu service.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>stop</term>
+ <listitem>
+ <para>
+ Stops aiccu service.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>tunnels</term>
+ <listitem>
+ <para>
+ Prints a list of currently available tunnels.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>test</term>
+ <listitem>
+ <para>
+ Builds the connection and runs a simple selftest allowing a user
+ to report this back as it should show most obvious problems.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>autotest</term>
+ <listitem>
+ <para>
+ Decription here
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>license</term>
+ <listitem>
+ <para>
+ Shows the license aiccu is released under.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term><replaceable>config</replaceable></term>
+ <listitem>
+ <para>
+ Read the configuration from <replaceable>config</replaceable> file.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1>
+ <title>SEE ALSO</title>
+
+ <para>The AICCU <ulink url="http://www.sixxs.net/tools/aiccu/">page</ulink> at sixxs.
+ </para>
+
+ </refsect1>
+ <refsect1>
+ <title>AUTHOR</title>
+
+ <para>AICCU was written by Jeroen Massar with contributions supplied a number of people as mentioned in the Changelog.</para>
+
+ </refsect1>
+</refentry>
+
+<!-- Keep this comment at the end of the file
+Local variables:
+mode: sgml
+sgml-omittag:t
+sgml-shorttag:t
+sgml-minimize-attributes:nil
+sgml-always-quote-attributes:t
+sgml-indent-step:2
+sgml-indent-data:t
+sgml-parent-document:nil
+sgml-default-dtd-file:nil
+sgml-exposed-tags:nil
+sgml-local-catalogs:nil
+sgml-local-ecat-files:nil
+End:
+-->
--- /dev/null
+aiccu (20070115) stable; urgency=medium
+ * Fixup in Debian init script (based on original patch by Bernhard Schmidt).
+ * Change in redirections so that errors don't show in debconf menu's etc.
+ * NetBSD fixes as there is not always a Tunnel Device that
+ supports IPv6 (thanks to Geert Hendrickx).
+ * Gentoo ebuild update, adding depends and require ntp-client.
+ * RPM spec update, add build-requirement.
+ * Check return values of system commands.
+ * Added a big warning about running AICCU from Daemontools and similar
+ programs which run AICCU in a loop, thus hammering the TIC server.
+ * Be a bit smarter in checking for support of IPv6.
+
+ -- Jeroen Massar <jeroen@sixxs.net> Mon, 15 Jan 2007 11:00:42 +0000
+
+aiccu (20070107) stable; urgency=high
+ * 2007 Edition of AICCU.
+ * License change to standard 3-clause BSD license.
+ With thanks to Theo de Raadt, Marco d'Itri and Philipp Kern for
+ their wise words and reasoning for coming to this decision.
+ * High urgency because of the above and it fixing large problems.
+ * Fixed Mac OS X / Darwin support on the MacBookPro of Pim van Pelt.
+ * Added MTU, from TIC, configuration on most platforms.
+ * Fixed up silly linux bug, adding LL address to tunnels but not to tun/taps.
+ * Removed Win32 Alpha Endianess (reported by Christian Weisgerber).
+ * Fixed up alignment error in parseline() (reported by Christian Weisgerber).
+ * OpenBSD 4.0 support (patch provided by Christian Weisgerber).
+ * OpenBSD AYIYA fixup (patch provided by Pim van Pelt).
+ * Fedora/RPM init script fixup (bash case's don't fall through)
+ reported and patch supplied by Matt Domsch.
+ * NetBSD AYIYA support (noted by Tobias Riediger)
+ Works on NetBSD 4.x, for NetBSD 3.0 one needs to patch tun/tap to
+ support IPv6. Patch is available from the archives.
+ * local_ipv4_override option so one can use AICCU behind a NAT that
+ has been configured correctly to do proto-41 forwarding. This is
+ usually called a DMZ setup.
+
+ -- Jeroen Massar <jeroen@sixxs.net> Sun, 07 Jan 2007 14:00:42 +0000
+
+aiccu (20060806) stable; urgency=low
+ * Changelog version format change as the 'official' (before there where
+ legal issues as they don't understand the word 'SHOULD' which is cleary
+ defined in the IETF and now somebody simply uploaded it anyway it without
+ even asking or notifying us about it) debian packages which are broken,
+ old and unsupported would seem newer and thus this new version would not
+ get updated to even when folks would have the official AICCU repository
+ in their sources.list. This solves that issue.
+ * pidfile fixup and configuration parameter.
+ * Corrected Broker selection in debconf.
+ * Configuration file rewriting by debconf is now done in a 'nice' way.
+
+ -- Jeroen Massar <jeroen@sixxs.net> Sun, 6 Aug 2006 13:56:42 +0100
+
+aiccu (2006-07-25) stable; urgency=low
+ * DragonFlyBSD fix
+
+ -- Jeroen Massar <jeroen@sixxs.net> Tue, 25 Jul 2006 11:22:42 +0100
+
+aiccu (2006-07-23) stable; urgency=low
+ * The Nina'th release.
+ * Verified AYIYA support on Windows, OpenBSD, FreeBSD and Linux ia32/AMD64/armeb.
+ * Disabled TSP and L2TP (Teepee) support as they are not finished.
+ * No more IPv4 interface as it is not used anymore.
+ * On AIX we now compile with xlc_r.
+ * Retrieves Tunnel Brokers from _aiccu.<search path> and from _aiccu.sixxs.net.
+
+ -- Jeroen Massar <jeroen@sixxs.net> Sun, 23 Jul 2006 16:48:42 +0100
+
+aiccu (2006-07-13) stable; urgency=low
+ * Added no-configure and defaultroute options.
+ * AYIYA now forks so that AYIYA heartbeats work.
+ * Ctrl-C handling
+ * Protocol and server can be specified in configuration file
+ * AYIYA fixes: header alignment, Win32 TAP 8.1 support
+ * TAP listing using --listtaps (windows)
+ * Confuration can now be saved using a menu entry in the GUI (windows)
+ * TAP interface renaming when it's the only TAP and name not in the config (windows)
+ * Fedora fixes by Matt Domsch
+
+ -- Jeroen Massar <jeroen@sixxs.net> Thu, 13 Jul 2006 22:42:42 +0100
+
+aiccu (2006-03-10) stable; urgency=low
+ * Changed Debian start/stop priority as noted by Mario 'BitKoenig' Holbe.
+ They now match openvpn/pppd etc.
+
+ -- Jeroen Massar <jeroen@sixxs.net> Fri, 10 Mar 2006 21:24:42 +0100
+
+aiccu (2005-12-05) stable; urgency=low
+ * DragonFlyBSD (uses the FreeBSD4 interface) added as noted by Geert Hendrickx.
+
+ -- Jeroen Massar <jeroen@sixxs.net> Sun, 14 Aug 2005 14:10:42 +0200
+
+aiccu (2005-08-14) stable; urgency=low
+ * Mac OS X typo-fix (reported by Wim Biemolt)
+ * GNUTLS support. TIC will go over TLS avoiding cleartext
+ negotiations where possible.
+ * Heartbeat stop & start per signal (requested by Peter Bieringer)
+ * AYIYA Heartbeating.
+ * L2TPv2 Support.
+ * TSP Support.
+ * Gary Coady's <gary@lyranthe.org> Debian/Ubuntu update:
+ * Use dpkg-buildpackage to generate deb files
+ * Remove configuration checks from Debian init script
+ * Use common print functions in Debian init script
+ * Add 'tunnels' parameter to aiccu, which reports available tunnels
+ * Return non-zero exit code if unable to successfully authenticate
+ to POP
+ * Log to stderr instead of stdout
+ * Send signal 0 to existing aiccu binary instead of SIGHUP
+ * Add debconf support
+ Thanks to Gary for these very nice addons!
+ * Added OpenBSD PortInfo by Thomas Kaschwig
+ * Added Makefile changes to support FreeBSD6, noted by Meno Abels
+ * Added _NETBSD_SOURCE define as mentioned by Maarten Dammers
+ * Changed aiccu_kame to do configuration differently depending
+ if the interface is a proto-41 one or a tun device.
+ * Solaris and AIX support + Endian Fixes.
+ * 'version' option for unix_console.
+ * 64bit fixes + compilation check against a big number of platforms.
+ * Multiple Tunnelbrokers Support using TXT records from _aiccu.sixxs.net DNS.
+ * AYIYA Port number set to 5072 (IANA assigned)
+
+ -- Jeroen Massar <jeroen@sixxs.net> Sun, 14 Aug 2005 14:10:42 +0200
+
+aiccu (2005-01-31) stable; urgency=low
+ * Full integration of AYIYA, thus normal request procedures
+ * Version -gui/-console correction
+ * FreeBSD/Darwin route fixes (reported by Peter van Dijk)
+ * Windows: New POP logos added
+ * Linklocals for AYIYA tunnels making MLD and thus multicast
+ work (reported by Marco d'Itri)
+ * fflush() during non-syslog logging so that AICCU logs
+ correctly when run from daemontools (Peter van Dijk)
+
+ -- Jeroen Massar <jeroen@sixxs.net> Mon, 31 Jan 2005 20:29:42 +0100
+
+aiccu (2005-01-09) stable; urgency=low
+
+ * Mum's birthday release
+ * MacOS X support (Marc Kramis)
+ * DEBUG messages are not logged anymore
+ * OpenBSD 2.x/3.x support (Wouter van Hemel)
+ * Don't overwrite config when doing a 'make install' (Wouter van Hemel)
+ * Manual page (Antonio Ospite)
+ * Windows Configuration directory based on GetWindowsDirectory()
+ (reported by Thomas B. Ruecker)
+ * Windows NAT message fix (reported by Thomas B. Ruecker)
+
+ -- Jeroen Massar <jeroen@sixxs.net> Sun, 9 Jan 2005 09:00:42 +0100
+
+aiccu (2004-09-17-beta2b) stable; urgency=low
+
+ * OpenBSD fixes (AO)
+ * debian/rules debclean - now calls the correct clean (A0)
+ * Debian dependency on iproute (MdI)
+ * Gentoo Port (Thorsten Becker)
+
+ -- Jeroen Massar <jeroen@sixxs.net> Sun, 12 Sep 2004 10:24:42 +0100
+
+aiccu (2004-09-09-beta2a) stable; urgency=low
+
+ * Compile with pendantic, removing C++ "//" comments (AO)
+ * Debian fixes: file permissions, distclean (AO)
+ * rc.d addon (AO)
+ * Remove superfluous CVS dirs (AO)
+ * init script fix specifying 'start' (RS)
+ * RPM_OPT_FLAGS passing (RS)
+ * License fixes, making it more open (PvD & MdI)
+ * RPM package (RS)
+ * FreeBSD 4.x + 5.x port (MA)
+ * Many more fixes and cleanups (JM)
+ Who/what:
+ * AO = Antonio Ospite
+ * RS = Robert Schiele
+ * PvD = Peter van Dijk
+ * MdI = Marco d'Itri
+ * MA = Meno Abels
+ * JM = Jeroen Massar
+
+ -- Jeroen Massar <jeroen@sixxs.net> Thu, 09 Sep 2004 10:24:42 +0100
+
+aiccu (2004-08-30-beta2) stable; urgency=low
+
+ * Updated LICENSE which should now be 100% free(tm)
+ * Local-IP fix when using heartbeat tunnels
+
+ -- Jeroen Massar <jeroen@sixxs.net> Mon, 30 Aug 2004 21:26:42 +0100
+
+aiccu (2004-08-29-beta2) stable; urgency=low
+
+ * Brand spanking new AICCU
+ * Compiles both on Windows and UNIX
+ * Supports:
+ - TIC
+ - 6in4-static
+ - 6in4-heartbeat
+ - AYIYA
+
+ -- Jeroen Massar <jeroen@sixxs.net> Sun, 29 Aug 2004 20:55:42 +0100
--- /dev/null
+{
+ '' => ''
+}
--- /dev/null
+echo "The following variables are available to this script as passed by AICCU:"\r
+echo "1: %1%"\r
+echo "2: %2%"\r
+echo "3: %3%"\r
--- /dev/null
+# New ports collection makefile for: sixxs-aiccu
+# Date created: 2004-09-09
+# Initial FreeBSD port by: Meno Abels <meno.abels@adviser.com>
+# Comments for this port please to the SixXS staff <info@sixxs.net>
+#
+## $FreeBSD: /repoman/r/pcvs/ports/net/sixxs-aiccu/Makefile,v 1.1 2005/03/14 17:47:07 vs Exp $
+#
+
+#PORTNAME= sixxs-aiccu
+PORTVERSION= 20070107
+CATEGORIES= net ipv6
+MASTER_SITES= http://www.sixxs.net/archive/sixxs/aiccu/unix/
+DISTNAME= aiccu_20070107
+
+# Maintainer of the FreeBSD port, but always copy: info@sixxs.net
+MAINTAINER= meno.abels@adviser.com
+COMMENT= IPv6 Tunnel Broker client capable of configuring using TIC, static, AYIYA and heartbeat tunnels
+
+USE_RC_SUBR= sixxs-aiccu
+USE_GMAKE= yes
+CFLAGS+= ${PTHREAD_CFLAGS}
+LDFLAGS+= ${PTHREAD_LIBS}
+MAKE_ARGS= CC="${CC}"
+MAKE_ENV= CFLAGS="${CFLAGS}" LDFLAGS="${LDFLAGS}"
+WRKSRC= ${WRKDIR}/aiccu
+BUILD_WRKSRC= ${WRKDIR}/aiccu/unix-console
+
+PORTDOCS= README
+
+# FreeBSD doesn't use named interfaces, thus default to gif0
+pre-build:
+ @${SED} \
+ -e 's:ipv6_interface sixxs:ipv6_interface gif0:' \
+ ${WRKSRC}/doc/aiccu.conf > ${WRKDIR}/aiccu.conf
+
+do-install:
+ @${MKDIR} ${DOCSDIR} ${EXAMPLESDIR}
+ ${INSTALL_PROGRAM} ${WRKSRC}/unix-console/aiccu ${PREFIX}/sbin/sixxs-aiccu
+ ${INSTALL_DATA} ${WRKSRC}/doc/README ${DOCSDIR}
+ ${INSTALL_DATA} ${WRKSRC}/doc/LICENSE ${DOCSDIR}
+ ${INSTALL_DATA} ${WRKSRC}/doc/aiccu.conf ${EXAMPLESDIR}
+ ${INSTALL_DATA} ${WRKDIR}/aiccu.conf ${PREFIX}/etc/aiccu.conf.sample
+
+.include <bsd.port.mk>
+
--- /dev/null
+#!/bin/sh
+#
+# $FreeBSD: ports/net/sixxs-aiccu/files/sixxs-aiccu.sh,v 1.3 2006/02/20 20:47:30 dougb Exp $
+#
+
+# PROVIDE: sixxs-aiccu
+# REQUIRE: NETWORKING
+
+#
+# Add the following lines to /etc/rc.conf to enable sixxs-aiccu:
+#
+#sixxs_aiccu_enable="YES"
+#
+
+. %%RC_SUBR%%
+
+name=sixxs_aiccu
+rcvar=`set_rcvar`
+
+command="%%PREFIX%%/sbin/sixxs-aiccu"
+command_args=%%PREFIX%%/etc/aiccu.conf
+start_cmd="%%PREFIX%%/sbin/sixxs-aiccu start $command_args"
+stop_cmd="%%PREFIX%%/sbin/sixxs-aiccu stop $command_args"
+required_files=%%PREFIX%%/etc/aiccu.conf
+
+# set default
+sixxs_aiccu_enable=${sixxs_aiccu_enable:-"NO"}
+
+load_rc_config ${name}
+run_rc_command "$1"
+
--- /dev/null
+SixXS AICCU: Automatic IPv6 Connectivity Configuration Utility
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+AICCU makes it very easy for anybody to get IPv6 connectivity
+everywhere they want. It uses the TIC (Tunnel Information & Control)
+protocol to request the information needed to setup a tunnel through
+which the connectivity is created.
+
+AICCU supports the following tunneling protocols:
+ - 6in4 static (RFC 2893)
+ - 6in4 heartbeat (RFC 2893 + draft-massar-v6ops-heartbeat)
+ - tinc (http://www.tinc-vpn.org)
+ - AYIYA (draft-massar-v6ops-ayiya)
+
+As AYIYA even works from behind NAT's, thus unless there is a very
+restrictive firewall in place, anybody should be able to get IPv6
+connectivity without problems and everywhere they want.
+
+The main AICCU page, containing information, screenshots, updates
+and of course the software itself, unix source + binaries/packages
+and Windows binaries, can be downloaded from:
+
+WWW: http://www.sixxs.net/tools/aiccu/
--- /dev/null
+@comment $FreeBSD$
+etc/aiccu.conf.sample
+sbin/sixxs-aiccu
+%%DOCSDIR%%/README
+%%EXAMPLESDIR%%/aiccu.conf
+@dirrm %%EXAMPLESDIR%%
--- /dev/null
+inherit eutils
+
+DESCRIPTION="AICCU, a cient to configure an IPv6 tunnel to SixXS and other Tunnel Brokers"
+HOMEPAGE="http://www.sixxs.net/"
+SRC_URI="http://www.sixxs.net/archive/sixxs/aiccu/unix/aiccu_current.tar.gz"
+
+LICENSE="BSD"
+SLOT="0"
+KEYWORDS="x86 amd64 ppc arm hppa"
+IUSE=""
+DEPEND="net-libs/gnutls sys-apps/iproute2"
+S=${WORKDIR}/aiccu
+
+src_compile() {
+ cd ${S}
+ export RPM_OPT_FLAGS=${CFLAGS}
+ make || die "Build Failed"
+}
+
+src_install() {
+ dosbin unix-console/aiccu
+ insopts -m 600
+ insinto /etc
+ doins aiccu.conf
+ dodoc doc/{HOWTO,LICENSE,README,changelog}
+ exeinto /etc/init.d
+ newexe doc/aiccu.init.gentoo aiccu
+}
+
+pkg_postinst() {
+ einfo "The aiccu ebuild installs an init script named 'aiccu'"
+ einfo "To add support for a SixXS connection at startup, do"
+ einfo "edit your /etc/aiccu.conf and do"
+ einfo "# rc-update add aiccu default"
+}
+
--- /dev/null
+AICCU (Automatic IPv6 Connectivity Client Utility) makes it easy for users to
+get IPv6 connectivity via SixXs. After having requested an account, tunnel and
+optionally a subnet, AICCU can be used to automatically configure the tunnel.
+AICCU supports TIC (Tunnel Information & Control protocol), which it uses for
+retrieving the tunnel configuration information, AYIYA, which allows tunnels to
+be created even behind firewalls and NATs.
+
--- /dev/null
+# $NetBSD: Makefile,v 1.7 2006/11/10 20:58:09 rillig Exp $
+
+DISTNAME= aiccu_2006.07.25
+PKGNAME= ${DISTNAME:S/_/-/:S/.//g}
+CATEGORIES= net
+MASTER_SITES= http://www.sixxs.net/archive/sixxs/aiccu/unix/
+
+MAINTAINER= ghen@NetBSD.org
+HOMEPAGE= http://www.sixxs.net/tools/aiccu/
+COMMENT= Automatic IPv6 Connectivity Client Utility
+
+USE_TOOLS+= gmake
+CHECK_PORTABILITY_SKIP+= debian/*
+
+SUBST_CLASSES+= sysconfdir
+SUBST_STAGE.sysconfdir= post-patch
+SUBST_FILES.sysconfdir= common/aiccu.h
+SUBST_SED.sysconfdir= -e 's,/etc/aiccu.conf,${PKG_SYSCONFDIR}/aiccu.conf,'
+
+EXAMPLESDIR= ${PREFIX}/share/examples/aiccu
+DOCDIR= ${PREFIX}/share/doc/aiccu
+CONF_FILES= ${EXAMPLESDIR}/aiccu.conf ${PKG_SYSCONFDIR}/aiccu.conf
+CONF_FILES_MODE= 0600
+
+RCD_SCRIPTS= aiccu
+
+.include "options.mk"
+
+# the distfile untars as ${WRKDIR}/aiccu/ but this would conflict with the
+# rc.d script that gets copied to the same name ${WRKDIR}/${RCD_SCRIPTS}
+post-extract:
+ ${MV} ${WRKDIR}/aiccu ${WRKDIR}/${DISTNAME}
+
+do-install:
+ ${INSTALL_PROGRAM} ${WRKSRC}/unix-console/aiccu ${PREFIX}/sbin/
+ ${INSTALL_MAN} ${WRKSRC}/doc/aiccu.1 ${PREFIX}/${PKGMANDIR}/man1/
+ ${INSTALL_DATA_DIR} ${EXAMPLESDIR}
+ ${INSTALL_DATA} ${WRKSRC}/doc/aiccu.conf ${EXAMPLESDIR}/
+ ${INSTALL_DATA_DIR} ${DOCDIR}
+ ${INSTALL_DATA} ${WRKSRC}/doc/README ${DOCDIR}
+ ${INSTALL_DATA} ${WRKSRC}/doc/LICENSE ${DOCDIR}
+ ${INSTALL_DATA} ${WRKSRC}/doc/HOWTO ${DOCDIR}
+
+.include "../../mk/pthread.buildlink3.mk"
+.include "../../mk/bsd.pkg.mk"
+
--- /dev/null
+@comment $NetBSD: PLIST,v 1.1.1.1 2005/12/29 14:53:52 ghen Exp $
+man/man1/aiccu.1
+sbin/aiccu
+share/doc/aiccu/HOWTO
+share/doc/aiccu/LICENSE
+share/doc/aiccu/README
+share/examples/aiccu/aiccu.conf
+share/examples/rc.d/aiccu
+@dirrm share/examples/aiccu
+@dirrm share/doc/aiccu
+
--- /dev/null
+# $NetBSD: options.mk,v 1.2 2007/01/03 15:25:12 tv Exp $
+
+PKG_OPTIONS_VAR= PKG_OPTIONS.aiccu
+PKG_SUPPORTED_OPTIONS= gnutls
+PKG_OPTIONS_REQUIRED_GROUPS= inet6 # require inet6 capability
+PKG_OPTIONS_GROUP.inet6= inet6
+
+.include "../../mk/bsd.options.mk"
+
+.if !empty(PKG_OPTIONS:Mgnutls)
+.include "../../security/gnutls/buildlink3.mk"
+CFLAGS+= -D AICCU_GNUTLS
+LDFLAGS+= -lgnutls
+.endif
+
--- /dev/null
+# $OpenBSD$
+
+COMMENT= "Automatic IPv6 Connectivity Configuration Utility (AICCU)"
+
+PKGNAME= sixxs-aiccu-2007-01-07
+DISTNAME= aiccu_20070107
+CATEGORIES= net
+
+HOMEPAGE= http://www.sixxs.net/tools/aiccu/
+MASTER_SITES= http://www.sixxs.net/archive/sixxs/aiccu/unix/
+
+MAINTAINER= Thomas Kaschwig <openbsd@kaschwig.net>
+
+SED= /usr/bin/sed
+
+# GPL
+PERMIT_PACKAGE_CDROM= Yes
+PERMIT_PACKAGE_FTP= Yes
+PERMIT_DISTFILES_CDROM= Yes
+PERMIT_DISTFILES_FTP= Yes
+WANTLIB= c pthread
+
+EXTRACT_SUFX= .tar.gz
+WRKDIST= ${WRKDIR}/aiccu
+
+NO_REGRESS= Yes
+
+USE_GMAKE= Yes
+DOCDIR= ${PREFIX}/share/doc/sixxs-aiccu
+EXAMPLEDIR= ${PREFIX}/share/examples/sixxs-aiccu
+
+pre-build:
+ ${SED} -e 's:ipv6_interface sixxs:ipv6_interface gif0:' \
+ ${WRKSRC}/doc/aiccu.conf > ${WRKSRC}/aiccu.conf
+
+do-install:
+ ${INSTALL_DATA_DIR} ${DOCDIR} ${EXAMPLEDIR}
+ ${INSTALL_PROGRAM} ${WRKSRC}/unix-console/aiccu ${PREFIX}/sbin/sixxs-aiccu
+ ${INSTALL_DATA} ${WRKSRC}/aiccu.conf ${SYSCONFDIR}/aiccu.conf.sample
+ ${INSTALL_DATA} ${WRKSRC}/aiccu.conf ${EXAMPLEDIR}
+ ${INSTALL_DATA} ${WRKSRC}/doc/README ${DOCDIR}
+ ${INSTALL_DATA} ${WRKSRC}/doc/LICENSE ${DOCDIR}
+ ${INSTALL_DATA} ${WRKSRC}/doc/HOWTO ${DOCDIR}
+
+.include <bsd.port.mk>
--- /dev/null
+Notes on the OpenBSD port of AICCU.
+You should regenerate the checksums in the distinfo file in this directory.
+
+Something like this should do the trick:
+{
+ md5 aiccu_2007.01.07.tar.gz
+ sha1 aiccu_2007.01.07.tar.gz
+ rmd160 aiccu_2007.01.07.tar.gz
+ echo "SIZE (aiccu_2007.01.07.tar.gz) = `ls -l aiccu_2007.01.07.tar.gz | awk '{ print $5}'`
+} > distinfo
--- /dev/null
+MD5 (aiccu_2005.01.31.tar.gz) = 7c3da5feab3d59fb5a99a45203e0ca56
+SHA1 (aiccu_2005.01.31.tar.gz) = 2d3e9e1844e7e2b2ae144b00974a9d1022b45396
+RMD160 (aiccu_2005.01.31.tar.gz) = 48f9508bb62984acc8cde8419765c5003a7200f4
+SIZE (aiccu_2005.01.31.tar.gz) = 45672
--- /dev/null
+../../freebsd/pkg-descr
\ No newline at end of file
--- /dev/null
+Copy ${PREFIX}/share/examples/sixxs-aiccu/aiccu.conf to
+${SYSCONFDIR} and insert your account data.
+
+You can start the daemon with:
+/usr/local/sbin/sixxs-aiccu start ${SYSCONFDIR}/aiccu.conf
+
+Add the following to the /etc/rc.local script to start the daemon on boot:
+
+if [ -x ${PREFIX}/sbin/sixxs-aiccu -a -f ${SYSCONFDIR}/aiccu.conf ]; then
+ echo -n ' sixxs-aiccu'
+ ${PREFIX}/sbin/sixxs-aiccu start ${SYSCONFDIR}/aiccu.conf
+fi
--- /dev/null
+@comment $OpenBSD$
+sbin/sixxs-aiccu
+share/doc/sixxs-aiccu/
+share/doc/sixxs-aiccu/HOWTO
+share/doc/sixxs-aiccu/LICENSE
+share/doc/sixxs-aiccu/README
+share/examples/sixxs-aiccu/
+share/examples/sixxs-aiccu/aiccu.conf
--- /dev/null
+############################################################
+# AICCU - Automatic IPv6 Connectivity Client Utility
+# by Jeroen Massar <jeroen@sixxs.net>
+# (c) Copyright 2003-2005 SixXS
+############################################################
+# AICCU RPM Spec File
+############################################################
+
+Summary: AICCU - SixXS Automatic IPv6 Connectivity Client Utility
+Name: aiccu
+Version: 2007.01.15
+Release: 1%{?dist}
+License: BSD
+Group: System Environment/Daemons
+URL: http://www.sixxs.net/tools/aiccu/
+BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
+Source: http://www.sixxs.net/archive/sixxs/aiccu/unix/aiccu_%{version}.tar.gz
+BuildRequires: gnutls-devel
+Requires: iproute
+Requires(post): chkconfig
+Requires(preun): chkconfig, initscripts
+Requires(postun): initscripts
+
+%description
+This client automatically gives one IPv6 connectivity
+without having to manually configure interfaces etc.
+One does need a SixXS account and at least a tunnel. These
+can be freely & gratis requested from the SixXS website.
+For more information about SixXS check http://www.sixxs.net
+
+%prep
+%setup -q -n %{name}
+# fix executable permissions on non-executable content
+# so debuginfo can pick them up properly
+find . -type f -not -name rules -and -not -name *init* -exec chmod a-x \{\} \;
+
+%build
+make %{?_smp_mflags} RPM_OPT_FLAGS="$RPM_OPT_FLAGS"
+
+%install
+rm -rf $RPM_BUILD_ROOT
+mkdir -p $RPM_BUILD_ROOT
+make install DESTDIR=$RPM_BUILD_ROOT
+
+%post
+if [ "$1" = "1" ]; then
+ /sbin/chkconfig --add aiccu
+fi
+
+%preun
+if [ "$1" = "0" ]; then
+ /sbin/service aiccu stop >/dev/null 2>&1
+ /sbin/chkconfig --del aiccu
+fi
+
+%postun
+/sbin/service aiccu condrestart > /dev/null 2>&1 || :
+
+%clean
+make clean
+[ "$RPM_BUILD_ROOT" != "/" ] && rm -rf $RPM_BUILD_ROOT
+
+%files
+%defattr(-,root,root)
+%doc doc/README doc/LICENSE
+%{_sbindir}/aiccu
+# aiccu.conf contains the users's SixXS password, so don't
+# make it readable by non-root
+%attr(600, root,root) %config(noreplace) %{_sysconfdir}/aiccu.conf
+%{_sysconfdir}/init.d/aiccu
+
+
+%changelog
+* Wed Jun 28 2006 Matt Domsch <matt@domsch.com> 2005.01.31-4
+- export CFLAGS properly, fix permissions on files for debuginfo
+
+* Wed Jun 28 2006 Matt Domsch <matt@domsch.com> 2005.01.31-3
+- cleanups per Fedora Extras review
+
+* Sat Apr 22 2006 Matt Domsch <matt@domsch.com> 2005.01.31-2
+- match Fedora Extras spec guidelines
+- add postun condrestart
+- add reload initscript arg to satisfy rpmlint
+
+* Sun Aug 29 2004 Jeroen Massar <jeroen@sixxs.net> 2004.08.29
+- Beta2 with TIC, 6in4, 6in4-heartbeat and AYIYA support
+
--- /dev/null
+# /**********************************************************
+# SixXS - Automatic IPv6 Connectivity Configuration Utility
+# ***********************************************************
+# Copyright 2003-2005 SixXS - http://www.sixxs.net
+# ***********************************************************
+# unix-client/Makefile - Makefile for the UNIX client
+# ***********************************************************
+# $Author: jeroen $
+# $Id: Makefile,v 1.32 2007-01-15 11:04:27 jeroen Exp $
+# $Date: 2007-01-15 11:04:27 $
+# **********************************************************/
+
+SRCS = main.c ../common/tun.c ../common/aiccu.c ../common/hash_md5.c ../common/hash_sha1.c ../common/common.c ../common/heartbeat.c ../common/tic.c ../common/ayiya.c ../common/aiccu_test.c ../common/resolver.c
+INCS = ../common/tun.h ../common/aiccu.h ../common/hash_md5.h ../common/hash_sha1.h ../common/common.h ../common/heartbeat.h ../common/tic.h ../common/ayiya.h ../common/resolver.h
+OBJS = main.o ../common/tun.o ../common/aiccu.o ../common/hash_md5.o ../common/hash_sha1.o ../common/common.o ../common/heartbeat.o ../common/tic.o ../common/ayiya.o ../common/aiccu_test.o ../common/resolver.o
+
+# New features not fully implemented and thus disabled for now
+#CFLAGS += -D NEWSTUFF_TSP -D NEWSTUFF_TEEPEE
+#SRCS += ../common/tsp.c ../common/teepee.c
+#OBJS += ../common/tsp.o ../common/teepee.o
+#INCS += ../common/tsp.h ../common/teepee.h
+
+# Our very *bliep* set of options to make sure that these things can't cause any issues
+CWARNS += -W -Wall -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls -Wnested-externs -Winline -Wbad-function-cast -fshort-enums -fstrict-aliasing -fno-common -Wpadded -pedantic -D_REENTRANT
+# CWARNS += -Wpacked
+
+#CFLAGS += $(CWARNS) -D_GNU_SOURCE -D_DEBUG -g3 -O0
+CFLAGS += $(CWARNS) -D_GNU_SOURCE
+CC = @gcc
+RM = rm
+
+# Add -O3 when nothing is specified yet
+ifeq ($(shell echo $(CFLAGS) | grep -c "\-O"),0)
+CFLAGS += -O3
+endif
+
+# This is a console client
+CFLAGS += -D AICCU_CONSOLE
+
+# GnuTLS Support ?
+# Used by TIC to secure that communication
+# Currently defaultly builds only on Linux, but other platforms might easily also support it
+ifeq ($(shell uname | grep -c "Linux"),1)
+CFLAGS += -D AICCU_GNUTLS
+LDFLAGS += -lgnutls
+endif
+
+# Linux
+ifeq ($(shell uname | grep -c "Linux"),1)
+CFLAGS += -D_LINUX -D HAS_IFHEAD -D AICCU_TYPE="\"linux\""
+SRCS += ../common/aiccu_linux.c
+OBJS += ../common/aiccu_linux.o
+LDFLAGS += -lpthread -lresolv
+endif
+
+# FreeBSD
+ifeq ($(shell uname | grep -c "FreeBSD"),1)
+CFLAGS += -D_FREEBSD
+
+# FreeBSD 4.x
+ifeq ($(shell uname -r | cut -c 1),4)
+CFLAGS += -D AICCU_TYPE="\"freebsd4\""
+SRCS += ../common/aiccu_freebsd4.c
+OBJS += ../common/aiccu_freebsd4.o
+else
+# FreeBSD 5.x/6.x/7.x
+CFLAGS += -D NEED_IFHEAD -D AICCU_TYPE="\"kame\""
+SRCS += ../common/aiccu_kame.c
+OBJS += ../common/aiccu_kame.o
+endif
+endif
+
+# DragonFlyBSD
+ifeq ($(shell uname | grep -c "DragonFly"),1)
+CFLAGS += -D_DFBSD -D NEED_IFHEAD -D AICCU_TYPE="\"dragonfly\""
+SRCS += ../common/aiccu_freebsd4.c
+OBJS += ../common/aiccu_freebsd4.o
+CFLAGS += -pthread
+endif
+
+# NetBSD
+ifeq ($(shell uname | grep -c "NetBSD"),1)
+CFLAGS += -D_NETBSD -D AICCU_TYPE="\"kame\""
+
+# Check if net/if_tun.h has TUNSIFHEAD and enable support for it
+ifneq ($(shell grep -c TUNSIFHEAD /usr/include/net/if_tun.h 2>/dev/null),1)
+# Supports TUNSIFHEAD -> AYIYA/l2tp available
+CFLAGS += -D NEED_IFHEAD
+else
+# Doesn't support TUNSIFHEAD -> No AYIYA/l2tp available
+CFLAGS += -D NO_IFHEAD
+endif
+
+SRCS += ../common/aiccu_kame.c
+OBJS += ../common/aiccu_kame.o
+CFLAGS += -pthread -D_NETBSD_SOURCE
+endif
+
+# OpenBSD
+ifeq ($(shell uname | grep -c "OpenBSD"),1)
+CFLAGS += -D_OPENBSD -D HAS_IFHEAD
+# 2.7-2.9
+ifeq ($(shell uname -r | cut -c 1),2)
+CFLAGS += -D AICCU_TYPE="\"openbsd2\""
+SRCS += ../common/aiccu_openbsd2.c
+OBJS += ../common/aiccu_openbsd2.o
+else
+# 3.x-4.x etc
+CFLAGS += -D AICCU_TYPE="\"openbsd\""
+SRCS += ../common/aiccu_openbsd.c
+OBJS += ../common/aiccu_openbsd.o
+endif
+CFLAGS += -pthread
+endif
+
+# Darwin
+ifeq ($(shell uname | grep -c "Darwin"),1)
+CFLAGS += -D_DARWIN -D NEED_IFHEAD -D AICCU_TYPE="\"darwin\""
+SRCS += ../common/aiccu_darwin.c
+OBJS += ../common/aiccu_darwin.o
+LDFLAGS += -lresolv
+endif
+
+# SunOS / Solaris
+ifeq ($(shell uname | grep -c "SunOS"),1)
+CFLAGS += -D_SUNOS -D AICCU_TYPE="\"sunos\""
+SRCS += ../common/aiccu_sunos.c
+OBJS += ../common/aiccu_sunos.o
+LDFLAGS += -lsocket -lnsl -lresolv
+endif
+
+# AIX
+ifeq ($(shell uname | grep -c "AIX"),1)
+CC = @/usr/vac/bin/xlc_r
+CFLAGS = -qthreaded -q64 -qlanglvl=stdc99 -bmaxdata:0xD0000000 -D_64BIT -g -qdbxextra -qfullpath -qheapdebug -qformat=all -qcheck=all
+CFLAGS += -D AICCU_CONSOLE
+CFLAGS += -D_AIX -D AICCU_TYPE="\"aix\""
+SRCS += ../common/aiccu_aix.c
+OBJS += ../common/aiccu_aix.o
+LDFLAGS += -lpthread
+endif
+
+
+all: aiccu
+
+aiccu: $(OBJS) ${SRCS} ${INCS}
+ $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJS)
+ifeq ($(shell echo $(CFLAGS) | grep -c "DEBUG"),0)
+ifeq ($(shell echo "$(RPM_OPT_FLAGS)" | wc -c),1)
+ strip $@
+endif
+endif
+
+clean:
+ $(RM) -f $(OBJS) aiccu
+
+install: aiccu
+ cp aiccu ${DESTDIR}${dirsbin}aiccu
+
--- /dev/null
+/**********************************************************
+ SixXS - Automatic IPv6 Connectivity Configuration Utility
+***********************************************************
+ Copyright 2003-2005 SixXS - http://www.sixxs.net
+***********************************************************
+ unix-client/aiccu.c - AICCU - The client for UNIX
+***********************************************************
+ $Author: jeroen $
+ $Id: main.c,v 1.20 2007-01-15 11:57:34 jeroen Exp $
+ $Date: 2007-01-15 11:57:34 $
+**********************************************************/
+
+#include "../common/aiccu.h"
+#include "../common/tun.h"
+
+#ifndef _WIN32
+/* Enable/Disable heartbeating */
+void sigusr1(int i);
+void sigusr1(int i)
+{
+ /* Toggle the flag */
+ g_aiccu->makebeats = !g_aiccu->makebeats;
+
+ /* Reset the signal */
+ signal(i, &sigusr1);
+}
+
+void sigterm(int i);
+void sigterm(int i)
+{
+ g_aiccu->running = false;
+ signal(i, SIG_IGN);
+}
+
+int sigrunning(int sig);
+int sigrunning(int sig)
+{
+ int pid;
+ FILE *f;
+
+ if (!g_aiccu) return 0;
+
+ /* Open our PID file */
+ f = fopen(g_aiccu->pidfile, "r");
+ if (!f) return 0;
+
+ /* Get the PID from the file or make it invalid when the format is wrong */
+ if (fscanf(f, "%d", &pid) != 1) pid = -1;
+
+ /* Close the file again */
+ fclose(f);
+
+ /* If we can HUP it, it still runs */
+ return (pid > 0 && kill(pid, sig) == 0 ? 1 : 0);
+}
+
+#else
+
+static BOOL sigterm(DWORD sig);
+static BOOL sigterm(DWORD sig)
+{
+ D(dolog(LOG_DEBUG, "Terminating due to CTRL event\n"));
+ g_aiccu->running = false;
+ return true;
+}
+static BOOL sigterm_testing(DWORD sig);
+static BOOL sigterm_testing(DWORD sig)
+{
+ D(dolog(LOG_DEBUG, "Ignoring CTRL event\n"));
+ return true;
+}
+
+#endif
+
+int list_tunnels(void);
+int list_tunnels(void)
+{
+ struct TIC_sTunnel *hsTunnel, *t;
+
+ if (!tic_Login(g_aiccu->tic, g_aiccu->username, g_aiccu->password, g_aiccu->server)) return 0;
+
+ hsTunnel = tic_ListTunnels(g_aiccu->tic);
+
+ if (!hsTunnel)
+ {
+ tic_Logout(g_aiccu->tic, "Getting current tunnel listing");
+ return 1;
+ }
+
+ for (t = hsTunnel; t; t = t->next)
+ {
+ printf("%s %s %s %s\n", t->sId, t->sIPv6, t->sIPv4, t->sPOPId);
+ }
+
+ tic_Free_sTunnel(hsTunnel);
+ tic_Logout(g_aiccu->tic, "Getting current tunnel listing");
+ return 1;
+}
+
+static unsigned int prevnum = 54321;
+
+/* Due to broken DNS servers out there, make sure that we get at least the SixXS TIC server */
+static bool foundsixxs = false;
+
+void gotrr(unsigned int num, int type, const char *record);
+void gotrr(unsigned int num, int type, const char *record)
+{
+ /* Skip non-TXT records + Comments */
+ if (type != T_TXT || record[0] == '#') return;
+ /* If the record number changed and it is not the first one, add a return */
+ if (num != prevnum && prevnum != 54321) printf("\n");
+
+ /* The current record = the last one seen */
+ prevnum = num;
+
+ /* Print the component */
+ printf("%s|", record);
+
+ /* Found SixXS? */
+ if (strcmp(record, "SixXS") == 0) foundsixxs = true;
+}
+
+/* Get Tunnel Brokers from _aiccu.<search path> and from _aiccu.sixxs.net */
+int list_brokers(void);
+int list_brokers(void)
+{
+ foundsixxs = false;
+ prevnum = 54321;
+ getrrs("_aiccu", T_TXT, gotrr);
+ prevnum = 54321;
+ getrrs("_aiccu.sixxs.net", T_TXT, gotrr);
+ printf("\n");
+
+ if (!foundsixxs)
+ {
+ printf("SixXS|tic://tic.sixxs.net|http://www.sixxs.net|be de ee fi gb ie it nl pl pt si se us");
+
+ /* Warn the user of the missing global tb's */
+ fprintf(stderr, "Warning: Couldn't find global Tunnel Brokers List, please check your DNS settings and read the FAQ.\n");
+ }
+
+ return 1;
+}
+
+/*
+ * AICCU! - Aka... let's get connected ;)
+ * returns a TIC_Tunnel which can then be
+ * used for configuring and keeping it running
+ */
+struct TIC_Tunnel *get_tunnel(void);
+struct TIC_Tunnel *get_tunnel(void)
+{
+
+ struct TIC_sTunnel *hsTunnel, *t;
+ struct TIC_Tunnel *hTunnel;
+
+ /* Login to the TIC Server */
+ if (!tic_Login(g_aiccu->tic, g_aiccu->username, g_aiccu->password, g_aiccu->server)) return NULL;
+
+ /*
+ * Don't try to list the tunnels when
+ * we already have a tunnel_id configured
+ */
+ if (!g_aiccu->tunnel_id)
+ {
+ hsTunnel = tic_ListTunnels(g_aiccu->tic);
+ if (!hsTunnel)
+ {
+ dolog(LOG_ERR, "No tunnel available, request one first\n");
+ tic_Free_sTunnel(hsTunnel);
+ tic_Logout(g_aiccu->tic, "I didn't have any tunnels to select");
+ return NULL;
+ }
+
+ if (hsTunnel->next)
+ {
+ dolog(LOG_ERR, "Multiple tunnels available, please pick one from the following list and configure the aiccu.conf using it\n");
+ for (t = hsTunnel; t; t = t->next)
+ {
+ dolog(LOG_ERR, "%s %s %s %s\n", t->sId, t->sIPv6, t->sIPv4, t->sPOPId);
+ }
+ tic_Free_sTunnel(hsTunnel);
+ tic_Logout(g_aiccu->tic, "User still needed to select a tunnel");
+ return NULL;
+ }
+ g_aiccu->tunnel_id = strdup(hsTunnel->sId);
+
+ /* Free the info */
+ tic_Free_sTunnel(hsTunnel);
+ }
+
+ /* Get Tunnel Information */
+ hTunnel = tic_GetTunnel(g_aiccu->tic, g_aiccu->tunnel_id);
+ if (!hTunnel)
+ {
+ tic_Logout(g_aiccu->tic, "No such tunnel");
+ return NULL;
+ }
+
+ /* Logout, TIC is not needed any more */
+ tic_Logout(g_aiccu->tic, NULL);
+
+ /* Swee.... sufficient information */
+ return hTunnel;
+}
+
+enum AICCU_MODES
+{
+ A_NONE = 0,
+ A_START,
+ A_STOP,
+ A_BROKERS,
+ A_TUNNELS,
+ A_TEST,
+ A_AUTOTEST,
+ A_LICENSE,
+#ifdef _WIN32
+ A_LISTTAPS,
+#endif
+ A_VERSION
+};
+
+const char *options = "aiccu (start|stop|brokers|tunnels|test|autotest|license|"
+#ifdef _WIN32
+ "listtaps|"
+#endif
+ "version) [<configfile>]\n";
+
+int main(int argc, char *argv[])
+{
+ enum AICCU_MODES mode = A_NONE;
+
+ struct TIC_Tunnel *hTunnel;
+#ifdef _WIN32
+ WSADATA wsadata;
+ unsigned int i;
+
+ /* Initialize Winsock so that we can do network functions */
+ WSAStartup(WINSOCK_VERSION, &wsadata);
+#endif
+
+ /* Initialize Configuration */
+ aiccu_InitConfig();
+
+ /* Make sure we actually have an IPv6 stack */
+ aiccu_install();
+
+ /* Require start/stop/test */
+ if (argc == 2 || argc == 3)
+ {
+ if (strcasecmp(argv[1], "start") == 0) mode = A_START;
+ else if (strcasecmp(argv[1], "stop") == 0) mode = A_STOP;
+ else if (strcasecmp(argv[1], "brokers") == 0) mode = A_BROKERS;
+ else if (strcasecmp(argv[1], "tunnels") == 0) mode = A_TUNNELS;
+ else if (strcasecmp(argv[1], "test") == 0) mode = A_TEST;
+ else if (strcasecmp(argv[1], "autotest")== 0) mode = A_AUTOTEST;
+ else if (strcasecmp(argv[1], "license") == 0) mode = A_LICENSE;
+#ifdef _WIN32
+ else if (strcasecmp(argv[1], "listtaps") == 0) mode = A_LISTTAPS;
+#endif
+ else if (strcasecmp(argv[1], "version") == 0) mode = A_VERSION;
+ }
+
+ /* Optionally we want a second argument: a config file */
+ if (( argc != 2 &&
+ argc != 3) ||
+ mode == A_NONE)
+ {
+ dolog(LOG_ERR, "%s", options);
+ return -1;
+ }
+
+ if ( mode == A_LICENSE)
+ {
+ printf("%s\n", aiccu_license());
+ return 0;
+ }
+
+ if ( mode == A_VERSION)
+ {
+ printf("AICCU %s by Jeroen Massar\n", AICCU_VERSION);
+ return 0;
+ }
+
+#ifdef _WIN32
+ if ( mode == A_LISTTAPS)
+ {
+ tun_list_tap_adapters();
+ return 0;
+ }
+#endif
+
+ if ( mode == A_BROKERS)
+ {
+ int ret = list_brokers();
+ aiccu_FreeConfig();
+ return ret == 0 ? -1 : 0;
+ }
+
+ if (!aiccu_LoadConfig(argc <= 2 ? NULL : argv[2]))
+ {
+ return -1;
+ }
+
+#ifndef _WIN32
+ /* start or stop? */
+ if ( mode != A_TEST &&
+ mode != A_AUTOTEST)
+ {
+ /* Already running? */
+ if (sigrunning(mode == A_STOP ? SIGTERM : 0) == 1)
+ {
+ dolog(LOG_ERR, "Already running instance HUP'ed, exiting\n");
+ return 0;
+ }
+ }
+#endif
+
+ /* Verify required parameters */
+ if (!g_aiccu->username || !g_aiccu->password)
+ {
+ dolog(LOG_ERR, "Required parameters missing, make sure that username and password are given\n");
+ aiccu_FreeConfig();
+ return -1;
+ }
+
+ if (mode == A_TUNNELS)
+ {
+ int ret = list_tunnels();
+ aiccu_FreeConfig();
+ return ret == 0 ? -1 : 0;
+ }
+
+ /* Get our tunnel */
+ hTunnel = get_tunnel();
+
+ if (!hTunnel)
+ {
+ dolog(LOG_ERR, "Couldn't retrieve first tunnel for the above reason, aborting\n");
+ aiccu_FreeConfig();
+ return -1;
+ }
+
+ /*
+ * We now have sufficient information.
+ * Thus we can logout from the TIC server
+ */
+ tic_Logout(g_aiccu->tic, NULL);
+ g_aiccu->tic = NULL;
+
+ if (g_aiccu->verbose)
+ {
+ printf("Tunnel Information for %s:\n",hTunnel->sId);
+ printf("POP Id : %s\n", hTunnel->sPOP_Id);
+ printf("IPv6 Local : %s/%u\n", hTunnel->sIPv6_Local,hTunnel->nIPv6_PrefixLength);
+ printf("IPv6 Remote : %s/%u\n", hTunnel->sIPv6_POP,hTunnel->nIPv6_PrefixLength);
+ printf("Tunnel Type : %s\n", hTunnel->sType);
+ printf("Adminstate : %s\n", hTunnel->sAdminState);
+ printf("Userstate : %s\n", hTunnel->sUserState);
+ }
+
+ /* One can always try to stop it */
+ if (mode == A_STOP)
+ {
+ aiccu_delete(hTunnel);
+
+ /* Free stuff and exit */
+ tic_Free_Tunnel(hTunnel);
+ aiccu_FreeConfig();
+ return 0;
+ }
+
+ if ( (strcmp(hTunnel->sAdminState, "enabled") != 0) ||
+ (strcmp(hTunnel->sUserState, "enabled") != 0))
+ {
+ dolog(LOG_ERR, "Tunnel is not enabled (UserState: %s, AdminState: %s)\n", hTunnel->sAdminState, hTunnel->sUserState);
+ return -1;
+ }
+
+ /* Do the test thing */
+ if ( mode == A_TEST ||
+ mode == A_AUTOTEST)
+ {
+#ifdef _WIN32
+ SetConsoleCtrlHandler((PHANDLER_ROUTINE)sigterm_testing, true);
+#endif
+ /* Setup the tunnel */
+ if (aiccu_setup(hTunnel, true))
+ {
+ aiccu_test(hTunnel, strcasecmp(argv[1], "autotest") == 0 ? true : false);
+
+ /* Tear the tunnel down again */
+ aiccu_delete(hTunnel);
+ }
+ else
+ {
+ dolog(LOG_ERR, "Tunnel Setup Failed\n");
+ }
+
+ /* exit as all is done */
+ tic_Free_Tunnel(hTunnel);
+ aiccu_FreeConfig();
+ return 0;
+ }
+
+#ifndef _WIN32
+ if ( mode == A_START &&
+ g_aiccu->daemonize != 0)
+ {
+ FILE *f;
+
+ /* Daemonize */
+ int i = fork();
+ if (i < 0)
+ {
+ fprintf(stderr, "Couldn't fork\n");
+ return -1;
+ }
+ /* Exit the mother fork */
+ if (i != 0) return 0;
+
+ /* Child fork */
+ setsid();
+
+ /* Chdir to minimise disruption to FS umounts */
+ (void)chdir("/");
+
+ /* Cleanup stdin/out/err */
+ freopen("/dev/null","r",stdin);
+ freopen("/dev/null","w",stdout);
+ freopen("/dev/null","w",stderr);
+
+ /* */
+ f = fopen(g_aiccu->pidfile, "w");
+ if (!f)
+ {
+ dolog(LOG_ERR, "Could not store PID in file %s\n", g_aiccu->pidfile);
+ return 0;
+ }
+
+ fprintf(f, "%d", getpid());
+ fclose(f);
+
+ dolog(LOG_INFO, "AICCU running as PID %d\n", getpid());
+ }
+
+#endif /* !_WIN32 */
+
+ /* mode == A_START */
+
+#ifndef _WIN32
+ /*
+ * Install a signal handler so that
+ * one can disable beating with SIGUSR1
+ */
+ signal(SIGUSR1, &sigusr1);
+
+ /*
+ * Install a signal handler so that
+ * one can stop this program with SIGTERM
+ */
+ signal(SIGTERM, &sigterm);
+ signal(SIGINT, &sigterm);
+#else
+ SetConsoleCtrlHandler((PHANDLER_ROUTINE)sigterm, true);
+#endif
+
+ /*
+ * Setup our tunnel
+ * This also spawns required threads for AYIYA
+ */
+ if (aiccu_setup(hTunnel, true))
+ {
+ /* We need to stay running when doing Heartbeat or AYIYA */
+ if ( strcasecmp(hTunnel->sType, "6in4-heartbeat") == 0 ||
+ strcasecmp(hTunnel->sType, "ayiya") == 0)
+ {
+ /* We are spawned, now just beat once in a while. */
+ while (g_aiccu->running)
+ {
+ aiccu_beat(hTunnel);
+#ifndef _WIN32
+ sleep(hTunnel->nHeartbeat_Interval);
+#else
+ for (i=0; g_aiccu->running && i <= hTunnel->nHeartbeat_Interval; i++) Sleep(1000);
+#endif
+ }
+
+ /* Clean up the the tunnel, no beat anyway */
+ aiccu_delete(hTunnel);
+ }
+
+#ifndef _WIN32
+ /* Remove our PID file */
+ if (g_aiccu) unlink(g_aiccu->pidfile);
+#endif
+ }
+
+ /* Free our resources */
+ aiccu_FreeConfig();
+
+ return 0;
+}
+