Imported Upstream version 0.3 v0.3
authorMichael Prokop <mika@grml.org>
Fri, 29 May 2009 19:19:02 +0000 (21:19 +0200)
committerMichael Prokop <mika@grml.org>
Fri, 29 May 2009 19:19:02 +0000 (21:19 +0200)
135 files changed:
AUTHORS [new file with mode: 0644]
ChangeLog [new file with mode: 0644]
LICENSE [new file with mode: 0644]
README [new file with mode: 0644]
etc/anytun/autostart [new file with mode: 0644]
etc/anytun/client1/config [new file with mode: 0644]
etc/anytun/client1/post-up.sh [new file with mode: 0755]
etc/anytun/client2/config [new file with mode: 0644]
etc/anytun/client2/post-up.sh [new file with mode: 0755]
etc/anytun/client3/config [new file with mode: 0644]
etc/anytun/client3/post-up.sh [new file with mode: 0755]
etc/anytun/p2p-a/config [new file with mode: 0644]
etc/anytun/p2p-b/config [new file with mode: 0644]
etc/anytun/server/conf.d/client1 [new file with mode: 0644]
etc/anytun/server/conf.d/client2 [new file with mode: 0644]
etc/anytun/server/conf.d/client3 [new file with mode: 0644]
etc/anytun/server/config [new file with mode: 0644]
etc/anytun/server/post-up.sh [new file with mode: 0755]
etc/init.d/anytun [new file with mode: 0755]
src/Doxyfile [new file with mode: 0644]
src/Makefile [new file with mode: 0644]
src/anyrtpproxy/Makefile [new file with mode: 0644]
src/anyrtpproxy/anyrtpproxy.cpp [new file with mode: 0644]
src/anyrtpproxy/callIdQueue.cpp [new file with mode: 0644]
src/anyrtpproxy/callIdQueue.h [new file with mode: 0644]
src/anyrtpproxy/commandHandler.cpp [new file with mode: 0644]
src/anyrtpproxy/commandHandler.h [new file with mode: 0644]
src/anyrtpproxy/connectionList.cpp [new file with mode: 0644]
src/anyrtpproxy/connectionList.h [new file with mode: 0644]
src/anyrtpproxy/options.cpp [new file with mode: 0644]
src/anyrtpproxy/options.h [new file with mode: 0644]
src/anyrtpproxy/portWindow.cpp [new file with mode: 0644]
src/anyrtpproxy/portWindow.h [new file with mode: 0644]
src/anyrtpproxy/rtpSession.cpp [new file with mode: 0644]
src/anyrtpproxy/rtpSession.h [new file with mode: 0644]
src/anyrtpproxy/rtpSessionTable.cpp [new file with mode: 0644]
src/anyrtpproxy/rtpSessionTable.h [new file with mode: 0644]
src/anyrtpproxy/syncRtpCommand.cpp [new file with mode: 0644]
src/anyrtpproxy/syncRtpCommand.h [new file with mode: 0644]
src/anytun-config.cpp [new file with mode: 0644]
src/anytun-controld.cpp [new file with mode: 0644]
src/anytun-showtables.cpp [new file with mode: 0644]
src/anytun.cpp [new file with mode: 0644]
src/anytun.sln [new file with mode: 0644]
src/anytun.suo [new file with mode: 0644]
src/anytun.vcproj [new file with mode: 0644]
src/anytunError.cpp [new file with mode: 0644]
src/anytunError.h [new file with mode: 0644]
src/authAlgo.cpp [new file with mode: 0644]
src/authAlgo.h [new file with mode: 0644]
src/authAlgoFactory.cpp [new file with mode: 0644]
src/authAlgoFactory.h [new file with mode: 0644]
src/bsd/tunDevice.cpp [new file with mode: 0644]
src/buffer.cpp [new file with mode: 0644]
src/buffer.h [new file with mode: 0644]
src/cipher.cpp [new file with mode: 0644]
src/cipher.h [new file with mode: 0644]
src/cipherFactory.cpp [new file with mode: 0644]
src/cipherFactory.h [new file with mode: 0644]
src/configure [new file with mode: 0755]
src/connectionList.cpp [new file with mode: 0644]
src/connectionList.h [new file with mode: 0644]
src/connectionParam.cpp [new file with mode: 0644]
src/connectionParam.h [new file with mode: 0644]
src/cryptinit.hpp [new file with mode: 0644]
src/daemon.hpp [new file with mode: 0644]
src/datatypes.h [new file with mode: 0644]
src/deviceConfig.hpp [new file with mode: 0644]
src/encryptedPacket.cpp [new file with mode: 0644]
src/encryptedPacket.h [new file with mode: 0644]
src/endian.h [new file with mode: 0644]
src/keyDerivation.cpp [new file with mode: 0644]
src/keyDerivation.h [new file with mode: 0644]
src/keyDerivationFactory.cpp [new file with mode: 0644]
src/keyDerivationFactory.h [new file with mode: 0644]
src/linux/tunDevice.cpp [new file with mode: 0644]
src/log.cpp [new file with mode: 0644]
src/log.h [new file with mode: 0644]
src/logTargets.cpp [new file with mode: 0644]
src/logTargets.h [new file with mode: 0644]
src/man/Makefile [new file with mode: 0644]
src/man/anyrtpproxy.8.txt [new file with mode: 0644]
src/man/anytun-config.8.txt [new file with mode: 0644]
src/man/anytun-controld.8.txt [new file with mode: 0644]
src/man/anytun-showtables.8.txt [new file with mode: 0644]
src/man/anytun.8.txt [new file with mode: 0644]
src/networkAddress.cpp [new file with mode: 0644]
src/networkAddress.h [new file with mode: 0644]
src/networkPrefix.cpp [new file with mode: 0644]
src/networkPrefix.h [new file with mode: 0644]
src/options.cpp [new file with mode: 0644]
src/options.h [new file with mode: 0644]
src/packetSource.cpp [new file with mode: 0644]
src/packetSource.h [new file with mode: 0644]
src/plainPacket.cpp [new file with mode: 0644]
src/plainPacket.h [new file with mode: 0644]
src/resolver.cpp [new file with mode: 0644]
src/resolver.h [new file with mode: 0644]
src/routingTable.cpp [new file with mode: 0644]
src/routingTable.h [new file with mode: 0644]
src/routingTree.hpp [new file with mode: 0644]
src/routingTreeNode.cpp [new file with mode: 0644]
src/routingTreeNode.h [new file with mode: 0644]
src/seqWindow.cpp [new file with mode: 0644]
src/seqWindow.h [new file with mode: 0644]
src/signalController.cpp [new file with mode: 0644]
src/signalController.h [new file with mode: 0644]
src/syncBuffer.cpp [new file with mode: 0644]
src/syncBuffer.h [new file with mode: 0644]
src/syncClient.cpp [new file with mode: 0644]
src/syncClient.h [new file with mode: 0644]
src/syncCommand.cpp [new file with mode: 0644]
src/syncCommand.h [new file with mode: 0644]
src/syncConnectionCommand.cpp [new file with mode: 0644]
src/syncConnectionCommand.h [new file with mode: 0644]
src/syncOnConnect.hpp [new file with mode: 0644]
src/syncQueue.cpp [new file with mode: 0644]
src/syncQueue.h [new file with mode: 0644]
src/syncRouteCommand.cpp [new file with mode: 0644]
src/syncRouteCommand.h [new file with mode: 0644]
src/syncServer.cpp [new file with mode: 0644]
src/syncServer.h [new file with mode: 0644]
src/syncTcpConnection.cpp [new file with mode: 0644]
src/syncTcpConnection.h [new file with mode: 0644]
src/sysexec.hpp [new file with mode: 0644]
src/threadUtils.hpp [new file with mode: 0644]
src/tunDevice.h [new file with mode: 0644]
src/win32/#winService.cpp# [new file with mode: 0644]
src/win32/common.h [new file with mode: 0644]
src/win32/registryKey.cpp [new file with mode: 0644]
src/win32/registryKey.h [new file with mode: 0644]
src/win32/tunDevice.cpp [new file with mode: 0644]
src/win32/winService.cpp [new file with mode: 0644]
src/win32/winService.h [new file with mode: 0644]
wireshark-lua/satp.lua [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..6d7339f
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,3 @@
+Othmar Gsenger <otti@anytun.org>
+Erwin Nindl <nine@anytun.org>
+Christian Pointner <equinox@anytun.org>
diff --git a/ChangeLog b/ChangeLog
new file mode 100644 (file)
index 0000000..a2736ca
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,43 @@
+2009.5.1 -- Version 0.3 svn834
+
+* updated to new protocol specification (extended label and crypto role)
+  Due to this changes this version is incompatible to version 0.2 and prior
+* the auth tag length can now be configured
+* added extended logging support (syslog, file stdout and stderr)
+* changed -n|--ifconfig parameter to new behavior
+  tun and tap devices now use the same syntax
+* added seperate resolver thread
+* fixed packet length errors
+* dropping privileges is now possible wihtout chroot
+* full ipv6 support
+ - ipv6 multiple connection routing
+ - syncronisation over ipv6
+ - 4in6,6in6 tunnels
+* replaced several dependencies with boost libs
+* ported basic functionality to Windows
+* dropped OpenBSD Port due to multi threading issues
+* code cleanup
+
+2008.6.20 -- Version 0.2.1svn556
+
+* finished own tun/tap devices and removed openvpn source code
+  currently there are tun/tap devices for Linux, FreeBSD, OpenBSD
+  and NetBSD
+* several fixes for building on OpenBSD
+* added manpages for all binaries
+* switched to GPLv3
+
+
+2008.4.12 -- Version 0.2svn490
+
+* updated to Internet Draft Revision 02
+  Mind that the this version is incompatible to version 0.1
+  However this is only the case if you use encryption. There
+  shouldn't be any Problem with NULL cipher
+* several fixes for tunneling IPv6
+       
+2008.3.18 -- Version 0.1svn441
+
+* Initial release.
+* IPv4 tunnel over UDP, with AES-CTR cipher and SHA1 HMAC signature.
+
diff --git a/LICENSE b/LICENSE
new file mode 100644 (file)
index 0000000..51e0b22
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,704 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+                    GNU GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+                            Preamble
+
+  The GNU General Public License is a free, copyleft license for
+software and other kinds of works.
+
+  The licenses for most software and other practical works are designed
+to take away your freedom to share and change the works.  By contrast,
+the GNU General Public License is intended to guarantee your freedom to
+share and change all versions of a program--to make sure it remains free
+software for all its users.  We, the Free Software Foundation, use the
+GNU General Public License for most of our software; it applies also to
+any other work released this way by its authors.  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+them if you wish), that you receive source code or can get it if you
+want it, that you can change the software or use pieces of it in new
+free programs, and that you know you can do these things.
+
+  To protect your rights, we need to prevent others from denying you
+these rights or asking you to surrender the rights.  Therefore, you have
+certain responsibilities if you distribute copies of the software, or if
+you modify it: responsibilities to respect the freedom of others.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must pass on to the recipients the same
+freedoms that you received.  You must make sure that they, too, receive
+or can get the source code.  And you must show them these terms so they
+know their rights.
+
+  Developers that use the GNU GPL protect your rights with two steps:
+(1) assert copyright on the software, and (2) offer you this License
+giving you legal permission to copy, distribute and/or modify it.
+
+  For the developers' and authors' protection, the GPL clearly explains
+that there is no warranty for this free software.  For both users' and
+authors' sake, the GPL requires that modified versions be marked as
+changed, so that their problems will not be attributed erroneously to
+authors of previous versions.
+
+  Some devices are designed to deny users access to install or run
+modified versions of the software inside them, although the manufacturer
+can do so.  This is fundamentally incompatible with the aim of
+protecting users' freedom to change the software.  The systematic
+pattern of such abuse occurs in the area of products for individuals to
+use, which is precisely where it is most unacceptable.  Therefore, we
+have designed this version of the GPL to prohibit the practice for those
+products.  If such problems arise substantially in other domains, we
+stand ready to extend this provision to those domains in future versions
+of the GPL, as needed to protect the freedom of users.
+
+  Finally, every program is threatened constantly by software patents.
+States should not allow patents to restrict development and use of
+software on general-purpose computers, but in those that do, we wish to
+avoid the special danger that patents applied to a free program could
+make it effectively proprietary.  To prevent this, the GPL assures that
+patents cannot be used to render the program non-free.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+                       TERMS AND CONDITIONS
+
+  0. Definitions.
+
+  "This License" refers to version 3 of the GNU General Public License.
+
+  "Copyright" also means copyright-like laws that apply to other kinds of
+works, such as semiconductor masks.
+
+  "The Program" refers to any copyrightable work licensed under this
+License.  Each licensee is addressed as "you".  "Licensees" and
+"recipients" may be individuals or organizations.
+
+  To "modify" a work means to copy from or adapt all or part of the work
+in a fashion requiring copyright permission, other than the making of an
+exact copy.  The resulting work is called a "modified version" of the
+earlier work or a work "based on" the earlier work.
+
+  A "covered work" means either the unmodified Program or a work based
+on the Program.
+
+  To "propagate" a work means to do anything with it that, without
+permission, would make you directly or secondarily liable for
+infringement under applicable copyright law, except executing it on a
+computer or modifying a private copy.  Propagation includes copying,
+distribution (with or without modification), making available to the
+public, and in some countries other activities as well.
+
+  To "convey" a work means any kind of propagation that enables other
+parties to make or receive copies.  Mere interaction with a user through
+a computer network, with no transfer of a copy, is not conveying.
+
+  An interactive user interface displays "Appropriate Legal Notices"
+to the extent that it includes a convenient and prominently visible
+feature that (1) displays an appropriate copyright notice, and (2)
+tells the user that there is no warranty for the work (except to the
+extent that warranties are provided), that licensees may convey the
+work under this License, and how to view a copy of this License.  If
+the interface presents a list of user commands or options, such as a
+menu, a prominent item in the list meets this criterion.
+
+  1. Source Code.
+
+  The "source code" for a work means the preferred form of the work
+for making modifications to it.  "Object code" means any non-source
+form of a work.
+
+  A "Standard Interface" means an interface that either is an official
+standard defined by a recognized standards body, or, in the case of
+interfaces specified for a particular programming language, one that
+is widely used among developers working in that language.
+
+  The "System Libraries" of an executable work include anything, other
+than the work as a whole, that (a) is included in the normal form of
+packaging a Major Component, but which is not part of that Major
+Component, and (b) serves only to enable use of the work with that
+Major Component, or to implement a Standard Interface for which an
+implementation is available to the public in source code form.  A
+"Major Component", in this context, means a major essential component
+(kernel, window system, and so on) of the specific operating system
+(if any) on which the executable work runs, or a compiler used to
+produce the work, or an object code interpreter used to run it.
+
+  The "Corresponding Source" for a work in object code form means all
+the source code needed to generate, install, and (for an executable
+work) run the object code and to modify the work, including scripts to
+control those activities.  However, it does not include the work's
+System Libraries, or general-purpose tools or generally available free
+programs which are used unmodified in performing those activities but
+which are not part of the work.  For example, Corresponding Source
+includes interface definition files associated with source files for
+the work, and the source code for shared libraries and dynamically
+linked subprograms that the work is specifically designed to require,
+such as by intimate data communication or control flow between those
+subprograms and other parts of the work.
+
+  The Corresponding Source need not include anything that users
+can regenerate automatically from other parts of the Corresponding
+Source.
+
+  The Corresponding Source for a work in source code form is that
+same work.
+
+  2. Basic Permissions.
+
+  All rights granted under this License are granted for the term of
+copyright on the Program, and are irrevocable provided the stated
+conditions are met.  This License explicitly affirms your unlimited
+permission to run the unmodified Program.  The output from running a
+covered work is covered by this License only if the output, given its
+content, constitutes a covered work.  This License acknowledges your
+rights of fair use or other equivalent, as provided by copyright law.
+
+  You may make, run and propagate covered works that you do not
+convey, without conditions so long as your license otherwise remains
+in force.  You may convey covered works to others for the sole purpose
+of having them make modifications exclusively for you, or provide you
+with facilities for running those works, provided that you comply with
+the terms of this License in conveying all material for which you do
+not control copyright.  Those thus making or running the covered works
+for you must do so exclusively on your behalf, under your direction
+and control, on terms that prohibit them from making any copies of
+your copyrighted material outside their relationship with you.
+
+  Conveying under any other circumstances is permitted solely under
+the conditions stated below.  Sublicensing is not allowed; section 10
+makes it unnecessary.
+
+  3. Protecting Users' Legal Rights From Anti-Circumvention Law.
+
+  No covered work shall be deemed part of an effective technological
+measure under any applicable law fulfilling obligations under article
+11 of the WIPO copyright treaty adopted on 20 December 1996, or
+similar laws prohibiting or restricting circumvention of such
+measures.
+
+  When you convey a covered work, you waive any legal power to forbid
+circumvention of technological measures to the extent such circumvention
+is effected by exercising rights under this License with respect to
+the covered work, and you disclaim any intention to limit operation or
+modification of the work as a means of enforcing, against the work's
+users, your or third parties' legal rights to forbid circumvention of
+technological measures.
+
+  4. Conveying Verbatim Copies.
+
+  You may convey verbatim copies of the Program's source code as you
+receive it, in any medium, provided that you conspicuously and
+appropriately publish on each copy an appropriate copyright notice;
+keep intact all notices stating that this License and any
+non-permissive terms added in accord with section 7 apply to the code;
+keep intact all notices of the absence of any warranty; and give all
+recipients a copy of this License along with the Program.
+
+  You may charge any price or no price for each copy that you convey,
+and you may offer support or warranty protection for a fee.
+
+  5. Conveying Modified Source Versions.
+
+  You may convey a work based on the Program, or the modifications to
+produce it from the Program, in the form of source code under the
+terms of section 4, provided that you also meet all of these conditions:
+
+    a) The work must carry prominent notices stating that you modified
+    it, and giving a relevant date.
+
+    b) The work must carry prominent notices stating that it is
+    released under this License and any conditions added under section
+    7.  This requirement modifies the requirement in section 4 to
+    "keep intact all notices".
+
+    c) You must license the entire work, as a whole, under this
+    License to anyone who comes into possession of a copy.  This
+    License will therefore apply, along with any applicable section 7
+    additional terms, to the whole of the work, and all its parts,
+    regardless of how they are packaged.  This License gives no
+    permission to license the work in any other way, but it does not
+    invalidate such permission if you have separately received it.
+
+    d) If the work has interactive user interfaces, each must display
+    Appropriate Legal Notices; however, if the Program has interactive
+    interfaces that do not display Appropriate Legal Notices, your
+    work need not make them do so.
+
+  A compilation of a covered work with other separate and independent
+works, which are not by their nature extensions of the covered work,
+and which are not combined with it such as to form a larger program,
+in or on a volume of a storage or distribution medium, is called an
+"aggregate" if the compilation and its resulting copyright are not
+used to limit the access or legal rights of the compilation's users
+beyond what the individual works permit.  Inclusion of a covered work
+in an aggregate does not cause this License to apply to the other
+parts of the aggregate.
+
+  6. Conveying Non-Source Forms.
+
+  You may convey a covered work in object code form under the terms
+of sections 4 and 5, provided that you also convey the
+machine-readable Corresponding Source under the terms of this License,
+in one of these ways:
+
+    a) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by the
+    Corresponding Source fixed on a durable physical medium
+    customarily used for software interchange.
+
+    b) Convey the object code in, or embodied in, a physical product
+    (including a physical distribution medium), accompanied by a
+    written offer, valid for at least three years and valid for as
+    long as you offer spare parts or customer support for that product
+    model, to give anyone who possesses the object code either (1) a
+    copy of the Corresponding Source for all the software in the
+    product that is covered by this License, on a durable physical
+    medium customarily used for software interchange, for a price no
+    more than your reasonable cost of physically performing this
+    conveying of source, or (2) access to copy the
+    Corresponding Source from a network server at no charge.
+
+    c) Convey individual copies of the object code with a copy of the
+    written offer to provide the Corresponding Source.  This
+    alternative is allowed only occasionally and noncommercially, and
+    only if you received the object code with such an offer, in accord
+    with subsection 6b.
+
+    d) Convey the object code by offering access from a designated
+    place (gratis or for a charge), and offer equivalent access to the
+    Corresponding Source in the same way through the same place at no
+    further charge.  You need not require recipients to copy the
+    Corresponding Source along with the object code.  If the place to
+    copy the object code is a network server, the Corresponding Source
+    may be on a different server (operated by you or a third party)
+    that supports equivalent copying facilities, provided you maintain
+    clear directions next to the object code saying where to find the
+    Corresponding Source.  Regardless of what server hosts the
+    Corresponding Source, you remain obligated to ensure that it is
+    available for as long as needed to satisfy these requirements.
+
+    e) Convey the object code using peer-to-peer transmission, provided
+    you inform other peers where the object code and Corresponding
+    Source of the work are being offered to the general public at no
+    charge under subsection 6d.
+
+  A separable portion of the object code, whose source code is excluded
+from the Corresponding Source as a System Library, need not be
+included in conveying the object code work.
+
+  A "User Product" is either (1) a "consumer product", which means any
+tangible personal property which is normally used for personal, family,
+or household purposes, or (2) anything designed or sold for incorporation
+into a dwelling.  In determining whether a product is a consumer product,
+doubtful cases shall be resolved in favor of coverage.  For a particular
+product received by a particular user, "normally used" refers to a
+typical or common use of that class of product, regardless of the status
+of the particular user or of the way in which the particular user
+actually uses, or expects or is expected to use, the product.  A product
+is a consumer product regardless of whether the product has substantial
+commercial, industrial or non-consumer uses, unless such uses represent
+the only significant mode of use of the product.
+
+  "Installation Information" for a User Product means any methods,
+procedures, authorization keys, or other information required to install
+and execute modified versions of a covered work in that User Product from
+a modified version of its Corresponding Source.  The information must
+suffice to ensure that the continued functioning of the modified object
+code is in no case prevented or interfered with solely because
+modification has been made.
+
+  If you convey an object code work under this section in, or with, or
+specifically for use in, a User Product, and the conveying occurs as
+part of a transaction in which the right of possession and use of the
+User Product is transferred to the recipient in perpetuity or for a
+fixed term (regardless of how the transaction is characterized), the
+Corresponding Source conveyed under this section must be accompanied
+by the Installation Information.  But this requirement does not apply
+if neither you nor any third party retains the ability to install
+modified object code on the User Product (for example, the work has
+been installed in ROM).
+
+  The requirement to provide Installation Information does not include a
+requirement to continue to provide support service, warranty, or updates
+for a work that has been modified or installed by the recipient, or for
+the User Product in which it has been modified or installed.  Access to a
+network may be denied when the modification itself materially and
+adversely affects the operation of the network or violates the rules and
+protocols for communication across the network.
+
+  Corresponding Source conveyed, and Installation Information provided,
+in accord with this section must be in a format that is publicly
+documented (and with an implementation available to the public in
+source code form), and must require no special password or key for
+unpacking, reading or copying.
+
+  7. Additional Terms.
+
+  "Additional permissions" are terms that supplement the terms of this
+License by making exceptions from one or more of its conditions.
+Additional permissions that are applicable to the entire Program shall
+be treated as though they were included in this License, to the extent
+that they are valid under applicable law.  If additional permissions
+apply only to part of the Program, that part may be used separately
+under those permissions, but the entire Program remains governed by
+this License without regard to the additional permissions.
+
+  When you convey a copy of a covered work, you may at your option
+remove any additional permissions from that copy, or from any part of
+it.  (Additional permissions may be written to require their own
+removal in certain cases when you modify the work.)  You may place
+additional permissions on material, added by you to a covered work,
+for which you have or can give appropriate copyright permission.
+
+  Notwithstanding any other provision of this License, for material you
+add to a covered work, you may (if authorized by the copyright holders of
+that material) supplement the terms of this License with terms:
+
+    a) Disclaiming warranty or limiting liability differently from the
+    terms of sections 15 and 16 of this License; or
+
+    b) Requiring preservation of specified reasonable legal notices or
+    author attributions in that material or in the Appropriate Legal
+    Notices displayed by works containing it; or
+
+    c) Prohibiting misrepresentation of the origin of that material, or
+    requiring that modified versions of such material be marked in
+    reasonable ways as different from the original version; or
+
+    d) Limiting the use for publicity purposes of names of licensors or
+    authors of the material; or
+
+    e) Declining to grant rights under trademark law for use of some
+    trade names, trademarks, or service marks; or
+
+    f) Requiring indemnification of licensors and authors of that
+    material by anyone who conveys the material (or modified versions of
+    it) with contractual assumptions of liability to the recipient, for
+    any liability that these contractual assumptions directly impose on
+    those licensors and authors.
+
+  All other non-permissive additional terms are considered "further
+restrictions" within the meaning of section 10.  If the Program as you
+received it, or any part of it, contains a notice stating that it is
+governed by this License along with a term that is a further
+restriction, you may remove that term.  If a license document contains
+a further restriction but permits relicensing or conveying under this
+License, you may add to a covered work material governed by the terms
+of that license document, provided that the further restriction does
+not survive such relicensing or conveying.
+
+  If you add terms to a covered work in accord with this section, you
+must place, in the relevant source files, a statement of the
+additional terms that apply to those files, or a notice indicating
+where to find the applicable terms.
+
+  Additional terms, permissive or non-permissive, may be stated in the
+form of a separately written license, or stated as exceptions;
+the above requirements apply either way.
+
+  8. Termination.
+
+  You may not propagate or modify a covered work except as expressly
+provided under this License.  Any attempt otherwise to propagate or
+modify it is void, and will automatically terminate your rights under
+this License (including any patent licenses granted under the third
+paragraph of section 11).
+
+  However, if you cease all violation of this License, then your
+license from a particular copyright holder is reinstated (a)
+provisionally, unless and until the copyright holder explicitly and
+finally terminates your license, and (b) permanently, if the copyright
+holder fails to notify you of the violation by some reasonable means
+prior to 60 days after the cessation.
+
+  Moreover, your license from a particular copyright holder is
+reinstated permanently if the copyright holder notifies you of the
+violation by some reasonable means, this is the first time you have
+received notice of violation of this License (for any work) from that
+copyright holder, and you cure the violation prior to 30 days after
+your receipt of the notice.
+
+  Termination of your rights under this section does not terminate the
+licenses of parties who have received copies or rights from you under
+this License.  If your rights have been terminated and not permanently
+reinstated, you do not qualify to receive new licenses for the same
+material under section 10.
+
+  9. Acceptance Not Required for Having Copies.
+
+  You are not required to accept this License in order to receive or
+run a copy of the Program.  Ancillary propagation of a covered work
+occurring solely as a consequence of using peer-to-peer transmission
+to receive a copy likewise does not require acceptance.  However,
+nothing other than this License grants you permission to propagate or
+modify any covered work.  These actions infringe copyright if you do
+not accept this License.  Therefore, by modifying or propagating a
+covered work, you indicate your acceptance of this License to do so.
+
+  10. Automatic Licensing of Downstream Recipients.
+
+  Each time you convey a covered work, the recipient automatically
+receives a license from the original licensors, to run, modify and
+propagate that work, subject to this License.  You are not responsible
+for enforcing compliance by third parties with this License.
+
+  An "entity transaction" is a transaction transferring control of an
+organization, or substantially all assets of one, or subdividing an
+organization, or merging organizations.  If propagation of a covered
+work results from an entity transaction, each party to that
+transaction who receives a copy of the work also receives whatever
+licenses to the work the party's predecessor in interest had or could
+give under the previous paragraph, plus a right to possession of the
+Corresponding Source of the work from the predecessor in interest, if
+the predecessor has it or can get it with reasonable efforts.
+
+  You may not impose any further restrictions on the exercise of the
+rights granted or affirmed under this License.  For example, you may
+not impose a license fee, royalty, or other charge for exercise of
+rights granted under this License, and you may not initiate litigation
+(including a cross-claim or counterclaim in a lawsuit) alleging that
+any patent claim is infringed by making, using, selling, offering for
+sale, or importing the Program or any portion of it.
+
+  11. Patents.
+
+  A "contributor" is a copyright holder who authorizes use under this
+License of the Program or a work on which the Program is based.  The
+work thus licensed is called the contributor's "contributor version".
+
+  A contributor's "essential patent claims" are all patent claims
+owned or controlled by the contributor, whether already acquired or
+hereafter acquired, that would be infringed by some manner, permitted
+by this License, of making, using, or selling its contributor version,
+but do not include claims that would be infringed only as a
+consequence of further modification of the contributor version.  For
+purposes of this definition, "control" includes the right to grant
+patent sublicenses in a manner consistent with the requirements of
+this License.
+
+  Each contributor grants you a non-exclusive, worldwide, royalty-free
+patent license under the contributor's essential patent claims, to
+make, use, sell, offer for sale, import and otherwise run, modify and
+propagate the contents of its contributor version.
+
+  In the following three paragraphs, a "patent license" is any express
+agreement or commitment, however denominated, not to enforce a patent
+(such as an express permission to practice a patent or covenant not to
+sue for patent infringement).  To "grant" such a patent license to a
+party means to make such an agreement or commitment not to enforce a
+patent against the party.
+
+  If you convey a covered work, knowingly relying on a patent license,
+and the Corresponding Source of the work is not available for anyone
+to copy, free of charge and under the terms of this License, through a
+publicly available network server or other readily accessible means,
+then you must either (1) cause the Corresponding Source to be so
+available, or (2) arrange to deprive yourself of the benefit of the
+patent license for this particular work, or (3) arrange, in a manner
+consistent with the requirements of this License, to extend the patent
+license to downstream recipients.  "Knowingly relying" means you have
+actual knowledge that, but for the patent license, your conveying the
+covered work in a country, or your recipient's use of the covered work
+in a country, would infringe one or more identifiable patents in that
+country that you have reason to believe are valid.
+
+  If, pursuant to or in connection with a single transaction or
+arrangement, you convey, or propagate by procuring conveyance of, a
+covered work, and grant a patent license to some of the parties
+receiving the covered work authorizing them to use, propagate, modify
+or convey a specific copy of the covered work, then the patent license
+you grant is automatically extended to all recipients of the covered
+work and works based on it.
+
+  A patent license is "discriminatory" if it does not include within
+the scope of its coverage, prohibits the exercise of, or is
+conditioned on the non-exercise of one or more of the rights that are
+specifically granted under this License.  You may not convey a covered
+work if you are a party to an arrangement with a third party that is
+in the business of distributing software, under which you make payment
+to the third party based on the extent of your activity of conveying
+the work, and under which the third party grants, to any of the
+parties who would receive the covered work from you, a discriminatory
+patent license (a) in connection with copies of the covered work
+conveyed by you (or copies made from those copies), or (b) primarily
+for and in connection with specific products or compilations that
+contain the covered work, unless you entered into that arrangement,
+or that patent license was granted, prior to 28 March 2007.
+
+  Nothing in this License shall be construed as excluding or limiting
+any implied license or other defenses to infringement that may
+otherwise be available to you under applicable patent law.
+
+  12. No Surrender of Others' Freedom.
+
+  If conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot convey a
+covered work so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you may
+not convey it at all.  For example, if you agree to terms that obligate you
+to collect a royalty for further conveying from those to whom you convey
+the Program, the only way you could satisfy both those terms and this
+License would be to refrain entirely from conveying the Program.
+
+  13. Use with the GNU Affero General Public License.
+
+  Notwithstanding any other provision of this License, you have
+permission to link or combine any covered work with a work licensed
+under version 3 of the GNU Affero General Public License into a single
+combined work, and to convey the resulting work.  The terms of this
+License will continue to apply to the part which is the covered work,
+but the special requirements of the GNU Affero General Public License,
+section 13, concerning interaction through a network will apply to the
+combination as such.
+
+  14. Revised Versions of this License.
+
+  The Free Software Foundation may publish revised and/or new versions of
+the GNU General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+  Each version is given a distinguishing version number.  If the
+Program specifies that a certain numbered version of the GNU General
+Public License "or any later version" applies to it, you have the
+option of following the terms and conditions either of that numbered
+version or of any later version published by the Free Software
+Foundation.  If the Program does not specify a version number of the
+GNU General Public License, you may choose any version ever published
+by the Free Software Foundation.
+
+  If the Program specifies that a proxy can decide which future
+versions of the GNU General Public License can be used, that proxy's
+public statement of acceptance of a version permanently authorizes you
+to choose that version for the Program.
+
+  Later license versions may give you additional or different
+permissions.  However, no additional obligations are imposed on any
+author or copyright holder as a result of your choosing to follow a
+later version.
+
+  15. Disclaimer of Warranty.
+
+  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
+APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
+IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. Limitation of Liability.
+
+  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGES.
+
+  17. Interpretation of Sections 15 and 16.
+
+  If the disclaimer of warranty and limitation of liability provided
+above cannot be given local legal effect according to their terms,
+reviewing courts shall apply local law that most closely approximates
+an absolute waiver of all civil liability in connection with the
+Program, unless a warranty or assumption of liability accompanies a
+copy of the Program in return for a fee.
+
+                     END OF TERMS AND CONDITIONS
+
+            How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+state the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+Also add information on how to contact you by electronic and paper mail.
+
+  If the program does terminal interaction, make it output a short
+notice like this when it starts in an interactive mode:
+
+    <program>  Copyright (C) <year>  <name of author>
+    This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, your program's commands
+might be different; for a GUI interface, you would use an "about box".
+
+  You should also get your employer (if you work as a programmer) or school,
+if any, to sign a "copyright disclaimer" for the program, if necessary.
+For more information on this, and how to apply and follow the GNU GPL, see
+<http://www.gnu.org/licenses/>.
+
+  The GNU General Public License does not permit incorporating your program
+into proprietary programs.  If your program is a subroutine library, you
+may consider it more useful to permit linking proprietary applications with
+the library.  If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.  But first, please read
+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..b7168e2
--- /dev/null
+++ b/README
@@ -0,0 +1,97 @@
+Dependencies
+============
+
+Anytun can be built by using either libgcrypt or the openssl-crypto library. 
+The latter is more performant in most cases but there are some license 
+issues when using this library.
+
+Linux
+-----
+
+using libgcrypt:
+  libgcrypt11-dev
+
+using ssl crypto lib:
+  libssl-dev
+
+common:
+  build-essential
+  libboost-serialization1.35-dev
+  libboost-thread1.35-dev
+  libboost-system1.35-dev
+  libboost-regex1.35-dev
+  asciidoc (only for manpage)
+
+
+Windows
+-------
+OpenSSL
+ Developer: 
+       http://www.slproweb.com/download/Win32OpenSSL-0_9_8j.exe
+
+ Runtime Only: 
+       http://www.slproweb.com/download/Win32OpenSSL_Light-0_9_8j.exe
+  
+Boost 1.35: 
+       http://www.boostpro.com/download/boost_1_35_0_setup.exe
+
+  As it can take some time to install everything from boost here is a 
+  complete list of libraries which have to be installed in order to build anytun:
+   
+   * Serialization
+   * Thread 
+   * date_time
+   * System
+   * regex
+
+Microsoft Visual C++ 2008 Redistributable Package (x86):
+       http://www.microsoft.com/downloads/details.aspx?familyid=9B2DA534-3E03-4391-8A4D-074B9F2BC1BF
+
+
+
+Installation
+============
+
+Getting the source via subversion:
+----------------------------------
+svn co http://anytun.org/svn/anytun/
+
+Building from source
+--------------------
+
+using libgcrypt:
+
+ # cd src
+ # ./configure
+ # make
+
+using ssl crypto library:
+
+ # cd src
+ # ./configure --use-ssl-crypto
+ # make
+
+
+Notes: 
+  - try './configure --help' for further information
+  - if using openssl pre 0.9.8 you have to disable passphrase
+    because openssl had no SHA256 implementation prior to this
+    version
+
+
+Errors:
+=======
+
+Note: Cannot open TUN/TAP dev /dev/net/tun: No such file or directory (errno=2)
+Cannot open TUN/TAP dev /dev/anytun0: No such file or directory (errno=2)
+
+Solution: Enabling tun/tap device
+------------------------------------
+
+modprobe tun
+cd /dev
+./MAKEDEV tun
+
+edit /etc/modules and add the line
+tun
+to load the module automatically
diff --git a/etc/anytun/autostart b/etc/anytun/autostart
new file mode 100644 (file)
index 0000000..328826b
--- /dev/null
@@ -0,0 +1,4 @@
+server
+#client1
+#client2
+#client3
diff --git a/etc/anytun/client1/config b/etc/anytun/client1/config
new file mode 100644 (file)
index 0000000..da11356
--- /dev/null
@@ -0,0 +1,94 @@
+#############################
+## Main options             #
+#############################
+
+role client
+
+## Client ID
+##  (has to be unique for each client)
+mux 1
+
+## device type tun = ip/ipv6, tap = ethernet
+type tun
+
+## payload encryption algorithm
+#cipher null
+#cipher aes-ctr-128
+#cipher aes-ctr-192
+#cipher aes-ctr-256
+cipher aes-ctr
+
+## message authentication algorithm
+#auth-algo null
+auth-algo sha1
+
+##message auth tag length
+#auth-tag-length 10
+
+## Passphrase
+## this is used to generate the crypto-key and salt
+## this should be al least 30 characters
+passphrase Creating_VPN_Tunnels_With_Anytun_Is_Easy
+
+## The remote host and port
+remote-host example.com
+remote-port 4444
+
+#############################
+## Debug options            #
+#############################
+
+## don't run in background
+#nodaemonize
+
+## additional log to standard output with a level of 5
+#log stdout:5
+
+
+#############################
+## Expert options           #
+#############################
+
+## log to syslog with a level of 3
+log syslog:3,anytun-client1,daemon
+
+## change user and group after init
+username anytun
+groupname anytun
+
+## chroot to users home directory
+#chroot /var/run/anytun
+
+## key derivation pseudo random function
+#kd-prf null
+#kd-prf aes-ctr
+#kd-prf aes-ctr-128
+#kd-prf aes-ctr-192
+#kd-prf aes-ctr-256
+
+## local ip address to bind to (for tunnel data)
+## (if you run an anycast cluster this has to be the anycast ip address)
+#interface <ip-address>
+
+## local port to bind to (for tunnel data)
+## make sure to use a different port for every server and client!
+port 4444
+
+## Device name
+#dev anytun0
+
+## Automaticaly configure the interface an set a route
+##
+## We highly recommend the use of the post up script to do this
+##
+## the address hast to be supplied in CIDR notation
+#ifconfig <local>/<prefix length>
+
+## Manually set encryption key and salt
+## (this replaces the passphrase)
+#key 0123456789ABCDEF0123456789ABCDEF
+#salt 0123456789ABCD0123456789ABCD
+
+## Setting a window size > 0 will enable replay protection
+## This most likely will only work with external rekeying
+#window-size 0
diff --git a/etc/anytun/client1/post-up.sh b/etc/anytun/client1/post-up.sh
new file mode 100755 (executable)
index 0000000..574a3e8
--- /dev/null
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+ip link set dev $1 up
+ip link set dev $1 mtu 1400
+ip addr add dev $1 192.168.123.1/24
+ip addr add dev $1 fec0::1/64
+
+# disable ICMP redirects as they don't work within the tunnel
+echo 0 > /proc/sys/net/ipv4/conf/$1/send_redirects
+echo 0 > /proc/sys/net/ipv4/conf/$1/accept_redirects
+
+exit 0
diff --git a/etc/anytun/client2/config b/etc/anytun/client2/config
new file mode 100644 (file)
index 0000000..ff9bab7
--- /dev/null
@@ -0,0 +1,94 @@
+#############################
+## Main options             #
+#############################
+
+role client
+
+## Client ID
+##  (has to be unique for each client)
+mux 2
+
+## device type tun = ip/ipv6, tap = ethernet
+type tun
+
+## payload encryption algorithm
+#cipher null
+#cipher aes-ctr-128
+#cipher aes-ctr-192
+#cipher aes-ctr-256
+cipher aes-ctr
+
+## message authentication algorithm
+#auth-algo null
+auth-algo sha1
+
+##message auth tag length
+#auth-tag-length 10
+
+## Passphrase
+## this is used to generate the crypto-key and salt
+## this should be al least 30 characters
+passphrase Creating_VPN_Tunnels_With_Anytun_Is_Easy
+
+## The remote host and port
+remote-host example.com
+remote-port 4444
+
+#############################
+## Debug options            #
+#############################
+
+## don't run in background
+#nodaemonize
+
+## additional log to standard output with a level of 5
+#log stdout:5
+
+
+#############################
+## Expert options           #
+#############################
+
+## log to syslog with a level of 3
+log syslog:3,anytun-client2,daemon
+
+## change user and group after init
+username anytun
+groupname anytun
+
+## chroot to users home directory
+#chroot /var/run/anytun
+
+## key derivation pseudo random function
+#kd-prf null
+#kd-prf aes-ctr
+#kd-prf aes-ctr-128
+#kd-prf aes-ctr-192
+#kd-prf aes-ctr-256
+
+## local ip address to bind to (for tunnel data)
+## (if you run an anycast cluster this has to be the anycast ip address)
+#interface <ip-address>
+
+## local port to bind to (for tunnel data)
+## make sure to use a different port for every server and client!
+port 4444
+
+## Device name
+#dev anytun0
+
+## Automaticaly configure the interface an set a route
+##
+## We highly recommend the use of the post up script to do this
+##
+## the address hast to be supplied in CIDR notation
+#ifconfig <local>/<prefix length>
+
+## Manually set encryption key and salt
+## (this replaces the passphrase)
+#key 2123456789ABCDEF0123456789ABCDEF
+#salt 2123456789ABCD0123456789ABCD
+
+## Setting a window size > 0 will enable replay protection
+## This most likely will only work with external rekeying
+#window-size 0
diff --git a/etc/anytun/client2/post-up.sh b/etc/anytun/client2/post-up.sh
new file mode 100755 (executable)
index 0000000..b65cb0b
--- /dev/null
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+ip link set dev $1 up
+ip link set dev $1 mtu 1400
+ip addr add dev $1 192.168.123.2/24
+ip addr add dev $1 fec0::2/64
+
+# disable ICMP redirects as they don't work within the tunnel
+echo 0 > /proc/sys/net/ipv4/conf/$1/send_redirects
+echo 0 > /proc/sys/net/ipv4/conf/$1/accept_redirects
+
+exit 0
diff --git a/etc/anytun/client3/config b/etc/anytun/client3/config
new file mode 100644 (file)
index 0000000..c5f529c
--- /dev/null
@@ -0,0 +1,94 @@
+#############################
+## Main options             #
+#############################
+
+role client
+
+## Client ID
+##  (has to be unique for each client)
+mux 3
+
+## device type tun = ip/ipv6, tap = ethernet
+type tun
+
+## payload encryption algorithm
+#cipher null
+#cipher aes-ctr-128
+#cipher aes-ctr-192
+#cipher aes-ctr-256
+cipher aes-ctr
+
+## message authentication algorithm
+#auth-algo null
+auth-algo sha1
+
+##message auth tag length
+#auth-tag-length 10
+
+## Passphrase
+## this is used to generate the crypto-key and salt
+## this should be al least 30 characters
+passphrase Creating_VPN_Tunnels_With_Anytun_Is_Easy
+
+## The remote host and port
+remote-host example.com
+remote-port 4444
+
+#############################
+## Debug options            #
+#############################
+
+## don't run in background
+#nodaemonize
+
+## additional log to standard output with a level of 5
+#log stdout:5
+
+
+#############################
+## Expert options           #
+#############################
+
+## log to syslog with a level of 3
+log syslog:3,anytun-client3,daemon
+
+## change user and group after init
+username anytun
+groupname anytun
+
+## chroot to users home directory
+#chroot /var/run/anytun
+
+## key derivation pseudo random function
+#kd-prf null
+#kd-prf aes-ctr
+#kd-prf aes-ctr-128
+#kd-prf aes-ctr-192
+#kd-prf aes-ctr-256
+
+## local ip address to bind to (for tunnel data)
+## (if you run an anycast cluster this has to be the anycast ip address)
+#interface <ip-address>
+
+## local port to bind to (for tunnel data)
+## make sure to use a different port for every server and client!
+port 4444
+
+## Device name
+#dev anytun0
+
+## Automaticaly configure the interface an set a route
+##
+## We highly recommend the use of the post up script to do this
+##
+## the address hast to be supplied in CIDR notation
+#ifconfig <local>/<prefix length>
+
+## Manually set encryption key and salt
+## (this replaces the passphrase)
+#key 3123456789ABCDEF0123456789ABCDEF
+#salt 3123456789ABCD0123456789ABCD
+
+## Setting a window size > 0 will enable replay protection
+## This most likely will only work with external rekeying
+#window-size 0
diff --git a/etc/anytun/client3/post-up.sh b/etc/anytun/client3/post-up.sh
new file mode 100755 (executable)
index 0000000..4245ff4
--- /dev/null
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+ip link set dev $1 up
+ip link set dev $1 mtu 1400
+ip addr add dev $1 192.168.123.3/24
+ip addr add dev $1 fec0::3/64
+
+# disable ICMP redirects as they don't work within the tunnel
+echo 0 > /proc/sys/net/ipv4/conf/$1/send_redirects
+echo 0 > /proc/sys/net/ipv4/conf/$1/accept_redirects
+
+exit 0
diff --git a/etc/anytun/p2p-a/config b/etc/anytun/p2p-a/config
new file mode 100644 (file)
index 0000000..126f918
--- /dev/null
@@ -0,0 +1,87 @@
+#############################
+## Main options             #
+#############################
+
+role alice
+
+## device type tun = ip/ipv6, tap = ethernet
+type tun
+
+## Automaticaly configure the interface
+## the address hast to be supplied in CIDR notation
+ifconfig 192.168.223.1/30
+
+## payload encryption algorithm
+#cipher null
+#cipher aes-ctr-128
+#cipher aes-ctr-192
+#cipher aes-ctr-256
+cipher aes-ctr
+
+## message authentication algorithm
+#auth-algo null
+auth-algo sha1
+
+##message auth tag length
+#auth-tag-length 10
+
+## Passphrase
+## this is used to generate the crypto-key and salt
+## this should be al least 30 characters
+passphrase Creating_P2P_VPN_Tunnels_With_Anytun_Is_Easy
+
+## local ip address to bind to (for tunnel data)
+## (if you run an anycast cluster this has to be the anycast ip address)
+#interface <ip-address>
+
+## local port to bind to (for tunnel data)
+## make sure to use a different port for every server and client!
+port 4445
+
+## The remote host and port
+remote-host p2p-b.example.com
+remote-port 4445
+
+#############################
+## Debug options            #
+#############################
+
+## don't run in background
+#nodaemonize
+
+## additional log to standard output with a level of 5
+#log stdout:5
+
+
+#############################
+## Expert options           #
+#############################
+
+## log to syslog with a level of 3
+log syslog:3,anytun-p2p-a,daemon
+
+## change user and group after init
+username anytun
+groupname anytun
+
+## chroot to users home directory
+#chroot /var/run/anytun
+
+## key derivation pseudo random function
+#kd-prf null
+#kd-prf aes-ctr
+#kd-prf aes-ctr-128
+#kd-prf aes-ctr-192
+#kd-prf aes-ctr-256
+
+## Device name
+#dev uanytun0
+
+## Manually set encryption key and salt
+## (this replaces the passphrase)
+#key 0123456789ABCDEF0123456789ABCDEF
+#salt 0123456789ABCD0123456789ABCD
+
+## Setting a window size > 0 will enable replay protection
+## This most likely will only work with external rekeying
+#window-size 0
diff --git a/etc/anytun/p2p-b/config b/etc/anytun/p2p-b/config
new file mode 100644 (file)
index 0000000..859b26d
--- /dev/null
@@ -0,0 +1,87 @@
+#############################
+## Main options             #
+#############################
+
+role bob
+
+## device type tun = ip/ipv6, tap = ethernet
+type tun
+
+## Automaticaly configure the interface
+## the address hast to be supplied in CIDR notation
+ifconfig 192.168.223.2/30
+
+## payload encryption algorithm
+#cipher null
+#cipher aes-ctr-128
+#cipher aes-ctr-192
+#cipher aes-ctr-256
+cipher aes-ctr
+
+## message authentication algorithm
+#auth-algo null
+auth-algo sha1
+
+##message auth tag length
+#auth-tag-length 10
+
+## Passphrase
+## this is used to generate the crypto-key and salt
+## this should be al least 30 characters
+passphrase Creating_P2P_VPN_Tunnels_With_Anytun_Is_Easy
+
+## local ip address to bind to (for tunnel data)
+## (if you run an anycast cluster this has to be the anycast ip address)
+#interface <ip-address>
+
+## local port to bind to (for tunnel data)
+## make sure to use a different port for every server and client!
+port 4445
+
+## The remote host and port
+remote-host p2p-a.example.com
+remote-port 4445
+
+#############################
+## Debug options            #
+#############################
+
+## don't run in background
+#nodaemonize
+
+## additional log to standard output with a level of 5
+#log stdout:5
+
+
+#############################
+## Expert options           #
+#############################
+
+## log to syslog with a level of 3
+log syslog:3,anytun-p2p-b,daemon
+
+## change user and group after init
+username anytun
+groupname anytun
+
+## chroot to users home directory
+#chroot /var/run/anytun
+
+## key derivation pseudo random function
+#kd-prf null
+#kd-prf aes-ctr
+#kd-prf aes-ctr-128
+#kd-prf aes-ctr-192
+#kd-prf aes-ctr-256
+
+## Device name
+#dev uanytun0
+
+## Manually set encryption key and salt
+## (this replaces the passphrase)
+#key 0123456789ABCDEF0123456789ABCDEF
+#salt 0123456789ABCD0123456789ABCD
+
+## Setting a window size > 0 will enable replay protection
+## This most likely will only work with external rekeying
+#window-size 0
diff --git a/etc/anytun/server/conf.d/client1 b/etc/anytun/server/conf.d/client1
new file mode 100644 (file)
index 0000000..5099cef
--- /dev/null
@@ -0,0 +1,48 @@
+#############################
+## main options             #
+#############################
+
+role server
+
+## Client ID
+##  (has to be unique for each client)
+mux 1
+
+## Passphrase
+## this is used to generate the crypto-key and salt
+## this should be al least 30 characters
+passphrase Creating_VPN_Tunnels_With_Anytun_Is_Easy
+
+## staticially configure client address
+## (autodetect if skiped)
+#remote-host <hostname|ip>
+#remote-port 4444
+
+#############################
+## routing options          #
+#############################
+
+## Internal Routing entries
+## multiple routes allowed
+## make sure to also set a system route in the post-up script
+route 192.168.123.1/32
+route fec0::1/128
+
+## Add a subnet route
+## make sure to also set a system route in the post-up script
+#route 192.168.11.0/24
+#route fec0:1::/48
+
+
+#############################
+## Expert options           #
+#############################
+
+## Manually set encryption key and salt
+## (this replaces the passphrase)
+#key 0123456789ABCDEF0123456789ABCDEF
+#salt 0123456789ABCD0123456789ABCD
+
+## Setting a window size > 0 will enable replay protection
+## This most likely will only work with external rekeying
+#window-size 0
diff --git a/etc/anytun/server/conf.d/client2 b/etc/anytun/server/conf.d/client2
new file mode 100644 (file)
index 0000000..e0b05d2
--- /dev/null
@@ -0,0 +1,48 @@
+#############################
+## main options             #
+#############################
+
+role server
+
+## Client ID
+##  (has to be unique for each client)
+mux 2
+
+## Passphrase
+## this is used to generate the crypto-key and salt
+## this should be al least 30 characters
+passphrase Creating_VPN_Tunnels_With_Anytun_Is_Easy
+
+## staticially configure client address
+## (autodetect if skiped)
+#remote-host <hostname|ip>
+#remote-port 4444
+
+#############################
+## routing options          #
+#############################
+
+## Internal Routing entries
+## multiple routes allowed
+## make sure to also set a system route in the post-up script
+route 192.168.123.2/32
+route fec0::2/128
+
+## Add a subnet route
+## make sure to also set a system route in the post-up script
+#route 192.168.12.0/24
+#route fec0:2::/48
+
+
+#############################
+## Expert options           #
+#############################
+
+## Manually set encryption key and salt
+## (this replaces the passphrase)
+#key 2123456789ABCDEF0123456789ABCDEF
+#salt 2123456789ABCD0123456789ABCD
+
+## Setting a window size > 0 will enable replay protection
+## This most likely will only work with external rekeying
+#window-size 0
diff --git a/etc/anytun/server/conf.d/client3 b/etc/anytun/server/conf.d/client3
new file mode 100644 (file)
index 0000000..8f22de0
--- /dev/null
@@ -0,0 +1,48 @@
+#############################
+## main options             #
+#############################
+
+role server
+
+## Client ID
+##  (has to be unique for each client)
+mux 3
+
+## Passphrase
+## this is used to generate the crypto-key and salt
+## this should be al least 30 characters
+passphrase Creating_VPN_Tunnels_With_Anytun_Is_Easy
+
+## staticially configure client address
+## (autodetect if skiped)
+#remote-host <hostname|ip>
+#remote-port 4444
+
+#############################
+## routing options          #
+#############################
+
+## Internal Routing entries
+## multiple routes allowed
+## make sure to also set a system route in the post-up script
+route 192.168.123.3/32
+route fec0::3/128
+
+## Add a subnet route
+## make sure to also set a system route in the post-up script
+#route 192.168.13.0/24
+#route fec0:3::/48
+
+
+#############################
+## Expert options           #
+#############################
+
+## Manually set encryption key and salt
+## (this replaces the passphrase)
+#key 3123456789ABCDEF0123456789ABCDEF
+#salt 3123456789ABCD0123456789ABCD
+
+## Setting a window size > 0 will enable replay protection
+## This most likely will only work with external rekeying
+#window-size 0
diff --git a/etc/anytun/server/config b/etc/anytun/server/config
new file mode 100644 (file)
index 0000000..8488923
--- /dev/null
@@ -0,0 +1,95 @@
+#############################
+## multi connection support #
+#############################
+
+## control host for multi-client support
+## This enables multi-connection support and splits configuration files per client
+## Make sure to use a unique port for each server, when runnig multiple servers
+control-host 127.0.0.1:4444
+
+#############################
+## Main options             #
+#############################
+
+## device type tun = ip/ipv6, tap = ethernet
+type tun
+
+## payload encryption algorithm
+#cipher null
+#cipher aes-ctr-128
+#cipher aes-ctr-192
+#cipher aes-ctr-256
+cipher aes-ctr
+
+## message authentication algorithm
+#auth-algo null
+auth-algo sha1
+
+##message auth tag length
+#auth-tag-length 10
+
+## local ip address to bind to (for tunnel data)
+## (if you run an anycast cluster this has to be the anycast ip address)
+#interface <ip-address>
+
+## local port to bind to (for tunnel data)
+## make sure to use a different port for every server and client!
+port 4444
+
+#############################
+## Debug options            #
+#############################
+
+## don't run in background
+#nodaemonize
+
+## additional log to standard output with a level of 5
+#log stdout:5
+
+
+#############################
+## Expert options           #
+#############################
+
+## log to syslog with a level of 3
+log syslog:3,anytun-server,daemon
+
+## change user and group after init
+username nobody
+groupname nogroup
+
+## chroot to /var/run/anytun
+#chroot /var/run/anytun
+
+## key derivation pseudo random function
+#kd-prf null
+#kd-prf aes-ctr
+#kd-prf aes-ctr-128
+#kd-prf aes-ctr-192
+#kd-prf aes-ctr-256
+
+## Device name
+#dev anytun0
+
+## Automaticaly configure the interface an set a route
+##
+## We highly recommend the use of the post up script to do this
+##
+## the address hast to be supplied in CIDR notation
+#ifconfig <local>/<prefix length>
+
+#############################
+## Cluster options          #
+#############################
+
+## the sender id to use (has to be unique for multiple anycast servers)
+#sender-id 1
+
+## local unicast(sync) ip address to bind to
+#sync-interface <ip-address>
+
+## local unicast(sync) port to bind to
+#sync-port 1234
+
+## remote hosts to sync with
+#sync-hosts <hostname|ip>:<port>[,<hostname|ip>:<port>[...]]
diff --git a/etc/anytun/server/post-up.sh b/etc/anytun/server/post-up.sh
new file mode 100755 (executable)
index 0000000..9d585a1
--- /dev/null
@@ -0,0 +1,30 @@
+#!/bin/sh
+ip link set dev $1 up
+ip link set mtu 1400 dev $1
+
+# add tunnel addresses
+ip addr add 192.168.123.254/24 dev $1
+ip addr add fec0::fd/64 dev $1
+
+# add routes to client subnets
+# you also have to add these routes to the client configuration file of each client
+# ip route add 192.168.11.0/24 dev $1
+# ip route add fec0:1::/48 dev $1
+# ip route add 192.168.12.0/24 dev $1
+# ip route add fec0:2::/48 dev $1
+# ip route add 192.168.13.0/24 dev $1
+# ip route add fec0:3::/48 dev $1
+
+# disable ICMP redirects as they don't work within the tunnel
+echo 0 > /proc/sys/net/ipv4/conf/$1/send_redirects
+echo 0 > /proc/sys/net/ipv4/conf/$1/accept_redirects
+
+# enable packet forwarding
+echo 1 > /proc/sys/net/ipv6/conf/$1/forwarding
+echo 1 > /proc/sys/net/ipv4/conf/$1/forwarding
+
+# enable routing to local ethernet interface
+# echo 1 > /proc/sys/net/ipv6/conf/eth0/forwarding
+# echo 1 > /proc/sys/net/ipv4/conf/eth0/forwarding
+
+exit 0
diff --git a/etc/init.d/anytun b/etc/init.d/anytun
new file mode 100755 (executable)
index 0000000..d0299d4
--- /dev/null
@@ -0,0 +1,204 @@
+#! /bin/sh
+### BEGIN INIT INFO
+# Provides:          anytun
+# Required-Start:    $network $named $syslog
+# Required-Stop:     
+# Default-Start:     2 3 4 5
+# Default-Stop:      0 1 6
+# Short-Description: Start anycast tunneling daemon at boot time
+# Description:       Enables networking over vpn tunnel interfaces
+### END INIT INFO
+PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
+DAEMON=/usr/sbin/anytun
+ANYTUNCONFIG=/usr/bin/anytun-config
+CONTROLDAEMON=/usr/bin/anytun-controld
+NAME=anytun
+DESC=anytun
+CONFIG_DIR=/etc/anytun
+VARCONFIG_DIR=/var/run/anytun-controld
+
+test -x $DAEMON || exit 0
+
+# Include anytun defaults if available
+if [ -f /etc/default/anytun ] ; then
+  . /etc/default/anytun
+fi
+
+start_vpn () {
+  STATUS="OK"
+  if [ -f $CONFIG_DIR/$NAME/config ] ; then
+    POSTUP=''
+    test -f  $CONFIG_DIR/$NAME/post-up.sh && POSTUP="-x $CONFIG_DIR/$NAME/post-up.sh"
+    CHROOTDIR=`grep '^chroot' < $CONFIG_DIR/$NAME/config | sed 's/chroot\s*//'`
+    if [ -n "$CHROOTDIR" ] ; then
+      test -d $CHROOTDIR || mkdir -p $CHROOTDIR
+    fi
+    DAEMONARG=`sed 's/#.*//' < $CONFIG_DIR/$NAME/config | grep -e '\w' | sed  's/^/--/' | tr '\n' ' '`
+    $DAEMON --write-pid /var/run/anytun.$NAME.pid $POSTUP \
+      $DAEMONOPTS $DAEMONARG || STATUS="FAILED"
+  else
+    STATUS="no config found"
+  fi
+  start_configd
+  echo -n "($STATUS)"
+}
+stop_vpn () {
+  kill `cat $PIDFILE` || true
+  rm $PIDFILE
+  stop_configd
+}
+
+start_configd () {
+  if [ -d $CONFIG_DIR/$NAME/conf.d ] ; then
+    test -d $VARCONFIG_DIR || mkdir -p $VARCONFIG_DIR
+    chmod 700 $VARCONFIG_DIR
+    rm -f $VARCONFIG_DIR/$NAME 2>/dev/null
+    for CLIENTNAME in `ls $CONFIG_DIR/$NAME/conf.d`; do
+      echo -n " ($CLIENTNAME)"
+      DAEMONARG=`sed 's/#.*//'  <  $CONFIG_DIR/$NAME/conf.d/$CLIENTNAME | grep -e '\w' | sed  's/^/ --/' | xargs echo`
+      $ANYTUNCONFIG $DAEMONARG >> $VARCONFIG_DIR/$NAME
+    done
+    CONTROLHOST=`sed 's/#.*//'  <  $CONFIG_DIR/$NAME/config | grep -e 'control-host' | sed  's/^/ --/'`
+    $CONTROLDAEMON -f $VARCONFIG_DIR/$NAME $DAEMONOPTS $CONTROLHOST \
+      --write-pid $VARCONFIG_DIR/$NAME.pid
+    # rm -f $VARCONFIG_DIR/$NAME
+  fi
+}
+stop_configd () {
+  if [ -d $CONFIG_DIR/$NAME/conf.d ] ; then
+    echo -n " ($NAME)"
+    kill `cat $VARCONFIG_DIR/$NAME.pid` || true
+    rm $VARCONFIG_DIR/$NAME.pid
+  fi 
+}
+
+set -e
+case "$1" in
+  start)
+  echo -n "Starting $DESC:"
+  if test -z "$2" ; then
+    if [ -f $CONFIG_DIR/autostart ] ; then
+      for NAME in `sed 's/#.*//'  <  $CONFIG_DIR/autostart | grep -e '\w'`; do
+        echo -n " $NAME"
+        start_vpn
+      done
+    else
+      echo "no config found"
+      exit 1;
+    fi
+  else
+    while shift ; do
+      [ -z "$1" ] && break
+      NAME=$1
+      echo -n " $NAME"
+      start_vpn
+    done
+  fi
+  echo "."
+  ;;
+  stop)
+  echo -n "Stoping $DESC:"
+  if test -z "$2" ; then
+    for PIDFILE in `ls /var/run/anytun.*.pid 2> /dev/null`; do
+      NAME=`echo $PIDFILE | cut -c17-`
+      NAME=${NAME%%.pid}
+      echo -n " $NAME"
+      stop_vpn
+    done
+  else
+    while shift ; do
+      [ -z "$1" ] && break
+      if test -e /var/run/anytun.$1.pid ; then
+        PIDFILE=`ls /var/run/anytun.$1.pid 2> /dev/null`
+        NAME=`echo $PIDFILE | cut -c17-`
+        NAME=${NAME%%.pid}
+        echo -n " $NAME"
+        stop_vpn
+      else
+        echo -n " (failure: No such tunnel is running: $1)"
+      fi
+    done
+  fi
+  echo "."
+  ;;
+  reload)
+  echo -n "Reloading $DESC:"
+  if test -z "$2" ; then
+    for PIDFILE in `ls /var/run/anytun.*.pid 2> /dev/null`; do
+      NAME=`echo $PIDFILE | cut -c17-`
+      NAME=${NAME%%.pid}
+      echo -n " $NAME"
+      if [ -d $CONFIG_DIR/$NAME/conf.d ] ; then
+        stop_vpn
+        start_vpn
+      else
+        stop_configd
+        start_configd
+      fi
+    done
+  else
+    while shift ; do
+      [ -z "$1" ] && break
+      if test -e /var/run/anytun.$1.pid ; then
+        PIDFILE=`ls /var/run/anytun.$1.pid 2> /dev/null`
+        NAME=`echo $PIDFILE | cut -c17-`
+        NAME=${NAME%%.pid}
+        echo -n " $NAME"
+        if [ -d $CONFIG_DIR/$NAME/conf.d ] ; then
+          stop_vpn
+          start_vpn
+        else
+          stop_configd
+          start_configd
+        fi
+      else
+        echo -n " (failure: No such tunnel is running: $1)"
+      fi
+    done
+  fi
+  echo "."
+  ;;
+  force-reload)
+  echo -n "Restarting $DESC:"
+  if test -z "$2" ; then
+    for PIDFILE in `ls /var/run/anytun.*.pid 2> /dev/null`; do
+      NAME=`echo $PIDFILE | cut -c17-`
+      NAME=${NAME%%.pid}
+      echo -n " $NAME"
+      stop_vpn
+      sleep 1
+      start_vpn
+    done
+  else
+    while shift ; do
+      [ -z "$1" ] && break
+      if test -e /var/run/anytun.$1.pid ; then
+        PIDFILE=`ls /var/run/anytun.$1.pid 2> /dev/null`
+        NAME=`echo $PIDFILE | cut -c17-`
+        NAME=${NAME%%.pid}
+        echo -n " $NAME"
+        stop_vpn
+        sleep 1
+        start_vpn
+      else
+        echo -n " (failure: No such tunnel is running: $1)"
+      fi
+    done
+  fi
+  echo "."
+  ;;
+  restart)
+    SCRIPT=$0
+    shift
+    $SCRIPT stop $*
+    sleep 1
+    $SCRIPT start $*
+  ;;
+  *)
+  N=/etc/init.d/$NAME
+  echo "Usage: $N {start|stop|restart|reload|force-reload}" >&2
+  exit 1
+  ;;
+esac
+
+exit 0
diff --git a/src/Doxyfile b/src/Doxyfile
new file mode 100644 (file)
index 0000000..9b5e4ef
--- /dev/null
@@ -0,0 +1,1252 @@
+# Doxyfile 1.5.1
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+#       TAG = value [value, ...]
+# For lists items can also be appended using:
+#       TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded 
+# by quotes) that should identify the project.
+
+PROJECT_NAME           = "anytun"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. 
+# This could be handy for archiving the generated documentation or 
+# if some version control system is used.
+
+PROJECT_NUMBER         = 
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) 
+# base path where the generated documentation will be put. 
+# If a relative path is entered, it will be relative to the location 
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = ./doc
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 
+# 4096 sub-directories (in 2 levels) under the output directory of each output 
+# format and will distribute the generated files over these directories. 
+# Enabling this option can be useful when feeding doxygen a huge amount of 
+# source files, where putting all generated files in the same directory would 
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS         = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all 
+# documentation generated by doxygen is written. Doxygen will use this 
+# information to generate all constant output in the proper language. 
+# The default language is English, other supported languages are: 
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, 
+# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, 
+# Italian, Japanese, Japanese-en (Japanese with English messages), Korean, 
+# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, 
+# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE        = English
+
+# This tag can be used to specify the encoding used in the generated output. 
+# The encoding is not always determined by the language that is chosen, 
+# but also whether or not the output is meant for Windows or non-Windows users. 
+# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES 
+# forces the Windows encoding (this is the default for the Windows binary), 
+# whereas setting the tag to NO uses a Unix-style encoding (the default for 
+# all platforms other than Windows).
+
+USE_WINDOWS_ENCODING   = NO
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will 
+# include brief member descriptions after the members that are listed in 
+# the file and class documentation (similar to JavaDoc). 
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend 
+# the brief description of a member or function before the detailed description. 
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the 
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator 
+# that is used to form the text in various listings. Each string 
+# in this list, if found as the leading text of the brief description, will be 
+# stripped from the text and the result after processing the whole list, is 
+# used as the annotated text. Otherwise, the brief description is used as-is. 
+# If left blank, the following values are used ("$name" is automatically 
+# replaced with the name of the entity): "The $name class" "The $name widget" 
+# "The $name file" "is" "provides" "specifies" "contains" 
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF       = 
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then 
+# Doxygen will generate a detailed section even if there is only a brief 
+# description.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all 
+# inherited members of a class in the documentation of that class as if those 
+# members were ordinary class members. Constructors, destructors and assignment 
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full 
+# path before files name in the file list and in the header files. If set 
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES        = YES
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag 
+# can be used to strip a user-defined part of the path. Stripping is 
+# only done if one of the specified strings matches the left-hand part of 
+# the path. The tag can be used to show relative paths in the file list. 
+# If left blank the directory from which doxygen is run is used as the 
+# path to strip.
+
+STRIP_FROM_PATH        = 
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of 
+# the path mentioned in the documentation of a class, which tells 
+# the reader which header file to include in order to use a class. 
+# If left blank only the name of the header file containing the class 
+# definition is used. Otherwise one should specify the include paths that 
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH    = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter 
+# (but less readable) file names. This can be useful is your file systems 
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen 
+# will interpret the first line (until the first dot) of a JavaDoc-style 
+# comment as the brief description. If set to NO, the JavaDoc 
+# comments will behave just like the Qt-style comments (thus requiring an 
+# explicit @brief command for a brief description.
+
+JAVADOC_AUTOBRIEF      = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen 
+# treat a multi-line C++ special comment block (i.e. a block of //! or /// 
+# comments) as a brief description. This used to be the default behaviour. 
+# The new default is to treat a multi-line C++ comment block as a detailed 
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen 
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member 
+# documentation.
+
+DETAILS_AT_TOP         = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented 
+# member inherits the documentation from any documented member that it 
+# re-implements.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce 
+# a new page for each member. If set to NO, the documentation of a member will 
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. 
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE               = 8
+
+# This tag can be used to specify a number of aliases that acts 
+# as commands in the documentation. An alias has the form "name=value". 
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to 
+# put the command \sideeffect (or @sideeffect) in the documentation, which 
+# will result in a user-defined paragraph with heading "Side Effects:". 
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES                = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 
+# sources only. Doxygen will then generate output that is more tailored for C. 
+# For instance, some of the names that are used will be different. The list 
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C  = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java 
+# sources only. Doxygen will then generate output that is more tailored for Java. 
+# For instance, namespaces will be presented as packages, qualified scopes 
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to 
+# include (a tag file for) the STL sources as input, then you should 
+# set this tag to YES in order to let doxygen match functions declarations and 
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. 
+# func(std::string) {}). This also make the inheritance and collaboration 
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC 
+# tag is set to YES, then doxygen will reuse the documentation of the first 
+# member in the group (if any) for the other members of the group. By default 
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of 
+# the same type (for instance a group of public functions) to be put as a 
+# subgroup of that type (e.g. under the Public Functions section). Set it to 
+# NO to prevent subgrouping. Alternatively, this can be done per class using 
+# the \nosubgrouping command.
+
+SUBGROUPING            = YES
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in 
+# documentation are documented, even if no documentation was available. 
+# Private class members and static file members will be hidden unless 
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL            = YES
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class 
+# will be included in the documentation.
+
+EXTRACT_PRIVATE        = YES
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file 
+# will be included in the documentation.
+
+EXTRACT_STATIC         = YES
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) 
+# defined locally in source files will be included in the documentation. 
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. When set to YES local 
+# methods, which are defined in the implementation section but not in 
+# the interface are included in the documentation. 
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all 
+# undocumented members of documented classes, files or namespaces. 
+# If set to NO (the default) these members will be included in the 
+# various overviews, but no documentation section is generated. 
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all 
+# undocumented classes that are normally visible in the class hierarchy. 
+# If set to NO (the default) these classes will be included in the various 
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all 
+# friend (class|struct|union) declarations. 
+# If set to NO (the default) these declarations will be included in the 
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any 
+# documentation blocks found inside the body of a function. 
+# If set to NO (the default) these blocks will be appended to the 
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation 
+# that is typed after a \internal command is included. If the tag is set 
+# to NO (the default) then the documentation will be excluded. 
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate 
+# file names in lower-case letters. If set to YES upper-case letters are also 
+# allowed. This is useful if you have classes or files whose names only differ 
+# in case and if your file system supports case sensitive file names. Windows 
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES       = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen 
+# will show members with their full class and namespace scopes in the 
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES       = NO
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen 
+# will put a list of the files that are included by a file in the documentation 
+# of that file.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] 
+# is inserted in the documentation for inline members.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen 
+# will sort the (detailed) documentation of file and class members 
+# alphabetically by member name. If set to NO the members will appear in 
+# declaration order.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the 
+# brief documentation of file, namespace and class members alphabetically 
+# by member name. If set to NO (the default) the members will appear in 
+# declaration order.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be 
+# sorted by fully-qualified names, including namespaces. If set to 
+# NO (the default), the class list will be sorted only by class name, 
+# not including the namespace part. 
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the 
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or 
+# disable (NO) the todo list. This list is created by putting \todo 
+# commands in the documentation.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or 
+# disable (NO) the test list. This list is created by putting \test 
+# commands in the documentation.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or 
+# disable (NO) the bug list. This list is created by putting \bug 
+# commands in the documentation.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or 
+# disable (NO) the deprecated list. This list is created by putting 
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional 
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines 
+# the initial value of a variable or define consists of for it to appear in 
+# the documentation. If the initializer consists of more lines than specified 
+# here it will be hidden. Use a value of 0 to hide initializers completely. 
+# The appearance of the initializer of individual variables and defines in the 
+# documentation can be controlled using \showinitializer or \hideinitializer 
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated 
+# at the bottom of the documentation of classes and structs. If set to YES the 
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES        = YES
+
+# If the sources in your project are distributed over multiple directories 
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy 
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES       = NO
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that 
+# doxygen should invoke to get the current version for each file (typically from the 
+# version control system). Doxygen will invoke the program by executing (via 
+# popen()) the command <command> <input-file>, where <command> is the value of 
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file 
+# provided by doxygen. Whatever the program writes to standard output 
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated 
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are 
+# generated by doxygen. Possible values are YES and NO. If left blank 
+# NO is used.
+
+WARNINGS               = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings 
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will 
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for 
+# potential errors in the documentation, such as not documenting some 
+# parameters in a documented function, or documenting parameters that 
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for 
+# functions that are documented, but have no documentation for their parameters 
+# or return value. If set to NO (the default) doxygen will only warn about 
+# wrong or incomplete parameter documentation, but not about the absence of 
+# documentation.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that 
+# doxygen can produce. The string should contain the $file, $line, and $text 
+# tags, which will be replaced by the file and line number from which the 
+# warning originated and the warning text. Optionally the format may contain 
+# $version, which will be replaced by the version of the file (if it could 
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning 
+# and error messages should be written. If left blank the output is written 
+# to stderr.
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain 
+# documented source files. You may enter file names like "myfile.cpp" or 
+# directories like "/usr/src/myproject". Separate the files or directories 
+# with spaces.
+
+INPUT                  = 
+
+# If the value of the INPUT tag contains directories, you can use the 
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank the following patterns are tested: 
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx 
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py
+
+FILE_PATTERNS          = 
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories 
+# should be searched for input files as well. Possible values are YES and NO. 
+# If left blank NO is used.
+
+RECURSIVE              = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should 
+# excluded from the INPUT source files. This way you can easily exclude a 
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE                = 
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or 
+# directories that are symbolic links (a Unix filesystem feature) are excluded 
+# from the input.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the 
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude 
+# certain files from those directories. Note that the wildcards are matched 
+# against the file with absolute path, so to exclude all test directories 
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or 
+# directories that contain example code fragments that are included (see 
+# the \include command).
+
+EXAMPLE_PATH           = 
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the 
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp 
+# and *.h) to filter out the source-files in the directories. If left 
+# blank all files are included.
+
+EXAMPLE_PATTERNS       = 
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be 
+# searched for input files to be used with the \include or \dontinclude 
+# commands irrespective of the value of the RECURSIVE tag. 
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or 
+# directories that contain image that are included in the documentation (see 
+# the \image command).
+
+IMAGE_PATH             = 
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should 
+# invoke to filter for each input file. Doxygen will invoke the filter program 
+# by executing (via popen()) the command <filter> <input-file>, where <filter> 
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an 
+# input file. Doxygen will then use the output that the filter program writes 
+# to standard output.  If FILTER_PATTERNS is specified, this tag will be 
+# ignored.
+
+INPUT_FILTER           = 
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern 
+# basis.  Doxygen will compare the file name with each pattern and apply the 
+# filter if there is a match.  The filters are a list of the form: 
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further 
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER 
+# is applied to all files.
+
+FILTER_PATTERNS        = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using 
+# INPUT_FILTER) will be used to filter the input files when producing source 
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES    = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will 
+# be generated. Documented entities will be cross-referenced with these sources. 
+# Note: To get rid of all source code in the generated output, make sure also 
+# VERBATIM_HEADERS is set to NO.
+
+SOURCE_BROWSER         = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body 
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct 
+# doxygen to hide any special comment blocks from generated source code 
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default) 
+# then for each documented function all documented 
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default) 
+# then for each documented function all documented entities 
+# called/used by that function will be listed.
+
+REFERENCES_RELATION    = YES
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code.  Otherwise they will link to the documentstion.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code 
+# will point to the HTML generated by the htags(1) tool instead of doxygen 
+# built-in source browser. The htags tool is part of GNU's global source 
+# tagging system (see http://www.gnu.org/software/global/global.html). You 
+# will need version 4.8.6 or higher.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen 
+# will generate a verbatim copy of the header file for each class for 
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS       = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index 
+# of all compounds will be generated. Enable this if the project 
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX     = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then 
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns 
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all 
+# classes will be put under the same header in the alphabetical index. 
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that 
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will 
+# generate HTML output.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for 
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank 
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard header.
+
+HTML_HEADER            = 
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for 
+# each generated HTML page. If it is left blank doxygen will generate a 
+# standard footer.
+
+HTML_FOOTER            = 
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading 
+# style sheet that is used by each HTML page. It can be used to 
+# fine-tune the look of the HTML output. If the tag is left blank doxygen 
+# will generate a default style sheet. Note that doxygen will try to copy 
+# the style sheet file to the HTML output directory, so don't put your own 
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET        = 
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, 
+# files or namespaces will be aligned in HTML using tables. If set to 
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS     = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files 
+# will be generated that can be used as input for tools like the 
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) 
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP      = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can 
+# be used to specify the file name of the resulting .chm file. You 
+# can add a path in front of the file if the result should not be 
+# written to the html output directory.
+
+CHM_FILE               = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can 
+# be used to specify the location (absolute path including file name) of 
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run 
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION           = 
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag 
+# controls if a separate .chi index file is generated (YES) or that 
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI           = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag 
+# controls whether a binary table of contents is generated (YES) or a 
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members 
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND             = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at 
+# top of each HTML page. The value NO (the default) enables the index and 
+# the value YES disables it.
+
+DISABLE_INDEX          = NO
+
+# This tag can be used to set the number of enum values (range [1..20]) 
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that 
+# is generated for HTML Help). For this to work a browser that supports 
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, 
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are 
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW      = YES
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be 
+# used to set the initial width (in pixels) of the frame in which the tree 
+# is shown.
+
+TREEVIEW_WIDTH         = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will 
+# generate Latex output.
+
+GENERATE_LATEX         = YES
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be 
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to 
+# generate index for LaTeX. If left blank `makeindex' will be used as the 
+# default command name.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact 
+# LaTeX documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used 
+# by the printer. Possible values are: a4, a4wide, letter, legal and 
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE             = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX 
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for 
+# the generated latex document. The header should contain everything until 
+# the first chapter. If it is left blank doxygen will generate a 
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER           = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated 
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will 
+# contain links (just like the HTML output) instead of page references 
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS         = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of 
+# plain latex in the generated Makefile. Set this option to YES to get a 
+# higher quality PDF documentation.
+
+USE_PDFLATEX           = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. 
+# command to the generated LaTeX files. This will instruct LaTeX to keep 
+# running if errors occur, instead of asking the user for help. 
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE        = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not 
+# include the index chapters (such as File Index, Compound Index, etc.) 
+# in the output.
+
+LATEX_HIDE_INDICES     = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output 
+# The RTF output is optimized for Word 97 and may not look very pretty with 
+# other RTF readers or editors.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact 
+# RTF documents. This may be useful for small projects and may help to 
+# save some trees in general.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated 
+# will contain hyperlink fields. The RTF file will 
+# contain links (just like the HTML output) instead of page references. 
+# This makes the output suitable for online browsing using WORD or other 
+# programs which support those fields. 
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's 
+# config file, i.e. a series of assignments. You only have to provide 
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an rtf document. 
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will 
+# generate man pages
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to 
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION          = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output, 
+# then it will generate one additional man file for each entity 
+# documented in the real man page(s). These additional files 
+# only source the real man page, but without them the man command 
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will 
+# generate an XML file that captures the structure of 
+# the code including all documentation.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. 
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be 
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT             = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_SCHEMA             = 
+
+# The XML_DTD tag can be used to specify an XML DTD, 
+# which can be used by a validating XML parser to check the 
+# syntax of the XML files.
+
+XML_DTD                = 
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will 
+# dump the program listings (including syntax highlighting 
+# and cross-referencing information) to the XML output. Note that 
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will 
+# generate an AutoGen Definitions (see autogen.sf.net) file 
+# that captures the structure of the code including all 
+# documentation. Note that this feature is still experimental 
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will 
+# generate a Perl module file that captures the structure of 
+# the code including all documentation. Note that this 
+# feature is still experimental and incomplete at the 
+# moment.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate 
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able 
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be 
+# nicely formatted so it can be parsed by a human reader.  This is useful 
+# if you want to understand what is going on.  On the other hand, if this 
+# tag is set to NO the size of the Perl module output will be much smaller 
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file 
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. 
+# This is useful so different doxyrules.make files included by the same 
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor   
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will 
+# evaluate all C-preprocessor directives found in the sources and include 
+# files.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro 
+# names in the source code. If set to NO (the default) only conditional 
+# compilation will be performed. Macro expansion can be done in a controlled 
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES 
+# then the macro expansion is limited to the macros specified with the 
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files 
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that 
+# contain include files that are not input files but should be processed by 
+# the preprocessor.
+
+INCLUDE_PATH           = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard 
+# patterns (like *.h and *.hpp) to filter out the header-files in the 
+# directories. If left blank, the patterns specified with FILE_PATTERNS will 
+# be used.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that 
+# are defined before the preprocessor is started (similar to the -D option of 
+# gcc). The argument of the tag is a list of macros of the form: name 
+# or name=definition (no spaces). If the definition and the = are 
+# omitted =1 is assumed. To prevent a macro definition from being 
+# undefined via #undef or recursively expanded use the := operator 
+# instead of the = operator.
+
+PREDEFINED             = 
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then 
+# this tag can be used to specify a list of macro names that should be expanded. 
+# The macro definition that is found in the sources will be used. 
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then 
+# doxygen's preprocessor will remove all function-like macros that are alone 
+# on a line, have an all uppercase name, and do not end with a semicolon. Such 
+# function macros are typically used for boiler-plate code, and will confuse 
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references   
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles. 
+# Optionally an initial location of the external documentation 
+# can be added for each tagfile. The format of a tag file without 
+# this location is as follows: 
+#   TAGFILES = file1 file2 ... 
+# Adding location for the tag files is done as follows: 
+#   TAGFILES = file1=loc1 "file2 = loc2" ... 
+# where "loc1" and "loc2" can be relative or absolute paths or 
+# URLs. If a location is present for each tag, the installdox tool 
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen 
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create 
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed 
+# in the class index. If set to NO only the inherited external classes 
+# will be listed.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed 
+# in the modules index. If set to NO, only the current project's groups will 
+# be listed.
+
+EXTERNAL_GROUPS        = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script 
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool   
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will 
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base 
+# or super classes. Setting the tag to NO turns the diagrams off. Note that 
+# this option is superseded by the HAVE_DOT option below. This is only a 
+# fallback. It is recommended to install and use dot, since it yields more 
+# powerful graphs.
+
+CLASS_DIAGRAMS         = YES
+
+# If set to YES, the inheritance and collaboration graphs will hide 
+# inheritance and usage relations if the target is undocumented 
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is 
+# available from the path. This tool is part of Graphviz, a graph visualization 
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section 
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT               = NO
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect inheritance relations. Setting this tag to YES will force the 
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for each documented class showing the direct and 
+# indirect implementation dependencies (inheritance, containment, and 
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen 
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and 
+# collaboration diagrams in a style similar to the OMG's Unified Modeling 
+# Language.
+
+UML_LOOK               = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the 
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT 
+# tags are set to YES then doxygen will generate a graph for each documented 
+# file showing the direct and indirect include dependencies of the file with 
+# other documented files.
+
+INCLUDE_GRAPH          = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and 
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each 
+# documented header file showing the documented files that directly or 
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will 
+# generate a call dependency graph for every global function or class method. 
+# Note that enabling this option will significantly increase the time of a run. 
+# So in most cases it will be better to enable call graphs for selected 
+# functions only using the \callgraph command.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will 
+# generate a caller dependency graph for every global function or class method. 
+# Note that enabling this option will significantly increase the time of a run. 
+# So in most cases it will be better to enable caller graphs for selected 
+# functions only using the \callergraph command.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen 
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES 
+# then doxygen will show the dependencies a directory has on other directories 
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images 
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT       = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be 
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that 
+# contain dot files that are included in the documentation (see the 
+# \dotfile command).
+
+DOTFILE_DIRS           = 
+
+# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width 
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
+# this value, doxygen will try to truncate the graph, so that it fits within 
+# the specified constraint. Beware that most browsers cannot cope with very 
+# large images.
+
+MAX_DOT_GRAPH_WIDTH    = 1024
+
+# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height 
+# (in pixels) of the graphs generated by dot. If a graph becomes larger than 
+# this value, doxygen will try to truncate the graph, so that it fits within 
+# the specified constraint. Beware that most browsers cannot cope with very 
+# large images.
+
+MAX_DOT_GRAPH_HEIGHT   = 1024
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the 
+# graphs generated by dot. A depth value of 3 means that only nodes reachable 
+# from the root by following a path via at most 3 edges will be shown. Nodes 
+# that lay further from the root node will be omitted. Note that setting this 
+# option to 1 or 2 may greatly reduce the computation time needed for large 
+# code bases. Also note that a graph may be further truncated if the graph's 
+# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH 
+# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), 
+# the graph is not depth-constrained.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent 
+# background. This is disabled by default, which results in a white background. 
+# Warning: Depending on the platform used, enabling this option may lead to 
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to 
+# read).
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output 
+# files in one run (i.e. multiple -o and -T options on the command line). This 
+# makes dot run faster, but since only newer versions of dot (>1.8.10) 
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will 
+# generate a legend page explaining the meaning of the various boxes and 
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will 
+# remove the intermediate dot files that are used to generate 
+# the various graphs.
+
+DOT_CLEANUP            = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine   
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be 
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE           = NO
diff --git a/src/Makefile b/src/Makefile
new file mode 100644 (file)
index 0000000..4f75c70
--- /dev/null
@@ -0,0 +1,198 @@
+##
+##  anytun
+##
+##  The secure anycast tunneling protocol (satp) defines a protocol used
+##  for communication between any combination of unicast and anycast
+##  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+##  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+##  ethernet, ip, arp ...). satp directly includes cryptography and
+##  message authentication based on the methodes used by SRTP.  It is
+##  intended to deliver a generic, scaleable and secure solution for
+##  tunneling and relaying of packets of any protocol.
+##
+##
+##  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+##                          Christian Pointner <satp@wirdorange.org>
+##
+##  This file is part of Anytun.
+##
+##  Anytun is free software: you can redistribute it and/or modify
+##  it under the terms of the GNU General Public License version 3 as
+##  published by the Free Software Foundation.
+##
+##  Anytun is distributed in the hope that it will be useful,
+##  but WITHOUT ANY WARRANTY; without even the implied warranty of
+##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+##  GNU General Public License for more details.
+##
+##  You should have received a copy of the GNU General Public License
+##  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+##
+
+ifneq ($(MAKECMDGOALS),distclean)
+include include.mk
+endif
+
+OBJS := tunDevice.o \
+       packetSource.o \
+       buffer.o \
+       syncBuffer.o \
+                        plainPacket.o \
+                        encryptedPacket.o \
+       cipher.o \
+       authAlgo.o \
+                        keyDerivation.o \
+                        cipherFactory.o \
+                        authAlgoFactory.o \
+                        keyDerivationFactory.o \
+                        connectionList.o \
+                        connectionParam.o \
+                        networkAddress.o \
+                        networkPrefix.o \
+                        routingTable.o \
+       signalController.o \
+       log.o \
+       logTargets.o \
+       anytunError.o \
+       options.o \
+       seqWindow.o \
+                        routingTreeNode.o \
+                        resolver.o
+
+SYNCOBJS := syncServer.o \
+       syncClient.o \
+       syncQueue.o \
+                        syncCommand.o \
+       syncRouteCommand.o \
+       syncConnectionCommand.o \
+       syncTcpConnection.o
+
+ANYCTROBJS := signalController.o \
+                                                       anyCtrOptions.o \
+                                                buffer.o \
+                                                log.o \
+                                                logTargets.o \
+                                                anytunError.o \
+                                                syncTcpConnection.o \
+                                                syncServer.o \
+                                                resolver.o
+
+ANYCONFOBJS := log.o \
+                                                logTargets.o \
+                                                anytunError.o \
+                                                buffer.o \
+                                                keyDerivation.o \
+                                                keyDerivationFactory.o \
+                                                networkAddress.o \
+                                                networkPrefix.o \
+                                                connectionList.o \
+                                                connectionParam.o \
+                                                routingTreeNode.o \
+                                                anyConfOptions.o \
+                                                routingTable.o \
+                                                seqWindow.o \
+                                                syncQueue.o \
+                                                syncBuffer.o \
+                                                syncCommand.o \
+                                                syncServer.o \
+             syncTcpConnection.o \
+                                                syncRouteCommand.o \
+                                                syncConnectionCommand.o \
+                                                resolver.o
+
+EXECUTABLE := anytun anytun-config anytun-controld anytun-showtables anytun-nosync
+EXEOBJS := anytun.o anytun-config.o anytun-controld.o anytun-showtables.o
+
+SRCS := $(OBJS:%.o=%.cpp)
+SYNCSRCS := $(SYNCOBJS:%.o=%.cpp)
+ANYCTRSRCS := $(ANYCTROBJS:%.o=%.cpp)
+ANYCONFSRCS := $(ANYCONFOBJS:%.o=%.cpp)
+EXESRCS := $(EXEOBJS:%.o=%.cpp)
+
+.PHONY: distclean cleanall clean ctags
+
+all: $(EXECUTABLE) #libAnysync.a 
+
+%.d: %.cpp
+       @set -e; rm -f $@; \
+        $(CXX) -MM $(CXXFLAGS) $< > $@.$$$$; \
+   sed 's,\($*\)\.o[ :]*,\1.o $@ : ,g' < $@.$$$$ > $@; \
+   rm -f $@.$$$$; echo '(re)building $@'
+
+ifneq ($(MAKECMDGOALS),distclean)
+-include $(SRCS:%.cpp=%.d) $(SYNCSRCS:%.cpp=%.d) $(ANYCTRSRCS:%.cpp=%.d) $(ANYCONFSRCS:%.cpp=%.d) $(EXESRCS:%.cpp=%.d)
+endif
+
+strip: $(EXECUTABLE)
+       strip -s $(EXECUTABLE) 
+
+anytun: $(OBJS) $(SYNCOBJS) anytun.o
+       $(LD) $(OBJS) $(SYNCOBJS) anytun.o -o $@ $(LDFLAGS)
+
+anytun-static: $(OBJS) $(SYNCOBJS) anytun-noprivdrop.o
+       $(LD) $(OBJS) $(SYNCOBJS) anytun-noprivdrop.o -o $@ -Bstatic -lstdc++ -static $(LDFLAGS) -lpthread
+       strip -s anytun-static
+
+anytun-nosync: $(OBJS) anytun-nosync.o
+       $(LD) $(OBJS) anytun-nosync.o -o $@ $(LDFLAGS)
+
+anytun-nosync.o: anytun.cpp
+       $(CXX) $(CXXFLAGS) -DANYTUN_NOSYNC $< -c -o anytun-nosync.o
+
+anytun-noprivdrop.o: anytun.cpp
+       $(CXX) $(CXXFLAGS) -DNO_PRIVDROP $< -c -o anytun-noprivdrop.o
+
+anytun-showtables: $(OBJS) $(SYNCOBJS) anytun-showtables.o
+       $(LD) $(OBJS) $(SYNCOBJS) anytun-showtables.o -o $@ $(LDFLAGS)
+
+anytun-config: $(ANYCONFOBJS) anytun-config.o
+       $(LD) $(ANYCONFOBJS) anytun-config.o -o $@ $(LDFLAGS)
+
+anytun-controld: $(ANYCTROBJS) anytun-controld.o
+       $(LD) $(ANYCTROBJS) anytun-controld.o -o $@ $(LDFLAGS)
+
+
+options.o: options.cpp 
+       $(CXX) $(CXXFLAGS) -DANYTUN_OPTIONS $< -c -o $@
+
+anyCtrOptions.o: options.cpp 
+       $(CXX) $(CXXFLAGS) -DANYCTR_OPTIONS $< -c -o $@
+
+anyConfOptions.o: options.cpp 
+       $(CXX) $(CXXFLAGS) -DANYCONF_OPTIONS $< -c -o $@
+
+%.o: %.cpp
+       $(CXX) $(CXXFLAGS) $< -c
+
+
+libAnysync.a: $(OBJS)
+       ar cru $@ $(OBJS)
+       ranlib $@
+
+anyrtpproxy: anytun
+       $(MAKE) --directory=$(CURDIR)/anyrtpproxy
+
+
+distclean: cleanall
+       find . -name *.o -exec rm -f {} \;
+       rm -f config.sub config.guess
+       rm -f tunDevice.cpp
+       rm -f include.mk
+
+cleanall: clean
+       $(MAKE) --directory=$(CURDIR)/man clean
+
+clean:
+       rm -f *.o
+       rm -f *.d
+       rm -f *.d.*
+       rm -f $(EXECUTABLE)
+       rm -f anytun-nosync
+       rm -f -r doc/html/*
+       rm -f -r doc/latex/*
+       rm -f libAnysync.a
+       $(MAKE) --directory=$(CURDIR)/anyrtpproxy clean
+
+manpage:
+       @cd man ; $(MAKE)
+
diff --git a/src/anyrtpproxy/Makefile b/src/anyrtpproxy/Makefile
new file mode 100644 (file)
index 0000000..40ca273
--- /dev/null
@@ -0,0 +1,79 @@
+##
+##  anytun
+##
+##  The secure anycast tunneling protocol (satp) defines a protocol used
+##  for communication between any combination of unicast and anycast
+##  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+##  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+##  ethernet, ip, arp ...). satp directly includes cryptography and
+##  message authentication based on the methodes used by SRTP.  It is
+##  intended to deliver a generic, scaleable and secure solution for
+##  tunneling and relaying of packets of any protocol.
+##
+##
+##  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+##                          Christian Pointner <satp@wirdorange.org>
+##
+##  This file is part of Anytun.
+##
+##  Anytun is free software: you can redistribute it and/or modify
+##  it under the terms of the GNU General Public License version 3 as
+##  published by the Free Software Foundation.
+##
+##  Anytun is distributed in the hope that it will be useful,
+##  but WITHOUT ANY WARRANTY; without even the implied warranty of
+##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+##  GNU General Public License for more details.
+##
+##  You should have received a copy of the GNU General Public License
+##  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+##
+CC = gcc
+CFLAGS = -g -Wall
+CXX = g++
+CXXFLAGS = -g -Wall
+LD = g++
+LDFLAGS = -g -Wall -O2 -lboost_thread -lboost_serialization -lboost_system
+
+OBJS = anyrtpproxy.o \
+       ../signalController.o \
+       ../log.o \
+       ../buffer.o \
+       rtpSessionTable.o \
+       rtpSession.o \
+       connectionList.o \
+       ../syncServer.o \
+       ../syncClient.o \
+       ../syncTcpConnection.o \
+       ../syncQueue.o \
+       syncRtpCommand.o \
+       commandHandler.o \
+       portWindow.o \
+       callIdQueue.o \
+       options.o
+
+SRCS = $(OBJS:%.o=%.cpp)
+
+EXECUTABLE = anyrtpproxy
+DEPENDFILE = .depend
+
+.PHONY: dep clean
+
+all: dep $(EXECUTABLE)
+
+dep: $(SRCS)
+       $(CC) -MM $(SRCS) > $(DEPENDFILE)
+
+-include $(DEPENDFILE)
+
+anyrtpproxy: $(OBJS)
+       $(LD) $(OBJS) -o $@ $(LDFLAGS)
+
+%.o: %.cpp
+       $(CXX) $(CXXFLAGS) $< -c
+
+clean:
+       rm -f *.o
+       rm -f $(DEPENDFILE)
+       rm -f $(EXECUTABLE)
+
diff --git a/src/anyrtpproxy/anyrtpproxy.cpp b/src/anyrtpproxy/anyrtpproxy.cpp
new file mode 100644 (file)
index 0000000..fdb809e
--- /dev/null
@@ -0,0 +1,387 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <iostream>
+
+#include <boost/asio.hpp>
+
+#include <fcntl.h>
+#include <pwd.h>
+#include <grp.h>
+
+#include "../datatypes.h"
+
+#include "../log.h"
+#include "../signalController.h"
+#include "../buffer.h"
+#include "connectionList.h"
+#include "rtpSessionTable.h"
+#include "syncRtpCommand.h"
+#include "../syncQueue.h"
+#include "../syncClient.h"
+#include "syncOnConnect.hpp"
+
+#include "../threadUtils.hpp"
+
+#include "commandHandler.h"
+#include "callIdQueue.h"
+
+#include "options.h"
+#include "portWindow.h"
+#include <map>
+#include <fstream>
+
+#define MAX_PACKET_SIZE 1500
+
+void listener(RtpSession::proto::socket* sock1, RtpSession::proto::socket* sock2, std::string call_id, int dir, SyncQueue* queue, bool* running)
+{
+  cLog.msg(Log::PRIO_NOTICE) << "listener(" << call_id << "/" << dir << ") started";
+
+  try 
+  {
+    Buffer buf(u_int32_t(MAX_PACKET_SIZE));
+    RtpSession::proto::endpoint remote_end;
+
+    while(1) {
+      buf.setLength(MAX_PACKET_SIZE);
+      u_int32_t len=0;
+      if(dir == 1)
+        len = 0;//sock1->recvFromNonBlocking(buf.getBuf(), buf.getLength(), remote_end, 1000);
+      else if(dir == 2)
+        len = 0; //sock2->recvFromNonBlocking(buf.getBuf(), buf.getLength(), remote_end, 1000);
+                       else break;
+
+      RtpSession& session = gRtpSessionTable.getSession(call_id);
+      if(session.isDead()) {
+        cLog.msg(Log::PRIO_NOTICE) << "listener(" << call_id << "/" << dir << ") session is dead, exiting"; 
+        break;
+      }
+
+      if(!len)
+        continue;
+      buf.setLength(len);
+      
+      if((dir == 1 && remote_end != session.getRemoteEnd1()) || 
+         (dir == 2 && remote_end != session.getRemoteEnd2()))
+      {
+        if(gOpt.getNat() ||
+           (!gOpt.getNoNatOnce() && ((dir == 1 && !session.getSeen1()) || 
+                                     (dir == 2 && !session.getSeen2()))))
+        {
+          cLog.msg(Log::PRIO_NOTICE) << "listener(" << call_id << "/" << dir << ") setting remote host to "
+                                     << remote_end;
+          if(dir == 1)
+            session.setRemoteEnd1(remote_end);
+          if(dir == 2)
+            session.setRemoteEnd2(remote_end);
+          
+          if(!gOpt.getNat()) { // with nat enabled sync is not needed
+            SyncRtpCommand sc(call_id);
+            queue->push(sc);
+          }
+        }
+        else
+          continue;
+                       }
+      session.setSeen1();
+      session.setSeen2();
+
+      if(dir == 1)
+        sock2->send_to(boost::asio::buffer(buf.getBuf(), buf.getLength()), session.getRemoteEnd2());
+      else if(dir == 2)
+        sock1->send_to(boost::asio::buffer(buf.getBuf(), buf.getLength()), session.getRemoteEnd1());
+      else break;
+    }  
+  }
+  catch(std::exception &e)
+  {
+    cLog.msg(Log::PRIO_ERR) << "listener(" << call_id << "/" << dir << ") exiting because: " << e.what();
+  }
+  *running = false;
+  gCallIdQueue.push(call_id);
+}
+
+class ListenerData
+{
+public:
+  ListenerData() : sock1_(ios1_), sock2_(ios2_) {}
+
+  boost::asio::io_service ios1_;
+  boost::asio::io_service ios2_;
+  RtpSession::proto::socket sock1_;
+  RtpSession::proto::socket sock2_;
+  boost::thread* thread1_;
+  boost::thread* thread2_;
+  bool running1_;
+  bool running2_;
+};
+
+void listenerManager(void* p)
+{
+  SyncQueue* queue_ = reinterpret_cast<SyncQueue*>(p);
+
+  std::map<std::string, ListenerData*> listenerMap;
+  while(1)
+  {
+    try 
+    {
+      std::string call_id = gCallIdQueue.front(); // waits for semaphor and returns next call_id
+      gCallIdQueue.pop();
+
+      RtpSession& session = gRtpSessionTable.getSession(call_id);
+      if(!session.isComplete())
+        continue;
+
+      std::map<std::string, ListenerData*>::iterator it;
+      it = listenerMap.find(call_id);
+      if(it == listenerMap.end()) // listener Threads not existing yet
+      {        
+        ListenerData* ld = new ListenerData();
+
+        ld->sock1_.open(session.getLocalEnd1().protocol());
+        ld->sock1_.bind(session.getLocalEnd1());
+
+        ld->sock2_.open(session.getLocalEnd2().protocol());
+        ld->sock2_.bind(session.getLocalEnd2());
+
+        ld->thread1_ = new boost::thread(boost::bind(listener, &(ld->sock1_), &(ld->sock2_), call_id, 1, queue_, &(ld->running1_)));
+        ld->thread2_ = new boost::thread(boost::bind(listener, &(ld->sock1_), &(ld->sock2_), call_id, 2, queue_, &(ld->running2_)));
+
+        std::pair<std::map<std::string, ListenerData*>::iterator, bool> ret;
+        ret = listenerMap.insert(std::map<std::string, ListenerData*>::value_type(call_id, ld));
+        continue;
+      }
+
+      if(!it->second->running1_ && !it->second->running2_)
+      {
+        cLog.msg(Log::PRIO_NOTICE) << "listenerManager both threads for '" << call_id << "' exited, cleaning up";
+        if(it->second->thread1_) {
+          it->second->thread1_->join();
+          delete it->second->thread1_;
+        }
+        if(it->second->thread2_) {
+          it->second->thread2_->join();
+          delete it->second->thread2_;
+        }
+        delete it->second;
+        listenerMap.erase(it);
+        gRtpSessionTable.delSession(call_id);
+        continue;
+      }
+          // TODO: reinit if session changed
+    }
+    catch(std::exception &e)
+    {
+      cLog.msg(Log::PRIO_ERR) << "listenerManager restarting after exception: " << e.what();
+      usleep(500); // in case of an hard error don't block cpu (this is ugly)
+    }
+  }
+  cLog.msg(Log::PRIO_ERR) << "listenerManager exiting because of unknown reason";
+}
+
+void chrootAndDrop(string const& chrootdir, string const& username)
+{
+       if (getuid() != 0)
+       {
+         std::cerr << "this programm has to be run as root in order to run in a chroot" << std::endl;
+               exit(-1);
+       }       
+
+  struct passwd *pw = getpwnam(username.c_str());
+       if(pw) {
+               if(chroot(chrootdir.c_str()))
+               {
+      std::cerr << "can't chroot to " << chrootdir << std::endl;
+      exit(-1);
+               }
+    std::cout << "we are in chroot jail (" << chrootdir << ") now" << std::endl;
+    chdir("/");
+               if (initgroups(pw->pw_name, pw->pw_gid) || setgid(pw->pw_gid) || setuid(pw->pw_uid)) 
+               {
+                       std::cerr << "can't drop to user " << username << " " << pw->pw_uid << ":" << pw->pw_gid << std::endl;
+                       exit(-1);
+               }
+    std::cout << "dropped user to " << username << " " << pw->pw_uid << ":" << pw->pw_gid << std::endl;
+       }
+       else 
+  {
+    std::cerr << "unknown user " << username << std::endl;
+    exit(-1);
+       }
+}
+
+void daemonize()
+{
+  pid_t pid;
+
+  pid = fork();
+  if(pid) exit(0);  
+  setsid();
+  pid = fork();
+  if(pid) exit(0);
+  
+//  std::cout << "running in background now..." << std::endl;
+
+  int fd;
+//  for (fd=getdtablesize();fd>=0;--fd) // close all file descriptors
+  for (fd=0;fd<=2;fd++) // close all file descriptors
+    close(fd);
+  fd=open("/dev/null",O_RDWR);        // stdin
+  dup(fd);                            // stdout
+  dup(fd);                            // stderr
+  umask(027); 
+}
+
+class ThreadParam
+{
+public:
+  ThreadParam(SyncQueue & queue_,OptionConnectTo & connto_)
+    : queue(queue_),connto(connto_)
+    {};
+  SyncQueue & queue;
+  OptionConnectTo & connto;
+};
+
+void syncConnector(void* p)
+{
+       ThreadParam* param = reinterpret_cast<ThreadParam*>(p);
+
+       SyncClient sc ( param->connto.host, param->connto.port);
+       sc.run();
+}
+
+void syncListener(SyncQueue * queue)
+{
+  try
+  {
+    boost::asio::io_service io_service;
+               SyncTcpConnection::proto::resolver resolver(io_service);
+               SyncTcpConnection::proto::endpoint e;
+               if(gOpt.getLocalSyncAddr()!="")
+               {
+                       SyncTcpConnection::proto::resolver::query query(gOpt.getLocalSyncAddr(), gOpt.getLocalSyncPort());
+                       e = *resolver.resolve(query);
+               } else {
+                       SyncTcpConnection::proto::resolver::query query(gOpt.getLocalSyncPort());
+                       e = *resolver.resolve(query);
+               }
+
+
+    SyncServer server(io_service,e);
+               server.onConnect=boost::bind(syncOnConnect,_1);
+               queue->setSyncServerPtr(&server);
+    io_service.run();
+  }
+  catch (std::exception& e)
+  {
+    std::string addr = gOpt.getLocalSyncAddr() == "" ? "*" : gOpt.getLocalSyncAddr();
+    cLog.msg(Log::PRIO_ERR) << "sync: cannot bind to " << addr << ":" << gOpt.getLocalSyncPort()
+                            << " (" << e.what() << ")" << std::endl;
+  }
+
+}
+
+int main(int argc, char* argv[])
+{
+//  std::cout << "anyrtpproxy" << std::endl;
+  if(!gOpt.parse(argc, argv))
+  {
+    gOpt.printUsage();
+    exit(-1);
+  }
+
+  cLog.setLogName("anyrtpproxy");
+  cLog.msg(Log::PRIO_NOTICE) << "anyrtpproxy started...";
+
+  std::ofstream pidFile;
+  if(gOpt.getPidFile() != "") {
+    pidFile.open(gOpt.getPidFile().c_str());
+    if(!pidFile.is_open()) {
+      std::cout << "can't open pid file" << std::endl;
+    }
+  }
+
+  if(gOpt.getChroot())
+    chrootAndDrop(gOpt.getChrootDir(), gOpt.getUsername());
+  if(gOpt.getDaemonize())
+    daemonize();
+
+  if(pidFile.is_open()) {
+    pid_t pid = getpid();
+    pidFile << pid;
+    pidFile.close();
+  }
+  
+  SignalController sig;
+  sig.init();
+
+  SyncQueue queue;
+
+
+  boost::thread listenerManagerThread(boost::bind(listenerManager,&queue));
+
+
+// #ifndef ANYTUN_NOSYNC
+//     boost::thread * syncListenerThread;
+//     if(gOpt.getLocalSyncPort() != "")
+//       syncListenerThread = new boost::thread(boost::bind(syncListener,&queue));
+    
+//     std::list<boost::thread *> connectThreads;
+//     for(ConnectToList::iterator it = connect_to.begin() ;it != connect_to.end(); ++it) { 
+//       ThreadParam * point = new ThreadParam(dev, *src, cl, queue,*it);
+//       connectThreads.push_back(new boost::thread(boost::bind(syncConnector,point)));
+//     }
+// #endif
+
+
+
+//   pthread_t syncListenerThread;
+
+//     ConnectToList connect_to = gOpt.getConnectTo();
+//     ThreadParam p( queue,*(new OptionConnectTo()));
+//   if ( gOpt.getLocalSyncPort())
+//     pthread_create(&syncListenerThread, NULL, syncListener, &p);
+
+//   std::list<pthread_t> connectThreads;
+//   for(ConnectToList::iterator it = connect_to.begin() ;it != connect_to.end(); ++it)
+//   {
+//     connectThreads.push_back(pthread_t());
+//     ThreadParam * point = new ThreadParam(queue,*it);
+//     pthread_create(& connectThreads.back(),  NULL, syncConnector, point);
+//   }
+
+       PortWindow port_window(gOpt.getRtpStartPort(),gOpt.getRtpEndPort());
+  CommandHandler cmd(queue, gOpt.getControlInterface().addr_, gOpt.getControlInterface().port_,port_window);
+  
+  int ret = sig.run();
+  return ret;
+}
+
diff --git a/src/anyrtpproxy/callIdQueue.cpp b/src/anyrtpproxy/callIdQueue.cpp
new file mode 100644 (file)
index 0000000..e2ce700
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "callIdQueue.h"
+
+CallIdQueue* CallIdQueue::inst = NULL;
+Mutex CallIdQueue::instMutex;
+CallIdQueue& gCallIdQueue = CallIdQueue::instance();
+
+CallIdQueue& CallIdQueue::instance()
+{
+  Lock lock(instMutex);
+  static instanceCleaner c;
+  if(!inst)
+    inst = new CallIdQueue();
+  
+  return *inst;
+}
+
+CallIdQueue::CallIdQueue()
+{
+}
+
+CallIdQueue::~CallIdQueue()
+{
+  while(!callids_.empty())
+    pop();
+}
+
+std::string& CallIdQueue::front()
+{
+  sem_.down();
+  Lock lock(mutex_);
+  return callids_.front();
+}
+
+void CallIdQueue::push(std::string c)
+{
+  Lock lock(mutex_);
+  callids_.push(c);
+  sem_.up();
+}
+
+void CallIdQueue::pop()
+{
+  Lock lock(mutex_);
+  callids_.pop();
+}
+
diff --git a/src/anyrtpproxy/callIdQueue.h b/src/anyrtpproxy/callIdQueue.h
new file mode 100644 (file)
index 0000000..1ffe2df
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __CALLID_QUEUE_H__
+#define __CALLID_QUEUE_H__
+
+#include <queue>
+#include <string>
+
+#include "../threadUtils.hpp"
+
+class CallIdQueue
+{
+public:
+  static CallIdQueue& instance(); 
+  
+  std::string& front();
+  void push(std::string c);
+  void pop();
+
+private:
+  CallIdQueue();
+  ~CallIdQueue();
+
+  void operator=(const CallIdQueue &src);
+  CallIdQueue(const CallIdQueue &src);
+
+  static CallIdQueue* inst;
+  static ::Mutex instMutex;
+  class instanceCleaner {
+    public: ~instanceCleaner() {
+      if(CallIdQueue::inst != 0)
+        delete CallIdQueue::inst;
+    }
+  };
+  friend class instanceCleaner;
+
+  ::Mutex mutex_;
+  Semaphore sem_;
+  std::queue<std::string> callids_;
+};
+
+extern CallIdQueue& gCallIdQueue;
+
+#endif
diff --git a/src/anyrtpproxy/commandHandler.cpp b/src/anyrtpproxy/commandHandler.cpp
new file mode 100644 (file)
index 0000000..01613ec
--- /dev/null
@@ -0,0 +1,286 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sstream>
+#include <vector>
+
+#include <iomanip>
+#include <iostream>
+#include <sstream>
+
+#include <boost/bind.hpp>
+
+#include "commandHandler.h"
+#include "../buffer.h"
+#include "../log.h"
+#include "../syncQueue.h"
+#include "syncRtpCommand.h"
+#include "rtpSessionTable.h"
+#include "callIdQueue.h"
+#include "options.h"
+
+#define MAX_COMMAND_LENGTH 1000
+
+CommandHandler::CommandHandler(SyncQueue& q, std::string lp,PortWindow & pw) : thread_(boost::bind(run,this)), 
+                                                                               queue_(q), running_(true), control_sock_(io_service_), 
+                                                                               local_address_(""), local_port_(lp),port_window_(pw)
+{
+  proto::resolver resolver(io_service_);
+  proto::resolver::query query(local_port_);  
+  proto::endpoint e = *resolver.resolve(query);
+  control_sock_.open(e.protocol());
+  control_sock_.bind(e);
+}
+
+CommandHandler::CommandHandler(SyncQueue& q, string la, std::string lp, PortWindow & pw) : thread_(boost::bind(run,this)), 
+                                                                                           queue_(q), running_(true), control_sock_(io_service_), 
+                                                                                           local_address_(la), local_port_(lp),port_window_(pw)
+{
+  proto::resolver resolver(io_service_);
+  proto::resolver::query query(local_address_, local_port_);  
+  proto::endpoint e = *resolver.resolve(query);
+  control_sock_.open(e.protocol());
+  control_sock_.bind(e);
+}
+
+void CommandHandler::run(void* s)
+{
+  CommandHandler* self = reinterpret_cast<CommandHandler*>(s);
+
+  Buffer buf(u_int32_t(MAX_COMMAND_LENGTH));
+  try
+  {
+    proto::endpoint remote_end;
+
+    int len;
+    while(1)
+    {
+      buf.setLength(MAX_COMMAND_LENGTH);
+
+      len = self->control_sock_.receive_from(boost::asio::buffer(buf.getBuf(), buf.getLength()), remote_end);
+      buf.setLength(len);
+
+      std::string ret = self->handle(std::string(reinterpret_cast<char*>(buf.getBuf()), buf.getLength())); // TODO: reinterpret is ugly
+
+      cLog.msg(Log::PRIO_DEBUG) << "CommandHandler received Command from " << remote_end << ", ret='" << ret << "'";
+
+      self->control_sock_.send_to(boost::asio::buffer(ret.c_str(), ret.length()), remote_end);
+    }
+  }
+  catch(std::exception& e)
+  {
+    self->running_ = false;
+  }
+  self->running_ = false;
+}
+
+bool CommandHandler::isRunning()
+{
+  return running_;
+}
+
+
+
+std::string CommandHandler::handle(std::string command)
+{
+  istringstream iss(command);
+  ostringstream oss;
+  std::string cookie;
+  std::string cmd;
+
+  iss >> cookie;
+  oss << cookie << " ";
+
+  if(iss.bad() || iss.eof()) {
+    oss << RET_ERR_SYNTAX;
+    return oss.str();
+  }
+  iss >> cmd;
+
+  std::vector<std::string> params;
+  while(!iss.bad() && !iss.eof()) {
+    std::string tmp;
+    iss >> tmp;
+    params.push_back(tmp);
+  }
+
+  switch(std::toupper(cmd[0]))
+  {
+  case CMD_REQUEST:
+    if(params.size() < 4) { oss << RET_ERR_SYNTAX; break; }
+    oss << handleRequest(cmd.erase(0,1), params[0], params[1], params[2], params[3], (params.size() < 5) ? "" : params[4]);
+    break;
+  case CMD_RESPONSE:
+    if(params.size() < 4) { oss << RET_ERR_SYNTAX; break; }
+    oss << handleResponse(cmd.erase(0,1), params[0], params[1], params[2], params[3], (params.size() < 5) ? "" : params[4]);
+    break;
+  case CMD_DELETE:
+    if(params.size() < 2) { oss << RET_ERR_SYNTAX; break; }
+    oss << handleDelete(params[0], params[1], (params.size() < 3) ? "" : params[2]);
+    break;
+  case CMD_VERSION:
+    if(cmd.length() > 1 && cmd[1] == 'F') {
+      if(params.size() < 1) { oss << RET_ERR_SYNTAX; break; }
+      oss << handleVersionF(params[0]);
+      break;
+    }
+    oss << handleVersion();
+    break;
+  case CMD_INFO:
+    oss << handleInfo();
+    break;
+  default:
+    oss << RET_ERR_SYNTAX;
+    break;
+  }
+
+  return oss.str();
+}
+
+string CommandHandler::handleRequest(string modifiers, string call_id, string addr, string port, string from_tag, string to_tag)
+{
+  std::cout << "received request[" << modifiers << "] command ('" << call_id << "','" << addr  << "','" << port 
+            << "','" << from_tag << "','" << to_tag << "')" << std::endl;
+
+  try 
+  {
+    RtpSession::proto::resolver resolver(io_service_);
+    bool is_new;
+    RtpSession& session = gRtpSessionTable.getOrNewSession(call_id, is_new);
+    if(is_new)
+    {
+      u_int16_t port1 = port_window_.newPort(); // TODO: get next available port
+      u_int16_t port2 = port_window_.newPort(); // TODO: get next available port
+                       if( !port1 || !port2)
+                       {
+                               if( port1) port_window_.freePort(port1);
+                               if( port2) port_window_.freePort(port2);
+                               throw std::runtime_error("no free port found");
+                       }
+      std::stringstream ps1, ps2;
+      ps1 << port1;
+      ps2 << port2;
+
+      RtpSession::proto::endpoint e1, e2;
+      if(gOpt.getLocalAddr() == "") {
+        RtpSession::proto::resolver::query query1(ps1.str());
+        e1 = *resolver.resolve(query1);
+        RtpSession::proto::resolver::query query2(ps2.str());
+        e2 = *resolver.resolve(query2);
+      }
+      else {
+        RtpSession::proto::resolver::query query1(gOpt.getLocalAddr(),ps1.str());
+        e1 = *resolver.resolve(query1);
+        RtpSession::proto::resolver::query query2(gOpt.getLocalAddr(),ps2.str());
+        e2 = *resolver.resolve(query2);
+      }
+
+      session.setLocalEnd1(e1);
+      session.setLocalEnd2(e2);
+    }
+    RtpSession::proto::resolver::query query(addr,port);
+    session.setRemoteEnd1(*resolver.resolve(query));
+
+    ostringstream oss;
+    oss << session.getLocalEnd2().port();
+    return oss.str();
+  }
+  catch(std::exception& e)
+  {
+    return RET_ERR_UNKNOWN; // TODO: change to corret error value
+  }
+}
+
+string CommandHandler::handleResponse(string modifiers, string call_id, string addr, string port, string from_tag, string to_tag)
+{
+  std::cout << "received response[" << modifiers << "] command ('" << call_id << "','" << addr  << "','" << port 
+            << "','" << from_tag << "','" << to_tag << "')" << std::endl;
+
+  try
+  {
+    RtpSession& session = gRtpSessionTable.getSession(call_id);
+    RtpSession::proto::resolver resolver(io_service_);
+    RtpSession::proto::resolver::query query(addr,port);
+    session.setRemoteEnd2(*resolver.resolve(query));
+    session.isComplete(true);
+    SyncRtpCommand sc(call_id);
+    queue_.push(sc);
+
+    ostringstream oss;
+    oss << session.getLocalEnd1().port();
+    return oss.str();
+  }
+  catch(std::exception& e)
+  {
+    return RET_ERR_UNKNOWN; // TODO: change to corret error value
+  }
+}
+
+string CommandHandler::handleDelete(string call_id, string from_tag, string to_tag)
+{
+  std::cout << "received delete command ('" << call_id << "','" << from_tag << "','" << to_tag << "')" << std::endl;
+
+  try
+  {
+    RtpSession& session = gRtpSessionTable.getSession(call_id);
+    session.isDead(true);
+    SyncRtpCommand sc(call_id);
+    queue_.push(sc);
+
+    return RET_OK;
+  }
+  catch(std::exception& e)
+  {
+    return RET_ERR_UNKNOWN; // TODO: change to corret error value
+  }
+}
+
+string CommandHandler::handleVersion()
+{
+  std::cout << "received version command" << std::endl;  
+  return BASE_VERSION;
+}
+
+string CommandHandler::handleVersionF(string date_code)
+{
+  std::cout << "received version[F] command ('" << date_code << "')" << std::endl;  
+  if(!date_code.compare(SUP_VERSION))
+    return "1";
+  
+  return "0";
+}
+
+string CommandHandler::handleInfo()
+{
+  std::cout << "received info command, ignoring" << std::endl;  
+  return RET_OK;
+}
+
diff --git a/src/anyrtpproxy/commandHandler.h b/src/anyrtpproxy/commandHandler.h
new file mode 100644 (file)
index 0000000..6bd802a
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _COMMAND_HANDLER_H_
+#define _COMMAND_HANDLER_H_
+
+#include <boost/asio.hpp>
+
+#include <string>
+#include "../datatypes.h"
+#include "../PracticalSocket.h"
+#include "../syncQueue.h"
+#include "portWindow.h"
+
+class CommandHandler
+{
+public:
+  typedef boost::asio::ip::udp proto;
+
+  CommandHandler(SyncQueue& q, std::string lp, PortWindow &);
+  CommandHandler(SyncQueue& q, std::string la, std::string lp, PortWindow &);
+  
+  bool isRunning();
+
+  #define CMD_REQUEST 'U'
+  #define CMD_RESPONSE 'L'
+  #define CMD_DELETE 'D'
+  #define CMD_VERSION 'V'
+  #define CMD_INFO 'I'
+
+  #define RET_OK "0"
+  #define RET_ERR_SYNTAX "E1"
+  #define RET_ERR_UNKNOWN "E2"
+
+  #define BASE_VERSION "20040107"
+  #define SUP_VERSION "20050322"
+
+private:
+  CommandHandler(const CommandHandler &c);
+  void operator=(const CommandHandler &c);
+
+  static void run(void* s);
+  std::string handle(std::string command);
+  
+  std::string handleRequest(std::string modifiers, std::string call_id, std::string addr, std::string port, std::string from_tag, std::string to_tag);
+  std::string handleResponse(std::string modifiers, std::string call_id, std::string addr, std::string port, std::string from_tag, std::string to_tag);
+  std::string handleDelete(std::string call_id, std::string from_tag, std::string to_tag);
+  std::string handleVersion();
+  std::string handleVersionF(std::string date_code);
+  std::string handleInfo();
+
+  boost::thread thread_;
+  SyncQueue& queue_;
+
+  bool running_;
+  boost::asio::io_service io_service_;
+  proto::socket control_sock_;
+  std::string local_address_;
+  std::string local_port_;
+       PortWindow& port_window_;
+};
+
+
+#endif
diff --git a/src/anyrtpproxy/connectionList.cpp b/src/anyrtpproxy/connectionList.cpp
new file mode 100644 (file)
index 0000000..eea1e38
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "connectionList.h"
+
+ConnectionList::ConnectionList()
+{
+}
+
+ConnectionList::~ConnectionList()
+{
+} 
+
+void ConnectionList::addConnection(ConnectionParam &conn, u_int16_t mux )
+{
+}
+
+const ConnectionMap::iterator ConnectionList::getEnd()
+{
+       return connections_.end();
+}
+
+ConnectionMap::iterator ConnectionList::getBeginUnlocked()
+{
+  return connections_.begin();
+}
+
+ConnectionMap::iterator ConnectionList::getEndUnlocked()
+{
+  return connections_.end();
+}
+
+const ConnectionMap::iterator ConnectionList::getConnection(u_int16_t mux)
+{
+       Lock lock(mutex_);
+       ConnectionMap::iterator it = connections_.find(mux);
+       return it;
+}
+
+
+ConnectionParam & ConnectionList::getOrNewConnectionUnlocked(u_int16_t mux)
+{
+       ConnectionMap::iterator it = connections_.find(mux);
+               return it->second;
+}
+
+void ConnectionList::clear()
+{
+  Lock lock(mutex_);
+       connections_.clear();
+}
+
+bool ConnectionList::empty()
+{
+  Lock lock(mutex_);
+       return connections_.empty();
+}
+
+Mutex& ConnectionList::getMutex()
+{
+  return mutex_;
+}
diff --git a/src/anyrtpproxy/connectionList.h b/src/anyrtpproxy/connectionList.h
new file mode 100644 (file)
index 0000000..de45f8a
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _CONNECTION_LIST_H
+#define _CONNECTION_LIST_H
+
+#include <map>
+
+#include "../threadUtils.hpp"
+#include "../datatypes.h"
+#include "../connectionParam.h"
+#include "../networkAddress.h"
+typedef std::map<u_int16_t, ConnectionParam> ConnectionMap;
+
+class ConnectionList
+{
+public:
+       ConnectionList();
+       ~ConnectionList();
+       void addConnection(ConnectionParam &conn, u_int16_t mux);
+       const ConnectionMap::iterator getConnection(u_int16_t mux);
+       const ConnectionMap::iterator getEnd();
+       ConnectionMap::iterator getEndUnlocked();
+       ConnectionMap::iterator getBeginUnlocked();
+       ConnectionParam & getOrNewConnectionUnlocked(u_int16_t mux);
+       bool empty();
+       void clear();
+  Mutex& getMutex();
+
+private:
+  ConnectionList(const ConnectionList &s);
+  void operator=(const ConnectionList &s);
+       ConnectionMap connections_;
+  Mutex mutex_;
+};
+
+#endif
diff --git a/src/anyrtpproxy/options.cpp b/src/anyrtpproxy/options.cpp
new file mode 100644 (file)
index 0000000..6a48483
--- /dev/null
@@ -0,0 +1,408 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <iostream>
+#include <queue>
+#include <string>
+#include <sstream>
+
+#include "options.h"
+
+Options* Options::inst = NULL;
+Mutex Options::instMutex;
+Options& gOpt = Options::instance();
+
+Options& Options::instance()
+{
+  Lock lock(instMutex);
+  static instanceCleaner c;
+  if(!inst)
+    inst = new Options();
+  
+  return *inst;
+}
+
+void Host::splitAndSetAddrPort(std::string addr_port)
+{
+  if(addr_port.length() >= 2 && addr_port[0] == ':' && addr_port[1] != ':') {
+    addr_ = "";
+    addr_port.erase(0,1);
+    std::stringstream tmp_stream(addr_port);    
+    tmp_stream >> port_;
+    return;
+  }
+
+  size_t pos = addr_port.find_first_of("[");
+
+  if(pos != std::string::npos && pos != 0)
+    return; // an [ was found but not at the beginning
+
+  bool hasPort = false;
+  if(pos != std::string::npos) {
+    addr_port.erase(pos, 1);
+    pos = addr_port.find_first_of("]");
+
+    if(pos == std::string::npos)
+      return; // no trailing ] although an leading [ was found
+
+    if(pos < addr_port.length()-2) {
+
+      if(addr_port[pos+1] != ':')
+        return; // wrong port delimieter
+
+      addr_port[pos+1] = '/';
+      hasPort = true;
+    }
+    else if(pos != addr_port.length()-1)
+      return; // to few characters left
+
+    addr_port.erase(pos, 1);
+  }
+
+  if(hasPort) {
+    std::stringstream tmp_stream(addr_port);
+
+    getline(tmp_stream, addr_, '/');
+    if(!tmp_stream.good())
+      return;
+
+    tmp_stream >> port_;
+  }
+  else {
+    addr_ = addr_port;
+    port_ = "2323"; // default sync port
+  }
+}
+
+
+Options::Options() : control_interface_("0.0.0.0", "22222")
+
+{
+  progname_ = "anyrtpproxy";
+  chroot_ = false;
+  username_ = "nobody";
+  chroot_dir_ = "/var/run";
+  daemonize_ = true;
+  pid_file_ = "";
+  local_addr_ = "";
+       local_sync_port_ = "";
+       rtp_start_port_ = 34000;
+       rtp_end_port_ = 35000;
+       no_nat_once_ = false;
+       nat_ = false;
+}
+
+Options::~Options()
+{
+}
+
+#define PARSE_BOOL_PARAM(SHORT, LONG, VALUE)             \
+    else if(str == SHORT || str == LONG)                 \
+      VALUE = true;
+
+#define PARSE_INVERSE_BOOL_PARAM(SHORT, LONG, VALUE)     \
+    else if(str == SHORT || str == LONG)                 \
+      VALUE = false;
+
+#define PARSE_SCALAR_PARAM(SHORT, LONG, VALUE)           \
+    else if(str == SHORT || str == LONG)                 \
+    {                                                    \
+      if(argc < 1 || argv[i+1][0] == '-')                \
+        return false;                                    \
+      std::stringstream tmp;                             \
+      tmp << argv[i+1];                                  \
+      tmp >> VALUE;                                      \
+      argc--;                                            \
+      i++;                                               \
+    }
+
+#define PARSE_SCALAR_PARAM2(SHORT, LONG, VALUE1, VALUE2) \
+    else if(str == SHORT || str == LONG)                 \
+    {                                                    \
+      if(argc < 2 ||                                     \
+         argv[i+1][0] == '-' || argv[i+2][0] == '-')     \
+        return false;                                    \
+      std::stringstream tmp;                             \
+      tmp << argv[i+1] << " " << argv[i+2];              \
+      tmp >> VALUE1;                                     \
+      tmp >> VALUE2;                                     \
+      argc-=2;                                           \
+      i+=2;                                              \
+    }
+
+#define PARSE_STRING_PARAM(SHORT, LONG, VALUE)           \
+    else if(str == SHORT || str == LONG)                 \
+    {                                                    \
+      if(argc < 1 || argv[i+1][0] == '-')                \
+        return false;                                    \
+      VALUE = std::string(argv[i+1]);                    \
+      argc--;                                            \
+      i++;                                               \
+    }
+
+#define PARSE_HEXSTRING_PARAM_SEC(SHORT, LONG, VALUE)    \
+    else if(str == SHORT || str == LONG)                 \
+    {                                                    \
+      if(argc < 1 || argv[i+1][0] == '-')                \
+        return false;                                    \
+      VALUE = Buffer(std::string(argv[i+1]));            \
+      for(size_t j=0; j < strlen(argv[i+1]); ++j)        \
+        argv[i+1][j] = '#';                              \
+      argc--;                                            \
+      i++;                                               \
+    }
+
+#define PARSE_CSLIST_PARAM(SHORT, LONG, LIST)            \
+    else if(str == SHORT || str == LONG)                 \
+    {                                                    \
+      if(argc < 1 || argv[i+1][0] == '-')                \
+        return false;                                    \
+      std::stringstream tmp(argv[i+1]);                  \
+      /* LIST.clear(); */                                \
+                       while (tmp.good())                                 \
+                       {                                                  \
+                               std::string tmp_line;                            \
+                               getline(tmp,tmp_line,',');                       \
+                               LIST.push(tmp_line);                        \
+                       }                                                  \
+      argc--;                                            \
+      i++;                                               \
+    }
+
+bool Options::parse(int argc, char* argv[])
+{
+  Lock lock(mutex);
+
+  progname_ = argv[0];
+  std::queue<std::string> host_port_queue;
+  argc--;
+  for(int i=1; argc > 0; ++i)
+  {
+    std::string str(argv[i]);
+    argc--;
+
+    if(str == "-h" || str == "--help")
+      return false;
+    PARSE_BOOL_PARAM("-t","--chroot", chroot_)
+    PARSE_BOOL_PARAM("-n","--nat", nat_)
+    PARSE_BOOL_PARAM("-o","--no-nat-once", no_nat_once_)
+    PARSE_SCALAR_PARAM("-u","--user", username_)
+    PARSE_SCALAR_PARAM("-c","--chroot-dir", chroot_dir_)
+    PARSE_INVERSE_BOOL_PARAM("-d","--nodaemonize", daemonize_)
+    PARSE_SCALAR_PARAM("-P","--write-pid", pid_file_)
+    PARSE_SCALAR_PARAM("-i","--interface", local_addr_)
+    PARSE_STRING_PARAM("-s","--control", control_interface_)
+    PARSE_SCALAR_PARAM2("-p","--port-range", rtp_start_port_, rtp_end_port_)
+               PARSE_CSLIST_PARAM("-M","--sync-hosts", host_port_queue)
+    PARSE_SCALAR_PARAM("-S","--sync-port", local_sync_port_)
+    PARSE_SCALAR_PARAM("-I","--sync-interface", local_sync_addr_)
+    else 
+      return false;
+  }
+  while(!host_port_queue.empty())
+  {
+    std::stringstream tmp_stream(host_port_queue.front());
+    OptionConnectTo oct;
+    getline(tmp_stream,oct.host,':');
+    if(!tmp_stream.good())
+      return false;
+    tmp_stream >> oct.port;
+    host_port_queue.pop();
+    connect_to_.push_back(oct);
+  }
+  
+  return sanityCheck();
+}
+
+bool Options::sanityCheck()
+{
+  if(control_interface_.port_ == "") control_interface_.port_ = "22222";
+  return true;
+}
+
+void Options::printUsage()
+{
+  std::cout << "USAGE: anyrtpproxy" << std::endl;
+  std::cout << "  [-h|--help]                      prints this..." << std::endl;
+  std::cout << "  [-t|--chroot]                    chroot and drop priviledges" << std::endl;
+  std::cout << "  [-u|--username] <username>       in case of chroot run as this user" << std::endl;
+  std::cout << "  [-c|--chroot-dir] <directory>    directory to make a chroot to" << std::endl;
+  std::cout << "  [-d|--nodaemonize]               don't run in background" << std::endl;
+  std::cout << "  [-P|--write-pid] <path>          write pid to this file" << std::endl;
+  std::cout << "  [-i|--interface] <ip-address>    local ip address to listen to for RTP packets" << std::endl;
+  std::cout << "  [-s|--control] <addr>[:<port>]   the address/port to listen on for control commands" << std::endl;
+  std::cout << "  [-p|--port-range] <start> <end>  port range used to relay rtp connections" << std::endl;
+  std::cout << "  [-n|--nat]                       enable permantent automatic nat detection(use only with anytun)" << std::endl;
+  std::cout << "  [-o|--no-nat-once]               disable automatic nat detection for new connections" << std::endl;
+  std::cout << "  [-I|--sync-interface] <ip-address>  local unicast(sync) ip address to bind to" << std::endl;
+  std::cout << "  [-S|--sync-port] <port>          local unicast(sync) port to bind to" << std::endl;
+  std::cout << "  [-M|--sync-hosts] <hostname|ip>:<port>[,<hostname|ip>:<port>[...]]"<< std::endl;
+  std::cout << "                                   List of Remote Sync Hosts/Ports"<< std::endl;
+}
+
+void Options::printOptions()
+{
+  Lock lock(mutex);
+  std::cout << "Options:" << std::endl;
+  std::cout << "chroot='" << chroot_ << "'" << std::endl;
+  std::cout << "username='" << username_ << "'" << std::endl;
+  std::cout << "chroot-dir='" << chroot_dir_ << "'" << std::endl;
+  std::cout << "daemonize='" << daemonize_ << "'" << std::endl;
+  std::cout << "pid_file='" << pid_file_ << "'" << std::endl;
+  std::cout << "control-interface='" << control_interface_.toString() << "'" << std::endl;
+  std::cout << "local_addr='" << local_addr_ << "'" << std::endl;
+  std::cout << "rtp_start_port=" << rtp_start_port_ << std::endl;
+  std::cout << "rtp_end_port=" << rtp_end_port_ << std::endl;
+  std::cout << "local_sync_addr='" << local_sync_addr_ << "'" << std::endl;
+  std::cout << "local_sync_port='" << local_sync_port_ << "'" << std::endl;
+}
+
+std::string Options::getProgname()
+{
+  Lock lock(mutex);
+  return progname_;
+}
+
+bool Options::getChroot()
+{
+  Lock lock(mutex);
+  return chroot_;
+}
+
+bool Options::getNat()
+{
+  Lock lock(mutex);
+  return nat_;
+}
+
+bool Options::getNoNatOnce()
+{
+  Lock lock(mutex);
+  return no_nat_once_;
+}
+
+std::string Options::getUsername()
+{
+  Lock lock(mutex);
+  return username_;
+}
+
+std::string Options::getChrootDir()
+{
+  Lock lock(mutex);
+  return chroot_dir_;
+}
+
+bool Options::getDaemonize()
+{
+  Lock lock(mutex);
+  return daemonize_;
+}
+
+std::string Options::getPidFile()
+{
+  Lock lock(mutex);
+  return pid_file_;
+}
+
+Host Options::getControlInterface()
+{
+  Lock lock(mutex);
+  return control_interface_;
+}
+
+std::string Options::getLocalAddr()
+{
+  Lock lock(mutex);
+  return local_addr_;
+}
+
+Options& Options::setLocalAddr(std::string l)
+{
+  Lock lock(mutex);
+  local_addr_ = l;
+  return *this;
+}
+
+std::string Options::getLocalSyncAddr()
+{
+  Lock lock(mutex);
+  return local_sync_addr_;
+}
+
+Options& Options::setLocalSyncAddr(std::string l)
+{
+  Lock lock(mutex);
+  local_sync_addr_ = l;
+  return *this;
+}
+
+std::string Options::getLocalSyncPort()
+{
+  Lock lock(mutex);
+  return local_sync_port_;
+}
+
+Options& Options::setLocalSyncPort(std::string l)
+{
+  Lock lock(mutex);
+  local_sync_port_ = l;
+  return *this;
+}
+
+u_int16_t Options::getRtpStartPort()
+{
+  return rtp_start_port_;
+}
+
+Options& Options::setRtpStartPort(u_int16_t l)
+{
+  rtp_start_port_ = l;
+  return *this;
+}
+
+u_int16_t Options::getRtpEndPort()
+{
+  return rtp_end_port_;
+}
+
+Options& Options::setRtpEndPort(u_int16_t l)
+{
+  rtp_end_port_ = l;
+  return *this;
+}
+
+ConnectToList Options::getConnectTo()
+{
+  Lock lock(mutex);
+  return connect_to_;
+}
+
diff --git a/src/anyrtpproxy/options.h b/src/anyrtpproxy/options.h
new file mode 100644 (file)
index 0000000..af09d4f
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _OPTIONS_H_
+#define _OPTIONS_H_
+
+#include "../threadUtils.hpp"
+#include <list>
+#include <sstream>
+
+typedef struct OptionConnectTo
+{
+  std::string host;
+  std::string port;
+};
+
+typedef std::list<OptionConnectTo>  ConnectToList;
+
+class Host
+{
+public:
+  Host(std::string addr, std::string port) : addr_(addr), port_(port) {}
+  Host(std::string addr_port) {
+    splitAndSetAddrPort(addr_port);
+  } 
+  std::string toString() const
+  {
+    std::ostringstream oss;
+    oss << addr_ << ":" << port_;
+    return oss.str();
+  }
+  
+  std::string addr_;
+       std::string port_;
+
+protected:
+  void splitAndSetAddrPort(std::string addr_port);
+};
+
+typedef std::list<Host> HostList;
+
+class Options
+{
+public:
+  static Options& instance();
+
+  bool parse(int argc, char* argv[]);
+  void printUsage();
+  void printOptions();
+
+  std::string getProgname();
+  bool getChroot();
+  bool getNat();
+  bool getNoNatOnce();
+  std::string getUsername();
+  std::string getChrootDir();
+  std::string getPidFile();
+  bool getDaemonize();
+  Host getControlInterface();
+  std::string getLocalAddr();
+  Options& setLocalAddr(std::string l);
+  std::string getLocalSyncAddr();
+       Options& setLocalSyncAddr(std::string l);
+  std::string getLocalSyncPort();
+       Options& setLocalSyncPort(std::string l);
+  u_int16_t getRtpStartPort();
+       Options& setRtpStartPort(u_int16_t l);
+  u_int16_t getRtpEndPort();
+       Options& setRtpEndPort(u_int16_t l);
+  ConnectToList getConnectTo();
+
+private:
+  Options();
+  ~Options();
+  Options(const Options &l);
+  void operator=(const Options &l);
+  bool sanityCheck();
+
+  static Options* inst;
+  static ::Mutex instMutex;
+  class instanceCleaner {
+    public: ~instanceCleaner() {
+      if(Options::inst != 0)
+        delete Options::inst;
+    }
+  };
+  friend class instanceCleaner;
+
+  ::Mutex mutex;
+
+  std::string progname_;
+  bool chroot_;
+  bool nat_;
+  bool no_nat_once_;
+  std::string username_;
+  std::string chroot_dir_;
+  std::string pid_file_;
+  bool daemonize_;
+       std::string local_sync_addr_;
+       std::string local_sync_port_;
+  std::string local_addr_;
+       u_int16_t rtp_start_port_;
+       u_int16_t rtp_end_port_;
+       ConnectToList connect_to_;
+  Host control_interface_;
+};
+
+extern Options& gOpt;
+
+#endif
diff --git a/src/anyrtpproxy/portWindow.cpp b/src/anyrtpproxy/portWindow.cpp
new file mode 100644 (file)
index 0000000..99dafd7
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "portWindow.h"
+
+PortWindow::PortWindow(u_int16_t start, u_int16_t end) : start_port_(start), end_port_(end)
+{
+}
+
+PortWindow::~PortWindow()
+{
+}
+
+PortWindow::PortSet::size_type PortWindow::getLength()
+{
+  Lock lock(mutex_);
+  return ports_.size();
+}
+
+bool PortWindow::hasPort(u_int16_t port)
+{
+  Lock lock(mutex_);
+
+  PortSet::const_iterator it=ports_.find(port);
+  if(it == ports_.end())
+    return false;
+  return true;
+}
+
+bool PortWindow::freePort(u_int16_t port)
+{
+  Lock lock(mutex_);
+
+  PortSet::iterator it=ports_.find(port);
+  if(it == ports_.end())
+    return false;
+       ports_.erase(it);
+  return true;
+}
+
+u_int16_t PortWindow::newPort()
+{
+  Lock lock(mutex_);
+       u_int16_t port= start_port_;
+       while (port<end_port_ && ports_.find(port) !=ports_.end())
+         port++;
+  if (port>=end_port_)
+               return 0;
+       ports_.insert(port);
+       return port;
+}
+
+void PortWindow::clear()
+{
+  Lock lock(mutex_);
+  ports_.clear();
+}
+
diff --git a/src/anyrtpproxy/portWindow.h b/src/anyrtpproxy/portWindow.h
new file mode 100644 (file)
index 0000000..f3bdffb
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _PORT_WINDOW_H_
+#define _PORT_WINDOW_H_
+
+#include <set>
+#include "../threadUtils.hpp"
+#include "../datatypes.h"
+
+class PortWindow
+{
+public:
+  typedef std::set<u_int16_t> PortSet;
+
+  PortWindow(u_int16_t,u_int16_t);
+  ~PortWindow();
+
+  PortSet::size_type getLength();
+  bool hasPort(u_int16_t);
+  bool freePort(u_int16_t);
+  u_int16_t newPort();
+  void clear();
+
+
+private:
+       u_int16_t start_port_;
+       u_int16_t end_port_;
+  ::Mutex mutex_;
+       PortSet ports_;
+
+  PortWindow(const PortWindow &s);
+  void operator=(const PortWindow &s);
+};
+
+#endif
diff --git a/src/anyrtpproxy/rtpSession.cpp b/src/anyrtpproxy/rtpSession.cpp
new file mode 100644 (file)
index 0000000..a3551e3
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "rtpSession.h"
+
+#include "callIdQueue.h"
+
+RtpSession::RtpSession(const std::string& call_id) : in_sync_(false), call_id_(call_id) , dead_(false), complete_(false), 
+                                                     seen1_(false), seen2_(false)
+{  
+}
+
+void RtpSession::reinit()
+{
+  gCallIdQueue.push(call_id_);
+}
+
+bool RtpSession::isDead()
+{
+  Lock lock(mutex_);
+  return (dead_ && in_sync_);
+}
+
+bool RtpSession::isDead(bool d)
+{
+  Lock Lock(mutex_);
+  return dead_ = d;
+}
+
+bool RtpSession::isComplete()
+{
+  Lock lock(mutex_);
+  return complete_;
+}
+
+bool RtpSession::isComplete(bool c)
+{
+  Lock lock(mutex_);
+  return complete_ = c;
+}
+
+bool RtpSession::getSeen1()
+{
+  Lock lock(mutex_);
+  return seen1_;
+}
+
+RtpSession& RtpSession::setSeen1()
+{
+  Lock lock(mutex_);
+  //in_sync_ = false;
+  seen1_ = true;
+  return *this;
+}
+
+bool RtpSession::getSeen2()
+{
+  Lock lock(mutex_);
+  return seen2_;
+}
+
+RtpSession& RtpSession::setSeen2()
+{
+  Lock lock(mutex_);
+  //in_sync_ = false;
+  seen2_ = true;
+  return *this;
+}
+
+RtpSession::proto::endpoint RtpSession::getLocalEnd1()
+{
+  Lock lock(mutex_);
+  return local_end1_;
+}
+
+RtpSession& RtpSession::setLocalEnd1(RtpSession::proto::endpoint e)
+{
+  Lock lock(mutex_);
+  in_sync_ = false;
+  local_end1_ = e;
+  return *this;
+}
+
+RtpSession::proto::endpoint RtpSession::getLocalEnd2()
+{
+  Lock lock(mutex_);
+  return local_end2_;
+}
+
+RtpSession& RtpSession::setLocalEnd2(RtpSession::proto::endpoint e)
+{
+  Lock lock(mutex_);
+  in_sync_ = false;
+  local_end2_ = e;
+  return *this;
+}
+
+RtpSession::proto::endpoint RtpSession::getRemoteEnd1()
+{
+  Lock lock(mutex_);
+  return remote_end1_;
+}
+
+RtpSession& RtpSession::setRemoteEnd1(RtpSession::proto::endpoint e)
+{
+  Lock lock(mutex_);
+  in_sync_ = false;
+  remote_end1_ = e;
+  return *this;
+}
+
+RtpSession::proto::endpoint RtpSession::getRemoteEnd2()
+{
+  Lock lock(mutex_);
+  return remote_end2_;
+}
+
+RtpSession& RtpSession::setRemoteEnd2(RtpSession::proto::endpoint e)
+{
+  Lock lock(mutex_);
+  in_sync_ = false;
+  remote_end2_ = e;
+  return *this;
+}
+
+
diff --git a/src/anyrtpproxy/rtpSession.h b/src/anyrtpproxy/rtpSession.h
new file mode 100644 (file)
index 0000000..3716c9b
--- /dev/null
@@ -0,0 +1,133 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _RTPSESSION_H_
+#define _RTPSESSION_H_
+
+#include <boost/asio.hpp>
+
+#include "../threadUtils.hpp"
+
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/archive/text_iarchive.hpp>
+
+class RtpSession
+{
+public:
+  typedef boost::asio::ip::udp proto;
+
+       RtpSession(const std::string& call_id);
+
+  bool isDead();
+  bool isDead(bool d);
+
+  bool isComplete();
+  bool isComplete(bool c);
+
+  proto::endpoint getLocalEnd1();
+  RtpSession& setLocalEnd1(proto::endpoint e);
+  proto::endpoint getLocalEnd2();
+  RtpSession& setLocalEnd2(proto::endpoint e);
+
+  proto::endpoint getRemoteEnd1();
+  RtpSession& setRemoteEnd1(proto::endpoint e);
+  proto::endpoint getRemoteEnd2();
+  RtpSession& setRemoteEnd2(proto::endpoint e);
+
+       RtpSession& setSeen1();
+  bool getSeen1();
+
+       RtpSession& setSeen2();
+  bool getSeen2();
+
+private:
+       RtpSession(const RtpSession & src);
+  
+  void reinit();
+
+  //TODO: check if this is ok
+  friend class boost::serialization::access;
+  template<class Archive>
+  void serialize(Archive & ar, const unsigned int version)
+       {    
+    Lock lock(mutex_);
+
+        // address of local_end1 and local_end2 are always equal
+               std::string local_addr(local_end1_.address().to_string());
+               u_int16_t local_port1 = local_end1_.port();
+               u_int16_t local_port2 = local_end2_.port();
+
+               std::string remote_addr1(remote_end1_.address().to_string());
+               u_int16_t remote_port1 = remote_end1_.port();
+               std::string remote_addr2(remote_end2_.address().to_string());
+               u_int16_t remote_port2 = remote_end2_.port();
+
+    ar & dead_;
+    ar & complete_;
+    ar & local_addr;
+    ar & local_port1;
+    ar & local_port2;
+    ar & remote_addr1;
+    ar & remote_port1;
+    ar & remote_addr2;
+    ar & remote_port2;
+               ar & seen1_;
+               ar & seen2_;
+
+               proto::endpoint local_end1(boost::asio::ip::address::from_string(local_addr), local_port1);
+    local_end1_ = local_end1;
+               proto::endpoint local_end2(boost::asio::ip::address::from_string(local_addr), local_port2);
+               local_end2_ = local_end2;
+
+               proto::endpoint remote_end1(boost::asio::ip::address::from_string(remote_addr1), remote_port1);
+               remote_end1_ = remote_end1;
+               proto::endpoint remote_end2(boost::asio::ip::address::from_string(remote_addr2), remote_port2);
+               remote_end2_ = remote_end2;
+
+    if(complete_ && !dead_)
+      reinit();
+
+    in_sync_ = true;
+       }
+
+  bool in_sync_;
+       ::Mutex mutex_;
+
+  const std::string& call_id_;
+  bool dead_;
+  bool complete_;
+  proto::endpoint local_end1_, local_end2_;
+  proto::endpoint remote_end1_, remote_end2_;
+       bool seen1_,seen2_; //has at least 1 packet been recieved?
+};
+
+
+#endif
diff --git a/src/anyrtpproxy/rtpSessionTable.cpp b/src/anyrtpproxy/rtpSessionTable.cpp
new file mode 100644 (file)
index 0000000..9237866
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "../threadUtils.hpp"
+#include "../datatypes.h"
+
+#include "rtpSessionTable.h"
+
+RtpSessionTable* RtpSessionTable::inst = NULL;
+Mutex RtpSessionTable::instMutex;
+RtpSessionTable& gRtpSessionTable = RtpSessionTable::instance();
+
+
+RtpSessionTable& RtpSessionTable::instance()
+{
+  Lock lock(instMutex);
+  static instanceCleaner c;
+  if(!inst)
+    inst = new RtpSessionTable();
+
+  return *inst;
+}
+
+RtpSessionTable::RtpSessionTable()
+{
+}
+
+RtpSessionTable::~RtpSessionTable()
+{
+} 
+
+void RtpSessionTable::delSession(const std::string & call_id)
+{
+  Lock lock(mutex_);
+
+  RtpSessionMap::iterator it = map_.find(call_id);
+  if(it!=map_.end())
+    delete it->second;
+
+  map_.erase(it);
+}
+
+RtpSession& RtpSessionTable::getOrNewSession(const std::string & call_id, bool& is_new)
+{
+  Lock lock(mutex_);
+  return getOrNewSessionUnlocked(call_id, is_new);
+}
+
+RtpSession& RtpSessionTable::getOrNewSessionUnlocked(const std::string & call_id, bool& is_new)
+{
+  is_new = false;
+  RtpSessionMap::iterator it = map_.find(call_id);
+  if(it!=map_.end())
+    return *(it->second);
+
+  is_new = true;
+  std::pair<RtpSessionMap::iterator, bool> ret = map_.insert(RtpSessionMap::value_type(call_id, NULL));
+  ret.first->second = new RtpSession(ret.first->first);
+  return *(ret.first->second);
+}
+
+RtpSession& RtpSessionTable::getSession(const std::string & call_id)
+{
+  RtpSessionMap::iterator it = map_.find(call_id);
+  if(it!=map_.end())
+    return *(it->second);
+
+  throw std::runtime_error("session not found");
+}
+
+RtpSessionMap::iterator RtpSessionTable::getBeginUnlocked()
+{
+  return map_.begin();
+}
+
+RtpSessionMap::iterator RtpSessionTable::getEndUnlocked()
+{
+  return map_.end();
+}
+
+void RtpSessionTable::clear()
+{
+  Lock lock(mutex_);
+       map_.clear();
+}
+
+bool RtpSessionTable::empty()
+{
+  Lock lock(mutex_);
+       return map_.empty();
+}
+
+Mutex& RtpSessionTable::getMutex()
+{
+  return mutex_;
+}
diff --git a/src/anyrtpproxy/rtpSessionTable.h b/src/anyrtpproxy/rtpSessionTable.h
new file mode 100644 (file)
index 0000000..a37318d
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _RTPSESSIONTABLE_H
+#define _RTPSESSIONTABLE_H
+
+#include <map>
+
+#include "../threadUtils.hpp"
+#include "../datatypes.h"
+#include "rtpSession.h"
+typedef std::map<std::string,RtpSession*> RtpSessionMap;
+
+class RtpSessionTable
+{
+public:
+       static RtpSessionTable& instance();
+       RtpSessionTable();
+       ~RtpSessionTable();
+       void delSession(const std::string & call_id);
+       bool empty();
+       void clear();
+  ::Mutex& getMutex();
+       RtpSessionMap::iterator getBeginUnlocked();
+       RtpSessionMap::iterator getEndUnlocked();
+       RtpSession& getOrNewSession(const std::string & call_id, bool& isnew);
+       RtpSession& getOrNewSessionUnlocked(const std::string & call_id, bool& isnew);
+       RtpSession& getSession(const std::string & call_id);
+
+private:
+  static ::Mutex instMutex;
+       static RtpSessionTable* inst;
+  class instanceCleaner {
+    public: ~instanceCleaner() {
+     if(RtpSessionTable::inst != 0)
+       delete RtpSessionTable::inst;
+   }
+       };
+       RtpSessionTable(const RtpSessionTable &s);
+  void operator=(const RtpSessionTable &s);
+       RtpSessionMap map_;
+  ::Mutex mutex_;
+};
+
+extern RtpSessionTable& gRtpSessionTable;
+
+#endif
diff --git a/src/anyrtpproxy/syncRtpCommand.cpp b/src/anyrtpproxy/syncRtpCommand.cpp
new file mode 100644 (file)
index 0000000..f612c8a
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "syncRtpCommand.h"
+
+SyncRtpCommand::SyncRtpCommand()
+{      
+}
+
+SyncRtpCommand::SyncRtpCommand( const std::string & addr )
+:callid_(addr)
+{      
+}
+
+
+std::string SyncRtpCommand::getCallId() const 
+{
+       return callid_;
+}
diff --git a/src/anyrtpproxy/syncRtpCommand.h b/src/anyrtpproxy/syncRtpCommand.h
new file mode 100644 (file)
index 0000000..282243b
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _SYNCRTPCOMMAND_H
+#define _SYNCRTPCOMMAND_H
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/archive/text_iarchive.hpp>
+
+#include "../threadUtils.hpp"
+#include "rtpSessionTable.h"
+
+class SyncRtpCommand
+{
+public:
+       SyncRtpCommand(const std::string & );
+       SyncRtpCommand();
+       std::string getCallId() const;
+
+private:
+       SyncRtpCommand(const SyncRtpCommand &);
+       std::string callid_;
+  friend class boost::serialization::access;
+  template<class Archive>
+  void serialize(Archive & ar, const unsigned int version)
+  {
+               Lock lock(gRtpSessionTable.getMutex());
+               ar & callid_;
+    bool is_new;
+               ar & gRtpSessionTable.getOrNewSessionUnlocked(callid_, is_new);
+       };
+};
+
+
+#endif // _SYNCCOMMAND_H
diff --git a/src/anytun-config.cpp b/src/anytun-config.cpp
new file mode 100644 (file)
index 0000000..72e4902
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <iostream>
+#include <poll.h>
+
+#include "datatypes.h"
+
+#include "log.h"
+#include "buffer.h"
+#include "keyDerivation.h"
+#include "keyDerivationFactory.h"
+#include "options.h"
+#include "connectionList.h"
+#include "routingTable.h"
+#include "networkAddress.h"
+#include "packetSource.h"
+#include "resolver.h"
+
+#include "syncQueue.h"
+#include "syncCommand.h"
+
+
+
+void createConnection(const PacketSourceEndpoint & remote_end, ConnectionList & cl, u_int16_t seqSize, SyncQueue & queue, mux_t mux, Semaphore& sem)
+{
+  SeqWindow * seq = new SeqWindow(seqSize);
+  seq_nr_t seq_nr_ = 0;
+  KeyDerivation * kd = KeyDerivationFactory::create(gOpt.getKdPrf());
+  kd->init(gOpt.getKey(), gOpt.getSalt(), gOpt.getPassphrase());
+  kd->setRole(gOpt.getRole());
+  cLog.msg(Log::PRIO_NOTICE) << "added connection remote host " << remote_end;
+  ConnectionParam connparam ((*kd), (*seq), seq_nr_, remote_end);
+  cl.addConnection(connparam, mux);
+
+  std::ostringstream sout;
+  boost::archive::text_oarchive oa(sout);
+  const SyncCommand scom(cl, mux);
+
+  oa << scom;
+  std::cout <<  std::setw(5) << std::setfill('0') << sout.str().size()<< ' ' << sout.str() << std::endl;
+
+  NetworkList routes = gOpt.getRoutes();
+  NetworkList::const_iterator rit;
+  for(rit = routes.begin(); rit != routes.end(); ++rit)
+  {
+    NetworkAddress addr(rit->net_addr.c_str());
+    NetworkPrefix prefix(addr, rit->prefix_length);
+    
+    gRoutingTable.addRoute(prefix, mux);
+    
+    std::ostringstream sout2;
+    boost::archive::text_oarchive oa2(sout2);
+    const SyncCommand scom2(prefix);
+    
+    oa2 << scom2;
+    std::cout <<  std::setw(5) << std::setfill('0') << sout2.str().size()<< ' ' << sout2.str() << std::endl;
+  }    
+  sem.up();
+}
+
+void createConnectionError(const std::exception& e, Semaphore& sem, int& ret)
+{
+  cLog.msg(Log::PRIO_ERROR) << "uncaught runtime error: " << e.what();
+  ret = -1;
+  sem.up();
+}
+
+int main(int argc, char* argv[])
+{
+  try 
+  {
+    bool result = gOpt.parse(argc, argv);
+    if(!result) {
+      gOpt.printUsage();
+      exit(0);
+    }
+    StringList targets = gOpt.getLogTargets();
+    if(targets.empty()) {
+      cLog.addTarget("stderr:2");
+    }
+    else {
+      StringList::const_iterator it;
+      for(it = targets.begin();it != targets.end(); ++it)
+        cLog.addTarget(*it);
+    }
+  }
+  catch(syntax_error& e)
+  {
+    std::cerr << e << std::endl;
+    gOpt.printUsage();
+    exit(-1);
+  }
+
+  gOpt.parse_post(); // print warnings  
+
+  gResolver.init();
+
+       ConnectionList cl;
+       SyncQueue queue;
+
+  Semaphore sem;
+  int ret = 0;
+       UDPPacketSource::proto::endpoint endpoint;
+       // allow emtpy endpoint!!!
+       gResolver.resolveUdp(gOpt.getRemoteAddr(), gOpt.getRemotePort(), 
+                                                                                        boost::bind(createConnection, _1, boost::ref(cl), gOpt.getSeqWindowSize(), boost::ref(queue), gOpt.getMux(), boost::ref(sem)),
+                                                                                        boost::bind(createConnectionError, _1, boost::ref(sem), boost::ref(ret)), 
+                                                                                        gOpt.getResolvAddrType());
+       sem.down();
+  return ret;
+}
+
diff --git a/src/anytun-controld.cpp b/src/anytun-controld.cpp
new file mode 100644 (file)
index 0000000..f32ec83
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <iostream>
+#include <fstream>
+#include <poll.h>
+#include <fcntl.h>
+#include <pwd.h>
+#include <grp.h>
+#include <string>
+
+#include "datatypes.h"
+
+#include "log.h"
+#include "signalController.h"
+#include "options.h"
+#include "resolver.h"
+
+#include "syncServer.h"
+#include "daemon.hpp"
+
+void syncOnConnect(SyncTcpConnection * connptr)
+{
+  std::ifstream file(gOpt.getFileName().c_str());
+  if(file.is_open()) {
+    std::string line;
+    while (!file.eof()) {
+      getline (file,line);
+      connptr->Send(line);
+    }
+    file.close();
+  }
+}
+
+void syncListener()
+{
+ boost::asio::io_service io_service;
+  try
+  {
+    SyncServer server(gOpt.getBindToAddr(), gOpt.getBindToPort(), boost::bind(syncOnConnect, _1));
+    server.run();
+  }
+  catch(std::runtime_error& e) {
+    cLog.msg(Log::PRIO_ERROR) << "sync listener thread died due to an uncaught runtime_error: " << e.what();
+  }
+  catch(std::exception& e) {
+    cLog.msg(Log::PRIO_ERROR) << "sync listener thread died due to an uncaught exception: " << e.what();
+  }
+}
+
+int main(int argc, char* argv[])
+{
+  bool daemonized=false;
+  try 
+  {
+    try 
+    {
+      bool result = gOpt.parse(argc, argv);
+      if(!result) {
+        gOpt.printUsage();
+        exit(0);
+      }
+      StringList targets = gOpt.getLogTargets();
+      if(targets.empty()) {
+        cLog.addTarget("syslog:3,anytun-controld,daemon");
+      }
+      else {
+        StringList::const_iterator it;
+        for(it = targets.begin();it != targets.end(); ++it)
+          cLog.addTarget(*it);
+      }
+    }
+    catch(syntax_error& e)
+    {
+      std::cerr << e << std::endl;
+      gOpt.printUsage();
+      exit(-1);
+    }
+       
+    cLog.msg(Log::PRIO_NOTICE) << "anytun-controld started..."; 
+    gOpt.parse_post(); // print warnings
+
+
+    std::ifstream file( gOpt.getFileName().c_str() );
+    if( file.is_open() )
+      file.close();
+    else {
+      std::cout << "ERROR: unable to open file!" << std::endl;
+      exit(-1);
+    }
+    
+    PrivInfo privs(gOpt.getUsername(), gOpt.getGroupname());
+    if(gOpt.getDaemonize()) {
+      daemonize();
+      daemonized = true;
+    }
+
+    gSignalController.init();
+    gResolver.init();
+    
+    if(gOpt.getChrootDir() != "")
+      do_chroot(gOpt.getChrootDir());
+    
+    privs.drop();
+
+    boost::thread * syncListenerThread;
+    syncListenerThread = new boost::thread(boost::bind(syncListener));
+    
+    int ret = gSignalController.run();
+    
+    return ret;
+  }
+  catch(std::runtime_error& e)
+  {
+    if(daemonized)
+      cLog.msg(Log::PRIO_ERROR) << "uncaught runtime error, exiting: " << e.what();
+    else
+      std::cout << "uncaught runtime error, exiting: " << e.what() << std::endl;
+  }
+  catch(std::exception& e)
+  {
+    if(daemonized)
+      cLog.msg(Log::PRIO_ERROR) << "uncaught exception, exiting: " << e.what();
+    else
+      std::cout << "uncaught exception, exiting: " << e.what() << std::endl;
+  }
+}
+
diff --git a/src/anytun-showtables.cpp b/src/anytun-showtables.cpp
new file mode 100644 (file)
index 0000000..5d061d6
--- /dev/null
@@ -0,0 +1,136 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "datatypes.h"
+
+#include "log.h"
+#include "buffer.h"
+#include "keyDerivation.h"
+#include "seqWindow.h"
+#include "connectionList.h"
+#include "routingTable.h"
+#include "networkAddress.h"
+#include "syncCommand.h"
+
+#include <sstream>
+#include <iostream>
+#include <string>
+
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/archive/text_iarchive.hpp>
+
+
+void output()
+{
+       ConnectionList &cl(gConnectionList);
+       if( !cl.empty() )
+       {
+               ConnectionMap::iterator it = cl.getBeginUnlocked();
+               mux_t mux = it->first;
+               ConnectionParam &conn( it->second );
+               std::cout << "Client " << mux << ": " ;
+               if( conn.remote_end_==PacketSourceEndpoint())
+               {
+                       std::cout<< "not registered";
+               } else {
+                 std::cout<< conn.remote_end_;
+               }
+               std::cout << std::endl;
+    //std::cout << "Connection: Keyderivation-Type: " << conn.kd_.printType() << std::endl;
+    cl.clear();
+       } else {
+         network_address_type_t types[] = {ipv4,ipv6,ethernet};
+               for (int types_idx=0; types_idx<3; types_idx++)
+               { 
+                       network_address_type_t type = types[types_idx];
+                       if( !gRoutingTable.empty(type) ) 
+                       {
+                               RoutingMap::iterator it = gRoutingTable.getBeginUnlocked(type);
+                               NetworkPrefix pref( it->first );
+                               std::cout << "Route: " << pref.toString() << "/" << (int)pref.getNetworkPrefixLength() << " -> ";
+                               mux_t mux = it->second;
+                               std::cout << mux << std::endl;
+                               gRoutingTable.clear(type);
+                       }
+               }
+       }
+}
+
+void readExactly(size_t toread, std::iostream & result)
+{
+  size_t hasread = 0;
+  while (toread > hasread && std::cin.good())
+  {
+                       char a[1];
+                       std::cin.read(a,1);
+      result.write(a,1);
+      hasread++;
+  }
+}
+
+void readAndProcessOne()
+{
+  size_t message_lenght ;
+       std::stringstream message_lenght_stream;
+       readExactly(5,message_lenght_stream);
+       message_lenght_stream >> message_lenght;
+       std::stringstream void_stream;
+       readExactly(1,void_stream); //skip space
+       if (!message_lenght)
+               return;
+       std::stringstream sync_command_stream;
+       readExactly(message_lenght, sync_command_stream);
+       //std::cout << message_lenght << std::endl;
+       //std::cout << sync_command_stream.str()<< std::endl;
+       boost::archive::text_iarchive ia(sync_command_stream);
+       SyncCommand scom(gConnectionList);
+       ia >> scom;
+}
+
+int main(int argc, char* argv[])
+{
+  int ret = 0;
+
+  while( std::cin.good() )
+  {
+               try
+               {
+                       readAndProcessOne();
+               }
+               catch(std::exception& e)
+               {
+                               std::cout << "uncaught exception, exiting: " << e.what() << std::endl;
+               }       
+               output();
+  }
+  return ret;
+}
+
diff --git a/src/anytun.cpp b/src/anytun.cpp
new file mode 100644 (file)
index 0000000..34fd5f5
--- /dev/null
@@ -0,0 +1,527 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <iostream>
+#include <fstream>
+
+
+#include <boost/bind.hpp>
+#include <cerrno>     // for ENOMEM
+
+#include "datatypes.h"
+
+#include "log.h"
+#include "resolver.h"
+#include "buffer.h"
+#include "plainPacket.h"
+#include "encryptedPacket.h"
+#include "cipher.h"
+#include "keyDerivation.h"
+#include "authAlgo.h"
+#include "cipherFactory.h"
+#include "authAlgoFactory.h"
+#include "keyDerivationFactory.h"
+#include "signalController.h"
+#ifdef WIN_SERVICE
+#include "win32/winService.h"
+#endif
+#include "packetSource.h"
+#include "tunDevice.h"
+#include "options.h"
+#include "seqWindow.h"
+#include "connectionList.h"
+#ifndef NO_ROUTING
+#include "routingTable.h"
+#include "networkAddress.h"
+#endif
+
+
+#ifndef ANYTUN_NOSYNC
+#include "syncQueue.h"
+#include "syncCommand.h"
+#include "syncServer.h"
+#include "syncClient.h"
+#include "syncOnConnect.hpp"
+#endif
+
+#define MAX_PACKET_LENGTH 1600
+
+#include "cryptinit.hpp"
+#include "daemon.hpp"
+#include "sysexec.hpp"
+
+bool disableRouting = false;
+
+void createConnection(const PacketSourceEndpoint& remote_end, window_size_t seqSize, mux_t mux)
+{
+       SeqWindow* seq = new SeqWindow(seqSize);
+       seq_nr_t seq_nr_=0;
+  KeyDerivation * kd = KeyDerivationFactory::create(gOpt.getKdPrf());
+  kd->init(gOpt.getKey(), gOpt.getSalt(), gOpt.getPassphrase());
+  kd->setRole(gOpt.getRole());
+  cLog.msg(Log::PRIO_NOTICE) << "added connection remote host " << remote_end;
+
+       ConnectionParam connparam ((*kd), (*seq), seq_nr_, remote_end);
+       gConnectionList.addConnection(connparam,mux);
+#ifndef ANYTUN_NOSYNC
+  SyncCommand sc (gConnectionList,mux);
+       gSyncQueue.push(sc);
+#endif
+}
+
+void createConnectionError(const std::exception& e)
+{
+  gSignalController.inject(SIGERROR, e.what());
+}
+
+#ifndef ANYTUN_NOSYNC
+void syncConnector(const OptionHost& connto)
+{
+  SyncClient sc(connto.addr, connto.port);
+  sc.run();
+}
+
+void syncListener()
+{
+  try
+  {
+    SyncServer server(gOpt.getLocalSyncAddr(), gOpt.getLocalSyncPort(), boost::bind(syncOnConnect, _1));
+    gSyncQueue.setSyncServerPtr(&server);
+    server.run();
+  }
+  catch(std::runtime_error& e) {
+    cLog.msg(Log::PRIO_ERROR) << "sync listener thread died due to an uncaught runtime_error: " << e.what();
+  }
+  catch(std::exception& e) {
+    cLog.msg(Log::PRIO_ERROR) << "sync listener thread died due to an uncaught exception: " << e.what();
+  }
+}
+#endif
+
+void sender(TunDevice* dev, PacketSource* src)
+{
+  if(!dev || !src) {
+    cLog.msg(Log::PRIO_ERROR) << "sender thread died because either dev or src pointer is null";    
+    return;
+  }
+
+  try 
+  {
+    std::auto_ptr<Cipher> c(CipherFactory::create(gOpt.getCipher(), KD_OUTBOUND));
+    std::auto_ptr<AuthAlgo> a(AuthAlgoFactory::create(gOpt.getAuthAlgo(), KD_OUTBOUND) );
+    
+    PlainPacket plain_packet(MAX_PACKET_LENGTH);
+    EncryptedPacket encrypted_packet(MAX_PACKET_LENGTH, gOpt.getAuthTagLength());
+    
+    u_int16_t mux = gOpt.getMux();
+    PacketSourceEndpoint emptyEndpoint;
+    while(1) {
+      plain_packet.setLength(MAX_PACKET_LENGTH);
+      encrypted_packet.withAuthTag(false);
+      encrypted_packet.setLength(MAX_PACKET_LENGTH);
+      
+          // read packet from device
+      int len = dev->read(plain_packet.getPayload(), plain_packet.getPayloadLength());
+      if(len < 0)
+        continue; // silently ignore device read errors, this is probably no good idea...
+
+      if(static_cast<u_int32_t>(len) < PlainPacket::getHeaderLength())
+        continue; // ignore short packets
+      plain_packet.setPayloadLength(len);
+          // set payload type
+      if(dev->getType() == TYPE_TUN)
+        plain_packet.setPayloadType(PAYLOAD_TYPE_TUN);
+      else if(dev->getType() == TYPE_TAP)
+        plain_packet.setPayloadType(PAYLOAD_TYPE_TAP);
+      else 
+        plain_packet.setPayloadType(0);
+      
+      if(gConnectionList.empty())
+        continue;
+          //std::cout << "got Packet for plain "<<plain_packet.getDstAddr().toString();
+                       ConnectionMap::iterator cit;
+#ifndef NO_ROUTING
+                       if (!disableRouting)
+                               try {
+                                       mux = gRoutingTable.getRoute(plain_packet.getDstAddr());
+                                                       //std::cout << " -> "<<mux << std::endl;
+                                       cit = gConnectionList.getConnection(mux);
+                               } catch (std::exception&) { continue; } // no route
+                       else
+                               cit = gConnectionList.getBegin();
+#else
+                               cit = gConnectionList.getBegin();
+#endif
+
+      if(cit==gConnectionList.getEnd())
+        continue; //no connection
+      ConnectionParam & conn = cit->second;
+      
+      if(conn.remote_end_ == emptyEndpoint) {
+        //cLog.msg(Log::PRIO_INFO) << "no remote address set";
+        continue;
+      }
+
+          // encrypt packet
+      c->encrypt(conn.kd_, plain_packet, encrypted_packet, conn.seq_nr_, gOpt.getSenderId(), mux);
+      
+      encrypted_packet.setHeader(conn.seq_nr_, gOpt.getSenderId(), mux);
+      conn.seq_nr_++;
+      
+          // add authentication tag
+      a->generate(conn.kd_, encrypted_packet);
+
+      try {
+        src->send(encrypted_packet.getBuf(), encrypted_packet.getLength(), conn.remote_end_);
+      } catch (std::exception& /*e*/) {
+                               //TODO: do something here
+                       //cLog.msg(Log::PRIO_ERROR) << "could not send data: " << e.what();
+               } 
+    }
+  }
+  catch(std::runtime_error& e) {
+    cLog.msg(Log::PRIO_ERROR) << "sender thread died due to an uncaught runtime_error: " << e.what();
+  }
+  catch(std::exception& e) {
+    cLog.msg(Log::PRIO_ERROR) << "sender thread died due to an uncaught exception: " << e.what();
+  }
+}
+
+void receiver(TunDevice* dev, PacketSource* src)
+{
+  if(!dev || !src) {
+    cLog.msg(Log::PRIO_ERROR) << "receiver thread died because either dev or src pointer is null";    
+    return;
+  }
+
+  try 
+  {
+    std::auto_ptr<Cipher> c(CipherFactory::create(gOpt.getCipher(), KD_INBOUND));
+    std::auto_ptr<AuthAlgo> a(AuthAlgoFactory::create(gOpt.getAuthAlgo(), KD_INBOUND));
+    
+    EncryptedPacket encrypted_packet(MAX_PACKET_LENGTH, gOpt.getAuthTagLength());
+    PlainPacket plain_packet(MAX_PACKET_LENGTH);
+    
+    while(1) {
+      PacketSourceEndpoint remote_end;
+
+      plain_packet.setLength(MAX_PACKET_LENGTH);
+      encrypted_packet.withAuthTag(false);
+      encrypted_packet.setLength(MAX_PACKET_LENGTH);
+      
+          // read packet from socket
+      int len;
+      try {
+        len = src->recv(encrypted_packet.getBuf(), encrypted_packet.getLength(), remote_end);
+      } catch (std::exception& /*e*/) { 
+                               //TODO: do something here
+                       //cLog.msg(Log::PRIO_ERROR) << "could not recive packet "<< e.what();
+                       continue; 
+               }
+      if(len < 0)
+        continue; // silently ignore socket recv errors, this is probably no good idea...
+
+      if(static_cast<u_int32_t>(len) < EncryptedPacket::getHeaderLength())
+        continue; // ignore short packets
+      encrypted_packet.setLength(len);
+      
+      mux_t mux = encrypted_packet.getMux();
+          // autodetect peer
+      if( gConnectionList.empty() && gOpt.getRemoteAddr() == "") {
+        cLog.msg(Log::PRIO_NOTICE) << "autodetected remote host " << remote_end;
+        createConnection(remote_end, gOpt.getSeqWindowSize(),mux);
+      }
+      
+      ConnectionMap::iterator cit = gConnectionList.getConnection(mux);
+      if (cit == gConnectionList.getEnd())
+        continue;
+      ConnectionParam & conn = cit->second;
+      
+          // check whether auth tag is ok or not
+      if(!a->checkTag(conn.kd_, encrypted_packet)) {
+        cLog.msg(Log::PRIO_NOTICE) << "wrong Authentication Tag!" << std::endl;
+        continue;
+      }        
+
+          // Replay Protection
+      if(conn.seq_window_.checkAndAdd(encrypted_packet.getSenderId(), encrypted_packet.getSeqNr())) {
+        cLog.msg(Log::PRIO_NOTICE) << "Replay attack from " << conn.remote_end_ 
+                                   << " seq:"<< encrypted_packet.getSeqNr() << " sid: "<< encrypted_packet.getSenderId();
+        continue;
+      }
+      
+          //Allow dynamic IP changes 
+          //TODO: add command line option to turn this off
+      if (remote_end != conn.remote_end_) {
+        cLog.msg(Log::PRIO_NOTICE) << "connection "<< mux << " autodetected remote host ip changed " << remote_end;
+        conn.remote_end_=remote_end;
+#ifndef ANYTUN_NOSYNC
+        SyncCommand sc (gConnectionList,mux);
+        gSyncQueue.push(sc);
+#endif
+      }        
+         // ignore zero length packets
+      if(encrypted_packet.getPayloadLength() <= PlainPacket::getHeaderLength())
+        continue;
+
+          // decrypt packet
+      c->decrypt(conn.kd_, encrypted_packet, plain_packet);
+      
+          // check payload_type
+      if((dev->getType() == TYPE_TUN && plain_packet.getPayloadType() != PAYLOAD_TYPE_TUN4 && 
+                                              plain_packet.getPayloadType() != PAYLOAD_TYPE_TUN6) ||
+         (dev->getType() == TYPE_TAP && plain_packet.getPayloadType() != PAYLOAD_TYPE_TAP))
+        continue;
+      
+          // write it on the device
+      dev->write(plain_packet.getPayload(), plain_packet.getLength());
+    }
+  }
+  catch(std::runtime_error& e) {
+    cLog.msg(Log::PRIO_ERROR) << "receiver thread died due to an uncaught runtime_error: " << e.what();
+  }
+  catch(std::exception& e) {
+    cLog.msg(Log::PRIO_ERROR) << "receiver thread died due to an uncaught exception: " << e.what();
+  }
+}
+
+#ifndef NO_DAEMON
+void startSendRecvThreads(PrivInfo& privs, TunDevice* dev, PacketSource* src)
+#else
+void startSendRecvThreads(TunDevice* dev, PacketSource* src)
+#endif
+{
+  src->waitUntilReady();
+  
+#ifndef NO_DAEMON
+  if(gOpt.getChrootDir() != "") {
+    try {
+      do_chroot(gOpt.getChrootDir());
+    }
+    catch(const std::runtime_error& e) {
+      cLog.msg(Log::PRIO_WARNING) << "ignroing chroot error: " << e.what();
+    }
+  }
+#ifndef NO_PRIVDROP
+  privs.drop();
+#endif
+#endif
+  
+  boost::thread(boost::bind(sender, dev, src));
+  boost::thread(boost::bind(receiver, dev, src)); 
+}
+
+
+
+#ifdef WIN_SERVICE
+int main(int argc, char* argv[])
+{
+  try {
+    if(argc > 1) {
+      if(std::string(argv[1]) == "install") {
+        WinService::install();  
+        return 0;
+      }
+      else if(std::string(argv[1]) == "uninstall") {
+        WinService::uninstall();  
+        return 0;
+      }
+    }
+    WinService::start();
+    return 0;
+  }
+  catch(std::runtime_error& e)
+  {
+    std::cout << "caught runtime error, exiting: " << e.what() << std::endl;
+  }
+  catch(std::exception& e)
+  {
+    std::cout << "caught exception, exiting: " << e.what() << std::endl;
+  }
+}
+
+int real_main(int argc, char* argv[])
+#else
+int main(int argc, char* argv[])
+#endif
+{
+#ifdef WIN_SERVICE
+  bool daemonized=true;
+#else
+  bool daemonized=false;
+#endif  
+  try 
+  {
+    try 
+    {
+      bool result = gOpt.parse(argc, argv);
+      if(!result) {
+        gOpt.printUsage();
+        exit(0);
+      }
+      StringList targets = gOpt.getLogTargets();
+      if(targets.empty()) {
+#ifndef _MSC_VER
+        cLog.addTarget("syslog:3,anytun,daemon");
+#else
+ #ifdef WIN_SERVICE
+        cLog.addTarget("eventlog:3,anytun");
+ #else
+        cLog.addTarget("stdout:3");
+ #endif
+#endif
+      }
+      else {
+        StringList::const_iterator it;
+        for(it = targets.begin();it != targets.end(); ++it)
+          cLog.addTarget(*it);
+      }
+    }
+    catch(syntax_error& e)
+    {
+      std::cerr << e << std::endl;
+      gOpt.printUsage();
+      exit(-1);
+    }
+
+    cLog.msg(Log::PRIO_NOTICE) << "anytun started...";
+    gOpt.parse_post(); // print warnings
+
+        // daemonizing has to done before any thread gets started
+#ifndef NO_DAEMON
+#ifndef NO_PRIVDROP
+               PrivInfo privs(gOpt.getUsername(), gOpt.getGroupname());
+#endif
+    if(gOpt.getDaemonize()) {
+      daemonize();
+      daemonized = true;
+    }
+#endif
+
+        // this has to be called before the first thread is started
+    gSignalController.init();
+    gResolver.init();
+   
+#ifndef NO_CRYPT
+#ifndef USE_SSL_CRYPTO
+// this must be called before any other libgcrypt call
+    if(!initLibGCrypt())
+      return -1;
+#endif
+#endif
+
+    OptionNetwork net = gOpt.getIfconfigParam();
+    TunDevice dev(gOpt.getDevName(), gOpt.getDevType(), net.net_addr, net.prefix_length);
+    cLog.msg(Log::PRIO_NOTICE) << "dev opened - name '" << dev.getActualName() << "', node '" << dev.getActualNode() << "'";
+    cLog.msg(Log::PRIO_NOTICE) << "dev type is '" << dev.getTypeString() << "'";
+#ifndef NO_EXEC
+    if(gOpt.getPostUpScript() != "") {
+      cLog.msg(Log::PRIO_NOTICE) << "executing post-up script '" << gOpt.getPostUpScript() << "'";
+      execScript(gOpt.getPostUpScript(), dev.getActualName(), dev.getActualNode());
+    }
+#endif
+    
+    PacketSource* src = new UDPPacketSource(gOpt.getLocalAddr(), gOpt.getLocalPort());
+
+    if(gOpt.getRemoteAddr() != "")
+      gResolver.resolveUdp(gOpt.getRemoteAddr(), gOpt.getRemotePort(), boost::bind(createConnection, _1, gOpt.getSeqWindowSize(), gOpt.getMux()), boost::bind(createConnectionError, _1), gOpt.getResolvAddrType());
+
+    HostList connect_to = gOpt.getRemoteSyncHosts();
+#ifndef NO_ROUTING
+    NetworkList routes = gOpt.getRoutes();
+               NetworkList::const_iterator rit;
+               for(rit = routes.begin(); rit != routes.end(); ++rit) {
+                       NetworkAddress addr( rit->net_addr );
+                       NetworkPrefix prefix( addr, static_cast<u_int8_t>(rit->prefix_length));
+                       gRoutingTable.addRoute( prefix, gOpt.getMux() );
+               }
+               if (connect_to.begin() == connect_to.end() || gOpt.getDevType()!="tun") {
+       cLog.msg(Log::PRIO_NOTICE) << "No sync/control host defined or not a tun device. Disabling multi connection support (routing)";
+                       disableRouting=true;
+               }
+#endif
+
+#ifndef ANYTUN_NOSYNC
+    boost::thread* syncListenerThread = NULL;
+    if(gOpt.getLocalSyncPort() != "")
+      syncListenerThread = new boost::thread(boost::bind(syncListener));
+    
+    boost::thread_group connectThreads;
+    for(HostList::const_iterator it = connect_to.begin() ;it != connect_to.end(); ++it)
+      connectThreads.create_thread(boost::bind(syncConnector, *it));
+#endif
+
+        // wait for packet source to finish in a seperate thread in order
+        // to be still able to process signals while waiting
+#ifndef NO_DAEMON
+    boost::thread(boost::bind(startSendRecvThreads, privs, &dev, src));
+#else
+    boost::thread(boost::bind(startSendRecvThreads, &dev, src));
+#endif
+
+#if defined(WIN_SERVICE)
+    int ret = 0;
+    gWinService.waitForStop();
+#else
+    int ret = gSignalController.run();  
+#endif
+
+// TODO: stop all threads and cleanup
+// 
+//     if(src)
+//       delete src;
+//     if(connTo)
+//       delete connTo;
+
+#if defined(WIN_SERVICE)
+    gWinService.stop();
+#endif
+    return ret; 
+  }
+  catch(std::runtime_error& e)
+  {
+    cLog.msg(Log::PRIO_ERROR) << "uncaught runtime error, exiting: " << e.what();
+    if(!daemonized)
+      std::cout << "uncaught runtime error, exiting: " << e.what() << std::endl;
+  }
+  catch(std::exception& e)
+  {
+    cLog.msg(Log::PRIO_ERROR) << "uncaught exception, exiting: " << e.what();
+    if(!daemonized)
+      std::cout << "uncaught exception, exiting: " << e.what() << std::endl;
+  }
+#if defined(WIN_SERVICE)
+  gWinService.stop();
+#endif
+  return -1;
+}
+  
+  
diff --git a/src/anytun.sln b/src/anytun.sln
new file mode 100644 (file)
index 0000000..b562246
--- /dev/null
@@ -0,0 +1,26 @@
+\r
+Microsoft Visual Studio Solution File, Format Version 10.00\r
+# Visual C++ Express 2008\r
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "anytun", "anytun.vcproj", "{12460D00-D78A-4C68-BDE2-9E3B2F9CD0F3}"\r
+EndProject\r
+Global\r
+       GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
+               Debug|Win32 = Debug|Win32\r
+               Release|Win32 = Release|Win32\r
+               Service Debug|Win32 = Service Debug|Win32\r
+               Service Release|Win32 = Service Release|Win32\r
+       EndGlobalSection\r
+       GlobalSection(ProjectConfigurationPlatforms) = postSolution\r
+               {12460D00-D78A-4C68-BDE2-9E3B2F9CD0F3}.Debug|Win32.ActiveCfg = Debug|Win32\r
+               {12460D00-D78A-4C68-BDE2-9E3B2F9CD0F3}.Debug|Win32.Build.0 = Debug|Win32\r
+               {12460D00-D78A-4C68-BDE2-9E3B2F9CD0F3}.Release|Win32.ActiveCfg = Release|Win32\r
+               {12460D00-D78A-4C68-BDE2-9E3B2F9CD0F3}.Release|Win32.Build.0 = Release|Win32\r
+               {12460D00-D78A-4C68-BDE2-9E3B2F9CD0F3}.Service Debug|Win32.ActiveCfg = Service Debug|Win32\r
+               {12460D00-D78A-4C68-BDE2-9E3B2F9CD0F3}.Service Debug|Win32.Build.0 = Service Debug|Win32\r
+               {12460D00-D78A-4C68-BDE2-9E3B2F9CD0F3}.Service Release|Win32.ActiveCfg = Service Release|Win32\r
+               {12460D00-D78A-4C68-BDE2-9E3B2F9CD0F3}.Service Release|Win32.Build.0 = Service Release|Win32\r
+       EndGlobalSection\r
+       GlobalSection(SolutionProperties) = preSolution\r
+               HideSolutionNode = FALSE\r
+       EndGlobalSection\r
+EndGlobal\r
diff --git a/src/anytun.suo b/src/anytun.suo
new file mode 100644 (file)
index 0000000..a2b304d
Binary files /dev/null and b/src/anytun.suo differ
diff --git a/src/anytun.vcproj b/src/anytun.vcproj
new file mode 100644 (file)
index 0000000..ea6a923
--- /dev/null
@@ -0,0 +1,682 @@
+<?xml version="1.0" encoding="UTF-8"?>\r
+<VisualStudioProject\r
+       ProjectType="Visual C++"\r
+       Version="9,00"\r
+       Name="anytun"\r
+       ProjectGUID="{12460D00-D78A-4C68-BDE2-9E3B2F9CD0F3}"\r
+       RootNamespace="anytun"\r
+       Keyword="Win32Proj"\r
+       AssemblyReferenceSearchPaths="&quot;..\..\..\..\Program Files\boost\boost_1_35_0&quot;"\r
+       TargetFrameworkVersion="196613"\r
+       >\r
+       <Platforms>\r
+               <Platform\r
+                       Name="Win32"\r
+               />\r
+       </Platforms>\r
+       <ToolFiles>\r
+       </ToolFiles>\r
+       <Configurations>\r
+               <Configuration\r
+                       Name="Debug|Win32"\r
+                       OutputDirectory="Debug"\r
+                       IntermediateDirectory="Debug"\r
+                       ConfigurationType="1"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               AdditionalOptions="/I &quot;C:\Program Files\boost\boost_1_35_0\&quot;"\r
+                               Optimization="0"\r
+                               PreprocessorDefinitions="LOG_FILE;LOG_STDOUT;LOG_WINEVENTLOG;USE_SSL_CRYPTO;NO_DAEMON;NO_EXEC;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK"\r
+                               MinimalRebuild="true"\r
+                               BasicRuntimeChecks="3"\r
+                               RuntimeLibrary="3"\r
+                               UsePrecompiledHeader="0"\r
+                               WarningLevel="3"\r
+                               DebugInformationFormat="4"\r
+                               ForcedIncludeFiles=""\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalDependencies="libeay32MDd.lib"\r
+                               LinkIncremental="2"\r
+                               AdditionalLibraryDirectories=""\r
+                               IgnoreAllDefaultLibraries="false"\r
+                               GenerateDebugInformation="true"\r
+                               SubSystem="1"\r
+                               TargetMachine="1"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Release|Win32"\r
+                       OutputDirectory="Release"\r
+                       IntermediateDirectory="Release"\r
+                       ConfigurationType="1"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               PreprocessorDefinitions="LOG_FILE;LOG_STDOUT;LOG_WINEVENTLOG;USE_SSL_CRYPTO;NO_DAEMON;NO_EXEC;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK"\r
+                               RuntimeLibrary="2"\r
+                               UsePrecompiledHeader="0"\r
+                               WarningLevel="3"\r
+                               Detect64BitPortabilityProblems="false"\r
+                               DebugInformationFormat="3"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalDependencies="libeay32MD.lib"\r
+                               LinkIncremental="2"\r
+                               AdditionalLibraryDirectories=""\r
+                               GenerateDebugInformation="true"\r
+                               SubSystem="1"\r
+                               OptimizeReferences="2"\r
+                               EnableCOMDATFolding="2"\r
+                               TargetMachine="1"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Service Debug|Win32"\r
+                       OutputDirectory="$(ConfigurationName)"\r
+                       IntermediateDirectory="$(ConfigurationName)"\r
+                       ConfigurationType="1"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               AdditionalOptions="/I &quot;C:\Program Files\boost\boost_1_35_0\&quot;"\r
+                               Optimization="0"\r
+                               PreprocessorDefinitions="LOG_FILE;LOG_STDOUT;LOG_WINEVENTLOG;WIN_SERVICE;USE_SSL_CRYPTO;NO_DAEMON;NO_EXEC;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK"\r
+                               MinimalRebuild="true"\r
+                               BasicRuntimeChecks="3"\r
+                               RuntimeLibrary="3"\r
+                               UsePrecompiledHeader="0"\r
+                               WarningLevel="3"\r
+                               Detect64BitPortabilityProblems="false"\r
+                               DebugInformationFormat="4"\r
+                               ForcedIncludeFiles=""\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalDependencies="libeay32MDd.lib"\r
+                               OutputFile="$(OutDir)\$(ProjectName)svc.exe"\r
+                               LinkIncremental="2"\r
+                               AdditionalLibraryDirectories=""\r
+                               IgnoreAllDefaultLibraries="false"\r
+                               GenerateDebugInformation="true"\r
+                               SubSystem="1"\r
+                               TargetMachine="1"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+               <Configuration\r
+                       Name="Service Release|Win32"\r
+                       OutputDirectory="$(ConfigurationName)"\r
+                       IntermediateDirectory="$(ConfigurationName)"\r
+                       ConfigurationType="1"\r
+                       >\r
+                       <Tool\r
+                               Name="VCPreBuildEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCustomBuildTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXMLDataGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCWebServiceProxyGeneratorTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCMIDLTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCCLCompilerTool"\r
+                               PreprocessorDefinitions="LOG_FILE;LOG_STDOUT;LOG_WINEVENTLOG;WIN_SERVICE;USE_SSL_CRYPTO;NO_DAEMON;NO_EXEC;WIN32_LEAN_AND_MEAN;BOOST_ALL_DYN_LINK"\r
+                               RuntimeLibrary="2"\r
+                               UsePrecompiledHeader="0"\r
+                               WarningLevel="3"\r
+                               Detect64BitPortabilityProblems="false"\r
+                               DebugInformationFormat="3"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManagedResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCResourceCompilerTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPreLinkEventTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCLinkerTool"\r
+                               AdditionalDependencies="libeay32MD.lib"\r
+                               OutputFile="$(OutDir)\$(ProjectName)svc.exe"\r
+                               LinkIncremental="2"\r
+                               AdditionalLibraryDirectories=""\r
+                               GenerateDebugInformation="true"\r
+                               SubSystem="1"\r
+                               OptimizeReferences="2"\r
+                               EnableCOMDATFolding="2"\r
+                               TargetMachine="1"\r
+                       />\r
+                       <Tool\r
+                               Name="VCALinkTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCManifestTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCXDCMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCBscMakeTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCFxCopTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCAppVerifierTool"\r
+                       />\r
+                       <Tool\r
+                               Name="VCPostBuildEventTool"\r
+                       />\r
+               </Configuration>\r
+       </Configurations>\r
+       <References>\r
+       </References>\r
+       <Files>\r
+               <Filter\r
+                       Name="Header Files"\r
+                       Filter="h;hpp;hxx;hm;inl;inc;xsd"\r
+                       UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"\r
+                       >\r
+                       <File\r
+                               RelativePath=".\anytunError.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\authAlgo.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\authAlgoFactory.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\buffer.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\cipher.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\cipherFactory.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\win32\common.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\connectionList.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\connectionParam.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\daemon.hpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\datatypes.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\deviceConfig.hpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\encryptedPacket.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\endian.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\keyDerivation.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\keyDerivationFactory.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\log.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\logTargets.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\networkAddress.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\networkPrefix.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\options.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\packetSource.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\plainPacket.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\win32\registryKey.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\resolver.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\routingTable.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\routingTree.hpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\routingTreeNode.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\seqWindow.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\signalController.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\syncBuffer.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\syncClient.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\syncCommand.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\syncConnectionCommand.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\syncOnConnect.hpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\syncQueue.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\syncRouteCommand.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\syncServer.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\syncTcpConnection.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\threadUtils.hpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\tunDevice.h"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\win32\winService.h"\r
+                               >\r
+                       </File>\r
+               </Filter>\r
+               <Filter\r
+                       Name="Resource Files"\r
+                       Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"\r
+                       UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"\r
+                       >\r
+               </Filter>\r
+               <Filter\r
+                       Name="Source Files"\r
+                       Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"\r
+                       UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"\r
+                       >\r
+                       <File\r
+                               RelativePath=".\anytun.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\anytunError.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\authAlgo.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\authAlgoFactory.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\buffer.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\cipher.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\cipherFactory.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\connectionList.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\connectionParam.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\encryptedPacket.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\keyDerivation.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\keyDerivationFactory.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\log.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\logTargets.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\networkAddress.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\networkPrefix.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\options.cpp"\r
+                               >\r
+                               <FileConfiguration\r
+                                       Name="Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions="ANYTUN_OPTIONS"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions="ANYTUN_OPTIONS"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Service Debug|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions="ANYTUN_OPTIONS"\r
+                                       />\r
+                               </FileConfiguration>\r
+                               <FileConfiguration\r
+                                       Name="Service Release|Win32"\r
+                                       >\r
+                                       <Tool\r
+                                               Name="VCCLCompilerTool"\r
+                                               PreprocessorDefinitions="ANYTUN_OPTIONS"\r
+                                       />\r
+                               </FileConfiguration>\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\packetSource.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\plainPacket.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\win32\registryKey.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\resolver.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\routingTable.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\routingTreeNode.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\seqWindow.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\signalController.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\syncBuffer.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\syncClient.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\syncCommand.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\syncConnectionCommand.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\syncQueue.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\syncRouteCommand.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\syncServer.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\syncTcpConnection.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\win32\tunDevice.cpp"\r
+                               >\r
+                       </File>\r
+                       <File\r
+                               RelativePath=".\win32\winService.cpp"\r
+                               >\r
+                       </File>\r
+               </Filter>\r
+       </Files>\r
+       <Globals>\r
+       </Globals>\r
+</VisualStudioProject>\r
diff --git a/src/anytunError.cpp b/src/anytunError.cpp
new file mode 100644 (file)
index 0000000..1a530a7
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "anytunError.h"
+
+#include <sstream>
+#include <boost/system/system_error.hpp>
+
+#ifndef NO_CRYPT
+#ifndef USE_SSL_CRYPTO
+std::ostream& operator<<(std::ostream& stream, AnytunGpgError const& value)
+{
+  char buf[STERROR_TEXT_MAX];
+  buf[0] = 0;
+  gpg_strerror_r(value.err_, buf, STERROR_TEXT_MAX);
+  return stream << buf;
+}
+#endif
+#endif
+
+std::ostream& operator<<(std::ostream& stream, AnytunErrno const& value)
+{
+  boost::system::system_error err(boost::system::error_code(value.err_, boost::system::get_system_category()));
+  return stream << err.what();
+}
diff --git a/src/anytunError.h b/src/anytunError.h
new file mode 100644 (file)
index 0000000..26b4012
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _ANYTUN_ERROR_H
+#define _ANYTUN_ERROR_H
+
+#include <sstream>
+#include <boost/system/system_error.hpp>
+#include "datatypes.h"
+
+#define STERROR_TEXT_MAX 200
+
+#ifndef NO_CRYPT
+#ifndef USE_SSL_CRYPTO
+#include <gcrypt.h>
+
+class AnytunGpgError
+{
+public:
+  AnytunGpgError(gcry_error_t e) : err_(e) {};
+  gcry_error_t err_;
+};
+std::ostream& operator<<(std::ostream& stream, AnytunGpgError const& value);
+#endif
+#endif
+
+class AnytunErrno
+{
+public:
+  AnytunErrno(system_error_t e) : err_(e) {};
+  system_error_t err_;
+};
+std::ostream& operator<<(std::ostream& stream, AnytunErrno const& value);
+
+class ErrorStringBuilder 
+{
+public:
+  ErrorStringBuilder(ErrorStringBuilder const& src) { stream << src.stream.str(); };
+  ErrorStringBuilder() {};
+  ~ErrorStringBuilder() { throw std::runtime_error(stream.str()); };
+
+  template<class T>
+  std::ostream& operator<<(T const& value) { return stream << value; }
+
+private:
+  std::stringstream stream;
+};
+
+class AnytunError
+{
+public:
+  static ErrorStringBuilder throwErr() { return ErrorStringBuilder(); }
+};
+
+#endif
diff --git a/src/authAlgo.cpp b/src/authAlgo.cpp
new file mode 100644 (file)
index 0000000..49974ee
--- /dev/null
@@ -0,0 +1,167 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "authAlgo.h"
+#include "log.h"
+#include "anytunError.h"
+#include "buffer.h"
+#include "encryptedPacket.h"
+
+#include <iostream>
+#include <cstring>
+
+//****** NullAuthAlgo ******
+void NullAuthAlgo::generate(KeyDerivation& kd, EncryptedPacket& packet)
+{
+}
+
+bool NullAuthAlgo::checkTag(KeyDerivation& kd, EncryptedPacket& packet)
+{
+  return true;
+}
+
+#ifndef NO_CRYPT
+//****** Sha1AuthAlgo ******
+
+Sha1AuthAlgo::Sha1AuthAlgo(kd_dir_t d) : AuthAlgo(d), key_(DIGEST_LENGTH)
+{
+#ifndef USE_SSL_CRYPTO
+  gcry_error_t err = gcry_md_open(&handle_, GCRY_MD_SHA1, GCRY_MD_FLAG_HMAC);
+  if(err) {
+    cLog.msg(Log::PRIO_ERROR) << "Sha1AuthAlgo::Sha1AuthAlgo: Failed to open message digest algo";
+    return;
+  } 
+#else
+  HMAC_CTX_init(&ctx_);
+  HMAC_Init_ex(&ctx_, NULL, 0, EVP_sha1(), NULL);
+#endif
+}
+
+Sha1AuthAlgo::~Sha1AuthAlgo()
+{
+#ifndef USE_SSL_CRYPTO
+  if(handle_)
+    gcry_md_close(handle_);
+#else
+  HMAC_CTX_cleanup(&ctx_);
+#endif    
+}
+
+void Sha1AuthAlgo::generate(KeyDerivation& kd, EncryptedPacket& packet)
+{
+#ifndef USE_SSL_CRYPTO
+  if(!handle_)
+    return;
+#endif
+
+  packet.addAuthTag();
+  if(!packet.getAuthTagLength())
+    return;
+  
+  kd.generate(dir_, LABEL_AUTH, packet.getSeqNr(), key_);
+#ifndef USE_SSL_CRYPTO
+  gcry_error_t err = gcry_md_setkey(handle_, key_.getBuf(), key_.getLength());
+  if(err) {
+    cLog.msg(Log::PRIO_ERROR) << "Sha1AuthAlgo::setKey: Failed to set hmac key: " << AnytunGpgError(err);
+    return;
+  } 
+
+  gcry_md_reset(handle_);
+  gcry_md_write(handle_, packet.getAuthenticatedPortion(), packet.getAuthenticatedPortionLength());
+  gcry_md_final(handle_);
+  u_int8_t* hmac = gcry_md_read(handle_, 0);
+#else
+  HMAC_Init_ex(&ctx_, key_.getBuf(), key_.getLength(), EVP_sha1(), NULL);
+
+  u_int8_t hmac[DIGEST_LENGTH];
+  HMAC_Update(&ctx_, packet.getAuthenticatedPortion(), packet.getAuthenticatedPortionLength());
+  HMAC_Final(&ctx_, hmac, NULL);
+#endif
+
+  u_int8_t* tag = packet.getAuthTag();
+  u_int32_t length = (packet.getAuthTagLength() < DIGEST_LENGTH) ? packet.getAuthTagLength() : DIGEST_LENGTH;
+
+  if(length > DIGEST_LENGTH)
+    std::memset(tag, 0, packet.getAuthTagLength());
+
+  std::memcpy(&tag[packet.getAuthTagLength() - length], &hmac[DIGEST_LENGTH - length], length);
+}
+
+bool Sha1AuthAlgo::checkTag(KeyDerivation& kd, EncryptedPacket& packet)
+{
+#ifndef USE_SSL_CRYPTO
+  if(!handle_)
+    return false;
+#endif
+
+  packet.withAuthTag(true);
+  if(!packet.getAuthTagLength())
+    return true;
+
+  kd.generate(dir_, LABEL_AUTH, packet.getSeqNr(), key_);
+#ifndef USE_SSL_CRYPTO
+  gcry_error_t err = gcry_md_setkey(handle_, key_.getBuf(), key_.getLength());
+  if(err) {
+    cLog.msg(Log::PRIO_ERROR) << "Sha1AuthAlgo::setKey: Failed to set hmac key: " << AnytunGpgError(err);
+    return false;
+  } 
+  
+  gcry_md_reset(handle_);
+  gcry_md_write(handle_, packet.getAuthenticatedPortion(), packet.getAuthenticatedPortionLength());
+  gcry_md_final(handle_);
+  u_int8_t* hmac = gcry_md_read(handle_, 0);
+#else
+  HMAC_Init_ex(&ctx_, key_.getBuf(), key_.getLength(), EVP_sha1(), NULL);
+  
+  u_int8_t hmac[DIGEST_LENGTH];
+  HMAC_Update(&ctx_, packet.getAuthenticatedPortion(), packet.getAuthenticatedPortionLength());
+  HMAC_Final(&ctx_, hmac, NULL);
+#endif
+
+  u_int8_t* tag = packet.getAuthTag();
+  u_int32_t length = (packet.getAuthTagLength() < DIGEST_LENGTH) ? packet.getAuthTagLength() : DIGEST_LENGTH;
+
+  if(length > DIGEST_LENGTH)
+    for(u_int32_t i=0; i < (packet.getAuthTagLength() - DIGEST_LENGTH); ++i)
+      if(tag[i]) return false;
+
+  int ret = std::memcmp(&tag[packet.getAuthTagLength() - length], &hmac[DIGEST_LENGTH - length], length);
+  packet.removeAuthTag();
+  
+  if(ret)
+    return false;
+
+  return true;
+
+}
+
+#endif
+
diff --git a/src/authAlgo.h b/src/authAlgo.h
new file mode 100644 (file)
index 0000000..c446853
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _AUTHALGO_H_
+#define _AUTHALGO_H_
+
+#include "datatypes.h"
+#include "buffer.h"
+#include "encryptedPacket.h"
+
+#ifndef NO_CRYPT
+#ifndef USE_SSL_CRYPTO
+#include <gcrypt.h>
+#else
+#include <openssl/hmac.h>
+#endif
+#endif
+#include "keyDerivation.h"
+
+class AuthAlgo
+{
+public:
+  AuthAlgo() : dir_(KD_INBOUND) {};
+  AuthAlgo(kd_dir_t d) : dir_(d) {};
+  virtual ~AuthAlgo() {};
+
+  /**
+   * generate the mac
+   * @param packet the packet to be authenticated
+   */
+  virtual void generate(KeyDerivation& kd, EncryptedPacket& packet) = 0;
+
+  /**
+   * check the mac
+   * @param packet the packet to be authenticated
+   */
+  virtual bool checkTag(KeyDerivation& kd, EncryptedPacket& packet) = 0;
+
+protected:
+  kd_dir_t dir_;
+};
+
+//****** NullAuthAlgo ******
+
+class NullAuthAlgo : public AuthAlgo
+{
+public:
+  void generate(KeyDerivation& kd, EncryptedPacket& packet);
+  bool checkTag(KeyDerivation& kd, EncryptedPacket& packet);
+
+  static const u_int32_t DIGEST_LENGTH = 0;
+};
+
+#ifndef NO_CRYPT
+//****** Sha1AuthAlgo ******
+//* HMAC SHA1 Auth Tag Generator Class
+
+class Sha1AuthAlgo : public AuthAlgo
+{
+public:
+  Sha1AuthAlgo(kd_dir_t d);
+  ~Sha1AuthAlgo();
+
+  void generate(KeyDerivation& kd, EncryptedPacket& packet);
+  bool checkTag(KeyDerivation& kd, EncryptedPacket& packet);
+
+  static const u_int32_t DIGEST_LENGTH = 20;
+
+private:
+#ifndef USE_SSL_CRYPTO
+  gcry_md_hd_t handle_;
+#else
+  HMAC_CTX ctx_;
+#endif
+  
+  Buffer key_;
+};
+#endif
+
+#endif
diff --git a/src/authAlgoFactory.cpp b/src/authAlgoFactory.cpp
new file mode 100644 (file)
index 0000000..c284f34
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <string>
+#include <stdexcept>
+
+#include "authAlgoFactory.h"
+#include "authAlgo.h"
+
+
+AuthAlgo* AuthAlgoFactory::create(std::string const& type, kd_dir_t dir)
+{
+  if(type == "null")
+    return new NullAuthAlgo();
+#ifndef NO_CRYPT
+  else if(type == "sha1")
+    return new Sha1AuthAlgo(dir);
+#endif
+  else
+    throw std::invalid_argument("auth algo not available");
+}
+
+u_int32_t AuthAlgoFactory::getDigestLength(std::string const& type)
+{
+  if(type == "null")
+    return NullAuthAlgo::DIGEST_LENGTH;
+#ifndef NO_CRYPT
+  else if(type == "sha1")
+    return Sha1AuthAlgo::DIGEST_LENGTH;
+#endif
+  else
+    throw std::invalid_argument("auth algo not available");
+}
+
diff --git a/src/authAlgoFactory.h b/src/authAlgoFactory.h
new file mode 100644 (file)
index 0000000..2dca567
--- /dev/null
@@ -0,0 +1,53 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _AUTHALGO_FACTORY_H_
+#define _AUTHALGO_FACTORY_H_
+
+#include <string>
+
+#include "datatypes.h"
+#include "authAlgo.h"
+
+class AuthAlgoFactory
+{
+public:
+  static AuthAlgo* create(std::string const& type, kd_dir_t dir);
+  static u_int32_t getDigestLength(std::string const& type);
+
+private:
+  AuthAlgoFactory();
+  AuthAlgoFactory(const AuthAlgoFactory& src);
+  void operator=(const AuthAlgoFactory& src);
+  ~AuthAlgoFactory();
+};
+
+#endif
diff --git a/src/bsd/tunDevice.cpp b/src/bsd/tunDevice.cpp
new file mode 100644 (file)
index 0000000..408434e
--- /dev/null
@@ -0,0 +1,283 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <fcntl.h>
+#include <unistd.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <net/if.h>
+#include <net/if_tun.h>
+#include <sys/ioctl.h>
+#include <sys/types.h>
+#include <sys/uio.h>
+#include <netinet/in_systm.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+
+#include <sstream>
+
+#include "tunDevice.h"
+#include "threadUtils.hpp"
+#include "log.h"
+#include "anytunError.h"
+
+#define DEVICE_FILE_MAX 255
+
+TunDevice::TunDevice(std::string dev_name, std::string dev_type, std::string ifcfg_addr, std::string ifcfg_prefix) : conf_(dev_name, dev_type, ifcfg_addr, ifcfg_prefix, 1400)
+{
+  std::string device_file = "/dev/";
+  bool dynamic = true;
+  if(dev_name != "") {
+    device_file.append(dev_name);
+    dynamic = false;
+  }
+#if defined(__GNUC__) && defined(__OpenBSD__)
+  else if(conf_.type_ == TYPE_TUN || conf_.type_ == TYPE_TAP) {
+    device_file.append("tun");
+    actual_name_ = "tun";
+  }
+#else
+  else if(conf_.type_ == TYPE_TUN) {
+    device_file.append("tun");
+    actual_name_ = "tun";
+  }
+  else if(conf_.type_ == TYPE_TAP) {
+    device_file.append("tap");
+    actual_name_ = "tap";
+  }
+#endif
+  else
+    AnytunError::throwErr() << "unable to recognize type of device (tun or tap)";
+
+  u_int32_t dev_id=0;
+  if(dynamic) {
+    for(; dev_id <= DEVICE_FILE_MAX; ++dev_id) {
+      std::ostringstream ds;
+      ds << device_file;
+      ds << dev_id;
+      fd_ = ::open(ds.str().c_str(), O_RDWR);
+      if(fd_ >= 0)
+        break;
+    }
+  }
+  else
+    fd_ = ::open(device_file.c_str(), O_RDWR);
+
+  if(fd_ < 0) {
+    if(dynamic)
+      AnytunError::throwErr() << "can't open device file dynamically: no unused node left";
+    else
+      AnytunError::throwErr() << "can't open device file (" << device_file << "): " << AnytunErrno(errno);
+  }
+
+  if(dynamic) {
+    std::stringstream s;
+    s << actual_name_;
+    s << dev_id;
+    actual_name_ = s.str();
+  }
+  else
+    actual_name_ = dev_name;
+  
+  actual_node_ = device_file;
+
+  init_post();
+
+  if(ifcfg_addr != "")
+    do_ifconfig();
+}
+
+TunDevice::~TunDevice()
+{
+  if(fd_ > 0)
+    ::close(fd_);
+}
+
+#if defined(__GNUC__) && defined(__OpenBSD__)
+
+void TunDevice::init_post()
+{
+  with_pi_ = true;
+  if(conf_.type_ == TYPE_TAP)
+    with_pi_ = false;
+  
+  struct tuninfo ti;  
+
+  if (ioctl(fd_, TUNGIFINFO, &ti) < 0) {
+    ::close(fd_);
+    AnytunError::throwErr() << "can't enable multicast for interface: " << AnytunErrno(errno);
+  }
+  
+  ti.flags |= IFF_MULTICAST;
+  if(conf_.type_ == TYPE_TUN)
+    ti.flags &= ~IFF_POINTOPOINT;
+  
+  if (ioctl(fd_, TUNSIFINFO, &ti) < 0) {
+    ::close(fd_);
+    AnytunError::throwErr() << "can't enable multicast for interface: " << AnytunErrno(errno);
+  }
+}
+
+#elif defined(__GNUC__) && defined(__FreeBSD__)
+
+void TunDevice::init_post()
+{
+  with_pi_ = true;
+  if(conf_.type_ == TYPE_TAP)
+    with_pi_ = false;
+
+  if(dev->type_ == TYPE_TUN) {
+    int arg = 0;
+    if(ioctl(dev->fd_, TUNSLMODE, &arg) < 0) {
+      ::close(fd_);
+      AnytunError::throwErr() << "can't disable link-layer mode for interface: " << AnytunErrno(errno);
+    }
+
+    arg = 1;
+    if(ioctl(dev->fd_, TUNSIFHEAD, &arg) < 0) {
+      ::close(fd_);
+      AnytunError::throwErr() << "can't enable multi-af modefor interface: " << AnytunErrno(errno);
+    }
+
+    arg = IFF_BROADCAST;
+    arg |= IFF_MULTICAST;
+    if(ioctl(dev->fd_, TUNSIFMODE, &arg) < 0) {
+      ::close(fd_);
+      AnytunError::throwErr() << "can't enable multicast for interface: " << AnytunErrno(errno);
+    }
+  }
+}
+
+#elif defined(__GNUC__) && defined(__NetBSD__)
+
+void TunDevice::init_post()
+{
+  with_pi_ = false;
+
+  int arg = IFF_POINTOPOINT|IFF_MULTICAST;
+  ioctl(fd_, TUNSIFMODE, &arg);
+  arg = 0;
+  ioctl(fd_, TUNSLMODE, &arg);
+}
+
+#else
+ #error This Device works just for OpenBSD, FreeBSD or NetBSD
+#endif
+
+int TunDevice::fix_return(int ret, size_t pi_length) const
+{
+  if(ret < 0)
+    return ret;
+
+  return (static_cast<size_t>(ret) > type_length ? (ret - type_length) : 0);
+}
+
+int TunDevice::read(u_int8_t* buf, u_int32_t len)
+{
+  if(fd_ < 0)
+    return -1;
+  
+  if(with_pi_) {
+    struct iovec iov[2];
+    u_int32_t type;
+    
+    iov[0].iov_base = &type;
+    iov[0].iov_len = sizeof(type);
+    iov[1].iov_base = buf;
+    iov[1].iov_len = len;
+    return(fix_return(::readv(fd_, iov, 2), sizeof(type)));
+  }
+  else
+    return(::read(fd_, buf, len));
+}
+
+int TunDevice::write(u_int8_t* buf, u_int32_t len)
+{
+  if(fd_ < 0)
+    return -1;
+  
+  if(!buf)
+    return 0;
+
+  if(with_pi_) {
+    struct iovec iov[2];
+    u_int32_t type;
+    struct ip *hdr = reinterpret_cast<struct ip*>(buf);
+    
+    type = 0;
+    if(hdr->ip_v == 4)
+      type = htonl(AF_INET);
+    else
+      type = htonl(AF_INET6);
+    
+    iov[0].iov_base = &type;
+    iov[0].iov_len = sizeof(type);
+    iov[1].iov_base = buf;
+    iov[1].iov_len = len;
+    return(fix_return(::writev(fd_, iov, 2), sizeof(type)));
+  }
+  else
+    return(::write(fd_, buf, len));
+}
+
+void TunDevice::do_ifconfig()
+{
+  std::ostringstream command;
+  command << "/sbin/ifconfig " << actual_name_ << " " << conf_.addr_.toString()
+          << " netmask " << conf_.netmask_.toString() << " mtu " << conf_.mtu_;
+
+  if(conf_.type_ == TYPE_TUN)
+    command << " up";
+  else {
+#if defined(__GNUC__) && defined(__OpenBSD__)
+    command << " link0";
+#elif defined(__GNUC__) && defined(__FreeBSD__)
+    command << " up";
+#elif defined(__GNUC__) && defined(__NetBSD__)
+    command << "";
+#else
+ #error This Device works just for OpenBSD, FreeBSD or NetBSD
+#endif
+  }
+
+  int result = system(command.str().c_str());
+  if(result == -1)
+    cLog.msg(Log::PRIO_ERROR) << "Execution of ifconfig failed" << AnytunErrno(errno);
+  else {
+    if(WIFEXITED(result))
+      cLog.msg(Log::PRIO_NOTICE) << "ifconfig returned " << WEXITSTATUS(result);  
+    else if(WIFSIGNALED(result))
+      cLog.msg(Log::PRIO_NOTICE) << "ifconfig terminated after signal " << WTERMSIG(result);
+    else
+      cLog.msg(Log::PRIO_ERROR) << "Execution of ifconfig: unkown error";
+  }
+
+}
diff --git a/src/buffer.cpp b/src/buffer.cpp
new file mode 100644 (file)
index 0000000..2597845
--- /dev/null
@@ -0,0 +1,257 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <cstring>
+#include <stdexcept>
+#include <string>
+#include <sstream>
+#include <iostream>
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/archive/text_iarchive.hpp>
+#include "datatypes.h"
+#include "buffer.h"
+
+Buffer::Buffer(bool allow_realloc) : buf_(0), length_(0), real_length_(0), allow_realloc_(allow_realloc)
+{  
+}
+
+Buffer::Buffer(u_int32_t length, bool allow_realloc) : length_(length), real_length_(length_ + Buffer::OVER_SIZE_), 
+                                                       allow_realloc_(allow_realloc)
+{
+  buf_ = new u_int8_t[real_length_];
+  if(!buf_) {
+    length_ = 0;
+    real_length_ = 0;
+    throw std::bad_alloc();
+  }
+  std::memset(buf_, 0, real_length_);
+}
+
+Buffer::Buffer(u_int8_t* data, u_int32_t length, bool allow_realloc) : length_(length), real_length_(length + Buffer::OVER_SIZE_), 
+                                                                       allow_realloc_(allow_realloc)
+{
+  if(!data) {
+    length_ = 0;
+    real_length_ = 0;
+    return;
+  }
+
+  buf_ = new u_int8_t[real_length_];
+  if(!buf_) {
+    length_ = 0;
+    real_length_ = 0;
+    throw std::bad_alloc();
+  }
+  std::memcpy(buf_, data, length_);
+}
+
+Buffer::Buffer(std::string hex_data, bool allow_realloc) : length_(static_cast<u_int32_t>(hex_data.size())/2), 
+                                                           real_length_(length_ + Buffer::OVER_SIZE_),
+                                                           allow_realloc_(allow_realloc)
+{
+  buf_ = new u_int8_t[real_length_];
+  if(!buf_) {
+    length_ = 0;
+    real_length_ = 0;
+    throw std::bad_alloc();
+  }
+  
+  for(u_int32_t i=0; i<length_; ++i)
+  {
+    u_int32_t tmp;
+    std::istringstream ss(std::string(hex_data.c_str(), i*2, 2));
+    if(!(ss >> std::hex >> tmp)) tmp = 0;
+    buf_[i] = static_cast<u_int8_t>(tmp);
+  }
+}
+
+Buffer::~Buffer()
+{
+  if(buf_)
+    delete[] buf_;
+}
+
+Buffer::Buffer(const Buffer &src) : length_(src.length_), real_length_(src.real_length_), allow_realloc_(src.allow_realloc_)
+{
+  buf_ = new u_int8_t[real_length_];
+  if(!buf_) {
+    length_ = 0;
+    real_length_ = 0;
+    throw std::bad_alloc();
+  }
+  std::memcpy(buf_, src.buf_, length_);
+}
+
+void Buffer::operator=(const Buffer &src)
+{
+  if(buf_)
+    delete[] buf_;
+  length_ = src.length_;
+  real_length_ = src.real_length_; 
+  allow_realloc_ = src.allow_realloc_;
+  buf_ = new u_int8_t[real_length_];
+  if(!buf_) {
+    length_ = 0;
+    real_length_ = 0;
+    throw std::bad_alloc();
+  }
+  std::memcpy(buf_, src.buf_, length_);
+}
+
+bool Buffer::operator==(const Buffer &cmp) const
+{
+  if(length_ != cmp.length_)
+    return false;
+
+  if(!std::memcmp(buf_, cmp.buf_, length_))
+    return true;
+
+  return false;
+}
+
+Buffer Buffer::operator^(const Buffer &xor_by) const
+{
+  u_int32_t res_length = (xor_by.length_ > length_) ? xor_by.length_ : length_;
+  u_int32_t min_length = (xor_by.length_ < length_) ? xor_by.length_ : length_;
+  Buffer res(res_length);
+
+  for( u_int32_t index = 0; index < min_length; index++ )
+    res[index] = buf_[index] ^ xor_by[index];
+  
+  return res;
+}
+
+u_int32_t Buffer::getLength() const
+{
+  return length_;
+}
+
+void Buffer::setLength(u_int32_t new_length)
+{
+  if(new_length == length_)
+    return;
+
+  if(new_length > real_length_)
+  {
+    if(!allow_realloc_)
+      throw std::out_of_range("buffer::setLength() - reallocation not allowed for this Buffer");
+
+    u_int8_t* old_buf = buf_;
+    u_int32_t old_length = length_;
+
+    length_ = new_length;
+    real_length_ = length_ + Buffer::OVER_SIZE_;
+    
+    buf_ = new u_int8_t[real_length_];
+    if(!buf_) {
+      length_ = 0;
+      real_length_ = 0;
+      if(old_buf)
+        delete[] old_buf;
+      
+      throw std::bad_alloc();
+    }
+    std::memcpy(buf_, old_buf, old_length);
+
+    if(old_buf)
+      delete[] old_buf;
+
+    old_buf = &buf_[old_length];
+    std::memset(old_buf, 0, real_length_ - old_length);
+  }
+  else
+    length_ = new_length;
+
+  reinit();
+}  
+
+
+u_int8_t* Buffer::getBuf()
+{
+  return buf_;
+}
+
+u_int8_t& Buffer::operator[](u_int32_t index)
+{
+  if(index >= length_)
+    throw std::out_of_range("buffer::operator[]");
+
+  return buf_[index];
+}
+
+u_int8_t Buffer::operator[](u_int32_t index) const
+{
+  if(index >= length_)
+    throw std::out_of_range("buffer::operator[] const");
+
+  return buf_[index];
+}
+
+Buffer::operator u_int8_t*()
+{
+  return buf_;
+}
+
+std::string Buffer::getHexDump() const
+{
+  std::stringstream ss;
+  ss << "Length=" << length_ << std::endl << std::hex << std::uppercase;
+  for( u_int32_t index = 0; index < length_; index++ )
+  {
+    ss << std::setw(2) << std::setfill('0') << u_int32_t(buf_[index]) << " ";
+    if(!((index+1) % 16)) {
+      ss << std::endl;
+      continue;
+    }
+    if(!((index+1) % 8))
+      ss << " ";
+  }
+  return ss.str();
+}
+
+std::string Buffer::getHexDumpOneLine() const
+{
+  std::stringstream ss;
+  ss << length_ << " Bytes,'" << std::hex << std::uppercase;
+  for( u_int32_t index = 0; index < length_; index++ )
+  {
+    ss << std::setw(2) << std::setfill('0') << u_int32_t(buf_[index]);
+  }
+  ss << "'";
+  return ss.str();
+}
+
+bool Buffer::isReallocAllowed() const
+{
+  return allow_realloc_;
+}
diff --git a/src/buffer.h b/src/buffer.h
new file mode 100644 (file)
index 0000000..db19947
--- /dev/null
@@ -0,0 +1,77 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _BUFFER_H_
+#define _BUFFER_H_
+
+#include "datatypes.h"
+#include <string>
+
+class TunDevice;
+class UDPPacketSource;
+
+class Buffer
+{
+public:
+  Buffer(bool allow_realloc = true);
+  Buffer(u_int32_t length, bool allow_realloc = true);
+  Buffer(u_int8_t* data, u_int32_t length, bool allow_realloc = true);
+  Buffer(std::string hex_data, bool allow_realloc = true);
+  virtual ~Buffer();
+  Buffer(const Buffer &src);
+  void operator=(const Buffer &src);
+  bool operator==(const Buffer &cmp) const;
+  Buffer operator^(const Buffer &xor_by) const;
+
+  u_int32_t getLength() const;
+  virtual void setLength(u_int32_t new_length);
+  u_int8_t* getBuf();
+  u_int8_t& operator[](u_int32_t index);
+  u_int8_t operator[](u_int32_t index) const;
+  std::string getHexDump() const;
+  std::string getHexDumpOneLine() const;
+
+  bool isReallocAllowed() const;
+
+  operator u_int8_t*();
+
+protected:
+  virtual void reinit() {};
+
+  u_int8_t *buf_;
+  u_int32_t length_;
+  u_int32_t real_length_;
+  bool allow_realloc_;
+
+  static const u_int32_t OVER_SIZE_ = 100;
+};
+
+#endif
diff --git a/src/cipher.cpp b/src/cipher.cpp
new file mode 100644 (file)
index 0000000..ddde683
--- /dev/null
@@ -0,0 +1,190 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdexcept>
+#include <iostream>
+#include <string>
+#include <cstdio>
+#include <cstring>
+
+#include "endian.h"
+
+#include "cipher.h"
+#include "log.h"
+#include "anytunError.h"
+
+void Cipher::encrypt(KeyDerivation& kd, PlainPacket & in, EncryptedPacket & out, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux)
+{
+       u_int32_t len = cipher(kd, in, in.getLength(), out.getPayload(), out.getPayloadLength(), seq_nr, sender_id, mux);
+       out.setSenderId(sender_id);
+       out.setSeqNr(seq_nr);
+  out.setMux(mux);
+       out.setPayloadLength(len);
+}
+
+void Cipher::decrypt(KeyDerivation& kd, EncryptedPacket & in, PlainPacket & out)
+{
+       u_int32_t len = decipher(kd, in.getPayload() , in.getPayloadLength(), out, out.getLength(), in.getSeqNr(), in.getSenderId(), in.getMux());
+       out.setLength(len);
+}
+
+
+//******* NullCipher *******
+
+u_int32_t NullCipher::cipher(KeyDerivation& kd, u_int8_t* in, u_int32_t ilen, u_int8_t* out, u_int32_t olen, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux)
+{
+       std::memcpy(out, in, (ilen < olen) ? ilen : olen);
+  return (ilen < olen) ? ilen : olen;
+}
+
+u_int32_t NullCipher::decipher(KeyDerivation& kd, u_int8_t* in, u_int32_t ilen, u_int8_t* out, u_int32_t olen, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux)
+{
+       std::memcpy(out, in, (ilen < olen) ? ilen : olen);
+  return (ilen < olen) ? ilen : olen;
+}
+
+#ifndef NO_CRYPT
+//****** AesIcmCipher ****** 
+
+AesIcmCipher::AesIcmCipher(kd_dir_t d) : Cipher(d), key_(u_int32_t(DEFAULT_KEY_LENGTH/8)), salt_(u_int32_t(SALT_LENGTH))
+{
+  init();
+}
+
+AesIcmCipher::AesIcmCipher(kd_dir_t d, u_int16_t key_length) : Cipher(d), key_(u_int32_t(key_length/8)), salt_(u_int32_t(SALT_LENGTH))
+{
+  init(key_length);
+}
+
+void AesIcmCipher::init(u_int16_t key_length)
+{
+#ifndef USE_SSL_CRYPTO
+  handle_ = NULL;
+  int algo;
+  switch(key_length) {
+  case 128: algo = GCRY_CIPHER_AES128; break;
+  case 192: algo = GCRY_CIPHER_AES192; break;
+  case 256: algo = GCRY_CIPHER_AES256; break;
+  default: {
+    cLog.msg(Log::PRIO_ERROR) << "AesIcmCipher::AesIcmCipher: cipher key length of " << key_length << " Bits is not supported";
+    return;
+  }
+  }
+
+  gcry_error_t err = gcry_cipher_open(&handle_, algo, GCRY_CIPHER_MODE_CTR, 0);
+  if( err ) {
+    cLog.msg(Log::PRIO_ERROR) << "AesIcmCipher::AesIcmCipher: Failed to open cipher" << AnytunGpgError(err);
+  } 
+#endif
+}
+
+
+AesIcmCipher::~AesIcmCipher()
+{
+#ifndef USE_SSL_CRYPTO
+  if(handle_)
+    gcry_cipher_close(handle_);
+#endif
+}
+
+u_int32_t AesIcmCipher::cipher(KeyDerivation& kd, u_int8_t* in, u_int32_t ilen, u_int8_t* out, u_int32_t olen, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux)
+{
+  calc(kd, in, ilen, out, olen, seq_nr, sender_id, mux);
+  return (ilen < olen) ? ilen : olen;
+}
+
+u_int32_t AesIcmCipher::decipher(KeyDerivation& kd, u_int8_t* in, u_int32_t ilen, u_int8_t* out, u_int32_t olen, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux)
+{
+  calc(kd, in, ilen, out, olen, seq_nr, sender_id, mux);
+  return (ilen < olen) ? ilen : olen;
+}
+
+void AesIcmCipher::calcCtr(KeyDerivation& kd, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux)
+{
+  kd.generate(dir_, LABEL_SALT, seq_nr, salt_);
+
+  std::memcpy(ctr_.salt_.buf_, salt_.getBuf(), SALT_LENGTH);
+  ctr_.salt_.zero_ = 0;
+  ctr_.params_.mux_ ^= MUX_T_HTON(mux);
+  ctr_.params_.sender_id_ ^= SENDER_ID_T_HTON(sender_id);
+  ctr_.params_.seq_nr_ ^= SEQ_NR_T_HTON(seq_nr);
+
+  return;
+}
+
+void AesIcmCipher::calc(KeyDerivation& kd, u_int8_t* in, u_int32_t ilen, u_int8_t* out, u_int32_t olen, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux)
+{
+#ifndef USE_SSL_CRYPTO
+  if(!handle_)
+    return;
+#endif
+
+  kd.generate(dir_, LABEL_ENC, seq_nr, key_);
+#ifdef USE_SSL_CRYPTO
+  int ret = AES_set_encrypt_key(key_.getBuf(), key_.getLength()*8, &aes_key_);
+  if(ret) {
+    cLog.msg(Log::PRIO_ERROR) << "AesIcmCipher: Failed to set cipher ssl key (code: " << ret << ")";
+    return;
+  }
+#else
+  gcry_error_t err = gcry_cipher_setkey(handle_, key_.getBuf(), key_.getLength());
+  if(err) {
+    cLog.msg(Log::PRIO_ERROR) << "AesIcmCipher: Failed to set cipher key: " << AnytunGpgError(err);
+    return;
+  }
+#endif
+
+  calcCtr(kd, seq_nr, sender_id, mux);
+#ifndef USE_SSL_CRYPTO
+  err = gcry_cipher_setctr(handle_, ctr_.buf_, CTR_LENGTH);
+  if(err) {
+    cLog.msg(Log::PRIO_ERROR) << "AesIcmCipher: Failed to set cipher CTR: " << AnytunGpgError(err);
+    return;
+  }
+
+  err = gcry_cipher_encrypt(handle_, out, olen, in, ilen);
+  if(err) {
+    cLog.msg(Log::PRIO_ERROR) << "AesIcmCipher: Failed to de/encrypt packet: " << AnytunGpgError(err);
+    return;
+  }
+#else
+  if(CTR_LENGTH != AES_BLOCK_SIZE) {
+    cLog.msg(Log::PRIO_ERROR) << "AesIcmCipher: Failed to set cipher CTR: size don't fits";
+    return;
+  }
+  unsigned int num = 0;
+  std::memset(ecount_buf_, 0, AES_BLOCK_SIZE);
+  AES_ctr128_encrypt(in, out, (ilen < olen) ? ilen : olen, &aes_key_, ctr_.buf_, ecount_buf_, &num);
+#endif
+}
+#endif
+
diff --git a/src/cipher.h b/src/cipher.h
new file mode 100644 (file)
index 0000000..3d922c0
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _CIPHER_H_
+#define _CIPHER_H_
+
+#include "datatypes.h"
+#include "buffer.h"
+#include "encryptedPacket.h"
+#include "plainPacket.h"
+#include "keyDerivation.h"
+
+#ifndef NO_CRYPT
+#ifndef USE_SSL_CRYPTO
+#include <gcrypt.h>
+#else
+#include <openssl/aes.h>
+#endif
+#endif
+
+class Cipher
+{
+public:
+  Cipher() : dir_(KD_INBOUND) {};
+  Cipher(kd_dir_t d) : dir_(d) {};
+  virtual ~Cipher() {};
+
+       void encrypt(KeyDerivation& kd, PlainPacket & in, EncryptedPacket & out, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux);
+       void decrypt(KeyDerivation& kd, EncryptedPacket & in, PlainPacket & out);
+  
+protected:
+  virtual u_int32_t cipher(KeyDerivation& kd, u_int8_t* in, u_int32_t ilen, u_int8_t* out, u_int32_t olen, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux) = 0;
+  virtual u_int32_t decipher(KeyDerivation& kd, u_int8_t* in, u_int32_t ilen, u_int8_t* out, u_int32_t olen, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux) = 0; 
+
+  kd_dir_t dir_;
+};
+
+//****** NullCipher ******
+
+class NullCipher : public Cipher
+{
+protected:
+  u_int32_t cipher(KeyDerivation& kd, u_int8_t* in, u_int32_t ilen, u_int8_t* out, u_int32_t olen, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux);
+  u_int32_t decipher(KeyDerivation& kd, u_int8_t* in, u_int32_t ilen, u_int8_t* out, u_int32_t olen, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux);
+};
+
+#ifndef NO_CRYPT
+//****** AesIcmCipher ******
+
+class AesIcmCipher : public Cipher
+{
+public:
+  AesIcmCipher(kd_dir_t d);
+  AesIcmCipher(kd_dir_t d, u_int16_t key_length);
+  ~AesIcmCipher();
+  
+  static const u_int16_t DEFAULT_KEY_LENGTH = 128;
+  static const u_int16_t CTR_LENGTH = 16;
+  static const u_int16_t SALT_LENGTH = 14;
+
+protected:
+  u_int32_t cipher(KeyDerivation& kd, u_int8_t* in, u_int32_t ilen, u_int8_t* out, u_int32_t olen, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux);
+  u_int32_t decipher(KeyDerivation& kd, u_int8_t* in, u_int32_t ilen, u_int8_t* out, u_int32_t olen, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux);
+
+private:
+  void init(u_int16_t key_length = DEFAULT_KEY_LENGTH);
+
+  void calcCtr(KeyDerivation& kd, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux);
+  void calc(KeyDerivation& kd, u_int8_t* in, u_int32_t ilen, u_int8_t* out, u_int32_t olen, seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux);
+
+#ifndef USE_SSL_CRYPTO
+  gcry_cipher_hd_t handle_;
+#else
+  AES_KEY aes_key_;
+  u_int8_t ecount_buf_[AES_BLOCK_SIZE];
+#endif
+  Buffer key_;
+  Buffer salt_;
+
+#ifdef _MSC_VER
+  #pragma pack(push, 1)
+#endif
+  union ATTR_PACKED cipher_aesctr_ctr_union {
+    u_int8_t buf_[CTR_LENGTH];
+    struct ATTR_PACKED {
+      u_int8_t buf_[SALT_LENGTH];
+      u_int16_t zero_;
+    } salt_;
+       struct ATTR_PACKED {
+      u_int8_t fill_[SALT_LENGTH - sizeof(mux_t) - sizeof(sender_id_t) - 2*sizeof(u_int8_t) - sizeof(seq_nr_t)];
+      mux_t mux_;
+      sender_id_t sender_id_;
+      u_int8_t empty_[2];
+      seq_nr_t seq_nr_;
+      u_int16_t zero_;
+    } params_;
+  } ctr_;
+#ifdef _MSC_VER
+  #pragma pack(pop)
+#endif
+};
+#endif
+
+#endif
diff --git a/src/cipherFactory.cpp b/src/cipherFactory.cpp
new file mode 100644 (file)
index 0000000..e9f0292
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <string>
+#include <stdexcept>
+
+#include "cipherFactory.h"
+#include "cipher.h"
+
+
+Cipher* CipherFactory::create(std::string const& type, kd_dir_t dir)
+{
+  if(type == "null")
+    return new NullCipher();
+#ifndef NO_CRYPT
+  else if(type == "aes-ctr")
+    return new AesIcmCipher(dir);
+  else if(type == "aes-ctr-128")
+    return new AesIcmCipher(dir, 128);
+  else if(type == "aes-ctr-192")
+    return new AesIcmCipher(dir, 192);
+  else if(type == "aes-ctr-256")
+    return new AesIcmCipher(dir, 256);
+#endif
+  else
+    throw std::invalid_argument("cipher not available");
+}
+
diff --git a/src/cipherFactory.h b/src/cipherFactory.h
new file mode 100644 (file)
index 0000000..23d3b92
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _CIPHER_FACTORY_H_
+#define _CIPHER_FACTORY_H_
+
+#include <string>
+
+#include "datatypes.h"
+#include "cipher.h"
+
+class CipherFactory
+{
+public:
+  static Cipher* create(std::string const& type, kd_dir_t dir);
+
+private:
+  CipherFactory();
+  CipherFactory(const CipherFactory& src);
+  void operator=(const CipherFactory& src);
+  ~CipherFactory();
+};
+
+#endif
diff --git a/src/configure b/src/configure
new file mode 100755 (executable)
index 0000000..770318b
--- /dev/null
@@ -0,0 +1,136 @@
+#!/bin/sh
+#
+#  anytun
+#
+#  The secure anycast tunneling protocol (satp) defines a protocol used
+#  for communication between any combination of unicast and anycast
+#  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+#  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+#  ethernet, ip, arp ...). satp directly includes cryptography and
+#  message authentication based on the methodes used by SRTP.  It is
+#  intended to deliver a generic, scaleable and secure solution for
+#  tunneling and relaying of packets of any protocol.
+#
+#
+#  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+#                          Christian Pointner <satp@wirdorange.org>
+#
+#  This file is part of Anytun.
+#
+#  Anytun is free software: you can redistribute it and/or modify
+#  it under the terms of the GNU General Public License version 3 as
+#  published by the Free Software Foundation.
+#
+#  Anytun is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+TARGET=`uname -s`
+
+CXXFLAGS='-g -Wall -O2 -DLOG_SYSLOG -DLOG_FILE -DLOG_STDOUT'
+LDFLAGS='-g -Wall -O2 -lboost_thread -lboost_serialization -lboost_system'
+
+CRYPTO_LIB='gcrypt'
+PASSPHRASE=1
+ROUTING=1
+
+print_usage() {
+  echo "configure --help                    print this"
+  echo "          --use-ssl-crypto          use ssl crypto library instead of libgcrypt"
+  echo "          --disable-crypto          disable crypto at all (only NULL cipher)"
+  echo "          --disable-passphrase      disable master key and salt passphrase"
+  echo "          --disable-routing         disable built-in routing capability"
+}
+
+for arg
+do
+  case $arg in
+  --use-ssl-crypto)
+    CRYPTO_LIB='ssl'
+  ;;
+  --disable-crypto)
+    CRYPTO_LIB='none'
+  ;; 
+  --disable-passphrase)
+    PASSPHRASE=0
+  ;;
+  --disable-routing)
+    ROUTING=0
+  ;;
+  --help)
+    print_usage
+    exit 0
+  ;;
+  *)
+    echo "Unknown argument: $arg"
+    print_usage
+    exit 1
+  ;;
+  esac
+done
+
+rm -f include.mk
+case $TARGET in 
+       Linux)
+               rm -rf tunDevice.cpp
+               ln -sf linux/tunDevice.cpp 
+    echo "loading Linux specific TUN Device"
+       ;;
+       OpenBSD|FreeBSD|NetBSD)
+               rm -rf tunDevice.cpp
+               ln -sf bsd/tunDevice.cpp 
+    echo "loading BSD specific TUN Device"
+    CXXFLAGS=$CXXFLAGS' -I/usr/local/include'
+    LDFLAGS=$LDFLAGS' -L/usr/local/lib'
+       ;;
+       *)
+               echo "Plattform not supported"
+    exit 1
+       ;;
+esac
+
+case $CRYPTO_LIB in
+  gcrypt)
+    LDFLAGS=$LDFLAGS' -lgcrypt -lgpg-error'
+    echo "using libgcrypt library"
+  ;;
+  ssl)
+    CXXFLAGS=$CXXFLAGS' -DUSE_SSL_CRYPTO'
+    LDFLAGS=$LDFLAGS' -lcrypto'
+    echo "using ssl crypto library"
+  ;;
+  none)
+    CXXFLAGS=$CXXFLAGS' -DNO_CRYPT'
+    echo "NO_CRYPT_OBJ = 1" >> include.mk
+    echo "disabling crypto"
+  ;;
+esac
+
+if [ $PASSPHRASE -eq 0 ]; then
+  CXXFLAGS=$CXXFLAGS' -DNO_PASSPHRASE'
+  echo "disabling master key and salt passphrase"
+fi
+
+if [ $ROUTING -eq 0 ]; then
+  CXXFLAGS=$CXXFLAGS' -DNO_ROUTING'
+  echo "disabling built-in routing capability"
+fi
+
+cat >> include.mk <<EOF
+# this file was created automatically
+# do not edit this file directly 
+# use ./configure instead
+
+TARGET = $TARGET
+CXX = gcc
+CXXFLAGS = $CXXFLAGS
+LD = gcc
+LDFLAGS = $LDFLAGS
+EOF
+
+exit 0
diff --git a/src/connectionList.cpp b/src/connectionList.cpp
new file mode 100644 (file)
index 0000000..6402711
--- /dev/null
@@ -0,0 +1,154 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "threadUtils.hpp"
+#include "datatypes.h"
+#include "keyDerivationFactory.h"
+#include "options.h"
+#include "packetSource.h"
+
+#include "connectionList.h"
+
+ConnectionList* ConnectionList::inst = NULL;
+Mutex ConnectionList::instMutex;
+ConnectionList& gConnectionList = ConnectionList::instance();
+
+
+ConnectionList& ConnectionList::instance()
+{
+  Lock lock(instMutex);
+  static instanceCleaner c;
+  if(!inst)
+    inst = new ConnectionList();
+
+  return *inst;
+}
+
+ConnectionList::ConnectionList()
+{
+}
+
+ConnectionList::~ConnectionList()
+{
+// TODO: comment this in as soon as threads @ main get cleaned up properly 
+//  Lock lock(mutex_);
+//     ConnectionMap::iterator it;
+//     for(it = connections_.begin(); it != connections_.end(); ++it) {
+//     delete &it->second.kd_;
+//     delete &it->second.seq_window_;
+//   }
+} 
+
+void ConnectionList::addConnection(ConnectionParam &conn, u_int16_t mux )
+{
+  Lock lock(mutex_);
+
+  std::pair<ConnectionMap::iterator, bool> ret = connections_.insert(ConnectionMap::value_type(mux, conn));
+  if(!ret.second)
+  {
+    connections_.erase(ret.first);
+    connections_.insert(ConnectionMap::value_type(mux, conn));
+  }
+}
+
+const ConnectionMap::iterator ConnectionList::getEnd()
+{
+    Lock lock(mutex_);
+       return connections_.end();
+}
+
+ConnectionMap::iterator ConnectionList::getBeginUnlocked()
+{
+  return connections_.begin();
+}
+
+const ConnectionMap::iterator ConnectionList::getBegin()
+{
+  Lock lock(mutex_);
+  return connections_.begin();
+}
+
+
+ConnectionMap::iterator ConnectionList::getEndUnlocked()
+{
+  return connections_.end();
+}
+
+const ConnectionMap::iterator ConnectionList::getConnection(u_int16_t mux)
+{
+       Lock lock(mutex_);
+       ConnectionMap::iterator it = connections_.find(mux);
+       return it;
+}
+
+
+ConnectionParam & ConnectionList::getOrNewConnectionUnlocked(u_int16_t mux)
+{
+       ConnectionMap::iterator it = connections_.find(mux);
+       if(it!=connections_.end())
+               return it->second;
+
+  u_int8_t key[] = {
+  'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
+  'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p'
+  };
+  
+  u_int8_t salt[] = {
+  'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h',
+  'i', 'j', 'k', 'l', 'm', 'n'
+  };
+
+  SeqWindow * seq= new SeqWindow(0);
+  seq_nr_t seq_nr_=0;
+  KeyDerivation * kd = KeyDerivationFactory::create(gOpt.getKdPrf());
+  kd->init(Buffer(key, sizeof(key)), Buffer(salt, sizeof(salt)));
+  ConnectionParam conn ((*kd), (*seq), seq_nr_, PacketSourceEndpoint());
+       connections_.insert(ConnectionMap::value_type(mux, conn));
+       it = connections_.find(mux);
+       return it->second;
+}
+
+void ConnectionList::clear()
+{
+  Lock lock(mutex_);
+       connections_.clear();
+}
+
+bool ConnectionList::empty()
+{
+  Lock lock(mutex_);
+       return connections_.empty();
+}
+
+Mutex& ConnectionList::getMutex()
+{
+  return mutex_;
+}
diff --git a/src/connectionList.h b/src/connectionList.h
new file mode 100644 (file)
index 0000000..cdf5268
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _CONNECTION_LIST_H
+#define _CONNECTION_LIST_H
+
+#include <map>
+#include <deque>
+
+#include "threadUtils.hpp"
+#include "datatypes.h"
+#include "connectionParam.h"
+#include "networkAddress.h"
+typedef std::map<u_int16_t, ConnectionParam> ConnectionMap;
+
+class ConnectionList
+{
+public:
+       ConnectionList();
+       ~ConnectionList();
+       static ConnectionList& instance();
+       void addConnection(ConnectionParam &conn, u_int16_t mux);
+       const ConnectionMap::iterator getConnection(u_int16_t mux);
+       const ConnectionMap::iterator getEnd();
+       ConnectionMap::iterator getEndUnlocked();
+       ConnectionMap::iterator getBeginUnlocked();     
+       const ConnectionMap::iterator getBegin();
+       ConnectionParam & getOrNewConnectionUnlocked(u_int16_t mux);
+       bool empty();
+       void clear();
+  Mutex& getMutex();
+
+private:
+  static Mutex instMutex;
+       static ConnectionList* inst;
+  class instanceCleaner {
+    public: ~instanceCleaner() {
+     if(ConnectionList::inst != 0)
+       delete ConnectionList::inst;
+   }
+  };
+       ConnectionList(const ConnectionList &s);
+  void operator=(const ConnectionList &s);
+       ConnectionMap connections_;
+  Mutex mutex_;
+};
+
+extern ConnectionList& gConnectionList;
+
+#endif
diff --git a/src/connectionParam.cpp b/src/connectionParam.cpp
new file mode 100644 (file)
index 0000000..c6b3ded
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "connectionParam.h"
+
+ConnectionParam::ConnectionParam(KeyDerivation& kd, SeqWindow& seq_window,seq_nr_t seq_nr, PacketSourceEndpoint remote_end) : kd_(kd),seq_window_(seq_window),seq_nr_(seq_nr), remote_end_(remote_end)
+{
+}
+
+ConnectionParam::ConnectionParam(const ConnectionParam & src) : kd_(src.kd_),seq_window_(src.seq_window_),seq_nr_(src.seq_nr_),remote_end_(src.remote_end_),mutex_()
+{
+}
diff --git a/src/connectionParam.h b/src/connectionParam.h
new file mode 100644 (file)
index 0000000..f929211
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _CONNECTIONPARAM_H_
+#define _CONNECTIONPARAM_H_
+
+#include "keyDerivation.h"
+#include "seqWindow.h"
+#include "threadUtils.hpp"
+#include "packetSource.h"
+#include "log.h"
+
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/archive/text_iarchive.hpp>
+
+class ConnectionParam
+{
+public:
+       ConnectionParam(const ConnectionParam & src);
+       ConnectionParam( KeyDerivation& kd, SeqWindow& seq_window, seq_nr_t seq_nr_, PacketSourceEndpoint remote_end);
+
+  KeyDerivation& kd_;
+  SeqWindow& seq_window_;
+       seq_nr_t seq_nr_;
+       PacketSourceEndpoint remote_end_;
+
+private:
+  //TODO: check if this is ok
+       Mutex mutex_;
+  friend class boost::serialization::access;
+  template<class Archive>
+  void serialize(Archive & ar, const unsigned int version)
+       {
+               Lock lock(mutex_);
+               std::string remote_host(remote_end_.address().to_string());
+               u_int16_t remote_port = remote_end_.port();
+               ar & kd_;
+    ar & seq_window_;
+    ar & seq_nr_;
+    ar & remote_host;
+    ar & remote_port;
+               PacketSourceEndpoint emptyEndpoint;
+               UDPPacketSource::proto::endpoint endpoint(boost::asio::ip::address::from_string(remote_host), remote_port);
+               //This is a workarround, against race condition in sync process
+               //TODO: find a better solution
+               if (endpoint != emptyEndpoint && remote_host != "::" && remote_host != "[::]" && remote_host != "0.0.0.0")
+                       remote_end_ = endpoint;
+       }
+};
+
+#endif
diff --git a/src/cryptinit.hpp b/src/cryptinit.hpp
new file mode 100644 (file)
index 0000000..4460de0
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _CRYPTINIT_HPP
+#define _CRYPTINIT_HPP
+
+#ifndef NO_CRYPT
+#ifndef USE_SSL_CRYPTO
+#include <gcrypt.h>
+
+// boost thread callbacks for libgcrypt
+#if defined(BOOST_HAS_PTHREADS)
+
+static int boost_mutex_init(void **priv)
+{
+  boost::mutex *lock = new boost::mutex();
+  if (!lock)
+    return ENOMEM;
+  *priv = lock;
+  return 0;
+}
+
+static int boost_mutex_destroy(void **lock)
+{
+  delete reinterpret_cast<boost::mutex*>(*lock);
+  return 0;
+}
+
+static int boost_mutex_lock(void **lock)
+{
+  reinterpret_cast<boost::mutex*>(*lock)->lock();
+  return 0;
+}
+
+static int boost_mutex_unlock(void **lock)
+{
+  reinterpret_cast<boost::mutex*>(*lock)->unlock();
+  return 0;
+}
+
+static struct gcry_thread_cbs gcry_threads_boost =
+{ GCRY_THREAD_OPTION_USER, NULL,
+  boost_mutex_init, boost_mutex_destroy,
+  boost_mutex_lock, boost_mutex_unlock };
+#else
+#error this libgcrypt thread callbacks only work with pthreads
+#endif
+
+
+#define MIN_GCRYPT_VERSION "1.2.0"
+
+bool initLibGCrypt()
+{
+  // make libgcrypt thread safe 
+  // this must be called before any other libgcrypt call
+  gcry_control( GCRYCTL_SET_THREAD_CBS, &gcry_threads_boost );
+
+  // this must be called right after the GCRYCTL_SET_THREAD_CBS command
+  // no other function must be called till now
+  if( !gcry_check_version( MIN_GCRYPT_VERSION ) ) {
+    std::cout << "initLibGCrypt: Invalid Version of libgcrypt, should be >= " << MIN_GCRYPT_VERSION << std::endl;
+    return false;
+  }
+
+  gcry_error_t err = gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
+  if( err ) {
+    std::cout << "initLibGCrypt: Failed to disable secure memory: " << AnytunGpgError(err) << std::endl;
+    return false;
+  }
+
+  // Tell Libgcrypt that initialization has completed.
+  err = gcry_control(GCRYCTL_INITIALIZATION_FINISHED);
+  if( err ) {
+    std::cout << "initLibGCrypt: Failed to finish initialization: " << AnytunGpgError(err) << std::endl;
+    return false;
+  }
+
+  cLog.msg(Log::PRIO_NOTICE) << "initLibGCrypt: libgcrypt init finished";
+  return true;
+}
+#endif
+#endif
+
+#endif
+
diff --git a/src/daemon.hpp b/src/daemon.hpp
new file mode 100644 (file)
index 0000000..b62da17
--- /dev/null
@@ -0,0 +1,165 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _DAEMON_HPP
+#define _DAEMON_HPP
+#ifndef NO_DAEMON
+
+#include <poll.h>
+#include <fcntl.h>
+#include <pwd.h>
+#include <grp.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "log.h"
+#include "anytunError.h"
+
+#ifndef NO_PRIVDROP
+class PrivInfo
+{
+public:
+  PrivInfo(std::string const& username, std::string const& groupname)
+  {
+    pw_ = NULL;
+    gr_ = NULL;
+    
+    if(username == "")
+      return;
+
+    pw_ = getpwnam(username.c_str());
+    if(!pw_)
+      AnytunError::throwErr() << "unkown user " << username;
+    
+    if(groupname != "")
+      gr_ = getgrnam(groupname.c_str());
+    else
+      gr_ = getgrgid(pw_->pw_gid);
+    
+    if(!gr_)
+      AnytunError::throwErr() << "unkown group " << groupname;
+  }
+
+  void drop()
+  {
+    if(!pw_ || !gr_)
+      return;
+
+    if(setgid(gr_->gr_gid))
+      AnytunError::throwErr() << "setgid('" << gr_->gr_name << "') failed: " << AnytunErrno(errno);
+    
+    gid_t gr_list[1];
+    gr_list[0] = gr_->gr_gid;
+    if(setgroups (1, gr_list))
+      AnytunError::throwErr() << "setgroups(['" << gr_->gr_name << "']) failed: " << AnytunErrno(errno);
+    
+    if(setuid(pw_->pw_uid))
+      AnytunError::throwErr() << "setuid('" << pw_->pw_name << "') failed: " << AnytunErrno(errno);
+    
+    cLog.msg(Log::PRIO_NOTICE) << "dropped privileges to " << pw_->pw_name << ":" << gr_->gr_name;
+  }
+
+private:
+  struct passwd* pw_;
+  struct group* gr_;
+};
+#endif
+
+void do_chroot(std::string const& chrootdir)
+{
+  if (getuid() != 0)
+    AnytunError::throwErr() << "this programm has to be run as root in order to run in a chroot";
+
+  if(chroot(chrootdir.c_str()))
+    AnytunError::throwErr() << "can't chroot to " << chrootdir;
+
+  cLog.msg(Log::PRIO_NOTICE) << "we are in chroot jail (" << chrootdir << ") now" << std::endl;
+  if(chdir("/"))
+    AnytunError::throwErr() << "can't change to /";
+}
+
+void daemonize()
+{
+  std::ofstream pidFile;
+  if(gOpt.getPidFile() != "") {
+    pidFile.open(gOpt.getPidFile().c_str());
+    if(!pidFile.is_open())
+      AnytunError::throwErr() << "can't open pid file (" << gOpt.getPidFile() << "): " << AnytunErrno(errno);
+  }
+
+  pid_t pid;
+
+  pid = fork();
+  if(pid < 0)
+    AnytunError::throwErr() << "daemonizing failed at fork(): " << AnytunErrno(errno) << ", exitting";
+
+  if(pid) exit(0);
+
+  umask(0);
+
+  if(setsid() < 0)
+    AnytunError::throwErr() << "daemonizing failed at setsid(): " << AnytunErrno(errno) << ", exitting";
+
+  pid = fork();
+  if(pid < 0)
+    AnytunError::throwErr() << "daemonizing failed at fork(): " << AnytunErrno(errno) << ", exitting";
+
+  if(pid) exit(0);
+
+  if ((chdir("/")) < 0)
+    AnytunError::throwErr() << "daemonizing failed at chdir(): " << AnytunErrno(errno) << ", exitting";
+
+//  std::cout << "running in background now..." << std::endl;
+
+  int fd;
+//  for (fd=getdtablesize();fd>=0;--fd) // close all file descriptors
+  for (fd=0;fd<=2;fd++) // close all file descriptors
+    close(fd);
+  fd = open("/dev/null",O_RDWR);        // stdin
+  if(fd == -1)
+    cLog.msg(Log::PRIO_WARNING) << "can't open /dev/null as stdin";
+  else {
+    if(dup(fd) == -1)   // stdout
+      cLog.msg(Log::PRIO_WARNING) << "can't open /dev/null as stdout";
+    if(dup(fd) == -1)   // stderr
+      cLog.msg(Log::PRIO_WARNING) << "can't open /dev/null as stderr";
+  }
+
+  if(pidFile.is_open()) {
+    pid_t pid = getpid();
+    pidFile << pid;
+    pidFile.close();
+  }
+}
+#endif
+#endif
+
diff --git a/src/datatypes.h b/src/datatypes.h
new file mode 100644 (file)
index 0000000..141aae3
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _DATATYPES_H_
+#define _DATATYPES_H_
+
+#include <boost/cstdint.hpp>
+#include <boost/integer_traits.hpp>
+
+typedef boost::uint8_t u_int8_t;
+typedef boost::uint16_t u_int16_t;
+typedef boost::uint32_t u_int32_t;
+typedef boost::uint64_t u_int64_t;
+typedef boost::int8_t int8_t;
+typedef boost::int16_t int16_t;
+typedef boost::int32_t int32_t;
+typedef boost::int64_t int64_t;
+
+typedef u_int32_t window_size_t;
+
+typedef u_int32_t seq_nr_t;
+#define SEQ_NR_MAX 0xFFFFFFFF
+typedef u_int16_t sender_id_t;
+typedef u_int16_t payload_type_t;
+typedef u_int16_t mux_t;
+typedef u_int32_t satp_prf_label_t;
+
+typedef enum { ANY, IPV4_ONLY, IPV6_ONLY } ResolvAddrType;
+
+#ifndef _MSC_VER
+#define ATTR_PACKED __attribute__((__packed__))
+typedef int system_error_t;
+#else
+#include <windows.h>
+#define ATTR_PACKED
+typedef DWORD system_error_t;
+#endif   
+
+#endif
diff --git a/src/deviceConfig.hpp b/src/deviceConfig.hpp
new file mode 100644 (file)
index 0000000..d8702b9
--- /dev/null
@@ -0,0 +1,97 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _DEVICE_CONFIG_HPP_
+#define _DEVICE_CONFIG_HPP_
+
+#include "networkAddress.h"
+#include <boost/asio.hpp>
+#include "anytunError.h"
+
+class TunDevice;
+
+enum device_type_t { TYPE_UNDEF, TYPE_TUN, TYPE_TAP };
+
+class DeviceConfig 
+{
+public:
+  DeviceConfig(std::string dev_name ,std::string dev_type, std::string ifcfg_addr, u_int16_t ifcfg_prefix, u_int16_t mtu)
+  {
+    mtu_ = mtu;
+    type_ = TYPE_UNDEF;
+#ifndef _MSC_VER
+    if(dev_type != "") {
+      if(!dev_type.compare(0,3,"tun"))
+        type_ = TYPE_TUN;
+      else if (!dev_type.compare(0,3,"tap"))
+        type_ = TYPE_TAP;
+    }
+    else if(dev_name != "") {
+      if(!dev_name.compare(0,3,"tun"))
+        type_ = TYPE_TUN;
+      else if(!dev_name.compare(0,3,"tap"))
+        type_ = TYPE_TAP;
+    }
+#else
+    if(dev_type == "")
+      AnytunError::throwErr() << "Device type must be specified on Windows";
+    
+    if(dev_type == "tun")
+      type_ = TYPE_TUN;
+    else if(dev_type == "tap")
+      type_ = TYPE_TAP;
+
+    if(type_ == TYPE_TUN && ifcfg_addr == "")
+      AnytunError::throwErr() << "Device type tun requires ifconfig parameter (--ifconfig)";
+#endif
+
+    if(ifcfg_addr != "")
+      addr_.setNetworkAddress(ipv4, ifcfg_addr.c_str());
+    prefix_ = ifcfg_prefix;
+    u_int32_t mask = 0;
+    for(u_int16_t i = 0; i < prefix_; ++i) {
+      mask = mask >> 1;
+      mask |= 0x80000000L;
+    }
+    netmask_.setNetworkAddress(boost::asio::ip::address_v4(mask));
+  }
+
+private:
+  device_type_t type_;
+  NetworkAddress addr_;
+  NetworkAddress netmask_;
+  u_int16_t prefix_;
+  u_int16_t mtu_;
+
+  friend class TunDevice;
+};
+
+#endif
diff --git a/src/encryptedPacket.cpp b/src/encryptedPacket.cpp
new file mode 100644 (file)
index 0000000..a5aec86
--- /dev/null
@@ -0,0 +1,222 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdexcept>
+#include <iostream>
+#include <cstdio>       // for std::memcpy
+
+#include "encryptedPacket.h"
+#include "endian.h"
+#include "datatypes.h"
+#include "log.h"
+#include "anytunError.h"
+
+EncryptedPacket::EncryptedPacket(u_int32_t payload_length, u_int32_t auth_tag_length, bool allow_realloc)
+  : Buffer(payload_length + sizeof(struct HeaderStruct), allow_realloc), auth_tag_length_(auth_tag_length)
+{
+  header_ = reinterpret_cast<struct HeaderStruct*>(buf_);
+  payload_ = buf_ + sizeof(struct HeaderStruct);
+  auth_tag_ = NULL;
+  if(header_)
+  {
+    header_->seq_nr = 0;
+    header_->sender_id = 0;
+    header_->mux = 0;
+  }
+}
+
+u_int32_t EncryptedPacket::getHeaderLength()
+{
+  return sizeof(struct HeaderStruct);
+}
+
+seq_nr_t EncryptedPacket::getSeqNr() const
+{
+  if(header_)
+    return SEQ_NR_T_NTOH(header_->seq_nr);
+  
+  return 0;
+}
+
+sender_id_t EncryptedPacket::getSenderId() const
+{
+  if(header_)
+    return SENDER_ID_T_NTOH(header_->sender_id);
+
+  return 0;
+}
+
+mux_t EncryptedPacket::getMux() const
+{
+  if(header_)
+    return MUX_T_NTOH(header_->mux);
+
+  return 0;
+}
+
+void EncryptedPacket::setSeqNr(seq_nr_t seq_nr)
+{
+  if(header_)
+    header_->seq_nr = SEQ_NR_T_HTON(seq_nr);
+}
+
+void EncryptedPacket::setSenderId(sender_id_t sender_id)
+{
+  if(header_)
+    header_->sender_id = SENDER_ID_T_HTON(sender_id);
+}
+
+void EncryptedPacket::setMux(mux_t mux)
+{
+  if(header_)
+    header_->mux = MUX_T_HTON(mux);
+}
+
+void EncryptedPacket::setHeader(seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux)
+{
+  if(!header_)
+    return;
+
+  header_->seq_nr = SEQ_NR_T_HTON(seq_nr);
+  header_->sender_id = SENDER_ID_T_HTON(sender_id);
+  header_->mux = MUX_T_HTON(mux);
+}
+
+u_int32_t EncryptedPacket::getPayloadLength() const
+{
+  if(!payload_) 
+    return 0;
+
+  if(!auth_tag_)
+    return (length_ > sizeof(struct HeaderStruct)) ? (length_ - sizeof(struct HeaderStruct)) : 0;
+  
+  return (length_ > (sizeof(struct HeaderStruct) + auth_tag_length_)) ? (length_ - sizeof(struct HeaderStruct) - auth_tag_length_) : 0;
+}
+
+void EncryptedPacket::setPayloadLength(u_int32_t payload_length)
+{
+  Buffer::setLength(payload_length + sizeof(struct HeaderStruct));
+      // depending on allow_realloc buf_ may point to another address
+      // therefore in this case reinit() gets called by Buffer::setLength()
+}
+
+void EncryptedPacket::reinit()
+{
+  header_ = reinterpret_cast<struct HeaderStruct*>(buf_);
+  payload_ = buf_ + sizeof(struct HeaderStruct);
+  
+  if(length_ <= (sizeof(struct HeaderStruct)))
+    payload_ = NULL;
+  
+  if(length_ < (sizeof(struct HeaderStruct))) {
+    header_ = NULL;
+    AnytunError::throwErr() << "encrypted packet can't be initialized, buffer is too small"; 
+  }  
+  
+  if(auth_tag_)
+  {
+    if(length_ < (sizeof(struct HeaderStruct) + auth_tag_length_)) {
+      auth_tag_ = NULL;
+      AnytunError::throwErr() << "auth-tag can't be enabled, buffer is too small"; 
+    }
+    auth_tag_ = buf_ + length_ - auth_tag_length_;
+  }  
+}
+
+u_int8_t* EncryptedPacket::getPayload()
+{
+  return payload_;
+}
+
+u_int8_t* EncryptedPacket::getAuthenticatedPortion()
+{
+  return buf_;
+}
+
+u_int32_t EncryptedPacket::getAuthenticatedPortionLength()
+{
+  if(!buf_)
+    return 0;
+
+  if(!auth_tag_)
+    return length_;
+  
+  return (length_ > auth_tag_length_) ? (length_ - auth_tag_length_) : 0;
+}
+
+void EncryptedPacket::withAuthTag(bool b)
+{
+  if((b && auth_tag_) || (!b && !auth_tag_))
+    return;
+  
+  if(b)
+  {
+    if(length_ < (sizeof(struct HeaderStruct) + auth_tag_length_))
+      AnytunError::throwErr() << "auth-tag can't be enabled, buffer is too small";
+    
+    auth_tag_ = buf_ + length_ - auth_tag_length_;
+  }
+  else
+    auth_tag_ = NULL;
+}
+
+void EncryptedPacket::addAuthTag()
+{
+  if(auth_tag_)
+    return;
+
+  auth_tag_ = buf_; // will be set to the correct value @ reinit
+  setLength(length_ + auth_tag_length_);
+  if(auth_tag_ == buf_) // reinit was not called by setLength
+    reinit();
+}
+
+void EncryptedPacket::removeAuthTag()
+{
+  if(!auth_tag_)
+    return;
+
+  auth_tag_ = NULL;
+  setLength(length_ - auth_tag_length_);
+}
+
+u_int8_t* EncryptedPacket::getAuthTag()
+{
+  return auth_tag_;
+}
+
+u_int32_t EncryptedPacket::getAuthTagLength()
+{
+  if(auth_tag_)
+    return auth_tag_length_;
+
+  return 0;
+}
diff --git a/src/encryptedPacket.h b/src/encryptedPacket.h
new file mode 100644 (file)
index 0000000..618fa44
--- /dev/null
@@ -0,0 +1,158 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _ENCRYPTED_PACKET_H_
+#define _ENCRYPTED_PACKET_H_
+
+#include "datatypes.h"
+#include "buffer.h"
+
+class Cipher;
+class EncryptedPacket : public Buffer
+{
+public:
+
+  /**
+   * Packet constructor
+   * @param the length of the payload 
+   * @param allow reallocation of buffer
+   */
+  EncryptedPacket(u_int32_t payload_length, u_int32_t auth_tag_length, bool allow_realloc = false);
+
+  /**
+   * Packet destructor
+   */
+  ~EncryptedPacket() {};
+
+  /**
+   * Get the length of the header
+   * @return the length of the header
+   */
+  static u_int32_t getHeaderLength();
+
+  /**
+   * Get the sequence number
+   * @return seqence number
+   */
+  seq_nr_t getSeqNr() const;
+
+  /**
+   * Set the seqence number
+   * @param seq_nr sequence number
+   */
+  void setSeqNr(seq_nr_t seq_nr);
+
+  /**
+   * Get the sender id
+   * @return sender id
+   */
+  sender_id_t getSenderId() const;
+
+  /**
+   * Set the sender id
+   * @param sender_id sender id
+   */
+  void setSenderId(sender_id_t sender_id);
+
+  /**
+   * Get the mulitplex id
+   * @return multiplex id
+   */
+  mux_t getMux() const;
+
+  /**
+   * Set the multiplex id
+   * @param mux multiplex id
+   */
+  void setMux(mux_t mux);
+
+  /**
+   * Set the header of a packet
+   * @param seq_nr sequence number
+   * @param sender_id sender id
+   * @param mux multiplex id
+   */
+  void setHeader(seq_nr_t seq_nr, sender_id_t sender_id, mux_t mux);
+
+  /**
+   * Get the length of the payload
+   * @return the length of the payload
+   */
+  u_int32_t getPayloadLength() const;
+
+  /**
+   * Set the length of the payload
+   * @param length length of the payload
+   */
+  void setPayloadLength(u_int32_t payload_length);
+
+  /**
+   * Get the the payload
+   * @return the Pointer to the payload
+   */
+  u_int8_t* getPayload();
+
+
+  u_int8_t* getAuthenticatedPortion();
+  u_int32_t getAuthenticatedPortionLength();
+
+  void withAuthTag(bool b);
+  void addAuthTag();
+  void removeAuthTag();
+  u_int8_t* getAuthTag();
+  u_int32_t getAuthTagLength();
+                      
+private:
+  EncryptedPacket();
+  EncryptedPacket(const EncryptedPacket &src);
+
+  void reinit();
+
+#ifdef _MSC_VER
+  #pragma pack(push, 1)
+#endif  
+  struct ATTR_PACKED HeaderStruct
+  {
+    seq_nr_t seq_nr;
+    sender_id_t sender_id;
+    mux_t mux;
+  };
+#ifdef _MSC_VER
+  #pragma pack(pop)
+#endif
+
+  struct HeaderStruct* header_;
+       u_int8_t * payload_;
+  u_int8_t * auth_tag_;
+  u_int32_t  auth_tag_length_;
+};
+
+#endif
diff --git a/src/endian.h b/src/endian.h
new file mode 100644 (file)
index 0000000..9d96126
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _ENDIAN_H_
+#define _ENDIAN_H_
+
+#ifndef _WIN32
+#include <arpa/inet.h>
+#else
+#include <Winsock2.h>
+#endif
+
+#define SEQ_NR_T_NTOH(a) ntohl(a)
+#define SEQ_NR_T_HTON(a) htonl(a)
+
+#define SENDER_ID_T_NTOH(a) ntohs(a)
+#define SENDER_ID_T_HTON(a) htons(a)
+
+#define PAYLOAD_TYPE_T_NTOH(a) ntohs(a)
+#define PAYLOAD_TYPE_T_HTON(a) htons(a)
+
+#define MUX_T_NTOH(a) ntohs(a)
+#define MUX_T_HTON(a) htons(a)
+
+#define SATP_PRF_LABEL_T_NTOH(a) ntohl(a)
+#define SATP_PRF_LABEL_T_HTON(a) htonl(a)
+
+//#define AUTH_TAG_T_NTOH(a) ntohl(a)
+//#define AUTH_TAG_T_HTON(a) htonl(a)
+
+#endif
diff --git a/src/keyDerivation.cpp b/src/keyDerivation.cpp
new file mode 100644 (file)
index 0000000..cdf6368
--- /dev/null
@@ -0,0 +1,340 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+
+#include "log.h"
+#include "anytunError.h"
+#include "keyDerivation.h"
+#include "threadUtils.hpp"
+#include "datatypes.h"
+#include "endian.h"
+
+#include <stdexcept>
+#include <iostream>
+#include <sstream>
+#include <string>
+
+#ifndef NO_CRYPT
+#ifndef NO_PASSPHRASE
+#ifdef USE_SSL_CRYPTO
+#include <openssl/sha.h>
+#endif
+#endif
+#endif
+
+void KeyDerivation::setRole(const role_t role)
+{
+  WritersLock lock(mutex_);
+  role_ = role;
+  cLog.msg(Log::PRIO_NOTICE) << "KeyDerivation: using role " << role_;
+}
+
+#ifndef NO_CRYPT
+#ifndef NO_PASSPHRASE
+void KeyDerivation::calcMasterKey(std::string passphrase, u_int16_t length)
+{
+  cLog.msg(Log::PRIO_NOTICE) << "KeyDerivation: calculating master key from passphrase";
+  if(!length) {
+    cLog.msg(Log::PRIO_ERROR) << "KeyDerivation: bad master key length";
+    return;
+  }
+
+#ifndef USE_SSL_CRYPTO
+  if(length > gcry_md_get_algo_dlen(GCRY_MD_SHA256)) {
+#else
+  if(length > SHA256_DIGEST_LENGTH) {
+#endif
+    cLog.msg(Log::PRIO_ERROR) << "KeyDerivation: master key too long for passphrase algorithm";
+    return;
+  }
+
+#ifndef USE_SSL_CRYPTO
+  Buffer digest(gcry_md_get_algo_dlen(GCRY_MD_SHA256));
+  gcry_md_hash_buffer(GCRY_MD_SHA256, digest.getBuf(), passphrase.c_str(), passphrase.length());
+#else
+  Buffer digest(u_int32_t(SHA256_DIGEST_LENGTH));
+  SHA256(reinterpret_cast<const unsigned char*>(passphrase.c_str()), passphrase.length(), digest.getBuf());
+#endif
+  master_key_.setLength(length);
+
+  memcpy(master_key_.getBuf(), &digest.getBuf()[digest.getLength() - master_key_.getLength()], master_key_.getLength());
+}
+
+void KeyDerivation::calcMasterSalt(std::string passphrase, u_int16_t length)
+{
+  cLog.msg(Log::PRIO_NOTICE) << "KeyDerivation: calculating master salt from passphrase";
+  if(!length) {
+    cLog.msg(Log::PRIO_ERROR) << "KeyDerivation: bad master salt length";
+    return;
+  }
+
+#ifndef USE_SSL_CRYPTO
+  if(length > gcry_md_get_algo_dlen(GCRY_MD_SHA1)) {
+#else
+  if(length > SHA_DIGEST_LENGTH) {
+#endif
+    cLog.msg(Log::PRIO_ERROR) << "KeyDerivation: master key too long for passphrase algorithm";
+    return;
+  }
+
+#ifndef USE_SSL_CRYPTO
+  Buffer digest(gcry_md_get_algo_dlen(GCRY_MD_SHA1));
+  gcry_md_hash_buffer(GCRY_MD_SHA1, digest.getBuf(), passphrase.c_str(), passphrase.length());
+#else
+  Buffer digest(u_int32_t(SHA_DIGEST_LENGTH));
+  SHA1(reinterpret_cast<const unsigned char*>(passphrase.c_str()), passphrase.length(), digest.getBuf());
+#endif
+  master_salt_.setLength(length);
+
+  memcpy(master_salt_.getBuf(), &digest.getBuf()[digest.getLength() - master_salt_.getLength()], master_salt_.getLength());
+}
+#endif
+#endif
+
+satp_prf_label_t KeyDerivation::convertLabel(kd_dir_t dir, satp_prf_label_t label)
+{
+  switch(label) {
+  case LABEL_ENC: {
+    if(dir == KD_OUTBOUND) {
+      if(role_ == ROLE_LEFT) return LABEL_LEFT_ENC;
+      if(role_ == ROLE_RIGHT) return LABEL_RIGHT_ENC;
+    }
+    else {
+      if(role_ == ROLE_LEFT) return LABEL_RIGHT_ENC;
+      if(role_ == ROLE_RIGHT) return LABEL_LEFT_ENC;
+    }
+    break;
+  }
+  case LABEL_SALT: {
+    if(dir == KD_OUTBOUND) {
+      if(role_ == ROLE_LEFT) return LABEL_LEFT_SALT;
+      if(role_ == ROLE_RIGHT) return LABEL_RIGHT_SALT;
+    }
+    else {
+      if(role_ == ROLE_LEFT) return LABEL_RIGHT_SALT;
+      if(role_ == ROLE_RIGHT) return LABEL_LEFT_SALT;
+    }
+    break;
+  }
+  case LABEL_AUTH: {
+    if(dir == KD_OUTBOUND) {
+      if(role_ == ROLE_LEFT) return LABEL_LEFT_AUTH;
+      if(role_ == ROLE_RIGHT) return LABEL_RIGHT_AUTH;
+    }
+    else {
+      if(role_ == ROLE_LEFT) return LABEL_RIGHT_AUTH;
+      if(role_ == ROLE_RIGHT) return LABEL_LEFT_AUTH;
+    }
+    break;
+  }
+  }
+
+  return label;
+}
+
+//****** NullKeyDerivation ******
+
+bool NullKeyDerivation::generate(kd_dir_t dir, satp_prf_label_t label, seq_nr_t seq_nr, Buffer& key)
+{
+  std::memset(key.getBuf(), 0, key.getLength());
+  return true;
+}
+
+#ifndef NO_CRYPT
+//****** AesIcmKeyDerivation ******
+
+AesIcmKeyDerivation::AesIcmKeyDerivation() : KeyDerivation(DEFAULT_KEY_LENGTH) 
+{
+#ifndef USE_SSL_CRYPTO
+  for(int i=0; i<2; i++)
+    handle_[i] = NULL;
+#endif
+}
+
+AesIcmKeyDerivation::AesIcmKeyDerivation(u_int16_t key_length) : KeyDerivation(key_length) 
+{
+#ifndef USE_SSL_CRYPTO
+  for(int i=0; i<2; i++)
+    handle_[i] = NULL;
+#endif
+}
+
+AesIcmKeyDerivation::~AesIcmKeyDerivation()
+{
+  WritersLock lock(mutex_);
+#ifndef USE_SSL_CRYPTO
+  for(int i=0; i<2; i++)
+    if(handle_[i])
+      gcry_cipher_close(handle_[i]);
+#endif
+}
+
+void AesIcmKeyDerivation::init(Buffer key, Buffer salt, std::string passphrase)
+{
+  WritersLock lock(mutex_);
+
+  is_initialized_ = false;
+#ifndef NO_PASSPHRASE
+  if(passphrase != "" && !key.getLength())
+    calcMasterKey(passphrase, key_length_/8);
+  else
+    master_key_ = SyncBuffer(key);
+  
+  if(passphrase != "" && !salt.getLength())
+    calcMasterSalt(passphrase, SALT_LENGTH);
+  else
+    master_salt_ = SyncBuffer(salt);
+#else
+  master_key_ = SyncBuffer(key);
+  master_salt_ = SyncBuffer(salt);
+#endif
+
+  updateMasterKey();
+}
+
+void AesIcmKeyDerivation::updateMasterKey()
+{
+  if(master_key_.getLength()*8 != key_length_) {
+    cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::updateMasterKey: key lengths don't match";
+    return;
+  }
+
+  if(master_salt_.getLength() != SALT_LENGTH) {
+    cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::updateMasterKey: salt lengths don't match";
+    return;
+  }
+
+#ifndef USE_SSL_CRYPTO
+  int algo;
+  switch(key_length_) {
+  case 128: algo = GCRY_CIPHER_AES128; break;
+  case 192: algo = GCRY_CIPHER_AES192; break;
+  case 256: algo = GCRY_CIPHER_AES256; break;
+  default: {
+    cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::updateMasterKey: cipher key length of " << key_length_ << " Bits is not supported";
+    return;
+  }
+  }
+
+  for(int i=0; i<2; i++) {
+    if(handle_[i])
+      gcry_cipher_close(handle_[i]);
+    
+    gcry_error_t err = gcry_cipher_open(&handle_[i], algo, GCRY_CIPHER_MODE_CTR, 0);
+    if(err) {
+      cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::updateMasterKey: Failed to open cipher: " << AnytunGpgError(err);
+      return;
+    } 
+    
+    err = gcry_cipher_setkey(handle_[i], master_key_.getBuf(), master_key_.getLength());
+    if(err) {
+      cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::updateMasterKey: Failed to set cipher key: " << AnytunGpgError(err);
+      return;
+    }
+  }
+#else
+  for(int i=0; i<2; i++) {
+    int ret = AES_set_encrypt_key(master_key_.getBuf(), master_key_.getLength()*8, &aes_key_[i]);
+    if(ret) {
+      cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::updateMasterKey: Failed to set ssl key (code: " << ret << ")";
+      return;
+    }
+  }
+#endif
+  is_initialized_ = true;
+}
+
+std::string AesIcmKeyDerivation::printType() 
+{
+  ReadersLock lock(mutex_);
+
+  std::stringstream sstr;
+  sstr << "AesIcm" << key_length_ << "KeyDerivation";
+  return sstr.str();
+}
+
+bool AesIcmKeyDerivation::calcCtr(kd_dir_t dir, satp_prf_label_t label, seq_nr_t seq_nr)
+{
+  if(master_salt_.getLength() != SALT_LENGTH) {
+    cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::calcCtr: salt lengths don't match";
+    return false;
+  }
+  memcpy(ctr_[dir].salt_.buf_, master_salt_.getBuf(), SALT_LENGTH);
+  ctr_[dir].salt_.zero_ = 0;
+  ctr_[dir].params_.label_ ^= SATP_PRF_LABEL_T_HTON(convertLabel(dir, label));
+  ctr_[dir].params_.seq_ ^= SEQ_NR_T_HTON(seq_nr);
+
+  return true;
+}
+
+bool AesIcmKeyDerivation::generate(kd_dir_t dir, satp_prf_label_t label, seq_nr_t seq_nr, Buffer& key) 
+{
+  ReadersLock lock(mutex_);
+
+  if(!is_initialized_)
+    return false;
+
+  if(!calcCtr(dir, label, seq_nr)) {
+    return false;
+  }
+#ifndef USE_SSL_CRYPTO
+  gcry_error_t err = gcry_cipher_reset(handle_[dir]);
+  if(err) {
+    cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::generate: Failed to reset cipher: " << AnytunGpgError(err);
+  }
+
+  err = gcry_cipher_setctr(handle_[dir], ctr_[dir].buf_, CTR_LENGTH);
+  if(err) {
+    cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::generate: Failed to set CTR: " << AnytunGpgError(err);
+    return false;
+  }
+
+  std::memset(key.getBuf(), 0, key.getLength());
+  err = gcry_cipher_encrypt(handle_[dir], key, key.getLength(), NULL, 0);
+  if(err) {
+    cLog.msg(Log::PRIO_ERROR) << "KeyDerivation::generate: Failed to generate cipher bitstream: " << AnytunGpgError(err);
+  }
+#else
+  if(CTR_LENGTH != AES_BLOCK_SIZE) {
+    cLog.msg(Log::PRIO_ERROR) << "AesIcmCipher: Failed to set cipher CTR: size don't fits";
+    return false;
+  }
+  unsigned int num = 0;
+  std::memset(ecount_buf_[dir], 0, AES_BLOCK_SIZE);
+  std::memset(key.getBuf(), 0, key.getLength());
+  AES_ctr128_encrypt(key.getBuf(), key.getBuf(), key.getLength(), &aes_key_[dir], ctr_[dir].buf_, ecount_buf_[dir], &num);
+#endif
+  
+  return true;
+}
+#endif
+
diff --git a/src/keyDerivation.h b/src/keyDerivation.h
new file mode 100644 (file)
index 0000000..12d370c
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _KEYDERIVATION_H_
+#define _KEYDERIVATION_H_
+
+#include "datatypes.h"
+#include "buffer.h"
+#include "threadUtils.hpp"
+#include "syncBuffer.h"
+#include "options.h"
+
+#ifndef NO_CRYPT
+#ifndef USE_SSL_CRYPTO
+#include <gcrypt.h>
+#else
+#include <openssl/aes.h>
+#endif
+#endif
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/archive/text_iarchive.hpp>
+
+#define LABEL_ENC 0
+#define LABEL_AUTH 1
+#define LABEL_SALT 2
+
+#define LABEL_LEFT_ENC 0x356A192B
+#define LABEL_RIGHT_ENC 0xDA4B9237
+#define LABEL_LEFT_SALT 0x77DE68DA
+#define LABEL_RIGHT_SALT 0x1B645389
+#define LABEL_LEFT_AUTH 0xAC3478D6
+#define LABEL_RIGHT_AUTH 0xC1DFD96E
+
+typedef enum { KD_INBOUND, KD_OUTBOUND } kd_dir_t;
+
+class KeyDerivation
+{
+public:
+  KeyDerivation() : is_initialized_(false), role_(ROLE_LEFT), key_length_(0), master_salt_(0), master_key_(0) {};
+  KeyDerivation(u_int16_t key_length) : is_initialized_(false), role_(ROLE_LEFT), key_length_(key_length), master_salt_(0), master_key_(0) {};
+  virtual ~KeyDerivation() {};
+
+  void setRole(const role_t role);
+
+  virtual void init(Buffer key, Buffer salt, std::string passphrase = "") = 0;
+  virtual bool generate(kd_dir_t dir, satp_prf_label_t label, seq_nr_t seq_nr, Buffer& key) = 0;
+
+  virtual std::string printType() { return "GenericKeyDerivation"; };
+
+  satp_prf_label_t convertLabel(kd_dir_t dir, satp_prf_label_t label);  
+
+protected:
+  virtual void updateMasterKey() = 0;
+  
+#ifndef NO_PASSPHRASE
+  void calcMasterKey(std::string passphrase, u_int16_t length);
+  void calcMasterSalt(std::string passphrase, u_int16_t length);
+#endif
+
+       KeyDerivation(const KeyDerivation & src);
+       friend class boost::serialization::access;
+       template<class Archive>
+       void serialize(Archive & ar, const unsigned int version)
+       {
+               WritersLock lock(mutex_);
+    ar & role_;
+    ar & key_length_;
+    ar & master_salt_;
+    ar & master_key_;
+    updateMasterKey();
+       }
+
+  bool is_initialized_;
+  role_t role_;
+  u_int16_t key_length_;
+  SyncBuffer master_salt_;
+  SyncBuffer master_key_;
+
+  SharedMutex mutex_;
+};
+
+#if BOOST_VERSION <= 103500 
+BOOST_IS_ABSTRACT(KeyDerivation);
+#else
+BOOST_SERIALIZATION_ASSUME_ABSTRACT(KeyDerivation);
+#endif
+
+//****** NullKeyDerivation ******
+
+class NullKeyDerivation : public KeyDerivation
+{
+public:
+  NullKeyDerivation() {};
+  ~NullKeyDerivation() {};
+
+  void init(Buffer key, Buffer salt, std::string passphrase = "") {};
+  bool generate(kd_dir_t dir, satp_prf_label_t label, seq_nr_t seq_nr, Buffer& key);
+
+  std::string printType() { return "NullKeyDerivation"; };
+
+private:
+  void updateMasterKey() {};
+
+       friend class boost::serialization::access;
+       template<class Archive>
+       void serialize(Archive & ar, const unsigned int version)
+       {
+    ar & boost::serialization::base_object<KeyDerivation>(*this);
+       }
+
+};
+
+#ifndef NO_CRYPT
+//****** AesIcmKeyDerivation ******
+
+class AesIcmKeyDerivation : public KeyDerivation
+{
+public:
+  AesIcmKeyDerivation();
+  AesIcmKeyDerivation(u_int16_t key_length);
+  ~AesIcmKeyDerivation();
+
+  static const u_int16_t DEFAULT_KEY_LENGTH = 128;
+  static const u_int16_t CTR_LENGTH = 16;
+  static const u_int16_t SALT_LENGTH = 14;
+   
+  void init(Buffer key, Buffer salt, std::string passphrase = "");
+  bool generate(kd_dir_t dir, satp_prf_label_t label, seq_nr_t seq_nr, Buffer& key);
+
+  std::string printType();
+
+private:
+  void updateMasterKey();
+
+  bool calcCtr(kd_dir_t dir, satp_prf_label_t label, seq_nr_t seq_nr);
+
+       friend class boost::serialization::access;
+       template<class Archive>
+       void serialize(Archive & ar, const unsigned int version)
+       {
+    ar & boost::serialization::base_object<KeyDerivation>(*this);
+       }
+
+#ifndef USE_SSL_CRYPTO
+  gcry_cipher_hd_t handle_[2];
+#else
+  AES_KEY aes_key_[2];
+  u_int8_t ecount_buf_[2][AES_BLOCK_SIZE];
+#endif
+
+#ifdef _MSC_VER
+  #pragma pack(push, 1)
+#endif  
+  union ATTR_PACKED key_derivation_aesctr_ctr_union {
+    u_int8_t buf_[CTR_LENGTH];
+    struct ATTR_PACKED {
+      u_int8_t buf_[SALT_LENGTH];
+      u_int16_t zero_;
+    } salt_;
+    struct ATTR_PACKED {
+      u_int8_t fill_[SALT_LENGTH - sizeof(satp_prf_label_t) - sizeof(seq_nr_t)];
+      satp_prf_label_t label_;
+      seq_nr_t seq_;
+      u_int16_t zero_;
+    } params_;
+  } ctr_[2];
+#ifdef _MSC_VER  
+  #pragma pack(pop)
+#endif
+};
+
+#endif
+
+#endif
+
diff --git a/src/keyDerivationFactory.cpp b/src/keyDerivationFactory.cpp
new file mode 100644 (file)
index 0000000..75df38a
--- /dev/null
@@ -0,0 +1,56 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <string>
+#include <stdexcept>
+
+#include "keyDerivationFactory.h"
+#include "keyDerivation.h"
+
+
+KeyDerivation* KeyDerivationFactory::create(std::string const& type)
+{
+  if(type == "null")
+    return new NullKeyDerivation();
+#ifndef NO_CRYPT
+  else if(type == "aes-ctr")
+    return new AesIcmKeyDerivation();
+  else if(type == "aes-ctr-128")
+    return new AesIcmKeyDerivation(128);
+  else if(type == "aes-ctr-192")
+    return new AesIcmKeyDerivation(192);
+  else if(type == "aes-ctr-256")
+    return new AesIcmKeyDerivation(256);
+#endif
+  else
+    throw std::invalid_argument("key derivation prf not available");
+}
+
diff --git a/src/keyDerivationFactory.h b/src/keyDerivationFactory.h
new file mode 100644 (file)
index 0000000..77caf58
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _KEYDERIVATION_FACTORY_H_
+#define _KEYDERIVATION_FACTORY_H_
+
+#include <string>
+
+#include "datatypes.h"
+#include "keyDerivation.h"
+
+class KeyDerivationFactory
+{
+public:
+  static KeyDerivation* create(std::string const& type);
+
+private:
+  KeyDerivationFactory();
+  KeyDerivationFactory(const KeyDerivationFactory& src);
+  void operator=(const KeyDerivationFactory& src);
+  ~KeyDerivationFactory();
+};
+
+#endif
diff --git a/src/linux/tunDevice.cpp b/src/linux/tunDevice.cpp
new file mode 100644 (file)
index 0000000..b34ae9d
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <string.h>
+#include <sstream>
+
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <arpa/inet.h>
+#include <errno.h>
+#include <net/if.h>
+#include <linux/ip.h>
+#include <linux/if_ether.h>
+#include <linux/if_tun.h>
+#define DEFAULT_DEVICE "/dev/net/tun"
+
+#include "tunDevice.h"
+#include "threadUtils.hpp"
+#include "log.h"
+#include "anytunError.h"
+
+TunDevice::TunDevice(std::string dev_name, std::string dev_type, std::string ifcfg_addr, u_int16_t ifcfg_prefix) : conf_(dev_name, dev_type, ifcfg_addr, ifcfg_prefix, 1400)
+{
+       struct ifreq ifr;
+       memset(&ifr, 0, sizeof(ifr));
+
+  if(conf_.type_ == TYPE_TUN) {
+    ifr.ifr_flags = IFF_TUN;
+    with_pi_ = true;
+  } 
+  else if(conf_.type_ == TYPE_TAP) {
+    ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
+    with_pi_ = false;
+  } 
+  else
+    AnytunError::throwErr() << "unable to recognize type of device (tun or tap)";
+
+       if(dev_name != "")
+               strncpy(ifr.ifr_name, dev_name.c_str(), IFNAMSIZ);
+
+       fd_ = ::open(DEFAULT_DEVICE, O_RDWR);
+       if(fd_ < 0)
+    AnytunError::throwErr() << "can't open device file (" << DEFAULT_DEVICE  << "): " << AnytunErrno(errno);
+
+       if(!ioctl(fd_, TUNSETIFF, &ifr)) {
+               actual_name_ = ifr.ifr_name;
+       } else if(!ioctl(fd_, (('T' << 8) | 202), &ifr)) {
+               actual_name_ = ifr.ifr_name;
+       } else {
+    ::close(fd_);
+    AnytunError::throwErr() << "tun/tap device ioctl failed: " << AnytunErrno(errno);
+  }
+  actual_node_ = DEFAULT_DEVICE;
+
+  if(ifcfg_addr != "")
+    do_ifconfig();
+}
+
+TunDevice::~TunDevice()
+{
+  if(fd_ > 0)
+    ::close(fd_);
+}
+
+int TunDevice::fix_return(int ret, size_t pi_length) const
+{
+  if(ret < 0)
+    return ret;
+
+  return (static_cast<size_t>(ret) > pi_length ? (ret - pi_length) : 0);
+}
+
+int TunDevice::read(u_int8_t* buf, u_int32_t len)
+{
+  if(fd_ < 0)
+    return -1;
+
+  if(with_pi_)
+  {
+    struct iovec iov[2];
+    struct tun_pi tpi;
+    
+    iov[0].iov_base = &tpi;
+    iov[0].iov_len = sizeof(tpi);
+    iov[1].iov_base = buf;
+    iov[1].iov_len = len;
+    return(fix_return(::readv(fd_, iov, 2), sizeof(tpi)));
+  }
+  else
+    return(::read(fd_, buf, len));
+}
+
+int TunDevice::write(u_int8_t* buf, u_int32_t len)
+{
+  if(fd_ < 0)
+    return -1;
+
+  if(!buf)
+    return 0;
+
+  if(with_pi_)
+  {
+    struct iovec iov[2];
+    struct tun_pi tpi;
+    struct iphdr *hdr = reinterpret_cast<struct iphdr *>(buf);
+    
+    tpi.flags = 0;
+    if(hdr->version == 4)
+      tpi.proto = htons(ETH_P_IP);
+    else
+      tpi.proto = htons(ETH_P_IPV6);
+    
+    iov[0].iov_base = &tpi;
+    iov[0].iov_len = sizeof(tpi);
+    iov[1].iov_base = buf;
+    iov[1].iov_len = len;
+    return(fix_return(::writev(fd_, iov, 2), sizeof(tpi)));
+  }
+  else
+    return(::write(fd_, buf, len));
+}
+
+void TunDevice::init_post()
+{
+// nothing to be done here
+}
+
+void TunDevice::do_ifconfig()
+{
+  std::ostringstream command;
+  command << "/sbin/ifconfig " << actual_name_ << " " << conf_.addr_.toString()
+          << " netmask " << conf_.netmask_.toString() << " mtu " << conf_.mtu_;
+
+  int result = system(command.str().c_str());
+  if(result == -1)
+    cLog.msg(Log::PRIO_ERROR) << "Execution of ifconfig failed: " << AnytunErrno(errno);
+  else {
+    if(WIFEXITED(result))
+      cLog.msg(Log::PRIO_NOTICE) << "ifconfig returned " << WEXITSTATUS(result);  
+    else if(WIFSIGNALED(result))
+      cLog.msg(Log::PRIO_NOTICE) << "ifconfig terminated after signal " << WTERMSIG(result);
+    else
+      cLog.msg(Log::PRIO_ERROR) << "Execution of ifconfig: unkown error";
+  }
+}
diff --git a/src/log.cpp b/src/log.cpp
new file mode 100644 (file)
index 0000000..d0ed7f8
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <iostream>
+#include <string>
+#include "log.h"
+
+#include "threadUtils.hpp"
+
+Log* Log::inst = NULL;
+Mutex Log::instMutex;
+Log& cLog = Log::instance();
+
+LogStringBuilder::LogStringBuilder(LogStringBuilder const& src) : log(src.log), prio(src.prio) 
+{
+  stream << src.stream.str();
+}
+
+LogStringBuilder::LogStringBuilder(Log& l, int p) : log(l), prio(p) 
+{
+      // do something on the start of the line.
+}
+
+LogStringBuilder::~LogStringBuilder() 
+{
+  log.log(stream.str(), prio);
+}
+
+Log& Log::instance()
+{
+  Lock lock(instMutex);
+  static instanceCleaner c;
+  if(!inst)
+    inst = new Log();
+  
+  return *inst;
+}
+
+void Log::addTarget(std::string conf)
+{
+  Lock lock(mutex);
+  LogTarget* target = targets.add(conf);
+  target->open();
+  if(target->getMaxPrio() > 0)
+    target->enable();
+}
+
+void Log::addTarget(LogTargetList::target_type_t type, int prio, std::string conf)
+{
+  Lock lock(mutex);
+  LogTarget* target = targets.add(type, prio, conf);
+  target->open();
+  if(target->getMaxPrio() > 0)
+    target->enable();
+}
+
+void Log::log(std::string msg, int prio)
+{
+  Lock lock(mutex);
+  targets.log(msg, prio);
+}
+
+std::string Log::prioToString(int prio)
+{
+  switch(prio) {
+  case PRIO_ERROR: return "ERROR";
+  case PRIO_WARNING: return "WARNING";
+  case PRIO_NOTICE: return "NOTICE";
+  case PRIO_INFO: return "INFO";
+  case PRIO_DEBUG: return "DEBUG";
+  default: return "UNKNOWN";
+  }
+}
diff --git a/src/log.h b/src/log.h
new file mode 100644 (file)
index 0000000..dcdedc4
--- /dev/null
+++ b/src/log.h
@@ -0,0 +1,102 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _LOG_H_
+#define _LOG_H_
+
+#include <string>
+#include <sstream>
+
+#include "logTargets.h"
+#include "threadUtils.hpp"
+
+class Log;
+
+class LogStringBuilder 
+{
+public:
+  LogStringBuilder(LogStringBuilder const& src);
+  LogStringBuilder(Log& l, int p);
+  ~LogStringBuilder();
+
+  template<class T>
+  std::ostream& operator<<(T const& value) { return stream << value; }
+
+private:
+  Log& log;
+  int prio;
+  std::stringstream stream;
+};
+
+class Log
+{
+public:
+  static const int PRIO_ERROR = 1;
+  static const int PRIO_WARNING = 2;
+  static const int PRIO_NOTICE = 3;
+  static const int PRIO_INFO = 4;
+  static const int PRIO_DEBUG = 5;
+
+  static std::string prioToString(int prio);
+
+  static Log& instance();
+
+  void addTarget(std::string conf);
+  void addTarget(LogTargetList::target_type_t type, int prio, std::string conf);
+  LogStringBuilder msg(int prio=PRIO_INFO) { return LogStringBuilder(*this, prio); }
+
+private:
+  Log() {};
+  ~Log() {};
+  Log(const Log &l);
+  void operator=(const Log &l);
+
+  static Log* inst;
+  static Mutex instMutex;
+  class instanceCleaner {
+    public: ~instanceCleaner() {
+      if(Log::inst != 0)
+        delete Log::inst;
+    }
+  };
+  friend class instanceCleaner;
+
+  void log(std::string msg, int prio);
+
+  Mutex mutex;
+  friend class LogStringBuilder;
+
+  LogTargetList targets;
+};
+
+extern Log& cLog;
+
+#endif
diff --git a/src/logTargets.cpp b/src/logTargets.cpp
new file mode 100644 (file)
index 0000000..9a07309
--- /dev/null
@@ -0,0 +1,436 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sstream>
+
+#include "datatypes.h"
+
+#include "logTargets.h"
+#include "log.h"
+#include "anytunError.h"
+
+#include "options.h"
+
+#ifdef LOG_WINEVENTLOG
+#include <windows.h>
+#include <strsafe.h>
+#endif
+
+LogTarget::LogTarget() : opened(false), enabled(false), max_prio(Log::PRIO_NOTICE)
+{
+}
+
+LogTarget::LogTarget(int prio) : opened(false), enabled(false), max_prio(prio)
+{
+}
+
+LogTargetList::~LogTargetList()
+{
+  clear();
+}
+
+LogTargetList::target_type_t LogTargetList::targetTypeFromString(std::string type)
+{
+  if(type == "syslog") return TARGET_SYSLOG;
+  if(type == "file") return TARGET_FILE;
+  if(type == "stdout") return TARGET_STDOUT;
+  if(type == "stderr") return TARGET_STDERR;
+  if(type == "eventlog") return TARGET_WINEVENTLOG;
+  return TARGET_UNKNOWN;
+}
+
+std::string LogTargetList::targetTypeToString(target_type_t type)
+{
+  switch(type) {
+  case TARGET_SYSLOG: return "syslog";
+  case TARGET_FILE: return "file";
+  case TARGET_STDOUT: return "stdout";
+  case TARGET_STDERR: return "stderr";
+  case TARGET_WINEVENTLOG: return "eventlog";
+  default: return "unknown";
+  }
+}
+
+LogTarget* LogTargetList::add(std::string conf)
+{
+  std::stringstream s(conf);
+  std::string type;
+  getline(s, type, ':');
+  if(!s.good())
+    throw syntax_error(conf, 0);
+
+  int prio = Log::PRIO_NOTICE;
+  s >> prio;
+  if(s.fail())
+    throw syntax_error(conf, conf.find_first_of(':')+1);
+
+  char buff[100];
+  if(s.good()) {
+    s.get(buff[0]);
+    if(buff[0] != ',')
+      throw syntax_error(conf, (s.tellg() > 0) ? static_cast<size_t>(s.tellg()) - 1 : 0);
+    s.get(buff, 100);
+  }
+  else
+    buff[0] = 0;
+
+  return add(targetTypeFromString(type), prio, buff);
+}
+
+LogTarget* LogTargetList::add(target_type_t type, int prio, std::string conf)
+{
+  switch(type) {
+  case TARGET_SYSLOG: {
+    #ifdef LOG_SYSLOG
+    if(!LogTargetSyslog::duplicateAllowed() && targets.count(TARGET_SYSLOG))
+      AnytunError::throwErr() << targetTypeToString(TARGET_SYSLOG) << " logtarget is supported only once";
+
+    return targets.insert(TargetsMap::value_type(TARGET_SYSLOG, new LogTargetSyslog(prio, conf)))->second;
+    #else
+    AnytunError::throwErr() << targetTypeToString(TARGET_SYSLOG) << " logtarget is not supported";
+    #endif
+  }
+  case TARGET_FILE: {
+    #ifdef LOG_FILE
+    if(!LogTargetFile::duplicateAllowed() && targets.count(TARGET_FILE))
+      AnytunError::throwErr() << targetTypeToString(TARGET_FILE) << " logtarget is supported only once";
+
+    return targets.insert(TargetsMap::value_type(TARGET_FILE, new LogTargetFile(prio, conf)))->second;
+    #else
+    AnytunError::throwErr() << targetTypeToString(TARGET_FILE) << " logtarget is not supported";
+    #endif
+  }
+  case TARGET_STDOUT: 
+  case TARGET_STDERR: {
+    #ifdef LOG_STDOUT
+    if(!LogTargetStdout::duplicateAllowed() && targets.count(type))
+      AnytunError::throwErr() << targetTypeToString(type) << " logtarget is supported only once";
+    
+    if(type == TARGET_STDERR)
+      return targets.insert(TargetsMap::value_type(type, new LogTargetStdout(prio, std::cerr)))->second;
+    else
+      return targets.insert(TargetsMap::value_type(type, new LogTargetStdout(prio, std::cout)))->second;
+    #else
+    AnytunError::throwErr() << targetTypeToString(type) + " logtarget is not supported";
+    #endif
+  }
+  case TARGET_WINEVENTLOG: {
+    #ifdef LOG_WINEVENTLOG
+    if(!LogTargetWinEventlog::duplicateAllowed() && targets.count(TARGET_WINEVENTLOG))
+      AnytunError::throwErr() << targetTypeToString(TARGET_WINEVENTLOG) << " logtarget is supported only once";
+
+    return targets.insert(TargetsMap::value_type(TARGET_WINEVENTLOG, new LogTargetWinEventlog(prio, conf)))->second;
+    #else
+    AnytunError::throwErr() << targetTypeToString(TARGET_WINEVENTLOG) << " logtarget is not supported";
+    #endif
+  }
+  default: 
+    AnytunError::throwErr() << "unknown log target";
+  }
+  return NULL;
+}
+
+void LogTargetList::clear()
+{
+  TargetsMap::iterator it;
+  for(it = targets.begin(); it != targets.end(); ++it)
+    delete it->second;
+  targets.clear();
+}
+  
+void LogTargetList::log(std::string msg, int prio)
+{
+  TargetsMap::const_iterator it;
+  for(it = targets.begin(); it != targets.end(); ++it) {
+    if(it->second->isEnabled() && it->second->getMaxPrio() >= prio)
+      it->second->log(msg, prio);
+  }
+}
+
+
+#ifdef LOG_SYSLOG
+int LogTargetSyslog::facilityFromString(std::string fac)
+{
+  if(fac == "user") return FAC_USER;
+  if(fac == "mail") return FAC_MAIL;
+  if(fac == "daemon") return FAC_DAEMON;
+  if(fac == "auth") return FAC_AUTH;
+  if(fac == "syslog") return FAC_SYSLOG;
+  if(fac == "lpr") return FAC_LPR;
+  if(fac == "news") return FAC_NEWS;
+  if(fac == "uucp") return FAC_UUCP;
+  if(fac == "cron") return FAC_CRON;
+  if(fac == "authpriv") return FAC_AUTHPRIV;
+  if(fac == "ftp") return FAC_FTP;
+  if(fac == "local0") return FAC_LOCAL0;
+  if(fac == "local1") return FAC_LOCAL1;
+  if(fac == "local2") return FAC_LOCAL2;
+  if(fac == "local3") return FAC_LOCAL3;
+  if(fac == "local4") return FAC_LOCAL4;
+  if(fac == "local5") return FAC_LOCAL5;
+  if(fac == "local6") return FAC_LOCAL6;
+  if(fac == "local7") return FAC_LOCAL7;
+  
+  AnytunError::throwErr() << "unknown syslog facility";
+  return 0;
+}
+
+std::string LogTargetSyslog::facilityToString(int fac)
+{
+  switch(fac) {
+  case FAC_USER: return "user";
+  case FAC_MAIL: return "mail";
+  case FAC_DAEMON: return "daemon";
+  case FAC_AUTH: return "auth";
+  case FAC_SYSLOG: return "syslog";
+  case FAC_LPR: return "lpr";
+  case FAC_NEWS: return "news";
+  case FAC_UUCP: return "uucp";
+  case FAC_CRON: return "cron";
+  case FAC_AUTHPRIV: return "authpriv";
+  case FAC_FTP: return "ftp";
+  case FAC_LOCAL0: return "local0";
+  case FAC_LOCAL1: return "local1";
+  case FAC_LOCAL2: return "local2";
+  case FAC_LOCAL3: return "local3";
+  case FAC_LOCAL4: return "local4";
+  case FAC_LOCAL5: return "local5";
+  case FAC_LOCAL6: return "local6";
+  case FAC_LOCAL7: return "local7";
+  default: AnytunError::throwErr() << "unknown syslog facility";
+  }
+  return "";
+}
+
+LogTargetSyslog::LogTargetSyslog(int prio, std::string conf) : LogTarget(prio)
+{
+  std::stringstream s(conf);
+  facility = FAC_DAEMON;
+  getline(s, logname, ',');
+  if(s.fail()) {
+    logname = "anytun";
+    return;
+  }
+  std::string fac;
+  getline(s, fac, ',');
+  if(s.fail())
+    return;
+
+  facility = LogTargetSyslog::facilityFromString(fac);
+}
+
+LogTargetSyslog::~LogTargetSyslog()
+{
+  if(opened)
+    close();
+}
+
+void LogTargetSyslog::open()
+{
+  openlog(logname.c_str(), LOG_PID, facility);
+  opened = true;
+}
+
+void LogTargetSyslog::close()
+{
+  closelog();
+  opened = false;
+}
+
+void LogTargetSyslog::log(std::string msg, int prio)
+{
+  if(!opened)
+    return;
+
+  syslog((prio + 2) | facility, "%s", msg.c_str());  
+}
+
+LogTargetSyslog& LogTargetSyslog::setLogName(std::string l)
+{
+  logname = l;
+  if(opened)
+    close();
+  open();
+  return *this;
+}
+
+LogTargetSyslog& LogTargetSyslog::setFacility(int f)
+{
+  facility = f;
+  if(opened)
+    close();
+  open();
+  return *this;
+}
+#endif
+
+
+#ifdef LOG_FILE
+LogTargetFile::LogTargetFile(int prio, std::string conf) : LogTarget(prio)
+{
+  std::stringstream s(conf);
+  getline(s, logfilename, ',');
+  if(s.fail())
+    logfilename = "anytun.log";
+}
+
+LogTargetFile::~LogTargetFile()
+{
+  if(opened)
+    close();
+}
+
+void LogTargetFile::open()
+{
+  logfile.open(logfilename.c_str(), std::fstream::out | std::fstream::app);
+  opened = logfile.is_open();
+}
+
+void LogTargetFile::close()
+{
+  if(logfile.is_open())
+    logfile.close();
+  opened = false;
+}
+
+void LogTargetFile::log(std::string msg, int prio)
+{
+  if(!opened)
+    return;
+
+  logfile << Log::prioToString(prio) << ": " << msg << std::endl;
+}
+
+LogTargetFile& LogTargetFile::setLogFilename(std::string l)
+{
+  logfilename = l;
+  if(opened)
+    close();
+  open();
+  return *this;
+}
+#endif
+
+
+#ifdef LOG_STDOUT
+LogTargetStdout::LogTargetStdout(int prio, std::ostream& s) : LogTarget(prio), stream(s)
+{
+}
+
+LogTargetStdout::~LogTargetStdout()
+{
+  if(opened)
+    close();
+}
+
+void LogTargetStdout::open()
+{
+  opened = true;
+}
+
+void LogTargetStdout::close()
+{
+  opened = false;
+}
+
+void LogTargetStdout::log(std::string msg, int prio)
+{
+  if(!opened)
+    return;
+
+  stream << "LOG-" << Log::prioToString(prio) << ": " << msg << std::endl;
+}
+#endif
+
+
+#ifdef LOG_WINEVENTLOG
+LogTargetWinEventlog::LogTargetWinEventlog(int prio, std::string conf) : LogTarget(prio)
+{
+  std::stringstream s(conf);
+  getline(s, logname, ',');
+  if(s.fail())
+    logname = "anytun";
+}
+
+LogTargetWinEventlog::~LogTargetWinEventlog()
+{
+  if(opened)
+    close();
+}
+
+void LogTargetWinEventlog::open()
+{
+  h_event_source = RegisterEventSourceA(NULL, logname.c_str());
+  if(h_event_source)
+    opened = true;
+}
+
+void LogTargetWinEventlog::close()
+{
+  if(h_event_source)
+    DeregisterEventSource(h_event_source);
+  opened = false;
+}
+
+void LogTargetWinEventlog::log(std::string msg, int prio)
+{
+  if(!opened)
+    return;
+
+  LPCTSTR lpszStrings[1];  
+  CHAR buffer[STERROR_TEXT_MAX];
+  StringCchPrintfA(buffer, STERROR_TEXT_MAX, "%s", msg.c_str());
+  lpszStrings[0] = buffer;
+  if(h_event_source)
+    ReportEventA(h_event_source, prioToEventLogType(prio), 0, prio, NULL, 1, 0, lpszStrings, NULL);
+}
+
+LogTargetWinEventlog& LogTargetWinEventlog::setLogName(std::string l)
+{
+  logname = l;
+  if(opened)
+    close();
+  open();
+  return *this;
+}
+
+WORD LogTargetWinEventlog::prioToEventLogType(int prio)
+{
+  switch(prio) {
+  case Log::PRIO_ERROR: return EVENTLOG_ERROR_TYPE;
+  case Log::PRIO_WARNING: return EVENTLOG_WARNING_TYPE;
+  case Log::PRIO_NOTICE: return EVENTLOG_INFORMATION_TYPE;
+  case Log::PRIO_INFO: return EVENTLOG_SUCCESS;
+  case Log::PRIO_DEBUG: return EVENTLOG_INFORMATION_TYPE;
+  default: return EVENTLOG_ERROR_TYPE;
+  }
+}
+#endif
diff --git a/src/logTargets.h b/src/logTargets.h
new file mode 100644 (file)
index 0000000..64ad945
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _LOG_TARGETS_H_
+#define _LOG_TARGETS_H_
+
+#include <string>
+#include <map>
+
+#ifdef LOG_SYSLOG
+#include <syslog.h>
+#endif
+
+#ifdef LOG_FILE
+#include <fstream>
+#endif
+
+#include "datatypes.h"
+
+class LogTarget
+{
+public:
+  LogTarget();
+  LogTarget(int prio);
+  virtual ~LogTarget() {};
+
+  virtual void open() = 0;
+  virtual void close() = 0;
+  bool isOpen() { return opened; };
+
+  void enable() { enabled = true; };
+  void disable() { enabled = false; };
+  bool isEnabled() { return enabled; };
+
+  int getMaxPrio() { return max_prio; };
+  void setMaxPrio(int p) { max_prio = p; };
+
+  virtual void log(std::string msg, int prio) = 0;  
+
+protected:
+  bool opened;
+  bool enabled;
+  int max_prio;
+};
+
+class LogTargetList 
+{
+public:
+  typedef enum { TARGET_UNKNOWN, TARGET_SYSLOG, TARGET_FILE, 
+                 TARGET_STDOUT, TARGET_STDERR, TARGET_WINEVENTLOG } target_type_t;
+
+  static target_type_t targetTypeFromString(std::string type);
+  static std::string targetTypeToString(target_type_t type);
+
+  ~LogTargetList();
+  LogTarget* add(std::string conf);
+  LogTarget* add(target_type_t type, int prio, std::string conf);
+  void clear();
+  
+  void log(std::string msg, int prio);
+
+private:
+  typedef std::multimap<target_type_t, LogTarget*> TargetsMap;
+  TargetsMap targets;
+};
+
+
+#ifdef LOG_SYSLOG
+class LogTargetSyslog : public LogTarget
+{
+public:
+  static const int FAC_USER = LOG_USER;
+  static const int FAC_MAIL = LOG_MAIL;
+  static const int FAC_DAEMON = LOG_DAEMON;
+  static const int FAC_AUTH = LOG_AUTH;
+  static const int FAC_SYSLOG = LOG_SYSLOG;
+  static const int FAC_LPR = LOG_LPR;
+  static const int FAC_NEWS = LOG_NEWS;
+  static const int FAC_UUCP = LOG_UUCP;
+  static const int FAC_CRON = LOG_CRON;
+  static const int FAC_AUTHPRIV = LOG_AUTHPRIV;
+  static const int FAC_FTP = LOG_FTP;
+  static const int FAC_LOCAL0 = LOG_LOCAL0;
+  static const int FAC_LOCAL1 = LOG_LOCAL1;
+  static const int FAC_LOCAL2 = LOG_LOCAL2;
+  static const int FAC_LOCAL3 = LOG_LOCAL3;
+  static const int FAC_LOCAL4 = LOG_LOCAL4;
+  static const int FAC_LOCAL5 = LOG_LOCAL5;
+  static const int FAC_LOCAL6 = LOG_LOCAL6;
+  static const int FAC_LOCAL7 = LOG_LOCAL7;
+
+  static int facilityFromString(std::string fac);
+  static std::string facilityToString(int fac);
+
+  LogTargetSyslog(int prio, std::string conf);
+  ~LogTargetSyslog();
+
+  void open();
+  void close();
+  void log(std::string msg, int prio);  
+  static bool duplicateAllowed() { return false; };
+
+  LogTargetSyslog& setLogName(std::string l); 
+  std::string getLogName() const { return logname; }
+  LogTargetSyslog& setFacility(int f);
+  int getFacility() const { return facility; }
+  
+private:
+  std::string logname;
+  int facility;
+};
+#endif
+
+#ifdef LOG_FILE
+class LogTargetFile : public LogTarget
+{
+public:
+  LogTargetFile(int prio, std::string conf);
+  ~LogTargetFile();
+
+  void open();
+  void close();
+  void log(std::string msg, int prio);  
+  static bool duplicateAllowed() { return true; };
+
+  LogTargetFile& setLogFilename(std::string l); 
+  std::string getLogFilename() const { return logfilename; }
+  
+private:
+  std::string logfilename;
+  std::ofstream logfile;
+};
+#endif
+
+#ifdef LOG_STDOUT
+class LogTargetStdout : public LogTarget
+{
+public:
+  LogTargetStdout(int prio, std::ostream& s);
+  ~LogTargetStdout();
+
+  void open();
+  void close();
+  void log(std::string msg, int prio);  
+  static bool duplicateAllowed() { return false; };
+
+private:
+  std::ostream& stream;
+};
+#endif
+
+#ifdef LOG_WINEVENTLOG
+class LogTargetWinEventlog : public LogTarget
+{
+public:
+  static WORD prioToEventLogType(int prio);
+
+  LogTargetWinEventlog(int prio, std::string conf);
+  ~LogTargetWinEventlog();
+
+  void open();
+  void close();
+  void log(std::string msg, int prio);  
+  static bool duplicateAllowed() { return false; };
+
+  LogTargetWinEventlog& setLogName(std::string l); 
+  std::string getLogName() const { return logname; };
+
+private:
+  std::string logname;
+  HANDLE h_event_source;
+};
+#endif
+
+#endif
diff --git a/src/man/Makefile b/src/man/Makefile
new file mode 100644 (file)
index 0000000..cdd45a6
--- /dev/null
@@ -0,0 +1,57 @@
+##
+##  anytun
+##
+##  The secure anycast tunneling protocol (satp) defines a protocol used
+##  for communication between any combination of unicast and anycast
+##  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+##  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+##  ethernet, ip, arp ...). satp directly includes cryptography and
+##  message authentication based on the methodes used by SRTP.  It is
+##  intended to deliver a generic, scaleable and secure solution for
+##  tunneling and relaying of packets of any protocol.
+##
+##
+##  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+##                          Christian Pointner <satp@wirdorange.org>
+##
+##  This file is part of Anytun.
+##
+##  Anytun is free software: you can redistribute it and/or modify
+##  it under the terms of the GNU General Public License version 3 as
+##  published by the Free Software Foundation.
+##
+##  Anytun is distributed in the hope that it will be useful,
+##  but WITHOUT ANY WARRANTY; without even the implied warranty of
+##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+##  GNU General Public License for more details.
+##
+##  You should have received a copy of the GNU General Public License
+##  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+##
+
+all: manpage
+
+anytun.8: anytun.8.txt
+       a2x -f manpage anytun.8.txt
+
+anytun-controld.8: anytun-controld.8.txt
+       a2x -f manpage anytun-controld.8.txt
+
+anytun-config.8: anytun-config.8.txt
+       a2x -f manpage anytun-config.8.txt
+
+anytun-showtables.8: anytun-showtables.8.txt
+       a2x -f manpage anytun-showtables.8.txt
+
+anyrtpproxy.8: anyrtpproxy.8.txt
+       a2x -f manpage anyrtpproxy.8.txt
+
+
+manpage: anytun.8 anytun-controld.8 anytun-config.8 anytun-showtables.8 anyrtpproxy.8
+
+clean:
+       rm -f anytun.8 anytun.8.xml
+       rm -f anytun-controld.8 anytun-controld.8.xml
+       rm -f anytun-config.8 anytun-config.8.xml
+       rm -f anytun-showtables.8 anytun-showtables.8.xml
+       rm -f anyrtpproxy.8 anyrtpproxy.8.xml
\ No newline at end of file
diff --git a/src/man/anyrtpproxy.8.txt b/src/man/anyrtpproxy.8.txt
new file mode 100644 (file)
index 0000000..a867631
--- /dev/null
@@ -0,0 +1,184 @@
+anyrtpproxy(8)
+==============
+
+NAME
+----
+anyrtpproxy - anycast rtpproxy
+
+SYNOPSIS
+--------
+
+*anyrtpproxy*
+[ *-h|--help* ]
+[ *-D|--nodaemonize* ]
+[ *-C|--chroot* ]
+[ *-u|--username* <username> ]
+[ *-H|--chroot-dir* <directory> ]
+[ *-P|--write-pid* <filename> ]
+[ *-i|--interface* <ip-address> ]
+[ *-s|--control* <hostname|ip>[:<port>] ]
+[ *-p|--port-range* <start> <end> ]
+[ *-n|--nat* ]
+[ *-o|--no-nat-once* ]
+[ *-S|--sync-port* port> ]
+[ *-M|--sync-hosts* <hostname|ip>:<port>[,<hostname|ip>:<port>[...]] ]
+
+
+DESCRIPTION
+-----------
+
+*anyrtpproxy* is a rtpproxy which can be used in combination with anycast. It uses
+the same control protocol than rtpproxy though it can be controled through the nathelper
+plugin of openser. *anyrtpproxy* uses the same synchronisation protocol than *anytun* 
+to sync the session information among all anycast instances.
+
+
+OPTIONS
+-------
+
+-D|--nodaemonize
+~~~~~~~~~~~~~~~~
+
+This option instructs *anyrtpproxy* to run in the foreground
+instead of becoming a daemon.
+
+-C|--chroot
+~~~~~~~~~~~
+
+chroot and drop privileges
+
+-u|--username <username>
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+if chroot change to this user
+
+-H|--chroot-dir <directory>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+chroot to this directory
+
+-P|--write-pid <filename>
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+write pid to this file
+
+-i|--interface <ip address>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The local interface to listen on for RTP packets
+
+-s|--control <hostname|ip>[:<port>]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The local address and port to listen on for control messages from openser
+
+-p|--port-range <start> <end>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A pool of ports which should be used by *anyrtpproxy* to relay RTP packets. 
+The range may not overlap between the anycast instances
+
+-n|--nat
+~~~~~~~~
+
+Allow to learn the remote address and port in order to handle clients behind nat.
+This option should only be enabled if the source is authenticated (i.e. through 
+*anytun*) 
+
+-o|--no-nat-once
+~~~~~~~~~~~~~~~~
+
+Disable learning of remote address and port in case the first packet does not 
+come from the client which is specified by openser during configuration. Invoking
+this parameter increases the security level of the system but in case of nat needs
+a working nat transversal such as stun.
+
+-S|--sync-port <port>
+~~~~~~~~~~~~~~~~~~~~~
+
+local unicast(sync) port to bind to
+
+This port is used by anycast hosts to synchronize information about tunnel
+endpoints. No payload data is transmitted via this port.
+
+It is possible to obtain a list of active connections by telnetting into 
+this port. This port is read-only and unprotected by default. It is advised 
+to protect this port using firewall rules and, eventually, IPsec.
+
+-M|--sync-hosts <hostname|ip>:<port>,[<hostname|ip>:<port>[...]]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+remote hosts to sync with
+
+Here, one has to specify all unicast IP addresses of all 
+other anycast hosts that comprise the anycast tunnel endpoint.
+
+EXAMPLES
+--------
+
+Anycast Setup with 3 instances:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+On the host with unicast hostname unicast1.anycast.anytun.org and anycast 
+hostname anycast.anytun.org:
+--------------------------------------------------------------------------------------
+# anyrtpproxy -i anycast.anytun.org -p 20000 25000 -S 2342 \
+              -M unicast2.anycast.anytun.org:2342,unicast3.anycast.anytun.org:2342
+--------------------------------------------------------------------------------------
+
+On the host with unicast hostname unicast2.anycast.anytun.org and anycast
+hostname anycast.anytun.org:
+--------------------------------------------------------------------------------------
+# anyrtpproxy -i anycast.anytun.org -p 25000 30000 -S 2342 \
+              -M unicast1.anycast.anytun.org:2342,unicast3.anycast.anytun.org:2342
+--------------------------------------------------------------------------------------
+
+On the host with unicast hostname unicast3.anycast.anytun.org and anycast
+hostname anycast.anytun.org:
+--------------------------------------------------------------------------------------
+# anyrtpproxy -i anycast.anytun.org -p 30000 35000 -S 2342 \
+              -M unicast1.anycast.anytun.org:2342,unicast2.anycast.anytun.org:2342
+--------------------------------------------------------------------------------------
+
+
+
+
+BUGS
+----
+Most likely there are some bugs in *anyrtpproxy*. If you find a bug, please let
+the developers know at satp@anytun.org. Of course, patches are preferred.
+
+SEE ALSO
+--------
+anytun(8)
+
+AUTHORS
+-------
+Design of SATP and wizards of this implementation:
+
+Othmar Gsenger <otti@anytun.org>
+Erwin Nindl <nine@anytun.org>
+Christian Pointner <equinox@anytun.org>
+
+Debian packaging:
+
+Andreas Hirczy <ahi@itp.tu-graz.ac.at>
+
+Manual page:
+
+Alexander List <alex@debian.org>
+
+RESOURCES
+---------
+
+Main web site: http://www.anytun.org/
+
+
+COPYING
+-------
+
+Copyright \(C) 2007-2008 Othmar Gsenger, Erwin Nindl and Christian
+Pointner. This  program  is  free software;  you  can redistribute
+it and/or modify it under the terms of the GNU General Public License
+version 2 as published by the Free Software Foundation.
+
diff --git a/src/man/anytun-config.8.txt b/src/man/anytun-config.8.txt
new file mode 100644 (file)
index 0000000..8eb2839
--- /dev/null
@@ -0,0 +1,217 @@
+anytun-config(8)
+================
+
+NAME
+----
+anytun-config - anycast tunneling configuration utility
+
+SYNOPSIS
+--------
+
+*anytun-config*
+[ *-h|--help* ]
+[ *-L|--log* <target>:<level>[,<param1>[,<param2>[..]]]
+[ *-r|--remote-host* <hostname|ip> ]
+[ *-o|--remote-port* <port> ]
+[ *-4|--ipv4-only* ]
+[ *-6|--ipv6-only* ]
+[ *-R|--route* <net>/<prefix length> ]
+[ *-m|--mux* <mux-id> ]
+[ *-w|--window-size* <window size> ]
+[ *-k|--kd-prf* <kd-prf type> ]
+[ *-e|--role <role>* ]
+[ *-E|--passphrase* <pass phrase> ]
+[ *-K|--key* <master key> ]
+[ *-A|--salt* <master salt> ]
+
+DESCRIPTION
+-----------
+
+*anytun-config* writes routing/connection table entries, that can be read by *anytun-controld*.
+
+OPTIONS
+-------
+
+-L|--log <target>:<level>[,<param1>[,<param2>[..]]]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+add log target to logging system. This can be invoked several times
+in order to log to different targets at the same time. Every target 
+hast its own log level which is a number between 0 and 5. Where 0 means
+disabling log and 5 means debug messages are enabled.
+
+The following targets are supported:
+
+* *syslog* - log to syslog daemon, parameters <level>[,<logname>[,<facility>]]
+* *file* - log to file, parameters <level>[,<path>]
+* *stdout* - log to standard output, parameters <level>
+* *stderr* - log to standard error, parameters <level> 
+
+The file target can be used more the once with different levels.
+If no target is provided at the command line a single target with the 
+following config is added:
+
+*syslog:3,uanytun,daemon*
+
+-r|--remote-host <hostname|ip>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+remote host
+
+This option can be used to specify the remote tunnel
+endpoint. In case of anycast tunnel endpoints, the
+anycast IP address has to be used. If you do not specify
+an address, it is automatically determined after receiving
+the first data packet.
+
+-o|--remote-port <port>
+~~~~~~~~~~~~~~~~~~~~~~~
+remote port
+
+The UDP port used for payload data by the remote host
+(specified with -p on the remote host). If you do not specify
+a port, it is automatically determined after receiving
+the first data packet.
+
+-4|--ipv4-only
+~~~~~~~~~~~~~~
+
+Resolv to IPv4 addresses only. The default is to resolv both
+IPv4 and IPv6 addresses.
+
+-6|--ipv6-only
+~~~~~~~~~~~~~~
+
+Resolv to IPv6 addresses only. The default is to resolv both
+IPv4 and IPv6 addresses.
+
+-R|--route <net>/<prefix length>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+add a route to connection. This can be invoked several times.
+
+-m|--mux <mux-id>
+~~~~~~~~~~~~~~~~~
+
+the multiplex id to use. default: 0
+
+-w|--window-size <window size>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+seqence window size
+
+Sometimes, packets arrive out of order on the receiver
+side. This option defines the size of a list of received
+packets' sequence numbers. If, according to this list,
+a received packet has been previously received or has
+been transmitted in the past, and is therefore not in
+the list anymore, this is interpreted as a replay attack
+and the packet is dropped. A value of 0 deactivates this
+list and, as a consequence, the replay protection employed
+by filtering packets according to their secuence number.
+By default the sequence window is disabled and therefore a
+window size of 0 is used.
+
+-k|--kd--prf <kd-prf type>
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+key derivation pseudo random function.
+
+The pseudo random function which is used for calculating the 
+session keys and session salt.
+
+Possible values:
+
+* *null* - no random function, keys and salt are set to 0..00
+* *aes-ctr* - AES in counter mode with 128 Bits, default value
+* *aes-ctr-128* - AES in counter mode with 128 Bits
+* *aes-ctr-192* - AES in counter mode with 192 Bits
+* *aes-ctr-256* - AES in counter mode with 256 Bits
+
+-e|--role <role>
+~~~~~~~~~~~~~~~~
+
+SATP uses different session keys for inbound and outbound traffic. The
+role parameter is used to determine which keys to use for outbound or
+inbound packets. On both sides of a vpn connection different roles have 
+to be used. Possible values are *left* and *right*. You may also use 
+*alice* or *server* as a replacement for *left* and *bob* or *client* as 
+a replacement for *right*. By default *left* is used.
+
+-E|--passphrase <pass phrase>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This passphrase is used to generate the master key and master salt.
+For the master key the last n bits of the SHA256 digest of the 
+passphrase (where n is the length of the master key in bits) is used. 
+The master salt gets generated with the SHA1 digest. 
+You may force a specific key and or salt by using *--key* and *--salt*.
+
+-K|--key <master key>
+~~~~~~~~~~~~~~~~~~~~~
+
+master key to use for key derivation
+
+Master key in hexadecimal notation, eg
+01a2b3c4d5e6f708a9b0cadbecfd0fa1, with a mandatory length
+of 32, 48 or 64 characters (128, 192 or 256 bits).
+
+-A|--salt <master salt>
+~~~~~~~~~~~~~~~~~~~~~~~
+
+master salt to use for key derivation
+
+Master salt in hexadecimal notation, eg
+01a2b3c4d5e6f708a9b0cadbecfd, with a mandatory length
+of 28 characters (14 bytes).
+
+
+EXAMPLES
+--------
+
+Add a client with Connection ID (Mux) 12 and add 2 Routes to this client
+
+------------------------------------------------------------------------------------------------ 
+# anytun-config -w 0 -m 12 -K 0123456789ABCDEFFEDCBA9876543210 -A 0123456789ABCDDCBA9876543210 \
+                -R 192.0.2.0/24 -R 192.168.1.1/32 -e server >> routingtable
+------------------------------------------------------------------------------------------------ 
+
+BUGS
+----
+Most likely there are some bugs in *anytun*. If you find a bug, please let
+the developers know at satp@anytun.org. Of course, patches are preferred.
+
+SEE ALSO
+--------
+anytun(8), anytun-controld(8), anytun-showtables(8)
+
+AUTHORS
+-------
+Design of SATP and wizards of this implementation:
+
+Othmar Gsenger <otti@anytun.org>
+Erwin Nindl <nine@anytun.org>
+Christian Pointner <equinox@anytun.org>
+
+Debian packaging:
+
+Andreas Hirczy <ahi@itp.tu-graz.ac.at>
+
+Manual page:
+
+Alexander List <alex@debian.org>
+
+RESOURCES
+---------
+
+Main web site: http://www.anytun.org/
+
+
+COPYING
+-------
+
+Copyright \(C) 2007-2008 Othmar Gsenger, Erwin Nindl and Christian
+Pointner. This  program  is  free software;  you  can redistribute
+it and/or modify it under the terms of the GNU General Public License
+version 2 as published by the Free Software Foundation.
+
diff --git a/src/man/anytun-controld.8.txt b/src/man/anytun-controld.8.txt
new file mode 100644 (file)
index 0000000..2b1c7a1
--- /dev/null
@@ -0,0 +1,136 @@
+anytun-controld(8)
+==================
+
+NAME
+----
+anytun-controld - anycast tunneling control daemon
+
+SYNOPSIS
+--------
+
+*anytun-controld*
+[ *-h|--help* ]
+[ *-D|--nodaemonize* ]
+[ *-u|--username* <username> ]
+[ *-g|--groupname* <groupname> ]
+[ *-C|--chroot* <path> ]
+[ *-P|--write-pid* <filename> ]
+[ *-L|--log* <target>:<level>[,<param1>[,<param2>[..]]] ]
+[ *-f|--file* <path> ]
+[ *-X|--control-host* < <host>[:port>] | :<port> > ]
+
+DESCRIPTION
+-----------
+
+*anytun-controld* configures the multi-connection support for *anytun*. It reads a connection/routing table and outputs it via a tcp socket to all connected *anytun* servers. When the control daemon is restarted with a new connection/routing table all *anytun* servers automatically load the new configuration. Please make sure to protect that information as it contains the connection keys.
+
+OPTIONS
+-------
+
+-D|--nodaemonize
+~~~~~~~~~~~~~~~~
+
+This option instructs *anytun* to run in foreground
+instead of becoming a daemon which is the default.
+
+-u|--username <username>
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+run as this user. If no group is specified (*-g*) the default group of 
+the user is used. The default is to not drop privileges.
+
+-g|--groupname <groupname>
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+run as this group. If no username is specified (*-u*) this gets ignored.
+The default is to not drop privileges.
+
+-C|--chroot <path>
+~~~~~~~~~~~~~~~~~~
+
+Instruct *anytun* to run in a chroot jail. The default is 
+to not run in chroot.
+
+-P|--write-pid <filename>
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Instruct *anytun* to write it's pid to this file. The default is 
+to not create a pid file.
+
+-L|--log <target>:<level>[,<param1>[,<param2>[..]]]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+add log target to logging system. This can be invoked several times
+in order to log to different targets at the same time. Every target 
+hast its own log level which is a number between 0 and 5. Where 0 means
+disabling log and 5 means debug messages are enabled.
+
+The following targets are supported:
+
+* *syslog* - log to syslog daemon, parameters <level>[,<logname>[,<facility>]]
+* *file* - log to file, parameters <level>[,<path>]
+* *stdout* - log to standard output, parameters <level>
+* *stderr* - log to standard error, parameters <level> 
+
+The file target can be used more the once with different levels.
+If no target is provided at the command line a single target with the 
+following config is added:
+
+*syslog:3,uanytun,daemon*
+
+-f|--file <path>
+~~~~~~~~~~~~~~~~
+
+The path to the file which holds the sync information.
+
+-X|--control-host < <host>[:<port>] | :<port> >
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The local ip address and or tcp port to bind to. Mind that if an 
+address is given the port can be omitted in which case port 2323 
+is used. You can also specify to listen on an specific port but on
+all interfaces by omitting the address. If you want to specify an
+ipv6 address and a port you have to use [ and ] to seperate the address
+from the port, eg.: [::1]:1234. If you want to use the default port 
+[ and ] can be omitted. default: 127.0.0.1:2323
+
+
+BUGS
+----
+Most likely there are some bugs in *anytun*. If you find a bug, please let
+the developers know at satp@anytun.org. Of course, patches are preferred.
+
+SEE ALSO
+--------
+anytun(8), anytun-config(8), anytun-showtables(8)
+
+AUTHORS
+-------
+Design of SATP and wizards of this implementation:
+
+Othmar Gsenger <otti@anytun.org>
+Erwin Nindl <nine@anytun.org>
+Christian Pointner <equinox@anytun.org>
+
+Debian packaging:
+
+Andreas Hirczy <ahi@itp.tu-graz.ac.at>
+
+Manual page:
+
+Alexander List <alex@debian.org>
+
+RESOURCES
+---------
+
+Main web site: http://www.anytun.org/
+
+
+COPYING
+-------
+
+Copyright \(C) 2007-2008 Othmar Gsenger, Erwin Nindl and Christian
+Pointner. This  program  is  free software;  you  can redistribute
+it and/or modify it under the terms of the GNU General Public License
+version 2 as published by the Free Software Foundation.
+
diff --git a/src/man/anytun-showtables.8.txt b/src/man/anytun-showtables.8.txt
new file mode 100644 (file)
index 0000000..9a04f26
--- /dev/null
@@ -0,0 +1,77 @@
+anytun-showtables(8)
+====================
+
+NAME
+----
+anytun-showtables - anycast tunneling routing table visualization utility
+
+SYNOPSIS
+--------
+
+*anytun-showtables*
+
+DESCRIPTION
+-----------
+
+*anytun-showtables* displays routing and connection tables used by *anytun*. It can be used to display a saved routing/connection table used by *anytun-controld* or to connect to a the sync port of *anytun*.
+
+OPTIONS
+-------
+
+This Tool does not take any options. It takes the sync information from
+the standard input and prints the routing table to the standard output.
+
+EXAMPLES
+--------
+
+Print routing table stored in local file
+
+-----------------------------------------------------------------------------------
+# perl -ne 'chomp; print' < routingtable | ./anytun-showtables
+-----------------------------------------------------------------------------------
+
+Print current routing table and watch changes
+
+-----------------------------------------------------------------------------------
+# nc unicast1.anycast.anytun.org 23 | ./anytun-showtables
+-----------------------------------------------------------------------------------
+
+BUGS
+----
+Most likely there are some bugs in *anytun*. If you find a bug, please let
+the developers know at satp@anytun.org. Of course, patches are preferred.
+
+SEE ALSO
+--------
+anytun(8), anytun-controld(8), anytun-config(8)
+
+AUTHORS
+-------
+Design of SATP and wizards of this implementation:
+
+Othmar Gsenger <otti@anytun.org>
+Erwin Nindl <nine@anytun.org>
+Christian Pointner <equinox@anytun.org>
+
+Debian packaging:
+
+Andreas Hirczy <ahi@itp.tu-graz.ac.at>
+
+Manual page:
+
+Alexander List <alex@debian.org>
+
+RESOURCES
+---------
+
+Main web site: http://www.anytun.org/
+
+
+COPYING
+-------
+
+Copyright \(C) 2007-2008 Othmar Gsenger, Erwin Nindl and Christian
+Pointner. This  program  is  free software;  you  can redistribute
+it and/or modify it under the terms of the GNU General Public License
+version 2 as published by the Free Software Foundation.
+
diff --git a/src/man/anytun.8.txt b/src/man/anytun.8.txt
new file mode 100644 (file)
index 0000000..fa30441
--- /dev/null
@@ -0,0 +1,468 @@
+anytun(8)
+=========
+
+NAME
+----
+anytun - anycast tunneling daemon
+
+SYNOPSIS
+--------
+
+*anytun*
+[ *-h|--help* ]
+[ *-D|--nodaemonize* ]
+[ *-u|--username* <username> ]
+[ *-g|--groupname* <groupname> ]
+[ *-C|--chroot* <path> ]
+[ *-P|--write-pid* <filename> ]
+[ *-L|--log* <target>:<level>[,<param1>[,<param2>[..]]] ]
+[ *-i|--interface* <ip-address> ]
+[ *-p|--port* <port> ]
+[ *-r|--remote-host* <hostname|ip> ]
+[ *-o|--remote-port* <port> ]
+[ *-4|--ipv4-only* ]
+[ *-6|--ipv6-only* ]
+[ *-I|--sync-interface* <ip-address> ]
+[ *-S|--sync-port* port> ]
+[ *-M|--sync-hosts* <hostname|ip>[:<port>][,<hostname|ip>[:<port>][...]] ]
+[ *-X|--control-host* <hostname|ip>[:<port>]
+[ *-d|--dev* <name> ]
+[ *-t|--type* <tun|tap> ]
+[ *-n|--ifconfig* <local>/<prefix> ]
+[ *-x|--post-up-script* <script> ]
+[ *-R|--route* <net>/<prefix length> ]
+[ *-m|--mux* <mux-id> ]
+[ *-s|--sender-id* <sender id> ]
+[ *-w|--window-size* <window size> ]
+[ *-k|--kd-prf* <kd-prf type> ]
+[ *-e|--role <role>* ]
+[ *-E|--passphrase* <pass phrase> ]
+[ *-K|--key* <master key> ]
+[ *-A|--salt* <master salt> ]
+[ *-c|--cipher* <cipher type> ]
+[ *-a|--auth-algo* <algo type> ]
+[ *-b|--auth-tag-length* <length> ]
+
+DESCRIPTION
+-----------
+
+*Anytun* is an implementation of the Secure Anycast Tunneling Protocol
+(SATP). It provides a complete VPN solution similar to OpenVPN or
+IPsec in tunnel mode. The main difference is that anycast enables the
+setup of tunnels between an arbitrary combination of anycast, unicast
+and multicast hosts.
+
+OPTIONS
+-------
+
+*Anytun* has been designed as a peer to peer application, so there is
+no difference between client and server. The following options can be
+passed to the daemon:
+
+-D|--nodaemonize
+~~~~~~~~~~~~~~~~
+
+This option instructs *anytun* to run in foreground
+instead of becoming a daemon which is the default.
+
+-u|--username <username>
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+run as this user. If no group is specified (*-g*) the default group of 
+the user is used. The default is to not drop privileges.
+
+-g|--groupname <groupname>
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+run as this group. If no username is specified (*-u*) this gets ignored.
+The default is to not drop privileges.
+
+-C|--chroot <path>
+~~~~~~~~~~~~~~~~~~
+
+Instruct *anytun* to run in a chroot jail. The default is 
+to not run in chroot.
+
+-P|--write-pid <filename>
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Instruct *anytun* to write it's pid to this file. The default is 
+to not create a pid file.
+
+-L|--log <target>:<level>[,<param1>[,<param2>[..]]]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+add log target to logging system. This can be invoked several times
+in order to log to different targets at the same time. Every target 
+hast its own log level which is a number between 0 and 5. Where 0 means
+disabling log and 5 means debug messages are enabled.
+
+The following targets are supported:
+
+* *syslog* - log to syslog daemon, parameters <level>[,<logname>[,<facility>]]
+* *file* - log to file, parameters <level>[,<path>]
+* *stdout* - log to standard output, parameters <level>
+* *stderr* - log to standard error, parameters <level> 
+
+The file target can be used more the once with different levels.
+If no target is provided at the command line a single target with the 
+following config is added:
+
+*syslog:3,uanytun,daemon*
+
+-i|--interface <ip address>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This IP address is used as the sender address for outgoing
+packets. In case of anycast tunnel endpoints, the anycast
+IP has to be used. In case of unicast endpoints, the
+address is usually derived correctly from the routing
+table. The default is to not use a special inteface and just
+bind on all interfaces.
+
+-p|--port <port>
+~~~~~~~~~~~~~~~~
+
+local anycast(data) port to bind to
+
+The local UDP port that is used to send and receive the
+payload data. The two tunnel endpoints can use different
+ports. If a tunnel endpoint consists of multiple anycast
+hosts, all hosts have to use the same port. default: 4444
+
+-r|--remote-host <hostname|ip>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+remote host
+
+This option can be used to specify the remote tunnel
+endpoint. In case of anycast tunnel endpoints, the
+anycast IP address has to be used. If you do not specify
+an address, it is automatically determined after receiving
+the first data packet.
+
+-o|--remote-port <port>
+~~~~~~~~~~~~~~~~~~~~~~~
+remote port
+
+The UDP port used for payload data by the remote host
+(specified with -p on the remote host). If you do not specify
+a port, it is automatically determined after receiving
+the first data packet.
+
+-4|--ipv4-only
+~~~~~~~~~~~~~~
+
+Resolv to IPv4 addresses only. The default is to resolv both
+IPv4 and IPv6 addresses.
+
+-6|--ipv6-only
+~~~~~~~~~~~~~~
+
+Resolv to IPv6 addresses only. The default is to resolv both
+IPv4 and IPv6 addresses.
+
+-I|--sync-interface <ip-address>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+local unicast(sync) ip address to bind to
+
+This option is only needed for tunnel endpoints consisting
+of multiple anycast hosts. The unicast IP address of
+the anycast host can be used here. This is needed for
+communication with the other anycast hosts. The default is to 
+not use a special inteface and just bind on all interfaces. However
+this is only the case if synchronisation is active see *--sync-port*.
+
+-S|--sync-port <port>
+~~~~~~~~~~~~~~~~~~~~~
+
+local unicast(sync) port to bind to
+
+This option is only needed for tunnel endpoints
+consisting of multiple anycast hosts. This port is used
+by anycast hosts to synchronize information about tunnel
+endpoints. No payload data is transmitted via this port.
+By default the synchronisation is disabled an therefore the
+port is kept empty.
+
+It is possible to obtain a list of active connections
+by telnetting into this port. This port is read-only
+and unprotected by default. It is advised to protect
+this port using firewall rules and, eventually, IPsec.
+
+-M|--sync-hosts <hostname|ip>[:<port>],[<hostname|ip>[:<port>][...]]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+remote hosts to sync with
+
+This option is only needed for tunnel endpoints consisting
+of multiple anycast hosts. Here, one has to specify all
+unicast IP addresses of all other anycast hosts that
+comprise the anycast tunnel endpoint. By default synchronisation is
+disabled and therefore this is empty. Mind that the port can be
+omitted in which case port 2323 is used. If you want to specify an
+ipv6 address and a port you have to use [ and ] to seperate the address
+from the port, eg.: [::1]:1234. If you want to use the default port 
+[ and ] can be omitted.
+
+-X|--control-host <hostname|ip>[:<port>]
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+fetch the config from this host. The default is not to use a control
+host and therefore this is empty. Mind that the port can be omitted 
+in which case port 2323 is used. If you want to specify an
+ipv6 address and a port you have to use [ and ] to seperate the address
+from the port, eg.: [::1]:1234. If you want to use the default port 
+[ and ] can be omitted.
+
+-d|--dev <name>
+~~~~~~~~~~~~~~~
+device name
+
+By default, tapN is used for Ethernet tunnel interfaces,
+and tunN for IP tunnels, respectively. This option can
+be used to manually override these defaults.
+
+-t|--type <tun|tap>
+~~~~~~~~~~~~~~~~~~~
+
+device type
+
+Type of the tunnels to create. Use tap for Ethernet
+tunnels, tun for IP tunnels.
+
+-n|--ifconfig <local>/<prefix>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+*<local>* the local IP address for the tun/tap device
+
+*<prefix>* the prefix length of the network
+
+The local IP address and prefix length. The remote tunnel endpoint
+has to use a different IP address in the same subnet
+
+-x|--post-up-script <script>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This option instructs *anytun* to run this script after the interface 
+is created. By default no script will be executed.
+
+-R|--route <net>/<prefix length>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+add a route to connection. This can be invoked several times.
+
+-m|--mux <mux-id>
+~~~~~~~~~~~~~~~~~
+
+the multiplex id to use. default: 0
+
+-s|--sender-id  <sender id>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Each anycast tunnel endpoint needs a uniqe sender id
+(1, 2, 3, ...). It is needed to distinguish the senders
+in case of replay attacks. This option can be ignored on
+unicast endpoints. default: 0
+
+-w|--window-size <window size>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+seqence window size
+
+Sometimes, packets arrive out of order on the receiver
+side. This option defines the size of a list of received
+packets' sequence numbers. If, according to this list,
+a received packet has been previously received or has
+been transmitted in the past, and is therefore not in
+the list anymore, this is interpreted as a replay attack
+and the packet is dropped. A value of 0 deactivates this
+list and, as a consequence, the replay protection employed
+by filtering packets according to their secuence number.
+By default the sequence window is disabled and therefore a
+window size of 0 is used.
+
+-k|--kd--prf <kd-prf type>
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+key derivation pseudo random function.
+
+The pseudo random function which is used for calculating the 
+session keys and session salt.
+
+Possible values:
+
+* *null* - no random function, keys and salt are set to 0..00
+* *aes-ctr* - AES in counter mode with 128 Bits, default value
+* *aes-ctr-128* - AES in counter mode with 128 Bits
+* *aes-ctr-192* - AES in counter mode with 192 Bits
+* *aes-ctr-256* - AES in counter mode with 256 Bits
+
+-e|--role <role>
+~~~~~~~~~~~~~~~~
+
+SATP uses different session keys for inbound and outbound traffic. The
+role parameter is used to determine which keys to use for outbound or
+inbound packets. On both sides of a vpn connection different roles have 
+to be used. Possible values are *left* and *right*. You may also use 
+*alice* or *server* as a replacement for *left* and *bob* or *client* as 
+a replacement for *right*. By default *left* is used.
+
+-E|--passphrase <pass phrase>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This passphrase is used to generate the master key and master salt.
+For the master key the last n bits of the SHA256 digest of the 
+passphrase (where n is the length of the master key in bits) is used. 
+The master salt gets generated with the SHA1 digest. 
+You may force a specific key and or salt by using *--key* and *--salt*.
+
+-K|--key <master key>
+~~~~~~~~~~~~~~~~~~~~~
+
+master key to use for key derivation
+
+Master key in hexadecimal notation, eg
+01a2b3c4d5e6f708a9b0cadbecfd0fa1, with a mandatory length
+of 32, 48 or 64 characters (128, 192 or 256 bits).
+
+-A|--salt <master salt>
+~~~~~~~~~~~~~~~~~~~~~~~
+
+master salt to use for key derivation
+
+Master salt in hexadecimal notation, eg
+01a2b3c4d5e6f708a9b0cadbecfd, with a mandatory length
+of 28 characters (14 bytes).
+
+-c|--cipher <cipher type>
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+payload encryption algorithm
+
+Encryption algorithm used for encrypting the payload
+
+Possible values:
+
+* *null* - no encryption
+* *aes-ctr* - AES in counter mode with 128 Bits, default value
+* *aes-ctr-128* - AES in counter mode with 128 Bits
+* *aes-ctr-192* - AES in counter mode with 192 Bits
+* *aes-ctr-256* - AES in counter mode with 256 Bits
+
+-a|--auth-algo <algo type>
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+message authentication algorithm
+
+This option sets the message authentication algorithm.
+
+Possible values:
+
+* *null* - no message authentication
+* *sha1* - HMAC-SHA1, default value
+
+If HMAC-SHA1 is used, the packet length is increased. The additional bytes 
+contain the authentication data. see *-b|--auth-tag-length* for more info.
+
+-b|--auth-tag-length <length>
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The number of bytes to use for the auth tag. This value defaults to 10 bytes 
+unless the *null* auth algo is used in which case it defaults to 0. 
+
+
+EXAMPLES
+--------
+
+P2P Setup between two unicast enpoints:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Host A:
+^^^^^^^
+
+anytun -r hostb.example.com -t tun -n 192.168.123.1/30 -c aes-ctr-256 -k aes-ctr-256 \
+       -E have_a_very_safe_and_productive_day -e left
+
+Host B:
+^^^^^^^
+anytun -r hosta.example.com -t tun -n 192.168.123.2/30 -c aes-ctr-256 -k aes-ctr-256 \
+       -E have_a_very_safe_and_productive_day -e right
+
+
+One unicast and one anycast tunnel endpoint:
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Unicast tunnel endpoint:
+^^^^^^^^^^^^^^^^^^^^^^^^
+
+anytun -r anycast.anytun.org -d anytun0 -t tun -n 192.0.2.2/30 -a null -c null -w 0 -e client
+
+Anycast tunnel endpoints:
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+On the host with unicast hostname unicast1.anycast.anytun.org and anycast 
+hostname anycast.anytun.org:
+-------------------------------------------------------------------------------------------------
+# anytun -i anycast.anytun.org -d anytun0 -t tun -n 192.0.2.1/30 -a null -c null -w 0 -e server \
+         -S 2342 -M unicast2.anycast.anytun.org:2342,unicast3.anycast.anytun.org:2342
+-------------------------------------------------------------------------------------------------
+
+On the host with unicast hostname unicast2.anycast.anytun.org and anycast
+hostname anycast.anytun.org:
+-------------------------------------------------------------------------------------------------
+# anytun -i anycast.anytun.org -d anytun0 -t tun -n 192.0.2.1/30 -a null -c null -w 0 -e server \
+         -S 2342 -M unicast1.anycast.anytun.org:2342,unicast3.anycast.anytun.org:2342
+-------------------------------------------------------------------------------------------------
+
+On the host with unicast hostname unicast3.anycast.anytun.org and anycast
+hostname anycast.anytun.org:
+-------------------------------------------------------------------------------------------------
+# anytun -i anycast.anytun.org -d anytun0 -t tun -n 192.0.2.1/30 -a null -c null -w 0 -e server \
+         -S 2342 -M unicast1.anycast.anytun.org:2342,unicast2.anycast.anytun.org:2342
+-------------------------------------------------------------------------------------------------
+
+For more sophisticated examples (like multiple unicast endpoints to one
+anycast tunnel endpoint) please consult the man page of anytun-config(8).
+
+
+BUGS
+----
+Most likely there are some bugs in *anytun*. If you find a bug, please let
+the developers know at satp@anytun.org. Of course, patches are preferred.
+
+SEE ALSO
+--------
+anytun-config(8), anytun-controld(8), anytun-showtables(8)
+
+AUTHORS
+-------
+Design of SATP and wizards of this implementation:
+
+Othmar Gsenger <otti@anytun.org>
+Erwin Nindl <nine@anytun.org>
+Christian Pointner <equinox@anytun.org>
+
+Debian packaging:
+
+Andreas Hirczy <ahi@itp.tu-graz.ac.at>
+
+Manual page:
+
+Alexander List <alex@debian.org>
+
+RESOURCES
+---------
+
+Main web site: http://www.anytun.org/
+
+
+COPYING
+-------
+
+Copyright \(C) 2007-2008 Othmar Gsenger, Erwin Nindl and Christian
+Pointner. This  program  is  free software;  you  can redistribute
+it and/or modify it under the terms of the GNU General Public License
+version 2 as published by the Free Software Foundation.
+
diff --git a/src/networkAddress.cpp b/src/networkAddress.cpp
new file mode 100644 (file)
index 0000000..61c8318
--- /dev/null
@@ -0,0 +1,203 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "threadUtils.hpp"
+#include "datatypes.h"
+#include <exception>
+
+#include "networkAddress.h"
+#include "anytunError.h"
+
+NetworkAddress::NetworkAddress():ipv4_address_(),ipv6_address_()
+{
+       network_address_type_=ipv4;
+}
+
+NetworkAddress::NetworkAddress(const NetworkAddress & ref) : mutex_(),ipv4_address_(ref.ipv4_address_),ipv6_address_(ref.ipv6_address_),ethernet_address_(ref.ethernet_address_),network_address_type_(ref.network_address_type_)
+{
+}
+
+NetworkAddress::NetworkAddress(const std::string & address)
+{
+       boost::asio::ip::address addr = boost::asio::ip::address::from_string(address);
+       if (addr.is_v4())
+       {
+               network_address_type_=ipv4;
+               ipv4_address_ = addr.to_v4();
+       } else {
+               network_address_type_=ipv6;
+               ipv6_address_ = addr.to_v6();
+       }
+}
+
+NetworkAddress::NetworkAddress(boost::asio::ip::address_v6 ipv6_address)
+{
+       network_address_type_=ipv6;
+       ipv6_address_ = ipv6_address;
+}
+
+NetworkAddress::NetworkAddress(boost::asio::ip::address_v4 ipv4_address)
+{
+       network_address_type_=ipv4;
+       ipv4_address_ = ipv4_address;
+}
+
+NetworkAddress::NetworkAddress(u_int64_t ethernet_address)
+{
+       network_address_type_=ethernet;
+       ethernet_address_=ethernet_address;
+}
+
+
+NetworkAddress::~NetworkAddress()
+{
+}
+
+NetworkAddress::NetworkAddress(const network_address_type_t type, const std::string & address )
+{
+       setNetworkAddress( type, address);
+}
+
+void NetworkAddress::setNetworkAddress(const network_address_type_t type, const std::string & address )
+{
+       if (type==ipv4)
+       {
+               ipv4_address_=boost::asio::ip::address_v4::from_string(address);
+       } else if (type==ipv6) {
+               ipv6_address_=boost::asio::ip::address_v6::from_string(address);
+       } else if (type==ethernet) {
+               //TODO
+       } else {
+               //TODO
+       }
+       network_address_type_ = type;
+}
+
+void NetworkAddress::setNetworkAddress(boost::asio::ip::address_v4 addr)
+{
+       network_address_type_=ipv4;
+       ipv4_address_ = addr;
+}
+
+void NetworkAddress::setNetworkAddress(boost::asio::ip::address_v6 addr)
+{
+       network_address_type_=ipv6;
+       ipv6_address_ = addr;
+}
+
+void NetworkAddress::setNetworkAddress(u_int64_t addr)
+{
+       network_address_type_=ethernet;
+       ethernet_address_=addr;
+}
+
+network_address_type_t NetworkAddress::getNetworkAddressType() const
+{
+       return network_address_type_;
+}
+
+const boost::asio::ip::address_v4& NetworkAddress::getNetworkAddressV4() const
+{
+  if(network_address_type_ != ipv4)
+    AnytunError::throwErr() << "wrong address type";
+  
+  return ipv4_address_;
+}
+
+const boost::asio::ip::address_v6& NetworkAddress::getNetworkAddressV6() const
+{
+  if(network_address_type_ != ipv6)
+    AnytunError::throwErr() << "wrong address type";
+  
+  return ipv6_address_;
+}
+
+const u_int64_t NetworkAddress::getNetworkAdrressEther() const
+{
+  if(network_address_type_ != ethernet)
+    AnytunError::throwErr() << "wrong address type";
+  
+  return ethernet_address_;
+}
+
+std::string NetworkAddress::toString() const
+{
+       if (network_address_type_==ipv4){
+               return ipv4_address_.to_string();
+       } 
+  else if (network_address_type_==ipv6) {
+               return ipv6_address_.to_string();
+       } 
+  else if (network_address_type_==ethernet) {
+        // TODO
+       } 
+  return std::string("");
+}
+
+ipv4_bytes_type        NetworkAddress::to_bytes_v4() const
+{
+       return ipv4_address_.to_bytes();
+}
+
+ipv6_bytes_type        NetworkAddress::to_bytes_v6() const
+{
+       return ipv6_address_.to_bytes();
+}
+
+ethernet_bytes_type    NetworkAddress::to_bytes_ethernet() const
+{
+       boost::array<unsigned char,6> result;
+       u_int64_t ether=ethernet_address_;
+       for (int i = 0; i < 6; i++)
+       {
+               result[i] = (unsigned char) (ether && 0xff);
+                       ether >>= 8;
+       }
+       return result;
+}
+
+bool NetworkAddress::operator<(const NetworkAddress &right) const
+{
+       if (network_address_type_!=right.network_address_type_)
+               AnytunError::throwErr() << "NetworkAddress::operator<() address types don't match";
+       if (network_address_type_==ipv4)
+       {
+               return (ipv4_address_ < right.ipv4_address_);
+       } else if (network_address_type_==ipv6) {
+               return (ipv6_address_ < right.ipv6_address_);
+       } else if (network_address_type_==ethernet) {
+                return (ethernet_address_ < right.ethernet_address_);
+       } else {
+               //TODO
+       }
+       return false;
+}
+
diff --git a/src/networkAddress.h b/src/networkAddress.h
new file mode 100644 (file)
index 0000000..d683b4c
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _NETWORK_ADDRESS_H
+#define _NETWORK_ADDRESS_H
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/archive/text_iarchive.hpp>
+
+#include "threadUtils.hpp"
+#include "datatypes.h"
+
+#include <string>
+#include <boost/asio.hpp>
+#include <boost/array.hpp>
+
+typedef boost::array<unsigned char,6> ethernet_bytes_type;
+typedef boost::asio::ip::address_v4::bytes_type ipv4_bytes_type;
+typedef boost::asio::ip::address_v6::bytes_type ipv6_bytes_type;
+
+enum network_address_type_t
+{
+       ipv4=0,
+       ipv6=1,
+       ethernet=2
+};
+
+class NetworkAddress
+{
+public:
+       NetworkAddress();
+       NetworkAddress(const NetworkAddress &);
+       NetworkAddress(const std::string &);
+       NetworkAddress(boost::asio::ip::address_v6);
+       NetworkAddress(boost::asio::ip::address_v4);
+       NetworkAddress(u_int64_t);
+       NetworkAddress(const network_address_type_t type, const std::string & address );
+       ~NetworkAddress();
+       void setNetworkAddress(const network_address_type_t type, const std::string & address );
+       void setNetworkAddress(boost::asio::ip::address_v4);
+       void setNetworkAddress(boost::asio::ip::address_v6);
+       void setNetworkAddress(u_int64_t);
+       network_address_type_t getNetworkAddressType() const;
+  std::string toString() const;
+       bool operator<(const NetworkAddress &s) const;
+       ipv4_bytes_type to_bytes_v4() const;    
+       ipv6_bytes_type to_bytes_v6() const;    
+       ethernet_bytes_type to_bytes_ethernet() const;  
+  const boost::asio::ip::address_v4& getNetworkAddressV4() const;
+  const boost::asio::ip::address_v6& getNetworkAddressV6() const;
+  const u_int64_t getNetworkAdrressEther() const;
+protected:
+  Mutex mutex_;
+       boost::asio::ip::address_v4 ipv4_address_;
+       boost::asio::ip::address_v6 ipv6_address_;
+       u_int64_t ethernet_address_;
+       network_address_type_t network_address_type_;
+private:
+       NetworkAddress operator=(const NetworkAddress &s);
+  friend class boost::serialization::access;
+  template<class Archive>
+  void serialize(Archive & ar, const unsigned int version)
+  {
+    ar & network_address_type_;
+               if (network_address_type_==ipv4)
+               {
+                       std::string ip(ipv4_address_.to_string());
+                       ar & ip;
+                       ipv4_address_=boost::asio::ip::address_v4::from_string(ip);
+               }
+               if (network_address_type_==ipv6)
+               {
+                       std::string ip(ipv6_address_.to_string());
+                       ar & ip;
+                       ipv6_address_=boost::asio::ip::address_v6::from_string(ip);
+               }
+               if (network_address_type_==ethernet)
+                       ar & ethernet_address_;
+   }
+};
+
+//                     for(int i=0;i<4;i++)
+//#if defined(__GNUC__) && defined(__linux__)
+//                             ar & ipv6_address_.s6_addr32;
+//#elif defined(__GNUC__) && defined(__OpenBSD__)
+//        ar & ipv6_address_.__u6_addr.__u6_addr32;
+//#else
+// #error Target not supported
+//#endif
+#endif
diff --git a/src/networkPrefix.cpp b/src/networkPrefix.cpp
new file mode 100644 (file)
index 0000000..045b251
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "threadUtils.hpp"
+#include "datatypes.h"
+
+#include "networkPrefix.h"
+
+
+NetworkPrefix::NetworkPrefix(): NetworkAddress(),length_(0)
+{
+}
+
+NetworkPrefix::NetworkPrefix(const NetworkAddress & src,u_int8_t length): NetworkAddress(src),length_(length)
+{
+}
+
+NetworkPrefix::NetworkPrefix(const NetworkPrefix & src): NetworkAddress(src),length_(src.length_)
+{
+}
+
+void NetworkPrefix::setNetworkPrefixLength(u_int8_t length )
+{
+       length_ = length;
+}
+
+u_int8_t NetworkPrefix::getNetworkPrefixLength() const
+{
+       return length_;
+}
+
+
+bool NetworkPrefix::operator<(const NetworkPrefix &right) const
+{
+       if (network_address_type_!=right.network_address_type_)
+               return false;
+       if (right.length_!=length_)
+               return (length_<right.length_);
+       return static_cast<NetworkAddress>(*this)<static_cast<NetworkAddress>(right);
+}
+
diff --git a/src/networkPrefix.h b/src/networkPrefix.h
new file mode 100644 (file)
index 0000000..5a0a69a
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _NETWORK_PREFIX_H
+#define _NETWORK_PREFIX_H
+
+#include "threadUtils.hpp"
+#include "datatypes.h"
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/archive/text_iarchive.hpp>
+
+#include "networkAddress.h"
+
+class NetworkPrefix : public NetworkAddress
+{
+public:
+       NetworkPrefix();
+       NetworkPrefix(const NetworkAddress &, u_int8_t length);
+       NetworkPrefix(const NetworkPrefix &);
+       void setNetworkPrefixLength(u_int8_t length );
+       u_int8_t getNetworkPrefixLength() const;
+  bool operator<(const NetworkPrefix &s) const;
+
+private:
+       operator NetworkAddress();
+  void operator=(const NetworkPrefix &s);
+       u_int8_t length_;
+  friend class boost::serialization::access;
+  template<class Archive>
+  void serialize(Archive & ar, const unsigned int version)
+  {
+    ar & length_;
+               ar & boost::serialization::base_object<NetworkAddress>(*this);
+  };
+
+};
+
+#endif
diff --git a/src/options.cpp b/src/options.cpp
new file mode 100644 (file)
index 0000000..b77ab41
--- /dev/null
@@ -0,0 +1,1098 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <cstring>
+#include <iostream>
+#include <queue>
+#include <string>
+#include <sstream>
+
+#include "datatypes.h"
+#include "options.h"
+#include "log.h"
+#include "authAlgoFactory.h"
+
+std::ostream& operator<<(std::ostream& stream, syntax_error const& error)
+{
+  stream << "syntax error: " << error.what() << std::endl;
+  if(error.pos >= 0) {
+    stream << "              ";
+    for(int32_t i = 0; i < error.pos; ++i) stream << " ";
+    return stream << "^";
+  }
+  return stream;
+}
+
+std::ostream& operator<<(std::ostream& stream, role_t const& role)
+{
+  switch(role) {
+  case ROLE_LEFT: stream << "left"; break;
+  case ROLE_RIGHT:  stream << "right"; break;
+  default: stream << "unknown"; break;
+  }  
+  return stream;
+}
+
+void OptionHost::init(std::string addrPort)
+{
+  std::string origAddrPort(addrPort);
+  size_t pos = addrPort.find_first_of("[");
+
+  if(pos != std::string::npos && pos != 0)
+    throw syntax_error(origAddrPort, pos); // an [ was found but not at the beginning;
+
+  bool hasPort = false;
+  if(pos != std::string::npos) {
+    addrPort.erase(pos, 1);
+    pos = addrPort.find_first_of("]");
+
+    if(pos == std::string::npos)
+      throw syntax_error(origAddrPort, origAddrPort.length()); //no trailing ] although an leading [ was found
+
+    if(pos < addrPort.length()-2) {
+      if(addrPort[pos+1] != ':')
+        throw syntax_error(origAddrPort, pos+2); // wrong port delimieter
+
+      addrPort[pos+1] = '/';
+      hasPort = true;
+    }
+    else if(pos != addrPort.length()-1)
+      throw syntax_error(origAddrPort, pos+2); // too few characters left
+
+    addrPort.erase(pos, 1);
+  }
+  else {
+    pos = addrPort.find_first_of(":");
+    if(pos != std::string::npos && pos == addrPort.find_last_of(":")) {
+      // an ':' has been found and it is the only one -> assuming port present
+      hasPort = true;
+      addrPort[pos] = '/';
+    }
+  }
+
+  if(hasPort) {
+    std::stringstream tmp_stream(addrPort);
+
+    getline(tmp_stream, addr, '/');
+    if(!tmp_stream.good())
+      throw syntax_error(origAddrPort, addr.length());
+
+    tmp_stream >> port;
+  }
+  else {
+    addr = addrPort;
+    port = "2323"; // default sync port
+  }
+}
+
+std::istream& operator>>(std::istream& stream, OptionHost& host)
+{
+  std::string tmp;
+  stream >> tmp;
+  host.init(tmp);
+  return stream;
+}
+
+void OptionNetwork::init(std::string network) 
+{
+  std::stringstream tmp_stream(network);
+  getline(tmp_stream, net_addr, '/');
+  if(!tmp_stream.good())
+    throw syntax_error(network, net_addr.length());
+  tmp_stream >> prefix_length;
+}
+
+std::istream& operator>>(std::istream& stream, OptionNetwork& network)
+{
+  std::string tmp;
+  stream >> tmp;
+  network.init(tmp);
+  return stream;
+}
+
+Options* Options::inst = NULL;
+Mutex Options::instMutex;
+Options& gOpt = Options::instance();
+
+Options& Options::instance()
+{
+  Lock lock(instMutex);
+  static instanceCleaner c;
+  if(!inst)
+    inst = new Options();
+  
+  return *inst;
+}
+
+Options::Options() : key_(u_int32_t(0)), salt_(u_int32_t(0))
+{
+#if defined(ANYCTR_OPTIONS)
+  progname_ = "anytun-controld";
+#elif defined(ANYCONF_OPTIONS)
+  progname_ = "anytun-config";
+#else
+  progname_ = "anytun";
+#endif
+
+  cluster_opts = false;
+  connection_opts = false;
+
+  daemonize_ = true;
+  username_ = "";
+  groupname_ = "";
+  chroot_dir_ = "";
+  pid_file_ = "";
+
+  file_name_ = "";
+  bind_to_.addr = "127.0.0.1";
+  bind_to_.port = "2323";
+
+  resolv_addr_type_ = ANY;
+
+  local_.addr = "";
+  local_.port = "4444";
+  remote_.addr = "";
+  remote_.port = "4444";
+  local_sync_.addr = "";
+  local_sync_.port = "";
+
+  dev_name_ = "";
+  dev_type_ = "";
+  post_up_script_ = "";
+
+  sender_id_ = 0;
+  mux_ = 0;
+  seq_window_size_ = 0;
+
+#if !defined(ANYCONF_OPTIONS)
+#ifndef NO_CRYPT
+  cipher_ = "aes-ctr";
+  auth_algo_ = "sha1";
+  auth_tag_length_ = 10;
+  kd_prf_ = "aes-ctr";
+#else
+  cipher_ = "null";
+  auth_algo_ = "null";
+  auth_tag_length_ = 0;
+  kd_prf_ = "null";
+#endif
+#else
+  cipher_ = "null";
+  auth_algo_ = "null";
+  auth_tag_length_ = 0;
+  kd_prf_ = "aes-ctr";
+#endif
+  role_ = ROLE_LEFT;
+}
+
+Options::~Options()
+{
+}
+
+#define NOTHING
+
+#define PARSE_BOOL_PARAM(SHORT, LONG, VALUE, DO_POST)                           \
+    else if(str == SHORT || str == LONG) {                                      \
+      VALUE = true;                                                             \
+      DO_POST;                                                                  \
+    }
+
+#define PARSE_INVERSE_BOOL_PARAM(SHORT, LONG, VALUE, DO_POST)                   \
+    else if(str == SHORT || str == LONG) {                                      \
+      VALUE = false;                                                            \
+      DO_POST;                                                                  \
+    }
+
+#define PARSE_SIGNED_INT_PARAM(SHORT, LONG, VALUE, DO_POST)                     \
+    else if(str == SHORT || str == LONG)                                        \
+    {                                                                           \
+      if(argc < 1)                                                              \
+        throw syntax_error(str, str.length());                                  \
+      std::stringstream tmp;                                                    \
+      tmp << argv[i+1];                                                         \
+      tmp >> VALUE;                                                             \
+      argc--;                                                                   \
+      i++;                                                                      \
+      DO_POST;                                                                  \
+    }
+
+#define PARSE_SCALAR_PARAM(SHORT, LONG, VALUE, DO_POST)                         \
+    else if(str == SHORT || str == LONG)                                        \
+    {                                                                           \
+      if(argc < 1)                                                              \
+        throw syntax_error(str, str.length());                                  \
+      if(argv[i+1][0] == '-') {                                                 \
+        u_int32_t pos = str.length() + 1;                                       \
+        throw syntax_error(str.append(" ").append(argv[i+1]), pos);             \
+      }                                                                         \
+      std::stringstream tmp;                                                    \
+      tmp << argv[i+1];                                                         \
+      tmp >> VALUE;                                                             \
+      argc--;                                                                   \
+      i++;                                                                      \
+      DO_POST;                                                                  \
+    }
+
+#define PARSE_SCALAR_PARAM2(SHORT, LONG, VALUE1, VALUE2, DO_POST)               \
+    else if(str == SHORT || str == LONG)                                        \
+    {                                                                           \
+      if(argc < 1)                                                              \
+        throw syntax_error(str, str.length());                                  \
+      if(argc < 2)                                                              \
+        throw syntax_error(str.append(" ").append(argv[i+1]), str.length());    \
+      if(argv[i+1][0] == '-') {                                                 \
+        u_int32_t pos = str.length() + 1;                                       \
+        throw syntax_error(str.append(" ").append(argv[i+1]), pos);             \
+      }                                                                         \
+      if(argv[i+2][0] == '-') {                                                 \
+        u_int32_t pos = str.length() + 1 + strlen(argv[i+1]) + 1;               \
+        throw syntax_error(str.append(" ").append(argv[i+1]).append(" ").append(argv[i+2]), pos); \
+      }                                                                         \
+      std::stringstream tmp;                                                    \
+      tmp << argv[i+1] << " " << argv[i+2];                                     \
+      tmp >> VALUE1;                                                            \
+      tmp >> VALUE2;                                                            \
+      argc-=2;                                                                  \
+      i+=2;                                                                     \
+      DO_POST;                                                                  \
+    }
+
+#define PARSE_CSLIST_PARAM(SHORT, LONG, LIST, TYPE, DO_POST)                    \
+    else if(str == SHORT || str == LONG)                                        \
+    {                                                                           \
+      if(argc < 1)                                                              \
+        throw syntax_error(str, str.length());                                  \
+      if(argv[i+1][0] == '-') {                                                 \
+        u_int32_t pos = str.length() + 1;                                       \
+        throw syntax_error(str.append(" ").append(argv[i+1]), pos);             \
+      }                                                                         \
+      std::stringstream tmp(argv[i+1]);                                         \
+      while (tmp.good())                                                        \
+      {                                                                         \
+        std::string tmp_line;                                                   \
+        getline(tmp,tmp_line,',');                                              \
+        LIST.push_back(TYPE(tmp_line));                                         \
+      }                                                                         \
+      argc--;                                                                   \
+      i++;                                                                      \
+      DO_POST;                                                                  \
+    }
+
+#define PARSE_HEXSTRING_PARAM_SEC(SHORT, LONG, VALUE, DO_POST)                  \
+    else if(str == SHORT || str == LONG)                                        \
+    {                                                                           \
+      if(argc < 1)                                                              \
+        throw syntax_error(str, str.length());                                  \
+      if(argv[i+1][0] == '-') {                                                 \
+        u_int32_t pos = str.length() + 1;                                       \
+        throw syntax_error(str.append(" ").append(argv[i+1]), pos);             \
+      }                                                                         \
+      VALUE = Buffer(std::string(argv[i+1]));                                   \
+      for(size_t j=0; j < strlen(argv[i+1]); ++j)                               \
+        argv[i+1][j] = '#';                                                     \
+      argc--;                                                                   \
+      i++;                                                                      \
+      DO_POST;                                                                  \
+    }
+
+#define PARSE_PHRASE_PARAM_SEC(SHORT, LONG, VALUE, DO_POST)                     \
+    else if(str == SHORT || str == LONG)                                        \
+    {                                                                           \
+      if(argc < 1)                                                              \
+        throw syntax_error(str, str.length());                                  \
+      if(argv[i+1][0] == '-') {                                                 \
+        u_int32_t pos = str.length() + 1;                                       \
+        throw syntax_error(str.append(" ").append(argv[i+1]), pos);             \
+      }                                                                         \
+      VALUE = argv[i+1];                                                        \
+      for(size_t j=0; j < strlen(argv[i+1]); ++j)                               \
+        argv[i+1][j] = '#';                                                     \
+      argc--;                                                                   \
+      i++;                                                                      \
+      DO_POST;                                                                  \
+    }
+
+#define PARSE_STRING_LIST(SHORT, LONG, LIST, DO_POST)                           \
+    else if(str == SHORT || str == LONG)                                        \
+    {                                                                           \
+      if(argc < 1)                                                              \
+        throw syntax_error(str, str.length());                                  \
+      if(argv[i+1][0] == '-') {                                                 \
+        u_int32_t pos = str.length() + 1;                                       \
+        throw syntax_error(str.append(" ").append(argv[i+1]), pos);             \
+      }                                                                         \
+      LIST.push_back(argv[i+1]);                                                \
+      argc--;                                                                   \
+      i++;                                                                      \
+      DO_POST;                                                                  \
+    }
+
+bool Options::parse(int argc, char* argv[])
+{
+  WritersLock lock(mutex);
+
+  progname_ = argv[0];
+  argc--;
+  bool ipv4_only = false, ipv6_only = false;
+  std::string role = "";
+  for(int i=1; argc > 0; ++i)
+  {
+    std::string str(argv[i]);
+    argc--;
+
+    if(str == "-h" || str == "--help")
+      return false;
+
+#if defined(ANYTUN_OPTIONS) || defined(ANYCTR_OPTIONS)
+
+  #ifndef NO_DAEMON
+    PARSE_INVERSE_BOOL_PARAM("-D","--nodaemonize", daemonize_, NOTHING)
+    PARSE_SCALAR_PARAM("-u","--username", username_, NOTHING)
+    PARSE_SCALAR_PARAM("-g","--groupname", groupname_, NOTHING)
+    PARSE_SCALAR_PARAM("-C","--chroot", chroot_dir_, NOTHING)
+    PARSE_SCALAR_PARAM("-P","--write-pid", pid_file_, NOTHING)
+  #endif
+
+#endif
+
+    PARSE_STRING_LIST("-L","--log", log_targets_, NOTHING)
+
+#if defined(ANYCTR_OPTIONS)
+
+    PARSE_SCALAR_PARAM("-f","--file", file_name_, NOTHING)
+    PARSE_SCALAR_PARAM("-X","--control-host", bind_to_, NOTHING)
+
+#endif
+#if defined(ANYTUN_OPTIONS)
+
+    PARSE_SCALAR_PARAM("-i","--interface", local_.addr, NOTHING)
+    PARSE_SCALAR_PARAM("-p","--port", local_.port, NOTHING)
+    PARSE_SCALAR_PARAM("-s","--sender-id", sender_id_, NOTHING)
+
+#endif
+#if defined(ANYTUN_OPTIONS) || defined(ANYCONF_OPTIONS)
+
+    PARSE_SCALAR_PARAM("-r","--remote-host", remote_.addr, connection_opts = true)
+    PARSE_SCALAR_PARAM("-o","--remote-port", remote_.port, connection_opts = true)
+    PARSE_BOOL_PARAM("-4","--ipv4-only", ipv4_only, connection_opts = true)
+    PARSE_BOOL_PARAM("-6","--ipv6-only", ipv6_only, connection_opts = true)
+
+#endif
+#if defined(ANYTUN_OPTIONS)
+
+    PARSE_SCALAR_PARAM("-I","--sync-interface", local_sync_.addr, cluster_opts = true)
+    PARSE_SCALAR_PARAM("-S","--sync-port", local_sync_.port, cluster_opts = true)
+    PARSE_CSLIST_PARAM("-M","--sync-hosts", remote_sync_hosts_, OptionHost, cluster_opts = true)
+    PARSE_CSLIST_PARAM("-X","--control-host", remote_sync_hosts_, OptionHost, cluster_opts = true)
+
+    PARSE_SCALAR_PARAM("-d","--dev", dev_name_, NOTHING)
+    PARSE_SCALAR_PARAM("-t","--type", dev_type_, NOTHING)
+    PARSE_SCALAR_PARAM("-n","--ifconfig", ifconfig_param_, NOTHING)
+  #ifndef NO_EXEC
+    PARSE_SCALAR_PARAM("-x","--post-up-script", post_up_script_, NOTHING)
+  #endif
+
+#endif
+#if defined(ANYTUN_OPTIONS) || defined(ANYCONF_OPTIONS)
+
+  #ifndef NO_ROUTING
+    PARSE_CSLIST_PARAM("-R","--route", routes_, OptionNetwork, connection_opts = true)
+  #endif
+
+    PARSE_SCALAR_PARAM("-m","--mux", mux_, connection_opts = true)
+    PARSE_SCALAR_PARAM("-w","--window-size", seq_window_size_, connection_opts = true)
+
+  #ifndef NO_CRYPT
+    PARSE_SCALAR_PARAM("-k","--kd-prf", kd_prf_, connection_opts = true)
+    PARSE_SCALAR_PARAM("-e","--role", role, connection_opts = true)
+  #ifndef NO_PASSPHRASE
+    PARSE_PHRASE_PARAM_SEC("-E","--passphrase", passphrase_, connection_opts = true)
+  #endif
+    PARSE_HEXSTRING_PARAM_SEC("-K","--key", key_, connection_opts = true)
+    PARSE_HEXSTRING_PARAM_SEC("-A","--salt", salt_, connection_opts = true)
+  #endif
+
+#endif
+#if defined(ANYTUN_OPTIONS)
+
+  #ifndef NO_CRYPT
+    PARSE_SCALAR_PARAM("-c","--cipher", cipher_, NOTHING)
+    PARSE_SCALAR_PARAM("-a","--auth-algo", auth_algo_, NOTHING)
+    PARSE_SCALAR_PARAM("-b","--auth-tag-length", auth_tag_length_, NOTHING)
+  #endif
+
+#endif
+    else 
+      throw syntax_error(str, 0);
+  }
+  if(ipv4_only && ipv6_only)
+    throw syntax_error("-4 and -6 are mutual exclusive", -1);
+  if(ipv4_only)
+    resolv_addr_type_ = IPV4_ONLY;
+  if(ipv6_only)
+    resolv_addr_type_ = IPV6_ONLY;
+
+  if(role != "") {
+    if(role == "alice" || role == "server" || role == "left")
+      role_ = ROLE_LEFT;
+    else if(role == "bob" || role == "client" || role == "right")
+      role_ = ROLE_RIGHT;
+    else
+      throw syntax_error("unknown role name: " + role, -1); 
+  }
+
+  return true;
+}
+
+void Options::parse_post()
+{
+#if defined(ANYTUN_OPTIONS)
+  if(cluster_opts && connection_opts)
+    cLog.msg(Log::PRIO_WARNING) << "you have provided options for cluster support as well as connection oriented options, we strongly recommend to use anytun-config and anytun-controld when building a cluster";
+
+  if(cipher_ == "null" && auth_algo_ == "null")
+    kd_prf_ = "null";
+  if((cipher_ != "null" || auth_algo_ != "null") && kd_prf_ == "null")
+    cLog.msg(Log::PRIO_WARNING) << "using NULL key derivation with encryption and or authentication enabled!";
+
+  u_int32_t tag_len_max = AuthAlgoFactory::getDigestLength(auth_algo_);
+  if(!tag_len_max) auth_tag_length_ = 0;
+  else if(tag_len_max < auth_tag_length_) {
+    cLog.msg(Log::PRIO_WARNING) << auth_algo_ << " auth algo can't generate tags of length " << auth_tag_length_ << ", using maximum tag length(" << tag_len_max << ")";
+    auth_tag_length_ = tag_len_max;
+  }
+#endif
+
+  if(dev_name_ == "" && dev_type_ == "")
+    dev_type_ = "tun";
+}
+
+void Options::printUsage()
+{
+  std::cout << "USAGE:" << std::endl;
+
+#if defined(ANYCTR_OPTIONS)
+  std::cout << "anytun-controld " << std::endl;
+#elif defined(ANYCONF_OPTIONS)
+  std::cout << "anytun-config " << std::endl;
+#else
+  std::cout << "anytun " << std::endl;
+#endif
+
+  std::cout << "   [-h|--help]                         prints this..." << std::endl;
+
+#if defined(ANYTUN_OPTIONS) || defined(ANYCTR_OPTIONS)
+
+ #ifndef NO_DAEMON
+  std::cout << "   [-D|--nodaemonize]                  don't run in background" << std::endl;
+  std::cout << "   [-u|--username] <username>          change to this user" << std::endl;
+  std::cout << "   [-g|--groupname] <groupname>        change to this group" << std::endl;
+  std::cout << "   [-C|--chroot] <path>                chroot to this directory" << std::endl;
+  std::cout << "   [-P|--write-pid] <path>             write pid to this file" << std::endl;
+ #endif
+
+#endif
+
+  std::cout << "   [-L|--log] <target>:<level>[,<param1>[,<param2>..]]" << std::endl;
+  std::cout << "                                       add a log target, can be invoked several times" << std::endl;
+
+#if defined(ANYCTR_OPTIONS)
+
+  std::cout << "   [-f|--file] <path>                  path to input file" << std::endl;
+  std::cout << "   [-X|--control-host] < <hostname|ip>[:<port>] | :<port> >" << std::endl;
+  std::cout << "                                       local tcp port and or ip address to bind to" << std::endl;
+
+#endif
+#if defined(ANYTUN_OPTIONS)
+
+  std::cout << "   [-i|--interface] <hostname|ip>      local anycast ip address to bind to" << std::endl;
+  std::cout << "   [-p|--port] <port>                  local anycast(data) port to bind to" << std::endl;
+  std::cout << "   [-s|--sender-id ] <sender id>       the sender id to use" << std::endl;
+
+#endif
+#if defined(ANYTUN_OPTIONS) || defined(ANYCONF_OPTIONS)
+
+  std::cout << "   [-r|--remote-host] <hostname|ip>    remote host" << std::endl;
+  std::cout << "   [-o|--remote-port] <port>           remote port" << std::endl;
+  std::cout << "   [-4|--ipv4-only]                    always resolv IPv4 addresses" << std::endl;
+  std::cout << "   [-6|--ipv6-only]                    always resolv IPv6 addresses" << std::endl;
+
+#endif
+#if defined(ANYTUN_OPTIONS)
+
+  std::cout << "   [-I|--sync-interface] <ip-address>  local unicast(sync) ip address to bind to" << std::endl;
+  std::cout << "   [-S|--sync-port] <port>             local unicast(sync) port to bind to" << std::endl;
+  std::cout << "   [-M|--sync-hosts] <hostname|ip>[:<port>][,<hostname|ip>[:<port>][...]]"<< std::endl;
+  std::cout << "                                       remote hosts to sync with" << std::endl;
+  std::cout << "   [-X|--control-host] <hostname|ip>[:<port>]"<< std::endl;
+  std::cout << "                                       fetch the config from this host" << std::endl;
+
+  std::cout << "   [-d|--dev] <name>                   device name" << std::endl;
+  std::cout << "   [-t|--type] <tun|tap>               device type" << std::endl;
+  std::cout << "   [-n|--ifconfig] <local>/<prefix>    the local address for the tun/tap device and the used prefix length" << std::endl;
+ #ifndef NO_EXEC
+  std::cout << "   [-x|--post-up-script] <script>      script gets called after interface is created" << std::endl;
+ #endif
+
+#endif
+#if defined(ANYTUN_OPTIONS) || defined(ANYCONF_OPTIONS)
+
+ #ifndef NO_ROUTING
+  std::cout << "   [-R|--route] <net>/<prefix length>  add a route to connection, can be invoked several times" << std::endl;
+ #endif
+
+  std::cout << "   [-m|--mux] <mux-id>                 the multiplex id to use" << std::endl;
+  std::cout << "   [-w|--window-size] <window size>    seqence number window size" << std::endl;
+
+ #ifndef NO_CRYPT
+  std::cout << "   [-k|--kd-prf] <kd-prf type>         key derivation pseudo random function" << std::endl;
+  std::cout << "   [-e|--role] <role>                  left (alice) or right (bob)" << std::endl;
+ #ifndef NO_PASSPHRASE
+  std::cout << "   [-E|--passphrase] <pass phrase>     a passprhase to generate master key and salt from" << std::endl;
+ #endif
+  std::cout << "   [-K|--key] <master key>             master key to use for encryption" << std::endl;
+  std::cout << "   [-A|--salt] <master salt>           master salt to use for encryption" << std::endl;
+ #endif
+
+#endif
+#if defined(ANYTUN_OPTIONS)
+
+ #ifndef NO_CRYPT
+  std::cout << "   [-c|--cipher] <cipher type>         payload encryption algorithm" << std::endl;
+  std::cout << "   [-a|--auth-algo] <algo type>        message authentication algorithm" << std::endl;
+  std::cout << "   [-b|--auth-tag-length]              length of the auth tag" << std::endl;
+ #endif
+
+#endif
+}
+
+void Options::printOptions()
+{
+  ReadersLock lock(mutex);
+
+  std::cout << "Options:" << std::endl;
+  std::cout << std::endl;
+  std::cout << "daemonize = " << daemonize_ << std::endl;
+  std::cout << "username = '" << username_ << "'" << std::endl;
+  std::cout << "groupname = '" << groupname_ << "'" << std::endl;
+  std::cout << "chroot_dir = '" << chroot_dir_ << "'" << std::endl;
+  std::cout << "pid_file = '" << pid_file_ << "'" << std::endl;
+  std::cout << std::endl;
+  std::cout << "log_targets:";
+  StringList::const_iterator lit = log_targets_.begin();
+  for(; lit != log_targets_.end(); ++lit)
+    std::cout << " '" << *lit << "',";
+  std::cout << std::endl << std::endl;
+  std::cout << "file_name = '" << file_name_ << "'" << std::endl;
+  std::cout << "bind_to.addr = '" << bind_to_.addr << "'" << std::endl;
+  std::cout << "bind_to.port = '" << bind_to_.port << "'" << std::endl;
+  std::cout << std::endl;
+  std::cout << "resolv_addr_type = ";
+  switch(resolv_addr_type_) {
+  case ANY: std::cout <<  "any" << std::endl; break;
+  case IPV4_ONLY: std::cout <<  "ipv4-only" << std::endl; break;
+  case IPV6_ONLY: std::cout <<  "ipv6-only" << std::endl; break;
+  default: std::cout <<  "?" << std::endl; break;
+  }
+  std::cout << std::endl;
+  std::cout << "local.addr = '" << local_.addr << "'" << std::endl;
+  std::cout << "local.port = '" << local_.port << "'" << std::endl;
+  std::cout << "remote.addr = '" << remote_.addr << "'" << std::endl;
+  std::cout << "remote.port = '" << remote_.port << "'" << std::endl;
+  std::cout << "local_sync.addr = '" << local_sync_.addr << "'" << std::endl;
+  std::cout << "local_sync.port = '" << local_sync_.port << "'" << std::endl;
+  std::cout << "remote_sync_hosts:" << std::endl;
+  HostList::const_iterator hit = remote_sync_hosts_.begin();
+  for(; hit != remote_sync_hosts_.end(); ++hit)
+    std::cout << "  '" << hit->addr << "','" << hit->port << "'" << std::endl;
+  std::cout << std::endl;
+  std::cout << "dev_name = '" << dev_name_ << "'" << std::endl;
+  std::cout << "dev_type = '" << dev_type_ << "'" << std::endl;
+  std::cout << "ifconfig_param_local = '" << ifconfig_param_.net_addr << "/" << ifconfig_param_.prefix_length << "'" << std::endl;
+  std::cout << "post_up_script = '" << post_up_script_ << "'" << std::endl;
+  std::cout << "routes:" << std::endl;
+  NetworkList::const_iterator rit;
+  for(rit = routes_.begin(); rit != routes_.end(); ++rit)
+    std::cout << "  " << rit->net_addr << "/" << rit->prefix_length << std::endl;
+  std::cout << std::endl;
+  std::cout << "sender_id = '" << sender_id_ << "'" << std::endl;
+  std::cout << "mux_id = " << mux_ << std::endl;
+  std::cout << "seq_window_size = '" << seq_window_size_ << "'" << std::endl;
+  std::cout << std::endl;
+  std::cout << "cipher = '" << cipher_ << "'" << std::endl;
+  std::cout << "auth_algo = '" << auth_algo_ << "'" << std::endl;
+  std::cout << "auth_tag_length = " << auth_tag_length_ << std::endl;
+  std::cout << "kd_prf = '" << kd_prf_ << "'" << std::endl;
+  std::cout << "role = ";
+  switch(role_) {
+  case ROLE_LEFT: std::cout << "left" << std::endl; break;
+  case ROLE_RIGHT: std::cout << "right" << std::endl; break;
+  default: std::cout << "??" << std::endl; break;
+  }
+  std::cout << "passphrase = '" << passphrase_ << "'" << std::endl;
+  std::cout << "key = " << key_.getHexDumpOneLine() << std::endl;
+  std::cout << "salt = " << salt_.getHexDumpOneLine() << std::endl;
+}
+
+
+
+std::string Options::getProgname()
+{
+  ReadersLock lock(mutex);
+  return progname_;
+}
+
+Options& Options::setProgname(std::string p)
+{
+  WritersLock lock(mutex);
+  progname_ = p;
+  return *this;
+}
+
+bool Options::getDaemonize()
+{
+  ReadersLock lock(mutex);
+  return daemonize_;
+}
+
+Options& Options::setDaemonize(bool d)
+{
+  WritersLock lock(mutex);
+  daemonize_ = d;
+  return *this;
+}
+
+std::string Options::getUsername()
+{
+  ReadersLock lock(mutex);
+  return username_;
+}
+
+Options& Options::setUsername(std::string u)
+{
+  WritersLock lock(mutex);
+  username_ = u;
+  return *this;
+}
+
+std::string Options::getGroupname()
+{
+  ReadersLock lock(mutex);
+  return groupname_;
+}
+
+Options& Options::setGroupname(std::string g)
+{
+  WritersLock lock(mutex);
+  groupname_ = g;
+  return *this;
+}
+
+std::string Options::getChrootDir()
+{
+  ReadersLock lock(mutex);
+  return chroot_dir_;
+}
+
+Options& Options::setChrootDir(std::string c)
+{
+  WritersLock lock(mutex);
+  chroot_dir_ = c;
+  return *this;
+}
+
+std::string Options::getPidFile()
+{
+  ReadersLock lock(mutex);
+  return pid_file_;
+}
+
+Options& Options::setPidFile(std::string p)
+{
+  WritersLock lock(mutex);
+  pid_file_ = p;
+  return *this;
+}
+
+
+
+StringList Options::getLogTargets()
+{
+  ReadersLock lock(mutex);
+  return log_targets_;
+}
+
+
+
+std::string Options::getFileName()
+{
+  ReadersLock lock(mutex);
+  return file_name_;
+}
+
+Options& Options::setFileName(std::string f)
+{
+  WritersLock lock(mutex);
+  file_name_ = f;
+  return *this;
+}
+
+std::string Options::getBindToAddr()
+{
+  ReadersLock lock(mutex);
+  return bind_to_.addr;
+}
+
+Options& Options::setBindToAddr(std::string b)
+{
+  WritersLock lock(mutex);
+  bind_to_.addr = b;
+  return *this;
+}
+
+std::string Options::getBindToPort()
+{
+  ReadersLock lock(mutex);
+  return bind_to_.port;  
+}
+
+Options& Options::setBindToPort(std::string b)
+{
+  WritersLock lock(mutex);
+  bind_to_.port = b;
+  return *this;
+}
+
+
+ResolvAddrType Options::getResolvAddrType()
+{
+  ReadersLock lock(mutex);
+  return resolv_addr_type_;
+}
+
+Options& Options::setResolvAddrType(ResolvAddrType r)
+{
+  WritersLock lock(mutex);
+  resolv_addr_type_ = r;
+  return *this;
+}
+
+std::string Options::getLocalAddr()
+{
+  ReadersLock lock(mutex);
+  return local_.addr;
+}
+
+Options& Options::setLocalAddr(std::string l)
+{
+  WritersLock lock(mutex);
+  local_.addr = l;
+  return *this;
+}
+
+std::string Options::getLocalPort()
+{
+  ReadersLock lock(mutex);
+  return local_.port;
+}
+
+Options& Options::setLocalPort(std::string l)
+{
+  WritersLock lock(mutex);
+  local_.port = l;
+  return *this;
+}
+
+std::string Options::getRemoteAddr()
+{
+  ReadersLock lock(mutex);
+  return remote_.addr;
+}
+
+Options& Options::setRemoteAddr(std::string r)
+{
+  WritersLock lock(mutex);
+  remote_.addr = r;
+  return *this;
+}
+
+std::string Options::getRemotePort()
+{
+  ReadersLock lock(mutex);
+  return remote_.port;
+}
+
+Options& Options::setRemotePort(std::string r)
+{
+  WritersLock lock(mutex);
+  remote_.port = r;
+  return *this;
+}
+
+std::string Options::getLocalSyncAddr()
+{
+  ReadersLock lock(mutex);
+  return local_sync_.addr;
+}
+
+Options& Options::setLocalSyncAddr(std::string l)
+{
+  WritersLock lock(mutex);
+  local_sync_.addr = l;
+  return *this;
+}
+
+std::string Options::getLocalSyncPort()
+{
+  ReadersLock lock(mutex);
+  return local_sync_.port;
+}
+
+Options& Options::setLocalSyncPort(std::string l)
+{
+  WritersLock lock(mutex);
+  local_sync_.port = l;
+  return *this;
+}
+
+HostList Options::getRemoteSyncHosts()
+{
+  ReadersLock lock(mutex);
+  return remote_sync_hosts_;
+}
+
+
+
+std::string Options::getDevName()
+{
+  ReadersLock lock(mutex);
+  return dev_name_;
+}
+
+Options& Options::setDevName(std::string d)
+{
+  WritersLock lock(mutex);
+  dev_name_ = d;
+  return *this;
+}
+
+std::string Options::getDevType()
+{
+  ReadersLock lock(mutex);
+  return dev_type_;
+}
+
+Options& Options::setDevType(std::string d)
+{
+  WritersLock lock(mutex);
+  dev_type_ = d;
+  return *this;
+}
+
+OptionNetwork Options::getIfconfigParam()
+{
+  ReadersLock lock(mutex);
+  return ifconfig_param_;
+}
+
+Options& Options::setIfconfigParam(OptionNetwork i)
+{
+  WritersLock lock(mutex);
+  ifconfig_param_ = i;
+  return *this;
+}
+
+std::string Options::getPostUpScript()
+{
+  ReadersLock lock(mutex);
+  return post_up_script_;
+}
+
+Options& Options::setPostUpScript(std::string p)
+{
+  WritersLock lock(mutex);
+  post_up_script_ = p;
+  return *this;
+}
+
+NetworkList Options::getRoutes()
+{
+  ReadersLock lock(mutex);
+  return routes_;
+}
+
+
+
+sender_id_t Options::getSenderId()
+{
+  ReadersLock lock(mutex);
+  return sender_id_;
+}
+
+Options& Options::setSenderId(sender_id_t s)
+{
+  WritersLock lock(mutex);
+  sender_id_ = s;
+  return *this;
+}
+
+mux_t Options::getMux()
+{
+  ReadersLock lock(mutex);
+  return mux_;
+}
+
+Options& Options::setMux(mux_t m)
+{
+  WritersLock lock(mutex);
+  mux_ = m;
+  return *this;
+}
+
+window_size_t Options::getSeqWindowSize()
+{
+  ReadersLock lock(mutex);
+  return seq_window_size_;
+}
+
+Options& Options::setSeqWindowSize(window_size_t s)
+{
+  WritersLock lock(mutex);
+  seq_window_size_ = s;
+  return *this;
+}
+
+
+
+std::string Options::getCipher()
+{
+  ReadersLock lock(mutex);
+  return cipher_;
+}
+
+Options& Options::setCipher(std::string c)
+{
+  WritersLock lock(mutex);
+  cipher_ = c;
+  return *this;
+}
+
+std::string Options::getAuthAlgo()
+{
+  ReadersLock lock(mutex);
+  return auth_algo_;
+}
+
+Options& Options::setAuthAlgo(std::string a)
+{
+  WritersLock lock(mutex);
+  auth_algo_ = a;
+  return *this;
+}
+
+u_int32_t Options::getAuthTagLength()
+{
+  ReadersLock lock(mutex);
+  return auth_tag_length_;
+}
+
+Options& Options::setAuthTagLength(u_int32_t a)
+{
+  WritersLock lock(mutex);
+  auth_tag_length_ = a;
+  return *this;
+}
+
+
+std::string Options::getKdPrf()
+{
+  ReadersLock lock(mutex);
+  return kd_prf_;
+}
+
+Options& Options::setKdPrf(std::string k)
+{
+  WritersLock lock(mutex);
+  kd_prf_ = k;
+  return *this;
+}
+
+role_t Options::getRole()
+{
+  ReadersLock lock(mutex);
+  return role_;
+}
+
+Options& Options::setRole(role_t r)
+{
+  WritersLock lock(mutex);
+  role_ = r;
+  return *this;
+}
+
+std::string Options::getPassphrase()
+{
+  ReadersLock lock(mutex);
+  return passphrase_;
+}
+
+Options& Options::setPassphrase(std::string p)
+{
+  WritersLock lock(mutex);
+  passphrase_ = p;
+  return *this;
+}
+
+Buffer Options::getKey()
+{
+  ReadersLock lock(mutex);
+  return key_;
+}
+
+Options& Options::setKey(std::string k)
+{
+  WritersLock lock(mutex);
+  key_ = k;
+  return *this;
+}
+
+Buffer Options::getSalt()
+{
+  ReadersLock lock(mutex);
+  return salt_;
+}
+
+Options& Options::setSalt(std::string s)
+{
+  WritersLock lock(mutex);
+  salt_ = s;
+  return *this;
+}
diff --git a/src/options.h b/src/options.h
new file mode 100644 (file)
index 0000000..9beda0c
--- /dev/null
@@ -0,0 +1,230 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _OPTIONS_H_
+#define _OPTIONS_H_
+
+#include "datatypes.h"
+#include "buffer.h"
+#include "threadUtils.hpp"
+#include <list>
+
+class syntax_error : public std::runtime_error
+{
+public:
+  syntax_error(std::string t, int32_t p) : runtime_error(t), pos(p) {};
+  int32_t pos;
+};
+std::ostream& operator<<(std::ostream& stream, syntax_error const& error);
+
+class OptionHost
+{
+public:
+  OptionHost() : addr(""), port("") {};
+  OptionHost(std::string addrPort) { init(addrPort); };
+  OptionHost(std::string a, std::string p) : addr(a), port(p) {};
+
+  void init(std::string addrPort);
+
+  std::string addr;
+       std::string port;
+};
+typedef std::list<OptionHost> HostList;
+std::istream& operator>>(std::istream& stream, OptionHost& host);
+
+class OptionNetwork
+{
+public:
+  OptionNetwork() : net_addr(""), prefix_length(0) {};
+  OptionNetwork(std::string network) { init(network); };
+  OptionNetwork(std::string n, u_int16_t p) : net_addr(n), prefix_length(p) {};
+
+  void init(std::string network);
+
+  std::string net_addr;
+  u_int16_t prefix_length;
+};
+typedef std::list<OptionNetwork> NetworkList;
+std::istream& operator>>(std::istream& stream, OptionNetwork& network);
+
+typedef std::list<std::string> StringList;
+
+typedef enum { ROLE_LEFT, ROLE_RIGHT } role_t;
+std::ostream& operator<<(std::ostream& stream, role_t const& role);
+
+class Options
+{
+public:
+  static Options& instance();
+
+  bool parse(int argc, char* argv[]);
+  void parse_post();
+  void printUsage();
+  void printOptions();
+
+  std::string getProgname();
+  Options& setProgname(std::string p);
+  bool getDaemonize();
+  Options& setDaemonize(bool d);
+  std::string getUsername();
+  Options& setUsername(std::string u);
+  std::string getGroupname();
+  Options& setGroupname(std::string g);
+  std::string getChrootDir();
+  Options& setChrootDir(std::string c);
+  std::string getPidFile();
+  Options& setPidFile(std::string p);
+
+  StringList getLogTargets();
+
+  std::string getFileName();
+  Options& setFileName(std::string f);
+  std::string getBindToAddr();
+  Options& setBindToAddr(std::string b);
+  std::string getBindToPort();
+  Options& setBindToPort(std::string b);
+
+  ResolvAddrType getResolvAddrType();
+  Options& setResolvAddrType(ResolvAddrType r);
+  std::string getLocalAddr();
+  Options& setLocalAddr(std::string l);
+  std::string getLocalPort();
+  Options& setLocalPort(std::string l);
+  std::string getRemoteAddr();
+  Options& setRemoteAddr(std::string r);
+  std::string getRemotePort();
+  Options& setRemotePort(std::string r);
+
+  std::string getLocalSyncAddr();
+  Options& setLocalSyncAddr(std::string l);
+  std::string getLocalSyncPort();
+  Options& setLocalSyncPort(std::string l);
+       HostList getRemoteSyncHosts();
+
+  std::string getDevName();
+  Options& setDevName(std::string d);
+  std::string getDevType();
+  Options& setDevType(std::string d);
+  OptionNetwork getIfconfigParam();
+  Options& setIfconfigParam(OptionNetwork i);
+  std::string getPostUpScript();
+  Options& setPostUpScript(std::string p);
+  NetworkList getRoutes();
+
+  sender_id_t getSenderId();
+  Options& setSenderId(sender_id_t s);
+  mux_t getMux();
+  Options& setMux(mux_t m);
+  window_size_t getSeqWindowSize();
+  Options& setSeqWindowSize(window_size_t s);
+
+  std::string getCipher();
+  Options& setCipher(std::string c);
+  std::string getAuthAlgo();
+  Options& setAuthAlgo(std::string a);
+  u_int32_t getAuthTagLength();
+  Options& setAuthTagLength(u_int32_t a);
+  std::string getKdPrf();
+  Options& setKdPrf(std::string k);
+  role_t getRole();
+  Options& setRole(role_t r);
+  std::string getPassphrase();
+  Options& setPassphrase(std::string p);
+  Options& setKey(std::string k);
+  Buffer getKey();
+  Options& setSalt(std::string s);
+  Buffer getSalt();
+
+
+private:
+  Options();
+  ~Options();
+  Options(const Options &l);
+  void operator=(const Options &l);
+
+  static Options* inst;
+  static ::Mutex instMutex;
+  class instanceCleaner {
+    public: ~instanceCleaner() {
+      if(Options::inst != 0)
+        delete Options::inst;
+    }
+  };
+  friend class instanceCleaner;
+
+  ::SharedMutex mutex;
+
+
+  bool cluster_opts;
+  bool connection_opts;
+
+  std::string progname_;
+  bool daemonize_;
+  std::string username_;
+  std::string groupname_;
+  std::string chroot_dir_;
+  std::string pid_file_;
+
+  StringList log_targets_;
+
+  std::string file_name_;
+  OptionHost bind_to_;
+
+  ResolvAddrType resolv_addr_type_;
+  OptionHost local_;
+  OptionHost remote_;
+
+  OptionHost local_sync_;
+       HostList remote_sync_hosts_;
+
+  std::string dev_name_;
+  std::string dev_type_;
+  OptionNetwork ifconfig_param_;
+  std::string post_up_script_;
+  NetworkList routes_;
+
+  sender_id_t sender_id_;
+  mux_t mux_;
+  window_size_t seq_window_size_;
+
+  std::string cipher_;
+  std::string auth_algo_;
+  u_int32_t auth_tag_length_;
+  std::string kd_prf_;
+  role_t role_;
+  std::string passphrase_;
+  Buffer key_;
+  Buffer salt_;
+};
+
+extern Options& gOpt;
+
+#endif
diff --git a/src/packetSource.cpp b/src/packetSource.cpp
new file mode 100644 (file)
index 0000000..9266b57
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <boost/asio.hpp>
+#include <boost/bind.hpp>
+
+#include "datatypes.h"
+#include "packetSource.h"
+#include "log.h"
+#include "resolver.h"
+#include "options.h"
+#include "signalController.h"
+
+void PacketSource::waitUntilReady()
+{
+  ready_sem_.down();
+}
+
+UDPPacketSource::UDPPacketSource(std::string localaddr, std::string port) : sock_(io_service_)
+{
+  gResolver.resolveUdp(localaddr, port, boost::bind(&UDPPacketSource::onResolve, this, _1), boost::bind(&UDPPacketSource::onError, this, _1), gOpt.getResolvAddrType());
+}
+
+void UDPPacketSource::onResolve(const boost::asio::ip::udp::endpoint& e)
+{
+  cLog.msg(Log::PRIO_NOTICE) << "opening socket: " << e;
+  sock_.open(e.protocol());
+  sock_.bind(e);
+  ready_sem_.up();
+}
+
+void UDPPacketSource::onError(const std::runtime_error& e)
+{
+  gSignalController.inject(SIGERROR, e.what());
+}
+
+u_int32_t UDPPacketSource::recv(u_int8_t* buf, u_int32_t len, PacketSourceEndpoint& remote)
+{
+  return static_cast<u_int32_t>(sock_.receive_from(boost::asio::buffer(buf, len), remote));
+}
+
+void UDPPacketSource::send(u_int8_t* buf, u_int32_t len, PacketSourceEndpoint remote)
+{
+  sock_.send_to(boost::asio::buffer(buf, len), remote);
+}
+
diff --git a/src/packetSource.h b/src/packetSource.h
new file mode 100644 (file)
index 0000000..1957eb8
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _PACKET_SOURCE_H_
+#define _PACKET_SOURCE_H_
+
+#include <boost/asio.hpp>
+
+#include "datatypes.h"
+#include "threadUtils.hpp"
+
+// TODO: fix this when other packetSource types are introduced
+typedef boost::asio::ip::udp::endpoint PacketSourceEndpoint;
+
+class PacketSource
+{
+public:
+  virtual ~PacketSource() {}
+
+  virtual u_int32_t recv(u_int8_t* buf, u_int32_t len, PacketSourceEndpoint& remote) = 0;
+  virtual void send(u_int8_t* buf, u_int32_t len, PacketSourceEndpoint remote) = 0;
+
+  void waitUntilReady();
+
+protected:
+  Semaphore ready_sem_;
+};
+
+class UDPPacketSource : public PacketSource
+{  
+public:
+  typedef boost::asio::ip::udp proto;
+
+  UDPPacketSource(std::string localaddr, std::string port);
+
+  u_int32_t recv(u_int8_t* buf, u_int32_t len, PacketSourceEndpoint& remote);
+  void send(u_int8_t* buf, u_int32_t len, PacketSourceEndpoint remote);
+
+  void onResolve(const boost::asio::ip::udp::endpoint& e);
+  void onError(const std::runtime_error& e);
+
+private:
+
+  boost::asio::io_service io_service_;
+  proto::socket sock_;
+};
+
+#endif
diff --git a/src/plainPacket.cpp b/src/plainPacket.cpp
new file mode 100644 (file)
index 0000000..9c39b63
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdexcept>
+#include <iostream>
+#include "datatypes.h"
+#include "endian.h"
+#include "plainPacket.h"
+#include "anytunError.h"
+
+PlainPacket::PlainPacket(u_int32_t payload_length, bool allow_realloc) : Buffer(payload_length + sizeof(payload_type_t), allow_realloc)
+{
+  payload_type_ = reinterpret_cast<payload_type_t*>(buf_);
+  payload_ = buf_ + sizeof(payload_type_t);
+  *payload_type_ = 0;
+}
+
+u_int32_t PlainPacket::getHeaderLength()
+{
+  return sizeof(payload_type_t);
+}
+
+payload_type_t PlainPacket::getPayloadType() const
+{
+  if(payload_type_)
+    return PAYLOAD_TYPE_T_NTOH(*payload_type_);
+
+  return 0;
+}
+
+void PlainPacket::setPayloadType(payload_type_t payload_type)
+{
+  if(!payload_type_)
+    return;
+  
+  if(payload_type == PAYLOAD_TYPE_TUN) {
+    if(!payload_) {
+      *payload_type_ = PAYLOAD_TYPE_T_HTON(PAYLOAD_TYPE_TUN);
+      return;
+    }
+
+    char * ip_version_ptr = reinterpret_cast<char *>(payload_);
+               char ip_version = ip_version_ptr[0];
+               ip_version >>=4;
+    if(ip_version == 4)
+      *payload_type_ = PAYLOAD_TYPE_T_HTON(PAYLOAD_TYPE_TUN4);
+    else if(ip_version == 6)
+      *payload_type_ = PAYLOAD_TYPE_T_HTON(PAYLOAD_TYPE_TUN6);
+  }
+  else
+    *payload_type_ = PAYLOAD_TYPE_T_HTON(payload_type);
+}
+
+u_int32_t PlainPacket::getPayloadLength() const
+{
+  if(!payload_)
+    return 0;
+
+  return (length_ > sizeof(payload_type_t)) ? (length_ - sizeof(payload_type_t)) : 0;
+}
+    
+void PlainPacket::setPayloadLength(u_int32_t payload_length)
+{
+  Buffer::setLength(payload_length + sizeof(payload_type_t));
+      // depending on allow_realloc buf_ may point to another address
+      // therefore in this case reinit() gets called by Buffer::setLength()
+}
+
+void PlainPacket::reinit()
+{
+  payload_type_ = reinterpret_cast<payload_type_t*>(buf_);
+  payload_ = buf_ + sizeof(payload_type_t);
+
+  if(length_ <= (sizeof(payload_type_t)))
+    payload_ = NULL;
+
+  if(length_ < (sizeof(payload_type_t))) {
+    payload_type_ = NULL;
+    AnytunError::throwErr() << "plain packet can't be initialized, buffer is too small"; 
+  }
+
+}
+
+u_int8_t* PlainPacket::getPayload()
+{
+  return payload_;
+}
+
+/*
+NetworkAddress PlainPacket::getSrcAddr() const
+{
+  if(!payload_type_ || !payload_)
+    return NetworkAddress();
+
+  payload_type_t type = PAYLOAD_TYPE_T_NTOH(*payload_type_);
+
+  if(type == PAYLOAD_TYPE_TAP) // Ehternet
+  {
+        // TODO
+    return NetworkAddress();
+  }
+  else if(type == PAYLOAD_TYPE_TUN4) // IPv4
+  {
+    if(length_ < (sizeof(payload_type_t)+sizeof(struct ip)))
+      return NetworkAddress();
+    struct ip* hdr = reinterpret_cast<struct ip*>(payload_);
+    return NetworkAddress(hdr->ip_src);
+  }
+  else if(type == PAYLOAD_TYPE_TUN6) // IPv6
+  {
+    if(length_ < (sizeof(payload_type_t)+sizeof(struct ip6_hdr)))
+      return NetworkAddress();
+    struct ip6_hdr* hdr = reinterpret_cast<struct ip6_hdr*>(payload_);
+    return NetworkAddress(hdr->ip6_src);
+  }
+  return NetworkAddress();
+}*/
+
+NetworkAddress PlainPacket::getDstAddr() const
+{
+       if(!payload_type_ || !payload_)
+               return NetworkAddress();
+
+       payload_type_t type = PAYLOAD_TYPE_T_NTOH(*payload_type_);
+
+       if(type == PAYLOAD_TYPE_TAP) // Ehternet
+       {
+               // TODO
+               return NetworkAddress();
+       }
+       else if(type == PAYLOAD_TYPE_TUN4) // IPv4
+       {
+               if(length_ < (sizeof(payload_type_t)+5*4))
+                       return NetworkAddress();
+               char * hdr = reinterpret_cast<char *>(payload_);
+               boost::asio::ip::address_v4::bytes_type ip_octets;
+               for (int i=0; i<4;i++)
+                       ip_octets[i]=hdr[4*4+i];
+               return NetworkAddress(boost::asio::ip::address_v4(ip_octets));
+       }
+       else if(type == PAYLOAD_TYPE_TUN6) // IPv6
+       {
+               if(length_ < (sizeof(payload_type_t)+2*16+2*4))
+                       return NetworkAddress();
+               char * hdr = reinterpret_cast<char *>(payload_);
+               boost::asio::ip::address_v6::bytes_type ip_octets;
+               for (int i=0; i<16;i++)
+                       ip_octets[i]=hdr[2*4+16+i];
+               return NetworkAddress(boost::asio::ip::address_v6(ip_octets));
+       }
+       return NetworkAddress();
+}
diff --git a/src/plainPacket.h b/src/plainPacket.h
new file mode 100644 (file)
index 0000000..5919c32
--- /dev/null
@@ -0,0 +1,115 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _PLAIN_PACKET_H_
+#define _PLAIN_PACKET_H_
+
+#include "datatypes.h"
+#include "buffer.h"
+
+#include "networkAddress.h"
+
+class Cipher;
+/**
+ * plain SATP packet class<br>
+ * includes payload_type and payload
+ */
+
+#define PAYLOAD_TYPE_TAP 0x6558
+#define PAYLOAD_TYPE_TUN 0x0000
+#define PAYLOAD_TYPE_TUN4 0x0800
+#define PAYLOAD_TYPE_TUN6 0x86DD 
+
+class PlainPacket : public Buffer
+{
+public:
+  /**
+   * Packet constructor
+   * @param the length of the payload 
+   * @param allow reallocation of buffer
+   */
+  PlainPacket(u_int32_t payload_length, bool allow_realloc = false);
+
+  /**
+   * Packet destructor
+   */
+  ~PlainPacket() {};
+
+  /**
+   * Get the length of the header
+   * @return the length of the header
+   */
+  static u_int32_t getHeaderLength();
+
+  /**
+   * Get the payload type
+   * @return the id of the payload type 
+   */
+  payload_type_t getPayloadType() const;
+
+  /**
+   * Set the payload type
+   * @param payload_type payload type id
+   */
+  void setPayloadType(payload_type_t payload_type);
+
+  /**
+   * Get the length of the payload
+   * @return the length of the payload
+   */
+  u_int32_t getPayloadLength() const;
+
+  /**
+   * Set the length of the payload
+   * @param length length of the payload
+   */
+  void setPayloadLength(u_int32_t payload_length);
+
+  /**
+   * Get the the payload
+   * @return the Pointer to the payload
+   */
+  u_int8_t* getPayload();
+
+//  NetworkAddress getSrcAddr() const;
+  NetworkAddress getDstAddr() const;
+
+private:
+  PlainPacket();
+  PlainPacket(const PlainPacket &src);
+
+  void reinit();
+
+  payload_type_t* payload_type_;
+  u_int8_t* payload_;
+};
+
+#endif
diff --git a/src/resolver.cpp b/src/resolver.cpp
new file mode 100644 (file)
index 0000000..06db1b4
--- /dev/null
@@ -0,0 +1,180 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <boost/bind.hpp>
+#include <boost/system/error_code.hpp>
+
+#include "resolver.h"
+#include "log.h"
+
+using ::boost::asio::ip::udp;
+using ::boost::asio::ip::tcp;
+
+template<class Proto>
+void waitAndEnqueue(u_int32_t s, const std::string& addr, const std::string& port, boost::function<void(boost::asio::ip::basic_endpoint<Proto>)> const& onResolve, ErrorCallback const& onError, ResolvAddrType r)
+{
+  cLog.msg(Log::PRIO_ERROR) << "the resolver only supports udp and tcp";
+}
+
+template<>
+void waitAndEnqueue(u_int32_t s, const std::string& addr, const std::string& port, boost::function<void(boost::asio::ip::basic_endpoint<udp>)> const& onResolve, ErrorCallback const& onError, ResolvAddrType r)
+{
+  boost::this_thread::sleep(boost::posix_time::milliseconds(s * 1000));
+  gResolver.resolveUdp(addr, port, onResolve, onError, r);
+}
+
+template<>
+void waitAndEnqueue(u_int32_t s, const std::string& addr, const std::string& port, boost::function<void(boost::asio::ip::basic_endpoint<tcp>)> const& onResolve, ErrorCallback const& onError, ResolvAddrType r)
+{
+  boost::this_thread::sleep(boost::posix_time::milliseconds(s * 1000));
+  gResolver.resolveTcp(addr, port, onResolve, onError, r);
+}
+
+
+template<class Proto>
+ResolveHandler<Proto>::ResolveHandler(const std::string& addr, const std::string& port, boost::function<void(boost::asio::ip::basic_endpoint<Proto>)> const& onResolve, ErrorCallback const& onError, ResolvAddrType r) : addr_(addr), port_(port), onResolve_(onResolve), onError_(onError), resolv_addr_type_(r)
+{
+}
+
+template<class Proto>
+void ResolveHandler<Proto>::operator()(const boost::system::error_code& e, const boost::asio::ip::basic_resolver_iterator<Proto> endpointIt)
+{
+  if(boost::system::posix_error::success == e) {
+    try {
+      onResolve_(*endpointIt);
+    }
+    catch(const std::runtime_error& e)
+    {
+      onError_(e);
+    }
+  } else {
+    cLog.msg(Log::PRIO_ERROR) << "Error while resolving '" << addr_ << "' '" << port_ << "', retrying in 10 sec.";
+    boost::thread(boost::bind(waitAndEnqueue<Proto>, 10, addr_, port_, onResolve_, onError_, resolv_addr_type_));
+  }
+}
+
+Resolver* Resolver::inst = NULL;
+Mutex Resolver::instMutex;
+Resolver& gResolver = Resolver::instance();
+
+Resolver& Resolver::instance()
+{
+  Lock lock(instMutex);
+  static instanceCleaner c;
+  if(!inst)
+    inst = new Resolver();
+  
+  return *inst;
+}
+
+Resolver::Resolver() : udp_resolver_(io_service_), tcp_resolver_(io_service_), thread_(NULL)
+{
+}
+
+Resolver::~Resolver()
+{
+  if(thread_)
+    delete thread_;
+}
+
+void Resolver::init()
+{
+  if(!thread_)
+         thread_ = new boost::thread(boost::bind(&Resolver::run, this));
+}
+
+void Resolver::run()
+{
+  cLog.msg(Log::PRIO_DEBUG) << "Resolver Thread started";
+
+  while(1) {
+    try {
+      io_service_.run();
+      io_service_.reset();
+      boost::this_thread::sleep(boost::posix_time::milliseconds(250));
+    }
+    catch(const std::runtime_error& e)
+    {
+      cLog.msg(Log::PRIO_ERROR) << "resolver caught runtime error, restarting: " << e.what();
+    }
+    catch(const std::exception& e)
+    {
+      cLog.msg(Log::PRIO_ERROR) << "resolver caught exception, restarting: " << e.what();
+    }
+  }
+}
+
+
+void Resolver::resolveUdp(const std::string& addr, const std::string& port, UdpResolveCallback const& onResolve, ErrorCallback const& onError, ResolvAddrType r)
+{
+  cLog.msg(Log::PRIO_DEBUG) << "trying to resolv UDP: '" << addr << "' '" << port << "'";
+
+  std::auto_ptr<udp::resolver::query> query;
+  if(addr != "") {
+    switch(r) {
+    case IPV4_ONLY: query = std::auto_ptr<udp::resolver::query>(new udp::resolver::query(udp::v4(), addr, port)); break;
+    case IPV6_ONLY: query = std::auto_ptr<udp::resolver::query>(new udp::resolver::query(udp::v6(), addr, port)); break;
+    default: query = std::auto_ptr<udp::resolver::query>(new udp::resolver::query(addr, port)); break;
+    }
+  }
+  else {
+    switch(r) {
+    case IPV4_ONLY: query = std::auto_ptr<udp::resolver::query>(new udp::resolver::query(udp::v4(), port)); break;
+    case IPV6_ONLY: query = std::auto_ptr<udp::resolver::query>(new udp::resolver::query(udp::v6(), port)); break;
+    default: query = std::auto_ptr<udp::resolver::query>(new udp::resolver::query(port)); break;
+    }
+  }
+  UdpResolveHandler handler(addr, port, onResolve, onError, r);
+  udp_resolver_.async_resolve(*query, handler);
+}
+
+void Resolver::resolveTcp(const std::string& addr, const std::string& port, TcpResolveCallback const& onResolve, ErrorCallback const& onError, ResolvAddrType r)
+{
+  cLog.msg(Log::PRIO_DEBUG) << "trying to resolv TCP: '" << addr << "' '" << port << "'";
+
+  std::auto_ptr<tcp::resolver::query> query;
+  if(addr != "") {
+    switch(r) {
+    case IPV4_ONLY: query = std::auto_ptr<tcp::resolver::query>(new tcp::resolver::query(tcp::v4(), addr, port)); break;
+    case IPV6_ONLY: query = std::auto_ptr<tcp::resolver::query>(new tcp::resolver::query(tcp::v6(), addr, port)); break;
+    default: query = std::auto_ptr<tcp::resolver::query>(new tcp::resolver::query(addr, port)); break;
+    }
+  }
+  else {
+    switch(r) {
+    case IPV4_ONLY: query = std::auto_ptr<tcp::resolver::query>(new tcp::resolver::query(tcp::v4(), port)); break;
+    case IPV6_ONLY: query = std::auto_ptr<tcp::resolver::query>(new tcp::resolver::query(tcp::v6(), port)); break;
+    default: query = std::auto_ptr<tcp::resolver::query>(new tcp::resolver::query(port)); break;
+    }
+  }
+  TcpResolveHandler handler(addr, port, onResolve, onError, r);
+  tcp_resolver_.async_resolve(*query, handler); 
+}
diff --git a/src/resolver.h b/src/resolver.h
new file mode 100644 (file)
index 0000000..b5553bc
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _RESOLVER_H_
+#define _RESOLVER_H_
+
+#include <queue>
+#include <boost/asio.hpp>
+#include <boost/function.hpp>
+
+#include "datatypes.h"
+#include "threadUtils.hpp"
+
+typedef boost::function<void (boost::asio::ip::udp::endpoint)> UdpResolveCallback;
+typedef boost::function<void (boost::asio::ip::tcp::endpoint)> TcpResolveCallback;
+typedef boost::function<void (std::runtime_error const&)> ErrorCallback;
+
+template<class Proto>
+class ResolveHandler
+{
+public:
+  ResolveHandler(const std::string& addr, const std::string& port, boost::function<void (boost::asio::ip::basic_endpoint<Proto>)> const& onResolve, ErrorCallback const& onError, ResolvAddrType r = ANY);
+  void operator()(const boost::system::error_code& e, const boost::asio::ip::basic_resolver_iterator<Proto>);
+
+private:
+  std::string addr_;
+  std::string port_;
+  boost::function<void (boost::asio::ip::basic_endpoint<Proto>)> onResolve_;
+  ErrorCallback onError_;
+  ResolvAddrType resolv_addr_type_;
+};
+
+typedef ResolveHandler<boost::asio::ip::udp> UdpResolveHandler;
+typedef ResolveHandler<boost::asio::ip::tcp> TcpResolveHandler;
+
+class Resolver 
+{
+public:
+  static Resolver& instance();
+
+  void init();
+  void run();
+
+  void resolveUdp(const std::string& addr, const std::string& port, UdpResolveCallback const& onResolve, ErrorCallback const& onError, ResolvAddrType r = ANY);
+  void resolveTcp(const std::string& addr, const std::string& port, TcpResolveCallback const& onResolve, ErrorCallback const& onError, ResolvAddrType r = ANY);
+
+private:
+  Resolver();
+  ~Resolver();
+  Resolver(const Resolver &r);
+  void operator=(const Resolver &r);
+
+  static Resolver* inst;
+  static ::Mutex instMutex;
+  class instanceCleaner {
+    public: ~instanceCleaner() {
+      if(Resolver::inst != 0)
+        delete Resolver::inst;
+    }
+  };
+  friend class instanceCleaner;
+
+  boost::asio::io_service io_service_;
+  boost::asio::ip::udp::resolver udp_resolver_;
+  boost::asio::ip::tcp::resolver tcp_resolver_;
+  boost::thread* thread_;
+};
+
+extern Resolver& gResolver;
+
+#endif
diff --git a/src/routingTable.cpp b/src/routingTable.cpp
new file mode 100644 (file)
index 0000000..b683dca
--- /dev/null
@@ -0,0 +1,196 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "networkPrefix.h"
+#include "threadUtils.hpp"
+#include "datatypes.h"
+#include "anytunError.h"
+
+#include "routingTable.h"
+#include "routingTree.hpp"
+
+RoutingTable* RoutingTable::inst = NULL;
+Mutex RoutingTable::instMutex;
+RoutingTable& gRoutingTable = RoutingTable::instance();
+
+
+RoutingTable& RoutingTable::instance()
+{
+  Lock lock(instMutex);
+  static instanceCleaner c;
+  if(!inst)
+    inst = new RoutingTable();
+
+  return *inst;
+}
+
+RoutingTable::RoutingTable()
+{
+}
+
+RoutingTable::~RoutingTable()
+{
+} 
+
+void RoutingTable::updateRouteTreeUnlocked(const NetworkPrefix & pref)
+{
+  //Lock lock(mutex_); //deadlock
+
+       u_int8_t length=pref.getNetworkPrefixLength();
+       network_address_type_t type=pref.getNetworkAddressType();
+       u_int16_t mux = routes_[pref.getNetworkAddressType()].find(pref)->second;
+       RoutingTreeNode * node = &(root_[type]);
+       if (type==ipv4)
+       {
+               ipv4_bytes_type bytes(pref.to_bytes_v4());
+               if (length>32)
+                       length=32;
+               RoutingTree::walk(bytes, node, length, mux);
+       } else if  (type==ipv6) {
+               ipv6_bytes_type bytes(pref.to_bytes_v6());
+               if (length>128)
+                       length=128;
+               RoutingTree::walk(bytes, node, length, mux);
+       } else if (type==ethernet) {
+               ethernet_bytes_type bytes(pref.to_bytes_ethernet());
+               if (length>48)
+                       length=48;
+               RoutingTree::walk(bytes, node, length, mux);
+       } else {
+               AnytunError::throwErr() << "illegal protocol type";     
+       }
+       //root_[type].print(0);
+}
+
+void RoutingTable::addRoute(const NetworkPrefix & pref, u_int16_t mux)
+{
+  Lock lock(mutex_);
+       
+       network_address_type_t type=pref.getNetworkAddressType();       
+
+       if (type==ipv4 || type==ipv6)
+       {
+    std::pair<RoutingMap::iterator, bool> ret = routes_[type].insert(RoutingMap::value_type(pref,mux));
+    if(!ret.second)
+    {
+      routes_[pref.getNetworkAddressType()].erase(ret.first);
+      routes_[pref.getNetworkAddressType()].insert(RoutingMap::value_type(pref,mux));
+    }
+               root_[pref.getNetworkAddressType()]=RoutingTreeNode();
+               RoutingMap::iterator it = routes_[type].begin();
+         for (;it!=routes_[pref.getNetworkAddressType()].end();++it)
+                       updateRouteTreeUnlocked(it->first);
+       } else if (type==ethernet) {
+    return; // TODO: add support for ethernet
+       } else {
+               AnytunError::throwErr() << "illegal protocol type";     
+       }
+}
+
+
+void RoutingTable::delRoute(const NetworkPrefix & pref )
+{
+  Lock lock(mutex_);
+       
+  routes_[pref.getNetworkAddressType()].erase(routes_[pref.getNetworkAddressType()].find(pref));       
+}
+
+u_int16_t RoutingTable::getRoute(const NetworkAddress & addr)
+{
+       Lock lock(mutex_);
+       network_address_type_t type=addr.getNetworkAddressType();
+       
+       if (routes_[type].empty())
+       AnytunError::throwErr() << "no route";
+
+       if (type==ipv4)
+       {
+               ipv4_bytes_type bytes(addr.to_bytes_v4());
+               return RoutingTree::find(bytes, root_[type]);
+       } else if  (type==ipv6) {
+               ipv6_bytes_type bytes(addr.to_bytes_v6());
+               return RoutingTree::find(bytes, root_[type]);
+       } else if (type==ethernet) {
+               //TODO Our model wont fit to ethernet addresses well.
+               // maybe use hashmap or something like that instead
+               ethernet_bytes_type bytes(addr.to_bytes_ethernet());
+               return RoutingTree::find(bytes, root_[type]);
+       } else {
+               AnytunError::throwErr() << "illegal protocol type";     
+       }
+  return 0;
+}
+
+u_int16_t* RoutingTable::getOrNewRoutingTEUnlocked(const NetworkPrefix & addr)
+{
+  RoutingMap::iterator it = routes_[addr.getNetworkAddressType()].find(addr);
+  if(it!=routes_[addr.getNetworkAddressType()].end())
+    return &(it->second);
+
+  routes_[addr.getNetworkAddressType()].insert(RoutingMap::value_type(addr, 1));
+  it = routes_[addr.getNetworkAddressType()].find(addr);
+  return &(it->second);
+}
+
+u_int16_t RoutingTable::getCountUnlocked(network_address_type_t type)
+{
+       RoutingMap::iterator it = routes_[type].begin();
+       u_int16_t routes=0;
+       for (;it!=routes_[type].end();++it)
+               routes++;
+       return routes;
+}
+
+RoutingMap::iterator RoutingTable::getBeginUnlocked(network_address_type_t type)
+{
+       return routes_[type].begin();
+}
+
+RoutingMap::iterator RoutingTable::getEndUnlocked(network_address_type_t type)
+{
+       return routes_[type].end();
+}
+
+void RoutingTable::clear(network_address_type_t type)
+{
+  Lock lock(mutex_);
+       routes_[type].clear();
+}
+
+bool RoutingTable::empty(network_address_type_t type)
+{
+  Lock lock(mutex_);
+       return routes_[type].empty();
+}
+
+Mutex& RoutingTable::getMutex()
+{
+  return mutex_;
+}
diff --git a/src/routingTable.h b/src/routingTable.h
new file mode 100644 (file)
index 0000000..9ab3260
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _ROUTINGTABLE_H
+#define _ROUTINGTABLE_H
+
+#include <map>
+#include <deque>
+
+#include "threadUtils.hpp"
+#include "datatypes.h"
+#include "networkAddress.h"
+#include "networkPrefix.h"
+#include "routingTreeNode.h"
+#include "boost/array.hpp"
+typedef std::map<NetworkPrefix,u_int16_t> RoutingMap;
+
+class RoutingTable
+{
+public:
+       static RoutingTable& instance();
+       RoutingTable();
+       ~RoutingTable();
+       void addRoute(const NetworkPrefix & ,u_int16_t);
+       void updateRouteTreeUnlocked(const NetworkPrefix & pref);
+       void delRoute(const NetworkPrefix & );
+       u_int16_t getRoute(const NetworkAddress &);
+       bool empty(network_address_type_t type);
+       void clear(network_address_type_t type);
+  Mutex& getMutex();
+       u_int16_t* getOrNewRoutingTEUnlocked(const NetworkPrefix & addr);
+       u_int16_t getCountUnlocked(network_address_type_t type);
+       RoutingMap::iterator getBeginUnlocked(network_address_type_t type);
+       RoutingMap::iterator getEndUnlocked(network_address_type_t type);
+
+private:
+  static Mutex instMutex;
+       static RoutingTable* inst;
+  class instanceCleaner {
+    public: ~instanceCleaner() {
+     if(RoutingTable::inst != 0)
+       delete RoutingTable::inst;
+   }
+       };
+       RoutingTable(const RoutingTable &s);
+  void operator=(const RoutingTable &s);
+       boost::array<RoutingMap,3> routes_;
+       boost::array<RoutingTreeNode,3> root_;
+  Mutex mutex_;
+};
+
+extern RoutingTable& gRoutingTable;
+
+#endif
diff --git a/src/routingTree.hpp b/src/routingTree.hpp
new file mode 100644 (file)
index 0000000..3a9024d
--- /dev/null
@@ -0,0 +1,104 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __ROUTING_TREE_
+#define __ROUTING_TREE_
+
+#include "anytunError.h"
+
+class RoutingTree {
+
+public:
+  template <class BinaryType>
+  static void walk(BinaryType bytes ,RoutingTreeNode * node,u_int8_t length,u_int16_t mux)
+  {
+    for (int i=0; i<(length/8); i++)
+    {
+      if (!node->nodes_[bytes[i]])
+        node->nodes_[bytes[i]] = new RoutingTreeNode;
+      node=node->nodes_[bytes[i]];
+    }
+    if (length%8)
+    {
+      unsigned char idx=0xff;
+      idx <<=8-(length%8);
+      idx &= bytes[length/8];
+      unsigned char maxidx=0xff;
+      maxidx>>=(length%8);
+      maxidx|=idx;
+      for (unsigned char i=idx; i<=maxidx; i++)
+      {
+        if (!node->nodes_[i])
+          node->nodes_[i] = new RoutingTreeNode;
+        node->nodes_[i]->valid_=true;
+        node->nodes_[i]->mux_=mux;
+      }
+    } else {
+      node->valid_=true;
+      node->mux_=mux;
+    }
+  }
+  
+  template <class BinaryType>
+  static u_int16_t find(BinaryType bytes ,RoutingTreeNode & root )
+  {
+    bool valid=0;
+    u_int16_t mux=0;
+    RoutingTreeNode * node = &root;
+    if (root.valid_)
+    {
+      mux=root.mux_;
+      valid=1;
+    }
+    for (size_t level=0;level<bytes.size();level++)
+    {
+      if (node->nodes_[bytes[level]])
+      {
+        node=node->nodes_[bytes[level]];
+        if(node->valid_)
+        {
+          mux=node->mux_;
+          valid=1;
+        }
+      } else {
+        break;
+      }
+    }
+    if(!valid)
+      AnytunError::throwErr() << "no route";
+    return mux;
+  }
+
+};
+
+#endif
+  
+  
diff --git a/src/routingTreeNode.cpp b/src/routingTreeNode.cpp
new file mode 100644 (file)
index 0000000..eed501b
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "routingTreeNode.h"
+
+RoutingTreeNode::RoutingTreeNode():mux_(0),valid_(false)
+{
+       for(int i=0; i<256; i++)
+               nodes_[i]=NULL;
+}
+
+void RoutingTreeNode::print(int level) const
+{
+       if (valid_)
+       {       
+               std::cout << " -> " <<mux_ ;
+       }
+       std::cout  << std::endl;
+  for(int i=0; i<256; i++)
+       {
+               if ( nodes_[i])
+               {
+                       for(int l=0;l<level;l++)
+                               std::cout << " ";
+                       std::cout << (int) i;
+                       nodes_[i]->print(level+1);
+               }
+       }
+}
+
+RoutingTreeNode::~RoutingTreeNode()
+{
+       for(int i=0; i<256; i++)
+               if(nodes_[i])
+                       delete nodes_[i];
+} 
diff --git a/src/routingTreeNode.h b/src/routingTreeNode.h
new file mode 100644 (file)
index 0000000..3c2d33d
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _ROUTING_TREE_NODE_H
+#define _ROUTING_TREE_NODE_H
+
+
+#include "threadUtils.hpp"
+#include "datatypes.h"
+#include "networkAddress.h"
+#include "networkPrefix.h"
+
+class RoutingTree;
+
+class RoutingTreeNode
+{
+public:
+       RoutingTreeNode();
+       ~RoutingTreeNode();
+       void print(int) const;
+
+private:
+//  Mutex mutex_;
+       u_int16_t mux_;
+       bool valid_;
+       boost::array<RoutingTreeNode *,256> nodes_;
+
+  friend class RoutingTree;
+};
+
+#endif
diff --git a/src/seqWindow.cpp b/src/seqWindow.cpp
new file mode 100644 (file)
index 0000000..34ce02c
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "threadUtils.hpp"
+#include "datatypes.h"
+
+#include "seqWindow.h"
+
+SeqWindowElement::SeqWindowElement()
+{
+  window_ = NULL;
+  pos_ = 0;
+  max_ = 0;
+}
+
+SeqWindowElement::~SeqWindowElement()
+{
+  if(window_)
+    delete[] window_;
+}
+
+void SeqWindowElement::init(window_size_t w, seq_nr_t m)
+{
+  if(window_)
+    delete[] window_;
+  window_ = new u_int8_t[w];
+  memset(window_, 0, w); 
+  pos_ = 0;
+  max_ = m;
+  window_[pos_] = 1;
+}
+
+SeqWindow::SeqWindow(window_size_t w) : window_size_(w)
+{
+}
+
+SeqWindow::~SeqWindow()
+{
+}
+
+bool SeqWindow::checkAndAdd(sender_id_t sender, seq_nr_t seq_nr)
+{
+  Lock lock(mutex_);
+  if (!window_size_)
+    return false;
+
+  SenderMap::iterator s = sender_.find(sender);
+  if(s == sender_.end()) {
+    sender_[sender].init(window_size_, seq_nr);
+    return false;
+  }
+
+  int shifted = 0;
+  if(s->second.max_ < window_size_) {
+    s->second.max_ += SEQ_NR_MAX/2;
+    seq_nr += SEQ_NR_MAX/2;
+    shifted = 1;
+  }
+  else if(s->second.max_ > (SEQ_NR_MAX - window_size_)) {
+    s->second.max_ -= SEQ_NR_MAX/2;
+    seq_nr -= SEQ_NR_MAX/2;
+    shifted = 2;
+  }
+  
+  seq_nr_t min = s->second.max_ - window_size_ + 1;
+  if(seq_nr < min || seq_nr == s->second.max_) {
+    if(shifted == 1)
+      s->second.max_ -= SEQ_NR_MAX/2;
+    else if(shifted == 2)
+      s->second.max_ += SEQ_NR_MAX/2;
+    return true;
+  }
+  
+  if(seq_nr > s->second.max_) {
+    seq_nr_t diff = seq_nr - s->second.max_;
+    if(diff >= window_size_)
+      diff = window_size_;
+    
+    window_size_t new_pos = s->second.pos_ + diff;
+    
+    if(new_pos >= window_size_) {
+      new_pos -= window_size_;
+      
+      if(s->second.pos_ < window_size_ - 1)
+        memset(&(s->second.window_[s->second.pos_ + 1]), 0, window_size_ - s->second.pos_ - 1);
+      
+      memset(s->second.window_, 0, new_pos);
+    }
+    else {
+      memset(&(s->second.window_[s->second.pos_ + 1]), 0, diff);
+    }
+    s->second.pos_ = new_pos;
+    s->second.window_[s->second.pos_] = 1;
+    s->second.max_ = seq_nr;
+    
+    if(shifted == 1)
+      s->second.max_ -= SEQ_NR_MAX/2;
+    else if(shifted == 2)
+      s->second.max_ += SEQ_NR_MAX/2;
+    
+    return false;
+  }
+  
+  seq_nr_t diff = s->second.max_ - seq_nr;
+  window_size_t pos = diff > s->second.pos_ ? s->second.pos_ + window_size_ : s->second.pos_; 
+  pos -= diff;
+  
+  if(shifted == 1)
+    s->second.max_ -= SEQ_NR_MAX/2;
+  else if(shifted == 2)
+    s->second.max_ += SEQ_NR_MAX/2;
+  
+  int ret = s->second.window_[pos];
+  s->second.window_[pos] = 1;
+  
+  if(ret)
+    return true;
+  
+  return false;
+}
+
+void SeqWindow::clear(sender_id_t sender)
+{
+  Lock lock(mutex_);
+  sender_.erase(sender);
+}
+
+void SeqWindow::clear()
+{
+  Lock lock(mutex_);
+  sender_.clear();
+}
diff --git a/src/seqWindow.h b/src/seqWindow.h
new file mode 100644 (file)
index 0000000..e16e335
--- /dev/null
@@ -0,0 +1,91 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SEQ_WINDOW_H_
+#define _SEQ_WINDOW_H_
+
+#include <map>
+#include <deque>
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/archive/text_iarchive.hpp>
+#include "threadUtils.hpp"
+#include "datatypes.h"
+
+class SeqWindow;
+
+class SeqWindowElement {
+public:
+  SeqWindowElement();
+  ~SeqWindowElement();
+
+  void init(window_size_t w, seq_nr_t m);
+
+  seq_nr_t max_;
+  window_size_t pos_;
+  u_int8_t* window_;
+};
+
+class SeqWindow
+{
+public:
+  typedef std::map<sender_id_t, SeqWindowElement> SenderMap;
+
+  SeqWindow(window_size_t w);
+  ~SeqWindow();
+
+  bool checkAndAdd(sender_id_t sender, seq_nr_t seq_nr);
+  void clear(sender_id_t sender);
+  void clear();
+
+private:
+  window_size_t window_size_;
+  Mutex mutex_;
+  SenderMap sender_;
+
+  SeqWindow(const SeqWindow &s);
+  void operator=(const SeqWindow &s);
+
+       friend class boost::serialization::access;
+       template<class Archive>
+       void serialize(Archive & ar, const unsigned int version)
+       {
+               Lock lock(mutex_);
+               //unsigned int serial = (unsigned int) window_size_;
+               //window_size_t serial = (window_size_t) window_size_;
+       ar & window_size_;
+       //TODO: Do not sync complete Sender Map!
+       // ar & sender_;
+  }
+
+};
+
+#endif
diff --git a/src/signalController.cpp b/src/signalController.cpp
new file mode 100644 (file)
index 0000000..b2017fd
--- /dev/null
@@ -0,0 +1,255 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <map>
+#include <iostream>
+
+#include "signalController.h"
+#include "log.h"
+#include "anytunError.h"
+#include "threadUtils.hpp"
+
+#ifndef _MSC_VER
+#include <csignal>
+#include <boost/bind.hpp>
+#else
+#include <windows.h>
+#endif
+
+SignalController* SignalController::inst = NULL;
+Mutex SignalController::instMutex;
+SignalController& gSignalController = SignalController::instance();
+
+SignalController& SignalController::instance()
+{
+       Lock lock(instMutex);
+       static instanceCleaner c;
+       if(!inst)
+               inst = new SignalController();
+
+       return *inst;
+}
+
+int SigErrorHandler::handle(const std::string& msg)
+{
+  AnytunError::throwErr() << msg;
+
+  return 0;
+}
+
+#ifndef _MSC_VER
+
+int SigIntHandler::handle()
+{
+  cLog.msg(Log::PRIO_NOTICE) << "SIG-Int caught, exiting";
+
+  return 1;
+}
+
+int SigQuitHandler::handle()
+{
+  cLog.msg(Log::PRIO_NOTICE) << "SIG-Quit caught, exiting";
+
+  return 1;
+}
+
+int SigHupHandler::handle()
+{
+  cLog.msg(Log::PRIO_NOTICE) << "SIG-Hup caught";
+
+  return 0;
+}
+
+int SigTermHandler::handle()
+{
+  cLog.msg(Log::PRIO_NOTICE) << "SIG-Term caughtm, exiting";
+
+  return 1;
+}
+
+int SigUsr1Handler::handle()
+{
+  cLog.msg(Log::PRIO_NOTICE) << "SIG-Usr1 caught";
+
+  return 0;
+}
+
+int SigUsr2Handler::handle()
+{
+  cLog.msg(Log::PRIO_NOTICE) << "SIG-Usr2 caught";
+
+  return 0;
+}
+#else
+int CtrlCHandler::handle()
+{
+  cLog.msg(Log::PRIO_NOTICE) << "CTRL-C Event received, exitting";
+
+  return 1;
+}
+
+int CtrlBreakHandler::handle()
+{
+  cLog.msg(Log::PRIO_NOTICE) << "CTRL-Break Event received, ignoring";
+
+  return 0;
+}
+
+int CtrlCloseHandler::handle()
+{
+  cLog.msg(Log::PRIO_NOTICE) << "Close Event received, exitting";
+
+  return 1;
+}
+
+int CtrlLogoffHandler::handle()
+{
+  cLog.msg(Log::PRIO_NOTICE) << "LogOff Event received, exitting";
+
+  return 1;
+}
+
+int CtrlShutdownHandler::handle()
+{
+  cLog.msg(Log::PRIO_NOTICE) << "Shutdown Event received, exitting";
+
+  return 1;
+}
+#endif
+
+SignalController::~SignalController() 
+{
+  for(HandlerMap::iterator it = handler.begin(); it != handler.end(); ++it)
+    delete it->second;
+
+#ifndef _MSC_VER
+  if(thread) delete thread;
+#endif
+}
+
+#ifndef _MSC_VER
+void SignalController::handle()
+{
+  sigset_t signal_set;
+  int sigNum;
+
+  while(1) 
+  {
+    sigfillset(&signal_set);
+    sigwait(&signal_set, &sigNum);
+    inject(sigNum);
+  }
+}
+#else
+bool SignalController::handle(DWORD ctrlType)
+{
+  gSignalController.inject(ctrlType);
+  return true;
+}
+#endif
+
+void SignalController::init()
+{
+#ifndef _MSC_VER
+  sigset_t signal_set;
+  
+  sigfillset(&signal_set);        
+  sigdelset(&signal_set, SIGCHLD);
+  sigdelset(&signal_set, SIGSEGV);
+  sigdelset(&signal_set, SIGBUS);
+  sigdelset(&signal_set, SIGFPE);
+
+#if defined(BOOST_HAS_PTHREADS)
+  pthread_sigmask(SIG_BLOCK, &signal_set, NULL);
+#else
+#error The signalhandler works only with pthreads
+#endif
+  
+  thread = new boost::thread(boost::bind(&SignalController::handle, this));
+
+  handler[SIGINT] = new SigIntHandler;
+  handler[SIGQUIT] = new SigQuitHandler;
+  handler[SIGHUP] = new SigHupHandler;
+  handler[SIGTERM] = new SigTermHandler;
+  handler[SIGUSR1] = new SigUsr1Handler;
+  handler[SIGUSR2] = new SigUsr2Handler;
+#else
+  if(!SetConsoleCtrlHandler((PHANDLER_ROUTINE)SignalController::handle, true))
+    AnytunError::throwErr() << "Error on SetConsoleCtrlhandler: " << AnytunErrno(GetLastError());
+
+  handler[CTRL_C_EVENT] = new CtrlCHandler;
+  handler[CTRL_BREAK_EVENT] = new CtrlBreakHandler;
+  handler[CTRL_CLOSE_EVENT] = new CtrlCloseHandler;
+  handler[CTRL_LOGOFF_EVENT] = new CtrlLogoffHandler;
+  handler[CTRL_SHUTDOWN_EVENT] = new CtrlShutdownHandler;
+#endif
+
+  handler[SIGERROR] = new SigErrorHandler;
+}
+
+void SignalController::inject(int sig, const std::string& msg)
+{
+  {
+    Lock lock(sigQueueMutex);
+    sigQueue.push(SigPair(sig, msg));
+  }
+  sigQueueSem.up();
+}
+
+int SignalController::run()
+{
+  while(1) {
+    sigQueueSem.down();
+    SigPair sig;
+    {
+      Lock lock(sigQueueMutex);
+      sig = sigQueue.front();
+      sigQueue.pop();
+    }
+    
+    HandlerMap::iterator it = handler.find(sig.first);
+    if(it != handler.end())
+    {
+      int ret;
+      if(sig.second == "")
+        ret = it->second->handle();
+      else
+        ret = it->second->handle(sig.second);
+
+      if(ret)
+        return ret;
+    }
+    else
+      cLog.msg(Log::PRIO_NOTICE) << "SIG " << sig.first << " caught with message '" << sig.second << "'- ignoring";
+  }
+  return 0;
+}
+
diff --git a/src/signalController.h b/src/signalController.h
new file mode 100644 (file)
index 0000000..575b50b
--- /dev/null
@@ -0,0 +1,199 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SIGNAL_CONTROLLER_H_
+#define _SIGNAL_CONTROLLER_H_
+
+#include <map>
+#include <queue>
+
+#include "threadUtils.hpp"
+
+#ifndef _MSC_VER
+#include <csignal>
+#endif
+
+#define SIGERROR -1
+
+class SignalHandler
+{
+public:
+  virtual ~SignalHandler() {}
+
+  virtual int handle() { return 0; }
+  virtual int handle(const std::string& msg) { return 0; }
+
+protected:
+  SignalHandler(int s) : sigNum(s) {}
+
+private:
+  int sigNum;
+  friend class SignalController;
+};
+
+class SigErrorHandler : public SignalHandler
+{
+public:
+  SigErrorHandler() : SignalHandler(SIGERROR) {}
+  int handle(const std::string& msg);
+};
+
+#ifndef _MSC_VER
+class SigIntHandler : public SignalHandler
+{
+public:
+  SigIntHandler() : SignalHandler(SIGINT) {}
+  int handle();
+};
+
+class SigQuitHandler : public SignalHandler
+{
+public:
+  SigQuitHandler() : SignalHandler(SIGQUIT) {}
+  int handle();
+};
+
+class SigHupHandler : public SignalHandler
+{
+public:
+  SigHupHandler() : SignalHandler(SIGHUP) {}
+  int handle();
+};
+
+class SigUsr1Handler : public SignalHandler
+{
+public:
+  SigUsr1Handler() : SignalHandler(SIGUSR1) {}
+  int handle();
+};
+
+class SigUsr2Handler : public SignalHandler
+{
+public:
+  SigUsr2Handler() : SignalHandler(SIGUSR2) {}
+  int handle();
+};
+
+class SigTermHandler : public SignalHandler
+{
+public:
+  SigTermHandler() : SignalHandler(SIGTERM) {}
+  int handle();
+};
+
+#else
+
+class CtrlCHandler : public SignalHandler
+{
+public:
+  CtrlCHandler() : SignalHandler(CTRL_C_EVENT) {}
+  int handle();
+};
+
+class CtrlBreakHandler : public SignalHandler
+{
+public:
+  CtrlBreakHandler() : SignalHandler(CTRL_BREAK_EVENT) {}
+  int handle();
+};
+
+class CtrlCloseHandler : public SignalHandler
+{
+public:
+  CtrlCloseHandler() : SignalHandler(CTRL_BREAK_EVENT) {}
+  int handle();
+};
+
+class CtrlLogoffHandler : public SignalHandler
+{
+public:
+  CtrlLogoffHandler() : SignalHandler(CTRL_BREAK_EVENT) {}
+  int handle();
+};
+
+class CtrlShutdownHandler : public SignalHandler
+{
+public:
+  CtrlShutdownHandler() : SignalHandler(CTRL_BREAK_EVENT) {}
+  int handle();
+};
+#endif
+
+class SignalController
+{
+public:
+  static SignalController& instance();
+#ifndef _MSC_VER
+  void handle();
+#else
+  static bool handle(DWORD ctrlType);
+#endif
+
+  void init();
+  int run();
+  void inject(int sig, const std::string& msg = "");
+
+private:
+  typedef std::map<int, SignalHandler*> HandlerMap;
+
+#ifndef _MSC_VER
+  SignalController() : thread(NULL) {};
+#else
+  SignalController() {};
+#endif
+  ~SignalController();
+  SignalController(const SignalController &s);
+  void operator=(const SignalController &s);
+
+  static SignalController* inst;
+  static Mutex instMutex;
+  class instanceCleaner {
+    public: ~instanceCleaner() {
+      if(SignalController::inst != NULL)
+        delete SignalController::inst;
+    }
+  };
+  friend class instanceCleaner;
+
+  typedef std::pair<int, std::string> SigPair;
+  std::queue<SigPair> sigQueue;
+  Mutex sigQueueMutex;
+  Semaphore sigQueueSem;
+
+#ifndef _MSC_VER  
+  boost::thread* thread;
+#endif
+  HandlerMap handler;
+};
+
+extern SignalController& gSignalController;
+
+#endif
diff --git a/src/syncBuffer.cpp b/src/syncBuffer.cpp
new file mode 100644 (file)
index 0000000..9247fff
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "syncBuffer.h"
+
diff --git a/src/syncBuffer.h b/src/syncBuffer.h
new file mode 100644 (file)
index 0000000..f5e2ff5
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SYNCBUFFER_H_
+#define _SYNCBUFFER_H_
+
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/archive/text_iarchive.hpp>
+#include "buffer.h"
+#include <iostream>
+#include "datatypes.h"
+#include "threadUtils.hpp"
+
+class SyncBuffer : public Buffer
+{
+public:
+               SyncBuffer() : Buffer(){};
+               SyncBuffer(u_int32_t length) : Buffer(length){};
+               SyncBuffer(Buffer b): Buffer(b) {};
+               SyncBuffer(u_int8_t* data, u_int32_t length): Buffer(data,length) {};
+               SyncBuffer(const SyncBuffer & src) : Buffer(src) {};
+private:
+//TODO check if this is ok
+//  Mutex mutex_;
+       friend class boost::serialization::access;
+       template<class Archive>
+       void serialize(Archive & ar, const unsigned int version)
+       {
+//             Lock lock(mutex_);
+    ar & length_;
+               for(u_int32_t i = 0; i < length_; i++)
+                       ar & (*this)[i];
+       }
+};
+
+#endif
diff --git a/src/syncClient.cpp b/src/syncClient.cpp
new file mode 100644 (file)
index 0000000..df99b83
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <sstream>
+#include <iostream>
+#include <string>
+#include "connectionList.h"
+#include "syncCommand.h"
+
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/archive/text_iarchive.hpp>
+
+
+#include "log.h"
+#include "syncClient.h"
+#include "syncTcpConnection.h"
+#include "buffer.h"
+#include <boost/array.hpp>
+
+
+SyncClient::SyncClient(std::string hostname,std::string port)
+:hostname_( hostname),port_(port)
+{
+}
+
+void SyncClient::run()
+{
+       bool connected(false);
+       for(;;)
+       {
+               try
+               {
+                       boost::asio::io_service io_service;
+                       SyncTcpConnection::proto::resolver resolver(io_service);
+                       SyncTcpConnection::proto::resolver::query query( hostname_, port_);
+                 SyncTcpConnection::proto::resolver::iterator endpoint_iterator = resolver.resolve(query);
+                       SyncTcpConnection::proto::resolver::iterator end;
+
+                       SyncTcpConnection::proto::socket socket(io_service);
+                       boost::system::error_code error = boost::asio::error::host_not_found;
+                       while (error && endpoint_iterator != end)
+                       {
+                               socket.close();
+                               socket.connect(*endpoint_iterator++, error);
+                       }
+                       if (error)
+                               throw boost::system::system_error(error);
+                       if (!connected)
+                               cLog.msg(Log::PRIO_NOTICE) << "sync: connected to " << hostname_ <<":"<< port_;
+                       connected=true;
+                       readAndProcess(socket); //endless loop
+               }
+               catch (std::exception& e)
+               {
+                       if (connected) 
+                               cLog.msg(Log::PRIO_NOTICE) << "sync: connection to " << hostname_ <<":"<< port_<< " lost ("<< e.what() << ") retrying every 10sec";
+                       connected=false;
+                       boost::this_thread::sleep(boost::posix_time::milliseconds(10000));
+               }
+       }
+}
+
+void SyncClient::readAndProcess(SyncTcpConnection::proto::socket & socket)
+{
+       ConnectionList & cl_ (gConnectionList);
+       size_t message_lenght ;
+       for (;;)
+       {
+               std::stringstream message_lenght_stream;
+               readExactly(socket,5,message_lenght_stream);
+               message_lenght_stream >> message_lenght;
+               std::stringstream void_stream;
+               readExactly(socket,1,void_stream); //skip space
+               std::stringstream sync_command_stream;
+               readExactly(socket,message_lenght, sync_command_stream);
+               //cLog.msg(Log::PRIO_NOTICE) << "recieved sync inforamtaion "<<tmp.str()<< std::endl;
+               boost::archive::text_iarchive ia(sync_command_stream);
+               SyncCommand scom(cl_);
+               ia >> scom;
+       }
+}
+
+void SyncClient::readExactly(SyncTcpConnection::proto::socket & socket,size_t toread, std::iostream & result)
+{
+       size_t hasread = 0;
+       while (toread > hasread)
+       {
+                       //TODO read bigger buffers
+                       boost::array<char, 1> buf;
+                       boost::system::error_code error;
+                       size_t len = socket.read_some(boost::asio::buffer(buf), error);
+                       if (error == boost::asio::error::eof)
+                               break; // Connection closed cleanly by peer.
+                       else if (error)
+                               throw boost::system::system_error(error); // Some other error.
+                       //for (size_t pos=0; pos<len; pos++)
+                               result<<buf[0];
+                       hasread+=len;
+       }
+}
diff --git a/src/syncClient.h b/src/syncClient.h
new file mode 100644 (file)
index 0000000..08b3015
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _SYNCCLIENT_H
+#define _SYNCCLIENT_H
+
+#include <string>
+#include "syncTcpConnection.h"
+class SyncClient
+{
+public:
+       SyncClient(std::string hostname,std::string port);
+
+       void run();
+private:
+       void readAndProcess(SyncTcpConnection::proto::socket & socket);
+       void readExactly(SyncTcpConnection::proto::socket & socket,size_t toread, std::iostream &);
+       std::string hostname_;
+       std::string port_;
+};
+
+
+#endif // _SYNCSOCKET_H
diff --git a/src/syncCommand.cpp b/src/syncCommand.cpp
new file mode 100644 (file)
index 0000000..48bed3a
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "syncCommand.h"
+
+SyncCommand::SyncCommand(ConnectionList & cl )
+{      
+       scc_ = new SyncConnectionCommand(cl);
+       src_ = new SyncRouteCommand();
+}
+
+SyncCommand::SyncCommand(ConnectionList & cl, u_int16_t mux )
+{      
+       scc_ = new SyncConnectionCommand(cl,mux);
+       src_=NULL;
+}
+
+SyncCommand::SyncCommand(NetworkPrefix np )
+{      
+       scc_ = NULL;
+       src_ = new SyncRouteCommand(np);
+}
+
+SyncCommand::~SyncCommand()
+{
+       if (scc_)
+               delete scc_;
+       if (src_)
+               delete src_;
+}
diff --git a/src/syncCommand.h b/src/syncCommand.h
new file mode 100644 (file)
index 0000000..9f0ef2a
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _SYNCCOMMAND_H
+#define _SYNCCOMMAND_H
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/archive/text_iarchive.hpp>
+
+#include "connectionList.h"
+#include "threadUtils.hpp"
+#include "syncConnectionCommand.h"
+#include "syncRouteCommand.h"
+#include "networkPrefix.h"
+#include <string>
+
+class SyncCommand
+{
+public:
+       SyncCommand(ConnectionList & cl );
+       SyncCommand(ConnectionList & cl ,u_int16_t mux);
+       SyncCommand(NetworkPrefix);
+       ~SyncCommand();
+
+private:
+       SyncCommand(const SyncCommand &);
+       SyncConnectionCommand * scc_;
+       SyncRouteCommand * src_;
+  friend class boost::serialization::access;
+  template<class Archive>
+  void serialize(Archive & ar, const unsigned int version)
+  {
+               std::string syncstr;
+               if (scc_)
+               {
+                       syncstr = "connection";
+               }
+               if ( src_)
+               {
+                       syncstr = "route";
+               }
+    ar & syncstr;
+//             std::cout << "syncstr received " <<syncstr << std::endl;
+               if (syncstr == "connection")
+                       ar & *scc_;
+               if (syncstr == "route")
+                       ar & *src_;
+//             std::cout << "syncstr done " <<syncstr << std::endl;
+       }
+};
+
+
+#endif // _SYNCCOMMAND_H
diff --git a/src/syncConnectionCommand.cpp b/src/syncConnectionCommand.cpp
new file mode 100644 (file)
index 0000000..844f8bc
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "syncConnectionCommand.h"
+
+SyncConnectionCommand::SyncConnectionCommand(ConnectionList & cl )
+:cl_(cl)
+{      
+}
+
+SyncConnectionCommand::SyncConnectionCommand(ConnectionList & cl, u_int16_t mux )
+:cl_(cl),mux_(mux)
+{      
+}
+
+u_int16_t SyncConnectionCommand::getMux() const 
+{
+       return mux_;
+}
diff --git a/src/syncConnectionCommand.h b/src/syncConnectionCommand.h
new file mode 100644 (file)
index 0000000..5debf1f
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SYNCCONNECTIONCOMMAND_H
+#define _SYNCCONNECTIONCOMMAND_H
+
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/archive/text_iarchive.hpp>
+
+#include "connectionList.h"
+#include "threadUtils.hpp"
+
+class SyncConnectionCommand
+{
+public:
+       SyncConnectionCommand(ConnectionList & cl );
+       SyncConnectionCommand(ConnectionList & cl ,u_int16_t mux);
+       u_int16_t getMux() const;
+
+private:
+       SyncConnectionCommand(const SyncConnectionCommand &);
+       ConnectionList & cl_;
+       u_int16_t mux_;
+  friend class boost::serialization::access;
+  template<class Archive>
+  void serialize(Archive & ar, const unsigned int version)
+  {
+               Lock lock(cl_.getMutex());
+    ar & mux_;
+               ConnectionParam & conn = cl_.getOrNewConnectionUnlocked(mux_);
+               ar & conn;
+       }
+};
+
+
+#endif // _SYNCCOMMAND_H
diff --git a/src/syncOnConnect.hpp b/src/syncOnConnect.hpp
new file mode 100644 (file)
index 0000000..0b454e7
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+void syncOnConnect(SyncTcpConnection * connptr)
+{
+  //TODO Locking here  
+  ConnectionList & cl_(gConnectionList);
+  ConnectionMap::iterator cit = cl_.getBeginUnlocked();
+  for (;cit!=cl_.getEndUnlocked();++cit)
+  {
+    std::ostringstream sout;
+    boost::archive::text_oarchive oa(sout);
+    const SyncCommand scom(cl_,cit->first);
+    oa << scom;
+    std::stringstream lengthout;
+    lengthout << std::setw(5) << std::setfill('0') << sout.str().size()<< ' ';
+    connptr->Send(lengthout.str());
+    connptr->Send(sout.str());
+  }
+  //TODO Locking here  
+       network_address_type_t types[] = {ipv4,ipv6,ethernet};
+       for (int types_idx=0; types_idx<3; types_idx++)
+       {
+               network_address_type_t type = types[types_idx];
+               RoutingMap::iterator it = gRoutingTable.getBeginUnlocked(type);
+               for (;it!=gRoutingTable.getEndUnlocked(type);++it)
+               {
+                       NetworkPrefix tmp(it->first);
+                       std::ostringstream sout;
+                       boost::archive::text_oarchive oa(sout);
+                       const SyncCommand scom(tmp);
+                       oa << scom;
+                       std::stringstream lengthout;
+                       lengthout << std::setw(5) << std::setfill('0') << sout.str().size()<< ' ';
+                       connptr->Send(lengthout.str());
+                       connptr->Send(sout.str());
+               }
+       }
+}
+
diff --git a/src/syncQueue.cpp b/src/syncQueue.cpp
new file mode 100644 (file)
index 0000000..636107b
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "threadUtils.hpp"
+#include "datatypes.h"
+
+#include <sstream>
+#include <iostream>
+#include <string>
+
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/archive/text_iarchive.hpp>
+
+
+#include "syncQueue.h"
+
+SyncQueue* SyncQueue::inst = NULL;
+Mutex SyncQueue::instMutex;
+SyncQueue& gSyncQueue = SyncQueue::instance();
+
+
+SyncQueue& SyncQueue::instance()
+{
+  Lock lock(instMutex);
+  static instanceCleaner c;
+  if(!inst)
+    inst = new SyncQueue();
+
+  return *inst;
+}
+
+void SyncQueue::push(const SyncCommand & scom )
+{
+       std::ostringstream sout;
+       boost::archive::text_oarchive oa(sout);
+       oa << scom;
+
+  std::stringstream lengthout;
+  lengthout << std::setw(5) << std::setfill('0') << sout.str().size()<< ' ';
+       push(lengthout.str()+sout.str());
+}
+
+void SyncQueue::push(const std::string & str )
+{
+  Lock lock(mutex_);
+//     std::cout << "Debug" << std:endl;
+       if( syncServer_)
+         syncServer_->send(str);
+}
+
+void SyncQueue::setSyncServerPtr(SyncServer * ptr)
+{
+  Lock lock(mutex_);
+       syncServer_=ptr;
+}
+
+bool SyncQueue::empty()
+{
+  Lock lock(mutex_);
+       return 1;
+}
diff --git a/src/syncQueue.h b/src/syncQueue.h
new file mode 100644 (file)
index 0000000..5cb4f6e
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SYNC_QUEUE_H
+#define _SYNC_QUEUE_H
+
+#include <deque>
+#include <queue>
+
+#include "syncCommand.h"
+
+#include "threadUtils.hpp"
+#include "datatypes.h"
+#include "syncServer.h"
+
+class SyncQueue
+{
+public:
+       SyncQueue():syncServer_(NULL) {};
+       ~SyncQueue() {};
+  static SyncQueue& instance();
+       void setSyncServerPtr(SyncServer *);
+       void push(const std::string & );
+       void push(const SyncCommand & );
+       std::string pop();
+       bool empty();
+
+private:
+  static Mutex instMutex;
+       static SyncQueue* inst;
+  class instanceCleaner {
+    public: ~instanceCleaner() {
+     if(SyncQueue::inst != 0)
+       delete SyncQueue::inst;
+   }
+  };
+  SyncQueue(const SyncQueue &s);
+  void operator=(const SyncQueue &s);
+  Mutex mutex_;
+       SyncServer * syncServer_;
+};
+
+extern SyncQueue& gSyncQueue;
+
+#endif
diff --git a/src/syncRouteCommand.cpp b/src/syncRouteCommand.cpp
new file mode 100644 (file)
index 0000000..bcfb925
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include "syncRouteCommand.h"
+
+SyncRouteCommand::SyncRouteCommand()
+{      
+}
+
+SyncRouteCommand::SyncRouteCommand( const NetworkPrefix & addr )
+:addr_(addr)
+{      
+}
+
+
+NetworkPrefix SyncRouteCommand::getPrefix() const 
+{
+       return addr_;
+}
diff --git a/src/syncRouteCommand.h b/src/syncRouteCommand.h
new file mode 100644 (file)
index 0000000..5bef2f9
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#ifndef _SYNCROUTECOMMAND_H
+#define _SYNCROUTECOMMAND_H
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/archive/text_iarchive.hpp>
+
+#include "threadUtils.hpp"
+#include "networkPrefix.h"
+#include "routingTable.h"
+
+class SyncRouteCommand
+{
+public:
+       SyncRouteCommand(const NetworkPrefix & );
+       SyncRouteCommand();
+       NetworkPrefix getPrefix() const;
+
+private:
+       SyncRouteCommand(const SyncRouteCommand &);
+       u_int16_t count_;
+       NetworkPrefix addr_;
+  friend class boost::serialization::access;
+  template<class Archive>
+  void serialize(Archive & ar, const unsigned int version)
+  {
+               Lock lock(gRoutingTable.getMutex());
+               ar & addr_;
+//             u_int16_t & mux (gRoutingTable.getOrNewRoutingTEUnlocked(addr_));
+//             ar & mux;
+               ar & (*(gRoutingTable.getOrNewRoutingTEUnlocked(addr_)));
+               gRoutingTable.updateRouteTreeUnlocked(addr_);
+       };
+};
+
+
+#endif // _SYNCCOMMAND_H
diff --git a/src/syncServer.cpp b/src/syncServer.cpp
new file mode 100644 (file)
index 0000000..bd5120c
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "syncServer.h"
+#include "resolver.h"
+#include "log.h"
+
+//using asio::ip::tcp;
+
+SyncServer::SyncServer(std::string localaddr, std::string port, ConnectCallback onConnect) 
+  : acceptor_(io_service_), onConnect_(onConnect)
+{
+  gResolver.resolveTcp(localaddr, port, boost::bind(&SyncServer::onResolve, this, _1), boost::bind(&SyncServer::onResolvError, this, _1));
+}
+
+void SyncServer::onResolve(const SyncTcpConnection::proto::endpoint& e)
+{
+  acceptor_.open(e.protocol());
+  acceptor_.set_option(boost::asio::socket_base::reuse_address(true));
+  acceptor_.bind(e);
+  acceptor_.listen();
+  start_accept();
+  ready_sem_.up();
+  cLog.msg(Log::PRIO_NOTICE) << "sync server listening on " << e;
+}
+
+void SyncServer::onResolvError(const std::runtime_error& e)
+{
+  cLog.msg(Log::PRIO_ERROR) << "sync server bind/listen failed: " << e.what();
+      // TODO: stop daemon??
+}
+
+void SyncServer::run()
+{
+  ready_sem_.down();
+  io_service_.run();
+}
+
+void SyncServer::send(std::string message)
+{
+  Lock lock(mutex_);
+  for(std::list<SyncTcpConnection::pointer>::iterator it = conns_.begin() ;it != conns_.end(); ++it)
+    (*it)->Send(message);
+}
+
+void SyncServer::start_accept()
+{
+  Lock lock(mutex_);
+  SyncTcpConnection::pointer new_connection = SyncTcpConnection::create(acceptor_.io_service());
+  conns_.push_back(new_connection);
+  acceptor_.async_accept(new_connection->socket(),
+                         boost::bind(&SyncServer::handle_accept, this, new_connection, boost::asio::placeholders::error));
+}
+
+void SyncServer::handle_accept(SyncTcpConnection::pointer new_connection, const boost::system::error_code& error)
+{
+  if (!error) {
+    new_connection->onConnect = onConnect_;
+    new_connection->start();
+    start_accept();
+  }
+}
diff --git a/src/syncServer.h b/src/syncServer.h
new file mode 100644 (file)
index 0000000..138f46e
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SYNC_SERVER_H_
+#define _SYNC_SERVER_H_
+//#include <iostream>
+//#include <string>
+#include <boost/bind.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include <boost/function.hpp>
+#include "threadUtils.hpp"
+
+
+#include <boost/asio.hpp>
+#include <list>
+#include "syncTcpConnection.h"
+
+typedef boost::function<void (SyncTcpConnection *)> ConnectCallback;
+
+class SyncServer
+{
+public:
+  SyncServer(std::string localaddr, std::string port, ConnectCallback onConnect);
+  void onResolve(const SyncTcpConnection::proto::endpoint& e);
+  void onResolvError(const std::runtime_error& e);
+  
+  void run();
+  void send(std::string message);
+  
+  std::list<SyncTcpConnection::pointer> conns_;
+  
+private:
+  void start_accept();
+  void handle_accept(SyncTcpConnection::pointer new_connection, const boost::system::error_code& error);
+  
+  Mutex mutex_; //Mutex for list conns_
+  boost::asio::io_service io_service_;
+  SyncTcpConnection::proto::acceptor acceptor_;
+  ConnectCallback onConnect_;
+  Semaphore ready_sem_;
+};
+#endif
diff --git a/src/syncTcpConnection.cpp b/src/syncTcpConnection.cpp
new file mode 100644 (file)
index 0000000..17d3ddd
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "syncTcpConnection.h"
+#include <boost/bind.hpp>
+#include <boost/asio.hpp>
+
+#include <string>
+
+SyncTcpConnection::proto::socket& SyncTcpConnection::socket()
+{
+  return socket_;
+}
+
+void SyncTcpConnection::start()
+{
+  onConnect(this);
+}
+
+void SyncTcpConnection::Send(std::string message)
+{
+    boost::asio::async_write(socket_, boost::asio::buffer(message),
+        boost::bind(&SyncTcpConnection::handle_write, shared_from_this(),
+          boost::asio::placeholders::error,
+          boost::asio::placeholders::bytes_transferred));
+}
+SyncTcpConnection::SyncTcpConnection(boost::asio::io_service& io_service)
+       : socket_(io_service)
+{
+}
+
+void SyncTcpConnection::handle_write(const boost::system::error_code& /*error*/,
+               size_t /*bytes_transferred*/)
+{
+}
diff --git a/src/syncTcpConnection.h b/src/syncTcpConnection.h
new file mode 100644 (file)
index 0000000..4bf458f
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SYNCTCPCONNECTION_H_
+#define _SYNCTCPCONNECTION_H_
+#include <boost/shared_ptr.hpp>
+#include <boost/enable_shared_from_this.hpp>
+#include <boost/function.hpp>
+#include <boost/asio.hpp>
+
+#include <string>
+
+class SyncTcpConnection
+  : public boost::enable_shared_from_this<SyncTcpConnection>
+{
+public:
+  typedef boost::shared_ptr<SyncTcpConnection> pointer;
+  typedef boost::asio::ip::tcp proto;
+
+  static pointer create(boost::asio::io_service& io_service)
+       {
+          return pointer(new SyncTcpConnection(io_service));
+       };
+
+       boost::function<void(SyncTcpConnection *)> onConnect;
+  proto::socket& socket();
+
+  void start();
+       void Send(std::string message);
+private:
+  SyncTcpConnection(boost::asio::io_service& io_service);
+
+  void handle_write(const boost::system::error_code & /*error*/,
+      size_t /*bytes_transferred*/);
+  proto::socket socket_;
+};
+#endif
diff --git a/src/sysexec.hpp b/src/sysexec.hpp
new file mode 100644 (file)
index 0000000..90bde90
--- /dev/null
@@ -0,0 +1,74 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _SYSEXEC_HPP
+#define _SYSEXEC_HPP
+#ifndef NO_EXEC
+
+int execScript(std::string const& script, std::string const& ifname, std::string const& ifnode)
+{
+  pid_t pid;
+  pid = fork();
+  if(!pid) {
+    int fd;
+    for (fd=getdtablesize();fd>=0;--fd) // close all file descriptors
+      close(fd);
+
+    fd = open("/dev/null",O_RDWR);        // stdin
+    if(fd == -1)
+      cLog.msg(Log::PRIO_WARNING) << "can't open stdin";
+    else {
+      if(dup(fd) == -1)   // stdout
+        cLog.msg(Log::PRIO_WARNING) << "can't open stdout";
+      if(dup(fd) == -1)   // stderr
+        cLog.msg(Log::PRIO_WARNING) << "can't open stderr";
+    }
+    execl("/bin/sh", "/bin/sh", script.c_str(), ifname.c_str(), ifnode.c_str(), (char*)NULL);
+        // if execl return, an error occurred
+    cLog.msg(Log::PRIO_ERROR) << "error on executing script: " << AnytunErrno(errno);
+    return -1;
+  }
+  int status = 0;
+  waitpid(pid, &status, 0);
+  if(WIFEXITED(status))
+    cLog.msg(Log::PRIO_NOTICE) << "script '" << script << "' returned " << WEXITSTATUS(status);  
+  else if(WIFSIGNALED(status))
+    cLog.msg(Log::PRIO_NOTICE) << "script '" << script << "' terminated after signal " << WTERMSIG(status);
+  else
+    cLog.msg(Log::PRIO_ERROR) << "executing script: unkown error";
+
+  return status;
+}
+
+
+#endif
+#endif
+
diff --git a/src/threadUtils.hpp b/src/threadUtils.hpp
new file mode 100644 (file)
index 0000000..85500c1
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+#include <boost/thread.hpp>
+#include <boost/thread/mutex.hpp>
+#include <boost/thread/shared_mutex.hpp>
+#include "datatypes.h"
+#ifndef __THREADUTILS__
+#define __THREADUTILS__
+typedef boost::mutex::scoped_lock Lock;
+typedef boost::mutex Mutex;
+
+typedef boost::shared_mutex SharedMutex;
+typedef boost::shared_lock<SharedMutex> ReadersLock;
+typedef boost::unique_lock<SharedMutex> WritersLock;
+
+class Semaphore
+{
+public:
+  Semaphore(unsigned int initVal=0)
+    :count_(initVal){};
+  void up()
+  {
+     boost::mutex::scoped_lock lock(mutex_);
+     count_++;
+     lock.unlock();
+     cond_.notify_one();
+  }
+  void down()
+  {
+     boost::mutex::scoped_lock lock(mutex_);
+     while (count_ <= 0)
+       cond_.wait(lock);
+     count_--;
+  }
+private:
+  boost::mutex mutex_;
+  boost::condition cond_;
+  int16_t count_;
+};
+
+#endif
diff --git a/src/tunDevice.h b/src/tunDevice.h
new file mode 100644 (file)
index 0000000..f37016d
--- /dev/null
@@ -0,0 +1,98 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _TUNDEVICE_H_
+#define _TUNDEVICE_H_
+
+#include "buffer.h"
+#include "deviceConfig.hpp"
+#include "threadUtils.hpp"
+
+#ifdef _MSC_VER
+#include <windows.h>
+#endif
+
+class TunDevice
+{
+public:
+  TunDevice(std::string dev,std::string dev_type, std::string ifcfg_addr, u_int16_t ifcfg_prefix);
+  ~TunDevice();
+  
+  int read(u_int8_t* buf, u_int32_t len);
+  int write(u_int8_t* buf, u_int32_t len);
+
+  const char* getActualName() const { return actual_name_.c_str(); }
+  const char* getActualNode() const { return actual_node_.c_str(); }
+  device_type_t getType() const { return conf_.type_; } 
+  const char* getTypeString() const
+  {
+#ifndef _MSC_VER
+    if(fd_ < 0)
+#else
+    if(handle_ == INVALID_HANDLE_VALUE)
+#endif
+      return "";
+    
+    switch(conf_.type_)
+    {
+    case TYPE_UNDEF: return "undef"; break;
+    case TYPE_TUN: return "tun"; break;
+    case TYPE_TAP: return "tap"; break;
+    }
+    return "";
+  }
+
+
+private:
+  void operator=(const TunDevice &src);
+  TunDevice(const TunDevice &src);
+
+  void init_post();
+  void do_ifconfig();
+  int fix_return(int ret, size_t pi_length) const;
+
+#ifndef _MSC_VER
+  int fd_;
+#else
+  bool getAdapter(std::string const& dev_name);
+  DWORD performIoControl(DWORD controlCode, LPVOID inBuffer, DWORD inBufferSize,
+                        LPVOID outBuffer, DWORD outBufferSize);
+  HANDLE handle_;
+  OVERLAPPED roverlapped_, woverlapped_;
+#endif
+
+  DeviceConfig conf_;
+  bool with_pi_;
+  std::string actual_name_;
+  std::string actual_node_;
+};
+
+#endif
diff --git a/src/win32/#winService.cpp# b/src/win32/#winService.cpp#
new file mode 100644 (file)
index 0000000..5406c2d
--- /dev/null
@@ -0,0 +1,212 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef WIN_SERVICE
+
+#include <iostream>
+
+#include <windows.h>
+
+#include "winService.h"
+#include "../log.h"
+#include "../anytunError.h"
+#include "../threadUtils.hpp"
+
+WinService* WinService::inst = NULL;
+Mutex WinService::instMutex;
+WinService& gWinService = WinService::instance();
+
+WinService& WinService::instance()
+{
+       Lock lock(instMutex);
+       static instanceCleaner c;
+       if(!inst)
+               inst = new WinService();
+       
+       return *inst;
+}
+
+WinService::~WinService()
+{
+  if(started_)
+    CloseHandle(stop_event_);
+}
+
+void WinService::install()
+{
+  SC_HANDLE schSCManager;
+  SC_HANDLE schService;
+  char szPath[MAX_PATH];
+
+  if(!GetModuleFileNameA(NULL, szPath, MAX_PATH))
+    AnytunError::throwErr() << "Error on GetModuleFileName: " << AnytunErrno(GetLastError());
+
+  schSCManager = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
+  if(NULL == schSCManager)
+    AnytunError::throwErr() << "Error on OpenSCManager: " << AnytunErrno(GetLastError());
+
+  schService = CreateServiceA(schSCManager, SVC_NAME, SVC_NAME, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, 
+                              SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, szPath, NULL, NULL, NULL, NULL, NULL);
+  if(schService == NULL) {
+    CloseServiceHandle(schSCManager);
+    AnytunError::throwErr() << "Error on CreateService: " << AnytunErrno(GetLastError());
+  }
+
+  std::cout << "Service installed successfully" << std::endl; 
+
+  CloseServiceHandle(schService); 
+  CloseServiceHandle(schSCManager);
+}
+
+void WinService::uninstall()
+{
+  SC_HANDLE schSCManager;
+  SC_HANDLE schService;
+
+  schSCManager = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);
+  if(NULL == schSCManager)
+    AnytunError::throwErr() << "Error on OpenSCManager: " << AnytunErrno(GetLastError());
+
+  schService = OpenServiceA(schSCManager, SVC_NAME, SERVICE_ALL_ACCESS);
+  if(schService == NULL) {
+    CloseServiceHandle(schSCManager);
+    AnytunError::throwErr() << "Error on CreateService: " << AnytunErrno(GetLastError());
+  }
+
+  if(!DeleteService(schService)) {
+    CloseServiceHandle(schService); 
+    CloseServiceHandle(schSCManager);
+    AnytunError::throwErr() << "Error on DeleteService: " << AnytunErrno(GetLastError());
+  }
+
+  std::cout << "Service uninstalled successfully" << std::endl; 
+
+  CloseServiceHandle(schService); 
+  CloseServiceHandle(schSCManager);
+}
+
+void WinService::start()
+{
+  SERVICE_TABLE_ENTRY DispatchTable[] = {
+    {SVC_NAME, (LPSERVICE_MAIN_FUNCTION)WinService::main },
+    {NULL, NULL}
+  };
+
+  if(!StartServiceCtrlDispatcherA(DispatchTable))
+    AnytunError::throwErr() << "Error on StartServiceCtrlDispatcher: " << AnytunErrno(GetLastError());
+}
+
+void WinService::waitForStop()
+{
+  if(!started_)
+    AnytunError::throwErr() << "Service not started correctly";
+  
+  reportStatus(SERVICE_RUNNING, NO_ERROR);
+  WaitForSingleObject(stop_event_, INFINITE);
+  reportStatus(SERVICE_STOP_PENDING, NO_ERROR);
+  cLog.msg(Log::PRIO_NOTICE) << "WinService received stop signal, exitting";
+}
+
+void WinService::stop()
+{
+  if(!started_)
+    AnytunError::throwErr() << "Service not started correctly";
+
+  reportStatus(SERVICE_STOPPED, NO_ERROR);
+}
+
+int real_main(int argc, char* argv[]);
+
+VOID WINAPI WinService::main(DWORD dwArgc, LPTSTR *lpszArgv)
+{
+  if(gWinService.started_) {
+    cLog.msg(Log::PRIO_ERROR) << "Service is already running";
+    return;
+  }
+
+  gWinService.status_handle_ = RegisterServiceCtrlHandlerA(SVC_NAME, WinService::ctrlHandler);
+  if(!gWinService.status_handle_) { 
+    cLog.msg(Log::PRIO_ERROR) << "Error on RegisterServiceCtrlHandler: " << AnytunErrno(GetLastError());
+    return;
+  }
+  gWinService.status_.dwServiceType = SERVICE_WIN32_OWN_PROCESS; 
+  gWinService.status_.dwServiceSpecificExitCode = 0;    
+  gWinService.reportStatus(SERVICE_START_PENDING, NO_ERROR);
+  gWinService.started_ = true;
+  
+  gWinService.stop_event_ = CreateEvent(NULL, true, false, NULL);
+  if(!gWinService.stop_event_) {
+    cLog.msg(Log::PRIO_ERROR) << "WinService Error on CreateEvent: " << AnytunErrno(GetLastError());
+    gWinService.reportStatus(SERVICE_STOPPED, -1);
+    return;
+  }
+
+  real_main(dwArgc, lpszArgv);
+}
+
+VOID WINAPI WinService::ctrlHandler(DWORD dwCtrl)
+{
+  switch(dwCtrl) {
+    case SERVICE_CONTROL_STOP: {
+      gWinService.reportStatus(SERVICE_STOP_PENDING, NO_ERROR);
+      SetEvent(gWinService.stop_event_);
+      return;
+    }
+    case SERVICE_CONTROL_INTERROGATE: break;
+    default: break;
+  }
+  gWinService.reportStatus(gWinService.status_.dwCurrentState, NO_ERROR);
+}
+
+void WinService::reportStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint)
+{
+  static DWORD dwCheckPoint = 1;
+
+  status_.dwCurrentState = dwCurrentState;
+  status_.dwWin32ExitCode = dwWin32ExitCode;
+  status_.dwWaitHint = dwWaitHint;
+
+  if((dwCurrentState == SERVICE_START_PENDING) ||
+     (dwCurrentState == SERVICE_STOP_PENDING))
+    status_.dwControlsAccepted = 0;
+  else 
+    status_.dwControlsAccepted = SERVICE_ACCEPT_STOP;
+
+  if((dwCurrentState == SERVICE_RUNNING) ||
+     (dwCurrentState == SERVICE_STOPPED))
+    status_.dwCheckPoint = 0;
+  else
+    status_.dwCheckPoint = dwCheckPoint++;
+
+  SetServiceStatus(status_handle_, &status_);
+}
+
+#endif
diff --git a/src/win32/common.h b/src/win32/common.h
new file mode 100644 (file)
index 0000000..3c183c2
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ *  TAP-Win32 -- A kernel driver to provide virtual tap device functionality
+ *               on Windows.  Originally derived from the CIPE-Win32
+ *               project by Damion K. Wilson, with extensive modifications by
+ *               James Yonan.
+ *
+ *  All source code which derives from the CIPE-Win32 project is
+ *  Copyright (C) Damion K. Wilson, 2003, and is released under the
+ *  GPL version 2 (see below).
+ *
+ *  All other source code is Copyright (C) 2002-2005 OpenVPN Solutions LLC,
+ *  and is released under the GPL version 2 (see below).
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2
+ *  as published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program (see the file COPYING included with this
+ *  distribution); if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+//===============================================
+// This file is included both by OpenVPN and
+// the TAP-Win32 driver and contains definitions
+// common to both.
+//===============================================
+
+//=============
+// TAP IOCTLs
+//=============
+
+#define TAP_CONTROL_CODE(request,method) \
+  CTL_CODE (FILE_DEVICE_UNKNOWN, request, method, FILE_ANY_ACCESS)
+
+// Present in 8.1
+
+#define TAP_IOCTL_GET_MAC               TAP_CONTROL_CODE (1, METHOD_BUFFERED)
+#define TAP_IOCTL_GET_VERSION           TAP_CONTROL_CODE (2, METHOD_BUFFERED)
+#define TAP_IOCTL_GET_MTU               TAP_CONTROL_CODE (3, METHOD_BUFFERED)
+#define TAP_IOCTL_GET_INFO              TAP_CONTROL_CODE (4, 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_IOCTL_CONFIG_DHCP_MASQ      TAP_CONTROL_CODE (7, METHOD_BUFFERED)
+#define TAP_IOCTL_GET_LOG_LINE          TAP_CONTROL_CODE (8, METHOD_BUFFERED)
+#define TAP_IOCTL_CONFIG_DHCP_SET_OPT   TAP_CONTROL_CODE (9, METHOD_BUFFERED)
+
+// Added in 8.2
+
+/* obsoletes TAP_IOCTL_CONFIG_POINT_TO_POINT */
+#define TAP_IOCTL_CONFIG_TUN            TAP_CONTROL_CODE (10, METHOD_BUFFERED)
+
+//=================
+// Registry keys
+//=================
+
+#define ADAPTER_KEY "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}"
+
+#define NETWORK_CONNECTIONS_KEY "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}"
+
+//======================
+// Filesystem prefixes
+//======================
+
+#define USERMODEDEVICEDIR "\\\\.\\Global\\"
+#define SYSDEVICEDIR      "\\Device\\"
+#define USERDEVICEDIR     "\\DosDevices\\Global\\"
+#define TAPSUFFIX         ".tap"
+
+//=========================================================
+// TAP_COMPONENT_ID -- This string defines the TAP driver
+// type -- different component IDs can reside in the system
+// simultaneously.
+//=========================================================
+
+#define TAP_COMPONENT_ID "tap0801"
diff --git a/src/win32/registryKey.cpp b/src/win32/registryKey.cpp
new file mode 100644 (file)
index 0000000..a6858e9
--- /dev/null
@@ -0,0 +1,121 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <string.h>
+#include <sstream>
+#include <windows.h>
+
+#include "registryKey.h"
+
+#include "../anytunError.h"
+
+RegistryKey::RegistryKey() : opened_(false)
+{
+}
+
+RegistryKey::RegistryKey(HKEY hkey, std::string subKey, REGSAM samDesired) : opened_(false)
+{
+  open(hkey, subKey, samDesired);
+}
+
+RegistryKey::~RegistryKey()
+{
+  close();
+}
+
+bool RegistryKey::isOpen() const
+{
+  return opened_;
+}
+
+std::string RegistryKey::getName() const
+{
+  return name_;
+}
+
+DWORD RegistryKey::open(HKEY hkey, std::string subKey, REGSAM samDesired)
+{
+  if(opened_)
+    RegCloseKey(key_);
+
+  opened_ = false;
+  name_ = "";
+  LONG err = RegOpenKeyExA(hkey, subKey.c_str(), 0, samDesired, &key_);
+  if(err != ERROR_SUCCESS)
+    return err;
+
+  name_ = subKey;
+  opened_ = true;
+  return ERROR_SUCCESS;
+}
+
+void RegistryKey::close()
+{
+  if(opened_)
+    RegCloseKey(key_);
+  opened_ = false;
+}
+
+std::string RegistryKey::operator[](std::string const& name) const
+{
+  if(!opened_)
+    throw AnytunErrno(ERROR_INVALID_HANDLE);
+
+  char value[STRING_VALUE_LENGTH];
+  DWORD len = sizeof(value);
+  LONG err = RegQueryValueExA(key_, name.c_str(), NULL, NULL, (LPBYTE)value, &len);
+  if(err != ERROR_SUCCESS)
+    throw AnytunErrno(err);
+
+  if(value[len-1] != 0) {
+    if(len < sizeof(value))
+      value[len++] = 0;
+    else
+      throw AnytunErrno(ERROR_INSUFFICIENT_BUFFER);
+  }  
+  return std::string(value);
+}
+
+DWORD RegistryKey::getSubKey(DWORD index, RegistryKey& subKey, REGSAM sam) const
+{
+  char subkeyname[NAME_LENGTH];
+  DWORD len = sizeof(subkeyname);
+  DWORD err = RegEnumKeyExA(key_, index, subkeyname, &len, NULL, NULL, NULL, NULL);
+  if(err != ERROR_SUCCESS)
+    return err;
+
+  return subKey.open(key_, subkeyname, sam);
+}
+
+DWORD RegistryKey::getSubKey(std::string name, RegistryKey& subKey, REGSAM sam) const
+{
+  return subKey.open(key_, name.c_str(), sam);
+}
diff --git a/src/win32/registryKey.h b/src/win32/registryKey.h
new file mode 100644 (file)
index 0000000..ce79d47
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <string.h>
+#include <windows.h>
+
+class RegistryKey
+{
+public: 
+  #define NAME_LENGTH 256
+  #define STRING_VALUE_LENGTH 256
+
+  RegistryKey();
+  RegistryKey(HKEY hkey, std::string subKey, REGSAM samDesired);
+  ~RegistryKey();
+
+  bool isOpen() const;
+  std::string getName() const;
+  DWORD open(HKEY hkey, std::string subKey, REGSAM samDesired);
+  void close();
+  DWORD getSubKey(DWORD index, RegistryKey& subKey, REGSAM sam) const;
+  DWORD getSubKey(std::string name, RegistryKey& subKey, REGSAM sam) const;
+  std::string operator[](std::string const& name) const;
+
+private:
+  HKEY key_;
+  bool opened_;
+  std::string name_;
+};
\ No newline at end of file
diff --git a/src/win32/tunDevice.cpp b/src/win32/tunDevice.cpp
new file mode 100644 (file)
index 0000000..1087092
--- /dev/null
@@ -0,0 +1,271 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <string.h>
+#include <sstream>
+#include <windows.h>
+#include <winioctl.h>
+
+#include "../endian.h"
+#include "../tunDevice.h"
+#include "../threadUtils.hpp"
+#include "../log.h"
+#include "../anytunError.h"
+
+#include "registryKey.h"
+#include "common.h"
+
+#define MIN_TAP_VER_MAJOR 8
+#define MIN_TAP_VER_MINOR 2
+
+TunDevice::TunDevice(std::string dev_name, std::string dev_type, std::string ifcfg_addr, u_int16_t ifcfg_prefix) : conf_(dev_name, dev_type, ifcfg_addr, ifcfg_prefix, 1400)
+{
+  if(conf_.type_ != TYPE_TUN && conf_.type_ != TYPE_TAP)
+    AnytunError::throwErr() << "unable to recognize type of device (tun or tap)";
+
+  handle_ = INVALID_HANDLE_VALUE;
+  if(!getAdapter(dev_name))
+    AnytunError::throwErr() << "can't find any suitable device";
+
+  if(handle_ == INVALID_HANDLE_VALUE) {
+    std::stringstream tapname;
+         tapname << USERMODEDEVICEDIR << actual_node_ << TAPSUFFIX;
+    handle_ = CreateFileA(tapname.str().c_str(), GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0);
+    if(handle_ == INVALID_HANDLE_VALUE)
+      AnytunError::throwErr() << "Unable to open device: " << actual_node_ << " (" << actual_name_ << "): " << AnytunErrno(GetLastError());
+  }
+
+  DWORD err;
+  u_long info[3];
+  info[0] = info[1] = info[2] = 0;
+  err = performIoControl(TAP_IOCTL_GET_VERSION, info, sizeof(info), info, sizeof(info));
+  if(err != ERROR_SUCCESS) {
+    CloseHandle(handle_);
+    AnytunError::throwErr() << "Unable to get device version: " << AnytunErrno(err);
+  }
+  cLog.msg(Log::PRIO_NOTICE) << "Windows TAP Driver Version " << info[0] << "." << info[1] << " " << (info[2] ? "(DEBUG)" : "");
+  if(!(info[0] > MIN_TAP_VER_MAJOR || (info[0] == MIN_TAP_VER_MAJOR && info[1] >= MIN_TAP_VER_MINOR))) {
+    CloseHandle(handle_);
+    AnytunError::throwErr() << "need a higher Version of TAP Driver (at least " << MIN_TAP_VER_MAJOR << "." << MIN_TAP_VER_MINOR << ")";
+  }
+
+  if(conf_.type_ == TYPE_TUN) {
+    u_long ep[3];
+    ep[0] = htonl(conf_.addr_.getNetworkAddressV4().to_ulong());
+    ep[1] = htonl(conf_.addr_.getNetworkAddressV4().to_ulong() & conf_.netmask_.getNetworkAddressV4().to_ulong());
+    ep[2] = htonl(conf_.netmask_.getNetworkAddressV4().to_ulong());
+    err = performIoControl(TAP_IOCTL_CONFIG_TUN, ep, sizeof(ep), ep, sizeof(ep));
+    if(err != ERROR_SUCCESS) {
+      CloseHandle(handle_);
+      AnytunError::throwErr() << "Unable to set device tun mode: " << AnytunErrno(err);
+    }
+  }
+
+  if(ifcfg_addr != "")
+    do_ifconfig();
+
+  int status = true;
+  err = performIoControl(TAP_IOCTL_SET_MEDIA_STATUS, &status, sizeof(status), &status, sizeof(status));
+  if(err != ERROR_SUCCESS) {
+    CloseHandle(handle_);
+    AnytunError::throwErr() << "Unable to set device media status: " << AnytunErrno(err);
+       }
+
+  roverlapped_.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+  woverlapped_.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+}
+
+bool TunDevice::getAdapter(std::string const& dev_name)
+{
+  RegistryKey akey;
+  DWORD err = akey.open(HKEY_LOCAL_MACHINE, ADAPTER_KEY, KEY_ENUMERATE_SUB_KEYS);
+  if(err != ERROR_SUCCESS)
+    AnytunError::throwErr() << "Unable to open registry key (HKLM\\" << ADAPTER_KEY << "): " << AnytunErrno(err);
+  
+  bool found = false;
+  for(int i=0; ; ++i) {
+    RegistryKey ckey;
+    DWORD err = akey.getSubKey(i, ckey, KEY_QUERY_VALUE);
+    if(err == ERROR_NO_MORE_ITEMS)
+      break;
+    if(err != ERROR_SUCCESS)
+      continue;
+
+    try {
+         if(ckey["ComponentId"] != TAP_COMPONENT_ID)
+        continue;
+      actual_node_ = ckey["NetCfgInstanceId"];
+
+      RegistryKey nkey;
+      std::stringstream keyname;
+      keyname << NETWORK_CONNECTIONS_KEY << "\\" << actual_node_ << "\\Connection";
+      err = nkey.open(HKEY_LOCAL_MACHINE, keyname.str().c_str(), KEY_QUERY_VALUE);;
+      if(err != ERROR_SUCCESS)
+        continue;
+         
+         actual_name_ = nkey["Name"];
+       } catch(AnytunErrno&) { continue; }
+
+    if(dev_name != "") {
+      if(dev_name == actual_name_) {
+        found = true;
+        break;
+      }
+    }
+    else {
+      std::stringstream tapname;
+      tapname << USERMODEDEVICEDIR << actual_node_ << TAPSUFFIX;
+      handle_ = CreateFileA(tapname.str().c_str(), GENERIC_WRITE | GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0);
+      if(handle_ == INVALID_HANDLE_VALUE)
+        continue;
+      found = true;
+      break;
+    }
+  }
+  if(!found) {
+    actual_node_ = "";
+    actual_name_ = "";
+  }
+  return found;
+}
+
+DWORD TunDevice::performIoControl(DWORD controlCode, LPVOID inBuffer, DWORD inBufferSize, LPVOID outBuffer, DWORD outBufferSize)
+{
+  OVERLAPPED overlapped;
+  overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+  overlapped.Offset = 0;
+       overlapped.OffsetHigh = 0;
+  
+  DWORD len;
+  if(!DeviceIoControl(handle_, controlCode, inBuffer, inBufferSize, outBuffer, outBufferSize, &len, &overlapped)) {
+    DWORD err = GetLastError();
+    if(err == ERROR_IO_PENDING) {
+      WaitForSingleObject(overlapped.hEvent, INFINITE);
+      if(!GetOverlappedResult(handle_, &overlapped, &len, FALSE))
+        return GetLastError();
+    }
+    else
+      return GetLastError();
+  }
+  return ERROR_SUCCESS;
+}
+
+
+TunDevice::~TunDevice()
+{
+  if(handle_ != INVALID_HANDLE_VALUE)
+    CloseHandle(handle_);
+  if(roverlapped_.hEvent != INVALID_HANDLE_VALUE)
+    CloseHandle(roverlapped_.hEvent);
+  if(woverlapped_.hEvent != INVALID_HANDLE_VALUE)
+    CloseHandle(woverlapped_.hEvent);
+}
+
+int TunDevice::fix_return(int ret, size_t pi_length) const
+{
+// nothing to be done here
+       return 0;
+}
+
+int TunDevice::read(u_int8_t* buf, u_int32_t len)
+{
+  DWORD lenout;
+  roverlapped_.Offset = 0;
+       roverlapped_.OffsetHigh = 0;
+  ResetEvent(roverlapped_.hEvent);
+  
+  if(!ReadFile(handle_, buf, len, &lenout, &roverlapped_)) {
+    DWORD err = GetLastError();
+    if(err == ERROR_IO_PENDING) {
+      WaitForSingleObject(roverlapped_.hEvent, INFINITE);
+      if(!GetOverlappedResult(handle_, &roverlapped_, &lenout, FALSE)) {
+        cLog.msg(Log::PRIO_ERROR) << "Error while trying to get overlapped result: " << AnytunErrno(GetLastError());
+        return -1;
+      }
+    }
+    else {
+      cLog.msg(Log::PRIO_ERROR) << "Error while reading from device: " << AnytunErrno(GetLastError());
+      return -1;
+    }
+  }
+  return lenout;
+}
+
+int TunDevice::write(u_int8_t* buf, u_int32_t len)
+{
+  DWORD lenout;
+  woverlapped_.Offset = 0;
+       woverlapped_.OffsetHigh = 0;
+  ResetEvent(woverlapped_.hEvent);
+
+       if(!WriteFile(handle_, buf, len, &lenout, &woverlapped_)) {
+    DWORD err = GetLastError();
+    if(err == ERROR_IO_PENDING) {
+      WaitForSingleObject(woverlapped_.hEvent, INFINITE);
+      if(!GetOverlappedResult(handle_, &woverlapped_, &lenout, FALSE)) {
+        cLog.msg(Log::PRIO_ERROR) << "Error while trying to get overlapped result: " << AnytunErrno(GetLastError());
+        return -1;
+      }
+    }
+    else {
+      cLog.msg(Log::PRIO_ERROR) << "Error while writing to device: " << AnytunErrno(GetLastError());
+      return -1;
+    }
+  }
+  return lenout;       
+}
+
+void TunDevice::init_post()
+{
+// nothing to be done here
+}
+
+void TunDevice::do_ifconfig()
+{
+  u_long ep[4];
+  ep[0] = htonl(conf_.addr_.getNetworkAddressV4().to_ulong());
+  ep[1] = htonl(conf_.netmask_.getNetworkAddressV4().to_ulong());
+  ep[2] = htonl(conf_.addr_.getNetworkAddressV4().to_ulong() & conf_.netmask_.getNetworkAddressV4().to_ulong());
+  ep[3] = 365 * 24 * 3600;  // lease time in seconds
+  DWORD err = performIoControl(TAP_IOCTL_CONFIG_DHCP_MASQ, ep, sizeof(ep), ep, sizeof(ep));
+  if(err != ERROR_SUCCESS) {
+    CloseHandle(handle_);
+    AnytunError::throwErr() << "Unable to set device dhcp masq mode: " << AnytunErrno(err);
+       }
+
+  u_long mtu;
+  err = performIoControl(TAP_IOCTL_GET_MTU, &mtu, sizeof(mtu), &mtu, sizeof(mtu));
+  if(err != ERROR_SUCCESS) {
+    CloseHandle(handle_);
+    AnytunError::throwErr() << "Unable to get device mtu: " << AnytunErrno(err);
+       }
+  conf_.mtu_ = static_cast<u_int16_t>(mtu);
+}
diff --git a/src/win32/winService.cpp b/src/win32/winService.cpp
new file mode 100644 (file)
index 0000000..b6ea67f
--- /dev/null
@@ -0,0 +1,212 @@
+/*\r
+ *  anytun\r
+ *\r
+ *  The secure anycast tunneling protocol (satp) defines a protocol used\r
+ *  for communication between any combination of unicast and anycast\r
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel\r
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.\r
+ *  ethernet, ip, arp ...). satp directly includes cryptography and\r
+ *  message authentication based on the methodes used by SRTP.  It is\r
+ *  intended to deliver a generic, scaleable and secure solution for\r
+ *  tunneling and relaying of packets of any protocol.\r
+ *\r
+ *\r
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, \r
+ *                          Christian Pointner <satp@wirdorange.org>\r
+ *\r
+ *  This file is part of Anytun.\r
+ *\r
+ *  Anytun is free software: you can redistribute it and/or modify\r
+ *  it under the terms of the GNU General Public License version 3 as\r
+ *  published by the Free Software Foundation.\r
+ *\r
+ *  Anytun is distributed in the hope that it will be useful,\r
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ *  GNU General Public License for more details.\r
+ *\r
+ *  You should have received a copy of the GNU General Public License\r
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.\r
+ */\r
+\r
+#ifdef WIN_SERVICE\r
+\r
+#include <iostream>\r
+\r
+#include <windows.h>\r
+\r
+#include "winService.h"\r
+#include "../log.h"\r
+#include "../anytunError.h"\r
+#include "../threadUtils.hpp"\r
+\r
+WinService* WinService::inst = NULL;\r
+Mutex WinService::instMutex;\r
+WinService& gWinService = WinService::instance();\r
+\r
+WinService& WinService::instance()\r
+{\r
+       Lock lock(instMutex);\r
+       static instanceCleaner c;\r
+       if(!inst)\r
+               inst = new WinService();\r
+       \r
+       return *inst;\r
+}\r
+\r
+WinService::~WinService()\r
+{\r
+  if(started_)\r
+    CloseHandle(stop_event_);\r
+}\r
+\r
+void WinService::install()\r
+{\r
+  SC_HANDLE schSCManager;\r
+  SC_HANDLE schService;\r
+  char szPath[MAX_PATH];\r
+\r
+  if(!GetModuleFileNameA(NULL, szPath, MAX_PATH))\r
+    AnytunError::throwErr() << "Error on GetModuleFileName: " << AnytunErrno(GetLastError());\r
+\r
+  schSCManager = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);\r
+  if(NULL == schSCManager)\r
+    AnytunError::throwErr() << "Error on OpenSCManager: " << AnytunErrno(GetLastError());\r
+\r
+  schService = CreateServiceA(schSCManager, SVC_NAME, SVC_NAME, SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, \r
+                              SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, szPath, NULL, NULL, NULL, NULL, NULL);\r
+  if(schService == NULL) {\r
+    CloseServiceHandle(schSCManager);\r
+    AnytunError::throwErr() << "Error on CreateService: " << AnytunErrno(GetLastError());\r
+  }\r
+\r
+  std::cout << "Service installed successfully" << std::endl; \r
+\r
+  CloseServiceHandle(schService); \r
+  CloseServiceHandle(schSCManager);\r
+}\r
+\r
+void WinService::uninstall()\r
+{\r
+  SC_HANDLE schSCManager;\r
+  SC_HANDLE schService;\r
+\r
+  schSCManager = OpenSCManagerA(NULL, NULL, SC_MANAGER_ALL_ACCESS);\r
+  if(NULL == schSCManager)\r
+    AnytunError::throwErr() << "Error on OpenSCManager: " << AnytunErrno(GetLastError());\r
+\r
+  schService = OpenServiceA(schSCManager, SVC_NAME, SERVICE_ALL_ACCESS);\r
+  if(schService == NULL) {\r
+    CloseServiceHandle(schSCManager);\r
+    AnytunError::throwErr() << "Error on CreateService: " << AnytunErrno(GetLastError());\r
+  }\r
+\r
+  if(!DeleteService(schService)) {\r
+    CloseServiceHandle(schService); \r
+    CloseServiceHandle(schSCManager);\r
+    AnytunError::throwErr() << "Error on DeleteService: " << AnytunErrno(GetLastError());\r
+  }\r
+\r
+  std::cout << "Service uninstalled successfully" << std::endl; \r
+\r
+  CloseServiceHandle(schService); \r
+  CloseServiceHandle(schSCManager);\r
+}\r
+\r
+void WinService::start()\r
+{\r
+  SERVICE_TABLE_ENTRY DispatchTable[] = {\r
+    {SVC_NAME, (LPSERVICE_MAIN_FUNCTION)WinService::main },\r
+    {NULL, NULL}\r
+  };\r
+\r
+  if(!StartServiceCtrlDispatcherA(DispatchTable))\r
+    AnytunError::throwErr() << "Error on StartServiceCtrlDispatcher: " << AnytunErrno(GetLastError());\r
+}\r
+\r
+void WinService::waitForStop()\r
+{\r
+  if(!started_)\r
+    AnytunError::throwErr() << "Service not started correctly";\r
+  \r
+  reportStatus(SERVICE_RUNNING, NO_ERROR);\r
+  WaitForSingleObject(stop_event_, INFINITE);\r
+  reportStatus(SERVICE_STOP_PENDING, NO_ERROR);\r
+  cLog.msg(Log::PRIO_NOTICE) << "WinService received stop signal, exitting";\r
+}\r
+\r
+void WinService::stop()\r
+{\r
+  if(!started_)\r
+    AnytunError::throwErr() << "Service not started correctly";\r
+\r
+  reportStatus(SERVICE_STOPPED, NO_ERROR);\r
+}\r
+\r
+int real_main(int argc, char* argv[]);\r
+\r
+VOID WINAPI WinService::main(DWORD dwArgc, LPTSTR *lpszArgv)\r
+{\r
+  if(gWinService.started_) {\r
+    cLog.msg(Log::PRIO_ERROR) << "Service is already running";\r
+    return;\r
+  }\r
+\r
+  gWinService.status_handle_ = RegisterServiceCtrlHandlerA(SVC_NAME, WinService::ctrlHandler);\r
+  if(!gWinService.status_handle_) { \r
+    cLog.msg(Log::PRIO_ERROR) << "Error on RegisterServiceCtrlHandler: " << AnytunErrno(GetLastError());\r
+    return;\r
+  }\r
+  gWinService.status_.dwServiceType = SERVICE_WIN32_OWN_PROCESS; \r
+  gWinService.status_.dwServiceSpecificExitCode = 0;    \r
+  gWinService.reportStatus(SERVICE_START_PENDING, NO_ERROR);\r
+  gWinService.started_ = true;\r
+  \r
+  gWinService.stop_event_ = CreateEvent(NULL, true, false, NULL);\r
+  if(!gWinService.stop_event_) {\r
+    cLog.msg(Log::PRIO_ERROR) << "WinService Error on CreateEvent: " << AnytunErrno(GetLastError());\r
+    gWinService.reportStatus(SERVICE_STOPPED, -1);\r
+    return;\r
+  }\r
+\r
+  real_main(dwArgc, lpszArgv);\r
+}\r
+\r
+VOID WINAPI WinService::ctrlHandler(DWORD dwCtrl)\r
+{\r
+  switch(dwCtrl) {\r
+    case SERVICE_CONTROL_STOP: {\r
+      gWinService.reportStatus(SERVICE_STOP_PENDING, NO_ERROR);\r
+      SetEvent(gWinService.stop_event_);\r
+      return;\r
+    }\r
+    case SERVICE_CONTROL_INTERROGATE: break;\r
+    default: break;\r
+  }\r
+  gWinService.reportStatus(gWinService.status_.dwCurrentState, NO_ERROR);\r
+}\r
+\r
+void WinService::reportStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint)\r
+{\r
+  static DWORD dwCheckPoint = 1;\r
+\r
+  status_.dwCurrentState = dwCurrentState;\r
+  status_.dwWin32ExitCode = dwWin32ExitCode;\r
+  status_.dwWaitHint = dwWaitHint;\r
+\r
+  if((dwCurrentState == SERVICE_START_PENDING) ||\r
+     (dwCurrentState == SERVICE_STOP_PENDING))\r
+    status_.dwControlsAccepted = 0;\r
+  else \r
+    status_.dwControlsAccepted = SERVICE_ACCEPT_STOP;\r
+\r
+  if((dwCurrentState == SERVICE_RUNNING) ||\r
+     (dwCurrentState == SERVICE_STOPPED))\r
+    status_.dwCheckPoint = 0;\r
+  else\r
+    status_.dwCheckPoint = dwCheckPoint++;\r
+\r
+  SetServiceStatus(status_handle_, &status_);\r
+}\r
+\r
+#endif\r
diff --git a/src/win32/winService.h b/src/win32/winService.h
new file mode 100644 (file)
index 0000000..53c2750
--- /dev/null
@@ -0,0 +1,81 @@
+/*
+ *  anytun
+ *
+ *  The secure anycast tunneling protocol (satp) defines a protocol used
+ *  for communication between any combination of unicast and anycast
+ *  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+ *  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+ *  ethernet, ip, arp ...). satp directly includes cryptography and
+ *  message authentication based on the methodes used by SRTP.  It is
+ *  intended to deliver a generic, scaleable and secure solution for
+ *  tunneling and relaying of packets of any protocol.
+ *
+ *
+ *  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+ *                          Christian Pointner <satp@wirdorange.org>
+ *
+ *  This file is part of Anytun.
+ *
+ *  Anytun is free software: you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3 as
+ *  published by the Free Software Foundation.
+ *
+ *  Anytun is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _WIN_SERVICE_H_
+#define _WIN_SERVICE_H_
+
+#ifdef WIN_SERVICE
+
+#include "../threadUtils.hpp"
+
+class WinService
+{
+public:
+  static WinService& instance();
+  #define SVC_NAME "anytun"
+  static void install();
+  static void uninstall();
+  static void start();
+
+  void waitForStop();
+  void stop();
+
+  static VOID WINAPI main(DWORD dwArgc, LPTSTR *lpszArgv);
+  static VOID WINAPI ctrlHandler(DWORD dwCtrl);
+private:
+  WinService() : started_(false) {};
+  ~WinService();
+  WinService(const WinService &w);
+  void operator=(const WinService &w);
+
+  void reportStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint=0);
+
+  static WinService* inst;
+  static Mutex instMutex;
+  class instanceCleaner {
+    public: ~instanceCleaner() {
+      if(WinService::inst != NULL)
+        delete WinService::inst;
+    }
+  };
+  friend class instanceCleaner;
+  
+  bool started_;
+  SERVICE_STATUS status_;
+  SERVICE_STATUS_HANDLE status_handle_;
+  HANDLE stop_event_;
+};
+
+extern WinService& gWinService;
+
+#endif
+
+#endif
\ No newline at end of file
diff --git a/wireshark-lua/satp.lua b/wireshark-lua/satp.lua
new file mode 100644 (file)
index 0000000..dcf4cdf
--- /dev/null
@@ -0,0 +1,82 @@
+--  anytun
+--
+--  The secure anycast tunneling protocol (satp) defines a protocol used
+--  for communication between any combination of unicast and anycast
+--  tunnel endpoints.  It has less protocol overhead than IPSec in Tunnel
+--  mode and allows tunneling of every ETHER TYPE protocol (e.g.
+--  ethernet, ip, arp ...). satp directly includes cryptography and
+--  message authentication based on the methodes used by SRTP.  It is
+--  intended to deliver a generic, scaleable and secure solution for
+--  tunneling and relaying of packets of any protocol.
+--
+--
+--  Copyright (C) 2007-2008 Othmar Gsenger, Erwin Nindl, 
+--                          Christian Pointner <satp@wirdorange.org>
+--
+--  This file is part of Anytun.
+--
+--  Anytun is free software: you can redistribute it and/or modify
+--  it under the terms of the GNU General Public License version 3 as
+--  published by the Free Software Foundation.
+--
+--  Anytun is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+--  GNU General Public License for more details.
+--
+--  You should have received a copy of the GNU General Public License
+--  along with anytun.  If not, see <http://www.gnu.org/licenses/>.
+
+
+do
+ local proto_satp = Proto("SATP","Secure Anycast Tunneling Protocol")
+
+ local payload_types = {
+       [0x0800] = "IPv4",
+       [0x6558] = "Ethernet",
+       [0x86DD] = "IPv6"
+ }
+
+ local payload_dissector = {
+       [0x0800] = "ip",
+       [0x6558] = "eth",
+       [0x86DD] = "ipv6"
+ }
+
+ local field_seq = ProtoField.uint32("satp.seq","Sequence Number",base.DEC)
+ local field_sid = ProtoField.uint16("satp.sid","Sender ID",base.DEC)
+ local field_mux = ProtoField.uint16("satp.mux","Mux",base.DEC)
+ local field_ptype = ProtoField.uint16("satp.ptype","Payload Type (plain?)",base.HEX,payload_types)
+
+ proto_satp.fields = { field_seq, field_sid, field_mux, field_ptype }
+
+
+ -- create a function to dissect it
+ function proto_satp.dissector(buffer,pinfo,tree)
+    local info_string = "Sender Id: " .. buffer(4,2):uint() .. ", Mux: " .. buffer(6,2):uint() .. ", SeqNr: " .. buffer(0,4):uint()
+    pinfo.cols.protocol = "SATP"
+    pinfo.cols.info = info_string
+
+    local subtree = tree:add(proto_satp,buffer(),"SATP, " .. info_string)
+
+    subtree:add(field_seq, buffer(0,4))
+    subtree:add(field_sid, buffer(4,2))
+    subtree:add(field_mux, buffer(6,2))
+
+    local payload_type = buffer(8,2):uint()
+
+    if payload_dissector[payload_type] ~= nil then
+       subtree:add(field_ptype, buffer(8,2))
+       Dissector.get(payload_dissector[payload_type]):call(buffer(10):tvb(),pinfo,tree)
+    else
+       Dissector.get("data"):call(buffer(8):tvb(),pinfo,tree)
+    end
+ end
+
+ -- load the udp.port table
+
+ udp_table = DissectorTable.get("udp.port")
+ -- register our protocol to handle udp port 4444
+ udp_table:add(4444,proto_satp)
+end