--- /dev/null
+Othmar Gsenger <otti@anytun.org>
+Erwin Nindl <nine@anytun.org>
+Christian Pointner <equinox@anytun.org>
--- /dev/null
+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.
+
--- /dev/null
+/*
+ * 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>.
--- /dev/null
+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
--- /dev/null
+server
+#client1
+#client2
+#client3
--- /dev/null
+#############################
+## 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
--- /dev/null
+#!/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
--- /dev/null
+#############################
+## 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
--- /dev/null
+#!/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
--- /dev/null
+#############################
+## 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
--- /dev/null
+#!/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
--- /dev/null
+#############################
+## 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
--- /dev/null
+#############################
+## 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
--- /dev/null
+#############################
+## 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
--- /dev/null
+#############################
+## 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
--- /dev/null
+#############################
+## 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
--- /dev/null
+#############################
+## 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>[...]]
--- /dev/null
+#!/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
--- /dev/null
+#! /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
--- /dev/null
+# 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
--- /dev/null
+##
+## 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)
+
--- /dev/null
+##
+## 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)
+
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+/*
+ * 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();
+}
+
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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_;
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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_;
+}
+
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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();
+}
+
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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;
+}
+
+
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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_;
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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_;
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+/*
+ * 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;
+ }
+}
+
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+/*
+ * 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;
+}
+
+
--- /dev/null
+\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
--- /dev/null
+<?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=""..\..\..\..\Program Files\boost\boost_1_35_0""\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 "C:\Program Files\boost\boost_1_35_0\""\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 "C:\Program Files\boost\boost_1_35_0\""\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
--- /dev/null
+/*
+ * 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();
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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");
+}
+
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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";
+ }
+
+}
--- /dev/null
+/*
+ * 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_;
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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");
+}
+
--- /dev/null
+/*
+ * 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
--- /dev/null
+#!/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
--- /dev/null
+/*
+ * 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_;
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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_()
+{
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * 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");
+}
+
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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";
+ }
+}
--- /dev/null
+/*
+ * 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";
+ }
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+##
+## 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
--- /dev/null
+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.
+
--- /dev/null
+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.
+
--- /dev/null
+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.
+
--- /dev/null
+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.
+
--- /dev/null
+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.
+
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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);
+}
+
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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);
+}
+
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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();
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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_;
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
+
+
--- /dev/null
+/*
+ * 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];
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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();
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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;
+}
+
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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"
+
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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;
+ }
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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_;
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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_;
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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());
+ }
+ }
+}
+
--- /dev/null
+/*
+ * 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;
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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_;
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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();
+ }
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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*/)
+{
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
+
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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"
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*
+ * 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
--- /dev/null
+/*
+ * 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);
+}
--- /dev/null
+/*\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
--- /dev/null
+/*
+ * 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
--- /dev/null
+-- 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