git repo init

This commit is contained in:
Kirill Sotnikov 2013-09-16 13:53:25 +04:00
parent cbddd9f7ac
commit f1761cad9a
185 changed files with 72008 additions and 0 deletions

24
AUTHORS Normal file
View File

@ -0,0 +1,24 @@
Main authors and maintainers:
Andrea Lo Pumo aka AlpT <alpt@netsukuku.org>
Contributors (in chronological order of initial contribution):
Andrea Leofreddi <andrea.leofreddi@gmail.com> wrote the first implementation
of the DNS wrapper code (dns_pkt.cpp, dns_rendian.h, dns_utils.h).
Enzo Nicosia (Katolaz) <katolaz@netsukuku.org> wrote the files needed to use
Automake/Autoconf. (Makefile.am configure.ac, src/Makefile.am,
src/man/Makefile.am).
Federico Tomassini (Efphe) <efphe@netsukuku.org> wrote andns, which provides
DNS compatibility for the ANDNA system. He also wrote the interface to the
libiptc. (andns* ntkresolv.* dnslib.[ch] mark.[ch] libiptc/*)
Website developers and maintainers:
Crash <crash@netsukuku.org>,
Entropika <e@entropika.net>,
Black <black@netsukuku.org>

340
COPYING Normal file
View File

@ -0,0 +1,340 @@
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) 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
this service 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 make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. 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.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
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
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the 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 a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE 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.
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
convey 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 2 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, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision 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, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This 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 Library General
Public License instead of this License.

295
ChangeLog Normal file
View File

@ -0,0 +1,295 @@
==== 0.0.9b ====
New features:
* ntk-resolv has the new option "-l"
* An active tcp socket is kept for each rnode, in this way, it is
possible to send them tcp packets without the need of estabilishing
a new tcp connection each time.
* The qspn packets are now sent using the tcp sockets described above.
* Since the UDP isn't used anymore for ntk packets, the udp daemon has
been removed. The udp port of the radar daemon is now 269/udp.
The 271/udp port has been deprecated.
* When we have multiple interfaces to reach the same rnode, send the
QSPN packets from a random device, each time.
* Code cleaned
Bug fixes:
* gcc-4 compilation warnings fixed.
* SNSD recursion works in ntk-resolv
==== 0.0.8b ====
New features:
* The Scattered Name Service Disgregation (NTK_RFC 0009) has been
implemented.
See http://lab.dyne.org/Ntk_SNSD and the man page of andna(8).
* ntk-resolve has been updated to support SNSD queries.
* The `netsukuku_d' binary and its man page have been renamed to `ntkd'
`netsukuku_wifi' and its man page have been renamed to `ntk-wifi'.
* Static binaries and packages are now available.
http://netsukuku.freaknet.org/packages/
* Netsukuku has been compiled for OpenWRT:
http://netsukuku.freaknet.org/openwrt/
* NetsukukuD compresses automatically packets > 1024 bytes using the
zlib.
* A pid file is written on /var/run/ntkd.pid. It is used to check if
other instances of ntkd are already running.
* The new option `use_shared_internet' has been added. It specifies if
ntkd will load balance the Internet traffic of this host using the
Inet connections shared by the Netsukuku nodes.
* The new command line option `-l' specifies that ntkd should send all
of its messages to the specified file.
* The scripts ip_masquerade.sh, tc_shaper.sh, rc.ntk, ntk-wifi, are
not dependent on bash anymore.
* The ANDNA keyring is now saved separately from the lcl_cache. It is
saved in andna_lcl_keyring.
* The `andna_' prefix is now used for the filename of the andna
caches.
Bug fixes:
* A workaround to the gcc 27945 bug
( http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27945 ) has been
implemented. The nodes affected with bug receive malformed packets
during the hook.
* The outgoing traffic to a node of the LAN is not shaped anymore.
* There was a bug that incremented the `hname_updates' counter, in the
andna_cache of a hostname, even if the registration/update was
rejected. Having wrong `hname_updates' counter, led to some
syncronization problems.
* Ntkd is now able to detect, while running, the remotion of a network
device it was using.
* Various memory leaks have been fixed.
* A workaround for the way getopt handles the optional arguments (i.e.
-r in ntkd) has been written. It is now possible to write
ntkd -drdddD without expecting strange behaviours. See
http://www.freaknet.org/alpt/src/patches/getopt-opt-arg/readme
* The code has been optimized and cleaned.
Extra:
* The man page for netsukuku.conf has been written.
netsukuku.conf(5).
==== 0.0.7b ====
New features:
* Multi-inet-gateways.
The Netsukuku nodes will now automatically use multiple
inet-gateways to connect to the Internet, therefore their Internet
connection will be effectively load-balanced.
* Anti-loop multi-igw shield.
The nodes which share their Internet connection will also
automatically use the shared connection of the other nodes. Through
a simple marking system, death loops are avoided.
* Traffic shaping.
The nodes which share their Internet connection can now shape it, in
this way they'll prioritize their local outgoingtraffic and the
lowdelay one (f.e. SSH).
* The lowdelay TOS is now set in the ANDNA resolve requests.
Bug fixes:
* When all the rnodes die, the radar resets the qspn counters
* Code cleaned
* A lot of bugs, which you haven't and you will never heard, have been
fixed. We've already forgotten them.
==== 0.0.6b ====
New features:
* The NTK_RFC 0008 has been implemented.
( http://lab.dyne.org/Ntk_restricted_ip_classes )
Bug fixes:
* The NTK_RFC 0007 has been implemented. It fixes an exploitable bug
in the ANDNA protocol.
* NetsukukuD has been tested on big endian machines. A lot of
endianness bugs has been fixed during the tests and now it seems to
work gracefully.
A lot of thanks to Vampire ;*
* The ppp connection to the Internet doesn't set an IP address in the
default route of the kernel but only the used ppp interface,
therefore NetsukukuD has to deduce it from the IP assigned to the
ppp interface, i.e. ppp0.
* Execute /etc/netsukuku/ip_masquerade.sh only if it is
writable just by root.
* Execute "/etc/netsukuku/ip_masquerade.sh stop" when NetsukukuD is
closed.
* Added a timeout of 60 seconds for the reverse resolution request.
* A possible memory overrun in the rsa (un)packing functions has been
fixed.
==== 0.0.5b ====
New features:
* The Internet Gateway Search (NTK_RFC 0003) has been implemented.
A node can now share its Internet connection among the other nodes
(only in restricted mode).
( Read the RFC: http://lab.dyne.org/Ntk_IGS )
* Main part of the NTK_RFC 0001 written, the (g)nodes have now the
ability to rehook to avoid IP collision.
( http://lab.dyne.org/Ntk_gnodes_contiguity )
* ANDNS has been implemented. It is a new specification of the DNS
protocol for Netsukuku. It is compatible with the actual DNS
protocol. ( http://lab.dyne.org/Ntk_andna_and_dns )
* Multi interfaces multipath: if we can reach a rnode trough multiple
interfaces, use them all with a multipath route.
* The dns_wrapper code is no more dependent on Boost.
Bug fixes:
* map_rnode doesn't use anymore the timeval struct and map_rnode.rtt was
removed 'cause it was obsolete. In conclusion we gained 12 bytes for
each rnode.
* Added a check in get_free_nodes to verify the validity of
fn_hdr->ipstart.
For example if the rnode has an IP which doesn't match with
fn_hdr->ipstart there must be some errors. This led to bug 0002.
* Fixed a bug in the multiif code: the packets destined to gnodes were
sent only from the first device.
* qspn_remove_deads() removes the routes of the dead nodes from the
routing table of the kernel.
* Restricted nodes and normal nodes are now invisible to each other.
* 127.0.0.0/8 banned.
* The command line options override the ones specified in the config file.
* code heavily cleaned.
==== 0.0.4b ====
New features:
* The multi-interface support was added, now it is possible to use
multiple network interfaces without the need of the bridge, just
specify each interface you want to use with the -i option. (man
netsukuku_d).
* The multipath support has been enabled for the external map, this
means that more than one route will be used to reach a gnode. In other
words the load balacing has been fully enabled.
* Endianness fixes: now the packets can be sent between two machines
with different endianness.
* When the daemon is launched /etc/resolv.conf is modified
automatically, so the "nameserver 127.0.0.1" is added in the first
line of resolv.conf. The old resolv.conf is at /etc/resolv.conf.bak.
When the daemon is closed /etc/resolv.conf.bak is moved to
/etc/resolv.conf.
* Added CC and CXX options in Scontruct.
Changes provided by Tero Auvinen.
* At hooking the first radar_scan is retried for three times.
* The Make/configure support was added. Now you can use both SCons or
Make to compile and install Netsukuku.
Bug fixes:
* All the the packets are now sent without any alignment.
* The free_nodes struct has been optimised: to keep the list of free
nodes it uses single bits instead of single bytes, this means that the
list is now of 32 bytes instead of 256.
* The bug in the load_rh_cache code is now fixed. (It caused crashes
when the daemon was closed).
* The installation path of the man page is now fixed.
* The installation paths are changed!! BIN_DIR=/usr/bin/,
MAN_DIR=/usr/man
* The /usr/share/netsukuku directory is now created by the daemon
itself.
* Now /sys/net/ipv4/conf/INTERFACE/rp_filter is automatically disabled
for the used network interface.
* Errors in load_hostnames() fixed. (It crashed if there was an just
an empty '\n').
==== 0.0.3b ====
* The ANDNA code, with its DNS wrapper, is completed and tested.
* The Netsukuku code was cleaned. Now it's ready to be an API.
* The Italian to English translation of the document is finished.
==== 0.0.2b ====
* NetsukukuD goes beta!
==== 0.0.1b ====
* NetsukukuD compiles, at least.
==== 0.0.0a ====
* The void and its nulliness filled the existence.

231
INSTALL Normal file
View File

@ -0,0 +1,231 @@
Installation Instructions
*************************
Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004 Free
Software Foundation, Inc.
This file is free documentation; the Free Software Foundation gives
unlimited permission to copy, distribute and modify it.
Basic Installation
==================
These are generic installation instructions.
The `configure' shell script attempts to guess correct values for
various system-dependent variables used during compilation. It uses
those values to create a `Makefile' in each directory of the package.
It may also create one or more `.h' files containing system-dependent
definitions. Finally, it creates a shell script `config.status' that
you can run in the future to recreate the current configuration, and a
file `config.log' containing compiler output (useful mainly for
debugging `configure').
It can also use an optional file (typically called `config.cache'
and enabled with `--cache-file=config.cache' or simply `-C') that saves
the results of its tests to speed up reconfiguring. (Caching is
disabled by default to prevent problems with accidental use of stale
cache files.)
If you need to do unusual things to compile the package, please try
to figure out how `configure' could check whether to do them, and mail
diffs or instructions to the address given in the `README' so they can
be considered for the next release. If you are using the cache, and at
some point `config.cache' contains results you don't want to keep, you
may remove or edit it.
The file `configure.ac' (or `configure.in') is used to create
`configure' by a program called `autoconf'. You only need
`configure.ac' if you want to change it or regenerate `configure' using
a newer version of `autoconf'.
The simplest way to compile this package is:
1. `cd' to the directory containing the package's source code and type
`./configure' to configure the package for your system. If you're
using `csh' on an old version of System V, you might need to type
`sh ./configure' instead to prevent `csh' from trying to execute
`configure' itself.
Running `configure' takes awhile. While running, it prints some
messages telling which features it is checking for.
2. Type `make' to compile the package.
3. Optionally, type `make check' to run any self-tests that come with
the package.
4. Type `make install' to install the programs and any data files and
documentation.
5. You can remove the program binaries and object files from the
source code directory by typing `make clean'. To also remove the
files that `configure' created (so you can compile the package for
a different kind of computer), type `make distclean'. There is
also a `make maintainer-clean' target, but that is intended mainly
for the package's developers. If you use it, you may have to get
all sorts of other programs in order to regenerate files that came
with the distribution.
Compilers and Options
=====================
Some systems require unusual options for compilation or linking that the
`configure' script does not know about. Run `./configure --help' for
details on some of the pertinent environment variables.
You can give `configure' initial values for configuration parameters
by setting variables in the command line or in the environment. Here
is an example:
./configure CC=c89 CFLAGS=-O2 LIBS=-lposix
*Note Defining Variables::, for more details.
Compiling For Multiple Architectures
====================================
You can compile the package for more than one kind of computer at the
same time, by placing the object files for each architecture in their
own directory. To do this, you must use a version of `make' that
supports the `VPATH' variable, such as GNU `make'. `cd' to the
directory where you want the object files and executables to go and run
the `configure' script. `configure' automatically checks for the
source code in the directory that `configure' is in and in `..'.
If you have to use a `make' that does not support the `VPATH'
variable, you have to compile the package for one architecture at a
time in the source code directory. After you have installed the
package for one architecture, use `make distclean' before reconfiguring
for another architecture.
Installation Names
==================
By default, `make install' will install the package's files in
`/usr/local/bin', `/usr/local/man', etc. You can specify an
installation prefix other than `/usr/local' by giving `configure' the
option `--prefix=PREFIX'.
You can specify separate installation prefixes for
architecture-specific files and architecture-independent files. If you
give `configure' the option `--exec-prefix=PREFIX', the package will
use PREFIX as the prefix for installing programs and libraries.
Documentation and other data files will still use the regular prefix.
In addition, if you use an unusual directory layout you can give
options like `--bindir=DIR' to specify different values for particular
kinds of files. Run `configure --help' for a list of the directories
you can set and what kinds of files go in them.
If the package supports it, you can cause programs to be installed
with an extra prefix or suffix on their names by giving `configure' the
option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'.
Optional Features
=================
Some packages pay attention to `--enable-FEATURE' options to
`configure', where FEATURE indicates an optional part of the package.
They may also pay attention to `--with-PACKAGE' options, where PACKAGE
is something like `gnu-as' or `x' (for the X Window System). The
`README' should mention any `--enable-' and `--with-' options that the
package recognizes.
For packages that use the X Window System, `configure' can usually
find the X include and library files automatically, but if it doesn't,
you can use the `configure' options `--x-includes=DIR' and
`--x-libraries=DIR' to specify their locations.
Specifying the System Type
==========================
There may be some features `configure' cannot figure out automatically,
but needs to determine by the type of machine the package will run on.
Usually, assuming the package is built to be run on the _same_
architectures, `configure' can figure that out, but if it prints a
message saying it cannot guess the machine type, give it the
`--build=TYPE' option. TYPE can either be a short name for the system
type, such as `sun4', or a canonical name which has the form:
CPU-COMPANY-SYSTEM
where SYSTEM can have one of these forms:
OS KERNEL-OS
See the file `config.sub' for the possible values of each field. If
`config.sub' isn't included in this package, then this package doesn't
need to know the machine type.
If you are _building_ compiler tools for cross-compiling, you should
use the `--target=TYPE' option to select the type of system they will
produce code for.
If you want to _use_ a cross compiler, that generates code for a
platform different from the build platform, you should specify the
"host" platform (i.e., that on which the generated programs will
eventually be run) with `--host=TYPE'.
Sharing Defaults
================
If you want to set default values for `configure' scripts to share, you
can create a site shell script called `config.site' that gives default
values for variables like `CC', `cache_file', and `prefix'.
`configure' looks for `PREFIX/share/config.site' if it exists, then
`PREFIX/etc/config.site' if it exists. Or, you can set the
`CONFIG_SITE' environment variable to the location of the site script.
A warning: not all `configure' scripts look for a site script.
Defining Variables
==================
Variables not defined in a site shell script can be set in the
environment passed to `configure'. However, some packages may run
configure again during the build, and the customized values of these
variables may be lost. In order to avoid this problem, you should set
them in the `configure' command line, using `VAR=value'. For example:
./configure CC=/usr/local2/bin/gcc
will cause the specified gcc to be used as the C compiler (unless it is
overridden in the site shell script).
`configure' Invocation
======================
`configure' recognizes the following options to control how it operates.
`--help'
`-h'
Print a summary of the options to `configure', and exit.
`--version'
`-V'
Print the version of Autoconf used to generate the `configure'
script, and exit.
`--cache-file=FILE'
Enable the cache: use and save the results of the tests in FILE,
traditionally `config.cache'. FILE defaults to `/dev/null' to
disable caching.
`--config-cache'
`-C'
Alias for `--cache-file=config.cache'.
`--quiet'
`--silent'
`-q'
Do not print messages saying which checks are being made. To
suppress all normal output, redirect it to `/dev/null' (any error
messages will still be shown).
`--srcdir=DIR'
Look for the package's source code in directory DIR. Usually
`configure' can determine that directory automatically.
`configure' also accepts some other, not widely useful, options. Run
`configure --help' for more details.

1
Makefile.am Normal file
View File

@ -0,0 +1 @@
SUBDIRS = src

560
Makefile.in Normal file
View File

@ -0,0 +1,560 @@
# Makefile.in generated by automake 1.8.5 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = .
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
host_triplet = @host@
DIST_COMMON = README $(am__configure_deps) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in $(top_srcdir)/configure AUTHORS COPYING \
ChangeLog INSTALL NEWS TODO config.guess config.sub depcomp \
install-sh missing
subdir = .
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
configure.lineno configure.status.lineno
mkinstalldirs = $(mkdir_p)
CONFIG_HEADER = $(top_builddir)/src/config.h
CONFIG_CLEAN_FILES =
SOURCES =
DIST_SOURCES =
RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
html-recursive info-recursive install-data-recursive \
install-exec-recursive install-info-recursive \
install-recursive installcheck-recursive installdirs-recursive \
pdf-recursive ps-recursive uninstall-info-recursive \
uninstall-recursive
ETAGS = etags
CTAGS = ctags
DIST_SUBDIRS = $(SUBDIRS)
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
distdir = $(PACKAGE)-$(VERSION)
top_distdir = $(distdir)
am__remove_distdir = \
{ test ! -d $(distdir) \
|| { find $(distdir) -type d ! -perm -200 -exec chmod u+w {} ';' \
&& rm -fr $(distdir); }; }
DIST_ARCHIVES = $(distdir).tar.gz
GZIP_ENV = --best
distuninstallcheck_listfiles = find . -type f -print
distcleancheck_listfiles = find . -type f -print
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CONF_DIR = @CONF_DIR@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DATA_DIR = @DATA_DIR@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
IF_METHOD = @IF_METHOD@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
KERNEL_METHOD = @KERNEL_METHOD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
OBJEXT = @OBJEXT@
OTHER_METHOD = @OTHER_METHOD@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PID_DIR = @PID_DIR@
RT_METHOD = @RT_METHOD@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_STRIP = @ac_ct_STRIP@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
debug_flags = @debug_flags@
exec_prefix = @exec_prefix@
gmp = @gmp@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
prefix = @prefix@
program_transform_name = @program_transform_name@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
SUBDIRS = src
all: all-recursive
.SUFFIXES:
am--refresh:
@:
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
echo ' cd $(srcdir) && $(AUTOMAKE) --gnu '; \
cd $(srcdir) && $(AUTOMAKE) --gnu \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
echo ' $(SHELL) ./config.status'; \
$(SHELL) ./config.status;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
$(SHELL) ./config.status --recheck
$(top_srcdir)/configure: $(am__configure_deps)
cd $(srcdir) && $(AUTOCONF)
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
uninstall-info-am:
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
# To change the values of `make' variables: instead of editing Makefiles,
# (1) if the variable is set in `config.status', edit `config.status'
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
$(RECURSIVE_TARGETS):
@set fnord $$MAKEFLAGS; amf=$$2; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
mostlyclean-recursive clean-recursive distclean-recursive \
maintainer-clean-recursive:
@set fnord $$MAKEFLAGS; amf=$$2; \
dot_seen=no; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
rev=''; for subdir in $$list; do \
if test "$$subdir" = "."; then :; else \
rev="$$subdir $$rev"; \
fi; \
done; \
rev="$$rev ."; \
target=`echo $@ | sed s/-recursive//`; \
for subdir in $$rev; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
done
ctags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
done
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
include_option=--etags-include; \
empty_fix=.; \
else \
include_option=--include; \
empty_fix=; \
fi; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test ! -f $$subdir/TAGS || \
tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
fi; \
done; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
$(am__remove_distdir)
mkdir $(distdir)
$(mkdir_p) $(distdir)/src/conf
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -d "$(distdir)/$$subdir" \
|| mkdir "$(distdir)/$$subdir" \
|| exit 1; \
(cd $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="../$(top_distdir)" \
distdir="../$(distdir)/$$subdir" \
distdir) \
|| exit 1; \
fi; \
done
-find $(distdir) -type d ! -perm -777 -exec chmod a+rwx {} \; -o \
! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
! -type d ! -perm -400 -exec chmod a+r {} \; -o \
! -type d ! -perm -444 -exec $(SHELL) $(install_sh) -c -m a+r {} {} \; \
|| chmod -R a+r $(distdir)
dist-gzip: distdir
$(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
$(am__remove_distdir)
dist-bzip2: distdir
$(AMTAR) chof - $(distdir) | bzip2 -9 -c >$(distdir).tar.bz2
$(am__remove_distdir)
dist-tarZ: distdir
$(AMTAR) chof - $(distdir) | compress -c >$(distdir).tar.Z
$(am__remove_distdir)
dist-shar: distdir
shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
$(am__remove_distdir)
dist-zip: distdir
-rm -f $(distdir).zip
zip -rq $(distdir).zip $(distdir)
$(am__remove_distdir)
dist dist-all: distdir
$(AMTAR) chof - $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
$(am__remove_distdir)
# This target untars the dist file and tries a VPATH configuration. Then
# it guarantees that the distribution is self-contained by making another
# tarfile.
distcheck: dist
case '$(DIST_ARCHIVES)' in \
*.tar.gz*) \
GZIP=$(GZIP_ENV) gunzip -c $(distdir).tar.gz | $(AMTAR) xf - ;;\
*.tar.bz2*) \
bunzip2 -c $(distdir).tar.bz2 | $(AMTAR) xf - ;;\
*.tar.Z*) \
uncompress -c $(distdir).tar.Z | $(AMTAR) xf - ;;\
*.shar.gz*) \
GZIP=$(GZIP_ENV) gunzip -c $(distdir).shar.gz | unshar ;;\
*.zip*) \
unzip $(distdir).zip ;;\
esac
chmod -R a-w $(distdir); chmod a+w $(distdir)
mkdir $(distdir)/_build
mkdir $(distdir)/_inst
chmod a-w $(distdir)
dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
&& cd $(distdir)/_build \
&& ../configure --srcdir=.. --prefix="$$dc_install_base" \
$(DISTCHECK_CONFIGURE_FLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) \
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
&& $(MAKE) $(AM_MAKEFLAGS) check \
&& $(MAKE) $(AM_MAKEFLAGS) install \
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
&& $(MAKE) $(AM_MAKEFLAGS) uninstall \
&& $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
distuninstallcheck \
&& chmod -R a-w "$$dc_install_base" \
&& ({ \
(cd ../.. && umask 077 && mkdir "$$dc_destdir") \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
} || { rm -rf "$$dc_destdir"; exit 1; }) \
&& rm -rf "$$dc_destdir" \
&& $(MAKE) $(AM_MAKEFLAGS) dist \
&& rm -rf $(DIST_ARCHIVES) \
&& $(MAKE) $(AM_MAKEFLAGS) distcleancheck
$(am__remove_distdir)
@(echo "$(distdir) archives ready for distribution: "; \
list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
sed -e '1{h;s/./=/g;p;x;}' -e '$${p;x;}'
distuninstallcheck:
@cd $(distuninstallcheck_dir) \
&& test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
|| { echo "ERROR: files left after uninstall:" ; \
if test -n "$(DESTDIR)"; then \
echo " (check DESTDIR support)"; \
fi ; \
$(distuninstallcheck_listfiles) ; \
exit 1; } >&2
distcleancheck: distclean
@if test '$(srcdir)' = . ; then \
echo "ERROR: distcleancheck can only run from a VPATH build" ; \
exit 1 ; \
fi
@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
|| { echo "ERROR: files left in build directory after distclean:" ; \
$(distcleancheck_listfiles) ; \
exit 1; } >&2
check-am: all-am
check: check-recursive
all-am: Makefile
installdirs: installdirs-recursive
installdirs-am:
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-recursive
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-recursive
clean-am: clean-generic mostlyclean-am
distclean: distclean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -f Makefile
distclean-am: clean-am distclean-generic distclean-tags
dvi: dvi-recursive
dvi-am:
html: html-recursive
info: info-recursive
info-am:
install-data-am:
install-exec-am:
install-info: install-info-recursive
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-recursive
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -rf $(top_srcdir)/autom4te.cache
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-generic
pdf: pdf-recursive
pdf-am:
ps: ps-recursive
ps-am:
uninstall-am: uninstall-info-am
uninstall-info: uninstall-info-recursive
.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am am--refresh check \
check-am clean clean-generic clean-recursive ctags \
ctags-recursive dist dist-all dist-bzip2 dist-gzip dist-shar \
dist-tarZ dist-zip distcheck distclean distclean-generic \
distclean-recursive distclean-tags distcleancheck distdir \
distuninstallcheck dvi dvi-am html html-am info info-am \
install install-am install-data install-data-am install-exec \
install-exec-am install-info install-info-am install-man \
install-strip installcheck installcheck-am installdirs \
installdirs-am maintainer-clean maintainer-clean-generic \
maintainer-clean-recursive mostlyclean mostlyclean-generic \
mostlyclean-recursive pdf pdf-am ps ps-am tags tags-recursive \
uninstall uninstall-am uninstall-info-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

1
NEWS Symbolic link
View File

@ -0,0 +1 @@
ChangeLog

272
README Normal file
View File

@ -0,0 +1,272 @@
Netsukuku
http://netsukuku.freaknet.org
--
1. What is this?
2. Get the code!
3. Build and install
3.1 Static Binaries and Packages
4. Kernel dependencies
5. How to use it
6. Where to get in touch with us
7. Bug report
8. Hack the code
9. License and that kind of stuff...
--
**
**** 1. What is this?
**
Netsukuku is a mesh network or a p2p net system that generates and sustains
itself autonomously. It is designed to handle an unlimited number of nodes
with minimal CPU and memory resources. Thanks to this feature it can be easily
used to build a worldwide distributed, anonymous and not controlled network,
separated from the Internet, without the support of any servers, ISPs or
authority controls.
This net is composed by computers linked physically each other, therefore it
isn't build upon any existing network. Netsukuku builds only the routes which
connects all the computers of the net.
In other words, Netsukuku replaces the level 3 of the model iso/osi with
another routing protocol.
The Domain Name System is also replaced by a decentralised and distributed
system: the Abnormal Netsukuku Domain Name Anarchy.
The complete features list of Netsukuku is here:
http://netsukuku.freaknet.org/files/doc/misc/Ntk_features_list
In order to join to Netsukuku you have to use NetsukukuD, which is the daemon
implementing the Npv7 protocol.
Before doing anything, please read the documentation in doc/ or in
http://netsukuku.freaknet.org
**
**** 2. Get the code!
**
Get the tarball of the latest stable version from:
http://netsukuku.freaknet.org/files/
If you want to download the development code you have to checkout it from the
cvs repository:
(Warning: It is highly probable the development code will not work!)
$ cvs -d :pserver:anoncvs@hinezumilabs.org:/home/cvsroot login
or
$ export CVSROOT=":pserver:anoncvs@hinezumilabs.org:/home/cvsroot"
$ cvs login
then check it out:
$ cvs -z3 -d :pserver:anoncvs@hinezumilabs.org:/home/cvsroot co netsukuku
or
$ cvs -z3 co netsukuku
(providing the CVSROOT variable was set in the previous step)
Once you've checked out a copy of the source tree, you can update
your source tree at any time so it is in sync with the latest and
greatest by running the command:
# cvs -z3 update -d -P
**
**** 3. Build and install
**
To compile the code you can use scons or just go with the old school way:
# ./configure && make && make install
But SCons is cooler:
http://www.scons.org/
(You should have installed at least the 2.4 version of Python in order to
avoid dirty bugs in scons)
The code depends also on the libgmp,zlib and openssl. Generally you have
already them installed on your system, but eventually you can retrieve them
here:
for the libgmp: http://www.swox.com/gmp/
the openssl library here: http://openssl.org
and finally the zlibs: http://zlib.net
Then go in the src/ directory and type:
$ scons --help
That will show you all the options you can use in the build and installation
process. Finally execute:
$ scons
The code will be compiled. If all went well install NetsukukuD with:
# scons install
Now you should give a look at /etc/netsukuku.conf (or wherever you installed
it) and modify it for your needs, but generally the default options are good.
- Notes:
If you want to change some scons option to do another installation, (i.e. you
may want to reinstall it with another MANDIR path), you have to run:
$ scons --clean
**
**** 3.1 Static Binaries and Packages
**
If you prefer to just install Netsukuku, without compiling it, you can
download the static binaries suitable to your platform. They come packed in
various formats (.tgz, .deb, .ipk).
The packages repository is at:
http://netsukuku.freaknet.org/packages/
**
**** 4. Kernel dependencies
**
On Linux be sure to have the following options set in your kernel .config.
These options are taken from linux-2.6.14.
#
# Networking options
#
CONFIG_PACKET=y
CONFIG_UNIX=y
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_ADVANCED_ROUTER=y
CONFIG_IP_MULTIPLE_TABLES=y
CONFIG_IP_ROUTE_MULTIPATH=y
CONFIG_NET_IPIP=y
CONFIG_NETFILTER=y
and these from linux-2.6.16.19.
#
# Core Netfilter Configuration
#
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
NETFILTER_XT_TARGET_CONNMARK=y
#
# IP: Netfilter Configuration
#
CONFIG_IP_NF_IPTABLES=y
CONFIG_IP_NF_FILTER=y
CONFIG_IP_NF_TARGET_REJECT=y
CONFIG_IP_NF_NAT=y
CONFIG_IP_NF_NAT_NEEDED=y
CONFIG_IP_NF_TARGET_MASQUERADE=y
If you are using modules you have to load them before launching the daemon.
**
**** 5. How to use it
**
Before doing anything do:
$ man ntkd
$ man andna
when you feel confortable and you are ready to dare type with root
priviledges:
# ntkd
then just wait... ^_-
(For the first times it's cool to use the -D option to see what happens).
- Note:
The daemon at startup takes the list of all the network interfaces which are
currently UP and it uses all of them to send and receive packets. If you want
to force the daemon to use specific interfaces you should use the B<-i>
option.
**
**** 6. Where to get in touch with us
**
> Mailing list
Subscribe to the netsukuku mailing to get help, be updated on the latest news
and discuss on its development.
To subscribe to the list, send a message to:
netsukuku-subscribe@lists.dyne.org
or use the web interface:
http://lists.dyne.org/mailman/listinfo/netsukuku
You can browse the archive here:
http://lists.dyne.org/netsukuku/
http://dir.gmane.org/gmane.network.peer-to-peer.netsukuku
> IRC
We live night and day in IRC, come to see us on channel
#netsukuku
on the FreeNode irc server (irc.freenode.org).
**
**** 7. Bug report
**
{ Don't panic! }
If you encounter any bug, please report it.
Use the online bug track system:
http://bugs.dyne.org/
or the mailing list:
http://lists.dyne.org/netsukuku/
and explain what the problem is and if possible a way to reproduce it.
**
**** 8. Hack the code
**
Feel free to debug, patch, modify and eat the code. Then submit your results
to the mailing list ^_-
There is a lot to code too! If you are a Kung Foo coder, get on board and
help the development writing some nice poems. For a start you can take a look
at the src/TODO file.
**
**** 9. License and that kind of stuff...
**
All the Netsukuku code is released under the GPL-2, please see the COPYING
file for more information.
The authors of Netsukuku and NetsukukuD are listed in the file AUTHORS.

932
aclocal.m4 vendored Normal file
View File

@ -0,0 +1,932 @@
# generated automatically by aclocal 1.8.5 -*- Autoconf -*-
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
# Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
# -*- Autoconf -*-
# Copyright (C) 2002, 2003 Free Software Foundation, Inc.
# Generated from amversion.in; do not edit by hand.
# 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 2, 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, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# AM_AUTOMAKE_VERSION(VERSION)
# ----------------------------
# Automake X.Y traces this macro to ensure aclocal.m4 has been
# generated from the m4 files accompanying Automake X.Y.
AC_DEFUN([AM_AUTOMAKE_VERSION], [am__api_version="1.8"])
# AM_SET_CURRENT_AUTOMAKE_VERSION
# -------------------------------
# Call AM_AUTOMAKE_VERSION so it can be traced.
# This function is AC_REQUIREd by AC_INIT_AUTOMAKE.
AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
[AM_AUTOMAKE_VERSION([1.8.5])])
# AM_AUX_DIR_EXPAND
# Copyright (C) 2001, 2003 Free Software Foundation, Inc.
# 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 2, 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, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
#
# Of course, Automake must honor this variable whenever it calls a
# tool from the auxiliary directory. The problem is that $srcdir (and
# therefore $ac_aux_dir as well) can be either absolute or relative,
# depending on how configure is run. This is pretty annoying, since
# it makes $ac_aux_dir quite unusable in subdirectories: in the top
# source directory, any form will work fine, but in subdirectories a
# relative path needs to be adjusted first.
#
# $ac_aux_dir/missing
# fails when called from a subdirectory if $ac_aux_dir is relative
# $top_srcdir/$ac_aux_dir/missing
# fails if $ac_aux_dir is absolute,
# fails when called from a subdirectory in a VPATH build with
# a relative $ac_aux_dir
#
# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
# are both prefixed by $srcdir. In an in-source build this is usually
# harmless because $srcdir is `.', but things will broke when you
# start a VPATH build or use an absolute $srcdir.
#
# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
# and then we would define $MISSING as
# MISSING="\${SHELL} $am_aux_dir/missing"
# This will work as long as MISSING is not called from configure, because
# unfortunately $(top_srcdir) has no meaning in configure.
# However there are other variables, like CC, which are often used in
# configure, and could therefore not use this "fixed" $ac_aux_dir.
#
# Another solution, used here, is to always expand $ac_aux_dir to an
# absolute PATH. The drawback is that using absolute paths prevent a
# configured tree to be moved without reconfiguration.
AC_DEFUN([AM_AUX_DIR_EXPAND],
[dnl Rely on autoconf to set up CDPATH properly.
AC_PREREQ([2.50])dnl
# expand $ac_aux_dir to an absolute path
am_aux_dir=`cd $ac_aux_dir && pwd`
])
# AM_CONDITIONAL -*- Autoconf -*-
# Copyright (C) 1997, 2000, 2001, 2003 Free Software Foundation, Inc.
# 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 2, 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, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
# serial 6
# AM_CONDITIONAL(NAME, SHELL-CONDITION)
# -------------------------------------
# Define a conditional.
AC_DEFUN([AM_CONDITIONAL],
[AC_PREREQ(2.52)dnl
ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
[$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
AC_SUBST([$1_TRUE])
AC_SUBST([$1_FALSE])
if $2; then
$1_TRUE=
$1_FALSE='#'
else
$1_TRUE='#'
$1_FALSE=
fi
AC_CONFIG_COMMANDS_PRE(
[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
AC_MSG_ERROR([conditional "$1" was never defined.
Usually this means the macro was only invoked conditionally.])
fi])])
# serial 7 -*- Autoconf -*-
# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
# Free Software Foundation, Inc.
# 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 2, 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, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
# written in clear, in which case automake, when reading aclocal.m4,
# will think it sees a *use*, and therefore will trigger all it's
# C support machinery. Also note that it means that autoscan, seeing
# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
# _AM_DEPENDENCIES(NAME)
# ----------------------
# See how the compiler implements dependency checking.
# NAME is "CC", "CXX", "GCJ", or "OBJC".
# We try a few techniques and use that to set a single cache variable.
#
# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
# dependency, and given that the user is not expected to run this macro,
# just rely on AC_PROG_CC.
AC_DEFUN([_AM_DEPENDENCIES],
[AC_REQUIRE([AM_SET_DEPDIR])dnl
AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
AC_REQUIRE([AM_MAKE_INCLUDE])dnl
AC_REQUIRE([AM_DEP_TRACK])dnl
ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
[$1], CXX, [depcc="$CXX" am_compiler_list=],
[$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
[$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
[depcc="$$1" am_compiler_list=])
AC_CACHE_CHECK([dependency style of $depcc],
[am_cv_$1_dependencies_compiler_type],
[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
# We make a subdir and do the tests there. Otherwise we can end up
# making bogus files that we don't know about and never remove. For
# instance it was reported that on HP-UX the gcc test will end up
# making a dummy file named `D' -- because `-MD' means `put the output
# in D'.
mkdir conftest.dir
# Copy depcomp to subdir because otherwise we won't find it if we're
# using a relative directory.
cp "$am_depcomp" conftest.dir
cd conftest.dir
# We will build objects and dependencies in a subdirectory because
# it helps to detect inapplicable dependency modes. For instance
# both Tru64's cc and ICC support -MD to output dependencies as a
# side effect of compilation, but ICC will put the dependencies in
# the current directory while Tru64 will put them in the object
# directory.
mkdir sub
am_cv_$1_dependencies_compiler_type=none
if test "$am_compiler_list" = ""; then
am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
fi
for depmode in $am_compiler_list; do
# Setup a source with many dependencies, because some compilers
# like to wrap large dependency lists on column 80 (with \), and
# we should not choose a depcomp mode which is confused by this.
#
# We need to recreate these files for each test, as the compiler may
# overwrite some of them when testing with obscure command lines.
# This happens at least with the AIX C compiler.
: > sub/conftest.c
for i in 1 2 3 4 5 6; do
echo '#include "conftst'$i'.h"' >> sub/conftest.c
# Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
# Solaris 8's {/usr,}/bin/sh.
touch sub/conftst$i.h
done
echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
case $depmode in
nosideeffect)
# after this tag, mechanisms are not by side-effect, so they'll
# only be used when explicitly requested
if test "x$enable_dependency_tracking" = xyes; then
continue
else
break
fi
;;
none) break ;;
esac
# We check with `-c' and `-o' for the sake of the "dashmstdout"
# mode. It turns out that the SunPro C++ compiler does not properly
# handle `-M -o', and we need to detect this.
if depmode=$depmode \
source=sub/conftest.c object=sub/conftest.${OBJEXT-o} \
depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
$SHELL ./depcomp $depcc -c -o sub/conftest.${OBJEXT-o} sub/conftest.c \
>/dev/null 2>conftest.err &&
grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
grep sub/conftest.${OBJEXT-o} sub/conftest.Po > /dev/null 2>&1 &&
${MAKE-make} -s -f confmf > /dev/null 2>&1; then
# icc doesn't choke on unknown options, it will just issue warnings
# or remarks (even with -Werror). So we grep stderr for any message
# that says an option was ignored or not supported.
# When given -MP, icc 7.0 and 7.1 complain thusly:
# icc: Command line warning: ignoring option '-M'; no argument required
# The diagnosis changed in icc 8.0:
# icc: Command line remark: option '-MP' not supported
if (grep 'ignoring option' conftest.err ||
grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
am_cv_$1_dependencies_compiler_type=$depmode
break
fi
fi
done
cd ..
rm -rf conftest.dir
else
am_cv_$1_dependencies_compiler_type=none
fi
])
AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
AM_CONDITIONAL([am__fastdep$1], [
test "x$enable_dependency_tracking" != xno \
&& test "$am_cv_$1_dependencies_compiler_type" = gcc3])
])
# AM_SET_DEPDIR
# -------------
# Choose a directory name for dependency files.
# This macro is AC_REQUIREd in _AM_DEPENDENCIES
AC_DEFUN([AM_SET_DEPDIR],
[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
])
# AM_DEP_TRACK
# ------------
AC_DEFUN([AM_DEP_TRACK],
[AC_ARG_ENABLE(dependency-tracking,
[ --disable-dependency-tracking speeds up one-time build
--enable-dependency-tracking do not reject slow dependency extractors])
if test "x$enable_dependency_tracking" != xno; then
am_depcomp="$ac_aux_dir/depcomp"
AMDEPBACKSLASH='\'
fi
AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
AC_SUBST([AMDEPBACKSLASH])
])
# Generate code to set up dependency tracking. -*- Autoconf -*-
# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
# 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 2, 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, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
#serial 2
# _AM_OUTPUT_DEPENDENCY_COMMANDS
# ------------------------------
AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
[for mf in $CONFIG_FILES; do
# Strip MF so we end up with the name of the file.
mf=`echo "$mf" | sed -e 's/:.*$//'`
# Check whether this is an Automake generated Makefile or not.
# We used to match only the files named `Makefile.in', but
# some people rename them; so instead we look at the file content.
# Grep'ing the first line is not enough: some people post-process
# each Makefile.in and add a new line on top of each file to say so.
# So let's grep whole file.
if grep '^#.*generated by automake' $mf > /dev/null 2>&1; then
dirpart=`AS_DIRNAME("$mf")`
else
continue
fi
grep '^DEP_FILES *= *[[^ @%:@]]' < "$mf" > /dev/null || continue
# Extract the definition of DEP_FILES from the Makefile without
# running `make'.
DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
test -z "$DEPDIR" && continue
# When using ansi2knr, U may be empty or an underscore; expand it
U=`sed -n 's/^U = //p' < "$mf"`
test -d "$dirpart/$DEPDIR" || mkdir "$dirpart/$DEPDIR"
# We invoke sed twice because it is the simplest approach to
# changing $(DEPDIR) to its actual value in the expansion.
for file in `sed -n '
/^DEP_FILES = .*\\\\$/ {
s/^DEP_FILES = //
:loop
s/\\\\$//
p
n
/\\\\$/ b loop
p
}
/^DEP_FILES = / s/^DEP_FILES = //p' < "$mf" | \
sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
# Make sure the directory exists.
test -f "$dirpart/$file" && continue
fdir=`AS_DIRNAME(["$file"])`
AS_MKDIR_P([$dirpart/$fdir])
# echo "creating $dirpart/$file"
echo '# dummy' > "$dirpart/$file"
done
done
])# _AM_OUTPUT_DEPENDENCY_COMMANDS
# AM_OUTPUT_DEPENDENCY_COMMANDS
# -----------------------------
# This macro should only be invoked once -- use via AC_REQUIRE.
#
# This code is only required when automatic dependency tracking
# is enabled. FIXME. This creates each `.P' file that we will
# need in order to bootstrap the dependency handling code.
AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
[AC_CONFIG_COMMANDS([depfiles],
[test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
[AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
])
# Like AC_CONFIG_HEADER, but automatically create stamp file. -*- Autoconf -*-
# Copyright (C) 1996, 1997, 2000, 2001, 2003 Free Software Foundation, Inc.
# 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 2, 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, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
# serial 7
# AM_CONFIG_HEADER is obsolete. It has been replaced by AC_CONFIG_HEADERS.
AU_DEFUN([AM_CONFIG_HEADER], [AC_CONFIG_HEADERS($@)])
# Do all the work for Automake. -*- Autoconf -*-
# This macro actually does too much some checks are only needed if
# your package does certain things. But this isn't really a big deal.
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
# Free Software Foundation, Inc.
# 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 2, 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, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
# serial 11
# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
# AM_INIT_AUTOMAKE([OPTIONS])
# -----------------------------------------------
# The call with PACKAGE and VERSION arguments is the old style
# call (pre autoconf-2.50), which is being phased out. PACKAGE
# and VERSION should now be passed to AC_INIT and removed from
# the call to AM_INIT_AUTOMAKE.
# We support both call styles for the transition. After
# the next Automake release, Autoconf can make the AC_INIT
# arguments mandatory, and then we can depend on a new Autoconf
# release and drop the old call support.
AC_DEFUN([AM_INIT_AUTOMAKE],
[AC_PREREQ([2.58])dnl
dnl Autoconf wants to disallow AM_ names. We explicitly allow
dnl the ones we care about.
m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
AC_REQUIRE([AC_PROG_INSTALL])dnl
# test to see if srcdir already configured
if test "`cd $srcdir && pwd`" != "`pwd`" &&
test -f $srcdir/config.status; then
AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
fi
# test whether we have cygpath
if test -z "$CYGPATH_W"; then
if (cygpath --version) >/dev/null 2>/dev/null; then
CYGPATH_W='cygpath -w'
else
CYGPATH_W=echo
fi
fi
AC_SUBST([CYGPATH_W])
# Define the identity of the package.
dnl Distinguish between old-style and new-style calls.
m4_ifval([$2],
[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
AC_SUBST([PACKAGE], [$1])dnl
AC_SUBST([VERSION], [$2])],
[_AM_SET_OPTIONS([$1])dnl
AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
_AM_IF_OPTION([no-define],,
[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
# Some tools Automake needs.
AC_REQUIRE([AM_SANITY_CHECK])dnl
AC_REQUIRE([AC_ARG_PROGRAM])dnl
AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
AM_MISSING_PROG(AUTOCONF, autoconf)
AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
AM_MISSING_PROG(AUTOHEADER, autoheader)
AM_MISSING_PROG(MAKEINFO, makeinfo)
AM_MISSING_PROG(AMTAR, tar)
AM_PROG_INSTALL_SH
AM_PROG_INSTALL_STRIP
AC_REQUIRE([AM_PROG_MKDIR_P])dnl
# We need awk for the "check" target. The system "awk" is bad on
# some platforms.
AC_REQUIRE([AC_PROG_AWK])dnl
AC_REQUIRE([AC_PROG_MAKE_SET])dnl
AC_REQUIRE([AM_SET_LEADING_DOT])dnl
_AM_IF_OPTION([no-dependencies],,
[AC_PROVIDE_IFELSE([AC_PROG_CC],
[_AM_DEPENDENCIES(CC)],
[define([AC_PROG_CC],
defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
AC_PROVIDE_IFELSE([AC_PROG_CXX],
[_AM_DEPENDENCIES(CXX)],
[define([AC_PROG_CXX],
defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
])
])
# When config.status generates a header, we must update the stamp-h file.
# This file resides in the same directory as the config header
# that is generated. The stamp files are numbered to have different names.
# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
# loop where config.status creates the headers, so we can generate
# our stamp files there.
AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
[# Compute $1's index in $config_headers.
_am_stamp_count=1
for _am_header in $config_headers :; do
case $_am_header in
$1 | $1:* )
break ;;
* )
_am_stamp_count=`expr $_am_stamp_count + 1` ;;
esac
done
echo "timestamp for $1" >`AS_DIRNAME([$1])`/stamp-h[]$_am_stamp_count])
# AM_PROG_INSTALL_SH
# ------------------
# Define $install_sh.
# Copyright (C) 2001, 2003 Free Software Foundation, Inc.
# 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 2, 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, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
AC_DEFUN([AM_PROG_INSTALL_SH],
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
install_sh=${install_sh-"$am_aux_dir/install-sh"}
AC_SUBST(install_sh)])
# -*- Autoconf -*-
# Copyright (C) 2003 Free Software Foundation, Inc.
# 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 2, 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, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
# serial 1
# Check whether the underlying file-system supports filenames
# with a leading dot. For instance MS-DOS doesn't.
AC_DEFUN([AM_SET_LEADING_DOT],
[rm -rf .tst 2>/dev/null
mkdir .tst 2>/dev/null
if test -d .tst; then
am__leading_dot=.
else
am__leading_dot=_
fi
rmdir .tst 2>/dev/null
AC_SUBST([am__leading_dot])])
# Check to see how 'make' treats includes. -*- Autoconf -*-
# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
# 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 2, 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, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
# serial 2
# AM_MAKE_INCLUDE()
# -----------------
# Check to see how make treats includes.
AC_DEFUN([AM_MAKE_INCLUDE],
[am_make=${MAKE-make}
cat > confinc << 'END'
am__doit:
@echo done
.PHONY: am__doit
END
# If we don't find an include directive, just comment out the code.
AC_MSG_CHECKING([for style of include used by $am_make])
am__include="#"
am__quote=
_am_result=none
# First try GNU make style include.
echo "include confinc" > confmf
# We grep out `Entering directory' and `Leaving directory'
# messages which can occur if `w' ends up in MAKEFLAGS.
# In particular we don't look at `^make:' because GNU make might
# be invoked under some other name (usually "gmake"), in which
# case it prints its new name instead of `make'.
if test "`$am_make -s -f confmf 2> /dev/null | grep -v 'ing directory'`" = "done"; then
am__include=include
am__quote=
_am_result=GNU
fi
# Now try BSD make style include.
if test "$am__include" = "#"; then
echo '.include "confinc"' > confmf
if test "`$am_make -s -f confmf 2> /dev/null`" = "done"; then
am__include=.include
am__quote="\""
_am_result=BSD
fi
fi
AC_SUBST([am__include])
AC_SUBST([am__quote])
AC_MSG_RESULT([$_am_result])
rm -f confinc confmf
])
# -*- Autoconf -*-
# Copyright (C) 1997, 1999, 2000, 2001, 2003 Free Software Foundation, Inc.
# 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 2, 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, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
# serial 3
# AM_MISSING_PROG(NAME, PROGRAM)
# ------------------------------
AC_DEFUN([AM_MISSING_PROG],
[AC_REQUIRE([AM_MISSING_HAS_RUN])
$1=${$1-"${am_missing_run}$2"}
AC_SUBST($1)])
# AM_MISSING_HAS_RUN
# ------------------
# Define MISSING if not defined so far and test if it supports --run.
# If it does, set am_missing_run to use it, otherwise, to nothing.
AC_DEFUN([AM_MISSING_HAS_RUN],
[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
test x"${MISSING+set}" = xset || MISSING="\${SHELL} $am_aux_dir/missing"
# Use eval to expand $SHELL
if eval "$MISSING --run true"; then
am_missing_run="$MISSING --run "
else
am_missing_run=
AC_MSG_WARN([`missing' script is too old or missing])
fi
])
# AM_PROG_MKDIR_P
# ---------------
# Check whether `mkdir -p' is supported, fallback to mkinstalldirs otherwise.
# Copyright (C) 2003, 2004 Free Software Foundation, Inc.
# 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 2, 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, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
# Automake 1.8 used `mkdir -m 0755 -p --' to ensure that directories
# created by `make install' are always world readable, even if the
# installer happens to have an overly restrictive umask (e.g. 077).
# This was a mistake. There are at least two reasons why we must not
# use `-m 0755':
# - it causes special bits like SGID to be ignored,
# - it may be too restrictive (some setups expect 775 directories).
#
# Do not use -m 0755 and let people choose whatever they expect by
# setting umask.
#
# We cannot accept any implementation of `mkdir' that recognizes `-p'.
# Some implementations (such as Solaris 8's) are not thread-safe: if a
# parallel make tries to run `mkdir -p a/b' and `mkdir -p a/c'
# concurrently, both version can detect that a/ is missing, but only
# one can create it and the other will error out. Consequently we
# restrict ourselves to GNU make (using the --version option ensures
# this.)
AC_DEFUN([AM_PROG_MKDIR_P],
[if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
# Keeping the `.' argument allows $(mkdir_p) to be used without
# argument. Indeed, we sometimes output rules like
# $(mkdir_p) $(somedir)
# where $(somedir) is conditionally defined.
# (`test -n '$(somedir)' && $(mkdir_p) $(somedir)' is a more
# expensive solution, as it forces Make to start a sub-shell.)
mkdir_p='mkdir -p -- .'
else
# On NextStep and OpenStep, the `mkdir' command does not
# recognize any option. It will interpret all options as
# directories to create, and then abort because `.' already
# exists.
for d in ./-p ./--version;
do
test -d $d && rmdir $d
done
# $(mkinstalldirs) is defined by Automake if mkinstalldirs exists.
if test -f "$ac_aux_dir/mkinstalldirs"; then
mkdir_p='$(mkinstalldirs)'
else
mkdir_p='$(install_sh) -d'
fi
fi
AC_SUBST([mkdir_p])])
# Helper functions for option handling. -*- Autoconf -*-
# Copyright (C) 2001, 2002, 2003 Free Software Foundation, Inc.
# 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 2, 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, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
# serial 2
# _AM_MANGLE_OPTION(NAME)
# -----------------------
AC_DEFUN([_AM_MANGLE_OPTION],
[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
# _AM_SET_OPTION(NAME)
# ------------------------------
# Set option NAME. Presently that only means defining a flag for this option.
AC_DEFUN([_AM_SET_OPTION],
[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
# _AM_SET_OPTIONS(OPTIONS)
# ----------------------------------
# OPTIONS is a space-separated list of Automake options.
AC_DEFUN([_AM_SET_OPTIONS],
[AC_FOREACH([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
# -------------------------------------------
# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
AC_DEFUN([_AM_IF_OPTION],
[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
#
# Check to make sure that the build environment is sane.
#
# Copyright (C) 1996, 1997, 2000, 2001, 2003 Free Software Foundation, Inc.
# 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 2, 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, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
# serial 3
# AM_SANITY_CHECK
# ---------------
AC_DEFUN([AM_SANITY_CHECK],
[AC_MSG_CHECKING([whether build environment is sane])
# Just in case
sleep 1
echo timestamp > conftest.file
# Do `set' in a subshell so we don't clobber the current shell's
# arguments. Must try -L first in case configure is actually a
# symlink; some systems play weird games with the mod time of symlinks
# (eg FreeBSD returns the mod time of the symlink's containing
# directory).
if (
set X `ls -Lt $srcdir/configure conftest.file 2> /dev/null`
if test "$[*]" = "X"; then
# -L didn't work.
set X `ls -t $srcdir/configure conftest.file`
fi
rm -f conftest.file
if test "$[*]" != "X $srcdir/configure conftest.file" \
&& test "$[*]" != "X conftest.file $srcdir/configure"; then
# If neither matched, then we have a broken ls. This can happen
# if, for instance, CONFIG_SHELL is bash and it inherits a
# broken ls alias from the environment. This has actually
# happened. Such a system could not be considered "sane".
AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
alias in your environment])
fi
test "$[2]" = conftest.file
)
then
# Ok.
:
else
AC_MSG_ERROR([newly created file is older than distributed files!
Check your system clock])
fi
AC_MSG_RESULT(yes)])
# AM_PROG_INSTALL_STRIP
# Copyright (C) 2001, 2003 Free Software Foundation, Inc.
# 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 2, 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, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.
# One issue with vendor `install' (even GNU) is that you can't
# specify the program used to strip binaries. This is especially
# annoying in cross-compiling environments, where the build's strip
# is unlikely to handle the host's binaries.
# Fortunately install-sh will honor a STRIPPROG variable, so we
# always use install-sh in `make install-strip', and initialize
# STRIPPROG with the value of the STRIP variable (set by the user).
AC_DEFUN([AM_PROG_INSTALL_STRIP],
[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
# Installed binaries are usually stripped using `strip' when the user
# run `make install-strip'. However `strip' might not be the right
# tool to use in cross-compilation environments, therefore Automake
# will honor the `STRIP' environment variable to overrule this program.
dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
if test "$cross_compiling" != no; then
AC_CHECK_TOOL([STRIP], [strip], :)
fi
INSTALL_STRIP_PROGRAM="\${SHELL} \$(install_sh) -c -s"
AC_SUBST([INSTALL_STRIP_PROGRAM])])

1517
config.guess vendored Executable file

File diff suppressed because it is too large Load Diff

1598
config.sub vendored Executable file

File diff suppressed because it is too large Load Diff

6749
configure vendored Executable file

File diff suppressed because it is too large Load Diff

184
configure.ac Normal file
View File

@ -0,0 +1,184 @@
AC_PREREQ(2.59)
AC_INIT(netsukuku, 0.0.9b)
AM_INIT_AUTOMAKE(netsukuku, 0.0.9b)
AC_DEFINE(VERSION, 0.0.9b)
AM_CONFIG_HEADER(src/config.h)
dnl -----------------------------------
dnl Get hostname and other information.
dnl -----------------------------------
AC_CANONICAL_HOST
AC_PROG_CC
AC_PROG_CPP
AC_PROG_CXX
prefix=/usr
datadir=/usr/share/netsukuku
sysconfdir=/etc/netsukuku
piddir=/var/run
AC_ARG_WITH(gmp-include, AS_HELP_STRING([--with-gmp-include], \
[gmp include dir]), [gmp="$withval"])
AC_SUBST(gmp)
AC_HEADER_STDC
AC_CHECK_HEADERS([unistd.h])
AC_CHECK_HEADERS([pthread.h], ,\
[echo "============================ Unable to find pthread.h"; \
echo "Do you have the libpthread library installed?" ])
AC_CHECK_HEADERS([zlib.h], ,\
[echo "============================ Unable to find zlib.h"; \
echo "Do you have the zlib library installed?" ])
AC_CHECK_HEADERS([openssl/crypto.h], ,\
[echo "============================ Unable to find openssl/crypto.h";\
echo "Read README first!!!!!"; \
echo "Install the openssl library"])
AC_CHECK_HEADERS([gmp.h], ,\
[echo "============================ Unable to find gmp.h"; \
echo "Read README first!!!!!"; \
echo "You need to install the libgmp library."; \
echo "In the debian the package is libgmp3-dev"])
AC_MSG_CHECKING(OS)
case "$host" in
*-sunos5.6* | *-solaris2.6*)
opsys=sol2-6
AC_DEFINE(SUNOS,,SunOS 5)
AC_CHECK_LIB(xnet, main)
AC_MSG_RESULT(solaris)
;;
*-sunos5* | *-solaris2*)
AC_DEFINE(SUNOS,,SunOS 5)
AC_CHECK_LIB(socket, main)
AC_CHECK_LIB(nsl, main)
AC_MSG_RESULT(solaris)
;;
*-linux-*)
opsys=gnu-linux
AC_DEFINE(GNU_LINUX,,GNU Linux)
AC_MSG_RESULT(linux)
;;
*-nec-sysv4*)
AC_CHECK_LIB(nsl, gethostbyname)
AC_CHECK_LIB(socket, socket)
AC_MSG_RESULT(net-sysv4)
;;
*-freebsd*)
AC_DEFINE(FREEBSD,,FreeBSD)
AC_MSG_RESULT(freebsd)
;;
*-openbsd*)
opsys=openbsd
AC_DEFINE(OPEN_BSD,,OpenBSD)
AC_MSG_RESULT(openbsd)
;;
*-bsdi*)
opsys=bsdi
OTHER_METHOD="mtu_kvm.o"
AC_CHECK_LIB(kvm, main)
AC_MSG_RESULT(bsdi)
;;
*-irix6.5)
opsys=irix
AC_DEFINE(IRIX,,IRIX 6.5)
AC_MSG_RESULT(irix)
;;
esac
dnl ------------------------------------
dnl Determine routing get and set method
dnl ------------------------------------
AC_MSG_CHECKING(Netsukuku kernel interface method)
if test x"$opsys" = x"gnu-linux"; then
AC_MSG_RESULT(netlink)
RT_METHOD=rt_netlink.o
AC_DEFINE(HAVE_NETLINK,,netlink)
netlink=yes
else
if test "$opsys" = "sol2-6";then
AC_MSG_RESULT(solaris)
KERNEL_METHOD="kernel_socket.o"
RT_METHOD="rt_socket.o"
elif test "$opsys" = "irix" ; then
AC_MSG_RESULT(irix)
KERNEL_METHOD="kernel_socket.o"
RT_METHOD="rt_socket.o"
else
AC_TRY_RUN([#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
main ()
{
int ac_sock;
ac_sock = socket (AF_ROUTE, SOCK_RAW, 0);
if (ac_sock < 0 && errno == EINVAL)
exit (1);
exit (0);
}],
[KERNEL_METHOD=kernel_socket.o
RT_METHOD=rt_socket.o
AC_MSG_RESULT(socket)],
[RT_METHOD=rt_ioctl.o
AC_MSG_RESULT(ioctl)],
[KERNEL_METHOD=kernel_socket.o
RT_METHOD=rt_socket.o
AC_MSG_RESULT(socket)])
fi
fi
AC_SUBST(RT_METHOD)
AC_SUBST(KERNEL_METHOD)
AC_SUBST(OTHER_METHOD)
dnl -----------------------------
dnl check interface lookup method
dnl -----------------------------
AC_MSG_CHECKING(interface looking up method)
if test "$netlink" = yes; then
AC_MSG_RESULT(netlink)
IF_METHOD=if_netlink.o
else
if test "$opsys" = "sol2-6";then
AC_MSG_RESULT(solaris)
IF_METHOD=if_ioctl.o
elif test "$opsys" = "irix" ; then
AC_MSG_RESULT(irix)
IF_METHOD=if_ioctl.o
elif test "$opsys" = "openbsd";then
AC_MSG_RESULT(openbsd)
IF_METHOD=if_ioctl.o
elif grep NET_RT_IFLIST /usr/include/sys/socket.h >/dev/null 2>&1; then
AC_MSG_RESULT(sysctl)
IF_METHOD=if_sysctl.o
AC_DEFINE(HAVE_NET_RT_IFLIST,,NET_RT_IFLIST)
else
AC_MSG_RESULT(ioctl)
IF_METHOD=if_ioctl.o
fi
fi
AC_SUBST(IF_METHOD)
AC_ARG_ENABLE(debug, AS_HELP_STRING([--enable-debug], [Enable Netsukuku debug]),\
[debug_flags="-Wall -DDEBUG"], [debug_flags=""])
AC_SUBST(debug_flags)
AC_DEFINE_UNQUOTED(DATA_DIR, "$datadir", "Where the Netsukuku data is saved")
AC_DEFINE_UNQUOTED(CONF_DIR, "$sysconfdir", "Location of configuration files")
AC_DEFINE_UNQUOTED(PID_DIR, "$piddir", "Location of ntkd.pid file")
AC_ARG_WITH(pid_dir,
[ --with-pid-dir=ARG Specify location of ntkd.pid file (default /var/run)],\
[AC_DEFINE_UNQUOTED(PID_DIR, "$withval", ntkd.pid file location)])
AC_SUBST(CONF_DIR)
AC_SUBST(DATA_DIR)
AC_SUBST(PID_DIR)
AC_CONFIG_FILES([Makefile src/Makefile src/man/Makefile src/scripts/Makefile\
src/conf/Makefile src/conf/netsukuku.conf])
AC_OUTPUT

530
depcomp Executable file
View File

@ -0,0 +1,530 @@
#! /bin/sh
# depcomp - compile a program generating dependencies as side-effects
scriptversion=2005-07-09.11
# Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
# 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 2, 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, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
case $1 in
'')
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
exit 1;
;;
-h | --h*)
cat <<\EOF
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
Run PROGRAMS ARGS to compile a file, generating dependencies
as side-effects.
Environment variables:
depmode Dependency tracking mode.
source Source file read by `PROGRAMS ARGS'.
object Object file output by `PROGRAMS ARGS'.
DEPDIR directory where to store dependencies.
depfile Dependency file to output.
tmpdepfile Temporary file to use when outputing dependencies.
libtool Whether libtool is used (yes/no).
Report bugs to <bug-automake@gnu.org>.
EOF
exit $?
;;
-v | --v*)
echo "depcomp $scriptversion"
exit $?
;;
esac
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
echo "depcomp: Variables source, object and depmode must be set" 1>&2
exit 1
fi
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
depfile=${depfile-`echo "$object" |
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
rm -f "$tmpdepfile"
# Some modes work just like other modes, but use different flags. We
# parameterize here, but still list the modes in the big case below,
# to make depend.m4 easier to write. Note that we *cannot* use a case
# here, because this file can only contain one case statement.
if test "$depmode" = hp; then
# HP compiler uses -M and no extra arg.
gccflag=-M
depmode=gcc
fi
if test "$depmode" = dashXmstdout; then
# This is just like dashmstdout with a different argument.
dashmflag=-xM
depmode=dashmstdout
fi
case "$depmode" in
gcc3)
## gcc 3 implements dependency tracking that does exactly what
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
## it if -MD -MP comes after the -MF stuff. Hmm.
"$@" -MT "$object" -MD -MP -MF "$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
mv "$tmpdepfile" "$depfile"
;;
gcc)
## There are various ways to get dependency output from gcc. Here's
## why we pick this rather obscure method:
## - Don't want to use -MD because we'd like the dependencies to end
## up in a subdir. Having to rename by hand is ugly.
## (We might end up doing this anyway to support other compilers.)
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
## -MM, not -M (despite what the docs say).
## - Using -M directly means running the compiler twice (even worse
## than renaming).
if test -z "$gccflag"; then
gccflag=-MD,
fi
"$@" -Wp,"$gccflag$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
echo "$object : \\" > "$depfile"
alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
## The second -e expression handles DOS-style file names with drive letters.
sed -e 's/^[^:]*: / /' \
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
## This next piece of magic avoids the `deleted header file' problem.
## The problem is that when a header file which appears in a .P file
## is deleted, the dependency causes make to die (because there is
## typically no way to rebuild the header). We avoid this by adding
## dummy dependencies for each header file. Too bad gcc doesn't do
## this for us directly.
tr ' ' '
' < "$tmpdepfile" |
## Some versions of gcc put a space before the `:'. On the theory
## that the space means something, we add a space to the output as
## well.
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
hp)
# This case exists only to let depend.m4 do its work. It works by
# looking at the text of this script. This case will never be run,
# since it is checked for above.
exit 1
;;
sgi)
if test "$libtool" = yes; then
"$@" "-Wp,-MDupdate,$tmpdepfile"
else
"$@" -MDupdate "$tmpdepfile"
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
echo "$object : \\" > "$depfile"
# Clip off the initial element (the dependent). Don't try to be
# clever and replace this with sed code, as IRIX sed won't handle
# lines with more than a fixed number of characters (4096 in
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
# the IRIX cc adds comments like `#:fec' to the end of the
# dependency line.
tr ' ' '
' < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
tr '
' ' ' >> $depfile
echo >> $depfile
# The second pass generates a dummy entry for each header file.
tr ' ' '
' < "$tmpdepfile" \
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
>> $depfile
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
aix)
# The C for AIX Compiler uses -M and outputs the dependencies
# in a .u file. In older versions, this file always lives in the
# current directory. Also, the AIX compiler puts `$object:' at the
# start of each line; $object doesn't have directory information.
# Version 6 uses the directory in both cases.
stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'`
tmpdepfile="$stripped.u"
if test "$libtool" = yes; then
"$@" -Wc,-M
else
"$@" -M
fi
stat=$?
if test -f "$tmpdepfile"; then :
else
stripped=`echo "$stripped" | sed 's,^.*/,,'`
tmpdepfile="$stripped.u"
fi
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
if test -f "$tmpdepfile"; then
outname="$stripped.o"
# Each line is of the form `foo.o: dependent.h'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile"
sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile"
else
# The sourcefile does not contain any dependencies, so just
# store a dummy comment line, to avoid errors with the Makefile
# "include basename.Plo" scheme.
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
icc)
# Intel's C compiler understands `-MD -MF file'. However on
# icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
# ICC 7.0 will fill foo.d with something like
# foo.o: sub/foo.c
# foo.o: sub/foo.h
# which is wrong. We want:
# sub/foo.o: sub/foo.c
# sub/foo.o: sub/foo.h
# sub/foo.c:
# sub/foo.h:
# ICC 7.1 will output
# foo.o: sub/foo.c sub/foo.h
# and will wrap long lines using \ :
# foo.o: sub/foo.c ... \
# sub/foo.h ... \
# ...
"$@" -MD -MF "$tmpdepfile"
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile"
exit $stat
fi
rm -f "$depfile"
# Each line is of the form `foo.o: dependent.h',
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
# Do two passes, one to just change these to
# `$object: dependent.h' and one to simply `dependent.h:'.
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
# Some versions of the HPUX 10.20 sed can't process this invocation
# correctly. Breaking it into two sed invocations is a workaround.
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
tru64)
# The Tru64 compiler uses -MD to generate dependencies as a side
# effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
# dependencies in `foo.d' instead, so we check for that too.
# Subdirectories are respected.
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
test "x$dir" = "x$object" && dir=
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
if test "$libtool" = yes; then
# With Tru64 cc, shared objects can also be used to make a
# static library. This mecanism is used in libtool 1.4 series to
# handle both shared and static libraries in a single compilation.
# With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
#
# With libtool 1.5 this exception was removed, and libtool now
# generates 2 separate objects for the 2 libraries. These two
# compilations output dependencies in in $dir.libs/$base.o.d and
# in $dir$base.o.d. We have to check for both files, because
# one of the two compilations can be disabled. We should prefer
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
# automatically cleaned when .libs/ is deleted, while ignoring
# the former would cause a distcleancheck panic.
tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4
tmpdepfile2=$dir$base.o.d # libtool 1.5
tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5
tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504
"$@" -Wc,-MD
else
tmpdepfile1=$dir$base.o.d
tmpdepfile2=$dir$base.d
tmpdepfile3=$dir$base.d
tmpdepfile4=$dir$base.d
"$@" -MD
fi
stat=$?
if test $stat -eq 0; then :
else
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
exit $stat
fi
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
do
test -f "$tmpdepfile" && break
done
if test -f "$tmpdepfile"; then
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
# That's a tab and a space in the [].
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
else
echo "#dummy" > "$depfile"
fi
rm -f "$tmpdepfile"
;;
#nosideeffect)
# This comment above is used by automake to tell side-effect
# dependency tracking mechanisms from slower ones.
dashmstdout)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout, regardless of -o.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test $1 != '--mode=compile'; do
shift
done
shift
fi
# Remove `-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
test -z "$dashmflag" && dashmflag=-M
# Require at least two characters before searching for `:'
# in the target name. This is to cope with DOS-style filenames:
# a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
"$@" $dashmflag |
sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
tr ' ' '
' < "$tmpdepfile" | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
dashXmstdout)
# This case only exists to satisfy depend.m4. It is never actually
# run, as this mode is specially recognized in the preamble.
exit 1
;;
makedepend)
"$@" || exit $?
# Remove any Libtool call
if test "$libtool" = yes; then
while test $1 != '--mode=compile'; do
shift
done
shift
fi
# X makedepend
shift
cleared=no
for arg in "$@"; do
case $cleared in
no)
set ""; shift
cleared=yes ;;
esac
case "$arg" in
-D*|-I*)
set fnord "$@" "$arg"; shift ;;
# Strip any option that makedepend may not understand. Remove
# the object too, otherwise makedepend will parse it as a source file.
-*|$object)
;;
*)
set fnord "$@" "$arg"; shift ;;
esac
done
obj_suffix="`echo $object | sed 's/^.*\././'`"
touch "$tmpdepfile"
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
rm -f "$depfile"
cat < "$tmpdepfile" > "$depfile"
sed '1,2d' "$tmpdepfile" | tr ' ' '
' | \
## Some versions of the HPUX 10.20 sed can't process this invocation
## correctly. Breaking it into two sed invocations is a workaround.
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
rm -f "$tmpdepfile" "$tmpdepfile".bak
;;
cpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout.
"$@" || exit $?
# Remove the call to Libtool.
if test "$libtool" = yes; then
while test $1 != '--mode=compile'; do
shift
done
shift
fi
# Remove `-o $object'.
IFS=" "
for arg
do
case $arg in
-o)
shift
;;
$object)
shift
;;
*)
set fnord "$@" "$arg"
shift # fnord
shift # $arg
;;
esac
done
"$@" -E |
sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
sed '$ s: \\$::' > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
cat < "$tmpdepfile" >> "$depfile"
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
rm -f "$tmpdepfile"
;;
msvisualcpp)
# Important note: in order to support this mode, a compiler *must*
# always write the preprocessed file to stdout, regardless of -o,
# because we must use -o when running libtool.
"$@" || exit $?
IFS=" "
for arg
do
case "$arg" in
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
set fnord "$@"
shift
shift
;;
*)
set fnord "$@" "$arg"
shift
shift
;;
esac
done
"$@" -E |
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile"
rm -f "$depfile"
echo "$object : \\" > "$depfile"
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
echo " " >> "$depfile"
. "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile"
rm -f "$tmpdepfile"
;;
none)
exec "$@"
;;
*)
echo "Unknown depmode $depmode" 1>&2
exit 1
;;
esac
exit 0
# Local Variables:
# mode: shell-script
# sh-indentation: 2
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

14
doc/README Normal file
View File

@ -0,0 +1,14 @@
What you can find in these sub-directories:
main_doc/ Essential documentation
articles/ Articles about various interesting topics
faq/ Frequently Asked Questions
howto/ Excuse me sir, how to do that?
manuals/ Online manual pages
misc/ Miscellanea documents

View File

@ -0,0 +1,51 @@
== Netsukuku and ICT infrastructure in the Developing World ==
{{{
Netsukuku network: enabled self-made and self-sustained ICT infrastructure
for developing countries.
The end-users, in order to connect their PC to the rest of the World
through the Internet, have to make a subscription with an Internet Operator.
The Domain Names, as well, are the unique way by which a network attached
device (which could consist of a computer, a file server, a network storage
device, a fax machine, a cable modem, etc.) is known on the Internet,
and are literally sold through the centralised system of the Domain
Name System (DNS). Netsukuku, an Open Source software, downloadable
from http://netsukuku.freaknet.org makes possible the creation of a
new distributed global Net, expandable to an unlimited number of users,
alternative, independent and totally apart from the Internet.
The Netsukuku particular routing system, created by some members of the
"Freaknet" group of Catania (Italy), allows the Net to be self-sustained,
thanks to all the Net users, that share a small part of their own PC
resources. Anybody has the chance to join the Net and, at the same time, to
let other users do the same.
In those countries and areas of the globe where Internet facilities are still
not available, a public Net can be created and developed in a very simple way
(i.e. through a wi-fi coverage), without depending on any Internet Operators.
In the same way, all the contents holder will be able to share any documents
simply from their PC, since a maximum of 256 hostnames can be recorded and
automatically supported by each PC (i.e. node of the Net).
Last but not least, inside Netsukuku Net all the users will have the chance to
get through the Internet: in fact any user can get the connectivity to
Internet from other users that share and devolve into the net the bandwidth
they don't use at the moment.
Netsukuku routing system differs from all the other protocols and algorithms:
the existing dynamic schemes are solely utilised to create small and medium
nets.
The routers of Internet are also managed by different protocols as the OSPF,
the RIP or the BGP, all based on different classical algorithms.
These algorithms are able to find out the best path to reach a node in the
net, but require a very high waste of CPU and memory. That's why inside
Internet, all the routers are powerful computers specifically dedicated to
this purpose. On the contrary, when a node hooks to Netsukuku, the net
automatically rewrites itself, while all the other nodes, using a very small
part of the CPU and of the memory resource (a few kb), recognised which are
the fastest and more efficient routes to communicate with the new arrived.
The nodes don't have privileges or limitations: when compared to other nodes,
they are part of the net and give their contribution to its expansion and
efficiency. The more they increase in number the more the net grows and
becomes stable. In Netsukuku there is no any difference between private and
public nets and talking about LAN become meaningless.
-CLazop

View File

@ -0,0 +1,29 @@
== Netsukuku can create a global Net indipendent from the Internet ==
{{{
The Open Source enables you to migrate towards free software, but there is
no chance to join your PC to the rest of the world in a free way.
Imagine to be titular of full membership into a global Network, without signing
contracts with any Internet Operators. Imagine to surf in a Net where there is
no central regulating Authority which assigns IP, conditions, names and
suffixes...
Netsukuku, an Open Source software, which can be downloaded from
http://netsukuku.freaknet.org, makes possible the creation of a new distributed
global Net, expandable to an unlimited number of users, independent and
totally apart from the Internet. Due to the Netsukuku particular routing
system, created by the "Freaknet" group of Catania (Italy), the Net is self
sustained, thanks to all the Net users, which share a small part of their
own PC resources. Anybody has the chance to join the Net and, at the same
time, to let other users do the same.
In this way, the countries and areas of the globe where Internet
facilities are still not available, simply through a wi-fi
coverage, can create and develop a Net without submitting themselves
to any Internet Operators or to any regulating central Authorities.
"I hope someday you'll join us
And the world will be as one...."
J.Lennon
-CLazop
}}}

View File

@ -0,0 +1,28 @@
{{{
L'Open Source vous permet de migrer vers une informatique libre, mais il
n'y a aucune possibilité de connecter votre ordinateur au reste du monde
en modalité libre.
Imaginez un Réseau global ou tout le monde peut entrer sans s'obliger avec des
fournisseurs d'accés a Internet.
Imaginez de naviguer dans un Net sans devoir vous soumettre à aucune Autorité
régulatrice centrale qui puisse contrôler les serveurs, établir les
conditions.
NETSUKUKU, un logiciel Open source, qui peut être téléchargé de
http://netsukuku.freaknet.org, rend possible la création d'un nouveau
réseau global distribué, extensible à un nombre illimité d'utilisateurs,
indépendant et totalement détaché de l'Internet. Grâce au système
particulier de cheminement de Netsukuku, créé par le groupe de "Freaknet"
de Catane (Italie), les utilisateurs de ce réseau en sont, aussi, les
membres actifs à travers le partage d'une petite partie des ressources de
leurs ordinateur. Quiconque a la possibilité de s'unir au Réseau et, en
même temps, de le faire grandir, l'objectif étant de créer et développer
un réseau libre, communautaire, citoyen, accessible à tous et permettant,
dans le respect des réglementations, la libre circulation des données.
Les pays et les régions du globe où Internet n'est encore pas disponible,
de cette façon, et simplement par l'utilisation d'une couverture wi-fi,
peuvent créer et développer un Réseau sans se soumettre aux Opérateurs
d'Internet ou à ses Autorités régulatrices centrales...
"And the world will be as one...."
J.Lennon

View File

@ -0,0 +1,19 @@
{{{
L'Open source da' la facolta' di migrare verso il software libero, ma non c'e'
alcuna possibilita' di collegare il proprio PC al resto del mondo senza
sottoscrivere abbonamenti con gli Operatori Internet o di navigare in una rete
libera da vincoli e condizionamenti.
Un software Open source, scaricabile all'indirizzo
http://netsukuku.freaknet.org, consente la creazione di una nuova rete globale
distribuita, espandibile ad un numero illimitato di utenti, indipendente e del
tutto staccata da Internet.
Grazie al particolare sistema di routing "Netsukuku" messo a punto dal gruppo
"Freaknet" di Catania, la Rete e' autogestita dagli stessi utenti, che mettono
in condivisione una piccolissima parte delle risorse del proprio PC. Chiunque
ha, cosi', la possibilita' di accedere alla Rete e sostenere, allo stesso
tempo, la sua espansione.
I paesi e nelle aree del globo attualmente escluse da Internet, tramite
Netsukuku e la semplice copertura wi-fi del territorio, possono, cosi', creare
ed implementare una Rete globale, senza ricorrere ne' al supporto degli
Operatori Internet ne' alle sue Autorita' regolatrici centrali.
}}}

View File

@ -0,0 +1,66 @@
== Netsukuku and the civic networks ==
{{{
Cities and Institutions are showing a growing interest in e-government
projects finilised in providing on line services to the citizens through
Internet.
For example are disposable:
- school related activities (enrolments, cultural and educational
programs),
- news, local radio and televisions
- guides for expositions and events, cultural and tourist information
- discussion forums, social and cultural activities
However, the diffusion and access to the Net isn't still disposable for
everyone: DSL facilities aren't available in many cities and the ISPs impose
expensive rates/costs to grant connectivity.
The creation of civic nets, in which the users can have free access to web
sites and to the on line e-services, surfing freely and without any cost web
sites dedicated to institutional, educational, tourist, commercial and social
activities, which need a constant and direct dialogue with the people, is
today made possible by NETSUKUKU Open Source software.
His first aim is the implementation of a global mesh network, completely
independent from Internet, in which the single PCs, communicating each other
through radio frequencies, become automatically the nodes/access points of the
net and in such way give their contribution to make it alive and, at the same
time, to expand it, exactly as in a fractal scheme.
The NETSUKUKU routing system allows:
- every user to go not only through the Net of their city but also through
those located in all the other cities which, once they are inter-connected,
create a kind of global Network, parallel to Internet, which can
indefinitely expand, completely without the support of ISPs;
- till a maximum of 256 hostnames to be recorded and supported by each PC
(i.e. node of the Net).
On the Netsukuku Net everybody wishing to offer digital contents/information,
will be able to share them simply from his or her PC. The more of actors
represented in the system is high in number, the more will be granted
dialogue, circulation of different ideas, democratic process and the full
right of citizenship inside the society of information.
Last but not least, inside Netsukuku Net users will have the chance to get
through the Internet free of cost: in fact any node can share with the
Netsukuku Net his connectivity to Internet and get from other users the
bandwidth they didn't use in any the moment.
=== How to realize a wireless Netsukuku Net ===
Netsukuku is an architecture of flexible net and will create autonomously an
efficient wireless mesh network among PCs equipped with radio connection
devices. The simplest way to create/join the Netsukuku Net is to install a
common wi-fi card inside your own PC and launch the Netsukuku program, freely
downloadable from Internet. The flux of data will reach the wished
destination, going through the same nodes (PCs or Access Points in which
Netsukuku as been installed inside), interconnected among them. Obviously a
larger diffusion of the Netsukuku dedicated network can be achieved by the
wi-fi coverage of wide urban and rural areas: in the market there are many and
different solutions of wireless devices, all valid and cheap (routers, access
points, omni directional antennas).
For more information or any request of assistance Netsukuku community is
available on the net at the following site:
http://netsukuku.freaknet.org

View File

@ -0,0 +1,68 @@
==== Netsukuku et les Réseaux citoyens ====
{{{
Les Institutions montrent un intérêt croissant pour des projets visant a'
fournir des services en ligne aux citoyens par l'Internet.
Par exemple les services suivants sont disponibles:
- services pour l'école (inscriptions, projets culturel et
éducatif),
- information, live web cam, radio locaux
- guides pour expositions et événements culturelle et touristiques
- forum de discussion, sociales et culturelles
Cependant, les citoyens n'ont pas libre accès aux services en ligne des
institutions, bien que les activités éducatives, administratives, commerciales
et sociales aient besoin d'une constante dialogue avec le public.
En fait, la diffusion et l'accès à l'Internet n'est pas encore a' la porté de
tous: l'ADSL n'est pas disponible dans beaucoup de région et les fournisseurs
d'accès imposent des prix trop hauts pour accorder la connectivité.
Le logiciel Open Source NETSUKUKU permet aux Institutions d'ériger un réseau
dans lequel les gens peuvent surfer sans besoin de supporter aucun coût ni de
s'abonner aux fournisseur d'accès.
Son but est la réalisation d'un réseau global, complètement indépendant de
l'Internet, dans lequel les ordinateurs, communiquant entre eux (par les
fréquences radio), deviennent automatiquement les noeuds du Réseau, donnent
leur contribution pour le maintenir et, en même temps, pour en permettre
l'expansion, exactement comme dans un schème à fractal.
Avec le système de cheminement NETSUKUKU, chaque utilisateur:
- navigue dans le réseau de sa ville, et également dans ceux situés dans
toutes les autres villes qui, une fois reliées, créent un réseau global,
parallèles à l'Internet, qui peut indéfiniment augmenter, complètement sans
l'appui de fournisseur;
- peut enregistrer jusqu'à un maximum de 256 hostnames, qu'il contient dans
son ordinateu.
Sur le réseau Netsukuku tout ceux qui souhaitent offrir contenus/informations
numériques, pourront les partager simplement avec leurs ordinateurs. Plus
d'acteurs seront représentés dans le système est plus large seront le
dialogue, la circulation des différentes idées, la participation au processus
démocratique et le droit de citoyenneté à l'intérieur de la société
d'information.
Enfin, les utilisateurs du réseau Netsukuku auront la chance d'accèder à
Internet exempt de coût: en fait n'importe tous les noeuds peuvent partager
avec le réseau Netsukuku leur connectivité à Internet et obtenir des autres
utilisateurs la largeur de bande qu'ils n'utilisent pas pour le moment.
=== Comment réaliser un réseau sans fil Netsukuku ===
Netsukuku est une architecture de réseau flexible et qui crée de façon
autonome un réseau wireless, efficace entre les ordinateur équipés de
dispositifs radio de raccordement.
La manière la plus simple de créer ou de s'unir à un réseau Netsukuku est
d'installer une commune carte wi-fi dans votre ordinateur et de lancer le
programme de Netsukuku, librement téléchargeable de l'Internet.
Le flux des données atteindra la destination souhaitée, passant par les noeuds
(les ordinateurs ou les points d'accès dans lesquels Netsukuku est installé à
l'intérieur), reliés ensemble entre eux.
Évidemment une plus grande diffusion du réseau consacré à Netsukuku peut être
réalisée par la couverture wi-fi de secteurs urbains et ruraux: sur le marché
il y a de nombreux et différents dispositifs sans fil, tous valides et à bon
marché ( access point, antennes omnidirectionnelles).
Pour plus d'information ou n'importe quelle demande d'aide, la communauté de
Netsukuku est disponible sur Internet a' l'adresse suivante:
http://netsukuku.freaknet.org

View File

@ -0,0 +1,91 @@
== Netsukuku e le reti civiche ==
{{{
Netsukuku e le reti civiche
Comuni, Enti ed Istituzioni stanno dimostrando un crescente interesse verso
progetti di e-government finalizzati a fornire servizi on line ai cittadini
attraverso Internet, chioschi informatici, call center, come
ad esempio:
- servizi amministrativi comunali (anagrafe, tributi locali, avvio e
monitoraggio di procedimenti amministrativi, ecc.)
- attivita' scolastiche (iscrizioni, iniziative culturali,progetti
educativi)
- portali territoriali, news, radio e live webcam locali
- guide per eventi e fiere, informazioni di interesse turistico e
culturale
- forum di discussione, sondaggi, iniziative socio-culturali.
Tuttavia, la diffusione e l'accesso alle reti civiche sono, oggi, limitati
dalla indisponibilita' della banda larga in molti Comuni e dai costi imposti
dagli Internet sevice provider (ISP) per fornire la connettivita'.
La realizzazione di reti telematiche cittadine, nelle quali gli utenti
possano accedere gratuitamente ai siti web ed ai servizi informatici di Enti
ed Istituzioni e' resa, oggi, possibile dal protocollo Netsukuku, che e' stato
ideato per permettere l'implementazione di una mesh network su scala globale,
indipendente da Internet, nella quale i singoli PC, collegandosi in frequenza
radio fra loro, diventano i nodi (router) della rete, e contribuiscono a
mantenerla e ad allargarla, secondo uno schema a frattale, recursivo ed a
crescita esponenziale.
Il protocollo Netsukuku abilita:
- gli utenti ad accedere non solo alla rete civica della propria citta' ma
anche a quelle allocate in tutte le citta' che, una volta interconesse,
formano una vera e propria ragnatela globale, parallela ad Internet, che
puo' espandersi indefinitamente, facendo sempre a meno di qualisiasi
operatore di telefonia o Internet (ISP);
- ciascun PC (ovvero nodo della rete) a supportare liberamente fino ad un
massimo di 256 hostnames.
Per collegarsi alla rete Netsukuku, gli utenti devono semplicemnte dotare
il proprio PC di una comune scheda wi-fi ed avviare il programma Netsukuku
scaricabile da Internet. E' evidente che una copertura del territorio
wi-fi a banda larga dedicata alla rete Netsukuku, ne puo' assicurare una
piu' rapida espansione. Il mercato del wireless mette ormai a disposizione
svariate soluzioni, tutte valide ed economiche (ripetitori, access point,
antenne ecc.)e Comuni, Istituzioni, Associazioni non-profit, Imprenditori
potranno cogliere l'opportunita' di sostenere questa rete come nuovo canale di
comunicazione efficace, affidabile, simile ma indipendente da Internet, ideale
per offrire a tutti la possibilita' di navigare liberamente e gratuitamente
in siti web dedicati ad attivita' istituzionali, educative, commerciali,
turistiche, promozionali e sociali, che richiedono un dialogo costante e
diretto col pubblico.
Sulla rete Netsukuku chiunque voglia, potra', semplicemente dal proprio
PC, offrire in rete contenuti digitali, informazioni e servizi informatici:
maggiore sara' il numero degli attori rappresentati nel sistema, piu' saranno
garantiti la patertecipazione, il dialogo, la circolazione delle idee,
il processo democratico ed il pieno esercizio del diritto di cittadinanza
nella nuova societa' dell'informazione.
La rete Netsukuku, infine, potra' essere utilizzata per connettersi
gratuitamente ad Internet:
infatti, qualsiasi nodo puo' condividere con la rete Netsukuku la
connettivita' ad Internet, a favore di chi non ha un account attivo con un ISP
o perche' ne e' provvisto o perche' si trova fuori sede.
Come realizzare facilmente una rete wireless Netsukuku:
La wireless mesh network di Netsukuku e' una architettura di rete flessibile
che fa muovere dati in maniera efficiente tra PC forniti di connessione radio,
in modo tale che il flusso di dati raggiunga la destinazione voluta, passando
attraverso gli stessi nodi (PC ovvero Access Point con Netsukuku installato)
interconnessi tra loro, e seguendo la rotta migliore.
Gli utenti potranno essere interconnessi tra loro, all'interno del raggio
d'azione delle proprie schede wi-fi o dei loro Access Point, sfruttando, ad
esempio, i supporti delle antenne televisive del loro palazzo, ove potranno
essere attaccate antenne wi-fi centralizzate (access point) o singole (schede
wi-fi).
Per favorire una piu' rapida e generale espansione della wireless mesh network
basata sul protocollo Netsukuku, bastera', poi, assicurare sul territorio la
presenza di semplici ripetitori wi-fi dotati di antenne omnidirezionali.
La comunita' di Netsukuku e' disponibile in rete, per qualsiasi ulteriore
informazione o richiesta di assistenza, sul sito:
http://netsukuku.freaknet.org
-CLazop
}}}

223
doc/faq/FAQ Normal file
View File

@ -0,0 +1,223 @@
0. General
Q: What is Netsukuku?
Q: What are its features?
Q: Why did you choose that name?
Q: What does it mean "it uses chaos and fractals"?
Q: Why another p2p network?
Q: Ehi! You're crazy. This shit will not work!
Q: Where are current Netsukuku networks that I can connect to?
Q: What can I do to help the development of Netsukuku? How can I
contribute to its growth?
1. Technical
Q: Does it scale in a network with A LOT of nodes?
Q: What do you intend to do to solve the IP unicity problem?
Q: Does it really works?
Q: Netsukuku is separated from Internet. How?
Q: How can I join in Netsukuku?
Q: And how does a new node begin to locate any of the other nodes in
the network?
Q: Will you provide "Internet to Netsukuku" tunnels?
Q: Aside from what I hack myself I was wondering what can be done on
the Netsukuku network?
Q: Will we be able to host websites anytime soon?
Q: Will glibc be able to resolve names for the ANDNA system?
Q: What sort of performance does Netsukuku have? Is it any good for
voice chat, video chat, games?
2. Software
Q: On what OS does it run?
Q: Will Netsukuku be ported to Windows?
Q: Will Netsukuku be ported to PSP / Nintendo DS / wifi phones / PDAs?
Q: How does it join the network?
Q: For using a wifi link do I need of an access point? What to do?
Q: Why the code is not written in java?
--
/ \
0. General
\ /
Q: What is Netsukuku?
A: Netsukuku is a mesh network or a p2p net system that generates and sustains
itself autonomously. It is designed to handle an unlimited number of nodes
with minimal CPU and memory resources. Thanks to this feature it can be
easily used to build a worldwide distributed, anonymous and anarchical
network, separated from the Internet, without the support of any servers,
ISPs or authority controls.
This net is composed by computers linked physically each other, therefore it
isn't build upon any existing network. Netsukuku builds only the routes which
connects all the computers of the net.
In other words, Netsukuku replaces the level 3 of the model iso/osi with
another routing protocol.
The Domain Name System is also replaced by a decentralised and distributed
system: the Abnormal Netsukuku Domain Name Anarchy.
For more information read the section "2.3 So, WTF is it?" of the
document ( http://netsukuku.freaknet.org/doc/netsukuku )
Q: What are its features?
A: The complete list of features is here:
http://netsukuku.freaknet.org/files/doc/misc/Ntk_features_list
Q: Why did you choose that name?
A: Networked Electronic Technician Skilled in Ultimate Killing, Utility and
Kamikaze Uplinking.
But there is also another story: we were learning Japanese katakana with
`slimeforest', a nice game for GNU/Linux.
Unfortunately when we encountered the "Network" word, written in Japanese,
we didn't know all the relative symbols, so the only katakana we were able
to read were few and mixed with others the name was: Ne tsu ku ku.
By the way, you can always think of any other deceitful and hidden
meanings.
Q: What does it mean "it uses chaos and fractals"?
A: The Netsukuku protocol (Npv7) structures the entire net as a fractal and,
in order to calculate all the needed routes which are necessary to connect a
node to all the other nodes, it makes use of a particular algorithm called
Quantum Shortest Path Netsukuku (QSPN).
Here a fractal is meant as a highly clusterized graph of nodes.
(For the in depth description of the map system in Netsukuku read the
"5.3 The truly Gnode^n for n<=INFINITE" section in the document.)
On the other hand, the QSPN is a meta-algorithm in the sense that it
has to run on a real (or simulated) network. The nodes have to send the
QSPN pkt in order to "execute" it. For this reason it is not always true
that a determinate pkt will be sent before another one.
This system allows to get the best routes without any heavy computation.
(read the "5.1 QSPN: Quantum Shortest Path Netsukuku" section in the
document).
Q: Why another p2p network?
A: Netsukuku is not a p2p net built upon the Internet. It is a physical
network and it is a dynamic routing system designed to handle 2^128 nodes
without any servers or central systems, in this way, it is possible to
build a physical network separated from the Internet. Btw, read "What is
Netsukuku".
Q: Ehi! You're crazy. It won't work!
A: Ehi pal, this doesn't pretend to be _now_ the final solution to the meaning
of life, the universe and everything. Why don't you contribute and give us
useful hints from your great knowledge? If you want to help in the
development, read the code and contact us ;)
Q: Where are current Netsukuku networks that I can connect to?
A: Simply we don't know and we can't, but the website team si developing a
community portal which will ease the difficulty of coordination. (Think of
Google maps).
Q: What can I do to help the development of Netsukuku? How can I contribute to
its growth?
A: http://lab.dyne.org/Ntk_Grow_Netsukuku
/ \
1. Technical
\ /
Q: Does it scale in a network with A LOT of nodes?
A: Simple and not accurate reasons for the scalability of Netsukuku (until there
is the technical documentation with math background that is being written):
1) the size of the maps is fixed: about 4Kb for the int_map and 16Kb for
the ext_map.
2) Not all the nodes sends a broadcast discovery.
3) There are few floods for each discovery.
4) When a node receives a flood it already has the routes without
calculating anything.
5) A flood is synchronized: the same flood starts at the same time for all
the nodes.
A first draft of the explanation of the Netsukuku scalability is available
here: http://lab.dyne.org/Netsukuku_scalability
Q: What do you intend to do to solve the IP unicity problem?
A: It is already solved: http://lab.dyne.org/Ntk_gnodes_contiguity
Q: Does it really works?
A: ^_^
Q: Netsukuku is separated from Internet. How?
Someone is building all new infrastructure? Who's paying for that?
A: Not at all, there is no need to pay. The best way to physical link two
nodes is using the wifi. Nowadays, there are a lot of cool wifi
technologies, which allows to link two nodes distant kilometres each other.
In the city there would be no problems, it suffices only a node for
each neighbourhood and the city will be completely covered.
Q: How can I join in Netsukuku?
A: Take out your wifi antenna, and start the Netsukuku daemon on the relative
network interface, then wait and tell to do the same thing to all your
friends ^_-
Q: And how does a new node begin to locate any of the other nodes in the
network?
A: The Netsukuku radar sends echo packets about every 10 seconds, if someone
replies it communicates with it.
Q: Will you provide "Internet to Netsukuku" tunnels?
A: Yes, they will be used to link close cities. Please read this for more
information:
http://lab.dyne.org/Ntk_Internet_tunnels
Q: Aside from what I hack myself I was wondering what can be done on the
Netsukuku network?
A: Whatever you already do in the actual Internet. What the Netsukuku daemon
does is to only set the routes in the kernel routing table.
Q: Will we be able to host websites anytime soon?
A: You can do it by now!
Q: Will glibc be able to resolve names for the ANDNA system?
A: ANDNA comes with a DNS wrapper so it is trasparent to all the programs
which uses the glibc. Read "man andna":
http://netsukuku.freaknet.org/doc/manuals/html/andna.html
Q: What sort of performance does Netsukuku have? Is it any good for voice chat
video chat?
A: What do you mean by `performance'?
Network performance: it is dependent on the links quality. If the nodes are
linked by 100Mbps cable you will feel like in a large LAN.
The distance from yourself and the destination node is also relevant.
Remember that the Netsukuku daemon chooses only the best way to reach
the other nodes, but cannot improve the roads themself.
Software performance: you really shouldn't worry about this:
PID USER PRI NI SIZE RSS SHARE %CPU %MEM TIME CPU COMMAND
18521 root 15 0 17708 1552 1164 0.0 0.3 0:00 0 ntkd
/ \
2. Software
\ /
Q: On what OS does it run?
A: For now it runs only on GNU/Linux, but it is easy to port it on other OS.
If you want to join in the development let us now ;)
Q: Will Netsukuku be ported to Windows?
A: Short answer: if you code the port, yes.
Answer: We need coders for that. There are a lot of things to be done and
the Windows port is what we care less.
Q: Will Netsukuku be ported to PSP / Nintendo DS / wifi phones / linux PDAs
etc...
A: We are currently working on flashing Netsukuku on Access Points (like
Linksys). See http://netsukuku.freaknet.org/openwrt/
Q: For using a wifi link do I need of an access point? What to do?
A: You just need a wifi network card. Put it in ad-hoc mode using "netsukuku"
as essid. ( man netsukuku_wifi:
http://netsukuku.freaknet.org/doc/manuals/html/netsukuku_wifi.html )
Q: Why the code is not written in java?
A: Are you kidding?
--
Q: My question is not answered here!
A: Contact us: http://netsukuku.freaknet.org

27
doc/faq/FAQ.fr Normal file
View File

@ -0,0 +1,27 @@
= Questions fréquentes sur Netsukuku (fr) =
== 0. Généralités ==
=== 0.1. Qu'est-ce que Netsukuku ? ===
Netsukuku est un réseau maillé ou un système P2P qui se génère et entretient son fonctionnement de façon autonome. Il est conçu pour gérer un nombre illimité de n?uds avec des ressources en puissance de calcul et en mémoire minimales. Il peut ainsi être facilement utilisé pour bâtir un réseau mondial distribué, anonyme et anarchique, distinct d'Internet, sans recourir à aucun serveur, fournisseur d'accès ou autorité de contrôle.
Gardez à l'esprit qu'il s'agit d'un réseau ''physique'' : il ne se fonde sur aucun autre réseau existant. Il doit par conséquent y avoir des ordinateurs reliés ''physiquement'', Netsukuku créant ensuite les routes.
En d'autres termes, Netsukuku remplace le niveau 3 du modèle ISO/OSI par un autre protocole de routage.
Pour plus d'informations, lisez la section 2.4, ''Mais qu'est-ce que c'est, à la fin ?'' de la documentation.
=== 0.2. Quelles sont ses fonctionnalités ? ===
La liste complète des fonctionnalités se trouve ici : [http://netsukuku.freaknet.org/files/doc/misc/Ntk_features_list].
=== 0.3. Pourquoi avoir choisi ce nom ? ===
Nouveaux Électriciens Trappistes Sans Kimono Unissant Karma et Urbanité.
Mais il y a une autre histoire, aussi. Nous apprenions les katakanas japonais avec slimeforest, un chouette jeu pour GNU/Linux.
Malheureusement, quand nous sommes tombés sur le mot ''réseau'' écrit en japonais, nous ne connaissions pas tous les symboles employés ; nous ne pouvions donc lire que quelques katakanas et, mélangés avec d'autres, ça donnait le nom Ne-tsu-ku-ku.
Bon, mais vous pouvez toujours imaginer d'autres significations exotiques...

65
doc/faq/FAQ.ru Normal file
View File

@ -0,0 +1,65 @@
= ???????? =
??? ????? Netsukuku:: Netsukuku - ??? P2P ???? ? ???????? ?????????? ??????? ????????? ? ?????????????? ??????????????. ??? ???????? ???????????? ?????????????? ?????????? ????? ? ???????????? ????????? ???????? ?????????? ? ??????. ????????? ????? ??? ????? ???? ??????? ??? ???????? ?????????? ??????????????, ????????? ? ???????????? ????, ?? ????????? ? ??????????, ??? ????????, ??????????? ??? ???????? ???????. ???? ????????? ??? Netsukuku ? ??? ?????????? ????, ?? ?????????? ??? ?????-???? ???????????? ?????, ???? ? ??? ?????? ???? ????????? ??????? ????? ????? ????? Netsukuku ????????? ??????? ?????????????. ??????? ??????? Netsukuku ???????? 3-? ??????? ??????? ?????? ISO/OSI (??????? ???????) ????? ?????????? ?????????????.[[BR]](??????: "2.4 So, WTF is it?" http://netsukuku.freaknet.org/?p=Documentation)
?????? ??????? ??? Netsukuku?:: Networked Electronic Technician Skilled in Ultimate Killing, Utility and Kamikaze Uplinking ? ??????? ??????????? ?????????? ???????????? ? ?????????? ???????????, ???????????? ? ??????????? ????? ?????????. [[BR]] ???? ??? ?? ?????? ??????. ?? ??????? ???????? ????? ? «slimeforest» ???? ??? GNU/Linux. ? ????????? ????? ?? ??????????? ?? ?????? «Network» ?????????? ?? ??????? ?? ?? ????? ?????????? ????????, ??? ??? ???????????? ????? ???????? ??????? ??? ??????? ????????? ? ??? ????: Ne tsu ku ku. ?????? ?? ?????? ?????? ????????? ???? ?????????? ????? ? ??????? ? ??? ?????? ?????.
??? ?????? «?????????? ??????????? ? ????????»?:: ???????? Netsukuku (Npv7) ????????????? ??? ???? ??? ??????? ? ??? ?????????? ????????? ??????????? ???? ??? ?????????????? ? ????? ?????????? ???????? ?????????? ??????????? ???? Netsukuku (QSPN). ????? ??? ????????? ?????????? ???? ? ??????? ???????? ????????????? ?????????. [[BR]] (??????: 5.3 The truly Gnode^n for n<=INFINITE" http://netsukuku.freaknet.org/?p=Documentation) [[BR]] ? ?????? ??????? QPSN ? ????-???????? ????? ?? ??????????? ? ???????? ???????? ???? (??? ?????????). ??? ??? «??????????» ???? ?????? ??????? QPSN pkt(?????). ??????? ?? ?????? ????? ??? ???????????? ????? ????? ?????? ????? ????? ??????. ??? ????????? ????????? ?????? ???? ??? ??????? ??????????. [[BR]] (??????: "5.1 QSPN: Quantum Shortest Path Netsukuku" http://netsukuku.freaknet.org/?p=Documentation)
??? ???? ??? ???? p2p ?????:: Netsukuku ?? p2p ??????????? ?????? ?????????. ??? ?????????? ???? ? ?? ????? ???????????? ????????????? ?????????????? ??? ???? ? 2^128 ????? ??? ???????? ??? ???????????????? ???????, ????? ??????? ???????? ????????? ??????????? ?? ????????? ????. ??????, ?????????? «??? ????? Netsukuku»
??! ?? ?? ???????. ??? ????? ?? ????? ????????!:: ??, ?????? ??? ?? ???????? ???? ????????????? ???????? ????????? ??????? ?????, ????????? ? ????? ??????????. ?????? ?? ?? ????????? ????-?????? ? ?????? ? ?? ?????????? ?????? ?????????? ???????????? ??????????? ???? ?????? ?????? ? ?????????? ????? ??? ? ??????? ? ???? ;)
??? ???? ???? Netsukuku ? ??? ? ??? ???????????????:: ?? ?? ?????? ?????, ?? ? ?? ????? ?????, ?? ?? ?????? ????? ??????? ????????? ??????, ??????? ???????? ???????????.
??? ? ???? ?????? ???????? Netsukuku? ??? ? ?????? ????? ? ?? ?????:: ??????? ????: http://lab.dyne.org/Ntk_Grow_Netsukuku
= ??????????? ????? =
??? Netsukuku ?????????????? ? ???? ? ??????? ??????????? ??????:: ??????? ? ?? ?????? ?????? ??????? ???????????????? Netsukuku (?? ??? ??? ???? ?? ????? ???????? ???. ???????????? ? ?????????????? ????????????):
1. ?????? ????? ??????????, ????? 4?? ??? int_map ? 16?? ??? ext_map.
1. ?? ??? ???? ???????? ????????????????? ?????? ??? ??????????? ???????? ????? (broadcast discovery)
1. ????????????????? ?????? ?????????????? ????????????.
1. ? ?????? ????????? ?????????????????? ?????? ???? ???????? ??????????? ???? ??? ?????-???? ??????????
1. ??????? ????????????????, ??? ???? ???????? ????????????? ????????????.
???????? ?????????? ???????????? ???????????????? Netsukuku ???????? ?? ??????: http://lab.dyne.org/Netsukuku_scalability
??? ?????????????? ?????? ???????? ?????????? IP ??? ????????? ??????:: ???????? ??? ??????: http://lab.dyne.org/Ntk_gnodes_contiguity
??? ??? ????????????? ?????????:: :)
Netsukuku ?????????? ?? ?????????. ???? ???-?? ?????? ?????????? ????? ??????????????? ??? ?? ??? ??? ???????:: ????? ???, ??????? ?? ????. ?????? ?????? ????????? ??????? ??? ???? ? ???????????? ?????????? (Wi-Fi). ?????? ?????????? ????????? ???????????? ?????????? ??????????? ???????? ????? ????? ???? ?? ?????????? ? ?????????. ? ??????? ?? ?????? ???? ?????-???? ???????, ?????????? Wi-Fi ???? ?? ?????/??????? ??? ??????? ????????.
??? ?????????????? ? Netsukuku?:: ?????????? Wi-Fi ???????, ????? ????????? Netsukuku ????? ?? ??????????????? ??????? ??????????. ?????, ? ?? ???????? ??????? ??????? ??????? ???? ????? ^_-
??? ????? ???? ???????????? ?????? ? ?????:: «?????» Netsukuku ???????? ??? ?????? ?????? 10 ??????, ???? ???-?????? ????????, ????????????? ?????.
?????-?? ????????????? «Netsukuku ? ????????» ????????:: ??, ??? ?????????? ????? ????????. ????? ???????? ???: http://lab.dyne.org/Ntk_Internet_tunnels
????? ??????????? ??? ? ???? ?????? ? ???? Netsukuku?:: ???? ????? ??? ????? ?????? ? ?????????. ????? Netsukuku ?????-???? ??????????? ???????? ? ??????? ????????????? ????.
?????-?? ????? ??????????? ??????:: ????? ??? ??????.
??????-?? glibc ??????????????? ????? ?? ANDNAv?:: ? ANDNA ???? ??????? DNS ??? ??? ??? ????????? ??? ???? ???????? ???????????? glibc. [[BR]] (?????? "man andna": http://netsukuku.freaknet.org/doc/manuals/html/andna.html )
?????? ?????????????????? Netsukuku? ???? ?? ???????????? ??? ?????- ??? ??????????:: ??? ??????????????? ??? «???????????????????»? [[BR]] ??????? ??????????????????: ??????? ?? ?? ???????? ?????. ???? ???? ??????? 100??/? ??????? ?? ????? ???????? ??????? ?? ??????? LAN. ?????????? ????? ?????? ????? ????? ????????. ???????? ??? ????? Netsukuku ???????? ????????? ??????? ?? ?????? ?????, ?? ?? ????? ???????? ??. [[BR]] ??????????? ??????????????????: ?? ???? ?? ????? ?????? ????????????:
{{{ PID USER PRI NI SIZE RSS SHARE %CPU %MEM TIME CPU COMMAND
18521 root 15 0 17708 1552 1164 0.0 0.3 0:00 0 netsukuku_d }}}
= ??????????? ????? =
?? ????? ???????????? ??????? ??????????? Netsukuku?:: ???? ?????? GNU/Linux, ???????? ??????????? ?? ????? ??. ???? ???? ??????? ???? ???????? ????? ??? ????? ;)
?????-?? Netsukuku ??? Windows?:: ???????? ?????: ???? ?? ????????, ?? ??. [[BR]] ?????: ??? ????? ??? ?????????? ??????, ???? ??????? ?????? ???? ??? ?????????? ??? ??????? ? ???? ?? Windows ?? ????????? ?????.
?????-?? Netsukuku ?????????? ?? PSP / Nintendo DS / Wi-Fi ?????????? / Linux
??? ? ??? ??????:: ?????? ?? ???????? ??? Netsukuku ??? ???????????? ?????
??????? (???????? Linksys). (http://netsukuku.freaknet.org/openwrt/)
??? ??????????? Wi-Fi ??? ????? ????? ????????:: ?????????? Wi-Fi ???????
?????. ?????????? ?? ? ????????? ?????????? (ad-hoc) ????????? «netsukuku»
??? essid [[BR]] (man netsukuku_wifi: http://netsukuku.freaknet.org/doc/manuals/html/netsukuku_wifi.html )
?????? ?? ?? ?????? ?? Java?:: ??? ????? ??????
????? ??????? ??? ???!:: ??? ????: http://netsukuku.freaknet.org/

147
doc/howto/igs_howto Normal file
View File

@ -0,0 +1,147 @@
Internet connection sharing in Netsukuku HOWTO
This document describes how to configure a Netsukuku node to share its
Internet connection and how to configure another node that will use the shared
connection.
--
* Internet Gateway Search
* Prerequisites
* How to share your Internet connection
* How to connect to the Internet using a shared connection
* Some nice feature you want to know
--
**
*** Internet Gateway Search
**
If the nodes are in restricted mode (compatibility with the Internet), they
can share their Internet connection. This can be easily done, in fact, if a
node X, connected to the Internet, activates the masquerading, it is possible
for the other nodes to connect by setting as the default gateway their rnode
which lead to the node X.
This can be automated by Netsukuku itself.
The node which is sharing its connection will tell to the Netsukuku daemon to
masquerade its connection and to set a specific flag in the QSPN packets.
The other nodes in restricted mode will automatically know their nearest
Netsukuku Internet gateway and set it in their default route.
For more information read http://lab.dyne.org/Ntk_IGS .
**
*** Prerequisites
**
The IGS code of Netsukuku depends on the IPIP tunnel code of the kernel, so if
you are using Linux be sure to have the `CONFIG_NET_IPIP' option set as a
module or built-in.
**
*** How to share your Internet connection
**
First of all modify the /etc/netsukuku/netsukuku.conf file.
Set `internet_connection' to 1.
Set the `internet_gateway' option to the IP of the gateway you use to reach
the Internet and specify the network interface too, for example:
"internet_gateway = 192.168.1.1:eth0". This option is necessary only if you
don't have the default route set when you run NetsukukuD (i.e. you haven't
connected yet), otherwise, leave it commented.
You have also to set your upload and download bandwidth in
`internet_upload_rate' and `internet_download_rate'. It is expressed in Kb/s,
so if you have a line which maximum can do: 640 Kb/s in dwload and 30 Kb/s in
upload, set them to 640 and 30.
`internet_ping_hosts' is a list of Internet hosts which will be pinged to
verify if the connection is alive, you can use the default hosts.
Finally, If you want to share your Internet connection among other Netsukuku
nodes, set `share_internet' to 1.
Ah, and you can set `shape_internet' to 1 if you want to shape your outgoing
Internet traffic.
---- netsukuku.conf snip ----
internet_connection = 1
internet_gateway = 192.168.1.1:eth0
internet_download_rate = 640
internet_upload_rate = 30
internet_ping_hosts = google.com:cisco.com:sourceforge.net:dyne.org
share_internet = 1
shape_internet = 1
---- snip end ----
Now you are ready to launch the Netsukuku daemon. You have just to append the -I
option in the command line. For example:
# ntkd -i wlan0 -r -I
**
*** How to connect to the Internet using a shared connection
**
Just start the daemon in restricted mode, f.e:
# ntkd -i wlan0 -r
If you have an Internet connection and you don't want to share it, you have to
set the correct options in netsukuku.conf:
---- netsukuku.conf snip ----
internet_connection = 1
internet_gateway = 192.168.1.1:eth0
internet_download_rate = 640
internet_upload_rate = 30
internet_ping_hosts = google.com:cisco.com:sourceforge.net:dyne.org
share_internet = 0
---- snip end ----
If you don't, your Internet connection default route will be overwritten with
that of another node.
**
*** Some nice feature you want to know
**
NetsukukuD supports a routing method called "multi inet gateway", this means
that your node can connect to the Internet using, at the same time, multiple
node which share their connection.
If there are 5 nodes which share their 640Kb/s connections, you can have 5
parallel downloads at 640Kb/s. Isn't it juicy?
There's more: if you decide to share your Internet connection, you will always
use the Internet connections shared by the other nodes, in this way you donate
your bandwidth but, at the same time, you receive donations from other users.
The other nice feature is the traffic shaping of your Internet connection (it
doesn't matter if you're sharing it or not).
If you decide to enable the relative option (shape_internet=1), NetsukukuD
will execute the /etc/netsukuku/tc_shaper.sh script.
This script shapes your Internet connection, this means that the traffic
generated from your private LAN (192.168.x.x) and the low delay traffic (i.e.
DNS, ssh...) are prioritised.
The benefits are:
* Even if you share your Internet connection to other Netsukuku nodes, your
traffic will have the maximum priority, therefore you won't notices any
slowdown
* Even if you are downloading a big file, your lowdelay traffic will have the
priority, therefor your ssh connections won't slow a bit
PS: for more information read: http://lab.dyne.org/Ntk_IGS
That's all,
enjoy ^_^

1616
doc/main_doc/netsukuku Normal file

File diff suppressed because it is too large Load Diff

1208
doc/main_doc/netsukuku.ita Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,130 @@
== NTK_RFC 0003 ==
Subject: Internet Gateway Search
----
This text describes a change to the Npv7.
It will be included in the final documentation, so feel free to correct it.
But if you want to change the system here described, please contact us first.
----
If the nodes are in restricted mode (compatibility with the Internet), they
should share their Internet connection. This can be easily done, in fact, if
a node X, connected to the Internet, activates the masquerading, it is
possible for the other nodes to connect by setting as the default gateway
their rnode which lead to the node X.
This can be automated by Netsukuku itself and it requires small changes in the
code: it is just necessary that the nodes connected to the Internet set a flag
in the qspn_pkt, in this way the other nodes will know the routes to reach the
Internet.
=== Multi-gateways ===
The situation becomes a little complex when there is more than one node which
shares its internet connection. Let's consider this scenario:
{{{
A(gw) B(gw)
\ /
\___ ___/
\/
Ntk nodes (10.x.x.x)
}}}
A and B are nodes which shares their internet connection, we call them
gateways. Let's call X the node which wants to connect to an Internet host.
In this case, the nodes near A, might find useful to use A itself to
reach the Internet, the same happens for the nodes near B.
Instead, the nodes in the middle don't know what is the best choice and they
might continuosly change their gw. This means that a tcp connection
(to an inet host), which was established trough A, when is then routed trough
B dies because A and B have different public IPs on the Internet.
The node X has to create an IPIP tunnel to the gateway it wants to use, and
set as default gw the tunnel. In this way, the node X is sure to always use
the same gateway while the routing of the packets between it and the gw is
made transparently by the other Netsukuku nodes.
==== Anti loop multi-inet_gw shield ====
An inet-gw is a normal node like all the other, therefore it can use the
Internet connections of the other inet-gws in conjunction with its own one.
Consider the previous scenario, A and B are two inet-gw.
A sets in his internet default route the adsl modem and B.
B does the same, but sets A as the second default route.
What would happen if the default route, written in the routing cache of A, is
B and, at the same time, the default route set in the routing cache of B is A?
The packets would jump endlessy in a infinite loop loosing themself forever.
That's why we need the "anti loop multi-inet_gw shield".
It's working way is simple: each inet-gw has a netfilter rule which marks
all the packets coming from the outside and directed to the Internet. These
packets are then routed directly to the Internet without being sent, again, to
an inet-gw. In the example:
A wants to send a packet to the Internet and its looks in its routing cache.
It decide to forward the packet to B. B receives the packet, recognizes it is
an extern packet directed to the Internet and shoots it on its modem.
=== Load sharing ===
Let's consider the previous scenario.
The node X can also decide to use both A and B to reach the Internet, using
at the same time their connections! Even the gw A can use at the same time
its own line and the connection of the gw B.
The procedure to implement this is what follows:
* X creates a tunnel to A and another one to B
* X adds in the routing table the default route using A and B as multipath
gateways. The gateway for the connections is chosen randomly.
* X adds a rule in the routing table to route all the packets of established
connections trough the same gateway used to create the same connection.
The rule is linked to some netfilter rules which track and mark each
connection. The method is described in details here:
https://lists.netfilter.org/pipermail/netfilter/2006-March/065005.html
=== The bad ===
The implementation of the Load sharing is very Linux specific, so it will be
very difficult to port it to other kernels, therefore this feature will be
available only to nodes which run Linux (ehi, one more reason to use Linux ;).
=== MASQUERADING ===
Each node sharing the Internet connection (inet-gw) has to masquerade its
interfaces, so iptables must be used.
In order to keep the daemon portable, NetsukukuD will launch the script found
at /etc/netsukuku/masquerade.sh, which in Linux will be a simple script that
executes "iptables -A POSTROUTING -t nat -j MASQUERADE".
When NetsukukuD is closed the added firewall rules are flushed with
"/etc/netsukuku/masquerade.sh close"
=== Traffic shaping ===
The inet-gw can also shape its internet connection in order to prioritize its
local outgoing traffic (the traffic coming from its 192.168.x.x LAN).
In this way, even if it shares its Internet connection, it won't notice any
difference 'cause it will have the first priority. Moreover with the traffic
shaper, the inet-gw can also prioritize some protocol, i.e. SSH.
The traffic shaper will activated at the start of NetsukukuD. The daemon will
run the /etc/netsukuku/tc_shaper.sh script, which in Linux utilizes the
iproute2 userspace utility.
When the daemon is closed the traffic shaping will be disabled with
"/etc/netsukuku/tc_shaper.sh close".
=== See also ===
For more information on the necessity of using ipip tunnels in an adhoc
network used to share internet connections, you can read this paper:
http://www.olsr.org/docs/XA-OLSR-paper-for-ICC04.pdf
----
related: ["Netsukuku RFC"]

View File

@ -0,0 +1,56 @@
== NTK_RFC 0004 ==
Subject: Mail Exchange request
----
This text describes how the MX DNS query are resolved by ANDNA.
* WARNING *
This RFC has been deprecated by the NTK_RFC 0009
* WARNING *
----
In the DNS the resolution of the MX field is handled directly by the DNS
servers, in ANDNA, instead, the resolution of an MX hostname is a redirect
request. In short it means that the request, instead of being sent to a
hash_node, is sent to the register_node itself,
== hname MX resolution ==
The resolution of a MX hostnames in ANDNA works in this way:
* We are trying to resolve the MX of the "pippo" hname.
* "pippo" is resolved normally and the IP of the register_node is gained.
* We ask to the register_node the IP of its MX.
== hname MX registration ==
Since the IP of the MX node can change during the time, the register_node must
be aware of its current IP.
It is the MX node itself that tells the register_node its current IP each time
it changes. The MX node to contact the register_node has to simply resolve its
hname.
The register_node has to verify the authenticity of the IP update request,
therefore the MX node will sign the request with the private key of the
register_node.
This system is necessary because the MX node and the register node have to be
synced. In this way when the register_node dies or can't be reached anymore,
the MX node can't be contacted too.
Moreover this system prevents the spoofing of the MX node.
The steps necessary to register a hname MX are:
* Copy the ANDNA private key of the register node, which is saved in its lcl_cache, to the MX node:
{{{
register_node# scp /usr/share/netsukuku/andna_lcl_keyring mx_node:/etc/netsukuku/mx/<HNAME_MX>
# <HNAME_MX> is the hname relative to the MX node
}}}
* Send a SIGHUP to the MX NetsukukuD:
{{{
register_node# ssh mx_node "killall -HUP ntkd"
}}}
If no MX is associated to an hostname, the register_node will use its own IP
as the default MX IP.
----
related: [Netsukuku_RFC]

View File

@ -0,0 +1,203 @@
== NTK_RFC 0009 ==
Subject: Scattered Name Service Disgregation
----
This text describes the Scattered Name Service Disgregation, an extension of
the ANDNA protocol.
It will be included in the final documentation, so feel free to correct it.
But if you want to change the system here described, please contact us first.
----
== SNSD ==
The Scattered Name Service Disgregation is the ANDNA equivalent of the
SRV Record of the Internet Domain Name System, which is defined here:
http://www.ietf.org/rfc/rfc2782.txt
For a brief explanation you can read:
http://en.wikipedia.org/wiki/SRV_record
SNSD isn't the same of the "SRV Record", in fact, it has its own unique
features.
With the SNSD it is possible to associate IPs and hostnames to another
hostname.
Each assigned record has a service number, in this way the IPs and hostnames
which have the same service number are grouped in an array.
In the resolution request the client will specify the service number too,
therefore it will get the record of the specified service number which is
associated to the hostname. Example:
The node X has registered the hostname "angelica".
The default IP of "angelica" is 1.2.3.4.
X associates the "depausceve" hostname to the `http' service number (80) of
"angelica".
X associates the "11.22.33.44" IP to the `ftp' service number (21) of
"angelica".
When the node Y resolves normally "angelica", it gets 1.2.3.4, but when
its web browser tries to resolve it, it asks for the record associated to
the `http' service, therefore the resolution will return "depausceve".
The browser will resolve "depausceve" and will finally contact the server.
When the ftp client of Y will try to resolve "angelica", it will get the
"11.22.33.44" IP.
If Y tries to resolve a service which hasn't been associated to anything, it
will get the mainip 1.2.3.4.
The node associated to a SNSD record is called "SNSD node". In this example
"depausceve" and 11.22.33.44 are SNSD nodes.
The node which registers the records and keeps the registration of the main
hostname is always called "register node", but it can also be named "Zero SNSD
node", in fact, it corresponds to the most general SNSD record: the service
number 0.
Note that with the SNSD, the NTK_RFC 0004 will be completely deprecated.
== Service, priority and weight number ==
==== Service number ====
The service number specifies the scope of a SNSD record. The IP associated to
the service number `x' will be returned only to a resolution request which has
the same service number.
A service number is the port number of a specific service. The port of the
service can be retrieved from /etc/services.
The service number 0 corresponds to a normal ANDNA record. The relative IP
will be returned to a general resolution request.
==== Priority ====
The SNSD record has also a priority number. This number specifies the priority
of the record inside its service array.
The client will contact first the SNSD nodes which have the higher priority,
and only if they are unreachable, it will try to contact the other nodes
which have a lower priority.
==== Weight ===
The weight number, associated to each SNSD record, is used when there are
more than one records which have the same priority number.
In this case, this is how the client chooses which record using to contact
the servers:
The client asks ANDNA the resolution request and it gets, for example, 8
different records.
The first record which will be used by the client is chosen in a pseudo-random
manner: each record has a probability to be picked, which is proportional to its
weight number, therefore the records with the heavier weight are more likely to
be picked.
Note that if the records have the same priority, then the choice is completely
random.
It is also possible to use a weight equal to zero to disable a record.
The weight number has to be less than 128.
== SNSD Registration ==
The registration method of a SNSD record is similar to that described in the
NTK_RFC 0004.
It is possible to associate up to 16 records to a single service.
The maximum number of total records which can be registered is 256.
The registration of the SNSD records is performed by the same register_node.
The hash_node which receives the registration won't contact the counter_node,
because the hostname is already registered and it doesn't need to verify
anything about it. It has only to check the validity of the signature.
The register node can also choose to use an optional SNSD feature to be sure
that a SNSD hostname is always associated to its trusted machine. In this
case, the register_node needs the ANDNA pubkey of the SNSD node to send a
periodical challenge to the node.
If the node fails to reply, the register_node will send to ANDNA a delete
request for the relative SNSD record.
The registration of SNSD records of hostnames which are only queued in the
andna_queue is discarded.
Practically, the steps necessary to register a SNSD record are:
* Modify the /etc/netsukuku/snsd_nodes file.
{{{
register_node# cd /etc/netsukuku/
register_node# cat snsd_nodes
#
# SNSD nodes file
#
# The format is:
# hostname:snsd_hostname:service:priority:weight[:pub_key_file]
# or
# hostname:snsd_ip:service:priority:weight[:pub_key_file]
#
# The `pub_key_file' parameter is optional. If you specify it, NetsukukuD will
# check periodically `snsd_hostname' and it will verify if it is always the
# same machine. If it isn't, the relative snsd will be deleted.
#
depausceve:pippo:http:1
depausceve:1.2.3.4:21:0
angelica:frenzu:ssh:1:/etc/netsukuku/snsd/frenzu.pubk
register_node#
register_node# scp frenzu:/usr/share/andna_lcl_keyring snsd/frenzu.pubk
}}}
* Send a SIGHUP to the NetsukukuD of the register node:
{{{
register_node# killall -HUP ntkd
# or, alternatively
register_node# rc.ntk reload
}}}
==== Zero SNSD IP ====
The main IP associated to a normal hostname has these default values:
{{{
IP = register_node IP # This value can't be changed
service = 0
priority = 16
weight = 1
}}}
It is possible to associate other SNSD records in the service 0, but it isn't
allowed to change the main IP. The main IP can only be the IP of the
register_node.
Although it isn't possible to set a different association for the main IP, it
can be disabled by setting its weight number to 0.
The string used to change the priority and weight value of the main IP is:
{{{
hostname:hostname:0:priority:weight
# For example:
register_node# echo depausceve:depausceve:0:23:12 >> /etc/netsukuku/snsd_nodes
}}}
==== SNSD chain ====
Since it is possible to assign different aliases and backup IPs to the zero
record, there is the possibility to create a SNSD chain.
For example:
{{{
depausceve registers: depausceve:80 --> pippo
pippo registers: pippo:0 --> frenzu
frenzu registers: frenzu:0 --> angelica
}}}
However the SNSD chains are ignored, only the first resolution is considered
valid. Since in the zero service there's always the main IP, the resolution is
always performed.
In this case ("depausceve:80 --> pippo:0") the resolution will return the main
IP of "pippo:0".
The reply to a resolution request of service zero, returns always IPs and not
hostnames.
----
related: ["Netsukuku RFC"]

View File

@ -0,0 +1,436 @@
{{{
ANDNS PROTOCOL
INDEX:
0 - Introduction
1 - Notations
2 - Packet Headers
3 - Query Type
4 - Query Realm
5 - Rcode
6 - Questions
7 - Answers
8 - Compression
0. - INTRODUCTION -
This document describes the protocol used to communicate with ANDNA.
This protocol is used also to make query in internet realm.
So, we can query for `google.it` in internet, or for `depausceve`
in the netsukuku net.
In the case of internet queries, the dns_wrapper will contact the
dns-servers specified in /etc/resolv.conf when ntkd is loaded.
1. - NOTATIONS -
In the next section, we represent a byte with this graphic:
1 2 3 4 5 6 7 8
+--+--+--+--+--+--+--+--+
| |
+--+--+--+--+--+--+--+--+
The numbers represent the bits
Let's show two bytes:
1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| | |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
2. - HEADERS -
Headers are 4-byte long, and the format is:
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ID | R|
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|QR| P| Z| QT | ANCOUNT |I | NK| RCODE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
where:
ID = It's a 2-byte value which identifies the query.
ID is choosed in a random way and the future
answers must have the same ID.
R = Recursion bit. If set, SNSD queries that have
a hostname as resolution will be resolved (if
possible).
QR = 0 implies that this packet contains a question
1 if the packets contains answers
P = If the query is h2ip and ntk-related, P specifies
the protocol service:
0 for TCP
1 for UDP
P has to be zero otherwise.
Z = zlib compression. If z=1, the packet contents,
headers excluded, are zlib-compressed. See
Section 8.
QT = Query Type. See below.
Note: answers must leave this field unchanged.
ANCOUNT = Answer Count. This field is set only if QR=1,
ie if this packet contains answers.
ANCOUNT is the number of answers which belongs
to this packet.
I = Ip-version bit. Specifies the ip version for the
packet contents. All addresses contained in the
packet are:
if I==0 IPv4 addresses (4-bytes)
if I==1 Ipv6 addresses (16-bytes)
This bit is useful only for questions. The server
will reply "NO SUCH DOMAIN" if his node is running
with a different ip-version.
Otherwise, only IPs of the same family will be
returned.
NK = Netsukuku bit. With this field, you can specify
the query realm.
If NK=1, the realm is netsukuku.
If NK=2, the realm is internet.
If NK=0, the packet is not encoded with this
protocol, but with standard DNS protocol.
To specify realms with DNS protocol, see below.
Note: answers must leave this field unchanged.
RCODE = This is the result of a query.
RCODE has to be 0 if this packet contains a
question.
In the case of errors, ANCOUNT has to be 0.
3. - QUERY TYPE -
There are different kind of questions:
QTYPE = 0
This is the classic resolution `hostname -> ip`.
A gethostbyname.
Note: this type of query is used also for SNSD
resolution (see `NTK_RFC 0009`).
You can specify a service.
So, the general way to represent this query is:
hostname:service -> ip
If you don't specify a service, the 0-service
will be used.
Example: if you want to discover which address is
hosting the http service of hostname `depausceve`,
you have to formule this query:
depausceve:80
See below how to formule queries.
QTYPE = 1
This is a reverse resolution: `ip -> host`.
QTYPE =2
This is a global query: all services for the
hostname will be answered.
The query realm has to be Ntk.
4. - QUERY REALMS -
A query can be formulated to find some object in the
netsukuku net or in internet.
Maybe you want to know the ip of `google.it`, but you
have to specify where: internet or netsukuku?
If you use ANDNS protocol, you specify this with NK
bit (See the HEADERS SECTION).
If you use DNS protocol, you have to formule the query
with some suffix: if you ask for `google.it.int` (or
google.it.INT), the question is made in internet.
If you ask for `google.it.ntk` (or `google.it.NTK)
the question is made in netsukuku.
If you don't specify any suffix, the default realm
is Netsukuku Realm
The dns_wrapper first search for a suffix, understanding
the correct realm.
If the question does not have any suffix, the query
will be made in the default realm.
Otherwise, dns_wrapper removes this suffix and
resolves the query without it.
5. - RCODE -
This is the answer report.
It's always 0 if the packet carries a question.
Possible values, in the case of an answer, are:
RCODE = 0 No Error.
This answer contains answers.
The number of ANSWERS is ANCOUNT (see
HEADERS SECTION).
RCODE = 1 Interpretation Error.
The server did not understand your query.
In other words, your question is malformed.
RCODE = 2 Server Fail.
The server did encounter some error processing
your question. Your question is good.
RCODE = 3 No Such Domain
The object of your question does not exist.
RCODE = 4 Not Implemented
This type of query is not implemented yet
in this server.
RCODE = 5 Refused
The server refuse to talk with you.
Note: this expression is always true:
(RCODE XOR ANCOUNT)
ie, if RCODE contains some error (RCODE!=0), there is
not answer in this packet. If RCODE is 0 (no error),
the packet contains some answer.
6. - QUESTIONS -
We have to switch the value QTYPE against realm.
- Case QTYPE = 0 (h2ip) AND Realm=NTK
The format of the question is:
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| SERVICE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| |
| |
| |
| HOSTNAME |
| HASH |
| (HH) |
| |
| |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
where:
SERVICE is a 2-byte field and represents the SNSD service
value (see `NTK_RFC 0009`).
HH is the 16-bytes hostname hash.
- Case QTYPE = 0 (h2ip) AND Realm=INET
The format of the question is:
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| SERVICE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| RDLENGTH |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| |
\ \
\ RDATA \
| |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
where:
SERVICE is a 2-byte field and represents the SNSD service
value (see `NTK_RFC 0009`). At this moment, for INET
resolutions, the service is limited to value 25
- TCP is assumed - or 0.
RDLENGTH is the RDATA len
RDATA is a hostname string, such that:
strlen(RDATA)=RDLENGTH
- Case QTYPE = 1 (ip2h).
The format of the question is:
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| |
/ RDATA /
/ /
| |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
where:
RDATA is an IP in the binary format.
The length of the field - ie the family address (4 or 6) -
depends on the bit `I' in the headers section.
- Case QTYPE = 2 (global query).
The format of the question is:
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| |
| |
| |
| HOSTNAME |
| HASH |
| (HH) |
| |
| |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
where:
HH is the 16-bytes hostname hash.
7. - ANSWERS -
The format of answers is:
CASE QTYPE=0 (h2ip)
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| | T| WG | PRIO |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| |
/ RDATA /
/ /
| |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
where:
T is set if this answer carries an IP.
T is 0 if the answer carries a hostname hash.
WG is the weigth of an answer (see `NTK_RFC 0009`)
PRIO the priority (see `NTK_RFC 0009`)
RDATA is a binary ip address (His family (and his length) is specified
in the headers bit `I') or a hostname hash).
CASE QTYPE=1 (ip2h)
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| RDLENGTH |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| |
/ RDATA /
/ /
| |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
where:
RDLENGTH is the strlen of RDATA (RDATA is a hostname).
RDATA the hostname resolution.
CASE QTYPE=2 (global query)
If QTYPE=2, there is a extra header field before answers:
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ANCOUNT |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
The two bytes are the number of answers that the query
produced. After the two bytes.
Note: the ANCOUNT field on main headers has to be 1 if
RCODE=0, 0 otherwise.
The two extra bytes are the real number of answers in the
case of QTYPE=2.
After the two bytes, this is the format for each answer:
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| M| T| P| WG | PRIO |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| SERVICE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| |
/ DATA /
/ /
| |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
where T is the type of the DATA.
T is:
T = 0 Hostname
T = 1 Ip
M is set if T is set, and specifies that this is the MAIN_IP
of the hostname.
P is The protocol: Tcp if 0, UDP if 1.
If T=1, the ip version is specified in main headers, in the
field I.
If T=0, the format of data is:
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| |
| |
| |
| HOSTNAME |
| HASH |
| (HH) |
| |
| |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
where HH is the 16 bytes hash of SNSD hostname.
If T=1, the format of data is:
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| |
/ RDATA /
/ /
| |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
where RDATA is the binary IP and the length of his contents
depends on the field I of main headers (4 in IPv4, 16 in IPv6).
8. - COMPRESSION -
The format of a compressed packet is:
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| ID | R|
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|QR| P| Z| QT | ANCOUNT |I | NK| RCODE |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| |
| USIZE |
| |
| |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
| |
/ DATA /
/ /
| |
+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
Headers remain uncompressed. The packet contents, question and
answers, are compressed with zlib. The buffer obtained with the
compression is DATA.
USIZE is the original size of packet contents (question and
answers).
If a packet is compressed, then Z=1.
}}}

View File

@ -0,0 +1,38 @@
== NTK_RFC 0007 ==
Subject: ANDNA counter system based on public key
----
This text describes a change to the counter_gnode system in ANDNA.
It will be included in the final documentation, so feel free to correct it.
But if you want to change the system here described, please contact us first.
----
{{{
The counter_gnode is used to prevent massive registrations of hnames by a
single node, however there is a bug in the actual protocol.
Currently the IP of the counter_gnode is the hash of the public key of the
register node.
The public key is part of the key pair used by the register_node to register
and update its hnames, therefore there should be only one key pair for each
node.
However, nothing prevents the register node to create multiple key pairs,
modify the ntkd code and use them at the same time.
With this technique, the register node can have a new counter_gnode for each
new generated key pair, avoiding in this way the registration limit.
The solution is to calculate the IP of the counter_gnode using the hash of the
IP of the register_node. This method was previously proposed but it was
discarded because every time the register_node changes IP it will have a new
counter_gnode. The new counter_gnode cannot know how many hnames the
register_node registered before so it will accept all the new requests, but in
reality, this is not a problem, in fact, the new counter_gnode can accept only
256 hnames, thus the limit is maintained.
}}}
----
related: ["Netsukuku RFC"]

View File

@ -0,0 +1,121 @@
== NTK_RFC 0002 ==
Subject: bandwidth measurement
----
This text describes a change to the Npv7.
It will be included in the final documentation, so feel free to correct it.
But if you want to change the system here described, please contact us first.
----
== Link measurement issues ==
In the current version of the Npv7 the link quality is measured only with the
rtt and packets loss, so only the lantecy is actually considered, this isn't
optimal since also a link with a bandwidth of 20000 bps can have a good
lantecy.
It isn't a critical problem since more than one route is used to reach a
single dst_node, so when a route is satured the kernel will use another one
looking in the nexthop table of that route.
== Improvement ==
In order to improve the link measurement a node must include in the tracer
pkts the available bandwidth of its traversed link.
The link bandwidth, which will be used to modify the real rtt, in this way it
will be possible to have a traffic shaping based also on the real bandwidth of
the links.
== Bandwidth measurement ==
There are two phases of measurement: in the first the total bandwidth of the
new links is measured by the hooking node and the destination nodes, in the
second the bandwidth of the links is constantly monitored.
The utilised bandwidth will be monitored with iptables and the libiptc library.
See http://www.tldp.org/HOWTO/Querying-libiptc-HOWTO/bmeter.html .
We also need to know the total bandwidth which can handle the network
interface. What is a good method to do this?
=== Total available bandwidth ===
{{{
A <-> B <-> C
}}}
The node B is hooking to A and C. At the end of the hook, B measures the
total available bandwidth of the links B<->C and B<->A.
It sends an indefinite amount of random packets, for some seconds, to the
destination of the link. The link is monitored with libiptc and the maximum
rate of bytes per second is registered as the maximum available upload
bandwidth for that specific link. These steps are repeated for each rnode.
Since the link might be asymettric the measurement is also repeated by A and
C. In the end we have the measurement of: A->B, B->A, C->B, B->C.
=== Realtime bandwidth monitoring ===
With the use of the libiptc library, B can monitor the bandwidth usage of its
links.
{{{
Max_link_bw = Total available bandwidth of the link
free_link_bw = available/not used bandwidth of the link
cur_used_link_bw= amount of bandwidth currently used
Max_NIC_bw = maximum bandwidth of the network interface
cur_used_NIC_bw = amount of the total bandwidth currently used of the network
interface
}}}
To calculate the `free_link_bw':
{{{
free_link_bw = Max_link_bw - cur_used_link_bw
if(free_link_bw > Max_NIC_bw - cur_used_NIC_bw)
free_link_bw = (Max_NIC_bw - cur_used_NIC_bw);
}}}
The `free_link_bw' value will be used to modify the `rtt' used to sort the
routes in the routing table.
{{{
modified_rtt(free_link_bw, real_rtt) = 27<<27 + real_rtt - bandwidth_in_8bit(free_link_bw)
real_rtt must be <= 2^32-27<<27-1 (about 8 days)
You can find the definition of bandwidth_in_8bit() here:
http://hinezumilabs.org/cgi-bin/viewcvs.cgi/netsukuku/src/igs.c?rev=HEAD&content-type=text/vnd.viewcvs-markup
}}}
== Latency VS bandwidth ==
It may also happens that a link has a good bandwidth but a high latency.
A low latency is needed by semi-realtime applications: for a ssh connection
we don't care to have a 100Mbs connection but we want to use the shell in
realtime, so when we type a command we get a fast response.
The Netsukuku should create three different routing tables:
* the first shall include the routes formed by the links with the best bandwidth value.
* the second shall include the "best latency" routes
* the routes in the third table shall be an average of the first and the second tables
If the protocol of the application uses the "tos" value in its IP packets, it
is possible to add a routing rule and choose the right table for that
protocol: the ssh protocol will be routed by the second table.
== Caveats ==
If the libiptc are used, it will be more difficult to port the daemon for
other kernels than Linux. Libpcap is a good alternative.
It is possible to capture the packets for some seconds using libpcap, count
them and find how much bandwidth is used.
== IGS ==
The inet-gw which share their internet connection measure also the utilzed
bandwidth of the Internet connection.
The maximum download and upload bandwidth is known since it must be specified
by the user in the netsukuku.conf config file. In this way, monitoring the
device used by the Internet default route, it's trivial to known the
available bandwidth.
----
related: [Netsukuku_RFC]

View File

@ -0,0 +1,198 @@
= NTK_RFC 0001 =
Subject: Gnode contiguity
----
This text describes a change to the Npv7 about the collision of IPs.
It will be included in the final documentation, so feel free to correct it.
But if you want to change the system here described, please contact us first.
----
= The real problems =
A collision of IPs happens when two gnodes with the same ID are born separately,
so when they meet each trough a direct link or trough other nodes many
problems arise since there are some ambiguities:
* In the first case there can be nodes which have the same IP.
* In the second:
A <-> B <-> D <-> A
After a qspn_round the node B will have two routes to reach the gnode A. But in this case the gnode A isn't a contiguous gnode, so when B wants to reach a node which belongs to A, it will send the packet using only one route which may lead to the A gnode which hasn't the wanted node.
So these are the real problems.
In order to solve them it is necessary that every time two gnodes meets each
other for the first time, one of them will redo the hook, in fact, this was
the cause of all.
When a gnode meets for the first time another gnode is like when a new node joins
the network: it hooks with the other nodes. The same must be done for the
gnode.
= Hook of gnodes =
The hook of two gnodes works in this way: only the gnode which has less
nodes than the other will change (let's call the first gnode X and the second
Y). If X and Y have the same number of nodes, the gnode which has the smaller
gnode_id will change.
The bnodes of X will start to re-hook, the other nodes will re-hook when
they notice that a new rnode which belongs to Y comes up.
Summing up: the bnodes re-hook first, then their rnodes, then the rnodes of
the rnodes of the bnodes... and so on, all the nodes of the gnode have
re-hooked.
It doesn't matter that a gnode composed by 2^24 nodes changes all its IPs,
since it will happen only very few times, i.e. when the gnode of the Europe
meets that of the America.
== Gnode count ==
This method requires that the number of nodes present in a gnode has to be
known, therefore the qspn_pkt which traverse gnodes stores also the number
of nodes of each traversed gnode.
== No first tracer_pkt ==
While re-hooking, the first tracer_pkt won't be sent like in the normal hook
'cause if all the nodes of the gnode which is re-hooking send it, there
would be a broadcast pkt for each node. The next qspn_round will let
the other know the routes to reach them.
== Re-hook of two equal, not contiguous gnodes ==
When there are two nodes with the same ip, or gnodes with the
same gid, one of them will re-hook, following the same rules we've described,
but all the packets that the two (g)nodes will send each other will be routed
by the daemons. For example if A wants to send a packet to A' it stores in the
pkt the route it received with the last qspn_pkt, the other nodes will forward
the packet to A' using that route, this is to avoid the problem described
above.
== Re-hook details ==
The gnode X is re-hooking at the gnode Y.
If the gnode Y hasn't enough free nodes for all the nodes of the
gnode X then the situation evolves in this way:
maxYnodes = maxmimum number of nodes in Y;
curYnodes = current number of nodes in Y (gnode count of Y).
diff = maxYnodes - curYnodes;
`diff' is the number of new nodes which the gnode Y can accept inside.
The bnodes of X will say to `diff'# nodes in X to re-hook in the gnode Y, all
the other non-informed nodes will create a new gnode.
Let's analyse the two cases.
=== informed nodes ===
Remembering how the nodes re-hook (first the bnode, then its rnodes, then the
rnodes of its rnodes, etc..) we adopt this strategy:
join_rate=diff/number_of_X_bnodes - 1;
Each bnode of X knows it can inform `join_rate'# nodes, so when its
rnodes try to re-hook at it, they'll know that:
* they will become part of the gnode Y
* they can inform other `(join_rate-1)/(number_of_links-1)'# nodes
The same procedure holds for recursively the rnodes of the rnodes of the
bnode.
When `join_rate' becomes zero the node becomes non-informed.
=== non-informed nodes ===
The gid of the new gnode they create is based on the hash of their previous
gid. In this way all the non-informed nodes will be in the same new gnode,
cause they all generates the same hash. If the new gid is already taken in the
map they'll increment it by one until they choose a non-taken gnode.
== Counting the nodes ==
At this point all seems to be solved, but it is not.
Anyone can modify the qspn, so for example the X which has less nodes than Y
can fake the number, and Y will be forced to re-hook.
It this happens anyone can easily force a gnode of 2^24 nodes to change its
IPs!
Therefore the problem to be solved now is: how can the gnode Y verify that the
gnode X has really more nodes?
What is the main property of a network which has more nodes than another?
The computability power!
We assume that the average computability power for a gnode of the second level
or greater is constant. (a gnode of the second level can have 2^16 nodes, in the
third level 2^24). Therefore the gnode of level 1 won't be checked.
Each node of the gnode which has to re-hook (in this case the gnode Y,
since the gnode X is faking the qspn_pkt) will send a problem to solve to the
other gnode and it wait for a very small time the reply with the solution in
it. If the solution is right the node receiving it will re-hook, otherwise
the gnode X will be banned and excluded from all the qspn floods.
Only one challenge each T time can occur, where T is proportional to the size
of the Y gnode. So say that Y has 16milions IPs, if it has already sent a
challenge it will send another after 10 minutes.
== Computability power ==
But this system leaves opened another kind of attack: the gnode X can target a single
node in Y, replying only to its reply and making it re-hook. In order to
prevent this the nodes act in this way:
* When a node hooks it creates a RSA key pair, then its rnodes get its public key.
* When a node receives a reply to the problem, it broadcasts the reply inside its gnode,
signing it with its public key. When its rnodes receive the pkt, check the signature.
If it is valid they update the counter of received replies for the problems sent, then
they substitute the signature with their own. The packet will propagate
until it reaches all the nodes of the gnode.
* The nodes will start to rehook only when all the replies will be
received (during the wait time). Since it is not possible that all the reply are
received it is allowed that 10% of replies are lost.
The problem to solve sent by the nodes is:
f(x) mod k
where k is a random number between 2^16 and 2^32.
f(x) is a function which is not easily computable with mod k.
When x gets bigger the computation time increases.
We are still deciding on what f() function using.
=== Dumb machines ===
Generating the problem doesn't require a high computability power, in
fact, the daemon will keep 8 or 16 problems cached, generated while the cpu
isn't used.
The machines which have a very low computability power won't reply and even
try to solve the problems they receive (but only if they can't take the
computability of the problem).
= ANDNA changes =
If a same hostname is registered in two separeted gnodes what happens when they meet?
Which node will mantain the hostname?
The node which is in the greater gnode wins: the hash_nodes of the smaller
gnode, which re-hooks, will reset their uptime counter, in this way when they
receive the update request from the node (which has changed its IP and must
update its hname), they ask to the other gnode for the old andna_caches.
Moreover the ANDNA_MIN_UPDATE_TIME (the minum amount of time to be waited
before sending an update os the hname) has to be reduced to
NEW_HOOK_WAIT_TIME, which is the minimum amount of time to be waited before
re-hooking. This is necessary, because all the hname updates sent
before ANDNA_MIN_UPDATE_TIME seconds have elapsed since the last update
rejected. If a gnode re-hooked, the hostname of its nodes has to be
updated, therefore the update request must be accepted.
= And that's all =
That's all folks.
Alpt, Katolaz, Mancausoft, Uscinziatu
----
related: [Netsukuku_RFC]

View File

@ -0,0 +1,46 @@
== NTK_RFC 0005 ==
Subject: Life probability
----
This text describes a change to the Npv7.
It will be included in the final documentation, so feel free to correct it.
But if you want to change the system here described, please contact us first.
----
Statistically the probability of a node to continue to stay up is related to
its uptime, for example if the node X has an uptime of 30 seconds and the node Y of
1200 seconds, then it is more probable that the node Y will continue to stay
up.
For this reason we give higher credits to older nodes/gnodes, this means that
in a multipath route we prefer to don't use very young nodes as main gateways.
{{{
A
/ \
L K
\ /
N
}}}
Let's say K has an uptime of 600 seconds and L of 200.
The node N, to reach A, will prefer the node K.
=== Implementation ===
In order to implement this we penalize the new nodes/gnodes by increasing
their rtt, in this way they will be considered as slow links.
We can do this only for new nodes/gnodes 'cause we cannot trust the uptime
value given by a node, but we can know for sure if that node is completely
new.
When the next qspn_round updates the routes the penality is removed.
Another system would be counting the number of qspn_rounds the nodes took part
in.
If it has only partecipated in < 3 rounds it is considered young.
----
related: [Netsukuku_RFC]

View File

@ -0,0 +1,64 @@
== NTK_RFC 0008 ==
Subject: Private IP classes in restricted mode
----
This text describes a change to the Npv7.
It will be included in the final documentation, so feel free to correct it.
But if you want to change the system here described, please contact us first.
----
The user can decide to use, in restricted mode, a different private IP
class from the default one ( 10.x.x.x ). This is useful if the 10.x.x.x class
cannot be used, for example in Russia, it is very popular to provide Internet
access through big LANs which use the 10.x.x.x class.
The other available classes are:
{{{
172.16.0.0 - 172.31.255.255 = 16*2^16 = 1048576 IPs
192.168.0.0 - 192.168.255.255 = 2^16 = 65536 IPs
}}}
The 192.168.x.x class cannot be used as an alternate restricted mode IP class
because it is the default Netsukuku private class, thus the only alternative
to 10.x.x.x is the "172.16.0.0 - 172.31.255.255" IP class.
However it is adviced to always use the default class.
== Netsukuku private classes ==
It necessary to provide at least one private IP class inside Netsukuku to
allow the creation of private LANs which are connected to Netsukuku with just
one node.
The default Netsukuku private class is 192.168.x.x.
The random IPs choosen by the nodes will be never one of that class.
The default private class is valid both in normal and restricted mode.
Only in normal mode the "172.16.0.0 - 172.31.255.255" class becomes private.
This class is assigned to very large private networks.
The 10.x.x.x class IS NOT private since it is too big and it would be just a
waste of IP addresses to use it as a private class.
Note also that for each Netsukuku node you can have a private network,
therefore with just 16 Netsukuku nodes you can form a private network of
16777216 nodes, which is equivalent to a 10.x.x.x class.
== Notes on the restricted mode ==
A node which runs in restricted mode cannot be compatible with normal mode
nodes, for this reason a restricted node will drop any packets coming from a
normal node.
While in restricted mode the "172.16.0.0 - 172.31.255.255" class IS NOT
private.
In restricted mode, when two different networks which use different
private classes (say 10.x.x.x and 192.168.x.x) are linked, nothing happens and
they will not rehook, this is necessary because it's assumed that the specified
private class is the only choice the user can utilize.
This leds to some problems, consider this scenario:
{{{
10.0.0.0 <-> 172.16.0.0
}}}
In this case the rehook isn't launched, so it is possible that there will be a
lot of collision.

View File

@ -0,0 +1,193 @@
== NTK_RFC 0010 ==
Subject: Viphilama - Virtual to Physical Layer Mapper
----
This text describes a change to the Npv7.
It will be included in the final documentation, so feel free to correct it.
But if you want to change the system here described, please contact us first.
----
=== Viphilama ===
Viphilama will permit to Netsukuku to expand itself over the Internet and then
switching automatically to the physical layer without interfering with the
stability of the Net.
The theory of Viphilama isn't complete yet. This document, right now, is just
a description of what it would be.
=== Layer ===
Netsukuku will be split in two layer: the virtual layer and the physical one.
==== The physical layer ====
This is the original Netsukuku layer: every node is linked to other nodes by
physical links (wifi, cables, ...).
The physical layer is prioritised over the virtual one.
==== The virtual layer ====
The virtual layer is built upon the Internet or any other existing network.
The Netsukuku nodes, in this layer, are linked each other by tunnels.
A node, in order to join in the virtual layer, has to know its physical
coordinates.
The use of geographical coordinates is required for Viphilama, because it has
to map the virtual layer to the physical one and it needs a way to measure
the effective distance between two virtual nodes.
The coordinates can be retrieved using an online map service like
http://maps.google.com or with a GPS.
The coordinates are stored in the internal, external and bnode maps.
In the internal map there are the coordinates of each single node.
In the external maps, the coordinates which locate a gnode are set to its
barycenter: it is the average of the coordinates of all its internal nodes.
==== Gate node ====
The two layers are joined by the gate nodes. They are nodes which belong to
both layers.
This means that the two layer form a unique network.
=== Virtual to Physical mapper ===
The mapper does a basic job: whenever it finds that a virtual link can be
replaced by a physical one, it removes the virtual link.
Assume this scenario:
{{{
Tokyo Moscow Rome London
| | | |
| | | |
|__________|Internet tunnel|_________|
}}}
Only one link exists, and it is a virtual one.
Only Tokyo and London are linked, all the other cities are alone.
When Tokyo and Moscow will be linked by a series of physical nodes, the mapper
will change the net in this way:
{{{
Tokyo<--ntk nodes-->Moscow Rome London
| | |
|______ Internet tunnel ___|
}}}
When even Moscow and Rome will be linked by physical nodes:
{{{
Tokyo<--ntk nodes-->Moscow<--ntk nodes-->Rome London
| |
|__ Inet tunnel _|
}}}
And so on.
Basically when there are two nodes linked physically, one of them can cut
its virtual link which connects it to the virtual layer.
Let's go into the details.
==== Virtual hooking ====
A node, which hasn't any physical neighbours, resides in a black zone and, for
this reason, it can't hook to the physical layer. It will hook directly to
a vnode (virtual node), joining the virtual layer.
Let this hooking node be X.
The first part of the Virtual Hooking is the creation of the virtual links
(ip tunnels).
X chooses, at first, a random vnode which can be located anywhere in the
globe. If it is its first hook to the virtual layer, it will get the IP of
the vnode from a small public list available on the Internet, otherwise it
will consult its saved virtual maps.
Let the chosen vnode be Y.
X sends to Y a packet containing its coordinates. This pkt will be forwarded
with a greedy technique:
Y looks up its maps and forwards the pkt to the vnode which is the nearest to X.
If this latter vnode knows another vnode which is nearer to X, it forwards
again the packet. Finally, the pkt will arrive to the node Z, which is a node
very near to X.
Let d(A, B) be the physical distance between the node A and B.
The node Z appends its Internet IP to the received packet and forwards it
again to a node T, so that d(X,T) ~= d(X,Z).
The node T will do the same (adds its IP and forwards the pkt).
When the packet will be forwarded for the 16th time or when it can't be
forwarded anymore, it is sent back to the node X.
The node X collects this last packet and creates a virtual link (tunnel) to
each Internet IP which has been stored in the packet itself.
These linked nodes are the new rnodes of the node X.
At this point the node X will hook to each linked node. This procedure is
called v-linking:
Let "L" be the generic linked node.
X sends the I_AM_VHOOKING request to L.
L analyses its virtual rnodes and compares d(L,vR) to d(X,vR), where vR is a
vrnode. If d(X,vR) < d(L,vR), L adds the Internet IP of the vR in the reply
packet. This means that if L finds out that X is nearer to one of its
vrnodes, it tells X to create a link to it and deletes its link to the vrnode.
X receives the reply packet of L and tries to create a virtual link to each
vR listed in the same packet.
X writes the list of all the vR nodes which has been successfully linked to X
itself. This list is sent back to L.
L reads this latter list and delete all its links to the vR nodes, which has
been successfully linked to X.
X repeats this same hooking procedure for each L.
In the end, X chooses one of its vrnodes and hooks with the classical method
to it.
==== Gate hooking ====
A node can hook to the physical layer as a normal node or as gate node.
A normal node is the old plain node of Netsukuku, it doesn't have to specify
its coordinates and doesn't need any other prerequisites.
The gate-node has an Internet connection that it uses to connect to
the virtual layer, it is also connected to physical nodes.
There are two cases:
* When the node is from the start a gate node
* When it is first a vnode and then becomes a gate node
In the first case it hooks directly to a physical node. If one of its rnodes
is a gate node too, it will start the v-linking procedure with it.
In this way, the new gate-node will be linked to its nearer vrnodes.
The old gate-node will delete all the links to the vrnodes which have been
linked by the new gate-node.
In the second case, the node directly v-links to the new gate node which is
connected to.
When a gate-node can reach one of it vrnodes using both a virtual and a
physical link, it will delete the virtual one.
== TODO ==
* Is it possible to avoid using the coordinates?
* What does happen when a (v)node dies?
----
Feel free to help the development of Viphilama.

160
doc/manuals/andna Normal file
View File

@ -0,0 +1,160 @@
NAME
ANDNA - Abnormal Netsukuku Domain Name Anarchy
DESCRIPTION
ANDNA is the distributed, non hierarchical and decentralised system of
hostname management in Netsukuku. It substitutes the DNS. The ANDNA
database is scattered inside all the Netsukuku net and in the worst case
every node will have to use about some hundreds Kb of memory.
In order to join ANDNA it is necessary to be hooked at Netsukuku with
the ntkd(8) daemon.
For more information about ANDNA visit: <http://netsukuku.freaknet.org>
USAGE
First of all be sure to have the ntkd(8) daemon up and running.
HOSTNAME REGISTRATION
You can register up to 256 hostnames. Each hostname can be a string of
maximum 512 bytes, which contains a newline (\n) only at its end.
The hostnames to be registered must be listed, one per line, in the
andna_hostnames file, which is by default in
/etc/netsukuku/andna_hostnames.
The ntkd(8) daemon reads it when it is started and when it receives the
SIGHUP signal. So if you've added a hostname while ntkd was running,
just do:
killall -HUP ntkd
All the hostnames, which are already registered by other nodes, are
added in the queue, in this way, when the other nodes won't update them,
your hostnames will automatically be the first in the queue.
An hostname expires after 3 days, if it isn't updated. ntkd
automatically updates the registered hostnames, therefore your hostnames
will expire only if you aren't present in the Netsukuku for 3 entire
days.
If you want to know the result of a registration read the ntkd logs.
HOSTNAME RESOLUTION
The ntkd(8) daemon runs also a DNS wrapper which receives standard DNS
queries for hostnames resolution. The hostnames are resolved in ANDNA,
then the DNS wrapper will reply to the requester.
When the ntkd(8) daemon is started it copies /etc/resolv.conf in
/etc/resolv.conf.bak and adds in the first line of /etc/resolv.conf the
"nameserver 127.0.0.1" string. When it is closed it moves back
/etc/resolv.conf.bak to /etc/resolv.conf. Use the -R option if you want
to disable this behaviour.
All the resolved hostnames are kept, until their expiration date, in the
"resolved hostnames cache". The entire cache is flushed each time the
ntkd(8) daemon receives the SIGALRM signal.
That's all.
IP RESOLUTION
It is possible to know the list of hostnames registered by a node. You
have to simply reverse resolve its ip. For example:
dig -x 127.0.0.2
This command shows your currently registered hostnames. You can use it
to know what hostnames have been already registered. Note the 127.0.0.2
ip. If you use 127.0.0.1 you get only the local hostname written in
/etc/hosts.
SCATTERED NAME SERVICE DISGREGATION
The Scattered Name Service Disgregation is the ANDNA equivalent of the
SRV Record of the Internet Domain Name System. For a complete
description of the SNSD read the NTK_RFC 0009:
<http://lab.dyne.org/Ntk_SNSD>
SNSD NODE REGISTRATION
* Modify the /etc/netsukuku/snsd_nodes file.
* Copy the needed public keys
* Send a SIGHUP to the NetsukukuD of the register node:
SNSD NODE DELETION
Not implemented
SNSD HNAME RESOLUTION
The utility ntk-resolv(8) can be used to resolve SNSD hostnames.
Examples:
ntk-resolv -s 53/udp host
ntk-resolv -s http host
SIGNALS
When the SIGHUP signal is sent to ntkd(8), the andna_hostnames and
snsd_nodes files will be reloaded and it will try to register all the
new added hostnames and snsd records.
When the SIGALRM signal is sent to ntkd(8), the resolved hostnames cache
will be flushed.
FILES
/etc/netsukuku/andna_hostnames
It is the file where the hostnames to be registerd in ANDNA are kept
one per line. It's location can be changed by modifying its option
in the netsukuku.conf file.
/etc/netsukuku/snsd_nodes
The snsd_nodes file keeps the list of the SNSD records which will be
register in ANDNA.
/usr/share/netsukuku/andna_lcl_keyring
In this keyring your ANDNA public and secret keys are saved. Handle
this file with care: without it, you won't be able to update your
hostnames, thus you'll definitely lose them.
/usr/share/netsukuku/andna_cache
/usr/share/netsukuku/andna_lcl_cache
/usr/share/netsukuku/andna_rh_cache
/usr/share/netsukuku/andna_counter_cache
They are the saved ANDNA caches. Their locations can be changed in
netsukuku.conf.
BUGS
{ Don't panic! }
If you encounter any bug, please report it. Use the online bug track
system: <http://bugs.dyne.org/>
or the mailing list: <http://lists.dyne.org/netsukuku/>
and explain what the problem is and if possible a way to reproduce it.
CONTACTS
Subscribe to the netsukuku mailing to get help, be updated on the latest
news and discuss on its development.
To subscribe to the list, send a message to:
netsukuku-subscribe@lists.dyne.org
We live night and day in IRC, come to see us in: #netsukuku on the
FreeNode irc server (irc.freenode.org).
AUTHORS
Main authors and maintainers:
Andrea Lo Pumo aka AlpT <alpt@freaknet.org>
Main contributors:
Andrea Leofreddi <andrea.leofreddi@gmail.com>, Katolaz
<katolaz@freaknet.org>, Federico Tomassini <effetom@gmail.com>
For a complete list read the AUTHORS file or visit:
<http://netsukuku.freaknet.org/?p=Contacts>
SEE ALSO
For more information about Netsukuku visit:
<http://netsukuku.freaknet.org>
ntkd(8), ntk-wifi(8), iproute2(8), route(8)

241
doc/manuals/netsukuku.conf Normal file
View File

@ -0,0 +1,241 @@
NAME
netsukuku.conf - Netsukuku daemon configuration file
SYNOPSIS
/etc/netsukuku/netsukuku.conf
DESCRIPTION
ntkd(8) loads its options from the command line and from netsukuku.conf.
The options that are changed infrequently resides in the configuration
file. The netsukuku.conf file is typically installed at
/etc/netsukuku/netsukuku.conf.
The comments starts with a '#'. If an option is commented, ntkd will use
its default value.
The character '=' is used to assign a value to an option.
All the options will be overridden by their command line equivalent.
OPTIONS
RESTRICTED MODE
ntk_restricted_mode = *bool*
When set to 1, ntkd will be started in restricted mode to be
compatible with Internet. In the restricted mode, only IPs of the
largest private subnet, i.e. 10.x.x.x are chosen.
Default: *0*
ntk_restricted_class = *bool*
When set to 1 the IPs will be chosen from the
172.16.0.0-172.31.255.255 range (use this option only if you can't
use the 10.x.x.x class).
Default: *0*
INTERNET CONNECTION
All these Internet options requires ntk_restricted_mode set to 1.
internet_connection = *bool*
When set to 1, it specifies that this computer has an active
Internet connection. Note that ntkd will overwrite any default route
if this option is set to 0 and the shared Internet connections of
other nodes are used.
Default: *0*
internet_gateway = *IP:interface*
It specifies the default gateway used by *localhost* to reach the
Internet. This option is necessary only if you don't have the
default route set when you run ntkd (i.e. you haven't connected
yet). If this option isn't specified, ntkd will automatically
retrieve the default Internet gateway from the routing table.
Example: internet_gateway = 192.168.1.1:eth0
Default: *(null)*
internet_download_rate = *Kb*
This option is required if the internet_connection option has been
set to 1. It must be set to the download rate of the Internet
connection in KiloBytes. Example:
internet_download_rate = 640
Default: *(null)*
internet_upload_rate = *Kb*
This option is required if the internet_connection option has been
set to 1. It must be set to the upload rate of the Internet
connection in KiloBytes. Example:
internet_upload_rate = 30
Default: *(null)*
internet_ping_hosts = *host1:host2:host3:...*
Specifies a list of Internet hostnames which ntkd will ping
periodically to verify the status of the Internet connection. If all
the hosts specified aren't reachable, it will assume that the
Internet connection isn't available anymore. When one them becoms
pingable, ntkd will enable again the Internet Gateway Search.
Example:
internet_ping_hosts = google.com:cisco.com:sourceforge.net:dyne.org
This option hasn't a default value, it must be specified in the
netsukuku.conf file.
share_internet = *bool*
When set to 1, ntkd shares the Internet connection among all the
other Netsukuku nodes.
Default: *1*
shape_internet = *bool*
Specifies if ntkd will execute the /etc/netsukuku/tc_shaper.sh
script to activate the traffic shaping of the Internet connection.
Default: *0*
use_shared_internet = *bool*
Specifies if ntkd will load balance the Internet traffic of this
host using the Inet connections shared by the Netsukuku nodes. When
set to 0, localhost (this machine) uses only its local Internet
connection (if any).
Default: *1*
ANDNA
disable_andna = *bool*
When set to 1, ntkd won't load the ANDNA(8) daemon. Note that when
the ANDNA daemon is disabled, the andna system will not work at all,
so it will be impossible to resolve, register or update hostnames.
Default: *0*
disable_resolvconf = *bool*
When ntkd starts it modifies /etc/resolv.conf writing in the first
line "nameserver 127.0.0.1". The old /etc/resolv.conf is copied in
/etc/resolv.conf.bak. When the daemon is closed /etc/resolv.conf is
restored. If you want to disable this set disable_resolvconf to 1.
If it is disabled you won't be able to resolve hostnames!
Default: *0*
LIMITS
Note: in the current ntkd version these limits aren't effective.
ntk_max_connections = *number*
How many connection the netsukuku daemons can simultaneusly handle.
Default: *512*
ntk_max_accepts_per_host = *number*
How many simultaneusly connections to the daemons from a single host
are allowed.
Default: *16*
max_accepts_per_host_time = *seconds*
The wait time necessary for a host to reconnect to the daemons after
all the ntk_max_accepts_per_host were used.
Default: *4*
FILES
pid_file = *filename*
ntkd will save its process id in this file. It is used to check if
other instances of ntkd are already running. Only one instance is
allowed.
Default: */var/run/ntkd.pid*
ntk_ext_map_file = *filename*
ntk_int_map_file = *filename*
ntk_bnode_map_file = *filename*
Specify the paths of the maps saved by the daemon.
Default: */usr/share/netsukuku/ext_map_file*
Default: */usr/share/netsukuku/int_map_file*
Default: */usr/share/netsukuku/bnode_map_file*
andna_hnames_file = *filename*
Specify the path of the file which keeps the ANDNA hostnames of the
local host. These hostnames will be registerd in ANDNA.
Default: */etc/netsukuku/andna_hostnames*
snsd_nodes_file = *filename*
The snsd_nodes_file keeps the list of the SNSD records which will be
register in ANDNA.
Default: */etc/netsukuku/snsd_nodes*
andna_lclkey_file = *filename*
Specifies the location of the *local keyring* file. In this keyring
the ANDNA public and secret keys are saved. Handle this file with
care: without it, you won't be able to update your hostnames, thus
you'll definitely lose them.
Default: */usr/share/netsukuku/andna_lcl_keyring*
andna_cache_file = *filename*
andna_lcl_file = *filename*
andna_rhc_file = *filename*
andna_counter_c_file = *filename*
Specify the paths of the caches used by the ANDNA daemon.
Default: */usr/share/netsukuku/andna_cache*
Default: */usr/share/netsukuku/andna_lcl_cache*
Default: */usr/share/netsukuku/andna_rh_cache*
Default: */usr/share/netsukuku/andna_counter_cache*
ip_masquerade_script = *filename*
Specifies the path of the IP masquerading script. This script is
launched by NetsukukuD, at its start, when it shares the Internet
connection. The script will activate the IP masquerading. The script
is also used to disable the IP masquerading when ntkd is closed.
Default: */etc/netsukuku/ip_masquerade.sh*
tc_shaper_script = *filename*
Specifies the path of the traffic shaping script. This script
manages the traffic shaping for the upload bandwidth. It is executed
by ntkd at its start if its relative option has been enabled.
Default: */etc/netsukuku/tc_shaper.sh*
CONTACTS
Subscribe to the netsukuku mailing to get help, be updated on the latest
news and discuss on its development.
To subscribe to the list, send a message to:
netsukuku-subscribe@lists.dyne.org
We live night and day in IRC, come to see us in: #netsukuku on the
FreeNode irc server (irc.freenode.org).
AUTHORS
Main authors and maintainers:
Andrea Lo Pumo aka AlpT <alpt@freaknet.org>
Main contributors:
Andrea Leofreddi <andrea.leofreddi@gmail.com>, Katolaz
<katolaz@freaknet.org>, Federico Tomassini <effetom@gmail.com>
For a complete list read the AUTHORS file or visit:
<http://netsukuku.freaknet.org/?p=Contacts>
SEE ALSO
For more information about Netsukuku visit:
<http://netsukuku.freaknet.org>
ntkd(8), ntk-wifi(8), andna(8), iproute2(8), route(8)

208
doc/manuals/ntk-resolv Normal file
View File

@ -0,0 +1,208 @@
NAME
ntk-resolv - Andns Lookup Resolver
SYNOPSIS
ntk-resolv [-vnPtrspShbml] host ntk-resolv -H host
DESCRIPTION
Ntk-resolv is an interface to ANDNA daemon: it performs andns queries
and displays the answers to stdout. It is able to formule questions for
objects in Internet and Netsukuku realms. It uses the 'andns protocol'
to encode his contents, as explained in Netsukuku RFC 006.
USAGE
The simplest example is:
ntk-resolv hname
With this comand, it asks ANDNA which IP registered the hostname
'hname'. The default behavior is to perform the query in the Netsukuku
realm.
OPTIONS
-v --version
Print Version, then exit.
-n --nameserver=host
Specify the nameserver to use. The default is localhost.
-P --port=n
Uses the port <n> of nameserver. Default is 53.
-t --query-type=snsd --query-type=ptr --qury-type=global --query-type=mx
Specify the query type . Default is snsd. See the section QUERY
TYPE.
-r --realm=inet --realm=ntk
Specify the realm of the query: Internet or Netsukuku. Default is
ntk.
-s --service=n[/proto]
Specify the SNSD service and the relative protocol to search. See
services(5). The service can be specified in alfanumeric or numeric
format. The default service and protocol are 0 and tcp. Example:
ntk-resolv -s domain/udp host
ntk-resolv -s 53/udp host
See the section QUERY TYPE, SERVICES AND PROTOCOL for a better
explanation.
-S --silent
With this option, ntk-resolv will be very discrete.
-b --block-recursion
Set recursion OFF. If recursion is ON (default), when a SNSD service
is requested, and the service is specified with a hostname instead
of an IP, the IP of that hostname will be searched. In the case of a
success research, the answer will contain the IP of the hostname,
and NOT the hostname HASH.
-m --md5-hash
If this option is set, the hostname specified is interpreted as a
MD5 hash. This is useful when you want to know a hostname IP, but
you know only the hash of his name.
-H --compute-hash
Compute the hash of specified hostname and print it to stdout.
Example:
ntk-resolv -H hname
It will print the md5 hash of `hname'. This is useful to debug SNSD
configurations. In fact, if a query is not recursive, the results
are hash'ed hostnames: so, it's possible to verify if the ANDNA
cache is storing the correct hash-value for your SNSD hostnames.
-l --parsable-output
Print answers in a synthetic way. The format of output is:
~ IP (SNSD s=0)
- hname (Inverse)
- hname prio weight (SNSD s!=0)
~ ip prio weight (SNSD s!=0)
~ ip service proto prio weight (Global)
- hname service proto prio weight (Global)
Note that when an answer contains an IP, the first character is `~';
if the answer contains a hostname (hash'ed or not) the line begins
with `-'.
-h --help
Prints to stdout a short explanation of ntk-resolv.
Final note:
All options that take string arguments could be expressed in a
shorter way, by specifing univoque abbreviation of argument. So,
there is the equivalence:
ntk-resolv -r i = ntk-resolv -r inet
with the exception of option -s, wich requires a valid service.
QUERY TYPE
You can formule different kind of queries.
With a `ptr' query, you specify an IP, and you will have, if exists,
the hostname that registered that IP.
With a `snsd' query, you specify a hostname, a service and a
protocol. If service and protocol are not specified, they are set to
0, and you will have the IP assigned to the hostname at this moment.
If you specify a service and a protocol, the answer will contain the
IP that gives the specified service/protocl for the hostname. See
the section SNSD, SERVICES AND PROTOCOL to understand better the
SNSD behavior.
A global query will return the complete SNSD configuration for a
hostname. Ie, you will have an answer for each service that hostname
registered.
The `mx' query is equivalent to a snsd query with service 25 and
proto TCP.
SNSD, SERVICES AND PROTOCOL
SNSD Query Type gives a hostname resolution. With SNSD (Scattered
Name Service Disgregation) ANDNA lets the user to ask for a domain
and a service. If service is 0, the resolution will show which IP
registered the hostname. If service is non-0, the resolution will
show which IP gives specified service for the hostname (considering
the protocol too). See services(5).
You can specify a service as expressed in /etc/services. It can be
expressed also in numeric form. It is also possible to specify the
protocol:
"domain", "53", "53/udp", "domain/udp"
are valid service/proto strings.
For example, the next commands will retrieve the IP(s) that offers
web-pages for the hostname "host":
ntk-resolv -s http/tcp host
ntk-resolv -s 80/tcp host
ntk-resolv -s 80 host
ntk-resolv -s http host
To configure the SNSD delegations, see the SNSD HowTo.
If the delegation for a service (say http) is not set, the IP
returned is the IP that registered the hostname. So, if you do not
want to set SNSD delegations for specific services, the main
hostname IP will be used and you don't need to do nothing.
The hope is that every client will build different queries: browsers
will make queries with service=80 and proto=tcp, mail-clients will
build queries with service=25 and proto tcp and so on.
The service is useless if the query realm is Internet.
The default service is 0: ie, the query will return the IP that
registered the hostname. Default protocol is tcp. Protocol is
ignored when service requested is 0.
Note: service and proto are also ignored when the query type is
`ip->host` (ptr query type).
BUGS
{ Don't panic! }
If you encounter any bug, please report it. Use the online bug track
system: <http://bugs.dyne.org/>
or the mailing list: <http://lists.dyne.org/netsukuku/>
and explain what the problem is and if possible a way to reproduce
it.
CONTACTS
Subscribe to the netsukuku mailing to get help, be updated on the
latest news and discuss on its development.
To subscribe to the list, send a message to:
netsukuku-subscribe@lists.dyne.org
We live night and day in IRC, come to see us in: #netsukuku on the
FreeNode irc server (irc.freenode.org).
AUTHORS
Main authors and maintainers:
Federico Tomassini <effetom@gmail.com> wrote ntk-resolv and network
libraries.
Andrea Lo Pumo aka AlpT <alpt@freaknet.org> wrote ANDNA and
Netsukuku Core.
Main contributors:
Andrea Leofreddi <andrea.leofreddi@gmail.com>, Katolaz
<katolaz@freaknet.org>,
For a complete list read the AUTHORS file or visit:
<http://netsukuku.freaknet.org/?p=Contacts>
SEE ALSO
ntkd(8), andna(8), services(5)

54
doc/manuals/ntk-wifi Normal file
View File

@ -0,0 +1,54 @@
NAME
ntk-wifi - configures the specified wifi card to join Netsukuku
SYNOPSIS
ntk-wifi *wifi_interface*
DESCRIPTION
Netsukuku_wifi is a shell script, which takes as its first argument the
name of the wifi network interface to be used in order to join in
Netsukuku. Then it sets the wifi interface in Ad-Hoc mode and its essid
to "netsukuku". At this point the ntkd daemon is ready to be launched,
EXAMPLES
ntk-wifi wlan0
BUGS
{ Don't panic! }
If you encounter any bug, please report it. Use the online bug track
system: <http://bugs.dyne.org/>
or the mailing list: <http://lists.dyne.org/netsukuku/>
and explain what the problem is and if possible a way to reproduce it.
CONTACTS
Subscribe to the netsukuku mailing to get help, be updated on the latest
news and discuss on its development.
To subscribe to the list, send a message to:
netsukuku-subscribe@lists.dyne.org
We live night and day in IRC, come to see us in: #netsukuku on the
FreeNode irc server (irc.freenode.org).
AUTHORS
Main authors and maintainers:
Andrea Lo Pumo aka AlpT <alpt@freaknet.org>
Main contributors:
Andrea Leofreddi <andrea.leofreddi@gmail.com>, Katolaz
<katolaz@freaknet.org>, Federico Tomassini <effetom@gmail.com>
For a complete list read the AUTHORS file or visit:
<http://netsukuku.freaknet.org/?p=Contacts>
SEE ALSO
For more information about Netsukuku visit:
<http://netsukuku.freaknet.org>
ntkd(8), andna(8), iproute2(8), route(8)

243
doc/manuals/ntkd Normal file
View File

@ -0,0 +1,243 @@
NAME
ntkd - Netsukuku protocol daemon
SYNOPSIS
ntkd [-hvaldrD46] [-i net_interface] [-c conf_file] [-l logfile]
DESCRIPTION
Netsukuku is a mesh network or a P2P net system that generates and
sustains itself autonomously. It is designed to handle an unlimited
number of nodes with minimal CPU and memory resources. Thanks to this
feature it can be easily used to build a worldwide distributed,
anonymous and anarchical network, separated from the Internet, without
the support of any servers, ISPs or authority controls.
The complete features list of Netsukuku is here:
<http://netsukuku.freaknet.org/files/doc/misc/Ntk_features_list>
In order to join to Netsukuku you have to use ntkd, which is the daemon
implementing the Npv7 protocol. The daemon at startup takes the list of
all the network interfaces which are currently UP and it uses all of
them to send and receive packets. If you want to force the daemon to use
specific interfaces you should use the -i option. The ports it listens
to are: 269-udp, 269-tcp, 277-udp, 277-tcp. So be sure to open them in
the firewall.
For more information about Netsukuku visit:
<http://netsukuku.freaknet.org>
OPTIONS
-4, --ipv4
Forces the daemon to use ipv4 addresses only
-6, --ipv6
Forces the daemon to use ipv6 addresses only. Warning, this is still
experimental.
-i *interface*, --iface *interface*
Specifies the network interface the daemon will use to join
Netsukuku, i.e. wlan0. You can use more than one interface by
specifying multiple times the -i option. For example:
ntkd -i wlan0 -i eth0 -i wifi1 -i eth1
-a, --no_andna
Forces ntkd to don't run the ANDNA daemon when started.
-R, --no_resolv
When NetsukukuD starts it modifies /etc/resolv.conf writing in the
first line the string "nameserver 127.0.0.1". The old
/etc/resolv.conf is copied in /etc/resolv.conf.bak. When the daemon
is closed /etc/resolv.conf is restored. If you want to disable this
set use the -R option.
-r*[bool]*, --restricted=*[bool]*
With this option the daemon will run in restricted mode as specified
in the Npv7, only IPs of a private class will be chosen. It is used
for Internet compatibility. If no argument is given to the option,
the default restricted private class 10.0.0.0 is used, otherwise if
*bool* is not zero, the restricted class will be
172.16.0.0-172.31.255.255.
-I, --share-inet
Tells NetsukukuD to run in restricted mode (see -r) and to share
your Internet connection. Please check the relative options in
/etc/netsukuku/netsukuku.conf
-D, --no_daemon
This option tells ntkd to don't detach to background and daemonizing
itself. The daemon will run on foreground instead.
-c *configuration_file*, --conf *configuration_file*
Specifies the name of the configuration file. The default is
/etc/netsukuku/netsukuku.conf. ntkd will not start without a
configuration file.
-l *logfile*, --logfile *logfile*
Specifies that ntkd should send all of its messages to the specified
file. The *logfile* will be overwritten.
-d, --debug
With this option the daemon will run with displaying its debug
messages. The more -d you specify the more debug messages you'll
get. Sometimes it's cool to use it, but be careful and don't go
insane ;)
-h, --help
Display a the list of available options and their brief description.
-v, --version
Displays the version of the ntkd daemon.
EXAMPLES
Usually you'll just want to use ntkd with a wifi device:
ntk-wifi wlan0
ntkd -i wlan0
If you one to use more than one network interface:
ntkd -i eth0 -i wlan0 -i wifi1 -i eth2
SIGNALS
When the SIGHUP signal is sent to ntkd(8), the andna_hostnames and
snsd_nodes files will be reloaded and it will try to register all the
new added hostnames and snsd records.
When the SIGALRM signal is sent to ntkd, the resolved hostnames cache is
flushed.
LOGS
If ntkd is started as a daemon (without the -D option), all the logs are
sent to syslog under the LOG_DAEMON category.
If the no-daemon option (-D) is used, all the logs are printed to
stderr.
FILES
/etc/netsukuku/netsukuku.conf
It is the default path for the ntkd configuration file. It's
possible to choose another file using the -c option.
/etc/netsukuku/andna_hostnames
It is the file where the hostnames to be registerd in ANDNA are kept
one per line. It's location can be changed by modifying the relative
option in the netsukuku.conf file.
/etc/netsukuku/snsd_nodes
The snsd_nodes_file keeps the list of the SNSD records which will be
register in ANDNA.
/usr/share/netsukuku/ext_map_file
/usr/share/netsukuku/int_map_file
/usr/share/netsukuku/bnode_map_file
They are the Netsukuku maps saved by the daemon. Their locations can
be changed in netsukuku.conf.
/usr/share/netsukuku/andna_lcl_keyring
In this keyring your ANDNA public and secret keys are saved. Handle
this file with care: without it, you won't be able to update your
hostnames, thus you'll definitely lose them.
/usr/share/netsukuku/andna_cache
/usr/share/netsukuku/andna_lcl_cache
/usr/share/netsukuku/andna_rh_cache
/usr/share/netsukuku/andna_counter_cache
They are the saved ANDNA caches. Their locations can be changed in
netsukuku.conf.
/etc/netsukuku/ip_masquerade.sh
This script is launched by NetsukukuD, at its start, when it shares
the Internet connection. The script will activate the IP
masquerading. The script is also used to disable the IP masquerading
when ntkd is closed.
/etc/netsukuku/tc_shaper.sh
This script manages the traffic shaping for the upload bandwidth. It
is executed by ntkd at its start if its relative option has been
enabled.
/var/run/ntkd.pid
It is the lock file created by ntkd at its start, it is used to
check if other instances of ntkd are already running. Only one
instance is allowed.
KERNEL DEPENDENCIES
On Linux be sure to have the following options set in your kernel
.config. These options are taken from linux-2.6.14.
#
# Networking options
#
CONFIG_PACKET=y
CONFIG_UNIX=y
CONFIG_INET=y
CONFIG_IP_MULTICAST=y
CONFIG_IP_ADVANCED_ROUTER=y
CONFIG_IP_MULTIPLE_TABLES=y
CONFIG_IP_ROUTE_MULTIPATH=y
CONFIG_NET_IPIP=y
CONFIG_NETFILTER=y
and these from linux-2.6.16.19.
#
# Core Netfilter Configuration
#
CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y
NETFILTER_XT_TARGET_CONNMARK=y
#
# IP: Netfilter Configuration
#
CONFIG_IP_NF_IPTABLES=y
CONFIG_IP_NF_FILTER=y
CONFIG_IP_NF_TARGET_REJECT=y
CONFIG_IP_NF_NAT=y
CONFIG_IP_NF_NAT_NEEDED=y
CONFIG_IP_NF_TARGET_MASQUERADE=y
If you are using modules you have to load them before launching the
daemon.
BUGS
{ Don't panic! }
If you encounter any bug, please report it. Use the online bug track
system: <http://bugs.dyne.org/>
or the mailing list: <http://lists.dyne.org/netsukuku/>
and explain what the problem is and if possible a way to reproduce it.
CONTACTS
Subscrive to the netsukuku mailing to get help, be updated on the latest
news and discuss on its development.
To subscribe to the list, send a message to:
netsukuku-subscribe@lists.dyne.org
We live night and day in IRC, come to see us in: #netsukuku on the
FreeNode irc server (irc.freenode.org).
AUTHORS
Main authors and maintainers:
Andrea Lo Pumo aka AlpT <alpt@freaknet.org>
Main contributors:
Andrea Leofreddi <andrea.leofreddi@gmail.com>, Katolaz
<katolaz@freaknet.org>, Federico Tomassini <effetom@gmail.com>
For a complete list read the AUTHORS file or visit:
<http://netsukuku.freaknet.org/?p=Contacts>
SEE ALSO
For more information about Netsukuku visit:
<http://netsukuku.freaknet.org>
netsukuku.conf(5), ntk-wifi(8), andna(8), iproute2(8), route(8)

View File

@ -0,0 +1,95 @@
== Grow Netsukuku ==
Netsukuku is a mesh network.
The mesh networks depend on the collaboration of each node, in fact, a
distributed network can grow only with the small contributions of each user.
Don't expect that someone will set up the whole net for you, just
because Netsukuku is decentralised, anonymous, distributed and independent
and it will never be possible to anybody to control it.
You have the possibility to be the citizen of a free world wide community,
where no one will ever be able to limit your digital rights with measures like
prosecution of file sharing, censorship, data retention, commercial
connectivity and so on.
=== Joining Netsukuku ===
The first step is to turn your PC into a Netsukuku node:
* take a computer
* install any distro of GNU/Linux
* install Netsukuku
* buy a wifi (PCI) card
* buy/build an external antenna (with the longest range as possible)
or
* buy an Access Point compatible with the Netsukuku-AP firmware
* buy/build an external antenna (with the longest range as possible)
* connect the AP to your PC. In this case it doesn't matter anymore
what OS you've installed and even if your PC is turned off, the AP
will continue to be an active Netsukuku node..
It's highly probable you will be the first node in your neighborhood,
but this is normal: someone have to be the first.
As soon as another user will do the same thing you did, you will be
automatically connected to each other.
Waiting doesn't cost you nothing.
In order to shorten your waiting you can help the growth of Netsukuku in your
neighborhood by following the advises written below.
=== Internet sharing ===
If you have an Internet connection, share it with your neighbours.
In this way everybody will be able to have a free Internet connection without
worrying of his or her location. Moreover, when this habit will be common, you
won't worry too, anywhere and anytime.
Don't worry too much about sharing your bandwidth.
These are some features of sharing the Internet connection with Netsukuku:
* You can connect to the Internet using, at the same time, multiple node
which share their connection. For example, if there are 5 nodes sharing
their 640Kb/s connections, you can have 5 parallel downloads at 640Kb/s.
* If you decide to share your Internet connection, you will always use the
Internet connections shared by the other nodes. In this way, you donate
your bandwidth, but, at the same time, receive donations from other users.
* Even if you share your Internet connection to other Netsukuku nodes, your
traffic will have the maximum priority, therefore you won't notice any
slowdown.
=== Spread the word ===
It is very important to let your neighbours aware of being inside a
Netsukuku area.
You have just to mark in a visible way the area, for example using:
* stickers: /* TODO: image and phrase for the sticker URL */
* papers: /* TODO: url of the sheet to print */
* posters: /* TODO */
For more information on this topic go to:
http://lab.dyne.org/Ntk_spread_the_word /* TODO */
=== City-City link ===
In the same way two nodes close to each other are linked, it is possible to connect
two close cities by wireless links.
Otherwise, if it is impossible to link physically them (f.e. there is a desert
area between them), they can still be connected with the use of Internet tunnels.
For more information on this topic go to:
http://lab.dyne.org/Ntk_Internet_tunnels
=== Documentation ===
Another useful thing you can do is writing or translating documentation.
Use the wiki: http://lab.dyne.org/Netsukuku
=== Code ===
There is a lot to code too! If you are a Kung Foo coder, get on board and
help the development writing some nice poems. For a start you can take a look
at the src/TODO file.
=== Misc ===
Finally, every good work you can do is welcomed and it will surely be used,
for example if you like to draw upload your drawings.

View File

@ -0,0 +1,36 @@
== Internet tunnels and Netsukuku ==
Internet tunnels can be used to link Netsukuku nodes.
Generally, it isn't a good idea because Netsukuku is meant to be a
physical net, in fact, if the links are based on a lower network (the
Internet), Netsukuku becomes dependent on it.
If Netsukuku becomes dependent on another network, all the advantages of
having a parallel net to the Internet are lost.
However the Internet tunnels can be useful.
Consider this scenario:
there two large gnode in two near cities and it is difficult to link the
cities, f.e. using a wireless hook.
In this case they can be linked with the use of Internet tunnels.
Some of nodes with the best Internet connection will be linked to the nodes of
the other city. In this way the links will be like real physical links,
because they'll have the same topological meaning, and the delay between the
two gnode won't be high (the cities are near).
Moreover the ISPs will be used to connect two large gnode, therefore the
Netsukuku net will be partially dependent on the Internet.
These tunnels have to be created manually.
It is important to not create tunnels which undermine the topological meaning
of physical links, thus you must not create a tunnel between Tokyo and
Amsterdam.
If there is the danger that the ISPs used to create the tunnels will try to
tap them, it is possible to create encrypted tunnels, or even better the
tunnel can be encrypted and routed through different routes using Tor. In the
latter case the link bandwidth will be heavily afflicted therefore this
countermeasure must be used with caution.
For an example on how to link two nodes using a tunnel see ["Ntk_vpn_test"].

100
doc/misc/Ntk_features_list Normal file
View File

@ -0,0 +1,100 @@
== Netsukuku features list ==
{{{
- The Netsukuku mesh network is: distributed, not hierarchic, and higly
scalable. The design of Netsukuku prioritises the stability of net.
For this reason, it isn't specifically suitable for mobile nodes.
However if the mobile nodes are inside an area covered by static Netsukuku
nodes, there aren't any problems. It is also possible to use other mesh
network protocols designed for mobility in conjunction with Netsukuku (f.e.
see olsrd.org), in the same way they are used in conjunction with the
Internet.
- Scalability: Netsukuku is specifically designed to handle an unlimited
number of nodes with minimal CPU and memory resources.
- The net isn't overloaded with discoveries packet
- The size of the maps is fixed: about 4Kb for the int_map and 16Kb
for the ext_map.
- Not all the nodes sends a broadcast discovery.
- There are few floods for each discovery.
- When a node receives a flood it has already the routes that can be
used to reach all the nodes traversed by the flood. It doesn't need
to calculate anything about them.
- A flood is synchronized: the same flood starts at the same time for
all the nodes.
- http://lab.dyne.org/Netsukuku_scalability
- zeroconf: the network builds itself, without need of human intervention
- ANDNA: distributed and not hierarchic DNS
- When the net becomes larger, ANDNA scales more because its DB will
be distributed among the nodes.
- Any node can register up to 256 hostnames.
- The registration is secure: it is based on asymmetric cryptography,
thus it is very difficult to take hostnames which has been already
registered by other nodes.
- Each hostname can be a string of maximum 512 bytes.
- DNS compatibility: all the network programs are already compatible
with ANDNA, because NetsukukuD comes with a DNS wrapper which
converts DNS queries to ANDNA requests.
- All the resolved hostnames are kept, in the "resolved hostnames
cache" to speed up the resolution process.
The rhcache is synchronized with ANDNA, therefore its stored
entries will expire exactly when the registered hostnames expire
in ANDNA.
- Scattered Name Service Disgregation
http://lab.dyne.org/Ntk_SNSD
The SNSD is the ANDNA equivalent of the SRV Record of the Internet
Domain Name System, which is defined here:
http://www.ietf.org/rfc/rfc2782.txt
SNSD isn't the same of the "SRV Record", in fact, it has its own
unique features.
- Internet compatibility
- internet sharing
* Multi-inet-gateways.
The Netsukuku nodes will now automatically use multiple
inet-gateways to connect to the Internet, therefore their
Internet connection will be effectively load-balanced.
* Anti-loop multi-igw shield.
The nodes which share their Internet connection will also
automatically use the shared connection of the other nodes.
Through a simple marking system, death loops are avoided.
* Traffic shaping.
The nodes which share their Internet connection can now
shape it, in this way they'll prioritize their local
outgoingtraffic and the lowdelay one (f.e. SSH).
- Routes based on bandwidth and latency
http://lab.dyne.org/Ntk_bandwidth_measurement
- NetsukukuD:
- low memory and CPU usage
- it can run smoothly on a small Access Point
- Support for multipath routes: to reach a destination node, the
packets will use, at the same time, more than one route.
- support for multi network interfaces
- Multi interfaces multipath: if the node can reach a rnode trough
multiple interfaces, it uses them all with a multipath route.
}}}

157
doc/misc/Ntk_scalability Normal file
View File

@ -0,0 +1,157 @@
- QSPN scalability
The QSPN is an optimised way of "sending a tracer_pkt from each extreme node".
A tracer_pkt is just a flood, and the total number of floods is given by:
total_floods = extreme_nodes + 1
where the extreme_nodes are:
extreme_nodes = number_of_nodes_with_only_one_link + number_of_cycles*2
A cycle here is meant as a set of nodes, where each node is linked at least at
two other nodes of the set.
The total different packets generated by a single flood is equal to:
total_packets_per_flood = Sum( number_of_links_of_each_node - 1 ) + 1
Since the network is organized in gnodes, the total_floods for all the levels
will be the sum of the total_floods of each level. The same applies to the
total_packets_per_flood.
Now we'll consider various worst scenarios.
- First scenario
The first worst case is a network where all the nodes are an extreme_node, i.e.
there's one node X and all the other are linked to it by just one link.
O Y
\ /
\ /
N ---- X ----L
|
|
M (A graph describing the first worst
scenario)
In this case all the nodes, including X, will send a tracer_pkt.
This means that if all the nodes in the level 0 are linked in that way, and all
the gnodes of the higher levels are also linked between them in the same way,
then the total floods, in all the levels, we'll be:
total_floods = MAXGROUPNODE * levels
Where MAXGROUPNODE is the number of (g)node present in a gnode.
By the way, this configuration has its advantages because there is only one
hop between each node, therefore each flood will end after one hop and the
total packets will be:
total_packets = MAXGROUPNODE^2 * levels
MAXGROUPNODE is equal to 256.
In the ipv4 we have 4 levels.
This means that in a network composed by 2^32 nodes, in the first worst
scenario to run the QSPN at all the levels will have:
total_floods = 1024; total_packets = 262144;
Note that "levels" is equal to log_2(N)/MAXGROUPNODE_BITS, where N is the
maximum number of nodes in the network and MAXGROUPNODE_BITS is equal to 8.
MAXGROUPNODE is also equal to 2^MAXGROUPNODE_BITS.
The final formulas that describes the growth of the number of floods and
packets are:
total_floods = 2^5 * log_2(N)
total_packets = 2^13 * log_2(N)
- Second scenario
In this case we consider a network where each (g)node is linked to all the other
(g)nodes.
C
/|\
/ | \
A-----D
\ | /
\|/
E
That means that we have 1 cycle and 0 nodes_with_only_one_link, so the
total_floods are:
total_floods = 2
Since every (g)node is linked with every other (g)gnodes, the number of links
for each of them is MAXGROUPNODE and the number of total different packets
generated per flood is:
total_packets = ( ( MAXGROUPNODE - 1 ) * MAXGROUPNODE + 1)
Supposing that this configuration is the same for the upper levels too, we have:
total_floods = 2 * levels
total_packets = total_floods * ( ( MAXGROUPNODE - 1 ) * MAXGROUPNODE + 1)
N = total_number_of_nodes_in_the_network
levels = log_2(N)/MAXGROUPNODE_BITS
total_packets = (log_2(N)/4) * ( ( MAXGROUPNODE - 1 ) * MAXGROUPNODE + 1)
In ipv4, with 2^32 nodes:
total_packets = 522248
- Third scenario
All the (g)nodes are in just one line: to reach the end node B from the start
node A we have traverse N nodes, with N equal to the total number of nodes
minus 2.
In this awful case a flood will have to traverse N hops, this means that if
the average rtt between two nodes is 70ms, then the flood, if started from an
extreme node will take about 9 years to reach the other end.
- About the maximum size of a tracer_pkt
Each time a tracer_pkt traverse a node it grows of one byte, since the
tracer_pkt is always restricted to a determinate level, which has maximum
MAXGROUPNODE nodes, the maximum size of a plain tracer_pkt is 256 Bytes (we
are not counting the headers, which are a constant size).
The things change if the tracer_pkt traverses border nodes, in fact,
(7 + 10*L) bytes are added in the the tracer_pkt each time it passes trough a
bnode. L is the number of gnodes the border node is linked to.
- About the maximum size of the maps
The size of levels in the maps is fixed 'cause we already know the maximum number
of nodes in the network. We are also considering that we store only the 20
best routes for each node.
So the maximum size of the maps, when we have all the routes stored, and the
bnode with all their maximum links filled is:
internal map | external map | border node map
ipv4 44032 | 136704 | 3159552
ipv6 44032 | 683520 | 15797760
(in bytes).
The bnode map is so large because we are considering the worst case in which
in each of our gnodes there are 256 bnodes each of them is linked to 512
gnodes.
- About the overload created by multiple hooks of (g)nodes
In order to prevent that a QSPN is sent every time a (g)node joins the network
the QSPN are all syncronised in each level, therefore the maps are updated at
each qspn_round. (Read the section "5.1.4 Qspn round").

12
doc/misc/mailinglist Normal file
View File

@ -0,0 +1,12 @@
Subscribe to the netsukuku mailing to get help, be updated on the latest news
and discuss on its development.
To subscribe to the list, send a message to:
netsukuku-subscribe@lists.dyne.org
or use the web interface:
http://lists.dyne.org/mailman/listinfo/netsukuku
You can browse the archive here:
http://lists.dyne.org/netsukuku/
http://dir.gmane.org/gmane.network.peer-to-peer.netsukuku

3077
doc/misc/rfc1035.txt Normal file

File diff suppressed because it is too large Load Diff

323
install-sh Executable file
View File

@ -0,0 +1,323 @@
#!/bin/sh
# install - install a program, script, or datafile
scriptversion=2005-05-14.22
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch. It can only install one file at a time, a restriction
# shared with many OS's install programs.
# set DOITPROG to echo to test this script
# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"
# put in absolute paths if you don't have them in your path; or use env. vars.
mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"
chmodcmd="$chmodprog 0755"
chowncmd=
chgrpcmd=
stripcmd=
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=
dst=
dir_arg=
dstarg=
no_target_directory=
usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
or: $0 [OPTION]... SRCFILES... DIRECTORY
or: $0 [OPTION]... -t DIRECTORY SRCFILES...
or: $0 [OPTION]... -d DIRECTORIES...
In the 1st form, copy SRCFILE to DSTFILE.
In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
In the 4th, create DIRECTORIES.
Options:
-c (ignored)
-d create directories instead of installing files.
-g GROUP $chgrpprog installed files to GROUP.
-m MODE $chmodprog installed files to MODE.
-o USER $chownprog installed files to USER.
-s $stripprog installed files.
-t DIRECTORY install into DIRECTORY.
-T report an error if DSTFILE is a directory.
--help display this help and exit.
--version display version info and exit.
Environment variables override the default commands:
CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
"
while test -n "$1"; do
case $1 in
-c) shift
continue;;
-d) dir_arg=true
shift
continue;;
-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;
--help) echo "$usage"; exit $?;;
-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;
-o) chowncmd="$chownprog $2"
shift
shift
continue;;
-s) stripcmd=$stripprog
shift
continue;;
-t) dstarg=$2
shift
shift
continue;;
-T) no_target_directory=true
shift
continue;;
--version) echo "$0 $scriptversion"; exit $?;;
*) # When -d is used, all remaining arguments are directories to create.
# When -t is used, the destination is already specified.
test -n "$dir_arg$dstarg" && break
# Otherwise, the last argument is the destination. Remove it from $@.
for arg
do
if test -n "$dstarg"; then
# $@ is not empty: it contains at least $arg.
set fnord "$@" "$dstarg"
shift # fnord
fi
shift # arg
dstarg=$arg
done
break;;
esac
done
if test -z "$1"; then
if test -z "$dir_arg"; then
echo "$0: no input file specified." >&2
exit 1
fi
# It's OK to call `install-sh -d' without argument.
# This can happen when creating conditional directories.
exit 0
fi
for src
do
# Protect names starting with `-'.
case $src in
-*) src=./$src ;;
esac
if test -n "$dir_arg"; then
dst=$src
src=
if test -d "$dst"; then
mkdircmd=:
chmodcmd=
else
mkdircmd=$mkdirprog
fi
else
# Waiting for this to be detected by the "$cpprog $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.
if test ! -f "$src" && test ! -d "$src"; then
echo "$0: $src does not exist." >&2
exit 1
fi
if test -z "$dstarg"; then
echo "$0: no destination specified." >&2
exit 1
fi
dst=$dstarg
# Protect names starting with `-'.
case $dst in
-*) dst=./$dst ;;
esac
# If destination is a directory, append the input filename; won't work
# if double slashes aren't ignored.
if test -d "$dst"; then
if test -n "$no_target_directory"; then
echo "$0: $dstarg: Is a directory" >&2
exit 1
fi
dst=$dst/`basename "$src"`
fi
fi
# This sed command emulates the dirname command.
dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'`
# Make sure that the destination directory exists.
# Skip lots of stat calls in the usual case.
if test ! -d "$dstdir"; then
defaultIFS='
'
IFS="${IFS-$defaultIFS}"
oIFS=$IFS
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
shift
IFS=$oIFS
pathcomp=
while test $# -ne 0 ; do
pathcomp=$pathcomp$1
shift
if test ! -d "$pathcomp"; then
$mkdirprog "$pathcomp"
# mkdir can fail with a `File exist' error in case several
# install-sh are creating the directory concurrently. This
# is OK.
test -d "$pathcomp" || exit
fi
pathcomp=$pathcomp/
done
fi
if test -n "$dir_arg"; then
$doit $mkdircmd "$dst" \
&& { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
&& { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
&& { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
else
dstfile=`basename "$dst"`
# Make a couple of temp file names in the proper directory.
dsttmp=$dstdir/_inst.$$_
rmtmp=$dstdir/_rm.$$_
# Trap to clean up those temp files at exit.
trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
trap '(exit $?); exit' 1 2 13 15
# Copy the file name to the temp name.
$doit $cpprog "$src" "$dsttmp" &&
# and set any options; do chmod last to preserve setuid bits.
#
# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $cpprog $src $dsttmp" command.
#
{ test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
&& { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
&& { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
&& { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
# Now rename the file to the real destination.
{ $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \
|| {
# The rename failed, perhaps because mv can't rename something else
# to itself, or perhaps because mv is so ancient that it does not
# support -f.
# Now remove or move aside any old file at destination location.
# We try this two ways since rm can't unlink itself on some
# systems and the destination file might be busy for other
# reasons. In this case, the final cleanup might fail but the new
# file should still install successfully.
{
if test -f "$dstdir/$dstfile"; then
$doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
|| $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
|| {
echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
(exit 1); exit 1
}
else
:
fi
} &&
# Now rename the file to the real destination.
$doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
}
}
fi || { (exit 1); exit 1; }
done
# The final little trick to "correctly" pass the exit status to the exit trap.
{
(exit 0); exit 0
}
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

360
missing Executable file
View File

@ -0,0 +1,360 @@
#! /bin/sh
# Common stub for a few missing GNU programs while installing.
scriptversion=2005-06-08.21
# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005
# Free Software Foundation, Inc.
# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
# 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 2, 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, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301, USA.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
if test $# -eq 0; then
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
fi
run=:
# In the cases where this matters, `missing' is being run in the
# srcdir already.
if test -f configure.ac; then
configure_ac=configure.ac
else
configure_ac=configure.in
fi
msg="missing on your system"
case "$1" in
--run)
# Try to run requested program, and just exit if it succeeds.
run=
shift
"$@" && exit 0
# Exit code 63 means version mismatch. This often happens
# when the user try to use an ancient version of a tool on
# a file that requires a minimum version. In this case we
# we should proceed has if the program had been absent, or
# if --run hadn't been passed.
if test $? = 63; then
run=:
msg="probably too old"
fi
;;
-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
error status if there is no known handling for PROGRAM.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
--run try to run the given command, and emulate it if it fails
Supported PROGRAM values:
aclocal touch file \`aclocal.m4'
autoconf touch file \`configure'
autoheader touch file \`config.h.in'
automake touch all \`Makefile.in' files
bison create \`y.tab.[ch]', if possible, from existing .[ch]
flex create \`lex.yy.c', if possible, from existing .c
help2man touch the output file
lex create \`lex.yy.c', if possible, from existing .c
makeinfo touch the output file
tar try tar, gnutar, gtar, then tar without non-portable flags
yacc create \`y.tab.[ch]', if possible, from existing .[ch]
Send bug reports to <bug-automake@gnu.org>."
exit $?
;;
-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing $scriptversion (GNU Automake)"
exit $?
;;
-*)
echo 1>&2 "$0: Unknown \`$1' option"
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
;;
esac
# Now exit if we have it, but it failed. Also exit now if we
# don't have it and --version was passed (most likely to detect
# the program).
case "$1" in
lex|yacc)
# Not GNU programs, they don't have --version.
;;
tar)
if test -n "$run"; then
echo 1>&2 "ERROR: \`tar' requires --run"
exit 1
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
exit 1
fi
;;
*)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
# Could not run --version or --help. This is probably someone
# running `$TOOL --version' or `$TOOL --help' to check whether
# $TOOL exists and not knowing $TOOL uses missing.
exit 1
fi
;;
esac
# If it does not exist, or fails to run (possibly an outdated version),
# try to emulate it.
case "$1" in
aclocal*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`acinclude.m4' or \`${configure_ac}'. You might want
to install the \`Automake' and \`Perl' packages. Grab them from
any GNU archive site."
touch aclocal.m4
;;
autoconf)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`${configure_ac}'. You might want to install the
\`Autoconf' and \`GNU m4' packages. Grab them from any GNU
archive site."
touch configure
;;
autoheader)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`acconfig.h' or \`${configure_ac}'. You might want
to install the \`Autoconf' and \`GNU m4' packages. Grab them
from any GNU archive site."
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
test -z "$files" && files="config.h"
touch_files=
for f in $files; do
case "$f" in
*:*) touch_files="$touch_files "`echo "$f" |
sed -e 's/^[^:]*://' -e 's/:.*//'`;;
*) touch_files="$touch_files $f.in";;
esac
done
touch $touch_files
;;
automake*)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
You might want to install the \`Automake' and \`Perl' packages.
Grab them from any GNU archive site."
find . -type f -name Makefile.am -print |
sed 's/\.am$/.in/' |
while read f; do touch "$f"; done
;;
autom4te)
echo 1>&2 "\
WARNING: \`$1' is needed, but is $msg.
You might have modified some files without having the
proper tools for further handling them.
You can get \`$1' as part of \`Autoconf' from any GNU
archive site."
file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
if test -f "$file"; then
touch $file
else
test -z "$file" || exec >$file
echo "#! /bin/sh"
echo "# Created by GNU Automake missing as a replacement of"
echo "# $ $@"
echo "exit 0"
chmod +x $file
exit 1
fi
;;
bison|yacc)
echo 1>&2 "\
WARNING: \`$1' $msg. You should only need it if
you modified a \`.y' file. You may need the \`Bison' package
in order for those modifications to take effect. You can get
\`Bison' from any GNU archive site."
rm -f y.tab.c y.tab.h
if [ $# -ne 1 ]; then
eval LASTARG="\${$#}"
case "$LASTARG" in
*.y)
SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" y.tab.c
fi
SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" y.tab.h
fi
;;
esac
fi
if [ ! -f y.tab.h ]; then
echo >y.tab.h
fi
if [ ! -f y.tab.c ]; then
echo 'main() { return 0; }' >y.tab.c
fi
;;
lex|flex)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a \`.l' file. You may need the \`Flex' package
in order for those modifications to take effect. You can get
\`Flex' from any GNU archive site."
rm -f lex.yy.c
if [ $# -ne 1 ]; then
eval LASTARG="\${$#}"
case "$LASTARG" in
*.l)
SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" lex.yy.c
fi
;;
esac
fi
if [ ! -f lex.yy.c ]; then
echo 'main() { return 0; }' >lex.yy.c
fi
;;
help2man)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a dependency of a manual page. You may need the
\`Help2man' package in order for those modifications to take
effect. You can get \`Help2man' from any GNU archive site."
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
if test -z "$file"; then
file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
fi
if [ -f "$file" ]; then
touch $file
else
test -z "$file" || exec >$file
echo ".ab help2man is required to generate this page"
exit 1
fi
;;
makeinfo)
echo 1>&2 "\
WARNING: \`$1' is $msg. You should only need it if
you modified a \`.texi' or \`.texinfo' file, or any other file
indirectly affecting the aspect of the manual. The spurious
call might also be the consequence of using a buggy \`make' (AIX,
DU, IRIX). You might want to install the \`Texinfo' package or
the \`GNU make' package. Grab either from any GNU archive site."
# The file to touch is that specified with -o ...
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
if test -z "$file"; then
# ... or it is the one specified with @setfilename ...
infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $infile`
# ... or it is derived from the source name (dir/f.texi becomes f.info)
test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
fi
# If the file does not exist, the user really needs makeinfo;
# let's fail without touching anything.
test -f $file || exit 1
touch $file
;;
tar)
shift
# We have already tried tar in the generic part.
# Look for gnutar/gtar before invocation to avoid ugly error
# messages.
if (gnutar --version > /dev/null 2>&1); then
gnutar "$@" && exit 0
fi
if (gtar --version > /dev/null 2>&1); then
gtar "$@" && exit 0
fi
firstarg="$1"
if shift; then
case "$firstarg" in
*o*)
firstarg=`echo "$firstarg" | sed s/o//`
tar "$firstarg" "$@" && exit 0
;;
esac
case "$firstarg" in
*h*)
firstarg=`echo "$firstarg" | sed s/h//`
tar "$firstarg" "$@" && exit 0
;;
esac
fi
echo 1>&2 "\
WARNING: I can't seem to be able to run \`tar' with the given arguments.
You may want to install GNU tar or Free paxutils, or check the
command line arguments."
exit 1
;;
*)
echo 1>&2 "\
WARNING: \`$1' is needed, and is $msg.
You might have modified some files without having the
proper tools for further handling them. Check the \`README' file,
it often tells you about the needed prerequisites for installing
this package. You may also peek at any GNU archive site, in case
some other package would contain this missing \`$1' program."
exit 1
;;
esac
exit 0
# Local variables:
# eval: (add-hook 'write-file-hooks 'time-stamp)
# time-stamp-start: "scriptversion="
# time-stamp-format: "%:y-%02m-%02d.%02H"
# time-stamp-end: "$"
# End:

21
src/Makefile.am Normal file
View File

@ -0,0 +1,21 @@
SUBDIRS = man scripts conf
AM_CFLAGS= -g -I. @debug_flags@ -I@gmp@
AM_CXXFLAGS = -g -I. @debug_flags@ -I@gmp@
bin_PROGRAMS = ntkd ntk-resolv
ntkd_SOURCES = accept.c map.c misc.c buffer.c hash.c pkts.c qspn.c \
request.c \
radar.c gmap.c hook.c rehook.c if.c inet.c ipv6-gmp.c \
krnl_route.c andna.c snsd_cache.c andna_cache.c err_errno.c \
andns.c andns_lib.c dnslib.c andns_net.c andns_snsd.c \
bmap.c conf.c crypto.c daemon.c dns_wrapper.c endianness.c \
krnl_rule.c iptunnel.c libnetlink.c ll_map.c llist.c log.c \
route.c tracer.c igs.c libping.c xmalloc.c netsukuku.c \
mark.c libiptc/libip4tc.c
ntkd_LDADD = -lpthread -lgmp -lcrypto -lresolv -lz
ntk_resolv_SOURCES = andns_lib.c ntkresolv.c andns_net.c crypto.c \
snsd_cache.c inet.c ll_map.c libnetlink.c log.c \
xmalloc.c endianness.c misc.c err_errno.c buffer.c
ntk_resolv_LDADD = -lz -lcrypto

656
src/Makefile.in Normal file
View File

@ -0,0 +1,656 @@
# Makefile.in generated by automake 1.8.5 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
SOURCES = $(ntk_resolv_SOURCES) $(ntkd_SOURCES)
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
host_triplet = @host@
bin_PROGRAMS = ntkd$(EXEEXT) ntk-resolv$(EXEEXT)
subdir = src
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
$(srcdir)/config.h.in TODO
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(mkdir_p)
CONFIG_HEADER = config.h
CONFIG_CLEAN_FILES =
am__installdirs = "$(DESTDIR)$(bindir)"
binPROGRAMS_INSTALL = $(INSTALL_PROGRAM)
PROGRAMS = $(bin_PROGRAMS)
am_ntk_resolv_OBJECTS = andns_lib.$(OBJEXT) ntkresolv.$(OBJEXT) \
andns_net.$(OBJEXT) crypto.$(OBJEXT) snsd_cache.$(OBJEXT) \
inet.$(OBJEXT) ll_map.$(OBJEXT) libnetlink.$(OBJEXT) \
log.$(OBJEXT) xmalloc.$(OBJEXT) endianness.$(OBJEXT) \
misc.$(OBJEXT) err_errno.$(OBJEXT) buffer.$(OBJEXT)
ntk_resolv_OBJECTS = $(am_ntk_resolv_OBJECTS)
ntk_resolv_DEPENDENCIES =
am_ntkd_OBJECTS = accept.$(OBJEXT) map.$(OBJEXT) misc.$(OBJEXT) \
buffer.$(OBJEXT) hash.$(OBJEXT) pkts.$(OBJEXT) qspn.$(OBJEXT) \
request.$(OBJEXT) radar.$(OBJEXT) gmap.$(OBJEXT) \
hook.$(OBJEXT) rehook.$(OBJEXT) if.$(OBJEXT) inet.$(OBJEXT) \
ipv6-gmp.$(OBJEXT) krnl_route.$(OBJEXT) andna.$(OBJEXT) \
snsd_cache.$(OBJEXT) andna_cache.$(OBJEXT) err_errno.$(OBJEXT) \
andns.$(OBJEXT) andns_lib.$(OBJEXT) dnslib.$(OBJEXT) \
andns_net.$(OBJEXT) andns_snsd.$(OBJEXT) bmap.$(OBJEXT) \
conf.$(OBJEXT) crypto.$(OBJEXT) daemon.$(OBJEXT) \
dns_wrapper.$(OBJEXT) endianness.$(OBJEXT) krnl_rule.$(OBJEXT) \
iptunnel.$(OBJEXT) libnetlink.$(OBJEXT) ll_map.$(OBJEXT) \
llist.$(OBJEXT) log.$(OBJEXT) route.$(OBJEXT) tracer.$(OBJEXT) \
igs.$(OBJEXT) libping.$(OBJEXT) xmalloc.$(OBJEXT) \
netsukuku.$(OBJEXT) mark.$(OBJEXT) libip4tc.$(OBJEXT)
ntkd_OBJECTS = $(am_ntkd_OBJECTS)
ntkd_DEPENDENCIES =
DEFAULT_INCLUDES = -I. -I$(srcdir) -I.
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
@AMDEP_TRUE@DEP_FILES = ./$(DEPDIR)/accept.Po ./$(DEPDIR)/andna.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/andna_cache.Po ./$(DEPDIR)/andns.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/andns_lib.Po ./$(DEPDIR)/andns_net.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/andns_snsd.Po ./$(DEPDIR)/bmap.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/buffer.Po ./$(DEPDIR)/conf.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/crypto.Po ./$(DEPDIR)/daemon.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/dns_wrapper.Po ./$(DEPDIR)/dnslib.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/endianness.Po ./$(DEPDIR)/err_errno.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/gmap.Po ./$(DEPDIR)/hash.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/hook.Po ./$(DEPDIR)/if.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/igs.Po ./$(DEPDIR)/inet.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/iptunnel.Po ./$(DEPDIR)/ipv6-gmp.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/krnl_route.Po ./$(DEPDIR)/krnl_rule.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/libip4tc.Po ./$(DEPDIR)/libnetlink.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/libping.Po ./$(DEPDIR)/ll_map.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/llist.Po ./$(DEPDIR)/log.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/map.Po ./$(DEPDIR)/mark.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/misc.Po ./$(DEPDIR)/netsukuku.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/ntkresolv.Po ./$(DEPDIR)/pkts.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/qspn.Po ./$(DEPDIR)/radar.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/rehook.Po ./$(DEPDIR)/request.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/route.Po ./$(DEPDIR)/snsd_cache.Po \
@AMDEP_TRUE@ ./$(DEPDIR)/tracer.Po ./$(DEPDIR)/xmalloc.Po
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
CCLD = $(CC)
LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
SOURCES = $(ntk_resolv_SOURCES) $(ntkd_SOURCES)
DIST_SOURCES = $(ntk_resolv_SOURCES) $(ntkd_SOURCES)
RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
html-recursive info-recursive install-data-recursive \
install-exec-recursive install-info-recursive \
install-recursive installcheck-recursive installdirs-recursive \
pdf-recursive ps-recursive uninstall-info-recursive \
uninstall-recursive
ETAGS = etags
CTAGS = ctags
DIST_SUBDIRS = $(SUBDIRS)
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CONF_DIR = @CONF_DIR@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DATA_DIR = @DATA_DIR@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
IF_METHOD = @IF_METHOD@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
KERNEL_METHOD = @KERNEL_METHOD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
OBJEXT = @OBJEXT@
OTHER_METHOD = @OTHER_METHOD@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PID_DIR = @PID_DIR@
RT_METHOD = @RT_METHOD@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_STRIP = @ac_ct_STRIP@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
debug_flags = @debug_flags@
exec_prefix = @exec_prefix@
gmp = @gmp@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
prefix = @prefix@
program_transform_name = @program_transform_name@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
SUBDIRS = man scripts conf
AM_CFLAGS = -g -I. @debug_flags@ -I@gmp@
AM_CXXFLAGS = -g -I. @debug_flags@ -I@gmp@
ntkd_SOURCES = accept.c map.c misc.c buffer.c hash.c pkts.c qspn.c \
request.c \
radar.c gmap.c hook.c rehook.c if.c inet.c ipv6-gmp.c \
krnl_route.c andna.c snsd_cache.c andna_cache.c err_errno.c \
andns.c andns_lib.c dnslib.c andns_net.c andns_snsd.c \
bmap.c conf.c crypto.c daemon.c dns_wrapper.c endianness.c \
krnl_rule.c iptunnel.c libnetlink.c ll_map.c llist.c log.c \
route.c tracer.c igs.c libping.c xmalloc.c netsukuku.c \
mark.c libiptc/libip4tc.c
ntkd_LDADD = -lpthread -lgmp -lcrypto -lresolv -lz
ntk_resolv_SOURCES = andns_lib.c ntkresolv.c andns_net.c crypto.c \
snsd_cache.c inet.c ll_map.c libnetlink.c log.c \
xmalloc.c endianness.c misc.c err_errno.c buffer.c
ntk_resolv_LDADD = -lz -lcrypto
all: config.h
$(MAKE) $(AM_MAKEFLAGS) all-recursive
.SUFFIXES:
.SUFFIXES: .c .o .obj
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu src/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
config.h: stamp-h1
@if test ! -f $@; then \
rm -f stamp-h1; \
$(MAKE) stamp-h1; \
else :; fi
stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
@rm -f stamp-h1
cd $(top_builddir) && $(SHELL) ./config.status src/config.h
$(srcdir)/config.h.in: $(am__configure_deps)
cd $(top_srcdir) && $(AUTOHEADER)
rm -f stamp-h1
touch $@
distclean-hdr:
-rm -f config.h stamp-h1
install-binPROGRAMS: $(bin_PROGRAMS)
@$(NORMAL_INSTALL)
test -z "$(bindir)" || $(mkdir_p) "$(DESTDIR)$(bindir)"
@list='$(bin_PROGRAMS)'; for p in $$list; do \
p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \
if test -f $$p \
; then \
f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \
echo " $(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(bindir)/$$f'"; \
$(INSTALL_PROGRAM_ENV) $(binPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(bindir)/$$f" || exit 1; \
else :; fi; \
done
uninstall-binPROGRAMS:
@$(NORMAL_UNINSTALL)
@list='$(bin_PROGRAMS)'; for p in $$list; do \
f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \
echo " rm -f '$(DESTDIR)$(bindir)/$$f'"; \
rm -f "$(DESTDIR)$(bindir)/$$f"; \
done
clean-binPROGRAMS:
-test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
ntk-resolv$(EXEEXT): $(ntk_resolv_OBJECTS) $(ntk_resolv_DEPENDENCIES)
@rm -f ntk-resolv$(EXEEXT)
$(LINK) $(ntk_resolv_LDFLAGS) $(ntk_resolv_OBJECTS) $(ntk_resolv_LDADD) $(LIBS)
ntkd$(EXEEXT): $(ntkd_OBJECTS) $(ntkd_DEPENDENCIES)
@rm -f ntkd$(EXEEXT)
$(LINK) $(ntkd_LDFLAGS) $(ntkd_OBJECTS) $(ntkd_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/accept.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/andna.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/andna_cache.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/andns.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/andns_lib.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/andns_net.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/andns_snsd.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bmap.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/buffer.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/conf.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/crypto.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/daemon.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dns_wrapper.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dnslib.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/endianness.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/err_errno.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gmap.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hook.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/if.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/igs.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/inet.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iptunnel.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ipv6-gmp.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/krnl_route.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/krnl_rule.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libip4tc.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libnetlink.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libping.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ll_map.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/llist.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/log.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/map.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mark.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/misc.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/netsukuku.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ntkresolv.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkts.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/qspn.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/radar.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rehook.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/request.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/route.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/snsd_cache.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tracer.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/xmalloc.Po@am__quote@
.c.o:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ $<; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
.c.obj:
@am__fastdepCC_TRUE@ if $(COMPILE) -MT $@ -MD -MP -MF "$(DEPDIR)/$*.Tpo" -c -o $@ `$(CYGPATH_W) '$<'`; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/$*.Tpo" "$(DEPDIR)/$*.Po"; else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/$*.Po' tmpdepfile='$(DEPDIR)/$*.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
libip4tc.o: libiptc/libip4tc.c
@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libip4tc.o -MD -MP -MF "$(DEPDIR)/libip4tc.Tpo" -c -o libip4tc.o `test -f 'libiptc/libip4tc.c' || echo '$(srcdir)/'`libiptc/libip4tc.c; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libip4tc.Tpo" "$(DEPDIR)/libip4tc.Po"; else rm -f "$(DEPDIR)/libip4tc.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libiptc/libip4tc.c' object='libip4tc.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libip4tc.Po' tmpdepfile='$(DEPDIR)/libip4tc.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libip4tc.o `test -f 'libiptc/libip4tc.c' || echo '$(srcdir)/'`libiptc/libip4tc.c
libip4tc.obj: libiptc/libip4tc.c
@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT libip4tc.obj -MD -MP -MF "$(DEPDIR)/libip4tc.Tpo" -c -o libip4tc.obj `if test -f 'libiptc/libip4tc.c'; then $(CYGPATH_W) 'libiptc/libip4tc.c'; else $(CYGPATH_W) '$(srcdir)/libiptc/libip4tc.c'; fi`; \
@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/libip4tc.Tpo" "$(DEPDIR)/libip4tc.Po"; else rm -f "$(DEPDIR)/libip4tc.Tpo"; exit 1; fi
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='libiptc/libip4tc.c' object='libip4tc.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/libip4tc.Po' tmpdepfile='$(DEPDIR)/libip4tc.TPo' @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o libip4tc.obj `if test -f 'libiptc/libip4tc.c'; then $(CYGPATH_W) 'libiptc/libip4tc.c'; else $(CYGPATH_W) '$(srcdir)/libiptc/libip4tc.c'; fi`
uninstall-info-am:
# This directory's subdirectories are mostly independent; you can cd
# into them and run `make' without going through this Makefile.
# To change the values of `make' variables: instead of editing Makefiles,
# (1) if the variable is set in `config.status', edit `config.status'
# (which will cause the Makefiles to be regenerated when you run `make');
# (2) otherwise, pass the desired values on the `make' command line.
$(RECURSIVE_TARGETS):
@set fnord $$MAKEFLAGS; amf=$$2; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
dot_seen=yes; \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done; \
if test "$$dot_seen" = "no"; then \
$(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
fi; test -z "$$fail"
mostlyclean-recursive clean-recursive distclean-recursive \
maintainer-clean-recursive:
@set fnord $$MAKEFLAGS; amf=$$2; \
dot_seen=no; \
case "$@" in \
distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
*) list='$(SUBDIRS)' ;; \
esac; \
rev=''; for subdir in $$list; do \
if test "$$subdir" = "."; then :; else \
rev="$$subdir $$rev"; \
fi; \
done; \
rev="$$rev ."; \
target=`echo $@ | sed s/-recursive//`; \
for subdir in $$rev; do \
echo "Making $$target in $$subdir"; \
if test "$$subdir" = "."; then \
local_target="$$target-am"; \
else \
local_target="$$target"; \
fi; \
(cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
|| case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
done && test -z "$$fail"
tags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
done
ctags-recursive:
list='$(SUBDIRS)'; for subdir in $$list; do \
test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
done
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
mkid -fID $$unique
tags: TAGS
TAGS: tags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
include_option=--etags-include; \
empty_fix=.; \
else \
include_option=--include; \
empty_fix=; \
fi; \
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test ! -f $$subdir/TAGS || \
tags="$$tags $$include_option=$$here/$$subdir/TAGS"; \
fi; \
done; \
list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$tags $$unique; \
fi
ctags: CTAGS
CTAGS: ctags-recursive $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
$(TAGS_FILES) $(LISP)
tags=; \
here=`pwd`; \
list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
$(AWK) ' { files[$$0] = 1; } \
END { for (i in files) print i; }'`; \
test -z "$(CTAGS_ARGS)$$tags$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$tags $$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& cd $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) $$here
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
list='$(SUBDIRS)'; for subdir in $$list; do \
if test "$$subdir" = .; then :; else \
test -d "$(distdir)/$$subdir" \
|| mkdir "$(distdir)/$$subdir" \
|| exit 1; \
(cd $$subdir && \
$(MAKE) $(AM_MAKEFLAGS) \
top_distdir="../$(top_distdir)" \
distdir="../$(distdir)/$$subdir" \
distdir) \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-recursive
all-am: Makefile $(PROGRAMS) config.h
installdirs: installdirs-recursive
installdirs-am:
for dir in "$(DESTDIR)$(bindir)"; do \
test -z "$$dir" || $(mkdir_p) "$$dir"; \
done
install: install-recursive
install-exec: install-exec-recursive
install-data: install-data-recursive
uninstall: uninstall-recursive
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-recursive
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-recursive
clean-am: clean-binPROGRAMS clean-generic mostlyclean-am
distclean: distclean-recursive
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-hdr distclean-tags
dvi: dvi-recursive
dvi-am:
html: html-recursive
info: info-recursive
info-am:
install-data-am:
install-exec-am: install-binPROGRAMS
install-info: install-info-recursive
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-recursive
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-recursive
mostlyclean-am: mostlyclean-compile mostlyclean-generic
pdf: pdf-recursive
pdf-am:
ps: ps-recursive
ps-am:
uninstall-am: uninstall-binPROGRAMS uninstall-info-am
uninstall-info: uninstall-info-recursive
.PHONY: $(RECURSIVE_TARGETS) CTAGS GTAGS all all-am check check-am \
clean clean-binPROGRAMS clean-generic clean-recursive ctags \
ctags-recursive distclean distclean-compile distclean-generic \
distclean-hdr distclean-recursive distclean-tags distdir dvi \
dvi-am html html-am info info-am install install-am \
install-binPROGRAMS install-data install-data-am install-exec \
install-exec-am install-info install-info-am install-man \
install-strip installcheck installcheck-am installdirs \
installdirs-am maintainer-clean maintainer-clean-generic \
maintainer-clean-recursive mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-recursive pdf pdf-am ps ps-am \
tags tags-recursive uninstall uninstall-am \
uninstall-binPROGRAMS uninstall-info-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

215
src/SConstruct Normal file
View File

@ -0,0 +1,215 @@
# This file is part of Netsukuku
# (c) Copyright 2005 Andrea Lo Pumo aka AlpT <alpt@freaknet.org>
#
# This source code is free software; you can redistribute it and/or
# modify it under the terms of the GNU Public License as published
# by the Free Software Foundation; either version 2 of the License,
# or (at your option) any later version.
#
# This source code 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.
# Please refer to the GNU Public License for more details.
#
# You should have received a copy of the GNU Public License along with
# this source code; if not, write to:
# Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
import sys
import os
NTK_VERSION="0.0.9b"
#
# Sources and libs
#
sources_common = Split('xmalloc.c log.c misc.c buffer.c endianness.c')
sources_qspn = Split('qspn-empiric.c') + sources_common
sources_netsukuku = Split("""accept.c llist.c ipv6-gmp.c inet.c request.c map.c
gmap.c bmap.c pkts.c radar.c hook.c rehook.c tracer.c qspn.c
hash.c daemon.c crypto.c snsd_cache.c
andna_cache.c andna.c andns_lib.c err_errno.c
dnslib.c andns.c andns_net.c andns_snsd.c
ll_map.c libnetlink.c if.c krnl_route.c krnl_rule.c
iptunnel.c route.c conf.c dns_wrapper.c igs.c mark.c
libiptc/libip4tc.c libping.c netsukuku.c""") + sources_common
sources_ntkresolv = sources_common + Split("""andns_lib.c ntkresolv.c andns_net.c
crypto.c snsd_cache.c inet.c
ll_map.c libnetlink.c
err_errno.c""")
libs = ['gmp', 'pthread', 'crypto', 'z']
#
# Command line options and help
#
opts = Options('build.conf')
opts.AddOptions(('CONF_DIR', """Directory where the Netsukuku configuration files will be installed""",
'/etc/netsukuku'),
('DATA_DIR', 'Directory to install data files',
'/usr/share/netsukuku'),
('MAN_DIR', 'Where the manuals will be installed',
'/usr/man'),
('BIN_DIR' , 'Directory to install the binaries',
'/usr/bin'),
('PID_DIR', 'Specify location of ntkd.pid file',
'/var/run'),
('destdir', 'SCons will copy all the files under destdir during installation',
'/'),
EnumOption('debug', 'build the debug code', 'no',
allowed_values=('yes', 'no', '1', '0'), map={},
ignorecase=0),
EnumOption('static', 'build statically the binaries', 'no',
allowed_values=('yes', 'no', '1', '0'), map={},
ignorecase=0))
opts.Add('CC', 'The C compiler.')
opts.Add('CXX', 'The C++ compiler.')
env = Environment(options = opts, ENV = os.environ, CCFLAGS = ' -Wall')
if ("yes" in env['debug']) or ("1" in env['debug']):
debug = 1
env.Append(CPPDEFINES={'DEBUG' : '${debug}'}, CCFLAGS = ' -ggdb -Wall', CXXFLAGS = '-g')
#CCFLAGS = ' -ggdb -Wall -DDMALLOC_FUNC_CHECK'
# libs+=['dmalloc', 'dmallocth']
os.system("echo Cscoping and ctagging...; cscope -b; ctags *")
else:
debug = 0
if ("yes" in env['static']) or ("1" in env['static']):
static = 1
env.Append(CCFLAGS = ' -static', CXXFLAGS = '-static')
else:
static = 0
if (env['destdir'] == "/"):
env['destdir']=""
opts.Save('build.conf', env)
if os.path.exists("conf/netsukuku.conf") and env.GetOption('clean'):
Execute(Delete('conf/netsukuku.conf'))
if os.path.exists("config.h") and env.GetOption('clean'):
Execute(Delete('config.h'))
if os.path.exists("config.log") and env.GetOption('clean'):
Execute(Delete('config.log'))
Help("""
*** Usage
'scons' to build the ntkd binary,
'scons debug=yes' to build the debug version.
'scons install' to install it in the system.
*** General options
""" + opts.GenerateHelpText(env))
if ARGUMENTS.get('install'):
print "you aren't root"
#
# Configure
#
if not os.path.exists("config.log") and not env.GetOption('clean'):
print 'Configuring... '
conf = Configure(env)
if not conf.CheckLib('gmp'):
print 'Did not find libgmp.a or gmp.lib, exiting!'
Execute(Delete('config.log'))
Exit(1)
if not conf.CheckCHeader([ "gmp.h" ]):
print 'Did not find the gmp headers, exiting!'
Execute(Delete('config.log'))
Exit(1)
if not conf.CheckCHeader([ "zlib.h" ]):
print 'Did not find the zlib headers, exiting!'
Execute(Delete('config.log'))
Exit(1)
if not conf.CheckLib('pthread'):
print 'Did not find pthread.a or pthread.lib, exiting!'
Execute(Delete('config.log'))
Exit(1)
if not conf.CheckLib('crypto'):
print 'Did not find the openssl libcrypto.a or libcrypto.lib, exiting!'
Execute(Delete('config.log'))
Exit(1)
if not conf.CheckCHeader([ "openssl/bio.h", "openssl/evp.h",
"openssl/crypto.h", "openssl/x509.h",
"openssl/engine.h", "openssl/err.h", "openssl/rand.h",
"openssl/rsa.h", "openssl/pem.h" ]):
print 'Did not find the openssl headers, exiting!'
Execute(Delete('config.log'))
Exit(1)
env = conf.Finish()
def conf_build(target, source, env):
conf_defines = {
"CONF_DIR": env["CONF_DIR"],
"DATA_DIR": env["DATA_DIR"],
"PID_DIR": env["PID_DIR"],
"VERSION": NTK_VERSION,
"debug": debug # this is an int. 1 for true, 0 for false
}
conf = file(str(target), "w")
conf_in = file(str(source), "r")
conf.write(conf_in.read() % conf_defines)
conf_in.close()
conf.close()
def build_config_files(target = None, source = None, env = None):
if not os.path.exists("config.h") and not env.GetOption('clean'):
print 'Generating config.h from config_scons.h.in'
conf_build('config.h', 'config_scons.h.in', env)
conf = file("config.h", "a")
if sys.platform == 'linux2' or sys.platform == 'linux-i386':
conf.write("#define GNU_LINUX\n")
elif sys.platform == 'darwin':
conf.write("#define DARWIN\n")
elif string.find (sys.platform, 'sunos') != -1:
conf.write("#define SUNOS\n")
elif sys.platform=='openbsd3':
conf.write("#define OPEN_BSD\n")
elif string.find (sys.platform, 'irix') != -1:
conf.write("#define IRIX\n")
conf.close()
if not os.path.exists("conf/netsukuku.conf") and not env.GetOption('clean'):
print 'Generating conf/netsukuku.conf from conf/ntk_scons.conf.in'
conf_build('conf/netsukuku.conf', 'conf/ntk_scons.conf.in', env)
return 0
build_config_files(env = env)
#
# Build
#
ntkd = env.Program('ntkd', sources_netsukuku, LIBS = libs, CPPPATH = '.')
qspn = env.Program('qspn-empiric', sources_qspn, LIBS = libs, CPPPATH = '.')
ntkresolv = env.Program('ntk-resolv', sources_ntkresolv, LIBS = libs, CPPPATH = '.')
Default(ntkd, ntkresolv)
#
# Install
#
SConscript(['man/SConscript', 'scripts/SConscript', 'conf/SConscript'], 'env')
# Here are our installation paths:
idir_bin = '$destdir' + '$BIN_DIR'
idir_data = '$destdir' + '$DATA_DIR'
idir_conf = '$destdir' + '$CONF_DIR'
idir_pid = '$destdir' + '$PID_DIR'
env.Install(idir_bin, [ntkd])
env.Install(idir_bin, [ntkresolv])
env.Alias('install', [idir_bin, idir_conf])
#Dirty hack ;( Why GetOption("install") doesn't work?
#if not os.path.exists(env["DATA_DIR"]) and os.path.exists(env["CONF_DIR"]):
# Execute(Mkdir(env["DATA_DIR"]))

185
src/TODO Normal file
View File

@ -0,0 +1,185 @@
*
**
*** HIGH PRIORITY
**
*
* (generally these TODOs are already being implemented at the moment)
- restore the network when NetsukukuD is closed (call /etc/rc.d/rc.inet1 ?)
- Netsukuku WRT firmware:
- a configured openwrt release with all the necessary kernel modules
and packages installed
- A web interface to configure the /etc/netsukuku/netsukuku.conf file
and to use the rc.ntk script.
- bugs
- comments in resolv.conf are not considered:
NOTE: Do not resolv this BUG: Now It's useful
*
**
*** MEDIUM PRIORITY
**
*
- Equalize multipath routes. The `equalize' module is still experimental in
the kernel.
- bandwidth measurement
- do not delete an inet-gw if there's still bw passing on it.
- Viphilama: http://lab.dyne.org/Ntk_viphilama
- Bandwidth weight for each entry of the qspn (not just rtt and latency):
- what to use to get the bandwidth of a network interface?
Use `iperf' to measure once the max link bw, then monitor with
iptables the link and calculate the used bw.
- See http://lab.dyne.org/Ntk_bandwidth_measurement
- Gnodes contiguity
- gnode re-hook
- When we have two different gnodes A and C, and
then B hooks to A, nothing happens, since C, doesn't
receive any qspn_pkt
- test: two (g)nodes with the same IP
- currently only in particular situations the rehook
isn't possible: A - A, A - B - A.
- Challenge
- RSA between rnodes: the nodes which are already hooked ask
for the public key to the node which is hooking.
- Creation of the problem.
- Resolution of the problem.
- Diffusion of the reply.
- Reject of challenge for X time after a first challenge has
been completed.
- Do just one challenge at the same time, reject/delay all the
other which came later.
- If the challenge was rejected/delayed wait the right amount
of time and retry.
- Ban of gnodes which lost the challenge ?
- Challenge between two gnode not contiguous, which have the
same gid.
- turn andns_lib.c into a real shared library
- SNSD
- pubkey: automatic deletion request
- A firewall script to turn a ntk node into a routing only node.
other ntk nodes
|
|
|
_________
| N |
Internet ---------- | WRT ntk | - - w i f i - - - Ntk node A
|_________| \
| \
| \ Ntk node B
L A N
If N is set to a routing only node, then the nodes A and B will always be
able to reach the Internet and the "other ntk nodes" through it, but they
will not be able to reach the LAN connected to the node N.
Optionally the node N can leave some "backdoor" ports opened, f.e. it might
want to leave a ssh login which accepts keys authentication only.
The port used by Netsukuku will be leaved open too, in this way the nodes
can still communicate between them.
- Can multiple qspn packets be processed concurrently? Or do we need mutexes
for them? Only the tests will give answer.
*
**
*** LOW PRIORITY
**
*
- Interactive shell/console. Some commands that should be implemented:
"stats" gives statistics,
"rnodes" show the list of rnodes,
"int_map" dumps the internal map in a ASCIIful way,
"ext_map", "bnode_map", "andna_cache", ...,
"flush rhcache"
- ntk-finger: it would be handy to be able to know some info on a particular
node. The user puts his node info in /etc/netsukuku/finger.
$ ntk-finger remote_node_ip
will print out its /etc/netsukuku/finger.
- why don't we just use fingerd?
- too bugged?
- and what about a stupid shell script like this:
while [ 0 ]; do cat /etc/netsukuku/finger | nc -l -p 79; done
- renice the NetsukukuD process?
- small memory: if the system has <= X Mb of free memory, switch on dumb mode.
In this mode NetsukukuD keeps only the list of rnodes and forwards every
request to one of them. The lcl_cache is kept too.
- better memory utilisation: see MAXMSGSZ, PKT_MAX_MSG_SZ, pkt_verify_hdr(),
pkt_uncompress(), andns_uncompress().
- The maximum size of an uncompressed or compressed packet must be
proportional to the total free memory reserved to the daemon.
- pkt_uncompress() must be able to drop the packet if there's no
free memory available. The same must be done by pkt_recv() and
other similar functions.
- option to disable the modification of the routing table
- option to change on runtime the wait-times of the QSPN, radar, etc...
-normal, -high, -low
- option (both on command line and in netsukuku.conf) to disable the saving of
caches. (the keyring will always be saved).
- Change with something else the eliminable fatal() calls in netsukuku_hook()
- Ipv6 support: use ff05::23 for multicast. qspn_gnode_count isn't IPv6
compatible!
- Test request.c
- Port the kernel route code for *BSD: take a look at rt_ioctl.c and
rt_socket.c of quagga.
- use PREFIX in the man pages
- xmalloc.c: Implement a "wrapper heap". We do a big malloc() at the start and
then we manage personally it, in this way we avoid the huge
overhead of malloc.
- Compressed maps: save the files in compressed formats
- API for the syncronization of the maps the daemon. A third party program,
might want to have always the latest maps.
- Write the documentation for the code that can be used by other
programs. (By the way it is already commented.)
- krnl_conf.c: it reads /proc/kallsyms and verifies that there are the symbols
used by the modules/builtins kernel code netsukuku is dependent
on. kernel_conf.h will have an array like pkt_op_table (pkts.h).
Each symbol will be checked by the init functions. There will be
also associated an help function that tells what to do when the
symbol is missing in /proc/kallsyms. For example,
mark_rule_init() will do:
if(krnl_conf_check("netfilter") <0) {
krnl_netfilter_usage();
return -1
}
- Launch a trigger script. Possible events: INET_UP, INET_DOWN, NEW_RNODE,
DEAD_RNODE.
- Use bireloc from autopackage
- Use qemu to make Netsukuku run on windows?!?
- /*\ \*/

276
src/accept.c Normal file
View File

@ -0,0 +1,276 @@
/* This file is part of Netsukuku
* (c) Copyright 2005 Andrea Lo Pumo aka AlpT <alpt@freaknet.org>
*
* This source code 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 2 of the License,
* or (at your option) any later version.
*
* This source code 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.
* Please refer to the GNU Public License for more details.
*
* You should have received a copy of the GNU Public License along with
* this source code; if not, write to:
* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* --
* accept.c: This is how it works:
*
* When a new accept is made add_accept is called. It first updates the accept
* table and then, if the accept_tbl isn't full add the new accept in the tbl.
* If the accept_tbl is full the connection is dropped.
* Each accept in the table last for free_accept_time after the close of that
* connection, so if an host has fulled the accept_tbl has to wait
* free_accept_time of seconds to be able to reconnect again.
*/
#include "includes.h"
#include "request.h"
#include "inet.h"
#include "accept.h"
#include "xmalloc.h"
#include "log.h"
void init_accept_tbl(int startups, int accepts, int time)
{
/* TODO: activate and test it !! */
#if 0
int i;
max_connections=startups;
max_accepts_per_host=accepts;
free_accept_time=time;
accept_idx=accept_sidx=0;
pthread_mutex_init(&mtx_acpt_idx, NULL);
pthread_mutex_init(&mtx_acpt_sidx, NULL);
accept_tbl=(struct accept_table *)xmalloc(sizeof(struct accept_table)*max_connections);
memset(accept_tbl, '\0', sizeof(struct accept_table)*max_connections);
for(i=0; i<max_connections; i++) {
accept_tbl[i].pid=(pid_t *)xmalloc(sizeof(pid_t)*max_accepts_per_host);
memset(accept_tbl[i].pid, '\0', sizeof(pid_t)*max_accepts_per_host);
accept_tbl[i].closed=(unsigned char *)xmalloc(sizeof(unsigned char)*max_accepts_per_host);
memset(accept_tbl[i].closed, '\0', sizeof(unsigned char)*max_accepts_per_host);
accept_tbl[i].acp_t=(time_t *)xmalloc(sizeof(time_t)*max_accepts_per_host);
memset(accept_tbl[i].acp_t, '\0', sizeof(time_t)*max_accepts_per_host);
}
#endif
}
void destroy_accept_tbl(void)
{
/* TODO: activate and test it !! */
#if 0
int i;
if(!accept_tbl)
return;
for(i=0; i<max_connections; i++) {
xfree(accept_tbl[i].pid);
xfree(accept_tbl[i].closed);
xfree(accept_tbl[i].acp_t);
}
xfree(accept_tbl);
accept_tbl=0;
#endif
}
void update_accept_tbl(void)
{
time_t cur_t, passed_time;
int i,e,k,ee, pid_exists;
if(update_accept_tbl_mutex)
return;
else
update_accept_tbl_mutex=1;
time(&cur_t);
for(i=0; i < max_connections; i++) {
if(!accept_tbl[i].ip.len)
continue;
if(accept_tbl[i].accepts) {
for(e=0; e<max_accepts_per_host; e++) {
if(!accept_tbl[i].acp_t[e])
continue;
if(accept_tbl[i].pid[e]) {
k=kill(accept_tbl[i].pid[e], 0);
pid_exists = !(k==-1 && errno==ESRCH);
} else
pid_exists=0;
#if 0
debug(DBG_NOISE, "ACPT: Updating tbl: cur_t: %d, "
"accept_tbl[%d].acp_t[%d]:%d+%d, "
"accept_tbl[i].pid[e]: %d, "
"kill=%d (ESRCH=%d)",
cur_t, i,e, accept_tbl[i].acp_t[e],
free_accept_time, accept_tbl[i].pid[e],
k, ESRCH);
#endif
passed_time=accept_tbl[i].acp_t[e]+free_accept_time;
if((accept_tbl[i].closed[e] || !pid_exists) &&
passed_time <= cur_t) {
ee=e;
del_accept(i, &ee);
}
}
}
}
update_accept_tbl_mutex=0;
}
int find_ip_acpt(inet_prefix ip)
{
int i;
for(i=0; i<max_accepts_per_host; i++) {
if(!memcmp(accept_tbl[i].ip.data, &ip.data, MAX_IP_SZ))
return i;
}
return -1;
}
int find_first_free(void)
{
int i;
for(i=0; i<max_connections; i++)
if(!accept_tbl[i].accepts)
return i;
return -1;
}
int is_ip_acpt_free(inet_prefix ip, int *index)
{
int idx;
update_accept_tbl();
if((idx=find_ip_acpt(ip))==-1)
if((idx=find_first_free())==-1)
return E_TOO_MANY_CONN;
/*debug(DBG_NOISE, "ACPT: accept_tbl[%d].accepts: %d, max_acp: %d", idx,
accept_tbl[idx].accepts, max_accepts_per_host); */
if(accept_tbl[idx].accepts >= max_accepts_per_host)
return E_ACCEPT_TBL_FULL;
*index=idx;
return 0;
}
int find_free_acp_t(int idx)
{
int e;
for(e=0; e < max_accepts_per_host; e++) {
if(!accept_tbl[idx].acp_t[e])
return e;
}
return -1; /*This happens if the rq_tbl is full for the "rq" request*/
}
int new_accept(int idx, inet_prefix ip)
{
int cl=0;
/* TODO: activate and test it !! */
#if 0
time_t cur_t;
time(&cur_t);
if((cl=find_free_acp_t(idx))==-1)
return -1;
accept_tbl[idx].accepts++;
accept_tbl[idx].acp_t[cl]=cur_t;
accept_tbl[idx].closed[cl]=0;
inet_copy(&accept_tbl[idx].ip, &ip);
#endif
return cl;
}
/*
* add_accept: It adds a new accept of `ip'. If `replace' is not 0 the `ip's
* accepts are not incremented and accept_sidx is set to 0.
*/
int add_accept(inet_prefix ip, int replace)
{
/* TODO: activate and test it !! */
#if 0
int err, idx, cl;
if((err=is_ip_acpt_free(ip, &idx)))
return err;
if(!replace || !accept_tbl[idx].accepts) {
cl=new_accept(idx, ip);
if(cl < 0)
return -1;
} else
cl=0;
/*This global var will be given to the thread*/
pthread_mutex_lock(&mtx_acpt_idx);
accept_idx=idx;
pthread_mutex_unlock(&mtx_acpt_idx);
pthread_mutex_lock(&mtx_acpt_sidx);
accept_sidx=cl;
pthread_mutex_unlock(&mtx_acpt_sidx);
#endif
return 0;
}
void del_accept(int idx, int *sidx)
{
#if 0
if(!accept_tbl[idx].accepts)
return;
if(accept_tbl[idx].acp_t[*sidx]) {
accept_tbl[idx].accepts--;
accept_tbl[idx].acp_t[*sidx]=0;
accept_tbl[idx].closed[*sidx]=0;
if(!accept_tbl[idx].accepts)
memset(&accept_tbl[idx].ip, '\0', sizeof(inet_prefix));
(*sidx)--;
}
#endif
}
int close_accept(int idx, int sidx)
{
#if 0
if(!accept_tbl[idx].accepts)
return -1;
accept_tbl[idx].closed[sidx]=1;
#endif
return 0;
}
void add_accept_pid(pid_t pid, int idx, int sidx)
{
/* TODO: activate and test it !! */
#if 0
accept_tbl[idx].pid[sidx]=pid;
/* debug(DBG_NOISE, "ACPT: Added pig %d in accept_tbl[%d].pid[%d]",
accept_tbl[idx].pid[sidx], idx, sidx);
*/
#endif
}

75
src/accept.h Normal file
View File

@ -0,0 +1,75 @@
/* This file is part of Netsukuku
* (c) Copyright 2004 Andrea Lo Pumo aka AlpT <alpt@freaknet.org>
*
* This source code 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 2 of the License,
* or (at your option) any later version.
*
* This source code 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.
* Please refer to the GNU Public License for more details.
*
* You should have received a copy of the GNU Public License along with
* this source code; if not, write to:
* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef ACCEPT_H
#define ACCEPT_H
#define MAX_CONNECTIONS 512
#define MAX_ACCEPTS 16
#define FREE_ACCEPT_TIME 4 /*in seconds*/
/*
* This struct keep tracks of single connection to the server.
* The thread_daemon who handle the connection knows the connection
* position in the accept_tbl.
*/
struct accept_table
{
inet_prefix ip; /*Ip of the node connected*/
unsigned char accepts; /*Number of connection from this node*/
pid_t *pid; /*The pid of each child that have accepted the conn*/
unsigned char *closed; /*Each element of this array is 1 or 0. It indicates if the connection has
been closed*/
time_t *acp_t; /*The time when the connection was accepted. The "accepts" counter
will decrement when one of the acp_t+FREE_ACCEPT_TIME will
be <= current_time AND (the relative pid will be non existent OR
the relative closed element will be == 1)
*/
struct request_tbl rqtbl; /*The request table*/
};
/* This struct keeps all the info regarding each node connected */
struct accept_table *accept_tbl;
/*
* accept_idx is the position of the accept_tbl of a thread.
* accept_sidx is the second index, it is used for example in pid[accept_sidx]
* note: this var are used only in the child and the child doesn't need to modify them!
*/
int accept_idx, accept_sidx;
pthread_mutex_t mtx_acpt_idx, mtx_acpt_sidx;
int update_accept_tbl_mutex;
int max_connections, max_accepts_per_host, free_accept_time;
void init_accept_tbl(int startups, int accepts, int time);
void destroy_accept_tbl(void);
void update_accept_tbl(void);
int find_ip_acpt(inet_prefix ip);
int find_first_free(void);
int is_ip_acpt_free(inet_prefix ip, int *index);
int find_free_acp_t(int idx);
int new_accept(int idx, inet_prefix ip);
int add_accept(inet_prefix ip, int replace);
void del_accept(int idx, int *sidx);
int close_accept(int idx, int sidx);
void add_accept_pid(pid_t pid, int idx, int sidx);
#endif /*ACCEPT_H*/

2507
src/andna.c Normal file

File diff suppressed because it is too large Load Diff

273
src/andna.h Normal file
View File

@ -0,0 +1,273 @@
/* This file is part of Netsukuku
* (c) Copyright 2005 Andrea Lo Pumo aka AlpT <alpt@freaknet.org>
*
* This source code 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 2 of the License,
* or (at your option) any later version.
*
* This source code 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.
* Please refer to the GNU Public License for more details.
*
* You should have received a copy of the GNU Public License along with
* this source code; if not, write to:
* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef ANDNA_H
#define ANDNA_H
#include "andna_cache.h"
#include "pkts.h"
#define MY_NAMESERV "nameserver 127.0.0.1"
#define MY_NAMESERV_IPV6 "nameserver ::1"
#define ETC_RESOLV_CONF "/etc/resolv.conf"
#define ETC_RESOLV_CONF_BAK "/etc/resolv.conf.bak"
/* How many different andna pkt can be flooded simultaneusly */
#define ANDNA_MAX_FLOODS (ANDNA_MAX_QUEUE*3+1)
/* How many new hash_gnodes are supported in the andna hash_gnode mutation */
#define ANDNA_MAX_NEW_GNODES 1024
/*
* These arrays keeps the latest reg_pkt and counter_check IDs to drop pkts
* alreay received during the floods. These arrays are a FIFO, so the
* last pkt_id will be always at the 0 position, while the first one will be
* at the last position
*/
int last_reg_pkt_id[ANDNA_MAX_FLOODS];
int last_counter_pkt_id[ANDNA_MAX_FLOODS];
int last_spread_acache_pkt_id[ANDNA_MAX_FLOODS];
/*\
* *** ANDNA hash notes ***
*
* In ANDNA there are three type of hashes: MD5, 32bit, 32bit hash of a MD5
* hash. These hashes are generally applied on hostnames.
*
* The andna_hash() function, defined in andna.c, is used to calculate
* the IP of a hash_node/hash_gnode/counter_node. It makes a MD5 digest of the
* input data. If we are working on ipv4, then a 32bit hash is applied to the
* previously calculated MD5 digest. The result is the IP of the hash_gnode.
* If we are in ipv6, we'll use directly the MD5 digest as the hash_gnode IP.
*
* In all the other cases we'll use directly the MD5 hash of the hostname,
* f.e. the hname hash of the registration and resolution packets is a MD5.
* The only exceptions are the lcl_cache and the rh_cache, which use
* internally a 32bit hash to speed up the hname lookups.
*
* The general guideline for new implementation is to always use big hashes
* (i.e. MD5) where we might get collisions (f.e in an andna_cache), and to
* use small hashes where we are safe (f.e. in the rhc_cache).
*
\*/
/*\
*
* * * * ANDNA requests/replies pkt stuff * * *
*
\*/
#define ANDNA_HOOK_TIMEOUT 8 /* seconds */
#define ANDNA_REV_RESOLVE_RQ_TIMEOUT 60
/* * * andna pkt flags * * */
#define ANDNA_PKT_UPDATE 1 /* Update the hostname */
#define ANDNA_PKT_FORWARD (1<<1) /* Forward this pkt, plz */
#define ANDNA_PKT_REV_RESOLVE (1<<2) /* Give me your hostnames */
#define ANDNA_PKT_JUST_CHECK (1<<3) /* Check only, don't update
anything */
#define ANDNA_PKT_SNSD_DEL (1<<4) /* SNSD delete request */
/*
* andna_reg_pkt
*
* Andna registration request pkt used to send the registration and update
* requests to the hash_gnode, backup_gnode and counter_gnode.
* When the pkt is sent to a counter_gnode, a second `rip', which is the ip
* of the hash_gnode who is contacting the counter_gnode, is appended at the
* end of the pkt.
*
* When the packet is sent to a hash_gnode, at the end of the packet is
* included a packed snsd_service linked list. It is the list of snsd_records
* that have to be registered. However the packet forwarded to the counter
* node won't keep this part.
*/
struct andna_reg_pkt
{
u_int rip[MAX_IP_INT]; /* register_node ip */
u_int hash[MAX_IP_INT]; /* md5 hash of the host name to
register. */
char pubkey[ANDNA_PKEY_LEN]; /* public key of the register
node. */
u_short hname_updates; /* number of updates already
made for the hostname */
char sign[ANDNA_SIGNATURE_LEN]; /* RSA signature of the
entire pkt (excluding
`sign' itself and `flags'
*/
char flags;
} _PACKED_;
#define ANDNA_REG_PKT_SZ (sizeof(struct andna_reg_pkt))
#define ANDNA_REG_SIGNED_BLOCK_SZ (ANDNA_REG_PKT_SZ - ANDNA_SIGNATURE_LEN - \
sizeof(char))
INT_INFO andna_reg_pkt_iinfo = { 1, /* `rip' and `hash' aren't considered */
{ INT_TYPE_16BIT },
{ MAX_IP_SZ*2 + ANDNA_PKEY_LEN },
{ 1 },
};
/*
* andna_resolve_rq_pkt
*
* The andna resolve request pkt is used to resolve hostnames, IPs and MX
* hostnames.
*/
struct andna_resolve_rq_pkt
{
u_int rip[MAX_IP_INT]; /* the ip of the requester node */
char flags;
u_int hash[MAX_IP_INT]; /* md5 hash of the hostname to
resolve. */
int service; /* the snsd service of the hname */
u_char proto; /* the protocol of `service' */
} _PACKED_;
#define ANDNA_RESOLVE_RQ_PKT_SZ (sizeof(struct andna_resolve_rq_pkt))
INT_INFO andna_resolve_rq_pkt_iinfo = { 1, /* `rip' and `hash' are ignored */
{ INT_TYPE_32BIT },
{ MAX_IP_SZ*2+sizeof(char) },
{ 1 },
};
/*
* The reply to the resolve request
*/
struct andna_resolve_reply_pkt
{
uint32_t timestamp; /* the difference between the current
time and the last time the resolved
hname was updated */
/*
* the rest of the pkt is a pack of one snsd_service llist:
* char service[SNSD_SERVICE_LLIST_PACK_SZ(service)];
*/
} _PACKED_;
#define ANDNA_RESOLVE_REPLY_PKT_SZ (sizeof(struct andna_resolve_reply_pkt))
INT_INFO andna_resolve_reply_pkt_iinfo = { 1, /* `ip' is ignored */
{ INT_TYPE_32BIT },
{ 0 },
{ 1 }
};
/*
* The reply to the reverse resolve request is just the packed local cache.
*/
/*
* single_acache
*
* The single_acache pkt is used to get from an old hash_gnode a single
* andna_cache, which has the wanted `hash'. Its propagation method is similar
* to that of andna_resolve_rq_pkt, but each new hash_gnode, which receives
* the pkt, adds in the body pkt its ip. The added ips are used as excluded
* hash_gnode by find_hash_gnode(). In this way each time an old hash_gnode
* receives the pkt, can verify if it is, at that current time, the true old
* hash_gnode by excluding the hash_gnodes listed in the pkt body. If it
* notices that there's an hash_gnode older than it, it will append its ip in
* the pkt body and will forward it to that older hash_gnode. And so on, until
* the pkt reaches a true old hash_gnode, or cannot be forwarded anymore since
* there are no more older hash_gnodes.
*/
struct single_acache_hdr
{
u_int rip[MAX_IP_INT]; /* the ip of the requester node */
u_int hash[MAX_IP_INT];
u_short hgnodes; /* Number of hgnodes in the
body. */
u_char flags;
} _PACKED_;
INT_INFO single_acache_hdr_iinfo = { 1, /* `rip' and `hash' are ignored */
{ INT_TYPE_16BIT },
{ MAX_IP_SZ*2 },
{ 1 },
};
/*
* The single_acache body is:
* struct {
* u_int hgnode[MAX_IP_INT];
* } body[new_hash_gnode_hdr.hgnodes];
*/
#define SINGLE_ACACHE_PKT_SZ(hgnodes) (sizeof(struct single_acache_hdr)+\
MAX_IP_SZ*(hgnodes))
/*
* The single_acache_reply is just an andna_cache_pkt with a single cache.
*/
/*
* Tell the node, which receives the pkt, to send a ANDNA_GET_SINGLE_ACACHE
* request to fetch the andna_cache for the `hash' included in the pkt.
*/
struct spread_acache_pkt
{
u_int hash[MAX_IP_INT];
} _PACKED_;
#define SPREAD_ACACHE_PKT_SZ (sizeof(struct spread_acache_pkt))
INT_INFO spread_acache_pkt_info = { 0, { 0 }, { 0 }, { 0 } };
/*\
*
* * * * Function declaration * * *
*
\*/
int andna_load_caches(void);
int andna_save_caches(void);
void andna_init(void);
void andna_close(void);
void andna_resolvconf_modify(void);
void andna_resolvconf_restore(void);
int andna_register_hname(lcl_cache *alcl, snsd_service *snsd_delete);
int andna_recv_reg_rq(PACKET rpkt);
int andna_check_counter(PACKET pkt);
int andna_recv_check_counter(PACKET rpkt);
snsd_service *andna_resolve_hash(u_int hname_hash[MAX_IP_INT], int service,
u_char proto, int *records);
snsd_service *andna_resolve_hname(char *hname, int service, u_char proto,
int *records);
int andna_recv_resolve_rq(PACKET rpkt);
lcl_cache *andna_reverse_resolve(inet_prefix ip);
int andna_recv_rev_resolve_rq(PACKET rpkt);
int spread_single_acache(u_int hash[MAX_IP_INT]);
int recv_spread_single_acache(PACKET rpkt);
andna_cache *get_single_andna_c(u_int hash[MAX_IP_INT], u_int hash_gnode[MAX_IP_INT]);
int put_single_acache(PACKET rpkt);
int put_andna_cache(PACKET rq_pkt);
int put_counter_cache(PACKET rq_pkt);
void *andna_hook(void *);
void andna_update_hnames(int only_new_hname);
void *andna_maintain_hnames_active(void *null);
void *andna_main(void *);
#endif /*ANDNA_H*/

2154
src/andna_cache.c Normal file

File diff suppressed because it is too large Load Diff

499
src/andna_cache.h Normal file
View File

@ -0,0 +1,499 @@
/* This file is part of Netsukuku
* (c) Copyright 2005 Andrea Lo Pumo aka AlpT <alpt@freaknet.org>
*
* This source code 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 2 of the License,
* or (at your option) any later version.
*
* This source code 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.
* Please refer to the GNU Public License for more details.
*
* You should have received a copy of the GNU Public License along with
* this source code; if not, write to:
* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef ANDNA_CACHE_H
#define ANDNA_CACHE_H
#include "inet.h"
#include "crypto.h"
#include "endianness.h"
#include "llist.c"
#include "snsd_cache.h"
/*
* ANDNA definitions
*/
#define ANDNA_MAX_BACKUP_GNODES 2
#define ANDNA_MAX_QUEUE 5
#define ANDNA_MAX_HNAME_LEN 512 /* (null terminator included) */
#define ANDNA_MAX_HOSTNAMES 256 /* Max number of hnames per node */
#define ANDNA_MAX_RHC_HNAMES 512 /* Max number of hnames kept in
the resolved_hnames cache* */
#define ANDNA_EXPIRATION_TIME 259200 /* 3 days (in seconds)*/
#define ANDNA_MIN_UPDATE_TIME 3600 /* The minum amount of time to
be waited before sending an
update of the hname. */
#define ANDNA_PRIVKEY_BITS 1024
#define ANDNA_SKEY_MAX_LEN 900
#define ANDNA_PKEY_LEN 140
#define ANDNA_HASH_SZ (MAX_IP_SZ)
#define ANDNA_SIGNATURE_LEN 128
/* Returns the number of nodes to be used in a backup_gnode */
#define ANDNA_BACKUP_NODES(seeds) ({(seeds) > 8 ? \
((seeds)*32)/MAXGROUPNODE : (seeds);})
#ifdef DEBUG
#undef ANDNA_EXPIRATION_TIME
#define ANDNA_EXPIRATION_TIME 100
#undef ANDNA_MIN_UPDATE_TIME
#define ANDNA_MIN_UPDATE_TIME 2
#endif
/*
* * * Cache stuff * * *
*/
/* * andna_cache flags * */
#define ANDNA_BACKUP 1 /* We are a backup_node */
#define ANDNA_COUNTER (1<<1) /* We are a counter_node */
#define ANDNA_ROUNDED (1<<2) /* We are a rounded_hash_node */
#define ANDNA_FULL (1<<3) /* Queue full */
#define ANDNA_UPDATING (1<<4) /* The hname is being updated
right now */
/*
* andna_cache_queue
*
* The queue of the andna_cache. (see below).
*/
struct andna_cache_queue
{
LLIST_HDR (struct andna_cache_queue);
time_t timestamp;
u_short hname_updates; /* numbers of hname's updates */
char pubkey[ANDNA_PKEY_LEN];
u_short snsd_counter; /* # of `snsd' nodes */
snsd_service *service;
};
typedef struct andna_cache_queue andna_cache_queue;
/*
* andna_cache
*
* It keeps the entries of the hostnames registered by other nodes.
*/
struct andna_cache
{
LLIST_HDR (struct andna_cache);
u_int hash[MAX_IP_INT]; /* hostname's hash */
char flags;
u_short queue_counter;
andna_cache_queue *acq; /* The queue of the registration.
The first is the active one */
};
typedef struct andna_cache andna_cache;
/* part of the counter cache, see below */
struct counter_c_hashes
{
LLIST_HDR (struct counter_c_hashes);
time_t timestamp;
u_short hname_updates;
int hash[MAX_IP_INT];
};
typedef struct counter_c_hashes counter_c_hashes;
INT_INFO counter_c_hashes_body_iinfo = { 2,
{ INT_TYPE_32BIT, INT_TYPE_16BIT },
{ 0, sizeof(time_t) },
{ 1, 1 }
};
/*
* counter_c
* Counter node's cache.
*
* All the infos regarding a particular register_node are stored here. For
* example, we need to know how many hostnames he already registered.
*/
struct counter_c
{
LLIST_HDR (struct counter_c);
char pubkey[ANDNA_PKEY_LEN];
char flags;
u_short hashes; /* The number of hashes in cch */
counter_c_hashes *cch; /* The hashes of the hnames */
};
typedef struct counter_c counter_c;
INT_INFO counter_c_body_iinfo = { 1,
{ INT_TYPE_16BIT },
{ ANDNA_PKEY_LEN+sizeof(char) },
{ 1 }
};
/*
* lcl_cache_keyring
*
* The lcl keyring is used to store the RSA keys used to complete some of the
* ANDNA requests, (f.e. registering or updating a hname).
*/
typedef struct
{
u_int skey_len;
u_int pkey_len;
u_char *privkey; /* secret key packed */
u_char *pubkey; /* pubkey packed */
RSA *priv_rsa; /* key pair unpacked */
} lcl_cache_keyring;
/*
* lcl_cache
*
* The Local Andna Cache keeps all the hostnames which have been register by
* localhost (ourself).
*/
struct lcl_cache
{
LLIST_HDR (struct lcl_cache);
char *hostname; /* The registered hostname */
u_int hash; /* 32bit hash of the md5 hash
of the hname */
u_short hname_updates; /* How many updates we've done
for this hostname */
time_t timestamp; /* the last time when the hname
was updated. If it is 0, the
hname has still to be
registered */
u_short snsd_counter; /* # of `snsds' */
snsd_service *service;
char flags;
};
typedef struct lcl_cache lcl_cache;
/*
* resolved_hnames_cache
*
* This cache keeps info on the already resolved hostnames, so we won't have
* to resolve them soon again.
* In order to optimize the search we order the linked list by the time
* of hname resolution. The last hname which has been searched/resolved is
* always moved at the head of the llist, in this way, at the end of the llist
* there is the hname which has been searched for the first time but has been
* ignored until now.
* When the cache is full, the hname which is at the end of the llist is
* removed to empty new space.
* The hname which have the `timestamp' expired are removed too.
*/
struct resolved_hnames_cache
{
LLIST_HDR (struct resolved_hnames_cache);
u_int hash; /* 32bit hash of the md5 hash of the
hname */
char flags;
time_t timestamp; /* the last time when the hname
was updated. With this we know that
at timestamp+ANDNA_EXPIRATION_TIME
this cache will expire. */
u_short snsd_counter;
snsd_service *service;
};
typedef struct resolved_hnames_cache rh_cache;
/*
* * * * Global vars * * *
*/
andna_cache *andna_c;
int andna_c_counter;
counter_c *andna_counter_c;
int cc_counter;
lcl_cache_keyring lcl_keyring;
lcl_cache *andna_lcl;
int lcl_counter;
rh_cache *andna_rhc;
int rhc_counter;
/*
*
* * * * Package stuff * * *
*
*/
/*
* * * * lcl cache package * * *
*/
struct lcl_keyring_pkt_hdr
{
u_int skey_len;
u_int pkey_len;
}_PACKED_;
/*
* the rest of the pkt is:
*
* char privkey[hdr.skey_len];
* char pubkey[hdr.pkey_len];
*/
INT_INFO lcl_keyring_pkt_hdr_iinfo = { 2,
{ INT_TYPE_32BIT, INT_TYPE_32BIT },
{ 0, sizeof(u_int) },
{ 1, 1 }
};
#define LCL_KEYRING_HDR_PACK_SZ(khdr) (sizeof(struct lcl_keyring_pkt_hdr) + \
(khdr)->skey_len + (khdr)->pkey_len)
/*
* The local cache pkt is used to pack the entire local cache to save it in a
* file or to send it to a node.
*/
struct lcl_cache_pkt_hdr
{
u_short tot_caches; /* How many lcl structs there
are in the pkt's body */
}_PACKED_;
INT_INFO lcl_cache_pkt_hdr_iinfo = { 1, { INT_TYPE_16BIT }, { 0 }, { 1 } };
#define LCL_CACHE_HDR_PACK_SZ (sizeof(struct lcl_cache_pkt_hdr))
/*
* The body is:
*
* struct lcl_cache_pkt_body {
* u_short hname_updates;
* time_t timestamp;
* char hostname[strlen(hostname)+1]; * null terminated *
* } body[ hdr.tot_caches ];
*
*/
#define LCL_CACHE_BODY_PACK_SZ(hname_len) ((hname_len) + sizeof(u_short) \
+ sizeof(time_t))
INT_INFO lcl_cache_pkt_body_iinfo = { 2, { INT_TYPE_16BIT, INT_TYPE_32BIT },
{ 0, sizeof(u_short) },
{ 1, 1 }
};
/*
* * * * andna cache package * * *
*/
/*
* the body of the acq_pkt is:
* struct acq_pkt_body {
* time_t timestamp;
* u_short hname_updates;
* char pubkey[ANDNA_PKEY_LEN];
*
* u_short snsd_counter;
* char snsd_service_pack[SNSD_SERVICE_PACK_SZ];
* };
*/
INT_INFO acq_body_iinfo = { 3,
{ INT_TYPE_32BIT, INT_TYPE_16BIT, INT_TYPE_16BIT },
{ 0, sizeof(time_t),
sizeof(time_t) + sizeof(u_short) + ANDNA_PKEY_LEN },
{ 1, 1, 1 }
};
#define ACQ_BODY_PACK_SZ (sizeof(time_t) + sizeof(u_short)*2 + \
ANDNA_PKEY_LEN)
#define ACQ_PACK_SZ(snsd_pack_sz) (ACQ_BODY_PACK_SZ + (snsd_pack_sz))
struct andna_cache_pkt_hdr
{
u_short tot_caches;
}_PACKED_;
INT_INFO andna_cache_pkt_hdr_iinfo = { 1, { INT_TYPE_16BIT }, { 0 }, { 1 } };
/*
* The body is:
* struct andna_cache_pack {
* u_int hash[MAX_IP_INT];
* char flags;
* u_short queue_counter;
* char acq_pack[ACQ_PACK_SZ*queue_counter];
* } acache_pack[hdr.tot_caches];
*/
INT_INFO andna_cache_body_iinfo = { 1,
{ INT_TYPE_16BIT },
{ MAX_IP_SZ+sizeof(char) },
{ 1 }
};
#define ACACHE_BODY_PACK_SZ (ANDNA_HASH_SZ + sizeof(char) + \
sizeof(u_short))
#define ACACHE_PACK_SZ(acq_pack_sz) ((acq_pack_sz) + ACACHE_BODY_PACK_SZ)
/*
* If the acache pack will be sent on a network packet, the `acq->timestamp'
* will be the difference of the current time with the same `acq->timestamp',
* in this way the node which receives the packet will add its current time to
* `acq->timestamp'. This is necessary because the sending and receiving node
* don't have the clock synced. Note that the rtt isn't considered because it
* is generally very small and the ANDNA times don't need an accurate
* precision, f.e. the expiration time is three days long.
* If the pack is saved on a file, then `acq->timestamp' remains the same.
* Problem: if the clock is changed, acq->timestamp will refer to the old
* clock.
*/
#define ACACHE_PACK_FILE 1
#define ACACHE_PACK_PKT 2
/*
* The counter cache pkt is similar to the andna_cache_pkt, it is completely
* arranged in the same way.
*/
struct counter_c_pkt_hdr
{
u_short tot_caches;
}_PACKED_;
INT_INFO counter_c_pkt_hdr_iinfo = { 1, { INT_TYPE_16BIT }, { 0 }, { 1 } };
#define COUNTER_CACHE_HASHES_PACK_SZ (sizeof(time_t) + sizeof(u_short) + \
ANDNA_HASH_SZ)
#define COUNTER_CACHE_BODY_PACK_SZ (ANDNA_PKEY_LEN + sizeof(char) + \
sizeof(u_short))
#define COUNTER_CACHE_PACK_SZ(hashes) ((COUNTER_CACHE_HASHES_PACK_SZ*(hashes))\
+ COUNTER_CACHE_BODY_PACK_SZ)
/*
* * * * Resolved hostnames cache pkt. * * *
*/
struct rh_cache_pkt_hdr
{
u_short tot_caches; /* How many lcl structs there
are in the pkt's hdr */
}_PACKED_;
INT_INFO rh_cache_pkt_hdr_iinfo = { 1, { INT_TYPE_16BIT }, { 0 }, { 1 } };
/*
* The body is:
* struct rh_cache_pkt_body {
* u_int hash;
* char flags;
* time_t timestamp;
*
* u_short snsd_counter;
* char snsd_service_pack[SNSD_SERVICE_PACK_SZ];
* } body[ hdr.tot_caches ];
*/
#define RH_CACHE_BODY_PACK_SZ(snsd_pack_sz) (sizeof(u_int)+sizeof(char)+ \
sizeof(time_t)+sizeof(u_short)+\
(snsd_pack_sz))
INT_INFO rh_cache_pkt_body_iinfo = { 3,
{ INT_TYPE_32BIT, INT_TYPE_32BIT, INT_TYPE_16BIT },
{ 0, sizeof(u_int)+sizeof(char),
sizeof(u_int)+sizeof(char)+sizeof(time_t) },
{ 1, 1, 1 }
};
/*
* * * Functions' declaration * * *
*/
void andna_caches_init(int family);
void lcl_new_keyring(lcl_cache_keyring *keyring);
void lcl_destroy_keyring(lcl_cache_keyring *keyring);
lcl_cache *lcl_cache_new(char *hname);
void lcl_cache_free(lcl_cache *alcl);
void lcl_cache_destroy(lcl_cache *head, int *counter);
lcl_cache *lcl_cache_find_hname(lcl_cache *head, char *hname);
lcl_cache *lcl_cache_find_hash(lcl_cache *alcl, u_int hash);
lcl_cache *lcl_get_registered_hnames(lcl_cache *alcl);
andna_cache_queue *ac_queue_findpubk(andna_cache *ac, char *pubk);
andna_cache_queue *ac_queue_add(andna_cache *ac, char *pubkey);
void ac_queue_del(andna_cache *ac, andna_cache_queue *acq);
void ac_queue_del_expired(andna_cache *ac);
void ac_queue_destroy(andna_cache *ac);
andna_cache *andna_cache_findhash(int hash[MAX_IP_INT]);
andna_cache *andna_cache_gethash(int hash[MAX_IP_INT]);
andna_cache *andna_cache_addhash(int hash[MAX_IP_INT]);
int andna_cache_del_ifexpired(andna_cache *ac);
void andna_cache_del_expired(void);
void andna_cache_destroy(void);
counter_c_hashes *cc_hashes_add(counter_c *cc, int hash[MAX_IP_INT]);
void cc_hashes_del(counter_c *cc, counter_c_hashes *cch);
int counter_c_del_ifexpired(counter_c *cc);
void cc_hashes_del_expired(counter_c *cc);
void cc_hashes_destroy(counter_c *cc);
counter_c_hashes *cc_findhash(counter_c *cc, int hash[MAX_IP_INT]);
counter_c *counter_c_findpubk(char *pubk);
counter_c *counter_c_add(inet_prefix *rip, char *pubkey);
void counter_c_del_expired(void);
void counter_c_destroy(void);
rh_cache *rh_cache_new(char *hname, time_t timestamp);
rh_cache *rh_cache_add_hash(u_int hash, time_t timestamp);
rh_cache *rh_cache_add(char *hname, time_t timestamp);
rh_cache *rh_cache_find_hash(u_int hash);
rh_cache *rh_cache_find_hname(char *hname);
void rh_cache_del(rh_cache *rhc);
void rh_cache_del_expired(void);
void rh_cache_flush(void);
char *pack_lcl_keyring(lcl_cache_keyring *keyring, size_t *pack_sz);
int unpack_lcl_keyring(lcl_cache_keyring *keyring, char *pack, size_t pack_sz);
char *pack_lcl_cache(lcl_cache *local_cache, size_t *pack_sz);
lcl_cache *unpack_lcl_cache(char *pack, size_t pack_sz, int *counter);
char *pack_andna_cache(andna_cache *acache, size_t *pack_sz, int pack_type);
andna_cache *unpack_andna_cache(char *pack, size_t pack_sz, int *counter,
int pack_type);
char *pack_counter_cache(counter_c *countercache, size_t *pack_sz);
counter_c *unpack_counter_cache(char *pack, size_t pack_sz, int *counter);
char *pack_rh_cache(rh_cache *rhcache, size_t *pack_sz);
rh_cache *unpack_rh_cache(char *pack, size_t pack_sz, int *counter);
int save_lcl_keyring(lcl_cache_keyring *keyring, char *file);
int load_lcl_keyring(lcl_cache_keyring *keyring, char *file);
int save_lcl_cache(lcl_cache *lcl, char *file);
lcl_cache *load_lcl_cache(char *file, int *counter);
int save_andna_cache(andna_cache *acache, char *file);
andna_cache *load_andna_cache(char *file, int *counter);
int save_counter_c(counter_c *countercache, char *file);
counter_c *load_counter_c(char *file, int *counter);
int save_rh_cache(rh_cache *rh, char *file);
rh_cache *load_rh_cache(char *file, int *counter);
int load_hostnames(char *file, lcl_cache **old_alcl_head, int *old_alcl_counter);
int load_snsd(char *file, lcl_cache *alcl_head);
int add_resolv_conf(char *hname, char *file);
int del_resolv_conf(char *hname, char *file);
#endif /*ANDNA_CACHE_H*/

959
src/andns.c Normal file
View File

@ -0,0 +1,959 @@
/**************************************
* AUTHOR: Federico Tomassini *
* Copyright (C) Federico Tomassini *
* Contact effetom@gmail.com *
***********************************************
******* BEGIN 3/2006 ********
*************************************************************************
* *
* 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 2 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. *
* *
************************************************************************/
#define _GNU_SOURCE
#include <string.h>
#include <netdb.h>
#include "includes.h"
#include "common.h"
#include "andns.h"
#include "err_errno.h"
#include "andna.h"
#include "andns_lib.h"
#include "andns_net.h"
#include "andns_snsd.h"
#include "dnslib.h"
static uint8_t _dns_forwarding_;
static uint8_t _andns_ns_count_;
static uint8_t _default_realm_;
static struct addrinfo _ns_filter_;
static struct addrinfo *_andns_ns_[MAXNSSERVERS];
static int _ip_len_;
/* Debugging Functions to isolate andns from andna
snsd_service* debug_andna_resolve_hname(char *s,int service,u_char proto,int *records)
{
char *ciccio="111.222.123.123";
debug(DBG_NORMAL,"Entering debug_andna_resolve.");
snsd_service *ss;
snsd_prio *sp;
snsd_node *sn;
ss=xmalloc(sizeof(snsd_service));
ss->prio=xmalloc(sizeof(snsd_prio));
sp=ss->prio;
sp->node=xmalloc(sizeof(snsd_node));
sn=sp->node;
inet_pton(AF_INET,ciccio,sn->record);
sn->flags|=SNSD_NODE_MAIN_IP;
sn->flags|=SNSD_NODE_IP;
ss->next=0;
ss->prev=0;
sp->next=0;
sp->prev=0;
sn->next=0;
sn->prev=0;
*records=1;
return ss;
}
lcl_cache* debug_andna_reverse_resolve(inet_prefix addr)
{
lcl_cache *lc;
debug(DBG_NORMAL,"Entering debug_andna_reverse.");
lc=xmalloc(sizeof(lcl_cache));
memset(lc,0,sizeof(lcl_cache));
lc->hostname=xmalloc(12);
strcpy(lc->hostname,"Ciao mamma");
return lc;
}*/
/* INIT FUNCTIONS */
/*
* Saves on `nsbuf' and `ns_count' the ip
* address ns: these infos will be used for DNS
* forwarding.
*
* Returns:
* -1 on error
* 0 if OK
*/
int store_ns(char *ns)
{
int res;
struct addrinfo **ai;
if (strstr(ns, "127.0.0.")) /* TODO: make it proto independent */
return -1;
ai=&_andns_ns_[_andns_ns_count_];
res=getaddrinfo(ns, DNS_PORT_STR, &_ns_filter_, ai);
if (res) {
debug(DBG_NORMAL,"In store_ns(): gai `%s' -> %s",ns,gai_strerror(errno));
return -1;
}
_andns_ns_count_++;
return 0;
}
/*
* Reads resolv.conf, searching nameserver lines.
* Takes the ip address from these lines and calls store_ns.
* "nameserver 127.0.0.1" is discarded to remove looping behaviors.
* The number of stored nameservers is written in
* `*ns_count' and it is returned.
* If an error occurred or no hostnames are available, -1 is returned.
*/
int collect_resolv_conf(char *resolve_conf)
{
FILE *erc;
char buf[512],*crow;
if (!(erc=fopen(resolve_conf,"r"))) {
error("In collect_resolv_conf: "
"error -> %s.", strerror(errno));
err_ret(ERR_RSLERC,-1);
}
while ((crow=fgets(buf,512,erc)) && _andns_ns_count_<MAXNSSERVERS) {
if (!(crow=strstr(buf,"nameserver "))) /* is a good line? */
continue;
/* Skip if the line is commented */
*crow=0;
if(strchr(buf, '#'))
continue;
crow+=11;
/* remove unwanted chars */
strip_char(crow, '\t');
strip_char(crow, ' ');
strip_char(crow, '\n');
store_ns(crow); /* finally store nameserver */
}
if (fclose(erc)!=0) {
error("In collect_resolv_conf: closing "
"resolv.conf -> %s",strerror(errno));
err_ret(ERR_RSLERC,-1);
}
if (!_andns_ns_count_)
err_ret(ERR_RSLNNS,-1);
return _andns_ns_count_;
}
void reset_andns_ns(void)
{
int i;
for(i=0; i<_andns_ns_count_; i++)
if(_andns_ns_[i])
freeaddrinfo(_andns_ns_[i]);
_andns_ns_count_=0;
setzero(_andns_ns_, sizeof(struct addrinfo *)*MAXNSSERVERS);
}
/*
* This function must be called before all.
* Sets the default realm for domain name resolution
* and stores infos about nameservers for dns query.
* On error -1 is returned.
*/
int andns_init(int restricted, char *resolv_conf,int family)
{
int i,res;
char msg[(INET6_ADDRSTRLEN+2)*MAXNSSERVERS];
char buf[INET6_ADDRSTRLEN];
struct addrinfo *ai;
memset(&_ns_filter_,0,sizeof(struct addrinfo));
_ns_filter_.ai_socktype=SOCK_DGRAM;
_ip_len_=family==AF_INET?4:16;
_default_realm_=(restricted)?INET_REALM:NTK_REALM;
_andns_ns_count_=0;
setzero(_andns_ns_, sizeof(struct addrinfo *)*MAXNSSERVERS);
memset(msg,0,(INET_ADDRSTRLEN+2)*MAXNSSERVERS);
if(_default_realm_ == NTK_REALM) {
/* We are in NTK realm, every IP is assigned to Netsukuku,
* therefore dns forwarding is meaningless */
_dns_forwarding_=0;
return 0;
}
res=collect_resolv_conf(resolv_conf);
if (res <=0) {
_dns_forwarding_=0;
debug(DBG_NORMAL,err_str);
err_ret(ERR_RSLAIE,-1);
}
/*
* Debug message
*/
for (i=0;i<_andns_ns_count_;i++) {
ai=_andns_ns_[i];
res=idp_inet_ntop(ai->ai_family,ai->ai_addr,buf,
INET6_ADDRSTRLEN);
if (!res) {
strncat(msg,buf,INET_ADDRSTRLEN);
strncat(msg,i==_andns_ns_count_-1?". ":", ",2);
} else
error("In andns_init: error "
"converting sockaddr -> %s.",\
strerror(errno));
}
loginfo("Inet DNS queries will be forwarded to: %s",msg);
_dns_forwarding_=1;
return 0;
}
void andns_close(void)
{
reset_andns_ns();
}
/* NET FUNCTIONS */
int ns_general_send(char *msg,int msglen,char *answer,int anslen)
{
int res,i;
for (i=0; i<_andns_ns_count_;i++) {
res=ai_send_recv_close(_andns_ns_[i],msg,msglen,
answer,anslen,0,0,ANDNS_TIMEOUT);
if(res != -1) {
return res;
}
}
err_ret(ERR_RSLFDQ,-1);
}
/* UTILS FUNCTIONS */
/*
* Make a copy of DNS pkt data. If prefix is not NULL,
* the prefix is added to strings.
*/
void dpktacpy(dns_pkt *dst,dns_pkt *src,const char *prefix)
{
dns_pkt_a *dpas,*dpad;
int slen;
int yet_pref=0;
char temp[257];
dpas=src->pkt_answ;
while(dpas) {
dpad=DP_ADD_ANSWER(dst);
memcpy(dpad,dpas,sizeof(dns_pkt_a));
dpad->next=NULL;
if (prefix && !yet_pref) { /* TODO: yet_pref better */
slen=strlen(dpad->name);
if (dpas->type!=T_PTR)
memcpy(dpad->name+slen,prefix,REALM_PREFIX_LEN);
else {
strcpy(temp,dpad->name);
memcpy(dpad->name,prefix+1,REALM_PREFIX_LEN-1);
dpad->name[REALM_PREFIX_LEN-1]='.';
strcpy(dpad->name+REALM_PREFIX_LEN,temp);
}
*(dpad->name+slen+REALM_PREFIX_LEN)=0;
yet_pref=1;
}
dpas=dpas->next;
}
dpas=src->pkt_auth;
while(dpas) {
dpad=DP_ADD_AUTH(dst);
memcpy(dpad,dpas,sizeof(dns_pkt_a));
dpad->next=NULL;
dpas=dpas->next;
}
dpas=src->pkt_add;
while(dpas) {
dpad=DP_ADD_ADD(dst);
memcpy(dpad,dpas,sizeof(dns_pkt_a));
dpad->next=NULL;
dpas=dpas->next;
}
}
/*
* Make a full copy of a dns pkt. If prefix is not
* null, prefix is added to names.
*/
dns_pkt* dpktcpy(dns_pkt *src,const char *prefix)
{
dns_pkt *dst;
dns_pkt_qst *dpq,*dpq_src;
dst=create_dns_pkt();
memcpy(dst,src,sizeof(dns_pkt));
dst->pkt_qst=NULL;
dst->pkt_answ=NULL;
dst->pkt_auth=NULL;
dst->pkt_add=NULL;
dpq_src=src->pkt_qst;
while (dpq_src) {
dpq=dns_add_qst(dst);
memcpy(dpq,dpq_src,sizeof(dns_pkt_qst));
dpq->next=NULL;
dpq_src=dpq_src->next;
}
dpktacpy(dst,src,prefix);
return dst;
}
/*
* Remove the suffix realm, if any.
* Writes the result on dst.
*/
char* rm_realm_prefix(char *from,char *dst,int type)
{
int slen;
slen=strlen(from);
if (slen<5)
strcpy(dst,from);
else if (type==T_PTR) {
if (strcasestr(from,PTR_INET_REALM_PREFIX)==from ||
strcasestr(from,PTR_NTK_REALM_PREFIX)==from)
strcpy(dst,from+REALM_PREFIX_LEN);
else
strcpy(dst,from);
} else if (strcasestr(from+slen-REALM_PREFIX_LEN,INET_REALM_PREFIX) ||
strcasestr(from+slen-REALM_PREFIX_LEN,NTK_REALM_PREFIX)) {
strncpy(dst,from,slen-REALM_PREFIX_LEN);
dst[slen-REALM_PREFIX_LEN]=0;
} else
strcpy(dst,from);
return dst;
}
/* Make a copy of a dns pkt, only for headers and questions.
* If the question is prefixed, the prefix is removed.
*/
dns_pkt* dpktcpy_rm_pref(dns_pkt *src)
{
dns_pkt *dst;
dns_pkt_qst *dpq;
// char temp[DNS_MAX_HNAME_LEN];
dst=dpktcpy(src,NULL);
dpq=dst->pkt_qst;
rm_realm_prefix(src->pkt_qst->qname,dpq->qname,dpq->qtype);
// strcpy(dpq->qname,temp);
return dst;
}
int andns_realm(dns_pkt_qst *dpq,int *prefixed)
{
int slen;
char *qst;
qst=dpq->qname;
if (!qst)
err_ret(ERR_UFOERR,-1);
slen=strlen(qst);
/* if qst is tto short, it's impossible to
consider a prefix. */
if (slen<5) return _default_realm_;
if (dpq->qtype==T_PTR) {
if (strcasestr(qst,PTR_INET_REALM_PREFIX)==qst) {
if (prefixed) *prefixed=1;
return INET_REALM;
}
if (strcasestr(qst,PTR_NTK_REALM_PREFIX)==qst) {
if (prefixed) *prefixed=1;
return NTK_REALM;
}
if (prefixed) *prefixed=0;
return _default_realm_;
}
if (strcasestr(qst+slen-REALM_PREFIX_LEN,INET_REALM_PREFIX)) {
if (prefixed) *prefixed=1;
return INET_REALM;
}
if (strcasestr(qst+slen-REALM_PREFIX_LEN,NTK_REALM_PREFIX)) {
if (prefixed) *prefixed=1;
return NTK_REALM;
}
if (prefixed) *prefixed=0;
return _default_realm_;
}
/*
* Returns:
* 0 if the question does not have a suffix
* 1 if the question has suffix
*/
int is_prefixed(dns_pkt *dp)
{
int prefix=0;
andns_realm(dp->pkt_qst,&prefix);
return prefix;
}
/*
* A very stupid function that converts
* ANDNS code to DNS code.
*/
int qtype_a_to_d(andns_pkt *ap)
{
switch (ap->qtype) {
case AT_PTR:
return T_PTR;
case AT_A:
if (ap->service==25)
return T_MX;
else if (!ap->service)
return T_A;
else
return -1;
default:
return -1;
}
}
int apqsttodpqst(andns_pkt *ap,dns_pkt **dpsrc)
{
dns_pkt *dp;
dns_pkt_hdr *dph;
dns_pkt_qst *dpq;
int res,qt;
int qlen,family;
qt=qtype_a_to_d(ap);
if (qt==-1)
err_ret(ERR_ANDNCQ,-1);
*dpsrc=create_dns_pkt();
dp=*dpsrc;
dph=&(dp->pkt_hdr);
dpq=dns_add_qst(dp);
if (qt==T_A || qt==T_MX) {
qlen=strlen(ap->qstdata);
if (qlen>DNS_MAX_HNAME_LEN)
goto incomp_err;
strcpy(dpq->qname,ap->qstdata);
}
else if (qt==T_PTR) {
char temp[DNS_MAX_HNAME_LEN];
qlen=ap->qstlength;
if (qlen==4)
family=AF_INET;
else if (qlen==16)
family=AF_INET6;
else
goto incomp_err;
if (!inet_ntop(family,ap->qstdata,temp,
DNS_MAX_HNAME_LEN)) {
debug(DBG_INSANE,err_str);
goto incomp_err;
}
res=swapped_straddr_pref(temp,
dpq->qname,family);
if (res==-1) {
debug(DBG_INSANE,err_str);
goto incomp_err;
}
}
else
goto incomp_err;
dph->id=ap->id;
dph->rd=1;
dph->qdcount++;
dpq->qtype=qt;
dpq->qclass=C_IN;
return 0;
incomp_err:
destroy_dns_pkt(dp);
err_ret(ERR_ANDNCQ,-1);
}
int dpanswtoapansw(dns_pkt *dp,andns_pkt *ap)
{
int i,rcode,qt,ancount,nan=0;
dns_pkt_a *dpa;
andns_pkt_data *apd;
ancount=DNS_GET_ANCOUNT(dp);
rcode=DNS_GET_RCODE(dp);
ap->rcode=rcode;
ap->qr=1;
if (rcode!=DNS_RCODE_NOERR)
return 0;
qt=dp->pkt_qst->qtype;
dpa=dp->pkt_answ;
for (i=0;i<ancount;i++) {
if (!dpa)
break;
apd=andns_add_answ(ap);
if (qt==T_A) {
apd->rdlength=_ip_len_;
APD_ALIGN(apd);
memcpy(apd->rdata,dpa->rdata,_ip_len_);
nan++;
}
else if (qt==T_PTR ) {
apd->rdlength=strlen(dpa->rdata);
APD_ALIGN(apd);
strcpy(apd->rdata,dpa->rdata);
nan++;
}
else if (qt==T_MX) {
struct hostent *h;
uint16_t prio;
h=gethostbyname(dpa->rdata+2);
if (!h || !(h->h_length)) {
andns_del_answ(ap);
debug(DBG_INSANE,"MX Ip Record not found.");
continue;
}
apd->rdlength=h->h_addrtype==AF_INET?4:16;
APD_ALIGN(apd);
memcpy(apd->rdata,h->h_addr_list[0],apd->rdlength);
memcpy(&prio,dpa->rdata,sizeof(uint16_t));
apd->prio=prio>>8;
// (uint8_t)(ntohs((uint16_t)(*(dpa->rdata))));
// memcpy(&(apd->prio),dpa->rdata,sizeof(uint16_t));
nan++;
}
else
andns_del_answ(ap);
dpa=dpa->next;
}
if (i!=ancount || nan!=ancount)
debug(DBG_INSANE,"In dpanswtoapansw: "
"ancount=%d, andns answers=%d",\
DNS_GET_ANCOUNT(dp),i);
ap->ancount=nan;
return 0;
}
/* FINALLY RESOLVING FUNCTIONS */
/*
* His goal is trivial.
* DO NOT USE suffixes query, i.e. query with ".INT" or ".NTK".
* NXDOMAIN otherwise.
*
* Returns:
* -1 on error
* 0 if OK
*/
int andns_gethostbyname(char *hname, inet_prefix *ip)
{
dns_pkt *dp;
dns_pkt_hdr *dph;
dns_pkt_qst *dpq;
int res;
char msg[DNS_MAX_SZ],answ[DNS_MAX_SZ];
uint32_t addr;
dp=create_dns_pkt();
dph=&(dp->pkt_hdr);
dph->id=(rand() >> 16) ^ (rand() >> 16);
dph->rd=1;
dpq=dns_add_qst(dp);
rm_realm_prefix(hname,dpq->qname,T_A);
dpq->qtype=T_A;
dpq->qclass=C_IN;
DP_QDCOUNT(dp)++;
memset(msg,0,DNS_MAX_SZ);
memset(answ,0,DNS_MAX_SZ);
if ((res=d_p(dp,msg))==-1) {
error(err_str);
err_ret(ERR_RSLRSL,-1);
}
if ((res=ns_general_send(msg,res,answ,DNS_MAX_SZ))==-1) {
error(err_str);
err_ret(ERR_RSLRSL,-1);
}
if ((res=d_u(answ,res,&dp))==-1) {
error(err_str);
err_ret(ERR_RSLRSL,-1);
}
memcpy(&addr, dp->pkt_answ->rdata, sizeof(uint32_t));
addr=ntohl(addr);
if ((res=inet_setip_raw(ip,&addr, AF_INET))==-1) {
error("In andns_gethostbyname: can not fill inet_prefix.");
err_ret(ERR_RSLRSL,-1);
}
destroy_dns_pkt(dp);
return 0;
}
/* There is a DNS query, internet realm.
* I'm going to forward it, but first I have
* to control suffix presence.
*
* After this function, `answer` is the answer to be
* sent to the client.
*
* Returns:
* answer len
*/
int dns_forward(dns_pkt *dp,char *msg,int msglen,char* answer)
{
dns_pkt *dp_forward;
char fwdbuf[DNS_MAX_SZ];
int res;
if (!_dns_forwarding_) {
error("In rslv: dns forwardind is disable.");
goto safe_failing;
}
debug(DBG_INSANE, "Forwarding dns query to inet nameservers...");
if (!is_prefixed(dp)) {
if((res=ns_general_send(msg,msglen,answer,ANDNS_MAX_SZ))==-1) {
error(err_str);
goto safe_failing;
}
destroy_dns_pkt(dp);
return res;
}
/* prepare to re-format query without prefix */
dp_forward=dpktcpy_rm_pref(dp);
memset(fwdbuf,0,DNS_MAX_SZ);
if ((res=d_p(dp_forward,fwdbuf))==-1) { /* dp_foward is destroyed */
error(err_str);
goto safe_failing;
}
res=ns_general_send(fwdbuf,res,answer,ANDNS_MAX_SZ);
if (res==-1) {
error(err_str);
goto safe_failing;
}
res=d_u(answer,res,&dp_forward);
if (res<=0) {
error(err_str);
goto safe_failing;
}
dpktacpy(dp,dp_forward,INET_REALM_PREFIX);
destroy_dns_pkt(dp_forward);
DNS_SET_NSCOUNT(dp,0);
DNS_SET_ARCOUNT(dp,0);
if ((res=d_p(dp,answer))==-1) {
error(err_str);
goto failing;
}
return res;
safe_failing:
destroy_dns_pkt(dp);
goto failing;
failing:
memcpy(answer,msg,msglen);
ANDNS_SET_RCODE(answer,RCODE_ESRVFAIL);
ANDNS_SET_QR(answer);
res=msglen;
err_ret(ERR_RSLFDQ,res);
}
/* There is a DNS query, netsukuku realm.
*
* I'm going to resolve it in ANDNA.
*
* After this function, `answer` is the answer to be
* sent to the client.
*
* Returns:
* answer len
*/
int inet_rslv(dns_pkt *dp,char *msg,int msglen,char *answer)
{
inet_prefix addr;
int res,qt,rcode;
u_short service;
snsd_service *ss;
snsd_prio *sp;
int records;
u_char proto;
char temp[DNS_MAX_HNAME_LEN];
qt=dp->pkt_qst->qtype;
rm_realm_prefix(dp->pkt_qst->qname,temp,qt);
if (qt==T_A || qt==T_MX) { /* snsd tcp resolution service */
service= (qt==T_A)?0:25;
proto = (qt!=T_A);
//ss=andna_resolve_hname(temp,service,proto,&records);
ss=andna_resolve_hname(temp,service,proto,&records);
if (!ss) {
rcode=RCODE_ENSDMN;
goto safe_return_rcode;
}
sp=ss->prio;
snsd_prio_to_dansws(dp,sp,_ip_len_);
snsd_service_llist_del(&ss);
} else if (qt==T_PTR) {
char tomp[DNS_MAX_HNAME_LEN];
lcl_cache *lc;
res=swapped_straddr(temp,tomp);
if (res==-1) {
rcode=RCODE_EINTRPRT;
goto safe_return_rcode;
}
res=str_to_inet(tomp,&addr);
if (res==-1) {
rcode=RCODE_ESRVFAIL;
goto safe_return_rcode;
}
lc=andna_reverse_resolve(addr);
res=lcl_cache_to_dansws(dp,lc); /* destroy lc */
if (!res) {
rcode=RCODE_ENSDMN;
goto safe_return_rcode;
}
} else {
rcode=RCODE_ENIMPL;
goto safe_return_rcode;
}
DNS_SET_QR(dp,1);
res=d_p(dp,answer);
if (res==-1) {
rcode=RCODE_ESRVFAIL;
goto return_rcode;
}
return res;
safe_return_rcode:
destroy_dns_pkt(dp);
goto return_rcode;
return_rcode:
memcpy(answer,msg,msglen);
ANDNS_SET_RCODE(answer,rcode);
ANDNS_SET_QR(answer);
return msglen;
}
int nk_rslv(andns_pkt *ap,char *msg,int msglen,char *answer)
{
int qt,res,rcode,records;
inet_prefix ipres;
uint8_t recs;
uint16_t s;
qt=ap->qtype;
if (qt==AT_A) {
snsd_service *ss;
ss=andna_resolve_hash((u_int *)ap->qstdata,
ap->service,ap->p+1,&records);
//ss=andna_resolve_hname(ap->qstdata, //USE HASH!
// ap->service,ap->p,&records);
if (!ss) {
rcode=RCODE_ENSDMN;
goto safe_return_rcode;
}
res=snsd_prio_to_aansws(answer+msglen,
ss->prio,_ip_len_,ap->r,&records);
if (!records) {
rcode=RCODE_ENSDMN;
goto safe_return_rcode;
}
snsd_service_llist_del(&ss);
}
else if (qt==AT_PTR) {
lcl_cache *lc;
int family;
family=ap->qstlength==4?AF_INET:AF_INET6;
res=inet_setip_raw(&ipres,(u_int*)ap->qstdata,family);
if (res==-1) {
rcode=RCODE_EINTRPRT;
goto safe_return_rcode;
}
inet_ntohl(ipres.data,family);
lc=andna_reverse_resolve(ipres);
//lc=andna_reverse_resolve(ipres);
if (!lc) {
rcode=RCODE_ENSDMN;
goto safe_return_rcode;
}
res=lcl_cache_to_aansws(answer+msglen,lc,&records); /* destroys lc */
}
else if (qt==AT_G) {
snsd_service *ss;
ss=andna_resolve_hash((u_int *)ap->qstdata,
-1,0,&records);
if (!ss) {
rcode=RCODE_ENSDMN;
goto safe_return_rcode;
}
res=snsd_service_to_aansws(answer+msglen+2,ss,
_ip_len_,&records,ap->r);
if (!res) {
rcode=RCODE_ENSDMN;
goto safe_return_rcode;
}
if (!records) {
rcode=RCODE_ESRVFAIL;
goto safe_return_rcode;
}
snsd_service_llist_del(&ss);
} else {
rcode=RCODE_EINTRPRT;
goto safe_return_rcode;
}
memcpy(answer,msg,msglen);
ANDNS_SET_RCODE(answer,RCODE_NOERR);
ANDNS_SET_QR(answer);
recs=records;
if (qt==AT_G) {
ANDNS_SET_ANCOUNT(answer,1);
s=htons(recs);
memcpy(answer+msglen,&s,2);
res+=2;
}
else
ANDNS_SET_ANCOUNT(answer,recs);
return res+msglen;
safe_return_rcode:
destroy_andns_pkt(ap);
/* goto return_rcode;
return_rcode:*/
memcpy(answer,msg,msglen);
ANDNS_SET_RCODE(answer,rcode);
ANDNS_SET_QR(answer);
return msglen;
}
int nk_forward(andns_pkt *ap,char *msg,int msglen,char *answer)
{
int res,rcode;
dns_pkt *dp;
char new_answ[DNS_MAX_SZ];
res=apqsttodpqst(ap,&dp);
if (res==-1) {
rcode=RCODE_EINTRPRT;
goto safe_return_rcode;
}
res=d_p(dp,answer);
if (res==-1) {
rcode=RCODE_ESRVFAIL;
goto safe_return_rcode;
}
res=ns_general_send(answer,res,new_answ,DNS_MAX_SZ);
if (res==-1) {
rcode=RCODE_ESRVFAIL;
goto safe_return_rcode;
}
res=d_u(new_answ,res,&dp);
if (res==-1) {
rcode=RCODE_ESRVFAIL;
goto safe_return_rcode;
}
res=dpanswtoapansw(dp,ap);
if (res==-1) {
rcode=RCODE_ESRVFAIL;
destroy_dns_pkt(dp);
goto safe_return_rcode;
}
destroy_dns_pkt(dp);
res=a_p(ap,answer);
if (res==-1) {
rcode=RCODE_ESRVFAIL;
goto safe_return_rcode;
}
return res;
safe_return_rcode:
debug(DBG_INSANE,err_str);
destroy_andns_pkt(ap);
memcpy(answer,msg,msglen);
ANDNS_SET_QR(answer);
ANDNS_SET_RCODE(answer,rcode);
return msglen;
}
/*
* This is the main function for the resolution: the dns_wrapper receive the
* buffer and rslv builds the answer.
* `answer' is the buffer where the answer will be stored, it must be at
* least of `ANDNS_MAX_SZ' bytes.
*
* Returns:
* NULL if the pkt has to be discarded.
* A ptr to the answer to be sended if OK:
* in this case, answ_len is filled with
* the answer len.
*/
char *andns_rslv(char *msg, int msglen,char *answer, int *answ_len)
{
int proto,res,r;
dns_pkt *dp;
andns_pkt *ap;
proto=GET_NK_BIT(msg);
if (proto==NK_DNS)
res=d_u(msg,msglen,&dp);
else if (proto==NK_INET || proto==NK_NTK)
res=a_u(msg,msglen,&ap);
else {
debug(DBG_INSANE,"andns_rslv(): "
"Which language are you speaking?");
return NULL;
}
if (res==0)
goto discard;
memset(answer, 0, ANDNS_MAX_SZ);
if (res==-1)
goto intrprt;
if (proto==NK_DNS) {
r=andns_realm(dp->pkt_qst,NULL);
if (r==INET_REALM)
res=dns_forward(dp,msg,msglen,answer);
else
res=inet_rslv(dp,msg,msglen,answer);
}
else if (proto==NK_NTK)
res=nk_rslv(ap,msg,msglen,answer);
else if (proto==NK_INET)
res=nk_forward(ap,msg,msglen,answer);
*answ_len=res;
return answer;
discard:
debug(DBG_INSANE,err_str);
err_ret(ERR_RSLAQD,NULL);
intrprt:
debug(DBG_INSANE,err_str);
memcpy(answer,msg,msglen);
ANDNS_SET_RCODE(answer,1);
//ANDNS_SET_RCODE(answer,RCODE_EINTRPRT);
ANDNS_SET_QR(answer);
*answ_len=msglen;
return answer;
}

86
src/andns.h Normal file
View File

@ -0,0 +1,86 @@
/**************************************
* AUTHOR: Federico Tomassini *
* Copyright (C) Federico Tomassini *
* Contact effetom@gmail.com *
***********************************************
******* BEGIN 3/2006 ********
*************************************************************************
* *
* 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 2 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. *
* *
************************************************************************/
#ifndef ANDNS_H
#define ANDNS_H
#include <stdio.h>
#include <sys/socket.h>
#include <netdb.h>
#include "dnslib.h"
#include "andns_lib.h"
#include "inet.h"
#define ANDNS_TIMEOUT 15
#define MAXNSSERVERS 3
#define DNS_REPLY_TIMEOUT 10 /* seconds */
#define DNS_PORT 53
#define DNS_PORT_STR "53"
/* PREFIX TO QUERY THE INET REALM */
#define INET_REALM_PREFIX ".INT"
#define NTK_REALM_PREFIX ".NTK"
#define PTR_INET_REALM_PREFIX "INT."
#define PTR_NTK_REALM_PREFIX "NTK."
#define REALM_PREFIX_LEN 4
#define DNS_PROTO 0
#define ANDNS_PROTO 1
#define NK_DNS 0
#define NK_NTK 1
#define NK_INET 2
#define GET_NK_BIT(msg) (*((msg+3))>>4)&0x03
#define RCODE_NOERR 0
#define RCODE_EINTRPRT 1
#define RCODE_ESRVFAIL 2
#define RCODE_ENSDMN 3
#define RCODE_ENIMPL 4
#define RCODE_ERFSD 5
/* FUNCTIONS */
int store_ns(char *ns);
int collect_resolv_conf(char *resolve_conf);
void reset_andns_ns(void);
int andns_init(int restricted, char *resolv_conf,int family);
void andns_close(void);
int ns_general_send(char *msg,int msglen,char *answer,int anslen);
void dpktacpy(dns_pkt *dst,dns_pkt *src,const char *prefix);
dns_pkt* dpktcpy(dns_pkt *src,const char *prefix);
char* rm_realm_prefix(char *from,char *dst,int type);
dns_pkt* dpktcpy_rm_pref(dns_pkt *src);
int andns_gethostbyname(char *hname, inet_prefix *ip);
int andns_realm(dns_pkt_qst *dpq,int *prefixed);
int is_prefixed(dns_pkt *dp);
int dns_forward(dns_pkt *dp,char *msg,int msglen,char* answer);
int inet_rslv(dns_pkt *dp,char *msg,int msglen,char *answer);
int nk_rslv(andns_pkt *ap,char *msg,int msglen,char *answer);
int qtype_a_to_d(andns_pkt *ap);
int apqsttodpqst(andns_pkt *ap,dns_pkt **dpsrc);
int dpanswtoapansw(dns_pkt *dp,andns_pkt *ap);
int nk_forward(andns_pkt *ap,char *msg,int msglen,char *answer);
char *andns_rslv(char *msg, int msglen,char *answer, int *answ_len);
#endif /* ANDNS_H */

610
src/andns_lib.c Normal file
View File

@ -0,0 +1,610 @@
/**************************************
* AUTHOR: Federico Tomassini *
* Copyright (C) Federico Tomassini *
* Contact effetom@gmail.com *
***********************************************
******* BEGIN 3/2006 ********
*************************************************************************
* *
* 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 2 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. *
* *
************************************************************************/
#include "andns_lib.h"
#include "andns_net.h"
#include "log.h"
#include "err_errno.h"
#include "xmalloc.h"
#include <arpa/inet.h>
#include <zlib.h>
int andns_compress(char *src,int srclen)
{
int res;
uLongf space;
src+=ANDNS_HDR_SZ;
srclen-=ANDNS_HDR_SZ;
space=compressBound(srclen);
unsigned char dst[space+ANDNS_HDR_Z];
/* The first four bytes will store
* the uncompressed size */
res=compress2(dst+ANDNS_HDR_Z, &space,(u_char *) src, srclen,
ANDNS_COMPR_LEVEL);
if (res!=Z_OK)
err_ret(ERR_ZLIBCP,-1);
if (space >= srclen-ANDNS_HDR_Z) /* We have to consider the four
bytes too */
err_ret(ERR_ZLIBNU,-1); /* This is a
silent return */
res=htonl(srclen);
memcpy(dst,&res,ANDNS_HDR_Z);
memcpy(src, dst, space);
return (int)space;
}
char* andns_uncompress(char *src,int srclen,int *dstlen)
{
unsigned char *dst;
uLongf space;
int res;
int c_len;
const int hdrsz=ANDNS_HDR_SZ+ANDNS_HDR_Z;
memcpy(&c_len,src+ANDNS_HDR_SZ,ANDNS_HDR_Z);
c_len=ntohl(c_len);
dst=xmalloc(c_len+ANDNS_HDR_SZ);
space=c_len;
res=uncompress(dst+ANDNS_HDR_SZ,&space,(u_char*) src+hdrsz, srclen-hdrsz);
if (res!=Z_OK) {
xfree(dst);
err_ret(ERR_ZLIBUP,NULL);
}
if ((int)space!=c_len) {
xfree(dst);
err_ret(ERR_ANDMAP,NULL);
}
memcpy(dst, src, ANDNS_HDR_SZ);
*dstlen=c_len+ANDNS_HDR_SZ;
return (char*)dst;
}
/*
* Takes the buffer stream and translate headers to
* andns_pkt struct.
* Returns ALWAYS 4. The pkt_len has to be controlled
* elsewhere.
*/
int a_hdr_u(char *buf,andns_pkt *ap)
{
uint8_t c;
uint16_t s;
char *start_buf;
start_buf=buf;
ap->r=*(buf+1)&0x01;
memcpy(&s,buf,2);
ap->id=ntohs(s);
ap->id>>=1;
buf+=2;
memcpy(&c,buf,2);
ap->qr=(c>>7)&0x01;
ap->p=c&0x40?ANDNS_PROTO_UDP:ANDNS_PROTO_TCP;
ap->z=c&0x20;
ap->qtype=(c>>3)&0x03;
ap->ancount=(c<<1)&0x0e;
buf++;
memcpy(&c,buf,sizeof(uint8_t));
if (((*buf)&0x80)) ap->ancount++;
ap->ipv=(c>>6)&0x01;
ap->nk=(c>>4)&0x03;
ap->rcode=c&0x0f;
return ANDNS_HDR_SZ;
}
/*
* Translate the andns_pkt question stream to andns_pkt struct.
* -1 on error. Bytes readed otherwise.
* NOTE: The qst-data size is controlled: apkt won't need
* this control.
*/
int a_qst_u(char *buf,andns_pkt *ap,int limitlen)
{
int ret;
uint16_t s;
if (limitlen<3)
err_ret(ERR_ANDMAP,-1);
switch(ap->qtype) {
case AT_A:
memcpy(&s,buf,2);
ap->service=ntohs(s);
buf+=2;
if (ap->nk==NTK_REALM) {
ap->qstlength=ANDNS_HASH_H;
if (ap->qstlength>limitlen-2)
err_ret(ERR_ANDPLB,-1);
AP_ALIGN(ap);
memcpy(ap->qstdata,buf,ANDNS_HASH_H);
ret=ANDNS_HASH_H+2;
} else if (ap->nk==INET_REALM) {
memcpy(&s,buf,2);
ap->qstlength=ntohs(s);
buf+=2;
if (ap->qstlength>=ANDNS_MAX_QST_LEN ||
ap->qstlength>limitlen-4)
err_ret(ERR_ANDPLB,-1);
AP_ALIGN(ap);
memcpy(ap->qstdata,buf,ap->qstlength);
ret=ap->qstlength+4;
} else
return -1;
break;
case AT_PTR:
ap->qstlength=ap->ipv?16:4;
if (ap->qstlength>limitlen)
err_ret(ERR_ANDMAP,-1)
AP_ALIGN(ap);
memcpy(ap->qstdata,buf,ap->qstlength);
ret=ap->qstlength;
break;
case AT_G:
if (ap->nk!=NTK_REALM)
err_ret(ERR_ANDMAP,-1);
ap->qstlength=ANDNS_HASH_H;
if (ap->qstlength>limitlen)
err_ret(ERR_ANDPLB,-1);
AP_ALIGN(ap);
memcpy(ap->qstdata,buf,ANDNS_HASH_H);
ret=ap->qstlength;
break;
default:
debug(DBG_INSANE,"In a_qst_u: unknow query type.");
err_ret(ERR_ANDMAP,-1)
}
return ret;
}
int a_answ_u(char *buf,andns_pkt *ap,int limitlen)
{
uint16_t alen;
andns_pkt_data *apd;
int limit;
if (limitlen<3)
err_ret(ERR_ANDMAP,-1);
switch (ap->qtype) {
case AT_A:
limit=2;
if (limitlen<limit)
err_ret(ERR_ANDPLB,-1);
apd=andns_add_answ(ap);
if (*buf&0x40) {
apd->m|=APD_IP;
if (*buf&0x80)
apd->m|=APD_MAIN_IP;
limit=ap->ipv?16:4;
} else
limit=ANDNS_HASH_H;
if (limitlen<limit+2)
err_ret(ERR_ANDPLB,-1);
apd->wg=(*buf&0x3f);
apd->prio=(*(buf+1));
apd->rdlength=limit;
APD_ALIGN(apd);
memcpy(apd->rdata,buf+2,limit);
limit+=2;
break;
case AT_PTR:
memcpy(&alen,buf,2);
alen=ntohs(alen);
if (alen+2>limitlen)
err_ret(ERR_ANDPLB,-1);
if (alen>ANDNS_MAX_DATA_LEN)
err_ret(ERR_ANDPLB,-1);
apd=andns_add_answ(ap);
apd->rdlength=alen;
APD_ALIGN(apd);
memcpy(apd->rdata,buf+2,alen);
limit=alen+2;
break;
case AT_G:
if (limitlen<8)
err_ret(ERR_ANDMAP,-1);
apd=andns_add_answ(ap);
if (*buf&0x40) {
apd->m|=APD_IP;
if (*buf&0x80)
apd->m|=APD_MAIN_IP;
}
apd->m|=*buf&0x20?APD_UDP:
APD_TCP;
apd->wg=(*buf&0x1f);
apd->prio=(*(buf+1));
buf+=2;
memcpy(&alen,buf,2);
apd->service=ntohs(alen);
buf+=2;
if (apd->m&APD_IP)
apd->rdlength=(ap->ipv?16:4);
else
apd->rdlength=ANDNS_HASH_H;
limit=4+apd->rdlength;
if (limitlen<limit)
err_ret(ERR_ANDPLB,-1);
APD_ALIGN(apd);
memcpy(apd->rdata,buf,apd->rdlength);
break;
default:
err_ret(ERR_ANDMAP,-1);
}
return limit;
}
int a_answs_u(char *buf,andns_pkt *ap,int limitlen)
{
int ancount,i;
int offset=0,res;
uint16_t alen;
if (ap->qtype==AT_G) {
memcpy(&alen,buf,sizeof(uint16_t));
ap->ancount=ntohs(alen);
offset+=2;
}
ancount=ap->ancount;
for (i=0;i<ancount;i++) {
res=a_answ_u(buf+offset,ap,limitlen-offset);
if (res==-1) {
error(err_str);
err_ret(ERR_ANDMAD,-1);
}
offset+=res;
}
return offset;
}
/*
* This is a main function: takes the pkt-buf and translate
* it in structured data.
* It cares about andns_pkt allocation.
* The apkt is allocate here.
*
* Returns:
* -1 on E_INTRPRT
* 0 if pkt must be discarded.
* Number of bytes readed otherwise
*/
int a_u(char *buf,int pktlen,andns_pkt **app)
{
andns_pkt *ap;
int offset,res;
int limitlen,u_len;
char *u_buf;
if (pktlen<ANDNS_HDR_SZ)
err_ret(ERR_ANDPLB,0);
*app=ap=create_andns_pkt();
offset=a_hdr_u(buf,ap);
if (ap->z) { /* Controls the space to read
uncompressed size */
if (pktlen<ANDNS_HDR_SZ+ANDNS_HDR_Z) {
destroy_andns_pkt(ap);
err_ret(ERR_ANDPLB,0);
}
if (!(u_buf=andns_uncompress(buf,pktlen,&u_len)))
goto andmap;
destroy_andns_pkt(ap);
ANDNS_UNSET_Z(u_buf);
res=a_u(u_buf,u_len,app);
xfree(u_buf);
return res;
}
buf+=offset;
limitlen=pktlen-offset;
if ((res=a_qst_u(buf,ap,limitlen))==-1)
goto andmap;
offset+=res;
if (!ap->ancount) /*No answers */
return offset;
buf+=res;
limitlen-=res;
if ((res=a_answs_u(buf,ap,limitlen))==-1)
goto andmap;
offset+=res;
if (offset!=pktlen)
error("In a_u(): pktlen differs from readed contents: ID query %d.",ap->id);
return offset;
andmap:
destroy_andns_pkt(ap);
error(err_str);
err_ret(ERR_ANDMAP,-1);
}
int a_hdr_p(andns_pkt *ap,char *buf)
{
uint16_t s;
uint8_t an;
ap->id<<=1;
s=htons(ap->id);
memcpy(buf,&s,sizeof(uint16_t));
if (ap->r)
*(buf+1)|=0x01;
else
*(buf+1)&=0xfe;
buf+=2;
if (ap->qr)
(*buf)|=0x80;
if (ap->p)
(*buf)|=0x40;
if (ap->z)
(*buf)|=0x20;
(*buf)|=( (ap->qtype)<<3);
an=ap->ancount;
(*buf++)|=( (an)>>1);
(*buf)|=( (ap->ancount)<<7);
if (ap->ipv)
*buf|=0x40;
(*buf)|=( (ap->nk)<<4);
(*buf)|=( ap->rcode);
return ANDNS_HDR_SZ;
}
int a_qst_p(andns_pkt *ap,char *buf,int limitlen)
{
int ret=0;
uint16_t s;
int limit;
switch(ap->qtype){
case AT_A:
limit=ap->nk==NTK_REALM?ANDNS_HASH_H+2:ap->qstlength+4;
if (limitlen<limit)
err_ret(ERR_ANDMAD,-1);
s=htons(ap->service);
memcpy(buf,&s,2);
buf+=2; /* here INET and NTK REALM change */
if (ap->nk==NTK_REALM) {
memcpy(buf,ap->qstdata,ANDNS_HASH_H);
ret=ANDNS_HASH_H+2;
} else if (ap->nk==INET_REALM) {
s=htons(ap->qstlength);
memcpy(buf,&s,2);
buf+=2;
memcpy(buf,ap->qstdata,ap->qstlength);
ret=ap->qstlength+4;
} else
err_ret(ERR_ANDMAD,-1);
break;
case AT_PTR:
limit=ap->ipv?16:4;
if (limitlen<limit)
err_ret(ERR_ANDMAD,-1);
memcpy(buf,ap->qstdata,limit);
ret=limit;
break;
case AT_G:
limit=ANDNS_HASH_H;
if (limitlen<limit)
err_ret(ERR_ANDMAD,-1);
memcpy(buf,ap->qstdata,ANDNS_HASH_H);
ret=ANDNS_HASH_H;
break;
default:
debug(DBG_INSANE,"In a_qst_p: unknow query type.");
err_ret(ERR_ANDMAD,-1);
break;
}
return ret;
}
int a_answ_p(andns_pkt *ap,andns_pkt_data *apd,char *buf,int limitlen)
{
uint16_t s;
int limit;
int ret;
switch(ap->qtype) {
case AT_A:
limit=ap->ipv?16:4;
if (limitlen<limit+2)
err_ret(ERR_ANDPLB,-1);
if (apd->m)
*buf|=0x80;
*buf++|= (apd->wg&0x7f);
*buf++|=apd->prio;
memcpy(buf,apd->rdata,limit);
ret=limit+2;
break;
case AT_PTR:
if (limitlen<apd->rdlength+2)
err_ret(ERR_ANDPLB,-1);
s=htons(apd->rdlength);
memcpy(buf,&s,sizeof(uint16_t));
buf+=2;
memcpy(buf,apd->rdata,apd->rdlength);
ret=apd->rdlength+2;
break;
case AT_G: /* TODO */
if (limitlen<4)
err_ret(ERR_ANDPLB,-1);
if (apd->m==1)
(*buf)|=0xc0;
else if (apd->m)
(*buf)|=0x40;
*buf++|= (apd->wg&0x3f);
*buf++|=apd->prio;
s=htons(apd->service);
memcpy(buf,&s,2);
if (apd->m) {
limit=ap->ipv?16:4;
if (limitlen<limit+4)
err_ret(ERR_ANDPLB,-1);
memcpy(buf,apd->rdata,limit);
ret=limit+4;
} else {
limit=strlen(apd->rdata);
if (limitlen<limit+6)
err_ret(ERR_ANDPLB,-1);
s=htons(limit);
memcpy(buf,&s,2);
buf+=2;
memcpy(buf,apd->rdata,limit);
ret=limit+6;
}
break;
default:
debug(DBG_INSANE,"In a_answ_p(): unknow query type.");
err_ret(ERR_ANDMAD,-1);
break;
}
return ret;
}
int a_answs_p(andns_pkt *ap,char *buf, int limitlen)
{
andns_pkt_data *apd;
int i;
int offset=0,res;
uint16_t s;
if (ap->qtype==AT_G) {
if (limitlen<2)
err_ret(ERR_ANDPLB,-1);
s=htons(ap->ancount);
memcpy(buf,&s,2);
offset+=2;
}
apd=ap->pkt_answ;
for (i=0;i<ap->ancount && apd;i++) {
if((res=a_answ_p(ap,apd,buf+offset,limitlen-offset))==-1) {
error(err_str);
err_ret(ERR_ANDMAD,-1);
}
offset+=res;
apd=apd->next;
}
return offset;
}
int a_p(andns_pkt *ap, char *buf)
{
int offset,res;
memset(buf,0,ANDNS_MAX_SZ);
offset=a_hdr_p(ap,buf);
buf+=offset;
if ((res=a_qst_p(ap,buf,ANDNS_MAX_SZ-offset))==-1)
goto server_fail;
offset+=res;
buf+=res;
if (ap->ancount) {
if ((res=a_answs_p(ap,buf,ANDNS_MAX_SZ-offset))==-1)
goto server_fail;
offset+=res;
}
destroy_andns_pkt(ap);
/* Compression */
if (offset>ANDNS_COMPR_THRESHOLD) {
res=andns_compress(buf,offset);
if (res==-1)
error(err_str);
else
return res;
}
/* end compression */
return offset;
server_fail:
destroy_andns_pkt(ap);
error(err_str);
err_ret(ERR_ANDMAD,-1);
}
/* MEM */
/* Borning functions */
andns_pkt* create_andns_pkt(void)
{
andns_pkt *ap;
ap=xmalloc(ANDNS_PKT_SZ);
memset(ap,0,ANDNS_PKT_SZ);
return ap;
}
andns_pkt_data* create_andns_pkt_data(void)
{
andns_pkt_data *apd;
apd=xmalloc(ANDNS_PKT_DATA_SZ);
memset(apd,0,ANDNS_PKT_DATA_SZ);
return apd;
}
andns_pkt_data* andns_add_answ(andns_pkt *ap)
{
andns_pkt_data *apd,*a;
apd=create_andns_pkt_data();
a=ap->pkt_answ;
if (!a) {
ap->pkt_answ=apd;
return apd;
}
while (a->next) a=a->next;
a->next=apd;
return apd;
}
/* Death functions */
void destroy_andns_pkt_data(andns_pkt_data *apd)
{
if (apd->rdata)
xfree(apd->rdata);
xfree(apd);
}
void andns_del_answ(andns_pkt *ap)
{
andns_pkt_data *apd,*apdt;
apd=ap->pkt_answ;
if (!apd)
return;
apdt=apd->next;
while (apdt) {
apd=apdt;
apdt=apdt->next;
}
apd->next=NULL;
destroy_andns_pkt_data(apdt);
}
void destroy_andns_pkt_datas(andns_pkt *ap)
{
andns_pkt_data *apd,*apd_t;
apd=ap->pkt_answ;
while(apd) {
apd_t=apd->next;
destroy_andns_pkt_data(apd);
apd=apd_t;
}
}
void destroy_andns_pkt(andns_pkt *ap)
{
if (ap->qstdata)
xfree(ap->qstdata);
destroy_andns_pkt_datas(ap);
xfree(ap);
}

136
src/andns_lib.h Normal file
View File

@ -0,0 +1,136 @@
/**************************************
* AUTHOR: Federico Tomassini *
* Copyright (C) Federico Tomassini *
* Contact effetom@gmail.com *
***********************************************
******* BEGIN 3/2006 ********
*************************************************************************
* *
* 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 2 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. *
* *
************************************************************************/
#ifndef ANDNS_LIB_H
#define ANDNS_LIB_H
#include <string.h>
#include <stdint.h>
#include <sys/types.h>
#define ANDNS_MAX_QUESTION_LEN 263 /* TODO */
#define ANDNS_MAX_ANSWER_LEN 516
#define ANDNS_MAX_ANSWERS_NUM 256
#define ANDNS_MAX_PK_LEN ANDNS_MAX_QUESTION_LEN+\
ANDNS_MAX_ANSWERS_NUM*ANDNS_MAX_ANSWER_LEN
#define ANDNS_MAX_DATA_LEN 512
#define ANDNS_MAX_QST_LEN 512
#define ANNDS_DNS_MAZ_QST_LEN 255
#define ANDNS_MAX_ANSW_IP_LEN 20
#define ANDNS_MAX_ANSW_H_LEN 516
#define ANDNS_HASH_H 16
#define ANDNS_COMPR_LEVEL Z_BEST_COMPRESSION
#define ANDNS_COMPR_THRESHOLD 1000
struct andns_pkt_data
{
uint8_t m;
uint8_t wg;
uint8_t prio;
uint16_t rdlength;
uint16_t service;
char *rdata;
struct andns_pkt_data *next;
};
typedef struct andns_pkt_data andns_pkt_data;
#define ANDNS_PKT_DATA_SZ sizeof(andns_pkt_data)
#define APD_ALIGN(apd) (apd)->rdata=(char*)xmalloc((apd)->rdlength+1); \
memset((apd)->rdata,0,(apd)->rdlength+1)
#define APD_MAIN_IP 1<<0
#define APD_IP 1<<1
#define APD_TCP 1<<2
#define APD_UDP 1<<3
typedef struct andns_pkt
{
uint16_t id;
uint8_t r;
uint8_t qr;
uint8_t p;
uint8_t z;
uint8_t qtype;
uint16_t ancount;
uint8_t ipv;
uint8_t nk;
uint8_t rcode;
uint16_t service;
uint16_t qstlength;
char *qstdata;
andns_pkt_data *pkt_answ;
} andns_pkt;
#define ANDNS_PKT_SZ sizeof(andns_pkt)
#define AP_ALIGN(ap) (ap)->qstdata=(char*)xmalloc((ap)->qstlength)
#define ANDNS_HDR_SZ 4
#define ANDNS_HDR_Z 4
#define ANDNS_MAX_SZ ANDNS_HDR_SZ+ANDNS_MAX_QST_LEN+ANDNS_MAX_QST_LEN+4
#define ANDNS_SET_RCODE(s,c) *((s)+3)=(((*((s)+3))&0xf0)|c)
#define ANDNS_SET_QR(s) (*((s)+2))|=0x80
#define ANDNS_SET_ANCOUNT(s,n) *(s+2)|=((n)>>1);*(s+3)|=((n)<<7);
#define ANDNS_SET_Z(s) *(s+3)|=0x20;
#define ANDNS_UNSET_Z(s) *(s+3)&=0xdf;
/* ANDNS PROTO-TYPE */
#define ANDNS_PROTO_TCP 0
#define ANDNS_PROTO_UDP 1
/* ANDNS QUERY-TYPE */
#define AT_A 0 /* h->ip */
#define AT_PTR 1 /* ip->h */
#define AT_G 2 /* global */
/* RCODES: The rcodes are portable between ANDNS and DNS */
#define ANDNS_RCODE_NOERR 0 /* No error */
#define ANDNS_RCODE_EINTRPRT 1 /* Intepret error */
#define ANDNS_RCODE_ESRVFAIL 2 /* Server failure */
#define ANDNS_RCODE_ENSDMN 3 /* No such domain */
#define ANDNS_RCODE_ENIMPL 4 /* Not implemented */
#define ANDNS_RCODE_ERFSD 5 /* Refused */
/* REALMS TO SEARCH */
#define NTK_REALM 1
#define INET_REALM 2
/* IP VERSION */
#define ANDNS_IPV4 0
#define ANDNS_IPV6 1
int andns_compress(char *src,int srclen);
char* andns_uncompress(char *src,int srclen,int *dstlen) ;
int a_hdr_u(char *buf,andns_pkt *ap);
int a_qst_u(char *buf,andns_pkt *ap,int limitlen);
int a_answ_u(char *buf,andns_pkt *ap,int limitlen);
int a_answs_u(char *buf,andns_pkt *ap,int limitlen);
int a_u(char *buf,int pktlen,andns_pkt **app);
int a_hdr_p(andns_pkt *ap,char *buf);
int a_qst_p(andns_pkt *ap,char *buf,int limitlen);
int a_answ_p(andns_pkt *ap,andns_pkt_data *apd,char *buf,int limitlen);
int a_answs_p(andns_pkt *ap,char *buf, int limitlen);
int a_p(andns_pkt *ap, char *buf);
andns_pkt* create_andns_pkt(void);
andns_pkt_data* create_andns_pkt_data(void);
andns_pkt_data* andns_add_answ(andns_pkt *ap);
void destroy_andns_pkt_data(andns_pkt_data *apd);
void andns_del_answ(andns_pkt *ap);
void destroy_andns_pkt_datas(andns_pkt *ap);
void destroy_andns_pkt(andns_pkt *ap);
#endif /* ANDNS_LIB_H */

297
src/andns_net.c Normal file
View File

@ -0,0 +1,297 @@
/**************************************
* AUTHOR: Federico Tomassini *
* Copyright (C) Federico Tomassini *
* Contact effetom@gmail.com *
***********************************************
******* BEGIN 4/2006 ********
*************************************************************************
* *
* 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 2 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. *
* *
************************************************************************/
#include "log.h"
#include "andns_net.h"
int idp_inet_ntop(int family,struct sockaddr *addr,char *buf,int buflen)
{
const char *res;
struct sockaddr_in *saddr;
struct sockaddr_in6 *saddr6;
switch(family) {
case AF_INET:
saddr=(struct sockaddr_in*)addr;
res=inet_ntop(family,(void*)(&(saddr->sin_addr)),buf,buflen);
break;
case AF_INET6:
saddr6=(struct sockaddr_in6*)addr;
res=inet_ntop(family,(void*)(&(saddr6->sin6_addr)),buf,buflen);
break;
default:
return -1;
}
if (!res)
return -1;
return 0;
}
/* Connection Layer */
int w_socket(int family,int type, int proto,int die)
{
int sk;
sk=socket(family,type,proto);
if (sk==-1) {
if (die)
fatal("w_socket: %s.",strerror(errno));
debug(DBG_NORMAL,"w_socket: %s.",strerror(errno));
return -1;
}
return sk;
}
int w_connect(struct addrinfo *ai,int die)
{
int sk,res;
sk=w_socket(ai->ai_family,ai->ai_socktype,ai->ai_protocol,die);
res=connect(sk,ai->ai_addr,ai->ai_addrlen);
if (!res)
return sk;
if (die)
fatal("Unable to connect: %s.", strerror(errno));
debug(DBG_NORMAL,"w_connect: %s.",strerror(errno));
close(sk);
return -1;
}
int serial_connect(struct addrinfo *ai,int die)
{
int res;
struct addrinfo *temp;
temp=ai;
if (!temp) {
if (die)
fatal("Unable to connect: no host specified.");
debug(DBG_NORMAL,"serial_connect: no host specified.");
return -1;
}
do {
res=w_connect(temp,0);
temp=temp->ai_next;
} while (res==-1 && temp);
if (res==-1) {
if (die)
fatal("Unable to connect.");
debug(DBG_NORMAL,"serial_connect: unable to connect.");
return -1;
}
return res;
}
/*
* host_connect returns a connected socket to (host,port)
* endpoint. It is protocol independent.
* -1 on error.
*/
int host_connect(const char *host,uint16_t port,int type,int die)
{
int res;
char portstr[6];
struct addrinfo *ai,filter;
memset(&filter,0,sizeof(struct addrinfo));
filter.ai_socktype=type;
if (!host)
fatal("w_connect: malicious call.");
memset(portstr,0,6);
res=snprintf(portstr,6,"%d",port);
if (res<0 || res>=6) {
printf("Depousceve\n");
return -1;
}
res=getaddrinfo(host,portstr,&filter,&ai);
if (res!=0) {
printf("w_connect: error %s.\n",gai_strerror(errno));
return -1;
}
res=serial_connect(ai,die);
freeaddrinfo(ai);
return res;
}
int ai_connect(struct addrinfo *ai,int die,int free_ai)
{
int res;
res=serial_connect(ai,die);
if (free_ai)
freeaddrinfo(ai);
return res;
}
/* Communication Layer */
ssize_t w_send(int sk,const void *buf,size_t len,int die)
{
ssize_t ret;
ret=send(sk,buf,len,0);
if (ret!=len) {
if (die)
fatal("Unable to send(): %s.",strerror(errno));
debug(DBG_NORMAL,"w_send(): %s.",strerror(errno));
}
return ret;
}
ssize_t w_recv(int sk,void *buf,size_t len,int die)
{
ssize_t ret;
ret=recv(sk,buf,len,0);
if (ret<=0) {
if (die)
fatal("Unable to recv(): %s.",strerror(errno));
debug(DBG_INSANE,"w_recv(): %s.",strerror(errno));
}
return ret;
}
/*
* These two functions and the MACRO are
* almost VERBATIM copied from inet.c and inet.h.
* Functions by AlpT, Andrea Lo Pumo.
*/
#define MILLISEC_TO_TV(x,t) \
do{ \
(t).tv_sec=(x)/1000; \
(t).tv_usec=((x) - ((x)/1000)*1000)*1000; \
}while(0)
ssize_t w_send_timeout(int s,const void *buf,size_t len,int die,int timeout)
{
struct timeval timeout_t;
fd_set fdset;
int ret;
MILLISEC_TO_TV(timeout*1000, timeout_t);
FD_ZERO(&fdset);
FD_SET(s, &fdset);
ret = select(s+1, &fdset, NULL, NULL, &timeout_t);
if (ret == -1) {
if (die)
fatal("send(): select error.");
debug(DBG_NORMAL,"send(): select error.");
return ret;
}
if(FD_ISSET(s, &fdset))
return w_send(s, buf, len, die);
return -1;
}
ssize_t w_recv_timeout(int s,void *buf,size_t len,int die,int timeout)
{
struct timeval timeout_t;
fd_set fdset;
int ret;
MILLISEC_TO_TV(timeout*1000, timeout_t);
FD_ZERO(&fdset);
FD_SET(s, &fdset);
ret = select(s+1, NULL, &fdset, NULL, &timeout_t);
if (ret == -1) {
if (die)
fatal("recv(): select error.");
debug(DBG_NORMAL,"recv(): select error.");
return ret;
}
if(FD_ISSET(s, &fdset))
return w_recv(s, buf, len, die);
return -1;
}
/* Dialog Layer */
/* "Botta e risposta" */
ssize_t hn_send_recv_close(const char *host,uint16_t port,int type,void *buf,
size_t buflen,void *anbuf,size_t anlen,int die,int timeout)
{
ssize_t ret;
int res;
res=host_connect(host,port,type,die);
if (res==-1)
return -1;
if (timeout)
ret=w_send_timeout(res,buf,buflen,die,timeout);
else
ret=w_send(res,buf,buflen,die);
if (ret==-1)
return -2;
if (timeout)
ret=w_recv_timeout(res,anbuf,anlen,die,timeout);
else
ret=w_recv(res,anbuf,anlen,die);
if (ret==-1)
return -3;
close(res);
return ret;
}
/* "Botta e risposta" */
ssize_t ai_send_recv_close(struct addrinfo *ai,void *buf,size_t buflen,
void *anbuf,size_t anlen,int die,int free_ai,int timeout)
{
ssize_t ret;
int res;
res=ai_connect(ai,die,free_ai);
if (res==-1)
return -1;
if (timeout)
ret=w_send_timeout(res,buf,buflen,die,timeout);
else
ret=w_send(res,buf,buflen,die);
if (ret==-1)
return -2;
if (timeout)
ret=w_recv_timeout(res,anbuf,anlen,die,timeout);
else
ret=w_recv(res,anbuf,anlen,die);
if (ret==-1)
return -3;
close(res);
return ret;
}
void char_print(char *buf, int len)
{
int i,count=0;
printf("Printing %d bytes\n",len);
for (i=0;i<len;i++) {
printf("%02X ", (unsigned char)(buf[i]));
count++;
if ((count%16)==0) printf("\n");
}
printf("\n");
return;
}

32
src/andns_net.h Normal file
View File

@ -0,0 +1,32 @@
#ifndef ANDNS_NET_H
#define ANDNS_NET_H
#include <errno.h>
#include <netdb.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
int idp_inet_ntop(int family,struct sockaddr *addr,char *buf,int buflen);
int w_socket(int family,int type, int proto,int die);
int w_connect(struct addrinfo *ai,int die) ;
int serial_connect(struct addrinfo *ai,int die);
int host_connect(const char *host,uint16_t port,int type,int die) ;
int ai_connect(struct addrinfo *ai,int die,int free_ai);
ssize_t w_send(int sk,const void *buf,size_t len,int die) ;
ssize_t w_recv(int sk,void *buf,size_t len,int die);
ssize_t w_send_timeout(int s,const void *buf,size_t len,int die,int timeout);
ssize_t w_recv_timeout(int s,void *buf,size_t len,int die,int timeout);
ssize_t ai_send_recv_close(struct addrinfo *ai,void *buf,size_t buflen,
void *anbuf,size_t anlen,int die,int free_ai,int timeout);
ssize_t hn_send_recv_close(const char *host,uint16_t port,int type,void *buf,
size_t buflen,void *anbuf,size_t anlen,int die,int timeout);
void char_print(char *buf, int len);
#endif /* ANDNS_NET_H */

316
src/andns_snsd.c Normal file
View File

@ -0,0 +1,316 @@
#include "includes.h"
#include "llist.c"
#include "andns_snsd.h"
#include "err_errno.h"
#include "andna.h"
#include "log.h"
/* h2ip functions */
/*
* Given a a hostname hash, makes a resolution
* call (service=0) and search the main ip entry,
* storing it to snsd_node dst.
*
* Returns:
* 0
* -1
*/
int snsd_main_ip(u_int *hname_hash,snsd_node *dst)
{
snsd_service *ss;
snsd_prio *sp;
snsd_node *sn;
int records;
ss=andna_resolve_hash(hname_hash,0,0,&records);
if (!ss)
err_ret(ERR_SNDMRF,-1);
if (!(sp=ss->prio)) {
goto destroy_return;
}
list_for(sp) {
sn=sp->node;
list_for(sn)
if (sn->flags & SNSD_NODE_MAIN_IP) {
memcpy(dst,sn,sizeof(snsd_node));
snsd_service_llist_del(&ss);
return 0;
}
}
goto destroy_return;
destroy_return:
snsd_service_llist_del(&ss);
err_ret(ERR_SNDMRF,-1);
}
/*
* Convert a snsd_node to a binary ip.
* If snsd_node does not contain a ip, but a hostname hash,
* calls another resolution with service=0.
*
* Returns:
* bytes writed
*
*/
int snsd_node_to_data(char *buf,snsd_node *sn,u_char prio,int iplen,int recursion)
{
int res;
int family;
if (recursion!=-1) {
*buf|=sn->weight&0x3f;
*(buf+1)|=prio;
}
if (! (sn->flags & SNSD_NODE_HNAME)) {
*buf|=0x40;
if (sn->flags & SNSD_NODE_MAIN_IP )
*buf|=0x80;
memcpy(buf+2,sn->record,iplen);
family=(iplen==4)?AF_INET:AF_INET6;
inet_htonl((u_int*)(buf+2),family);
return iplen+2;
} else if (recursion) {
snsd_node snt;
res=snsd_main_ip(sn->record,&snt);
if (!res) { /* I love recursion */
res=snsd_node_to_data(buf,&snt,prio,iplen,-1);
return res;
}
}
memcpy(buf+2,sn->record,ANDNS_HASH_H);
return ANDNS_HASH_H+2;
}
/*
* Converts a snsd_node struct to andns data.
* data means a packed answer.
* buf has to be ANDNS_MAX_ANSW_IP_LEN long.
*
* returns -1 on error, answer len otherwise.
*
* O B S O L E T E
size_t snsd_node_to_aansw(char *buf,snsd_node *sn,u_char prio,int iplen)
{
int res;
res=snsd_node_to_data(buf+2,sn,iplen);
if (res==-1) {
error(err_str);
return -1;
}
if (sn->flags & SNSD_NODE_MAIN_IP)
*buf|=0x80;
*buf++=sn->weight;
*buf=prio;
return 0;
}
*/
/*
* Converts a snsd_prio list to andns data.
* data means a set of contiguous answers ready
* to be sent.
*
* Returns the number of bytes writed to buf.
* The size is computable with iplen.
*
* buf has to be long enough, ie, you have to count node
* in prio list and take ANDNS_MAX_ANSW_IP_LEN * n space.
*
*/
int snsd_prio_to_aansws(char *buf,snsd_prio *sp,int iplen,int recursion,int *count)
{
int res=0;
snsd_node *sn;
int c=0;
if(!sp || !buf)
return 0;
sn=sp->node;
list_for(sn) {
res+=snsd_node_to_data(buf+res,sn,sp->prio,
iplen,recursion);
c++;
}
*count=c;
return res;
}
int snsd_service_to_aansws(char *buf,snsd_service *ss,int iplen,int *count,int recursion)
{
int family,c=0;
uint16_t service;
uint8_t prio,proto;
snsd_prio *sp;
snsd_node *sn;
char *rem;
snsd_node snt;
if (!ss || !buf)
return 0;
rem=buf;
list_for(ss) {
service=htons(ss->service);
proto=ss->proto;
sp=ss->prio;
list_for(sp) {
prio=sp->prio;
sn=sp->node;
list_for(sn) {
if (sn->flags & SNSD_NODE_MAIN_IP)
(*buf)|=0xc0;
else if (sn->flags & SNSD_NODE_IP)
(*buf)|=0x40;
if (proto==ANDNS_SNSD_PROTO_UDP)
(*buf)|=0x20;
*buf++|=(sn->weight&0x1f);
*buf++|=prio;
memcpy(buf,&service,2);
buf+=2;
if (sn->flags & SNSD_NODE_MAIN_IP ||
sn->flags & SNSD_NODE_IP ) {
memcpy(buf,sn->record,iplen);
family=(iplen==4)?AF_INET:AF_INET6;
inet_htonl((u_int*)buf,family);
buf+=iplen;
} else {
if (recursion && !snsd_main_ip(sn->record,&snt)) {
memcpy(buf,snt.record,iplen);
*(buf-4)|=0x40;
family=(iplen==4)?AF_INET:AF_INET6;
inet_htonl((u_int*)buf,family);
buf+=iplen;
} else {
memcpy(buf,sn->record, ANDNS_HASH_H);
buf+=ANDNS_HASH_H;
}
/* service=strlen((char*)sn->record);
temp=htons(service);
memcpy(buf,&temp,2);
memcpy(buf+2,sn->record,service);
buf+=ANDNS_HASH_H;
res=snsd_main_ip(sn->record,&snt);
if (res) {
buf-=4;
continue;
}
memcpy(buf,snt.record,iplen);
family=(iplen==4)?AF_INET:AF_INET6;
inet_htonl((u_int*)buf,family);
buf+=iplen; */
}
c++;
}
}
}
*count=c;
return (int)(buf-rem);
}
/*
* Given a dns_packet, this function add an answer to it
* and returns 0;
* Otherwise returns -1.
*/
int snsd_node_to_dansw(dns_pkt *dp,snsd_node *sn,int iplen)
{
char temp[18];
dns_pkt_a *dpa;
snsd_node snt,*s;
int res;
if (!(sn->flags & SNSD_NODE_HNAME)) {
if (!(res=snsd_main_ip(sn->record,&snt)))
return -1;
s=&snt;
} else
s=sn;
memcpy(temp,sn->record,iplen);
inet_htonl((u_int*)(temp),
(iplen==4)?AF_INET:AF_INET6);
dpa=DP_ADD_ANSWER(dp);
dns_a_default_fill(dp,dpa);
dpa->rdlength=iplen;
memcpy(dpa->rdata,temp,iplen);
return 0;
}
/*
* Converts a snsd_prio struct, adding a set of answers to
* the dns_packet dp.
* Returns the number of answers added to dp.
*/
int snsd_prio_to_dansws(dns_pkt *dp,snsd_prio *sp,int iplen)
{
int res=0;
snsd_node *sn;
sn=sp->node;
list_for(sn)
if (!snsd_node_to_dansw(dp,sn,iplen))
res++;
return res;
}
/* ip2h functions */
/*
* Converts a lcl_cache struct to a set of dns answers.
* Returns the number of answers added.
*/
int lcl_cache_to_dansws(dns_pkt *dp,lcl_cache *lc)
{
dns_pkt_a *dpa;
int res=0;
list_for(lc) {
dpa=DP_ADD_ANSWER(dp);
dns_a_default_fill(dp,dpa);
strcpy(dpa->rdata,lc->hostname);
res++;
}
if(lc)
lcl_cache_free(lc);
return res;
}
/*
* Converts a lcl_cache to andns data.
* Returns the number of bytes writed.
*/
size_t lcl_cache_to_aansws(char *buf,lcl_cache *lc,int *count)
{
uint16_t slen;
size_t ret=0;
int lcount=0;
lcl_cache *lcl=lc;
list_for(lcl) {
slen=strlen(lc->hostname);
ret+=2+slen;
slen=htons(slen);
memcpy(buf,&slen,2);
buf+=2;
strcpy(buf,lc->hostname);
lcount++;
}
*count=lcount;
lcl_cache_free(lc);
return ret;
}

22
src/andns_snsd.h Normal file
View File

@ -0,0 +1,22 @@
#ifndef ANDNS_SNSD_H
#define ANDNS_SNSD_H
#include "dnslib.h"
#include "andns_lib.h"
#include "andna_cache.h"
#define ANDNS_SNSD_PROTO_TCP 1
#define ANDNS_SNSD_PROTO_UDP 2
/* functions */
int snsd_main_ip(u_int *hname_hash,snsd_node *dst);
int snsd_node_to_data(char *buf,snsd_node *sn,u_char prio,int iplen,int recursion);
size_t snsd_node_to_aansw(char *buf,snsd_node *sn,u_char prio,int iplen);
int snsd_prio_to_aansws(char *buf,snsd_prio *sp,int iplen,int recursion,int *count);
int snsd_service_to_aansws(char *buf,snsd_service *ss,int iplen,int *count,int recursion);
int snsd_node_to_dansw(dns_pkt *dp,snsd_node *sn,int iplen);
int snsd_prio_to_dansws(dns_pkt *dp,snsd_prio *sp,int iplen);
int lcl_cache_to_dansws(dns_pkt *dp,lcl_cache *lc);
size_t lcl_cache_to_aansws(char *buf,lcl_cache *lc,int *count);
#endif /* ANDNS_SNSD_H */

454
src/bmap.c Normal file
View File

@ -0,0 +1,454 @@
/* This file is part of Netsukuku
* (c) Copyright 2005 Andrea Lo Pumo aka AlpT <alpt@freaknet.org>
*
* This source code 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 2 of the License,
* or (at your option) any later version.
*
* This source code 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.
* Please refer to the GNU Public License for more details.
*
* You should have received a copy of the GNU Public License along with
* this source code; if not, write to:
* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* --
* bmap.c:
* Border node map code.
*/
#include "includes.h"
#include "common.h"
#include "inet.h"
#include "endianness.h"
#include "map.h"
#include "gmap.h"
#include "bmap.h"
void bmap_levels_init(u_char levels, map_bnode ***bmap, u_int **bmap_nodes)
{
*bmap=xmalloc(sizeof(map_bnode *) * levels);
*bmap_nodes=(u_int *)xmalloc(sizeof(u_int) * levels);
setzero(*bmap, sizeof(map_bnode *) * levels);
bmap_counter_reset(levels, *bmap_nodes);
}
void bmap_levels_free(map_bnode **bmap, u_int *bmap_nodes)
{
xfree(bmap);
xfree(bmap_nodes);
}
void bmap_counter_init(u_char levels, u_int **bnodes_closed, u_int **bnodes_opened)
{
*bnodes_closed=(u_int *)xmalloc(sizeof(u_int) * levels);
*bnodes_opened=(u_int *)xmalloc(sizeof(u_int) * levels);
bmap_counter_reset(levels, *bnodes_closed);
bmap_counter_reset(levels, *bnodes_opened);
}
void bmap_counter_free(u_int *bnodes_closed, u_int *bnodes_opened)
{
xfree(bnodes_closed);
xfree(bnodes_opened);
}
void bmap_counter_reset(u_char levels, u_int *counter)
{
setzero(counter, sizeof(u_int) * levels);
}
/*
* map_add_bnode: It adds a new bnode in the `bmap' and then returns its position
* in the bmap. It also increments the `*bmap_nodes' counter. The bnode_ptr is set
* to `bnode' and the links to `links'.
* Note that the `bmap' argument must be an adress of a pointer.
*/
int map_add_bnode(map_bnode **bmap, u_int *bmap_nodes, u_int bnode, u_int links)
{
map_bnode *bnode_map;
u_int bm;
bm=*bmap_nodes;
(*bmap_nodes)++;
if(!bm)
*bmap=xmalloc(sizeof(map_bnode));
else
*bmap=xrealloc(*bmap, sizeof(map_bnode) * *bmap_nodes);
bnode_map=*bmap;
setzero(bnode_map, sizeof(map_bnode));
bnode_map[bm].bnode_ptr=bnode;
bnode_map[bm].links=links;
return bm;
}
/*
* map_bnode_del: It deletes the `bnode' in the `bmap' which has `bmap_nodes'.
* It returns the newly rescaled `bmap'.
* It returns 0 if the `bmap' doesn't exist anymore.*/
map_bnode *map_bnode_del(map_bnode *bmap, u_int *bmap_nodes, map_bnode *bnode)
{
map_node_del((map_node *)bnode);
if( ((char *)bnode-(char *)bmap)/sizeof(map_bnode) != (*bmap_nodes)-1 )
memcpy(bnode, &bmap[*bmap_nodes-1], sizeof(map_bnode));
(*bmap_nodes)--;
if(*bmap_nodes)
return xrealloc(bmap, (*bmap_nodes) * sizeof(map_bnode));
else {
*bmap_nodes=0;
xfree(bmap);
return 0;
}
}
/*
* bmap_del_rnode_by_level: it is pretty specific, it deletes all the rnodes
* of `bnode' which point to a gnode located in a level not equal to `level'.
* The number of rnode deleted is returned.
* `total_levels' must be equal to the maximum levels
* available (use FAMILY_LVLS).
*/
int bmap_del_rnode_by_level(map_bnode *bnode, int level, map_gnode **ext_map,
int total_levels)
{
map_gnode *gn;
int i, ret=0, lvl;
for(i=0; i < bnode->links; i++) {
gn=(map_gnode *)bnode->r_node[i].r_node;
lvl=extmap_find_level(ext_map, gn, total_levels);
if(lvl != level) {
rnode_del(bnode, i);
ret++;
}
}
return ret;
}
/*
* map_find_bnode: Find the given `node' (in the pos_from_node() format) in the
* given map_bnode `bmap'.
*/
int map_find_bnode(map_bnode *bmap, int bmap_nodes, int node)
{
int e;
for(e=0; e<bmap_nodes; e++)
if(bmap[e].bnode_ptr == node)
return e;
return -1;
}
/*
* map_find_bnode_rnode: Find the first bnode in the `bmap' which has a rnode
* which points to `n'. If it is found the pos of the bnode in the `bmap' is
* returned, otherwise -1 is the return value.
*/
int map_find_bnode_rnode(map_bnode *bmap, int bmap_nodes, void *n)
{
int e;
for(e=0; e<bmap_nodes; e++)
if(rnode_find((map_node *)&bmap[e], (map_node *)n) != -1)
return e;
return -1;
}
/*
* map_count_bnode_rnode: counts how many bnode which have a rnode which
* points to `n' there are in `bmap'.
*/
int map_count_bnode_rnode(map_bnode *bmap, int bmap_nodes, void *n)
{
int e, i;
for(i=0, e=0; i<bmap_nodes; i++)
if(rnode_find((map_node *)&bmap[i], (map_node *)n) != -1)
e++;
return e;
}
/*
* bmaps_count_bnode_rnode: applies map_count_bnode_rnode() to each level of
* `bmap' and returns the sum of the results.
* `levels' are the total levels of `bmap'.
*/
int bmaps_count_bnode_rnode(map_bnode **bmap, int *bmap_nodes, int levels, void *n)
{
int i, e;
for(i=0, e=0; i<levels; i++)
e+=map_count_bnode_rnode(bmap[i], bmap_nodes[i], n);
return e;
}
/*
* map_del_bnode_rnode: deletes all the rnodes of the bnode, present in `bmap',
* which points to `n' and deletes the bnodes remained empty.
* `bmap' is the address of the pointer to the bmap.
* It returns the number of rnodes deleted.
*/
int map_del_bnode_rnode(map_bnode **bmap, int *bmap_nodes, void *n)
{
map_bnode *bm;
int e, p, ret=0;
bm=*bmap;
for(e=0; e < *bmap_nodes; e++) {
if((p=rnode_find((map_node *)&bm[e], (map_node *)n)) != -1) {
rnode_del(&bm[e], p);
if(!bm[e].links) {
*bmap=map_bnode_del(*bmap,(u_int*)bmap_nodes, &bm[e]);
bm=*bmap;
}
ret++;
}
}
return ret;
}
/*
* bmaps_del_bnode_rnode: applies map_del_bnode_rnode() to each level of
* `bmap'.
* `levels' are the total levels of `bmap'.
* It returns the total number of rnodes deleted
*/
int bmaps_del_bnode_rnode(map_bnode **bmap, int *bmap_nodes, int levels, void *n)
{
int i, e;
for(i=0, e=0; i<levels; i++)
e+=map_del_bnode_rnode(&bmap[i], &bmap_nodes[i], n);
return e;
}
/*
* map_set_bnode_flag: sets the `flags' to all the `bmap_nodes'# present in
* `bmap'.
*/
void map_set_bnode_flag(map_bnode *bmap, int bmap_nodes, int flags)
{
int e;
for(e=0; e<bmap_nodes; e++)
bmap[e].flags|=flags;
}
/*
* bmaps_set_bnode_flag: sets the `flags' to all the bnodes present in the
* `levels'# `bmap'.
*/
void bmaps_set_bnode_flag(map_bnode **bmap, int *bmap_nodes, int levels, int flags)
{
int i;
for(i=0; i<levels; i++)
map_set_bnode_flag(bmap[i], bmap_nodes[i], flags);
}
/*
* pack_all_bmaps: It creates the block of all the `bmaps' which have
* `bmap_nodes' nodes. `ext_map' and `quadg' are the structs referring
* to the external map. In `pack_sz' is stored the size of the block.
* The address pointing to the block is returned otherwise 0 is given.
* The package will be in network order.
*/
char *
pack_all_bmaps(map_bnode **bmaps, u_int *bmap_nodes, map_gnode **ext_map,
quadro_group quadg, size_t *pack_sz)
{
struct bnode_maps_hdr bmaps_hdr;
size_t sz, tmp_sz[BMAP_LEVELS(quadg.levels)];
char *pack[BMAP_LEVELS(quadg.levels)], *final_pack, *buf;
u_char level;
*pack_sz=0;
for(level=0; level < BMAP_LEVELS(quadg.levels); level++) {
pack[level]=pack_map((map_node *)bmaps[level], (int *)ext_map[_EL(level+1)],
bmap_nodes[level], 0, &sz);
tmp_sz[level]=sz;
(*pack_sz)+=sz;
}
bmaps_hdr.levels=BMAP_LEVELS(quadg.levels);
bmaps_hdr.bmaps_block_sz=*pack_sz;
(*pack_sz)+=sizeof(struct bnode_maps_hdr);
final_pack=xmalloc((*pack_sz));
memcpy(final_pack, &bmaps_hdr, sizeof(struct bnode_maps_hdr));
ints_host_to_network(final_pack, bnode_maps_hdr_iinfo);
buf=final_pack+sizeof(struct bnode_maps_hdr);
for(level=0; level < BMAP_LEVELS(quadg.levels); level++) {
memcpy(buf, pack[level], tmp_sz[level]);
buf+=tmp_sz[level];
xfree(pack[level]);
}
return final_pack;
}
/*
* unpack_all_bmaps: Given a block `pack' of size `pack_sz' containing `levels'
* it unpacks each bnode map it finds in it.
* `ext_map' is the external map used by the new bmaps.
* In `bmap_nodes' unpack_all_bmaps stores the address of the newly xmallocated
* array of u_int. Each bmap_nodes[x] contains the number of nodes of the bmap
* of level x.
* `maxbnodes' is the maximum number of nodes each bmap can contain,
* while `maxbnode_rnodeblock' is the maximum number of rnodes each node can
* contain.
* On error 0 is returned.
* Note: `pack' will be modified during the unpacking.
*/
map_bnode **
unpack_all_bmaps(char *pack, u_char max_levels, map_gnode **ext_map,
u_int **bmap_nodes, int maxbnodes, int maxbnode_rnodeblock)
{
struct bnode_maps_hdr *bmaps_hdr;
struct bnode_map_hdr *bmap_hdr;
map_bnode **bmap, *unpacked_bmap;
size_t bblock_sz, pack_sz;
int i,e=0;
char *bblock, *buf;
u_char levels;
bmaps_hdr=(struct bnode_maps_hdr *)pack;
ints_network_to_host(bmaps_hdr, bnode_maps_hdr_iinfo);
levels=bmaps_hdr->levels;
pack_sz=bmaps_hdr->bmaps_block_sz;
if(levels > max_levels || pack_sz < sizeof(struct bnode_maps_hdr))
return 0;
bmap_levels_init(levels, &bmap, bmap_nodes);
buf=pack+sizeof(struct bnode_maps_hdr);
for(i=0; i<levels; i++) {
bmap_hdr=(struct bnode_map_hdr *)buf;
if(!bmap_hdr->bnode_map_sz) {
buf+=sizeof(struct bnode_map_hdr);
continue;
}
/*Extracting the map...*/
bblock=(char *)bmap_hdr;
unpacked_bmap=unpack_map(bblock, (int *)ext_map[_EL(i+1)], 0,
maxbnodes, maxbnode_rnodeblock);
if(!unpacked_bmap) {
error("Cannot unpack the bnode_map at level %d ! Skipping...", i);
e++;
continue;
}
(*bmap_nodes)[i]=bmap_hdr->bnode_map_sz/MAP_BNODE_PACK_SZ;
bblock_sz=INT_MAP_BLOCK_SZ(bmap_hdr->bnode_map_sz, bmap_hdr->rblock_sz);
bmap[i]=unpacked_bmap;
buf+=bblock_sz;
}
if(e == levels)
/* Not a single map was restored */
return 0;
return bmap;
}
/* * * save/load bnode_map * * */
/*
* save_bmap: It saves the bnode maps `bmaps' in `file'. The each `bmaps[x]' has
* `bmap_nodes[x]' nodes. `ext_map' is the pointer to the external map the bmap is
* referring to.
*/
int save_bmap(map_bnode **bmaps, u_int *bmap_nodes, map_gnode **ext_map,
quadro_group quadg, char *file)
{
FILE *fd;
char *pack;
size_t pack_sz;
pack=pack_all_bmaps(bmaps, bmap_nodes, ext_map, quadg, &pack_sz);
if(!pack_sz || !pack)
return 0;
if((fd=fopen(file, "w"))==NULL) {
error("Cannot save the bnode_map in %s: %s", file, strerror(errno));
return -1;
}
fwrite(pack, pack_sz, 1, fd);
xfree(pack);
fclose(fd);
return 0;
}
/*
* load_bmap: It loads all the bnode maps from `file' and returns the address
* of the array of pointer to the loaded bmaps. `ext_map' is the external maps
* the bmap shall refer to. In `bmap_nodes' the address of the u_int array, used
* to count the nodes in each bmaps, is stored. On error 0 is returned.
*/
map_bnode **load_bmap(char *file, map_gnode **ext_map, u_char max_levels, u_int **bmap_nodes)
{
map_bnode **bmap=0;
FILE *fd;
struct bnode_maps_hdr bmaps_hdr;
size_t pack_sz;
u_char levels;
char *pack=0;
if((fd=fopen(file, "r"))==NULL) {
error("Cannot load the bmap from %s: %s", file, strerror(errno));
return 0;
}
if(!fread(&bmaps_hdr, sizeof(struct bnode_maps_hdr), 1, fd))
goto finish;
ints_network_to_host(&bmaps_hdr, bnode_maps_hdr_iinfo);
levels=bmaps_hdr.levels;
pack_sz=bmaps_hdr.bmaps_block_sz;
if(levels > max_levels || pack_sz < sizeof(struct bnode_maps_hdr))
goto finish;
/* Extracting the map... */
rewind(fd);
pack=xmalloc(pack_sz);
if(!fread(pack, pack_sz, 1, fd))
goto finish;
bmap=unpack_all_bmaps(pack, max_levels, ext_map, bmap_nodes,
MAXGROUPNODE, MAXBNODE_RNODEBLOCK);
finish:
fclose(fd);
if(pack)
xfree(pack);
if(!bmap)
error("Malformed bmap file. Cannot load the bnode maps.");
return bmap;
}

169
src/bmap.h Normal file
View File

@ -0,0 +1,169 @@
/* This file is part of Netsukuku system
* (c) Copyright 2004 Andrea Lo Pumo aka AlpT <alpt@freaknet.org>
*
* This source code 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 2 of the License,
* or (at your option) any later version.
*
* This source code 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.
* Please refer to the GNU Public License for more details.
*
* You should have received a copy of the GNU Public License along with
* this source code; if not, write to:
* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef BMAP_H
#define BMAP_H
#include "gmap.h"
#define BMAP_UPDATE MAP_UPDATE /* At each new qspn_round all the bnodes flags are set
to BMAP_UPDATE, thus when tracer_store_pkt() updates
them for the first time during the new round, it
deletes their rnodes. */
/*
* map_bnode is the struct used to create the "map border node".
* This map keeps all the border node of the map, making it easy to retrieve
* the gnode they are linked to.
* It is indentical to the map_node but, as always there are some little
* differences:
*
* uint16_t links; is the number of gnodes the bnode is
* linked to.
* map_rnode *r_node; r_node[x].r_node, in this case, points
* to the position of the bnode's gnode in
* the ext_map.
* u_int brdcast; Where this node is in the int/ext_map.
* The position is stored in the usual
* pos_from_node() format. (Yep, a dirty hack)
*
* So you are asking why I didn't made a new struct for the bmap. Well, I don't
* want to [re]write all the functions to handle the map, for example
* rnode_add,rnode_del, save_map, etc... it's a pain, just for a little map and
* moreover it adds new potential bugs. In conclusion: laziness + fear == hacks++;
*
*/
typedef map_node map_bnode;
#define MAP_BNODE_PACK_SZ MAP_NODE_PACK_SZ
#define MAXGROUPBNODE MAXGROUPNODE /*the maximum number of bnodes in
a gnode is equal to the maximum
number of nodes*/
#define MAXBNODE_LINKS (MAXGROUPNODE*2)/*The maximum number of gnodes a
bnode is linked to*/
#define MAXBNODE_RNODEBLOCK (MAXBNODE_LINKS*MAXGROUPBNODE*MAP_RNODE_PACK_SZ)
/*
* These defines make the life easier, so instead of writing int_map_hdr I
* write bnode_map_hdr. Cool eh? ^_^.
*/
#define bnode_ptr brdcast /*Don't kill me*/
#define bnode_map_hdr int_map_hdr
#define bnode_map_sz int_map_sz
/*
* The bnode map uses only `me.cur_quadg.levels-1' levels, because each level of
* the bmap points to the upper one, therefore the last level is ignored.
*/
#define BMAP_LEVELS(levels) (levels-1)
#define BMAP_MAX_LEVELS (BMAP_LEVELS(MAX_LEVELS))
#define GET_BMAP_LEVELS(family) (BMAP_LEVELS(GET_LEVELS((family))))
/*
* border node block: this is the block which keeps the gnodes linked to the
* `bnode' border_node. When a bnode has to add his entry in the tracer_pkt it
* encapsulates the bnode_block at the end of the packet, in this way it is
* possible to know all the gnodes linked to the bnode's gnode.
* Note: It is possible that the packet passes trough many bnodes, in this case
* the bnode block is always put at the end, ex:
* |pkt_hdr|brdcast_hdr|tracer_hdr|tracer_chunks|bnode_hdr|bnode_chunks|bnode_hdr|bnode_chunks|...
* and so on.
*
* The bblock is also used to store the Internet gateways, see igs.h for more
* details.
*/
typedef struct
{
u_char bnode_levels;
u_short links; /*The number of linked gnode*/
}_PACKED_ bnode_hdr;
INT_INFO bnode_hdr_iinfo = { 1, { INT_TYPE_16BIT }, { sizeof(char) }, { 1 } };
/*
* This is part of the bnode_hdr.
*
* u_char bnode[bnode_levels]; The bnode this bnode_block belongs to.
*/
#define BNODE_HDR_SZ(levels) (sizeof(bnode_hdr)+sizeof(u_char)*(levels))
typedef struct
{
/* The `bnode_hdr.bnode' borders on the `gnode' of `level'th level with
* a round trip time which is stored in `rtt'. */
u_char gnode;
u_char level;
u_int rtt;
}_PACKED_ bnode_chunk;
#define BNODEBLOCK_SZ(levels, links) (BNODE_HDR_SZ((levels)) + \
(sizeof(bnode_chunk)*(links)))
INT_INFO bnode_chunk_iinfo = { 1, { INT_TYPE_32BIT }, { sizeof(char)*2 }, { 1 } };
/*
* This is the header placed on top of all the bnode_map blocks.
* So the bnode maps final block is:
*
* bnode_maps_hdr
*
* ---------
* bnode_map_hdr
* bnode_map_block
* ---------
* bnode_map_hdr
* bnode_map_block
* ---------
*
* ...
*/
struct bnode_maps_hdr
{
u_char levels;
size_t bmaps_block_sz;
}_PACKED_;
INT_INFO bnode_maps_hdr_iinfo = { 1, { INT_TYPE_32BIT }, { sizeof(char) }, { 1 } };
/* * * Functions' declaration * * */
void bmap_levels_init(u_char levels, map_bnode ***bmap, u_int **bmap_nodes);
void bmap_levels_free(map_bnode **bmap, u_int *bmap_nodes);
void bmap_counter_init(u_char levels, u_int **bnodes_closed, u_int **bnodes_opened);
void bmap_counter_free(u_int *bnodes_closed, u_int *bnodes_opened);
void bmap_counter_reset(u_char levels, u_int *counter);
int map_add_bnode(map_bnode **bmap, u_int *bmap_nodes, u_int bnode, u_int links);
map_bnode *map_bnode_del(map_bnode *bmap, u_int *bmap_nodes, map_bnode *bnode);
int bmap_del_rnode_by_level(map_bnode *, int, map_gnode **, int);
int map_find_bnode(map_bnode *bmap, int bmap_nodes, int node);
int map_find_bnode_rnode(map_bnode *bmap, int bmap_nodes, void *n);
int map_count_bnode_rnode(map_bnode *bmap, int bmap_nodes, void *n);
int bmaps_count_bnode_rnode(map_bnode **bmap, int *bmap_nodes, int levels, void *n);
int map_del_bnode_rnode(map_bnode **bmap, int *bmap_nodes, void *n);
int bmaps_del_bnode_rnode(map_bnode **bmap, int *bmap_nodes, int levels, void *n);
void map_set_bnode_flag(map_bnode *bmap, int bmap_nodes, int flags);
void bmaps_set_bnode_flag(map_bnode **bmap, int *bmap_nodes, int levels, int flags);
char *pack_all_bmaps(map_bnode **, u_int *, map_gnode **, quadro_group, size_t *);
map_bnode **unpack_all_bmaps(char *, u_char, map_gnode **, u_int **, int, int);
int save_bmap(map_bnode **, u_int *, map_gnode **, quadro_group, char *);
map_bnode **load_bmap(char *, map_gnode **, u_char, u_int **);
#endif /*BMAP_H*/

36
src/buffer.c Normal file
View File

@ -0,0 +1,36 @@
/* This file is part of Netsukuku
* (c) Copyright 2005 Andrea Lo Pumo aka AlpT <alpt@freaknet.org>
*
* This source code 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 2 of the License,
* or (at your option) any later version.
*
* This source code 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.
* Please refer to the GNU Public License for more details.
*
* You should have received a copy of the GNU Public License along with
* this source code; if not, write to:
* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* --
* buffer.c: various functions to manipulate buffers
*/
/*
* is_bufzero
*
* Is the buffer `a' filled with `sz'# of zeros?
* If yes return 1.
*/
int is_bufzero(const void *a, int sz)
{
const char *p=a;
int i;
for(i=0; i<sz; i++, p++)
if(*p)
return 0;
return 1;
}

76
src/buffer.h Normal file
View File

@ -0,0 +1,76 @@
/* This file is part of Netsukuku
* (c) Copyright 2005 Andrea Lo Pumo aka AlpT <alpt@freaknet.org>
*
* This source code 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 2 of the License,
* or (at your option) any later version.
*
* This source code 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.
* Please refer to the GNU Public License for more details.
*
* You should have received a copy of the GNU Public License along with
* this source code; if not, write to:
* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* --
* buffer.c: various functions to manipulate buffers
*/
#ifndef BUFFER_H
#define BUFFER_H
/*
* In bzero(3):
* <<4.3BSD. This function [bzero] is deprecated -- use memset in new
* programs.>>
*/
#define setzero(_p, _sz) memset((_p), 0, (_sz))
/*
* memput
*
* It copies `__sz' bytes from `__src' to `__dst' and then increments the `__dst'
* pointer of `__sz' bytes.
*
* *WARNING*
* Do NOT put expression in `__dst', and `__sz', f.e.
* *WRONG CODE*
* memput(buf++, src, (size+=sizeof(src));
*
* *CORRECT CODE*
* buf++; size+=sizeof(src);
* memput(buf, src, size);
* *WARNING*
*/
#define memput(__dst, __src, __sz) \
({ \
void *_bufret=memcpy((__dst), (__src), (__sz)); \
(__dst)+=(__sz); \
_bufret; \
})
/*
* memget
*
* the same of memput(), but it increments `__src' instead.
*/
#define memget(__dst, __src, __sz) \
({ \
void *_bufret=memcpy((__dst), (__src), (__sz)); \
(__src)+=(__sz); \
_bufret; \
})
/* use of hardcoded `_src' and `_dst' variable names */
#define bufput(_src, _sz) (memput(buf, (_src), (_sz)))
#define bufget(_dst, _sz) (memget((_dst), buf, (_sz)))
/*\
* * * * Functions declaration * * *
\*/
int is_bufzero(const void *a, int sz);
#endif /*BUFFER_H*/

9
src/common.h Normal file
View File

@ -0,0 +1,9 @@
#ifndef COMMON_H
#define COMMON_H
#include "misc.h"
#include "buffer.h"
#include "xmalloc.h"
#include "log.h"
#endif

136
src/conf.c Normal file
View File

@ -0,0 +1,136 @@
/* This file is part of Netsukuku
* (c) Copyright 2005 Andrea Lo Pumo aka AlpT <alpt@freaknet.org>
*
* This source code 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 2 of the License,
* or (at your option) any later version.
*
* This source code 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.
* Please refer to the GNU Public License for more details.
*
* You should have received a copy of the GNU Public License along with
* this source code; if not, write to:
* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* --
* conf.c:
* Configuration file loader and parser. All the accepted option. which are
* listed in conf.h, are put in the environment for later retrievement.
*/
#include "includes.h"
#include <ctype.h>
#include "common.h"
#include "conf.h"
/*
* clear_config_env
*
* do not make the environment dirty
*/
void clear_config_env(void)
{
int i;
for(i=0; config_str[i][0]; i++)
if(getenv(config_str[i]))
unsetenv(config_str[i]);
}
/*
* parse_config_line: it reads the `line' string and sees if it has a valid
* option assignment that is in the form of "option = value".
* On success it stores the option name with its value in the environment.
* On failure fatal() is called, so it will never return ;)
* `file' and `pos' are used by fatal() to tell where the corrupted `line' was.
*/
void parse_config_line(char *file, int pos, char *line)
{
int i, e=0;
char *value;
if(!(value=strchr(line, '=')))
fatal("The line %s:%d is invalid, it does not contain the '=' "
"character. Aborting.", file, pos);
for(i=0; config_str[i][0]; i++)
if(strstr(line, config_str[i])) {
e=1;
break;
}
if(!e)
fatal("The line %s:%d does not contain a valid option. Aborting.",
file, pos);
value++;
while(isspace(*value))
value++;
if(setenv(config_str[i], value, 1))
fatal("Error in line %s:%d: %s. Aborting.", file, pos,
strerror(errno));
}
/*
* load_config_file: loads from `file' all the options that are written in it
* and stores them in the environment. See parse_config_line() above.
* If `file' cannot be opened -1 is returned, but if it is read and
* parse_config_line() detects a corrupted line, fatal() is directly called.
* On success 0 is returned.
*/
int load_config_file(char *file)
{
FILE *fd;
char buf[PATH_MAX+1], *p, *str;
size_t slen;
int i=0, e=0;
if(!(fd=fopen(file, "r"))) {
fatal("Cannot load the configuration file from %s: %s\n"
" Maybe you want to use the -c option ?",
file, strerror(errno));
return -1;
}
while(!feof(fd) && i < CONF_MAX_LINES) {
setzero(buf, PATH_MAX+1);
fgets(buf, PATH_MAX, fd);
e++;
if(feof(fd))
break;
str=buf;
while(isspace(*str))
str++;
if(*str=='#' || !*str) {
/* Strip off any comment or null lines */
continue;
} else {
/* Remove the last part of the string where a side
* comment starts, #a comment like this.
*/
if((p=strrchr(str, '#')))
*p='\0';
/* Don't include the newline and spaces of the end of
* the string */
slen=strlen(str);
for(p=&str[slen-1]; isspace(*p); p--)
*p='\0';
parse_config_line(file, e, str);
i++;
}
}
fclose(fd);
return 0;
}

120
src/conf.h Normal file
View File

@ -0,0 +1,120 @@
/* This file is part of Netsukuku
* (c) Copyright 2005 Andrea Lo Pumo aka AlpT <alpt@freaknet.org>
*
* This source code 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 2 of the License,
* or (at your option) any later version.
*
* This source code 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.
* Please refer to the GNU Public License for more details.
*
* You should have received a copy of the GNU Public License along with
* this source code; if not, write to:
* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef CONF_H
#define CONF_H
#define CONF_MAX_LINES 500 /* Max number of option lines */
#define CONF_GET_VALUE(opt) (getenv(config_str[(opt)]))
#define CONF_GET_INT_VALUE(opt, n) \
({ \
char *_val; \
_val=CONF_GET_VALUE((opt)); \
if(_val) \
(n)=atoi(_val); \
})
#define CONF_GET_STRN_VALUE(opt, str, maxbytes) \
({ \
char *_val; \
_val=CONF_GET_VALUE((opt)); \
if(_val) \
*(str)=xstrndup(_val, (maxbytes)); \
})
/*
* The allowed options in the configuration file
*/
enum config_options
{
CONF_NTK_INT_MAP_FILE,
CONF_NTK_BNODE_MAP_FILE,
CONF_NTK_EXT_MAP_FILE,
CONF_ANDNA_HNAMES_FILE,
CONF_SNSD_NODES_FILE,
CONF_ANDNA_CACHE_FILE,
CONF_ANDNA_LCLKEY_FILE,
CONF_ANDNA_LCL_FILE,
CONF_ANDNA_RHC_FILE,
CONF_ANDNA_COUNTER_C_FILE,
CONF_NTK_PID_FILE,
CONF_NTK_MAX_CONNECTIONS,
CONF_NTK_MAX_ACCEPTS_PER_HOST,
CONF_NTK_MAX_ACCEPTS_PER_HOST_TIME,
CONF_DISABLE_ANDNA,
CONF_DISABLE_RESOLVCONF,
CONF_NTK_RESTRICTED_MODE,
CONF_NTK_RESTRICTED_CLASS,
CONF_NTK_INTERNET_CONNECTION,
CONF_NTK_INTERNET_GW,
CONF_NTK_INTERNET_UPLOAD,
CONF_NTK_INTERNET_DOWNLOAD,
CONF_NTK_INTERNET_PING_HOSTS,
CONF_SHARE_INTERNET,
CONF_SHAPE_INTERNET,
CONF_USE_SHARED_INET,
CONF_NTK_IP_MASQ_SCRIPT,
CONF_NTK_TC_SHAPER_SCRIPT,
};
const static char config_str[][30]=
{
{ "ntk_int_map_file" },
{ "ntk_bnode_map_file" },
{ "ntk_ext_map_file" },
{ "andna_hnames_file" },
{ "snsd_nodes_file" },
{ "andna_cache_file" },
{ "andna_lclkey_file" },
{ "andna_lcl_file" },
{ "andna_rhc_file" },
{ "andna_counter_c_file" },
{ "pid_file" },
{ "ntk_max_connections" },
{ "ntk_max_accepts_per_host" },
{ "max_accepts_per_host_time" },
{ "disable_andna" },
{ "disable_resolvconf" },
{ "ntk_restricted_mode" },
{ "ntk_restricted_class" },
{ "internet_connection" },
{ "internet_gateway" },
{ "internet_upload_rate" },
{ "internet_download_rate" },
{ "internet_ping_hosts" },
{ "share_internet" },
{ "shape_internet" },
{ "use_shared_internet" },
{ "ip_masquerade_script" },
{ "tc_shaper_script" },
{ 0 },
};
void clear_config_env(void);
int load_config_file(char *file);
#endif /*CONF_H*/

1
src/conf/Makefile.am Normal file
View File

@ -0,0 +1 @@
sysconf_DATA = netsukuku.conf andna_hostnames snsd_nodes

321
src/conf/Makefile.in Normal file
View File

@ -0,0 +1,321 @@
# Makefile.in generated by automake 1.8.5 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
# 2003, 2004 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
VPATH = @srcdir@
pkgdatadir = $(datadir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
top_builddir = ../..
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
INSTALL = @INSTALL@
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
host_triplet = @host@
subdir = src/conf
DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in \
$(srcdir)/netsukuku.conf.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(mkdir_p)
CONFIG_HEADER = $(top_builddir)/src/config.h
CONFIG_CLEAN_FILES = netsukuku.conf
SOURCES =
DIST_SOURCES =
am__installdirs = "$(DESTDIR)$(sysconfdir)"
sysconfDATA_INSTALL = $(INSTALL_DATA)
DATA = $(sysconf_DATA)
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMDEP_FALSE = @AMDEP_FALSE@
AMDEP_TRUE = @AMDEP_TRUE@
AMTAR = @AMTAR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CONF_DIR = @CONF_DIR@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DATA_DIR = @DATA_DIR@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
IF_METHOD = @IF_METHOD@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
KERNEL_METHOD = @KERNEL_METHOD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LTLIBOBJS = @LTLIBOBJS@
MAKEINFO = @MAKEINFO@
OBJEXT = @OBJEXT@
OTHER_METHOD = @OTHER_METHOD@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PID_DIR = @PID_DIR@
RT_METHOD = @RT_METHOD@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_STRIP = @ac_ct_STRIP@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
debug_flags = @debug_flags@
exec_prefix = @exec_prefix@
gmp = @gmp@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
prefix = @prefix@
program_transform_name = @program_transform_name@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
sysconf_DATA = netsukuku.conf andna_hostnames snsd_nodes
all: all-am
.SUFFIXES:
$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
&& exit 0; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/conf/Makefile'; \
cd $(top_srcdir) && \
$(AUTOMAKE) --gnu src/conf/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
netsukuku.conf: $(top_builddir)/config.status $(srcdir)/netsukuku.conf.in
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
uninstall-info-am:
install-sysconfDATA: $(sysconf_DATA)
@$(NORMAL_INSTALL)
test -z "$(sysconfdir)" || $(mkdir_p) "$(DESTDIR)$(sysconfdir)"
@list='$(sysconf_DATA)'; for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
f="`echo $$p | sed -e 's|^.*/||'`"; \
echo " $(sysconfDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(sysconfdir)/$$f'"; \
$(sysconfDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(sysconfdir)/$$f"; \
done
uninstall-sysconfDATA:
@$(NORMAL_UNINSTALL)
@list='$(sysconf_DATA)'; for p in $$list; do \
f="`echo $$p | sed -e 's|^.*/||'`"; \
echo " rm -f '$(DESTDIR)$(sysconfdir)/$$f'"; \
rm -f "$(DESTDIR)$(sysconfdir)/$$f"; \
done
tags: TAGS
TAGS:
ctags: CTAGS
CTAGS:
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
case $$file in \
$(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
$(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
esac; \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
if test "$$dir" != "$$file" && test "$$dir" != "."; then \
dir="/$$dir"; \
$(mkdir_p) "$(distdir)$$dir"; \
else \
dir=''; \
fi; \
if test -d $$d/$$file; then \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
fi; \
cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
else \
test -f $(distdir)/$$file \
|| cp -p $$d/$$file $(distdir)/$$file \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(DATA)
installdirs:
for dir in "$(DESTDIR)$(sysconfdir)"; do \
test -z "$$dir" || $(mkdir_p) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
`test -z '$(STRIP)' || \
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
mostlyclean-generic:
clean-generic:
distclean-generic:
-rm -f $(CONFIG_CLEAN_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic mostlyclean-am
distclean: distclean-am
-rm -f Makefile
distclean-am: clean-am distclean-generic
dvi: dvi-am
dvi-am:
html: html-am
info: info-am
info-am:
install-data-am:
install-exec-am: install-sysconfDATA
install-info: install-info-am
install-man:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-generic
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-info-am uninstall-sysconfDATA
.PHONY: all all-am check check-am clean clean-generic distclean \
distclean-generic distdir dvi dvi-am html html-am info info-am \
install install-am install-data install-data-am install-exec \
install-exec-am install-info install-info-am install-man \
install-strip install-sysconfDATA installcheck installcheck-am \
installdirs maintainer-clean maintainer-clean-generic \
mostlyclean mostlyclean-generic pdf pdf-am ps ps-am uninstall \
uninstall-am uninstall-info-am uninstall-sysconfDATA
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

6
src/conf/SConscript Normal file
View File

@ -0,0 +1,6 @@
Import('env')
idir_conf = '$destdir' + '$CONF_DIR'
env.Install(idir_conf, ['netsukuku.conf', 'andna_hostnames', 'snsd_nodes'])
env.Alias('install', [idir_conf])

16
src/conf/andna_hostnames Normal file
View File

@ -0,0 +1,16 @@
#
# ANDNA hostnames
#
#
# In this file you can list, one per line, all the hostnames you want to
# register in ANDNA.
#
# You can register up to 256 hostnames. Each hostname can be a string of
# maximum 512 bytes, which contains a newline (\n) only at its end.
#
# Read: man andna
#
# *WARNING* DO NOT LEAVE EMPTY LINES WITH SPACES OR TABS, *WARNING*
# THEY WILL BE REGISTERED AS REAL HOSTNAMES
#my_cool_hostname

199
src/conf/netsukuku.conf.in Normal file
View File

@ -0,0 +1,199 @@
#
# NetsukukuD @VERSION@
#
#
# The comments starts with a '#'.
# To use a default option leave its line commented.
# Use always the '=' to assign a value.
#
# Note: the options will be overridden by their command line equivalent.
#
# Options index:
#
# ## Restricted mode
# - ntk_restricted_mode
# - ntk_restricted_class
# ## Internet connection
# - internet_connection
# - internet_gateway
# - internet_download_rate
# - internet_upload_rate
# - internet_ping_hosts
# - share_internet
# - shape_internet
# - use_shared_internet
# ## ANDNA
# - disable_andna
# - disable_resolvconf
# ## Limits
# - ntk_max_connections
# - ntk_max_accepts_per_host
# - max_accepts_per_host_time
# ## Files
# - pid_file
# - ntk_ext_map_file
# - ntk_int_map_file
# - ntk_bnode_map_file
# - andna_hnames_file
# - snsd_nodes_file
# - andna_cache_file
# - andna_lclkey_file
# - andna_lcl_file
# - andna_rhc_file
# - andna_counter_c_file
# - ip_masquerade_script
# - tc_shaper_script
#
##
#### Restricted mode
##
#
# If the `ntk_restricted_mode' option is set to 1, NetsukukuD will be started
# in restricted mode to be compatible with Internet. In the restricted mode,
# only IPs of the largest private subnet (i.e. 10.x.x.x) are chosen.
#
# If `ntk_restricted_class' is set to 1 the IPs will be chosen from the
# 172.16.0.0-172.31.255.255 range (use this option only if you can't use the
# 10.x.x.x class).
#
#ntk_restricted_mode = 0
#ntk_restricted_class = 0
##
#### Internet connection
##
#
# * * If you have an Internet connection please fill this options. * *
#
# We are assuming that you are running in restricted mode since you want to
# be both in Netsukuku and Internet. So, if you have an internet connection
# set `internet_connection' to 1. Note that ntkd will overwrite any default
# route if this option is set to 0 and the shared Internet connections of
# other nodes are used.
#
# Set the `internet_gateway' option to the IP of the gateway you use to reach
# the Internet and specify the network interface too, for example:
# "internet_gateway = 192.168.1.1:eth0". This option is necessary only if you
# don't have the default route set when you run NetsukukuD (i.e. you haven't
# connected yet), otherwise, leave it commented.
#
# You have also to set your upload and download bandwidth in
# `internet_upload_rate' and `internet_download_rate'. It is expressed in Kb/s,
# so if you have a line which maximum can do: 640 Kb/s in dwload and 30 Kb/s in
# upload, set them to 640 and 30.
#
# `internet_ping_hosts' is a list of Internet hosts which will be pinged to
# verify if the connection is alive, you can use the default hosts.
#
# If you want to share your Internet connection among other Netsukuku nodes,
# set `share_internet' to 1.
#
# Set `shape_internet' to 1 if you want to shape your outgoing
# Internet traffic.
#
# `use_shared_internet' specifies if you want to use the Internet connections
# shared by the Netsukuku nodes. Set it to 0, if you want to rely only on your
# connection (if any).
#
#internet_connection = 1
#internet_gateway = 192.168.1.1:eth0
internet_download_rate = 640
internet_upload_rate = 30
internet_ping_hosts = google.com:cisco.com:sourceforge.net:dyne.org
#share_internet = 1
#shape_internet = 1
#use_shared_internet = 1
##
#### ANDNA
##
#
# To disable the start of the ANDNA daemon at the launch of ntkd, set
# this option to 1. Note that when the ANDNA daemon is disabled, the andna
# system will not work at all, so it will be impossible to resolve, register
# or update hostnames.
#
#disable_andna = 0
#
# When NetsukukuD starts it modifies /etc/resolv.conf writing in the first
# line "nameserver 127.0.0.1". The old /etc/resolv.conf is copied in
# /etc/resolv.conf.bak. When the daemon is closed /etc/resolv.conf is
# restored. If you want to disable this set disable_resolvconf to 1.
# If it is disabled you won't be able to resolve hostnames!
#
#disable_resolvconf = 0
##
#### Limits
##
#
# How many connection the netsukuku daemons can simultaneusly handle.
#
#ntk_max_connections = 512
# How many simultaneusly connections to the daemons from a single host are
# allowed.
#ntk_max_accepts_per_host = 16
# The wait time necessary for a host to reconnect to the daemons after all the
# ntk_max_accepts_per_host were used.
#
#max_accepts_per_host_time = 4 #in seconds
##
#### Files
##
#
# ntkd will save its process id in this file
#
#pid_file = @PID_DIR@/ntkd.pid
#
# The paths of the Netsukuku maps saved by the daemon
#
#ntk_ext_map_file = @DT_DIR@/ext_map_file
#ntk_int_map_file = @DT_DIR@/int_map_file
#ntk_bnode_map_file = @DT_DIR@/bnode_map_file
#
# The hostnames that will be registered in ANDNA are kept, one per line, in
# this file.
#
#andna_hnames_file = @CONF_DIR@/andna_hostnames
#
# The snsd_nodes_file keeps the list of the SNSD records which will be
# register in ANDNA.
#
#snsd_nodes_file = @CONF_DIR@/snsd_nodes
#
# Caches used by the ANDNA daemon
#
#andna_cache_file = @DT_DIR@/andna_cache
#andna_lclkey_file = @DT_DIR@/andna_lcl_keyring
#andna_lcl_file = @DT_DIR@/andna_lcl_cache
#andna_rhc_file = @DT_DIR@/andna_rh_cache
#andna_counter_c_file = @DT_DIR@/andna_counter_cache
#
# The script launched by NetsukukuD to share the Internet connection
#
#ip_masquerade_script = @CONF_DIR@/ip_masquerade.sh
#
# The script launched by NetsukukuD to shape the Internet connection
#
#tc_shaper_script = @CONF_DIR@/tc_shaper.sh

199
src/conf/ntk_scons.conf.in Normal file
View File

@ -0,0 +1,199 @@
#
# NetsukukuD %(VERSION)s
#
#
# The comments starts with a '#'.
# To use a default option leave its line commented.
# Use always the '=' to assign a value.
#
# Note: the options will be overridden by their command line equivalent.
#
# Options index:
#
# ## Restricted mode
# - ntk_restricted_mode
# - ntk_restricted_class
# ## Internet connection
# - internet_connection
# - internet_gateway
# - internet_download_rate
# - internet_upload_rate
# - internet_ping_hosts
# - share_internet
# - shape_internet
# - use_shared_internet
# ## ANDNA
# - disable_andna
# - disable_resolvconf
# ## Limits
# - ntk_max_connections
# - ntk_max_accepts_per_host
# - max_accepts_per_host_time
# ## Files
# - pid_file
# - ntk_ext_map_file
# - ntk_int_map_file
# - ntk_bnode_map_file
# - andna_hnames_file
# - snsd_nodes_file
# - andna_cache_file
# - andna_lclkey_file
# - andna_lcl_file
# - andna_rhc_file
# - andna_counter_c_file
# - ip_masquerade_script
# - tc_shaper_script
#
##
#### Restricted mode
##
#
# If the `ntk_restricted_mode' option is set to 1, NetsukukuD will be started
# in restricted mode to be compatible with Internet. In the restricted mode,
# only IPs of the largest private subnet (i.e. 10.x.x.x) are chosen.
#
# If `ntk_restricted_class' is set to 1 the IPs will be chosen from the
# 172.16.0.0-172.31.255.255 range (use this option only if you can't use the
# 10.x.x.x class).
#
#ntk_restricted_mode = 0
#ntk_restricted_class = 0
##
#### Internet connection
##
#
# * * If you have an Internet connection please fill this options. * *
#
# We are assuming that you are running in restricted mode since you want to
# be both in Netsukuku and Internet. So, if you have an internet connection
# set `internet_connection' to 1. Note that ntkd will overwrite any default
# route if this option is set to 0 and the shared Internet connections of
# other nodes are used.
#
# Set the `internet_gateway' option to the IP of the gateway you use to reach
# the Internet and specify the network interface too, for example:
# "internet_gateway = 192.168.1.1:eth0". This option is necessary only if you
# don't have the default route set when you run NetsukukuD (i.e. you haven't
# connected yet), otherwise, leave it commented.
#
# You have also to set your upload and download bandwidth in
# `internet_upload_rate' and `internet_download_rate'. It is expressed in Kb/s,
# so if you have a line which maximum can do: 640 Kb/s in dwload and 30 Kb/s in
# upload, set them to 640 and 30.
#
# `internet_ping_hosts' is a list of Internet hosts which will be pinged to
# verify if the connection is alive, you can use the default hosts.
#
# If you want to share your Internet connection among other Netsukuku nodes,
# set `share_internet' to 1.
#
# Set `shape_internet' to 1 if you want to shape your outgoing
# Internet traffic.
#
# `use_shared_internet' specifies if you want to use the Internet connections
# shared by the Netsukuku nodes. Set it to 0, if you want to rely only on your
# connection (if any).
#
#internet_connection = 1
#internet_gateway = 192.168.1.1:eth0
internet_download_rate = 640
internet_upload_rate = 30
internet_ping_hosts = google.com:cisco.com:sourceforge.net:dyne.org
#share_internet = 1
#shape_internet = 1
#use_shared_internet = 1
##
#### ANDNA
##
#
# To disable the start of the ANDNA daemon at the launch of ntkd, set
# this option to 1. Note that when the ANDNA daemon is disabled, the andna
# system will not work at all, so it will be impossible to resolve, register
# or update hostnames.
#
#disable_andna = 0
#
# When NetsukukuD starts it modifies /etc/resolv.conf writing in the first
# line "nameserver 127.0.0.1". The old /etc/resolv.conf is copied in
# /etc/resolv.conf.bak. When the daemon is closed /etc/resolv.conf is
# restored. If you want to disable this set disable_resolvconf to 1.
# If it is disabled you won't be able to resolve hostnames!
#
#disable_resolvconf = 0
##
#### Limits
##
#
# How many connection the netsukuku daemons can simultaneusly handle.
#
#ntk_max_connections = 512
# How many simultaneusly connections to the daemons from a single host are
# allowed.
#ntk_max_accepts_per_host = 16
# The wait time necessary for a host to reconnect to the daemons after all the
# ntk_max_accepts_per_host were used.
#
#max_accepts_per_host_time = 4 #in seconds
##
#### Files
##
#
# ntkd will save its process id in this file
#
#pid_file = %(PID_DIR)s/ntkd.pid
#
# The paths of the Netsukuku maps saved by the daemon
#
#ntk_ext_map_file = %(DATA_DIR)s/ext_map_file
#ntk_int_map_file = %(DATA_DIR)s/int_map_file
#ntk_bnode_map_file = %(DATA_DIR)s/bnode_map_file
#
# The hostnames that will be registered in ANDNA are kept, one per line, in
# this file.
#
#andna_hnames_file = %(CONF_DIR)s/andna_hostnames
#
# The snsd_nodes_file keeps the list of the SNSD records which will be
# register in ANDNA.
#
#snsd_nodes_file = %(CONF_DIR)s/snsd_nodes
#
# Caches used by the ANDNA daemon
#
#andna_cache_file = %(DATA_DIR)s/andna_cache
#andna_lclkey_file = %(DATA_DIR)s/andna_lcl_keyring
#andna_lcl_file = %(DATA_DIR)s/andna_lcl_cache
#andna_rhc_file = %(DATA_DIR)s/andna_rh_cache
#andna_counter_c_file = %(DATA_DIR)s/andna_counter_cache
#
# The script launched by NetsukukuD to share the Internet connection
#
#ip_masquerade_script = %(CONF_DIR)s/ip_masquerade.sh
#
# The script launched by NetsukukuD to shape the Internet connection
#
#tc_shaper_script = %(CONF_DIR)s/tc_shaper.sh

53
src/conf/snsd_nodes Normal file
View File

@ -0,0 +1,53 @@
#
# SNSD nodes file
#
# List, one per line, the SNSD records you want register in ANDNA.
#
# You can register up to 255 records and you can associate a maximum of 16
# records to a service.
#
# Each line must be in the following format:
#
# hostname:snsd_hostname:service:priority:weight[:pub_key_file]
# or
# hostname:snsd_ip:service:priority:weight[:pub_key_file]
#
#
# The `pub_key_file' parameter is optional. If you specify it, NetsukukuD will
# challenge periodically `snsd_hostname' and it will verify if it is always the
# same machine. If it isn't, the relative snsd will be deleted.
#
# `hostname' must be one of the hostnames listed in the andna_hostnames file.
#
# `snsd_hostname' is the hostname of the snsd_node. `snsd_ip' is, instead, its
# ip.
#
# `service' specifies the service of the snsd record. It is one of the
# service listed in /etc/services. It can be expressed also in numeric form.
# It is also possible to specify the protocol, f.e:
# "domain", "53", "53/udp", "domain/udp"
# are valid service strings.
#
# `priority' is an integer between 0 and 255, it specifies the "backup"
# priority of the snsd record.
#
# `weight' is an integer between 0 and 12, it specifies the "load balancing"
# weight of the snsd record.
#
# --
#
# The main IP associated to a normal hostname has these default values:
# IP = register_node IP # This value can't be changed
# service = 0
# priority = 16
# weight = 1
# If you want to modify the paremeters of the mainip use this syntax:
# hostname:hostname:0:priority:weight
# Only one line with this syntax is allowed, duplicates will be ignored.
#
#my_cool_hostname:mysnsdnode:http:23:2
#my_cool_hostname:1.2.4.5:21:1:4
#my_good_hostname:mysnsdnode:ssh:1:9:/etc/netsukuku/snsd/mgh.pubk
#another_hostname:anotherone:53/udp:1:4

106
src/config.h.in Normal file
View File

@ -0,0 +1,106 @@
/* src/config.h.in. Generated from configure.ac by autoheader. */
/* "Location of configuration files" */
#undef CONF_DIR
/* "Where the Netsukuku data is saved" */
#undef DATA_DIR
/* FreeBSD */
#undef FREEBSD
/* GNU Linux */
#undef GNU_LINUX
/* Define to 1 if you have the <gmp.h> header file. */
#undef HAVE_GMP_H
/* Define to 1 if you have the <inttypes.h> header file. */
#undef HAVE_INTTYPES_H
/* Define to 1 if you have the `kvm' library (-lkvm). */
#undef HAVE_LIBKVM
/* Define to 1 if you have the `nsl' library (-lnsl). */
#undef HAVE_LIBNSL
/* Define to 1 if you have the `socket' library (-lsocket). */
#undef HAVE_LIBSOCKET
/* Define to 1 if you have the `xnet' library (-lxnet). */
#undef HAVE_LIBXNET
/* Define to 1 if you have the <memory.h> header file. */
#undef HAVE_MEMORY_H
/* netlink */
#undef HAVE_NETLINK
/* NET_RT_IFLIST */
#undef HAVE_NET_RT_IFLIST
/* Define to 1 if you have the <openssl/crypto.h> header file. */
#undef HAVE_OPENSSL_CRYPTO_H
/* Define to 1 if you have the <pthread.h> header file. */
#undef HAVE_PTHREAD_H
/* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H
/* Define to 1 if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#undef HAVE_STRING_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/types.h> header file. */
#undef HAVE_SYS_TYPES_H
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
/* Define to 1 if you have the <zlib.h> header file. */
#undef HAVE_ZLIB_H
/* IRIX 6.5 */
#undef IRIX
/* OpenBSD */
#undef OPEN_BSD
/* Name of package */
#undef PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#undef PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#undef PACKAGE_NAME
/* Define to the full name and version of this package. */
#undef PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the version of this package. */
#undef PACKAGE_VERSION
/* ntkd.pid file location */
#undef PID_DIR
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* SunOS 5 */
#undef SUNOS
/* Version number of package */
#undef VERSION

10
src/config_scons.h.in Normal file
View File

@ -0,0 +1,10 @@
#define CONF_DIR "%(CONF_DIR)s"
#define DATA_DIR "%(DATA_DIR)s"
#define PID_DIR "%(PID_DIR)s"
#if %(debug)d
# undef DEBUG
# define DEBUG
#endif
#define VERSION "%(VERSION)s"

164
src/crypto.c Normal file
View File

@ -0,0 +1,164 @@
/* This file is part of Netsukuku
* (c) Copyright 2005 Andrea Lo Pumo aka AlpT <alpt@freaknet.org>
*
* This source code 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 2 of the License,
* or (at your option) any later version.
*
* This source code 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.
* Please refer to the GNU Public License for more details.
*
* You should have received a copy of the GNU Public License along with
* this source code; if not, write to:
* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* --
* crypto.c:
* front end to the OpenSSL cryptographic functions
*/
#include <openssl/bio.h>
#include <openssl/evp.h>
#include <openssl/crypto.h>
#include <openssl/md5.h>
#include <openssl/x509.h>
#include <openssl/err.h>
#include <openssl/rand.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include "crypto.h"
#include "log.h"
#include "xmalloc.h"
void init_crypto(void)
{
RAND_load_file("/dev/urandom", 1024);
ERR_load_crypto_strings();
}
void free_crypto(void)
{
ERR_free_strings();
}
char *ssl_strerr(void)
{
return ERR_error_string(ERR_get_error(), 0);
}
/*
* genrsa: generates a new rsa key pair and returns the private key in the RSA
* format. If `pub' is not null, it stores in it the pointer to a newly
* allocated dump of the public key that is `*pub_len' bytes. The same is for
* `priv' and `priv_len'.
* On error null is returned.
*/
RSA *genrsa(int key_bits, u_char **pub, u_int *pub_len, u_char **priv, u_int *priv_len)
{
RSA *rsa=0;
int len;
rsa=RSA_generate_key(key_bits, RSA_F4, NULL, NULL);
if (!rsa) {
debug(DBG_SOFT, "RSA key generation failed");
goto error;
}
if(priv) {
*priv=0;
len=i2d_RSAPrivateKey(rsa, priv);
if(priv_len)
*priv_len=len;
if(len <= 0) {
debug(DBG_SOFT, "Cannot dump RSA public key: %s", ssl_strerr());
goto error;
}
}
if(pub) {
*pub=0;
len=i2d_RSAPublicKey(rsa, pub);
if(pub_len)
*pub_len=len;
if(len <= 0) {
debug(DBG_SOFT, "Cannot dump RSA public key: %s", ssl_strerr());
goto error;
}
}
return rsa;
error:
if(rsa)
RSA_free(rsa);
return 0;
}
/*
* get_rsa_pub
*
* Converts a dump of a rsa pub key to a RSA structure, which is returned.
* Remeber to RSA_free() the returned key.
*/
RSA *get_rsa_pub(const u_char **pub_key, long length)
{
return d2i_RSAPublicKey(NULL, pub_key, length);
}
/*
* get_rsa_priv
*
* Converts a dump of a rsa priv key to a RSA structure, which is returned.
* Remeber to RSA_free() the returned key.
*/
RSA *get_rsa_priv(const u_char **priv_key, long length)
{
return d2i_RSAPrivateKey(NULL, priv_key, length);
}
u_char *hash_sha1(u_char *msg, u_int m_len, u_char *hash)
{
return SHA1(msg, m_len, hash);
}
u_char *hash_md5(u_char *msg, u_int m_len, u_char *hash)
{
return MD5(msg, m_len, hash);
}
/*
* rsa_sign: It signs the given message `msg' and returns its newly allocated
* signature. In `siglen' it stores the signature's lenght.
* On error null is returned.
*/
u_char *rsa_sign(u_char *msg, u_int m_len, RSA *priv, u_int *siglen)
{
u_char *signature;
int ret, len;
ret=RSA_size(priv);
if(!ret)
return 0;
signature=(u_char *)xmalloc(ret);
ret=RSA_sign(NID_sha1, hash_sha1(msg, m_len, 0), SHA_DIGEST_LENGTH,
signature,(u_int*) &len, priv);
if(siglen)
*siglen=len;
return !ret ? 0 : signature;
}
/*
* verify_sign: verifies the rsa `signature' of `msg'.
* It returns 1 if the signature is valid, otherwise 0 is returned.
*/
int verify_sign(u_char *msg, u_int m_len, u_char *signature, u_int siglen, RSA *pub)
{
return RSA_verify(NID_sha1, hash_sha1(msg, m_len, 0), SHA_DIGEST_LENGTH,
signature, siglen, pub);
}

46
src/crypto.h Normal file
View File

@ -0,0 +1,46 @@
/* This file is part of Netsukuku
* (c) Copyright 2005 Andrea Lo Pumo aka AlpT <alpt@freaknet.org>
*
* This source code 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 2 of the License,
* or (at your option) any later version.
*
* This source code 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.
* Please refer to the GNU Public License for more details.
*
* You should have received a copy of the GNU Public License along with
* this source code; if not, write to:
* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef CRYPTO_H
#define CRYPTO_H
#include <openssl/bio.h>
#include <openssl/evp.h>
#include <openssl/crypto.h>
#include <openssl/x509.h>
#include <openssl/err.h>
#include <openssl/rand.h>
#include <openssl/rsa.h>
#include <openssl/pem.h>
#include <sys/types.h>
#define RSA_PUB_EXPONENT 65537
void init_crypto(void);
void free_crypto(void);
char *ssl_strerr(void);
RSA *genrsa(int key_bits, u_char **pub, u_int *pub_len, u_char **priv, u_int *priv_len);
RSA *get_rsa_pub(const u_char **pub_key, long length);
RSA *get_rsa_priv(const u_char **priv_key, long length);
u_char *hash_sha1(u_char *msg, u_int len, u_char *hash);
u_char *hash_md5(u_char *msg, u_int m_len, u_char *hash);
u_char *rsa_sign(u_char *msg, u_int m_len, RSA *priv, u_int *siglen);
int verify_sign(u_char *msg, u_int m_len, u_char *signature, u_int siglen, RSA *pub);
#endif /*CRYPTO_H*/

459
src/daemon.c Normal file
View File

@ -0,0 +1,459 @@
/* This file is part of Netsukuku
* (c) Copyright 2005 Andrea Lo Pumo aka AlpT <alpt@freaknet.org>
*
* This source code 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 2 of the License,
* or (at your option) any later version.
*
* This source code 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.
* Please refer to the GNU Public License for more details.
*
* You should have received a copy of the GNU Public License along with
* this source code; if not, write to:
* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "includes.h"
#include "common.h"
#include "inet.h"
#include "request.h"
#include "if.h"
#include "pkts.h"
#include "bmap.h"
#include "daemon.h"
#include "netsukuku.h"
#include "accept.h"
extern int errno;
/*
* prepare_listen_socket:
* It creates a new socket of the desired `family' and binds it to the
* specified `port'. It sets also the reuseaddr and NONBLOCK
* socket options, because this new socket shall be used to listen() and
* accept().
* If `dev' is not null, the socket will be binded to the device named
* `dev'->dev_name with the SO_BINDTODEVICE socket option.
* The created socket is returned.
*/
int prepare_listen_socket(int family, int socktype, u_short port,
interface *dev)
{
struct addrinfo hints, *ai, *aitop;
char strport[NI_MAXSERV];
int err, s;
setzero(&hints, sizeof(struct addrinfo));
hints.ai_family=family;
hints.ai_socktype=socktype;
hints.ai_flags=AI_PASSIVE;
snprintf(strport, NI_MAXSERV, "%u", port);
err=getaddrinfo(NULL, strport, &hints, &aitop);
if(err) {
error("Getaddrinfo error: %s", gai_strerror(err));
return -1;
}
for (ai = aitop; ai; ai = ai->ai_next) {
if (ai->ai_family != AF_INET && ai->ai_family != AF_INET6)
continue;
s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol);
if (s == -1)
/* Maybe we can use another socket...*/
continue;
/* Bind the created socket to the device named dev->dev_name */
if(dev && (set_bindtodevice_sk(s, dev->dev_name) < 0)) {
inet_close(&s);
continue;
}
if(set_reuseaddr_sk(s) < 0) {
inet_close(&s);
continue;
}
/* Let's bind it! */
if(bind(s, ai->ai_addr, ai->ai_addrlen) < 0) {
error("Cannot bind the port %d: %s. Trying another "
"socket...", port, strerror(errno));
inet_close(&s);
continue;
}
freeaddrinfo(aitop);
return s;
}
error("Cannot open inbound socket on port %d: %s", port, strerror(errno));
freeaddrinfo(aitop);
return -1;
}
/*
* sockets_all_ifs
*
* creates a socket for each interface which is in the `ifs' array.
* The array has `ifs_n' members.
* Each created socket is stored in the `dev_sk' array, which has `ifs_n'#
* members.
* The created socket will be bound to the relative interface.
* In `max_sk_idx' is stored the index of the `dev_sk' array, which has the
* biggest dev_sk.
*
* On error 0 is returned, otherwise the number of utilised interfaces is
* returned.
* If the error is fatal, a negative value is returned.
*/
int sockets_all_ifs(int family, int socktype, u_short port,
interface *ifs, int ifs_n,
int *dev_sk, int *max_sk_idx)
{
int i, n, e=0;
*max_sk_idx=0;
for(i=0, n=0; i<ifs_n; i++) {
dev_sk[i] = prepare_listen_socket(family, socktype, port,
&ifs[i]);
if(dev_sk[i] < 0) {
error("Cannot create a socket on the %s interface! "
"Ignoring it", ifs[i].dev_name);
dev_sk[i]=0;
e++;
continue;
}
if(dev_sk[i] >= dev_sk[*max_sk_idx])
*max_sk_idx=i;
n++;
}
if(e == ifs_n)
return -1;
return n;
}
/*
* udp_exec_pkt: passes the received udp packet to pkt_exec().
* `passed_argv' is a pointer to a udp_exec_pkt_argv struct
*/
void *udp_exec_pkt(void *passed_argv)
{
struct udp_exec_pkt_argv argv;
PACKET rpkt;
const char *ntop;
memcpy(&argv, passed_argv, sizeof(struct udp_exec_pkt_argv));
memcpy(&rpkt, argv.recv_pkt, sizeof(PACKET));
if(argv.flags & UDP_THREAD_FOR_EACH_PKT)
pthread_mutex_unlock(&udp_exec_lock);
/* Drop any packet we sent in broadcast */
if(!memcmp(rpkt.from.data, me.cur_ip.data, MAX_IP_SZ)) {
pkt_free(&rpkt, 0);
return 0;
}
if(add_accept(rpkt.from, 1)) {
ntop=inet_to_str(rpkt.from);
debug(DBG_NORMAL, "ACPT: dropped UDP pkt from %s: "
"Accept table full.", ntop);
return 0;
}
pkt_exec(rpkt, argv.acpt_idx);
pkt_free(&rpkt, 0);
return 0;
}
/*
* udp_daemon: Takes care of receiving udp packets.
* `passed_argv' is a pointer to a udp_daemon_argv struct
*/
void *udp_daemon(void *passed_argv)
{
struct udp_daemon_argv argv;
struct udp_exec_pkt_argv exec_pkt_argv;
interface *ifs;
int max_sk_idx, dev_sk[me.cur_ifs_n];
PACKET rpkt;
fd_set fdset;
int ret, i, err;
u_short udp_port;
pthread_t thread;
pthread_attr_t t_attr;
#ifdef DEBUG
int select_errors=0;
#endif
memcpy(&argv, passed_argv, sizeof(struct udp_daemon_argv));
udp_port=argv.port;
setzero(&exec_pkt_argv, sizeof(struct udp_exec_pkt_argv));
if(argv.flags & UDP_THREAD_FOR_EACH_PKT) {
pthread_attr_init(&t_attr);
pthread_attr_setdetachstate(&t_attr, PTHREAD_CREATE_DETACHED);
exec_pkt_argv.flags|=UDP_THREAD_FOR_EACH_PKT;
}
debug(DBG_SOFT, "Preparing the udp listening socket on port %d", udp_port);
err=sockets_all_ifs(my_family, SOCK_DGRAM, udp_port, me.cur_ifs,
me.cur_ifs_n, dev_sk, &max_sk_idx);
if(!err)
return NULL;
else if(err < 0)
fatal("Creation of the %s daemon aborted. "
"Is there another ntkd running?", "udp");
debug(DBG_NORMAL, "Udp daemon on port %d up & running", udp_port);
pthread_mutex_unlock(&udp_daemon_lock);
pthread_mutex_init(&udp_exec_lock, 0);
for(;;) {
FD_ZERO(&fdset);
if(!me.cur_ifs_n) {
/* All the devices have been removed while ntkd was
* running, sleep well */
sleep(1);
continue;
}
for(i=0; i < me.cur_ifs_n; i++)
if(dev_sk[i])
FD_SET(dev_sk[i], &fdset);
ret=select(dev_sk[max_sk_idx]+1, &fdset, NULL, NULL, NULL);
if(sigterm_timestamp)
/* NetsukukuD has been closed */
break;
if (ret < 0) {
#ifdef DEBUG
if(select_errors > 20)
break;
select_errors++;
#endif
error("daemon_udp: select error: %s", strerror(errno));
continue;
}
for(i=0; i < me.cur_ifs_n; i++) {
ifs=&me.cur_ifs[i];
if(!dev_sk[i])
continue;
if(!FD_ISSET(dev_sk[i], &fdset))
continue;
setzero(&rpkt, sizeof(PACKET));
pkt_addsk(&rpkt, my_family, dev_sk[i], SKT_UDP);
pkt_add_dev(&rpkt, ifs, 0);
rpkt.flags=MSG_WAITALL;
pkt_addport(&rpkt, udp_port);
if(pkt_recv(&rpkt) < 0) {
pkt_free(&rpkt, 0);
continue;
}
exec_pkt_argv.acpt_idx=accept_idx;
exec_pkt_argv.acpt_sidx=accept_sidx;
if(argv.flags & UDP_THREAD_FOR_EACH_PKT) {
exec_pkt_argv.recv_pkt=&rpkt;
pthread_mutex_lock(&udp_exec_lock);
pthread_create(&thread, &t_attr, udp_exec_pkt,
&exec_pkt_argv);
pthread_mutex_lock(&udp_exec_lock);
pthread_mutex_unlock(&udp_exec_lock);
} else {
exec_pkt_argv.recv_pkt=&rpkt;
udp_exec_pkt(&exec_pkt_argv);
}
}
}
destroy_accept_tbl();
return NULL;
}
void *tcp_recv_loop(void *recv_pkt)
{
PACKET rpkt;
int acpt_idx, acpt_sidx;
acpt_idx=accept_idx;
acpt_sidx=accept_sidx;
memcpy(&rpkt, recv_pkt, sizeof(PACKET));
pthread_mutex_unlock(&tcp_exec_lock);
#if 0
add_accept_pid(getpid(), acpt_idx, acpt_sidx);
#endif
while( pkt_recv(&rpkt) != -1 ) {
if(pkt_exec(rpkt, acpt_idx) < 0) {
goto close;
break;
} else
pkt_free(&rpkt, 0);
}
close:
pkt_free(&rpkt, 1);
close_accept(acpt_idx, acpt_sidx);
return NULL;
}
void *tcp_daemon(void *door)
{
pthread_t thread;
pthread_attr_t t_attr;
PACKET rpkt;
struct sockaddr_storage addr;
socklen_t addrlen = sizeof addr;
inet_prefix ip;
fd_set fdset;
int fd, ret, err, i;
interface *ifs;
int max_sk_idx, dev_sk[me.cur_ifs_n];
u_short tcp_port=*(u_short *)door;
const char *ntop;
pthread_attr_init(&t_attr);
pthread_attr_setdetachstate(&t_attr, PTHREAD_CREATE_DETACHED);
debug(DBG_SOFT, "Preparing the tcp listening socket on port %d", tcp_port);
err=sockets_all_ifs(my_family, SOCK_STREAM, tcp_port, me.cur_ifs,
me.cur_ifs_n, dev_sk, &max_sk_idx);
if(!err)
return NULL;
else if(err < 0)
fatal("Creation of the %s daemon aborted. "
"Is there another ntkd running?", "tcp");
pthread_mutex_init(&tcp_exec_lock, 0);
for(i=0; i<me.cur_ifs_n; i++) {
if(!dev_sk[i])
continue;
/*
* While we are accepting the connections we keep the socket non
* blocking.
*/
if(set_nonblock_sk(dev_sk[i]))
return NULL;
/* Shhh, it's listening... */
if(listen(dev_sk[i], 5) == -1) {
inet_close(&dev_sk[i]);
return NULL;
}
}
debug(DBG_NORMAL, "Tcp daemon on port %d up & running", tcp_port);
pthread_mutex_unlock(&tcp_daemon_lock);
for(;;) {
FD_ZERO(&fdset);
if(!me.cur_ifs_n) {
/* All the devices have been removed while ntkd was
* running, sleep well */
sleep(1);
continue;
}
for(i=0; i < me.cur_ifs_n; i++)
if(dev_sk[i])
FD_SET(dev_sk[i], &fdset);
ret=select(dev_sk[max_sk_idx]+1, &fdset, NULL, NULL, NULL);
if(sigterm_timestamp)
/* NetsukukuD has been closed */
break;
if(ret < 0 && errno != EINTR)
error("daemon_tcp: select error: %s", strerror(errno));
if(ret < 0)
continue;
for(i=0; i < me.cur_ifs_n; i++) {
ifs=&me.cur_ifs[i];
if(!dev_sk[i])
continue;
if(!FD_ISSET(dev_sk[i], &fdset))
continue;
fd=accept(dev_sk[i], (struct sockaddr *)&addr, &addrlen);
if(fd == -1) {
if (errno != EINTR && errno != EWOULDBLOCK)
error("daemon_tcp: accept(): %s", strerror(errno));
continue;
}
setzero(&rpkt, sizeof(PACKET));
pkt_addsk(&rpkt, my_family, fd, SKT_TCP);
pkt_add_dev(&rpkt, ifs, 0);
rpkt.flags=MSG_WAITALL;
pkt_addport(&rpkt, tcp_port);
ntop=0;
sockaddr_to_inet((struct sockaddr *)&addr, &ip, 0);
pkt_addfrom(&rpkt, &ip);
if(server_opt.dbg_lvl)
ntop=inet_to_str(ip);
if((ret=add_accept(ip, 0))) {
debug(DBG_NORMAL, "ACPT: drop connection with %s: "
"Accept table full.", ntop);
/* Omg, we cannot take it anymore, go away: ACK_NEGATIVE */
pkt_err(rpkt, ret, 1);
inet_close(&fd);
continue;
} else {
/*
* Ok, the connection is good, send back the
* ACK_AFFERMATIVE.
*/
pkt_addto(&rpkt, &rpkt.from);
send_rq(&rpkt, 0, ACK_AFFERMATIVE, 0, 0, 0, 0);
}
if(unset_nonblock_sk(fd))
continue;
pthread_mutex_lock(&tcp_exec_lock);
err=pthread_create(&thread, &t_attr, tcp_recv_loop, (void *)&rpkt);
pthread_detach(thread);
pthread_mutex_lock(&tcp_exec_lock);
pthread_mutex_unlock(&tcp_exec_lock);
}
}
return NULL;
}

55
src/daemon.h Normal file
View File

@ -0,0 +1,55 @@
/* This file is part of Netsukuku
* (c) Copyright 2004 Andrea Lo Pumo aka AlpT <alpt@freaknet.org>
*
* This source code 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 2 of the License,
* or (at your option) any later version.
*
* This source code 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.
* Please refer to the GNU Public License for more details.
*
* You should have received a copy of the GNU Public License along with
* this source code; if not, write to:
* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef DAEMON_H
#define DAEMON_H
#define MAX_LISTENING_SOCKETS MAX_INTERFACES
/* These mutexes are used to wait the complete start up of the daemons when
* launched. */
pthread_mutex_t udp_daemon_lock;
pthread_mutex_t tcp_daemon_lock;
/* flags for udp_exec_pkt_argv and udp_daemon_argv */
#define UDP_THREAD_FOR_EACH_PKT 1 /* For each incoming udp
packets use threads */
/* Argv passed to udp_exec_pkt() */
struct udp_exec_pkt_argv {
PACKET *recv_pkt;
int acpt_idx;
int acpt_sidx;
u_char flags;
};
/* Argv passed to udp_daemon */
struct udp_daemon_argv {
u_short port;
u_char flags;
};
pthread_mutex_t udp_exec_lock;
pthread_mutex_t tcp_exec_lock;
int prepare_listen_socket(int family, int socktype, u_short port, interface *dev);
void *tcp_recv_loop(void *recv_pkt);
void *tcp_daemon(void *null);
void *udp_daemon(void *door);
#endif /*DAEMON_H*/

174
src/dns_wrapper.c Normal file
View File

@ -0,0 +1,174 @@
/* This file is part of Netsukuku
* (c) Copyright 2005 Andrea Lo Pumo aka AlpT <alpt@freaknet.org>
*
* This source code 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 2 of the License,
* or (at your option) any later version.
*
* This source code 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.
* Please refer to the GNU Public License for more details.
*
* You should have received a copy of the GNU Public License along with
* this source code; if not, write to:
* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* --
* dns_wrapper.c:
*
* The DNS wrapper listens to the port 53 for DNS hostname resolution queries,
* it then resolves the hostname by using the ANDNA system and sends back the
* resolved ip. In this way, every program can use ANDNA: just set
* "nameserver localhost"
* in /etc/resolv.conf ;)
*/
#include "includes.h"
#include "inet.h"
#include "endianness.h"
#include "map.h"
#include "gmap.h"
#include "bmap.h"
#include "route.h"
#include "request.h"
#include "pkts.h"
#include "tracer.h"
#include "qspn.h"
#include "radar.h"
#include "netsukuku.h"
#include "daemon.h"
#include "crypto.h"
#include "andna_cache.h"
#include "andna.h"
#include "andns.h"
#include "dns_wrapper.h"
#include "common.h"
/*
* dns_exec_pkt: resolve the hostname contained in the DNS query and sends
* the reply to from.
* `passed_argv' is a pointer to a dns_exec_pkt_argv struct.
*/
void *dns_exec_pkt(void *passed_argv)
{
struct dns_exec_pkt_argv argv;
char buf[MAX_DNS_PKT_SZ];
char answer_buffer[ANDNS_MAX_SZ];
int answer_length;
int bytes_sent;
memcpy(&argv, passed_argv, sizeof(struct dns_exec_pkt_argv));
memcpy(&buf, argv.rpkt, argv.rpkt_sz);
pthread_mutex_unlock(&dns_exec_lock);
if (argv.rpkt_sz < MIN_PKT_SZ) {
debug(DBG_NORMAL, "Received malformed DNS packet");
return 0;
}
/* Unpack the DNS query and resolve the hostname */
if(!andns_rslv(buf, argv.rpkt_sz, answer_buffer, &answer_length))
return 0;
/* Send the DNS reply */
bytes_sent=inet_sendto(argv.sk, answer_buffer, answer_length, 0,
&argv.from, argv.from_len);
if(bytes_sent != answer_length)
debug(DBG_SOFT, ERROR_MSG "inet_sendto error: %s", ERROR_POS,
strerror(errno));
return 0;
}
/*
* dns_wrapper_daemon: It receives DNS query pkts, resolves them in ANDNA and
* replies with a DNS reply.
* It listens to `port'.
*/
void dns_wrapper_daemon(u_short port)
{
struct dns_exec_pkt_argv exec_pkt_argv;
char buf[MAX_DNS_PKT_SZ];
fd_set fdset;
int ret, sk;
pthread_t thread;
pthread_attr_t t_attr;
ssize_t err=-1;
#ifdef DEBUG
int select_errors=0;
#endif
pthread_attr_init(&t_attr);
pthread_attr_setdetachstate(&t_attr, PTHREAD_CREATE_DETACHED);
pthread_mutex_init(&dns_exec_lock, 0);
debug(DBG_SOFT, "Preparing the dns_udp listening socket on port %d", port);
sk=prepare_listen_socket(my_family, SOCK_DGRAM, port, 0);
if(sk == -1)
return;
debug(DBG_NORMAL, "DNS wrapper daemon on port %d up & running", port);
for(;;) {
if(!sk)
fatal("The dns_wrapper_daemon socket got corrupted");
FD_ZERO(&fdset);
FD_SET(sk, &fdset);
ret = select(sk+1, &fdset, NULL, NULL, NULL);
if(sigterm_timestamp)
/* NetsukukuD has been closed */
break;
if (ret < 0) {
#ifdef DEBUG
if(select_errors > 20)
break;
select_errors++;
#endif
error("dns_wrapper_daemonp: select error: %s",
strerror(errno));
continue;
}
if(!FD_ISSET(sk, &fdset))
continue;
setzero(&buf, MAX_DNS_PKT_SZ);
setzero(&exec_pkt_argv.from, sizeof(struct sockaddr));
setzero(&exec_pkt_argv, sizeof(struct dns_exec_pkt_argv));
exec_pkt_argv.from_len = my_family == AF_INET ?
sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6);
/* we get the DNS query */
err=inet_recvfrom(sk, buf, MAX_DNS_PKT_SZ, MSG_WAITALL,
&exec_pkt_argv.from, &exec_pkt_argv.from_len);
if(err < 0) {
debug(DBG_NOISE, "dns_wrapper_daemonp: recv of the dns"
" query pkt aborted!");
continue;
}
/* Exec the pkt in another thread */
exec_pkt_argv.sk=sk;
exec_pkt_argv.rpkt_sz=err;
exec_pkt_argv.rpkt=buf;
pthread_mutex_lock(&dns_exec_lock);
pthread_create(&thread, &t_attr, dns_exec_pkt,
(void *)&exec_pkt_argv);
pthread_mutex_lock(&dns_exec_lock);
pthread_mutex_unlock(&dns_exec_lock);
}
}
void *dns_wrapper_thread(void *null)
{
dns_wrapper_daemon(DNS_WRAPPER_PORT);
return 0;
}

50
src/dns_wrapper.h Normal file
View File

@ -0,0 +1,50 @@
/* This file is part of Netsukuku
* (c) Copyright 2005 Andrea Lo Pumo aka AlpT <alpt@freaknet.org>
*
* This source code 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 2 of the License,
* or (at your option) any later version.
*
* This source code 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.
* Please refer to the GNU Public License for more details.
*
* You should have received a copy of the GNU Public License along with
* this source code; if not, write to:
* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef DNS_WRAPPER_H
#define DNS_WRAPPER_H
#define DNS_WRAPPER_PORT 53
#define MAX_DNS_PKT_SZ 512
#define MIN_PKT_SZ 7
/* DNS wrapper resolver api */
void resolver_process(const char *question, unsigned question_length,
char *answer, unsigned *answer_length,
int (*callback)(const char *name, uint32_t *ip));
/*
* dns_exec_pkt_argv is the struct passed to dns_exec_pkt() as argument
*/
struct dns_exec_pkt_argv
{
char *rpkt; /* Received dns query pkt */
ssize_t rpkt_sz;
int sk;
struct sockaddr from;
socklen_t from_len;
};
pthread_mutex_t dns_exec_lock;
/* * * Functions declarations * * */
void *dns_wrapper_thread(void *null);
#endif /*DNS_WRAPPER_H*/

888
src/dnslib.c Normal file
View File

@ -0,0 +1,888 @@
/**************************************
* AUTHOR: Federico Tomassini *
* Copyright (C) Federico Tomassini *
* Contact effetom@gmail.com *
***********************************************
******* BEGIN 3/2006 ********
*************************************************************************
* *
* 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 2 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. *
* *
************************************************************************/
#define _GNU_SOURCE
#include <string.h>
#include "dnslib.h"
#include "err_errno.h"
#include "log.h"
#include "xmalloc.h"
/*
* Takes a label: is there a ptr?
* Returns:
* -1 is a malformed label is found
* 0 if there's no pointer
* <offset from start_pkt> if a pointer is found
*/
int getlblptr(char *buf)
{
uint16_t dlbl;
char c[2];
memcpy(c,buf,2);
if (!LBL_PTR(*c)) /* No ptr */
return 0;
if (LBL_PTR(*c)!=LBL_PTR_MASK) {
debug(DBG_INSANE,"In getlblptr: invalid octet %02x",(unsigned char)c[0]);
err_ret(ERR_DNSMLO,-1);
}
(*c)&=LBL_PTR_OFF_MASK;
memcpy(&dlbl,c,2);
dlbl=ntohs(dlbl);
return dlbl; /* offset */
}
/*
* Reads a contiguous octet-sequence-label.
* Writes on dst.
* There are two limits:
* the name has to be less than MAX_SEQ_LBL_LEN
* we must stay in pkt_len
* -limit- is the less limit
*
* Returns:
* -1 On error
* Bytes readed if OK
*/
int read_label_octet(const char *src,char *dst,int limit)
{
int how;
how=*src++;
if ( how > limit || how > DNS_MAX_LABELS) {
error("In read_label_octet: got %d with limti %d\n",how,limit);
err_ret(ERR_DNSMSL,-1);
}
memcpy(dst,src,how);
return how;
}
/*
* Converts a dns compliant sequence label name to string.
* we start to read at -buf-
* we need start_pkt for pointers
* we need limit to remain under pktlen
* Returns:
* Bytes readed if OK
* -1 on error
*/
int lbltoname(char *buf,char *start_pkt,char *dst,int limit)
{
char *crow;
int how,recursion=0;
int ptr;
int writed=0,readed=0;
int new_limit=limit;
crow=buf;
while (*crow) {
ptr=getlblptr(crow);
if (ptr) { /* Got a pointer.... or got an error*/
if (ptr==-1) {
debug(DBG_INSANE,err_str);
err_ret(ERR_DNSMSL,-1);
}
if (++recursion>MAX_RECURSION_PTR)
err_ret(ERR_DNSTRP,-1);
if (recursion==1) readed+=2; /* we read the pointer */
crow=start_pkt+ptr;
new_limit=limit - (int)(crow - buf);
if (new_limit<=0 || new_limit > (int)(buf-start_pkt)+limit)
err_ret(ERR_DNSPLB,-1);
if (getlblptr(crow))
err_ret(ERR_DNSPTP,-1);
}
how=read_label_octet(crow,dst,min(new_limit,DNS_MAX_HNAME_LEN-writed));
if (how==-1) {
debug(DBG_INSANE,err_str);
err_ret(ERR_DNSMSL,-1);
}
if (!recursion)
readed+=how+1;
writed+=how+1;
dst+=how;
crow+=how+1;
*dst++=(*crow)?'.':0;
}
if (!recursion) readed++;
return readed;
}
/*
* DNS PTR query ask for 4.3.2.1.in-addr.arpa to know
* who is 1.2.3.4.
* This function reads this type of query transalting it
* in the second form.
* Writes result on *dst.
* -1 on error.
*/
int swap_straddr(char *src,char *dst)
{
char a[3];
int i,slen;
char *crow,*tmp,*atom;
int count=0,offset=0;
slen=strlen(src);
if (slen>DNS_MAX_HNAME_LEN)
goto mlf_addr;
tmp=src;
for (i=0;i<4;i++) {
count=0;
atom=a;
while (*tmp && *tmp!='.') {
if (count>2)
goto mlf_addr;
*atom++=*tmp++;
count++;
}
if (!count)
goto mlf_addr;
crow=dst+slen-count-offset;
strncpy(crow,a,count);
offset+=count;
if (!(*tmp))
break;
else {
if (i==3)
goto mlf_addr;
*(crow-1)='.';
offset++;
tmp++;
}
}
*(dst+slen)=0;
return 0;
mlf_addr:
debug(DBG_INSANE,"in swap_straddr: invalid address `%s`.\n",src);
err_ret(ERR_DNSMDD,-1);
}
int swap_straddr6(char *src,char *dst)
{
int slen;
char *tmp;
slen=strlen(src);
tmp=src+slen-1;
while (tmp!=src)
*dst++=*tmp--;
*dst++=*tmp;
*dst=0;
return 0;
}
int rm_inv_prefix(char *src,char *dst)
{
char *temp;
int ret;
if (!src) {
debug(DBG_INSANE,"In rm_inv_prefix: NULL argument!");
err_ret(ERR_DNSMDD,-1);
}
if( ! \
( (temp=(char*)strcasestr(src,DNS_INV_PREFIX)) ||\
(temp=(char*)strcasestr(src,DNS_INV_PREFIX6)) ||\
(temp=(char*)strcasestr(src,OLD_DNS_INV_PREFIX6)))) {
debug(DBG_INSANE,"In rm_inv_prefix(): no suffix for PTR query.");
err_ret(ERR_DNSMDD,-1);
}
if (temp-src>=DNS_MAX_HNAME_LEN) {
error("In rm_inv_prefix(): name too long.");
err_ret(ERR_DNSMDD,-1);
}
ret=strstr(temp,"6")?AF_INET6:AF_INET;
strncpy(dst,src,temp-src);
dst[temp-src]=0;
return ret;
}
int add_inv_prefix(char *s,int family)
{
int len;
len=strlen(s);
if (family==AF_INET)
strcat(s,DNS_INV_PREFIX);
else
strcat(s,DNS_INV_PREFIX6);
return 0;
}
int swapped_straddr(char *src,char *dst)
{
char temp[DNS_MAX_HNAME_LEN];
int res;
res=rm_inv_prefix(src,temp);
if (res==-1) {
error(err_str);
err_ret(ERR_DNSMDD,-1);
}
if (res==AF_INET)
res=swap_straddr(temp,dst);
else
res=swap_straddr6(temp,dst);
if (res==-1) {
error(err_str);
err_ret(ERR_DNSMDD,-1);
}
return 0;
}
int swapped_straddr_pref(char *src,char *dst,int family)
{
int res;
if (family==AF_INET)
res=swap_straddr(src,dst);
else
res=swap_straddr6(src,dst);
if (res==-1) {
error(err_str);
err_ret(ERR_DNSMDD,-1);
}
add_inv_prefix(dst,family);
return 0;
}
/*
* Converts a domain_name_string into a sequence label format,
* dns compliant. Writes on dst.
* -1 on error, number of bytes writed on success
*/
int nametolbl(char *name,char *dst)
{
char *crow;
int offset=0,res;
if (strlen(name)>DNS_MAX_HNAME_LEN) {
debug(DBG_INSANE,"Malformed name: %s.",name);
err_ret(ERR_DNSMDA,-1);
}
while ((crow=strstr(name+1,"."))) {
res=crow-name;
if (res>DNS_MAX_LABELS) {
debug(DBG_INSANE,"Malformed name: %s.",name);
err_ret(ERR_DNSMDA,-1);
}
*dst=(char)res; /* write the octet length */
dst++;
offset++;
memcpy(dst,name,(size_t)res); /* write label */
name+=res+1;dst+=res;offset+=res; /* shift ptrs */
}
if (!name) return offset;
if((res=(char)strlen(name))>DNS_MAX_LABELS) {
debug(DBG_INSANE,"Malformed name: %s",name);
err_ret(ERR_DNSMDA,-1);
}
*dst++=(char)res;
strcpy(dst,name);
offset+=res+2;
return offset;
}
/*
* Disassembles DNS packet headers, writing a yet allocated
* dns_pkt_hdr struct.
* No controls on len, bcz <<--the min_pkt_len is controlled
* by recv.-->>
* Returns the number of bytes readed (always DNS_HDR_SZ).
*/
int d_hdr_u(char *buf,dns_pkt_hdr *dph)
{
uint8_t c;
uint16_t s;
// ROW 1
memcpy(&s,buf,sizeof(uint16_t));
dph->id=ntohs(s);
// ROW 2
buf+=2;
memcpy(&c,buf,sizeof(uint8_t));
dph->qr= (c>>7)&0x01;
dph->opcode=(c>>3)&0x0f;
dph->aa=(c>>2)&0x01;
dph->tc=(c>>1)&0x01;
dph->rd=c&0x01;
buf++;
memcpy(&c,buf,sizeof(uint8_t));
dph->ra=(c>>7)&0x01;
dph->z=(c>>4)&0x07;
dph->rcode=c&0x0f;
// ROW 3
buf++;
memcpy(&s,buf,sizeof(uint16_t));
dph->qdcount=ntohs(s);
// ROW 4
buf+=2;
memcpy(&s,buf,sizeof(uint16_t));
dph->ancount=ntohs(s);
// ROW 5
buf+=2;
memcpy(&s,buf,sizeof(uint16_t));
dph->nscount=ntohs(s);
// ROW 6
buf+=2;
memcpy(&s,buf,sizeof(uint16_t));
dph->arcount=ntohs(s);
buf+=2;
return DNS_HDR_SZ; // i.e. 12 :)
}
/*
* This function alloc a new dns_pkt_qst to store a dns_question_section.
* The new dns_pkt_qst is also added to the principal dp-struct
* Returns bytes readed if OK. -1 otherwise.
*/
int d_qst_u(char *start_buf,char *buf,dns_pkt *dp,int limit_len)
{
int count;
uint16_t s;
dns_pkt_qst *dpq;
dpq=dns_add_qst(dp);
/* get name */
if((count=lbltoname(buf,start_buf,dpq->qname,limit_len))==-1) {
error(err_str);
err_ret(ERR_DNSMDD,1);
}
buf+=count;
/* Now we have to write 2+2 bytes */
if (count+4>limit_len)
err_ret(ERR_DNSPLB,1);
/* shift to type and class */
memcpy(&s,buf,2);
dpq->qtype=ntohs(s);
count+=2;
buf+=2;
memcpy(&s,buf,2);
dpq->qclass=ntohs(s);
count+=2;
return count;
}
/*
* Disassembles a DNS qst_section_set.
* Use the above function for each question section.
* -1 on error. Number of bytes readed on success.
* If -1 is returned, rcode ha sto be set to E_INTRPRT
*/
int d_qsts_u(char *start_buf,char *buf,dns_pkt *dp,int limit_len)
{
int offset=0,res;
int i,count;
if (!(count=DP_QDCOUNT(dp)))
return 0; /* No questions. */
for(i=0;i<count;i++) {
if ( (res=d_qst_u(start_buf,buf+offset,dp,limit_len-offset))==-1) {
error(err_str);
err_ret(ERR_DNSMDD,-1);
}
offset+=res;
}
return offset;
}
/*
* The behavior of this function is in all similar to dpkttoqst.
* Returns -1 on error. Bytes readed otherwise.
*/
int d_a_u(char *start_buf,char *buf,dns_pkt_a **dpa_orig,int limit_len)
{
int count,rdlen;
dns_pkt_a *dpa;
uint16_t s;
uint32_t ui;
dpa=dns_add_a(dpa_orig);
/* get name */
if((count=lbltoname(buf,start_buf,dpa->name,limit_len))==-1) {
error(err_str);
err_ret(ERR_DNSMDD,-1);
}
buf+=count;
/* Now we have to write 2+2+4+2 bytes */
if (count+10>limit_len)
err_ret(ERR_DNSPLB,-1);
memcpy(&s,buf,2);
dpa->type=ntohs(s);
count+=2;
buf+=2;
memcpy(&s,buf,2);
dpa->cl=ntohs(s);
count+=2;
buf+=2;
memcpy(&ui,buf,4);
dpa->ttl=ntohl(ui);
count+=4;
buf+=4;
memcpy(&s,buf,2);
dpa->rdlength=ntohs(s);
count+=2;
buf+=2;
rdlen=dpa->rdlength;
if (rdlen>DNS_MAX_HNAME_LEN)
err_ret(ERR_DNSMDD,-1);
/* Now we have to write dpa->rdlength bytes */
if (count+rdlen>limit_len)
err_ret(ERR_DNSPLB,-1);
if (dpa->type==T_A) {
memcpy(dpa->rdata,buf,rdlen); /* 32bit address */
count+=rdlen;
}
else if (dpa->type==T_MX) {
memcpy(dpa->rdata,buf,2);
if ((ui=lbltoname(buf+2,start_buf,dpa->rdata+2,rdlen-2))==-1) {
error(err_str);
err_ret(ERR_DNSMDD,-1);
}
if (rdlen!=ui+2) {
debug(DBG_NORMAL,"In d_a_u(): rdlen (%d) differs from readed bytes (%d).",rdlen,ui+2);
err_ret(ERR_DNSMDD,-1);
}
count+=2+ui;
} else {
if ((ui=lbltoname(buf,start_buf,dpa->rdata,rdlen))==-1) {
error(err_str);
err_intret(ERR_DNSMDD);
}
if (rdlen!=ui) {
debug(DBG_NORMAL,"In d_a_u(): rdlen (%d) differs from readed bytes (%d).",rdlen,ui);
err_ret(ERR_DNSMDD,-1);
}
count+=ui;
}
return count;
}
/*
* like d_qs_u. count is the number of section to read.
* -1 on error. Bytes readed otherwise.
*/
int d_as_u(char *start_buf,char *buf,dns_pkt_a **dpa,int limit_len,int count)
{
int offset=0,res;
int i;
if (!count) return 0;
for(i=0;i<count;i++) {
if ((res=d_a_u(start_buf,buf+offset,dpa,limit_len-offset))==-1) {
error(err_str);
err_intret(ERR_DNSMDD);
}
offset+=res;
}
return offset;
}
/*
* This is a main function: takes the pkt-buf and translate
* it in structured data.
* It cares about dns_pkt allocations.
*
* Returns:
* -1 on E_INTRPRT
* 0 if pkt must be discarded.
* Number of bytes readed otherwise
*/
int d_u(char *buf,int pktlen,dns_pkt **dpp)
{
dns_pkt *dp;
int offset=0,res;
char *crow;
crow=buf;
/* Controls pkt consistency: we must at least read pkt headers */
if (pktlen<DNS_HDR_SZ)
err_ret(ERR_DNSMDP,0);
*dpp=dp=create_dns_pkt();
/* Writes headers */
offset+=d_hdr_u(buf,&(dp->pkt_hdr));
if (pktlen > DNS_MAX_SZ) /* If pkt is too long: the headers are written,
* so we can reply with E_INTRPRT
*/
err_intret(ERR_DNSPLB);
crow+=offset;
/* Writes qsts */
if (dp->pkt_hdr.qdcount) {
if ((res=d_qsts_u(buf,crow,dp,pktlen-offset))==-1) {
error(err_str);
err_intret(ERR_DNSMDP);
}
offset+=res;
crow+=res;
}
if (dp->pkt_hdr.ancount) {
if ((res=d_as_u(buf,crow,&(dp->pkt_answ),pktlen-offset,DP_ANCOUNT(dp)))==-1) {
error(err_str);
err_intret(ERR_DNSMDP);
}
offset+=res;
}
/*crow+=res;
if ((res=dpkttoas(buf,crow,&(dp->pkt_auth),pktlen-offset,DP_NSCOUNT(dp)))==-1)
return -1;
offset+=res;
crow+=res;
if ((res=dpkttoas(buf,crow,&(dp->pkt_add),pktlen-offset,DP_ARCOUNT(dp)))==-1)
return -1;*/
return offset;
}
/*
* This function is the d_hdr_u inverse.
* Takes a dns_pkt struct and builds the
* header pkt-buffer
* Returns the number of bytes writed.
*/
int d_hdr_p(dns_pkt *dp,char *buf)
{
char *crow=buf;
uint16_t u;
dns_pkt_hdr *dph;
dph=&(dp->pkt_hdr);
u=htons(dph->id);
memcpy(buf,&u,2);
buf+=2;
if (dph->qr) *buf|=0x80;
*buf|=dph->opcode<<3;
*buf|=dph->aa<<2;
*buf|=dph->tc<<1;
*buf|=dph->rd;
buf++;
*buf|=dph->ra<<7;
*buf|=dph->z<<4;
*buf|=dph->rcode;
buf++;
u=htons(dph->qdcount);
memcpy(buf,&u,2);
buf+=2;
u=htons(dph->ancount);
memcpy(buf,&u,2);
buf+=2;
u=htons(dph->nscount);
memcpy(buf,&u,2);
buf+=2;
u=htons(dph->arcount);
memcpy(buf,&u,2);
buf+=2;
return (int)(buf-crow);
}
/*
* Translate a struct dns_pkt_qst in the dns-buffer buf.
* Returns:
* -1 On error
* Bytes writed otherwise.
*/
int d_qst_p(dns_pkt_qst *dpq,char *buf, int limitlen)
{
int offset;
uint16_t u;
if((offset=nametolbl(dpq->qname,buf))==-1) {
error(err_str);
err_ret(ERR_DNSMDA,-1);
}
if (offset+4>limitlen)
err_ret(ERR_DNSPLB,-1);
buf+=offset;
u=htons(dpq->qtype);
memcpy(buf,&u,2);
buf+=2;offset+=2;
u=htons(dpq->qclass);
memcpy(buf,&u,2);
buf+=2;offset+=2;
return offset;
}
/*
* Translates the question sections of a struct dns_pkt
* into buf.
* Returns:
* -1 on error.
* Number of bytes writed otherwise,
*/
int d_qsts_p(dns_pkt *dp,char *buf,int limitlen)
{
int offset=0,res;
int i;
dns_pkt_qst *dpq;
dpq=dp->pkt_qst;
for (i=0;dpq && i<DP_QDCOUNT(dp);i++) {
if ((res=d_qst_p(dpq,buf+offset,limitlen-offset))==-1) {
error(err_str);
err_ret(ERR_DNSMDA,-1);
}
offset+=res;
dpq=dpq->next;
}
return offset;
}
int d_a_p(dns_pkt_a *dpa,char *buf,int limitlen)
{
int offset,rdlen;
uint16_t u;
int i;
if((rdlen=nametolbl(dpa->name,buf))==-1)
return -1;
offset=rdlen;
if (offset+10>limitlen)
err_intret(ERR_DNSPLB);
buf+=offset;
u=htons(dpa->type);
memcpy(buf,&u,2);
buf+=2;offset+=2;
u=htons(dpa->cl);
memcpy(buf,&u,2);
buf+=2;offset+=2;
i=htonl(dpa->ttl);
memcpy(buf,&i,4);
buf+=4;offset+=4;
if (dpa->type==T_A) {
if (offset+dpa->rdlength>limitlen)
err_intret(ERR_DNSPLB);
memcpy(buf+2,dpa->rdata,dpa->rdlength);
offset+=dpa->rdlength;
} else if (dpa->type==T_MX) {
memcpy(buf+2,dpa->rdata,2);
if ((rdlen=nametolbl(dpa->rdata+2,buf+4))==-1) {
error(err_str);
err_ret(ERR_DNSMDA,-1);
}
offset+=rdlen+2;
if (offset>limitlen)
err_ret(ERR_DNSPLB,-1);
dpa->rdlength=rdlen+2;
} else {
if ((rdlen=nametolbl(dpa->rdata,buf+2))==-1) {
error(err_str);
err_ret(ERR_DNSMDA,-1);
}
offset+=rdlen;
if (offset>limitlen)
err_ret(ERR_DNSPLB,-1);
dpa->rdlength=rdlen;
}
u=htons(dpa->rdlength);
memcpy(buf,&u,2);
offset+=2;
return offset;
}
int d_as_p(dns_pkt_a *dpa,char *buf,int limitlen,int count)
{
int offset=0,res;
int i;
for (i=0;dpa && i<count;i++) {
if ((res=d_a_p(dpa,buf+offset,limitlen-offset))==-1) {
error(err_str);
err_ret(ERR_DNSMDA,-1);
}
offset+=res;
dpa=dpa->next;
}
return offset;
}
/*
* Transform a dns_pkt structure in char stream.
*
* Returns:
* -1 on error
* len(stream) if OK
*
* The stream has at least the header section writed.
* `buf' must be at least of DNS_MAX_SZ bytes.
*
* DANGER: This function realeses *ALWAYS* the dns_pkt *dp!!!!
*/
int d_p(dns_pkt *dp,char *buf)
{
int offset,res;
memset(buf,0,DNS_MAX_SZ);
offset=d_hdr_p(dp,buf);
buf+=offset;
if((res=d_qsts_p(dp,buf,DNS_MAX_SZ-offset))==-1)
goto server_fail;
offset+=res;
buf+=res;
if ( (res=d_as_p(dp->pkt_answ,buf,DNS_MAX_SZ-offset,DP_ANCOUNT(dp)))==-1)
goto server_fail;
offset+=res;
/*buf+=res;
if ( (res=astodpkt(dp->pkt_auth,buf,DNS_MAX_SZ-offset,DP_NSCOUNT(dp)))==-1)
goto server_fail;
offset+=res;
buf+=res;*/
/*if ( (res=astodpkt(dp->pkt_add,buf,DNS_MAX_SZ-offset,DP_ARCOUNT(dp)))==-1)
goto server_fail;
offset+=res;*/
destroy_dns_pkt(dp);
return offset;
server_fail:
error(err_str);
destroy_dns_pkt(dp);
err_ret(ERR_DNSPDS,-1);
}
/* Memory Functions */
dns_pkt* create_dns_pkt(void)
{
dns_pkt *dp;
dp=xmalloc(DNS_PKT_SZ);
memset(dp,0,DNS_PKT_SZ);
dp->pkt_qst=NULL;
dp->pkt_answ=NULL;
dp->pkt_add=NULL;
dp->pkt_auth=NULL;
return dp;
}
dns_pkt_qst* create_dns_pkt_qst(void)
{
dns_pkt_qst *dpq;
dpq=xmalloc(DNS_PKT_QST_SZ);
dpq->next=NULL;
memset(dpq->qname,0,DNS_MAX_HNAME_LEN);
return dpq;
}
dns_pkt_a* create_dns_pkt_a(void)
{
dns_pkt_a *dpa;
dpa=xmalloc(DNS_PKT_A_SZ);
memset(dpa->name,0,DNS_MAX_HNAME_LEN);
memset(dpa->rdata,0,DNS_MAX_HNAME_LEN);
dpa->next=NULL;
return dpa;
}
dns_pkt_qst* dns_add_qst(dns_pkt *dp)
{
dns_pkt_qst *dpq,*temp;
dpq=create_dns_pkt_qst();
temp=dp->pkt_qst;
if (!temp) {
dp->pkt_qst=dpq;
return dpq;
}
while (temp->next) temp=temp->next;
temp->next=dpq;
return dpq;
}
void dns_del_last_qst(dns_pkt *dp)
{
dns_pkt_qst *dpq=dp->pkt_qst;
if (!dpq) return;
if (!(dpq->next)){
xfree(dpq);
dp->pkt_qst=NULL;
return;
}
while ((dpq->next)->next);
xfree(dpq->next);
dpq->next=NULL;
return;
}
dns_pkt_a* dns_add_a(dns_pkt_a **dpa)
{
dns_pkt_a *dpa_add,*a;
int count=0;
a=*dpa;
dpa_add=create_dns_pkt_a();
if (!a) {
(*dpa)=dpa_add;
}
else {
while (a->next) {
a=a->next;
count++;
}
a->next=dpa_add;
}
return dpa_add;
}
void dns_a_default_fill(dns_pkt *dp,dns_pkt_a *dpa)
{
strcpy(dpa->name,dp->pkt_qst->qname);
dpa->cl=C_IN;
dpa->ttl=DNS_TTL;
dpa->type=dp->pkt_qst->qtype;
}
void destroy_dns_pkt(dns_pkt *dp)
{
dns_pkt_a *dpa,*dpa_t;
dns_pkt_qst *dpq,*dpq_t;
if (dp->pkt_qst) {
dpq=dp->pkt_qst;
while (dpq) {
dpq_t=dpq->next;
xfree(dpq);
dpq=dpq_t;
}
}
if (dp->pkt_answ) {
dpa=dp->pkt_answ;
while (dpa) {
dpa_t=dpa->next;
xfree(dpa);
dpa=dpa_t;
}
}
if (dp->pkt_add) {
dpa=dp->pkt_add;
while (dpa) {
dpa_t=dpa->next;
xfree(dpa);
dpa=dpa_t;
}
}
if (dp->pkt_auth) {
dpa=dp->pkt_auth;
while (dpa) {
dpa_t=dpa->next;
xfree(dpa);
dpa=dpa_t;
}
}
xfree(dp);
return;
}

189
src/dnslib.h Normal file
View File

@ -0,0 +1,189 @@
/**************************************
* AUTHOR: Federico Tomassini *
* Copyright (C) Federico Tomassini *
* Contact effetom@gmail.com *
***********************************************
******* BEGIN 3/2006 ********
*************************************************************************
* *
* 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 2 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. *
* *
************************************************************************/
#ifndef DNSLIB_H
#define DNSLIB_H
#include <string.h>
#include <stdint.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#define LBL_PTR_MASK 0xC0 /* Network byte order */
#define LBL_PTR_OFF_MASK 0x3f /* N.b. order */
#define LBL_PTR(c) ((c)&LBL_PTR_MASK) /* AND whith 0xC000 */
#define MAX_RECURSION_PTR 20
/* PREFIXES FOR PTR QUERY */
#define DNS_INV_PREFIX ".IN-ADDR.ARPA"
#define DNS_INV_PREFIX6 ".IP6.ARPA"
#define OLD_DNS_INV_PREFIX6 ".IP6.INT" /* For backward compatibility */
/* DNS QUERY-TYPE: others type will be discarded */
#define T_AAAA 28 /* h->ip IPV6 */
#define T_A 1 /* h->ip IPV4 */
#define T_PTR 12 /* ip->h */
#define T_MX 15 /* h->mx */
/* RCODES */
#define DNS_RCODE_NOERR 0 /* No error */
#define DNS_RCODE_EINTRPRT 1 /* Intepret error */
#define DNS_RCODE_ESRVFAIL 2 /* Server failure */
#define DNS_RCODE_ENSDMN 3 /* No such domain */
#define DNS_RCODE_ENIMPL 4 /* Not implemented */
#define DNS_RCODE_ERFSD 5 /* Refused */
/* INET CLASS */
#define C_IN 1
/* RFC */
#define DNS_MAX_SZ 512
#define DNS_HDR_SZ 12
#define DNS_MAX_LABELS 63
#define DNS_MAX_HNAME_LEN 255
#define DNS_TTL 86400;
#define min(x,y) ((x)<(y))?(x):(y)
typedef struct dns_pkt_hdr {
uint16_t id;
uint8_t qr;
uint8_t opcode;
uint8_t aa;
uint8_t tc;
uint8_t rd;
uint8_t ra;
uint8_t z;
uint8_t rcode;
uint8_t qdcount;
uint8_t ancount;
uint8_t nscount;
uint8_t arcount;
} dns_pkt_hdr;
#define DNS_PKT_HDR_SZ sizeof(dns_pkt_hdr)
/* DNS_PKT_HDR MACROS */
#define DP_QDCOUNT(dp) ((dp)->pkt_hdr).qdcount
#define DP_ANCOUNT(dp) ((dp)->pkt_hdr).ancount
#define DP_NSCOUNT(dp) ((dp)->pkt_hdr).nscount
#define DP_ARCOUNT(dp) ((dp)->pkt_hdr).arcount
struct dns_pkt_qst {
char qname[DNS_MAX_HNAME_LEN];
uint16_t qtype;
uint16_t qclass;
struct dns_pkt_qst *next;
};
typedef struct dns_pkt_qst dns_pkt_qst;
#define DNS_PKT_QST_SZ sizeof(dns_pkt_qst)
struct dns_pkt_a
{
char name[DNS_MAX_HNAME_LEN];
uint16_t type;
uint16_t cl;
uint32_t ttl;
uint16_t rdlength;
char rdata[DNS_MAX_HNAME_LEN];
struct dns_pkt_a *next;
};
typedef struct dns_pkt_a dns_pkt_a;
#define DNS_PKT_A_SZ sizeof(dns_pkt_a)
typedef struct dns_pkt
{
dns_pkt_hdr pkt_hdr;
dns_pkt_qst *pkt_qst;
dns_pkt_a *pkt_answ;
dns_pkt_a *pkt_auth;
dns_pkt_a *pkt_add;
} dns_pkt;
#define DNS_PKT_SZ sizeof(dns_pkt)
/* USER MACRO */
#define DNS_GET_ID(dp) (dp)->pkt_hdr.id
#define DNS_GET_QR(dp) (dp)->pkt_hdr.qr
#define DNS_GET_OPCODE(dp) (dp)->pkt_hdr.opcode
#define DNS_GET_AA(dp) (dp)->pkt_hdr.aa
#define DNS_GET_TC(dp) (dp)->pkt_hdr.tc
#define DNS_GET_RD(dp) (dp)->pkt_hdr.rd
#define DNS_GET_RA(dp) (dp)->pkt_hdr.ra
#define DNS_GET_Z(dp) (dp)->pkt_hdr.z
#define DNS_GET_RCODE(dp) (dp)->pkt_hdr.rcode
#define DNS_GET_QDCOUNT(dp) (dp)->pkt_hdr.qdcount
#define DNS_GET_ANCOUNT(dp) (dp)->pkt_hdr.ancount
#define DNS_GET_NSCOUNT(dp) (dp)->pkt_hdr.nscount
#define DNS_GET_ARCOUNT(dp) (dp)->pkt_hdr.arcount
#define DNS_SET_ID(dp,x) (dp)->pkt_hdr.id=x
#define DNS_SET_QR(dp,x) (dp)->pkt_hdr.qr=x
#define DNS_SET_OPCODE(dp,x) (dp)->pkt_hdr.opcode=x
#define DNS_SET_AA(dp,x) (dp)->pkt_hdr.aa=x
#define DNS_SET_TC(dp,x) (dp)->pkt_hdr.tc=x
#define DNS_SET_RD(dp,x) (dp)->pkt_hdr.rd=x
#define DNS_SET_RA(dp,x) (dp)->pkt_hdr.ra=x
#define DNS_SET_Z(dp,x) (dp)->pkt_hdr.z=x
#define DNS_SET_RCODE(dp,x) (dp)->pkt_hdr.rcode=x
#define DNS_SET_QDCOUNT(dp,x) (dp)->pkt_hdr.qdcount=x
#define DNS_SET_ANCOUNT(dp,x) (dp)->pkt_hdr.ancount=x
#define DNS_SET_NSCOUNT(dp,x) (dp)->pkt_hdr.nscount=x
#define DNS_SET_ARCOUNT(dp,x) (dp)->pkt_hdr.arcount=x
#define DP_ADD_ANSWER(dp) dns_add_a(&((dp)->pkt_answ));DP_ANCOUNT(dp)+=1;
#define DP_ADD_AUTH(dp) dns_add_a(&((dp)->pkt_auth));DP_NSCOUNT(dp)+=1;
#define DP_ADD_ADD(dp) dns_add_a(&((dp)->pkt_add));DP_ARCOUNT(dp)+=1;
/* Functions */
int getlblptr(char *buf);
int read_label_octet(const char *src,char *dst,int limit);
int lbltoname(char *buf,char *start_pkt,char *dst,int limit);
int swap_straddr(char *src,char *dst);
int swap_straddr6(char *src,char *dst);
int rm_inv_prefix(char *src,char *dst) ;
int add_inv_prefix(char *s,int family);
int swapped_straddr(char *src,char *dst) ;
int swapped_straddr_pref(char *src,char *dst,int family);
int nametolbl(char *name,char *dst);
int d_hdr_u(char *buf,dns_pkt_hdr *dph);
int d_qst_u(char *start_buf,char *buf,dns_pkt *dp,int limit_len);
int d_qsts_u(char *start_buf,char *buf,dns_pkt *dp,int limit_len);
int d_a_u(char *start_buf,char *buf,dns_pkt_a **dpa_orig,int limit_len);
int d_as_u(char *start_buf,char *buf,dns_pkt_a **dpa,int limit_len,int count);
int d_u(char *buf,int pktlen,dns_pkt **dpp);
int d_hdr_p(dns_pkt *dp,char *buf);
int d_qst_p(dns_pkt_qst *dpq,char *buf, int limitlen);
int d_qsts_p(dns_pkt *dp,char *buf,int limitlen);
int d_a_p(dns_pkt_a *dpa,char *buf,int limitlen);
int d_as_p(dns_pkt_a *dpa,char *buf,int limitlen,int count);
int d_p(dns_pkt *dp,char *buf);
dns_pkt* create_dns_pkt(void);
dns_pkt_qst* create_dns_pkt_qst(void);
dns_pkt_a* create_dns_pkt_a(void);
dns_pkt_qst* dns_add_qst(dns_pkt *dp);
void dns_del_last_qst(dns_pkt *dp);
dns_pkt_a* dns_add_a(dns_pkt_a **dpa);
void dns_a_default_fill(dns_pkt *dp,dns_pkt_a *dpa);
void destroy_dns_pkt(dns_pkt *dp);
#endif /* DNSLIB_H */

219
src/endianness.c Normal file
View File

@ -0,0 +1,219 @@
/* This file is part of Netsukuku
* (c) Copyright 2005 Andrea Lo Pumo aka AlpT <alpt@freaknet.org>
*
* This source code 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 2 of the License,
* or (at your option) any later version.
*
* This source code 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.
* Please refer to the GNU Public License for more details.
*
* You should have received a copy of the GNU Public License along with
* this source code; if not, write to:
* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* --
* endian.c:
* stuff to handle endianess mischief.
*/
#include "includes.h"
#include "common.h"
#include "log.h"
#include "endianness.h"
#ifdef DEBUG
/* Call fatal if `i' is equal to IINFO_DYNAMIC_VALUE.
* Note: this is needed only for debugging purpose */
#define IS_DYNAMIC(i) \
({ \
if((i) == IINFO_DYNAMIC_VALUE) \
fatal("%s:%d: IINFO_DYNAMIC_VALUE encountered", ERROR_POS); \
})
#else
#define IS_DYNAMIC(i) ({do_nothing();})
#endif /*DEBUG*/
void *int_info_copy(int_info *dst, const int_info *src)
{
return memcpy(dst, src, sizeof(int_info));
}
void ints_array_ntohl(int *hostlong, int nmemb)
{
#if BYTE_ORDER == LITTLE_ENDIAN
int i;
for(i=0; i<nmemb; i++)
hostlong[i]=ntohl(hostlong[i]);
#endif
}
void ints_array_htonl(int *netlong, int nmemb)
{
#if BYTE_ORDER == LITTLE_ENDIAN
int i;
for(i=0; i<nmemb; i++)
netlong[i]=htonl(netlong[i]);
#endif
}
void ints_array_ntohs(short *hostshort, int nmemb)
{
#if BYTE_ORDER == LITTLE_ENDIAN
int i;
for(i=0; i<nmemb; i++)
hostshort[i]=ntohs(hostshort[i]);
#endif
}
void ints_array_htons(short *netshort, int nmemb)
{
#if BYTE_ORDER == LITTLE_ENDIAN
int i;
for(i=0; i<nmemb; i++)
netshort[i]=htons(netshort[i]);
#endif
}
/*
* ints_network_to_host: converts all the int/short variables present in the
* struct `s' from network order to host order. The `s' struct must be
* described in the `iinfo' struct.
*/
void ints_network_to_host(void *s, int_info iinfo)
{
#if BYTE_ORDER == LITTLE_ENDIAN
int i;
char *p;
IS_DYNAMIC(iinfo.total_ints);
for(i=0; i < iinfo.total_ints; i++) {
if(!iinfo.int_type[i])
continue;
IS_DYNAMIC(iinfo.int_offset[i]);
p=(char *)s + iinfo.int_offset[i];
IS_DYNAMIC(iinfo.int_nmemb[i]);
IS_DYNAMIC(iinfo.int_type[i]);
/*
* Swap the entire array if it is a single integer and if we
* are on a little endian machine.
*/
if(iinfo.int_type[i] & INT_TYPE_WORDS) {
if(iinfo.int_type[i] & INT_TYPE_32BIT)
swap_ints(iinfo.int_nmemb[i], (u_int *)p,
(u_int *)p);
else
swap_shorts(iinfo.int_nmemb[i], (u_short *)p,
(u_short *)p);
}
if(iinfo.int_type[i] & INT_TYPE_32BIT)
ints_array_ntohl((int *)p, iinfo.int_nmemb[i]);
else
ints_array_ntohs((short *)p, iinfo.int_nmemb[i]);
}
#endif
}
/*
* ints_host_to_network: converts all the int/short variables present in the
* struct `s' from host order to network order. The `s' struct must be
* described in the `iinfo' struct.
*/
void ints_host_to_network(void *s, int_info iinfo)
{
#if BYTE_ORDER == LITTLE_ENDIAN
int i;
char *p;
IS_DYNAMIC(iinfo.total_ints);
for(i=0; i < iinfo.total_ints; i++) {
if(!iinfo.int_type[i])
continue;
IS_DYNAMIC(iinfo.int_offset[i]);
p=(char *)s + iinfo.int_offset[i];
IS_DYNAMIC(iinfo.int_nmemb[i]);
IS_DYNAMIC(iinfo.int_type[i]);
/*
* Swap the entire array if it is a single integer and if we
* are on a little endian machine.
*/
if(iinfo.int_type[i] & INT_TYPE_WORDS) {
if(iinfo.int_type[i] & INT_TYPE_32BIT)
swap_ints(iinfo.int_nmemb[i], (u_int *)p, (u_int *)p);
else
swap_shorts(iinfo.int_nmemb[i], (u_short *)p, (u_short *)p);
}
if(iinfo.int_type[i] & INT_TYPE_32BIT)
ints_array_htonl((int *)p, iinfo.int_nmemb[i]);
else
ints_array_htons((short *)p, iinfo.int_nmemb[i]);
}
#endif
}
/*
* ints_printf: prints all the int/short vars present in the `s' struct
* described by `iinfo'. It uses `print_func' as the the printing function
*/
void ints_printf(void *s, int_info iinfo, void(*print_func(const char *, ...)))
{
int i, e, *i32;
short *i16;
char *p;
IS_DYNAMIC(iinfo.total_ints);
for(i=0; i < iinfo.total_ints; i++) {
if(!iinfo.int_type[i])
continue;
IS_DYNAMIC(iinfo.int_offset[i]);
p=(char *)s + iinfo.int_offset[i];
IS_DYNAMIC(iinfo.int_nmemb[i]);
IS_DYNAMIC(iinfo.int_type[i]);
for(e=0; e < iinfo.int_nmemb[i]; e++) {
print_func("ints_printf: offset %d, nmemb %d, ",
iinfo.int_offset[i], e);
if(iinfo.int_type[i] & INT_TYPE_32BIT) {
i32 = (int *)(p + (sizeof(int) * e));
print_func("32bit value %d\n", *i32);
} else {
i16 = (short *)(p + (sizeof(short) * e));
print_func("16bit value %d\n", *i16);
}
}
}
}

109
src/endianness.h Normal file
View File

@ -0,0 +1,109 @@
/* This file is part of Netsukuku
* (c) Copyright 2005 Andrea Lo Pumo aka AlpT <alpt@freaknet.org>
*
* This source code 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 2 of the License,
* or (at your option) any later version.
*
* This source code 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.
* Please refer to the GNU Public License for more details.
*
* You should have received a copy of the GNU Public License along with
* this source code; if not, write to:
* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef ENDIANNESS_H
#define ENDIANNESS_H
#define MAX_INTS_PER_STRUCT 8 /* The maximum number of short/int variables
present in a struct */
#define IINFO_DYNAMIC_VALUE -1 /* This define is used to fill part in a
int_info struct that must be set each time.
If that part is not set, -1 will remain, and
the int_info functions will call fatal().
Therefore this is useful to track bugs. */
/* flags for int_info.int_type */
#define INT_TYPE_VOID 0 /* Emptiness is loneliness, and loneliness is
cleanliness */
#define INT_TYPE_32BIT 1 /* The int var is of 32 bits */
#define INT_TYPE_16BIT (1<<1) /* The int var is of 16 bits */
#define INT_TYPE_WORDS (1<<2) /* The int var is composed by an array of ints,
like the ipv6 ip (struct in6_addr) */
#define INT_TYPE_NETWORK (1<<3) /* The int var is stored in network order */
/*
* int_info: this struct is used to keep the information about the int/short
* variables present in a struct. It is useful to convert all the int/short
* vars in another endian format with a simple function.
* WARNING: There is a drawback: the struct must have the __packed__
* attribute (but since we are using this for packet structs we don't care).
*
* Here there is an example which show how to use this int_info:
*
* given the struct s:
* struct
* {
* u_char a;
* int b;
* short c;
* char d[23];
* int e[4];
* }__attribute__ ((__packed__)) s;
*
* its int_info struct should be filled in this way:
*
* int_info s_int_info = { 3,
* {INT_TYPE_32BIT, INT_TYPE_16BIT, INT_TYPE_32BIT},
* { sizeof(char), sizeof(char)+sizeof(int),
* sizeof(char)+sizeof(int)+sizeof(short)+sizeof(char)*23},
* { 1, 1, 4 }
* };
*/
typedef struct
{
/* The total int/short vars present in the struct */
int total_ints;
/* Each member in the int_type array corresponds to a int/short var
* and it is set using the above INT_TYPE_ flags */
char int_type[MAX_INTS_PER_STRUCT];
/* Each member in the int_offset array specifies the amount of bytes
* to be added at the end of the struct to get the relative int/short
* var. */
size_t int_offset[MAX_INTS_PER_STRUCT];
/* int_nmemb[x] is equal to the number of consecutive ints/shorts var,
* which start at the int_offset[x] offset. */
size_t int_nmemb[MAX_INTS_PER_STRUCT];
} int_info;
/* Useful to declare constant static int_info structs in .h files */
#define INT_INFO const static int_info
#if BYTE_ORDER == LITTLE_ENDIAN
#include <linux/byteorder/little_endian.h>
#else
#include <linux/byteorder/big_endian.h>
#endif
/* * * Functions declaration * * */
void *int_info_copy(int_info *dst, const int_info *src);
void ints_array_htons(short *netshort, int nmemb);
void ints_array_ntohs(short *hostshort, int nmemb);
void ints_array_htonl(int *netlong, int nmemb);
void ints_array_ntohl(int *hostlong, int nmemb);
void ints_network_to_host(void *s, int_info iinfo);
void ints_host_to_network(void *s, int_info iinfo);
void ints_printf(void *s, int_info iinfo, void(*print_func(const char *, ...)));
#endif /*ENDIANNESS_H*/

69
src/err_errno.c Normal file
View File

@ -0,0 +1,69 @@
/**************************************
* AUTHOR: Federico Tomassini *
* Copyright (C) Federico Tomassini *
* Contact effetom@gmail.com *
***********************************************
***** ******
*************************************************************************
* *
* 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 2 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. *
* *
************************************************************************/
#include "err_errno.h"
static const char *err_strings[] = {
"UFO error -o-", /* ERR_UFOERR */
"Malformed Label Octet.", /* ERR_DNSMLO */
"Malformed Sequence Label.", /* ERR_DNSMSL */
"Malformed Dns Packet.", /* ERR_DNSMDP */
"Malformed Dns Data.", /* ERR_DNSMDD */
"Too many Recursive Pointers.", /* ERR_DNSTRP */
"Dns Packet Len Break.", /* ERR_DNSPLB */
"Pointer To Pointer error.", /* ERR_DNSPTP */
"Malformed Data.", /* ERR_DNSMDA */
"Error Packing Dns Struct.", /* ERR_DNSPDS */
/**/
"Malformed Andna Packet.", /* ERR_ANDMAP */
"Andns Packet Len Break.", /* ERR_ANDPLB */
"Malformed Andns Data.", /* ERR_ANDMAD */
"Andna Not Compatbile Query.", /* ERR_ANDNCQ */
/**/
"Error reading resolv.conf.", /* ERR_RSLERC */
"Andns init error.", /* ERR_RSLAIE */
"There isn't No NameServer.", /* ERR_RSLNNS */
"Error Forwarding DNS Query.", /* ERR_RSLFDQ */
"Resolution Error.", /* ERR_RSLRSL */
"Andns Query Discarded.", /* ERR_RSLAQD */
/**/
"mark_init error!.", /* ERR_NETINI */
"netfilter table not loadable.", /* ERR_NETFIL */
"error adding netfilter rules.", /* ERR_NETRUL */
"error committing netfilter rules.", /* ERR_NETCOM */
"error initializing ntk_mark_chain.", /* ERR_NETCHA */
"netfilter delete error.", /* ERR_NETDEL */
"error storing rules.", /* ERR_NETSTO */
"Nefilter was not restored.", /* ERR_NETRST */
/**/
"SNSD main record not found.", /* ERR_SNDMRF */
"SNSD recursion failed.", /* ERR_SNDRCS */
/**/
"Zlib Compression Fail.", /* ERR_ZLIBCP */
"Zlib Uncompression Fail.", /* ERR_ZLIBUP */
"Zlib compression is useless.", /* ERR_ZLIBNU */
};
const char *__err_strerror(int n)
{
int __n=-((n)+1);
return (__n>=ERR_NERR || __n<0) ? ERR_OVERFLOW : err_strings[__n];
}

95
src/err_errno.h Normal file
View File

@ -0,0 +1,95 @@
/**************************************
* AUTHOR: Federico Tomassini *
* Copyright (C) Federico Tomassini *
* Contact effetom@gmail.com *
***********************************************
***** ******
*************************************************************************
* *
* 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 2 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. *
* *
************************************************************************/
#ifndef ERR_ERRNO_H
#define ERR_ERRNO_H
#include <errno.h>
#include <string.h>
#include <stdlib.h>
#define ERR_UFOERR -1
#define ERR_DNSMLO -2
#define ERR_DNSMSL -3
#define ERR_DNSMDP -4
#define ERR_DNSMDD -5
#define ERR_DNSTRP -6
#define ERR_DNSPLB -7
#define ERR_DNSPTP -8
#define ERR_DNSMDA -9
#define ERR_DNSPDS -10
#define ERR_ANDMAP -11
#define ERR_ANDPLB -12
#define ERR_ANDMAD -13
#define ERR_ANDNCQ -14
#define ERR_RSLERC -15
#define ERR_RSLAIE -16
#define ERR_RSLNNS -17
#define ERR_RSLFDQ -18
#define ERR_RSLRSL -19
#define ERR_RSLAQD -20
#define ERR_MRKINI -21
#define ERR_NETFIL -22
#define ERR_NETRUL -23
#define ERR_NETCOM -24
#define ERR_NETCHA -25
#define ERR_NETDEL -26
#define ERR_NETSTO -27
#define ERR_NETRST -28
#define ERR_SNDMRF -29
#define ERR_SNDRCS -30
#define ERR_ZLIBCP -31
#define ERR_ZLIBUP -32
#define ERR_ZLIBNU -33
#define ERR_TOTAL_ERRS (-(ERR_ZLIBNU))
#define ERR_OVERFLOW "Error number does not exist."
/* END OF DEFS */
/*
* Core
*/
const char *err_func,*err_file;
#define ERR_NERR (ERR_TOTAL_ERRS)
#define err_seterrno(n) errno=(n);err_func=__func__; \
err_file=__FILE__
#define err_ret(n,ret) {err_seterrno(n);return ret;}
#define err_intret(n) {err_seterrno(n);return -1;}
#define err_voidret(n) {err_seterrno(n);return NULL;}
#define err_strerror(e) \
((e)>=0)? \
strerror(e): \
__err_strerror(e)
#define ERR_FORMAT "In %s(): %s() returns -> %s"
#define err_str ERR_FORMAT,__func__, \
err_func,__err_strerror(errno)
const char *__err_strerror(int n);
#endif /* ERR_ERRNO_H */

1493
src/gmap.c Normal file

File diff suppressed because it is too large Load Diff

270
src/gmap.h Normal file
View File

@ -0,0 +1,270 @@
/* This file is part of Netsukuku
* (c) Copyright 2004 Andrea Lo Pumo aka AlpT <alpt@freaknet.org>
*
* This source code 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 2 of the License,
* or (at your option) any later version.
*
* This source code 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.
* Please refer to the GNU Public License for more details.
*
* You should have received a copy of the GNU Public License along with
* this source code; if not, write to:
* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#ifndef GMAP_H
#define GMAP_H
#include "llist.c"
#include "map.h"
/* * * Groupnode stuff * * */
#define GMAP_ME MAP_ME /*1*/
#define GMAP_VOID MAP_VOID /*(1<<1)*/
#define GMAP_HGNODE (1<<2) /*Hooked Gnode. We already hooked at
this gnode */
#define GMAP_FULL (1<<3) /*The gnode is full!! aaahh, run away!*/
/* This is the holy external_map. Each struct corresponds to a groupnode.
* This groupnode cointains MAXGROUPNODE nodes if we are at level 1 or
* MAXGROUPNODE groups. The map is equal to the int_map, in fact, a map_node
* is embedded in a map_gnode.
* This int_map uses the QSPN_MAP_STYLEII (see qspn.h). */
typedef struct
{
/*
* The gnode_map starts here. Note that it is a normal map. (See map.h).
* It is here, at the top of the struct to allow to manipulate a map_gnode
* as a map_node with the help of the magic cast. The cast is heavily
* used in qspn.c
*/
map_node g;
u_char flags;
u_char seeds; /*The number of active static nodes connected to this
gnode minus one (the root_node is not counted).
If seeds == MAXGROUPNODE-1, the gnode is full ^_^*/
u_int gcount; /*The total number of nodes which are inside this
gnode*/
} map_gnode;
INT_INFO map_gnode_iinfo = { 1,
{ INT_TYPE_32BIT },
{ MAP_NODE_PACK_SZ+sizeof(u_char)*2 },
{ 1 }
};
#define MAP_GNODE_PACK_SZ (MAP_NODE_PACK_SZ+sizeof(u_char)*2+sizeof(int))
/*
* * * * Levels notes * * *
*
* These are the levels of the external_map. Note that the 0 level is never used
* for the ext_map because it corresponds to the internal map. Btw the 0 level is
* counted so the number of LEVELS includes it too.
* But we have to add another extra level: the last exiled level. It is also never
* used but it is vital, cause, its gnode 0 includes the entire Netsukuku, the other
* gnodes aren't used, it is a mere symbol. We call it the unity level.
*
* All the structs/arrays related to the external map, and the ext_map itself, don't
* use the EXTRA_LEVELS, thus, they lack of the zero level. To retrieve the position
* in the array from the level the _EL macro must be used. In other words:
* because the arrays goes from 0 to n-1 we refer to the levels as the arrays,
* so the level 1 is the level 0, the level 2 is the level 1, and so on.
* These arrays/structs are: quadg.gnode, rblock, ext_map, qspn_gnode_count.
*/
#define ZERO_LEVEL 1
#define UNITY_LEVEL 1
#define EXTRA_LEVELS (ZERO_LEVEL + UNITY_LEVEL)
/* To use the right level. */
#define _EL(level) ((level)-1)
/* And to restore it. */
#define _NL(level) ((level)+1)
/*
* Using MAXGROUPNODE = 2^8; IPV4_LEVELS = 3; ips = 2^32;
* ips/(MAXGROUPNODE^IPV4_LEVELS) == 256;
* If we use IPV4_LEVELS = 3, we almost cover all the ips, but the division gives
* 256. So there are only 256 groups in the last level (3), in fact:
* ips/(256 * (MAXGROUPNODE^3)) == 1
* And to include them we use the unity level, thus IPV4_LEVELS is equal to 3+1.
* This means that the unity level is the one which has only one group node which includes
* the entire network.
* Sadly we cannot use all this ips, because there are the banned classes (MULTICAST,
* ZERONET), the kernel will sput on us.
*
* For the ipv6 we have IPV6_LEVELS = 16, ips = 2^128; so:
* ips/(MAXGROUPNODE^16) == 1
*/
#define IPV4_LEVELS (2+EXTRA_LEVELS)
#define IPV6_LEVELS (14+EXTRA_LEVELS)
#define MAX_LEVELS IPV6_LEVELS
#ifdef DEBUG
#define GET_LEVELS(family) \
({ \
if((family) != AF_INET && (family) != AF_INET6) \
fatal("GET_LEVELS: family not specified!"); \
(family) == AF_INET ? IPV4_LEVELS : IPV6_LEVELS; \
})
#else
#define GET_LEVELS(family) ({ (family)==AF_INET ? IPV4_LEVELS : IPV6_LEVELS; })
#endif
#define FAMILY_LVLS (GET_LEVELS(my_family))
/* NODES_PER_LEVEL: returns the maximum number of nodes which can reside in
* a gnode of the `lvl'th level */
#define NODES_PER_LEVEL(lvl) ((1<<(MAXGROUPNODE_BITS*(lvl))))
/* Struct used to keep all the quadro_group ids of a node. (The node is part of this
* quadro groups) */
typedef struct {
u_char levels; /*How many levels we have*/
int gid[MAX_LEVELS]; /*Group ids. Each element is the gid of the quadrogroup in the
relative level. (ex: gid[n] is the gid of the quadropgroup a
the n-th level)*/
map_gnode *gnode[MAX_LEVELS-ZERO_LEVEL]; /*Each element is a pointer to the relative
gnode in the ext_map.*/
inet_prefix ipstart[MAX_LEVELS]; /*The ipstart of each quadg.gid in their respective levels*/
}quadro_group;
/* Note: this is the int_info of the a packed quadro_group struct, which
* hasnt't the `map_gnode *gnode' pointers. The ipstart structs must be also
* packed with pack_inet_prefix() */
INT_INFO quadro_group_iinfo = { 1,
{ INT_TYPE_32BIT },
{ sizeof(u_char) },
{ MAX_LEVELS }
};
#define QUADRO_GROUP_PACK_SZ (sizeof(u_char) + sizeof(int)*MAX_LEVELS + \
+ INET_PREFIX_PACK_SZ * MAX_LEVELS)
/*These are the flags passed to iptoquadg()*/
#define QUADG_IPSTART 1
#define QUADG_GID (1<<1)
#define QUADG_GNODE (1<<2)
/* This block is used to send the ext_map */
struct ext_map_hdr
{
char quadg[QUADRO_GROUP_PACK_SZ]; /* The packed me.cur_quadg */
size_t ext_map_sz; /*It's the sum of all the gmaps_sz.
The size of a single map is:
(ext_map_sz/(MAP_GNODE_PACK_SZ*
(quadg.levels-EXTRA_LEVELS)); */
size_t rblock_sz[MAX_LEVELS]; /*The size of the rblock of each gmap*/
size_t total_rblock_sz; /*The sum of all rblock_sz*/
}_PACKED_;
/* Note: You have to consider the quadro_group struct when convert between
* endianness */
INT_INFO ext_map_hdr_iinfo = { 3,
{ INT_TYPE_32BIT, INT_TYPE_32BIT, INT_TYPE_32BIT },
{ QUADRO_GROUP_PACK_SZ,
QUADRO_GROUP_PACK_SZ+sizeof(size_t),
QUADRO_GROUP_PACK_SZ+(sizeof(size_t)*(MAX_LEVELS+1)) },
{ 1, MAX_LEVELS, 1 }
};
/* The ext_map_block is:
* struct ext_map_hdr hdr;
* char ext_map[ext_map_sz];
* char rnode_blocks[total_rblock_sz];
*/
#define EXT_MAP_BLOCK_SZ(ext_map_sz, rblock_sz) (sizeof(struct ext_map_hdr)+(ext_map_sz)+(rblock_sz))
/*
* This struct is used by the root_node to describe all the rnodes which
* doesn't belongs to our same gnode.
*/
typedef struct {
map_node node;
quadro_group quadg; /* quadg.gnode[level] may be set to 0
* if that gnode doesn't belong to the
* same upper level of me.cur_quadg:
* quadg.gid[level+1] != me.cur_quadg.gid[level+1]
*/
}ext_rnode;
/*This cache keeps the list of all the ext_rnode used.*/
struct ext_rnode_cache {
LLIST_HDR (struct ext_rnode_cache);
ext_rnode *e; /*The pointer to the ext_rnode struct*/
int rnode_pos; /*The ext_rnode position in the
array of rnodes of the root_node */
};
typedef struct ext_rnode_cache ext_rnode_cache;
/* * * Functions' declaration * * */
inline int get_groups(int family, int lvl);
int is_group_invalid(int *gids, int gid, int lvl, int family);
int pos_from_gnode(map_gnode *gnode, map_gnode *map);
map_gnode * gnode_from_pos(int pos, map_gnode *map);
void rnodetoip(u_int mapstart, u_int maprnode, inet_prefix ipstart, inet_prefix *ret);
const char *rnode_to_ipstr(u_int mapstart, u_int maprnode, inet_prefix ipstart);
int iptogid(inet_prefix *ip, int level);
void iptogids(inet_prefix *ip, int *gid, int levels);
void gidtoipstart(int *gid, u_char total_levels, u_char levels, int family,
inet_prefix *ip);
void iptoquadg(inet_prefix ip, map_gnode **ext_map, quadro_group *qg, char flags);
void quadg_setflags(quadro_group *qg, char flags);
void quadg_free(quadro_group *qg);
void quadg_destroy(quadro_group *qg);
void gnode_inc_seeds(quadro_group *qg, int level);
void gnode_dec_seeds(quadro_group *qg, int level);
void pack_quadro_group(quadro_group *qg, char *pack);
void unpack_quadro_group(quadro_group *qg, char *pack);
int free_gids(quadro_group *qg, int level, map_gnode **ext_map, map_node *int_map);
int void_gids(quadro_group *qg, int level, map_gnode **ext_map, map_node *int_map);
int random_ip(inet_prefix *ipstart, int final_level, int final_gid,
int total_levels, map_gnode **ext_map, int only_free_gnode,
inet_prefix *new_ip, int my_family);
void gnodetoip(quadro_group *quadg, int gnodeid, u_char level, inet_prefix *ip);
int gids_cmp(int *gids_a, int *gids_b, int lvl, int max_lvl);
int quadg_gids_cmp(quadro_group a, quadro_group b, int lvl);
int ip_gids_cmp(inet_prefix a, inet_prefix b, int lvl);
ext_rnode_cache *erc_find(ext_rnode_cache *erc, ext_rnode *e_rnode);
void e_rnode_del(ext_rnode_cache **erc_head, u_int *counter, ext_rnode_cache *erc);
void e_rnode_add(ext_rnode_cache **erc, ext_rnode *e_rnode, int rnode_pos, u_int *counter);
ext_rnode_cache *e_rnode_init(u_int *counter);
void e_rnode_free(ext_rnode_cache **erc, u_int *counter);
ext_rnode_cache *e_rnode_find(ext_rnode_cache *erc, quadro_group *qg, int level);
void erc_update_rnodepos(ext_rnode_cache *erc, map_node *root_node, int old_rnode_pos);
void erc_reorder_rnodepos(ext_rnode_cache **erc, u_int *erc_counter, map_node *root_node);
ext_rnode_cache *erc_find_gnode(ext_rnode_cache *erc, map_gnode *gnode, u_char level);
map_gnode *init_gmap(int groups);
void reset_gmap(map_gnode *gmap, int groups);
map_gnode **init_extmap(u_char levels, int groups);
void free_extmap(map_gnode **ext_map, u_char levels, int groups);
void reset_extmap(map_gnode **ext_map, u_char levels, int groups);
int g_rnode_find(map_gnode *gnode, map_gnode *n);
int extmap_find_level(map_gnode **ext_map, map_gnode *gnode, u_char max_level);
void gmap_node_del(map_gnode *gnode);
int merge_ext_maps(map_gnode **base, map_gnode **new, quadro_group base_root,
quadro_group new_root);
int verify_ext_map_hdr(struct ext_map_hdr *emap_hdr, quadro_group *quadg);
void free_extmap_rblock(map_rnode **rblock, u_char levels);
void pack_map_gnode(map_gnode *gnode, char *pack);
void unpack_map_gnode(map_gnode *gnode, char *pack);
char *pack_extmap(map_gnode **ext_map, int maxgroupnode, quadro_group *quadg, size_t *pack_sz);
map_gnode **unpack_extmap(char *package, quadro_group *quadg);
int save_extmap(map_gnode **ext_map, int maxgroupnode, quadro_group *quadg, char *file);
map_gnode **load_extmap(char *file, quadro_group *quadg);
#endif /*GMAP_H*/

166
src/hash.c Normal file
View File

@ -0,0 +1,166 @@
/* This file is part of Netsukuku
* (c) Copyright 2005 Andrea Lo Pumo aka AlpT <alpt@freaknet.org>
*
* This source code 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 2 of the License,
* or (at your option) any later version.
*
* This source code 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.
* Please refer to the GNU Public License for more details.
*
* You should have received a copy of the GNU Public License along with
* this source code; if not, write to:
* Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* --
* hash.c: hash functions
*/
#include "includes.h"
#include "hash.h"
/* Robert Jenkins's 32 bit Mix Function */
unsigned int inthash(unsigned int key)
{
key += (key << 12);
key ^= (key >> 22);
key += (key << 4);
key ^= (key >> 9);
key += (key << 10);
key ^= (key >> 2);
key += (key << 7);
key ^= (key >> 12);
return key;
}
/* Ripped 32bit Hash function
*
* Fowler/Noll/Vo hash
*
* See http://www.isthe.com/chongo/tech/comp/fnv/index.html
* for more details as well as other forms of the FNV hash.
*
***
*
* Use the recommended 32 bit FNV-1 hash, pass FNV1_32_INIT as the
* u_long hashval argument to fnv_32_buf().
*
***
*
* Please do not copyright this code. This code is in the public domain.
*
* LANDON CURT NOLL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO
* EVENT SHALL LANDON CURT NOLL BE LIABLE FOR ANY SPECIAL, INDIRECT OR
* CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
* USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*
* By:
* chongo <Landon Curt Noll> /\oo/\
* http://www.isthe.com/chongo/
* Share and Enjoy! :-)
*
* fnv_32_buf - perform a 32 bit Fowler/Noll/Vo hash on a buffer
* `hval' - previous hash value or 0 if first call
* returns:
* 32 bit hash as a static hash type
*/
u_long fnv_32_buf(void *buf, size_t len, u_long hval)
{
u_char *bp = (u_char *)buf; /* start of buffer */
u_char *be = bp + len; /* beyond end of buffer */
/*
* FNV-1 hash each octet in the buffer
*/
while (bp < be) {
/* multiply by the 32 bit FNV magic prime mod 2^32 */
hval += (hval<<1) + (hval<<4) + (hval<<7) + (hval<<8) + (hval<<24);
/* xor the bottom with the current octet */
hval ^= (u_long)*bp++;
}
/* return our new hash value */
return hval;
}
/*
* Ripped from glibc.
* This is the hashing function specified by the ELF ABI. In the
* first five operations no overflow is possible so we optimized it a
* bit.
*/
inline unsigned int dl_elf_hash (const unsigned char *name)
{
unsigned long int hash = 0;
if (*name != '\0') {
hash = *name++;
if (*name != '\0') {
hash = (hash << 4) + *name++;
if (*name != '\0') {
hash = (hash << 4) + *name++;
if (*name != '\0') {
hash = (hash << 4) + *name++;
if (*name != '\0') {
hash = (hash << 4) + *name++;
while (*name != '\0') {
unsigned long int hi;
hash = (hash << 4) + *name++;
hi = hash & 0xf0000000;
/* The algorithm specified in the ELF ABI is as
follows:
if (hi != 0)
hash ^= hi >> 24;
hash &= ~hi;
But the following is equivalent and a lot
faster, especially on modern processors. */
hash ^= hi;
hash ^= hi >> 24;
}
}
}
}
}
}
return hash;
}
/*
* hash_time: As the name says: hash time!
* This function generates the hash of the timeval struct which refer
* to the current time.
* If h_sec or h_usec are not null, it stores in them respectively the hash of
* the second and the microsecond.
*/
int hash_time(int *h_sec, int *h_usec)
{
struct timeval t;
char str[sizeof(struct timeval)+1];
u_int elf_hash;
gettimeofday(&t, 0);
memcpy(str, &t, sizeof(struct timeval));
str[sizeof(struct timeval)]=0;
elf_hash=dl_elf_hash((u_char *)str);
if(h_sec)
*h_sec=inthash(t.tv_sec);
if(h_usec)
*h_usec=inthash(t.tv_usec);
return inthash(elf_hash);
}

Some files were not shown because too many files have changed in this diff Show More