From 2a103687b6c08c95b96ccf447ef096bc7e54d7ae Mon Sep 17 00:00:00 2001 From: Emmanuel Bretelle Date: Tue, 7 Sep 2010 17:01:20 +0200 Subject: [PATCH] Move common sgsnemu/ggsn files to directory "lib" Some files like in sgsnemu and ggsn directory where exactly the same. They are now moved to the same directory for easier maintenance Signed-off-by: Emmanuel Bretelle --- acinclude.m4 | 4 +- configure.in | 2 + ggsn/Makefile.am | 5 +- ggsn/ggsn.c | 6 +- {ggsn => lib}/getopt.c | 0 {ggsn => lib}/getopt1.c | 0 {ggsn => lib}/gnugetopt.h | 0 {ggsn => lib}/ippool.c | 0 {ggsn => lib}/ippool.h | 0 {ggsn => lib}/lookup.c | 0 {ggsn => lib}/lookup.h | 0 {ggsn => lib}/syserr.c | 0 {ggsn => lib}/syserr.h | 0 {ggsn => lib}/tun.c | 0 {ggsn => lib}/tun.h | 0 sgsnemu/Makefile.am | 5 +- sgsnemu/getopt.c | 1055 ------------------------------------- sgsnemu/getopt1.c | 188 ------- sgsnemu/gnugetopt.h | 180 ------- sgsnemu/ippool.c | 526 ------------------ sgsnemu/ippool.h | 105 ---- sgsnemu/lookup.c | 80 --- sgsnemu/lookup.h | 25 - sgsnemu/sgsnemu.c | 6 +- sgsnemu/syserr.c | 71 --- sgsnemu/syserr.h | 21 - sgsnemu/tun.c | 897 ------------------------------- sgsnemu/tun.h | 74 --- 28 files changed, 18 insertions(+), 3232 deletions(-) rename {ggsn => lib}/getopt.c (100%) rename {ggsn => lib}/getopt1.c (100%) rename {ggsn => lib}/gnugetopt.h (100%) rename {ggsn => lib}/ippool.c (100%) rename {ggsn => lib}/ippool.h (100%) rename {ggsn => lib}/lookup.c (100%) rename {ggsn => lib}/lookup.h (100%) rename {ggsn => lib}/syserr.c (100%) rename {ggsn => lib}/syserr.h (100%) rename {ggsn => lib}/tun.c (100%) rename {ggsn => lib}/tun.h (100%) delete mode 100644 sgsnemu/getopt.c delete mode 100644 sgsnemu/getopt1.c delete mode 100644 sgsnemu/gnugetopt.h delete mode 100644 sgsnemu/ippool.c delete mode 100644 sgsnemu/ippool.h delete mode 100755 sgsnemu/lookup.c delete mode 100755 sgsnemu/lookup.h delete mode 100644 sgsnemu/syserr.c delete mode 100644 sgsnemu/syserr.h delete mode 100644 sgsnemu/tun.c delete mode 100644 sgsnemu/tun.h diff --git a/acinclude.m4 b/acinclude.m4 index 2aea10b..c20fab5 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -13,5 +13,5 @@ AC_DEFUN([adl_FUNC_GETOPT_LONG], [# use the GNU replacement AC_LIBOBJ(getopt) AC_LIBOBJ(getopt1) - AC_CONFIG_LINKS([ggsn/getopt.h:ggsn/gnugetopt.h]) - AC_CONFIG_LINKS([sgsnemu/getopt.h:sgsnemu/gnugetopt.h])])])]) + AC_CONFIG_LINKS([lib/getopt.h:lib/gnugetopt.h])])])]) + diff --git a/configure.in b/configure.in index bfd2bea..bd55028 100644 --- a/configure.in +++ b/configure.in @@ -14,6 +14,8 @@ AC_PROG_CPP AC_PROG_CXX AC_PROG_RANLIB +AC_CONFIG_MACRO_DIR([m4]) +AC_CONFIG_LIBOBJ_DIR([lib]) #JJAKO Check for libtool AC_PROG_LIBTOOL diff --git a/ggsn/Makefile.am b/ggsn/Makefile.am index c15f767..0aff773 100644 --- a/ggsn/Makefile.am +++ b/ggsn/Makefile.am @@ -1,5 +1,7 @@ bin_PROGRAMS = ggsn +AUTOMAKE_OPTIONS = subdir-objects + AM_LDFLAGS = @EXEC_LDFLAGS@ AM_CFLAGS = -O2 -D_GNU_SOURCE -fno-builtin -Wall -DSBINDIR='"$(sbindir)"' -ggdb @@ -8,5 +10,6 @@ ggsn_LDADD = @LIBOBJS@ @EXEC_LDADD@ -lgtp -L../gtp #ggsn_DEPENDENCIES = ../gtp/libgtp.la -ggsn_SOURCES = ggsn.c tun.c tun.h cmdline.c cmdline.h ippool.h ippool.c syserr.h syserr.c lookup.c lookup.h +ggsn_SOURCES = ggsn.c ../lib/tun.c ../lib/tun.h cmdline.c cmdline.h ../lib/ippool.h ../lib/ippool.c ../lib/syserr.h ../lib/syserr.c ../lib/lookup.c ../lib/lookup.h +#ggsn_SOURCES = ggsn.c cmdline.c cmdline.h diff --git a/ggsn/ggsn.c b/ggsn/ggsn.c index 8b71884..57116ce 100644 --- a/ggsn/ggsn.c +++ b/ggsn/ggsn.c @@ -47,9 +47,9 @@ #include -#include "tun.h" -#include "ippool.h" -#include "syserr.h" +#include "../lib/tun.h" +#include "../lib/ippool.h" +#include "../lib/syserr.h" #include "../gtp/pdp.h" #include "../gtp/gtp.h" #include "cmdline.h" diff --git a/ggsn/getopt.c b/lib/getopt.c similarity index 100% rename from ggsn/getopt.c rename to lib/getopt.c diff --git a/ggsn/getopt1.c b/lib/getopt1.c similarity index 100% rename from ggsn/getopt1.c rename to lib/getopt1.c diff --git a/ggsn/gnugetopt.h b/lib/gnugetopt.h similarity index 100% rename from ggsn/gnugetopt.h rename to lib/gnugetopt.h diff --git a/ggsn/ippool.c b/lib/ippool.c similarity index 100% rename from ggsn/ippool.c rename to lib/ippool.c diff --git a/ggsn/ippool.h b/lib/ippool.h similarity index 100% rename from ggsn/ippool.h rename to lib/ippool.h diff --git a/ggsn/lookup.c b/lib/lookup.c similarity index 100% rename from ggsn/lookup.c rename to lib/lookup.c diff --git a/ggsn/lookup.h b/lib/lookup.h similarity index 100% rename from ggsn/lookup.h rename to lib/lookup.h diff --git a/ggsn/syserr.c b/lib/syserr.c similarity index 100% rename from ggsn/syserr.c rename to lib/syserr.c diff --git a/ggsn/syserr.h b/lib/syserr.h similarity index 100% rename from ggsn/syserr.h rename to lib/syserr.h diff --git a/ggsn/tun.c b/lib/tun.c similarity index 100% rename from ggsn/tun.c rename to lib/tun.c diff --git a/ggsn/tun.h b/lib/tun.h similarity index 100% rename from ggsn/tun.h rename to lib/tun.h diff --git a/sgsnemu/Makefile.am b/sgsnemu/Makefile.am index f2f930d..eecd9fd 100644 --- a/sgsnemu/Makefile.am +++ b/sgsnemu/Makefile.am @@ -1,5 +1,7 @@ bin_PROGRAMS = sgsnemu +AUTOMAKE_OPTIONS = subdir-objects + AM_LDFLAGS = @EXEC_LDFLAGS@ AM_CFLAGS = -O2 -D_GNU_SOURCE -fno-builtin -Wall -DSBINDIR='"$(sbindir)"' -ggdb @@ -8,4 +10,5 @@ sgsnemu_LDADD = @LIBOBJS@ @EXEC_LDADD@ -lgtp -L../gtp #sgsnemu_DEPENDENCIES = ../gtp/libgtp.la -sgsnemu_SOURCES = sgsnemu.c tun.c tun.h cmdline.c cmdline.h ippool.h ippool.c syserr.h syserr.c lookup.c lookup.h +sgsnemu_SOURCES = sgsnemu.c ../lib/tun.c ../lib/tun.h cmdline.c cmdline.h ../lib/ippool.h ../lib/ippool.c ../lib/syserr.h ../lib/syserr.c ../lib/lookup.c ../lib/lookup.h +#sgsnemu_SOURCES = sgsnemu.c cmdline.c cmdline.h diff --git a/sgsnemu/getopt.c b/sgsnemu/getopt.c deleted file mode 100644 index 9bafa45..0000000 --- a/sgsnemu/getopt.c +++ /dev/null @@ -1,1055 +0,0 @@ -/* Getopt for GNU. - NOTE: getopt is now part of the C library, so if you don't know what - "Keep this file name-space clean" means, talk to drepper@gnu.org - before changing it! - Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001 - Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -/* This tells Alpha OSF/1 not to define a getopt prototype in . - Ditto for AIX 3.2 and . */ -#ifndef _NO_PROTO -# define _NO_PROTO -#endif - -#ifdef HAVE_CONFIG_H -# include -#endif - -#if !defined __STDC__ || !__STDC__ -/* This is a separate conditional since some stdc systems - reject `defined (const)'. */ -# ifndef const -# define const -# endif -#endif - -#include - -/* Comment out all this code if we are using the GNU C Library, and are not - actually compiling the library itself. This code is part of the GNU C - Library, but also included in many other GNU distributions. Compiling - and linking in this code is a waste when using the GNU C library - (especially if it is a shared library). Rather than having every GNU - program understand `configure --with-gnu-libc' and omit the object files, - it is simpler to just do this in the source for each such file. */ - -#define GETOPT_INTERFACE_VERSION 2 -#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 -# include -# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION -# define ELIDE_CODE -# endif -#endif - -#ifndef ELIDE_CODE - - -/* This needs to come after some library #include - to get __GNU_LIBRARY__ defined. */ -#ifdef __GNU_LIBRARY__ -/* Don't include stdlib.h for non-GNU C libraries because some of them - contain conflicting prototypes for getopt. */ -# include -# include -#endif /* GNU C library. */ - -#ifdef VMS -# include -# if HAVE_STRING_H - 0 -# include -# endif -#endif - -#ifndef _ -/* This is for other GNU distributions with internationalized messages. */ -# if defined HAVE_LIBINTL_H || defined _LIBC -# include -# ifndef _ -# define _(msgid) gettext (msgid) -# endif -# else -# define _(msgid) (msgid) -# endif -#endif - -/* This version of `getopt' appears to the caller like standard Unix `getopt' - but it behaves differently for the user, since it allows the user - to intersperse the options with the other arguments. - - As `getopt' works, it permutes the elements of ARGV so that, - when it is done, all the options precede everything else. Thus - all application programs are extended to handle flexible argument order. - - Setting the environment variable POSIXLY_CORRECT disables permutation. - Then the behavior is completely standard. - - GNU application programs can use a third alternative mode in which - they can distinguish the relative order of options and other arguments. */ - -#include "getopt.h" - -/* For communication from `getopt' to the caller. - When `getopt' finds an option that takes an argument, - the argument value is returned here. - Also, when `ordering' is RETURN_IN_ORDER, - each non-option ARGV-element is returned here. */ - -char *optarg; - -/* Index in ARGV of the next element to be scanned. - This is used for communication to and from the caller - and for communication between successive calls to `getopt'. - - On entry to `getopt', zero means this is the first call; initialize. - - When `getopt' returns -1, this is the index of the first of the - non-option elements that the caller should itself scan. - - Otherwise, `optind' communicates from one call to the next - how much of ARGV has been scanned so far. */ - -/* 1003.2 says this must be 1 before any call. */ -int optind = 1; - -/* Formerly, initialization of getopt depended on optind==0, which - causes problems with re-calling getopt as programs generally don't - know that. */ - -int __getopt_initialized; - -/* The next char to be scanned in the option-element - in which the last option character we returned was found. - This allows us to pick up the scan where we left off. - - If this is zero, or a null string, it means resume the scan - by advancing to the next ARGV-element. */ - -static char *nextchar; - -/* Callers store zero here to inhibit the error message - for unrecognized options. */ - -int opterr = 1; - -/* Set to an option character which was unrecognized. - This must be initialized on some systems to avoid linking in the - system's own getopt implementation. */ - -int optopt = '?'; - -/* Describe how to deal with options that follow non-option ARGV-elements. - - If the caller did not specify anything, - the default is REQUIRE_ORDER if the environment variable - POSIXLY_CORRECT is defined, PERMUTE otherwise. - - REQUIRE_ORDER means don't recognize them as options; - stop option processing when the first non-option is seen. - This is what Unix does. - This mode of operation is selected by either setting the environment - variable POSIXLY_CORRECT, or using `+' as the first character - of the list of option characters. - - PERMUTE is the default. We permute the contents of ARGV as we scan, - so that eventually all the non-options are at the end. This allows options - to be given in any order, even with programs that were not written to - expect this. - - RETURN_IN_ORDER is an option available to programs that were written - to expect options and other ARGV-elements in any order and that care about - the ordering of the two. We describe each non-option ARGV-element - as if it were the argument of an option with character code 1. - Using `-' as the first character of the list of option characters - selects this mode of operation. - - The special argument `--' forces an end of option-scanning regardless - of the value of `ordering'. In the case of RETURN_IN_ORDER, only - `--' can cause `getopt' to return -1 with `optind' != ARGC. */ - -static enum -{ - REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER -} ordering; - -/* Value of POSIXLY_CORRECT environment variable. */ -static char *posixly_correct; - -#ifdef __GNU_LIBRARY__ -/* We want to avoid inclusion of string.h with non-GNU libraries - because there are many ways it can cause trouble. - On some systems, it contains special magic macros that don't work - in GCC. */ -# include -# define my_index strchr -#else - -# if HAVE_STRING_H -# include -# else -# include -# endif - -/* Avoid depending on library functions or files - whose names are inconsistent. */ - -#ifndef getenv -extern char *getenv (); -#endif - -static char * -my_index (str, chr) - const char *str; - int chr; -{ - while (*str) - { - if (*str == chr) - return (char *) str; - str++; - } - return 0; -} - -/* If using GCC, we can safely declare strlen this way. - If not using GCC, it is ok not to declare it. */ -#ifdef __GNUC__ -/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h. - That was relevant to code that was here before. */ -# if (!defined __STDC__ || !__STDC__) && !defined strlen -/* gcc with -traditional declares the built-in strlen to return int, - and has done so at least since version 2.4.5. -- rms. */ -extern int strlen (const char *); -# endif /* not __STDC__ */ -#endif /* __GNUC__ */ - -#endif /* not __GNU_LIBRARY__ */ - -/* Handle permutation of arguments. */ - -/* Describe the part of ARGV that contains non-options that have - been skipped. `first_nonopt' is the index in ARGV of the first of them; - `last_nonopt' is the index after the last of them. */ - -static int first_nonopt; -static int last_nonopt; - -#ifdef _LIBC -/* Stored original parameters. - XXX This is no good solution. We should rather copy the args so - that we can compare them later. But we must not use malloc(3). */ -extern int __libc_argc; -extern char **__libc_argv; - -/* Bash 2.0 gives us an environment variable containing flags - indicating ARGV elements that should not be considered arguments. */ - -# ifdef USE_NONOPTION_FLAGS -/* Defined in getopt_init.c */ -extern char *__getopt_nonoption_flags; - -static int nonoption_flags_max_len; -static int nonoption_flags_len; -# endif - -# ifdef USE_NONOPTION_FLAGS -# define SWAP_FLAGS(ch1, ch2) \ - if (nonoption_flags_len > 0) \ - { \ - char __tmp = __getopt_nonoption_flags[ch1]; \ - __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \ - __getopt_nonoption_flags[ch2] = __tmp; \ - } -# else -# define SWAP_FLAGS(ch1, ch2) -# endif -#else /* !_LIBC */ -# define SWAP_FLAGS(ch1, ch2) -#endif /* _LIBC */ - -/* Exchange two adjacent subsequences of ARGV. - One subsequence is elements [first_nonopt,last_nonopt) - which contains all the non-options that have been skipped so far. - The other is elements [last_nonopt,optind), which contains all - the options processed since those non-options were skipped. - - `first_nonopt' and `last_nonopt' are relocated so that they describe - the new indices of the non-options in ARGV after they are moved. */ - -#if defined __STDC__ && __STDC__ -static void exchange (char **); -#endif - -static void -exchange (argv) - char **argv; -{ - int bottom = first_nonopt; - int middle = last_nonopt; - int top = optind; - char *tem; - - /* Exchange the shorter segment with the far end of the longer segment. - That puts the shorter segment into the right place. - It leaves the longer segment in the right place overall, - but it consists of two parts that need to be swapped next. */ - -#if defined _LIBC && defined USE_NONOPTION_FLAGS - /* First make sure the handling of the `__getopt_nonoption_flags' - string can work normally. Our top argument must be in the range - of the string. */ - if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len) - { - /* We must extend the array. The user plays games with us and - presents new arguments. */ - char *new_str = malloc (top + 1); - if (new_str == NULL) - nonoption_flags_len = nonoption_flags_max_len = 0; - else - { - memset (__mempcpy (new_str, __getopt_nonoption_flags, - nonoption_flags_max_len), - '\0', top + 1 - nonoption_flags_max_len); - nonoption_flags_max_len = top + 1; - __getopt_nonoption_flags = new_str; - } - } -#endif - - while (top > middle && middle > bottom) - { - if (top - middle > middle - bottom) - { - /* Bottom segment is the short one. */ - int len = middle - bottom; - register int i; - - /* Swap it with the top part of the top segment. */ - for (i = 0; i < len; i++) - { - tem = argv[bottom + i]; - argv[bottom + i] = argv[top - (middle - bottom) + i]; - argv[top - (middle - bottom) + i] = tem; - SWAP_FLAGS (bottom + i, top - (middle - bottom) + i); - } - /* Exclude the moved bottom segment from further swapping. */ - top -= len; - } - else - { - /* Top segment is the short one. */ - int len = top - middle; - register int i; - - /* Swap it with the bottom part of the bottom segment. */ - for (i = 0; i < len; i++) - { - tem = argv[bottom + i]; - argv[bottom + i] = argv[middle + i]; - argv[middle + i] = tem; - SWAP_FLAGS (bottom + i, middle + i); - } - /* Exclude the moved top segment from further swapping. */ - bottom += len; - } - } - - /* Update records for the slots the non-options now occupy. */ - - first_nonopt += (optind - last_nonopt); - last_nonopt = optind; -} - -/* Initialize the internal data when the first call is made. */ - -#if defined __STDC__ && __STDC__ -static const char *_getopt_initialize (int, char *const *, const char *); -#endif -static const char * -_getopt_initialize (argc, argv, optstring) - int argc; - char *const *argv; - const char *optstring; -{ - /* Start processing options with ARGV-element 1 (since ARGV-element 0 - is the program name); the sequence of previously skipped - non-option ARGV-elements is empty. */ - - first_nonopt = last_nonopt = optind; - - nextchar = NULL; - - posixly_correct = getenv ("POSIXLY_CORRECT"); - - /* Determine how to handle the ordering of options and nonoptions. */ - - if (optstring[0] == '-') - { - ordering = RETURN_IN_ORDER; - ++optstring; - } - else if (optstring[0] == '+') - { - ordering = REQUIRE_ORDER; - ++optstring; - } - else if (posixly_correct != NULL) - ordering = REQUIRE_ORDER; - else - ordering = PERMUTE; - -#if defined _LIBC && defined USE_NONOPTION_FLAGS - if (posixly_correct == NULL - && argc == __libc_argc && argv == __libc_argv) - { - if (nonoption_flags_max_len == 0) - { - if (__getopt_nonoption_flags == NULL - || __getopt_nonoption_flags[0] == '\0') - nonoption_flags_max_len = -1; - else - { - const char *orig_str = __getopt_nonoption_flags; - int len = nonoption_flags_max_len = strlen (orig_str); - if (nonoption_flags_max_len < argc) - nonoption_flags_max_len = argc; - __getopt_nonoption_flags = - (char *) malloc (nonoption_flags_max_len); - if (__getopt_nonoption_flags == NULL) - nonoption_flags_max_len = -1; - else - memset (__mempcpy (__getopt_nonoption_flags, orig_str, len), - '\0', nonoption_flags_max_len - len); - } - } - nonoption_flags_len = nonoption_flags_max_len; - } - else - nonoption_flags_len = 0; -#endif - - return optstring; -} - -/* Scan elements of ARGV (whose length is ARGC) for option characters - given in OPTSTRING. - - If an element of ARGV starts with '-', and is not exactly "-" or "--", - then it is an option element. The characters of this element - (aside from the initial '-') are option characters. If `getopt' - is called repeatedly, it returns successively each of the option characters - from each of the option elements. - - If `getopt' finds another option character, it returns that character, - updating `optind' and `nextchar' so that the next call to `getopt' can - resume the scan with the following option character or ARGV-element. - - If there are no more option characters, `getopt' returns -1. - Then `optind' is the index in ARGV of the first ARGV-element - that is not an option. (The ARGV-elements have been permuted - so that those that are not options now come last.) - - OPTSTRING is a string containing the legitimate option characters. - If an option character is seen that is not listed in OPTSTRING, - return '?' after printing an error message. If you set `opterr' to - zero, the error message is suppressed but we still return '?'. - - If a char in OPTSTRING is followed by a colon, that means it wants an arg, - so the following text in the same ARGV-element, or the text of the following - ARGV-element, is returned in `optarg'. Two colons mean an option that - wants an optional arg; if there is text in the current ARGV-element, - it is returned in `optarg', otherwise `optarg' is set to zero. - - If OPTSTRING starts with `-' or `+', it requests different methods of - handling the non-option ARGV-elements. - See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. - - Long-named options begin with `--' instead of `-'. - Their names may be abbreviated as long as the abbreviation is unique - or is an exact match for some defined option. If they have an - argument, it follows the option name in the same ARGV-element, separated - from the option name by a `=', or else the in next ARGV-element. - When `getopt' finds a long-named option, it returns 0 if that option's - `flag' field is nonzero, the value of the option's `val' field - if the `flag' field is zero. - - The elements of ARGV aren't really const, because we permute them. - But we pretend they're const in the prototype to be compatible - with other systems. - - LONGOPTS is a vector of `struct option' terminated by an - element containing a name which is zero. - - LONGIND returns the index in LONGOPT of the long-named option found. - It is only valid when a long-named option has been found by the most - recent call. - - If LONG_ONLY is nonzero, '-' as well as '--' can introduce - long-named options. */ - -int -_getopt_internal (argc, argv, optstring, longopts, longind, long_only) - int argc; - char *const *argv; - const char *optstring; - const struct option *longopts; - int *longind; - int long_only; -{ - int print_errors = opterr; - if (optstring[0] == ':') - print_errors = 0; - - if (argc < 1) - return -1; - - optarg = NULL; - - if (optind == 0 || !__getopt_initialized) - { - if (optind == 0) - optind = 1; /* Don't scan ARGV[0], the program name. */ - optstring = _getopt_initialize (argc, argv, optstring); - __getopt_initialized = 1; - } - - /* Test whether ARGV[optind] points to a non-option argument. - Either it does not have option syntax, or there is an environment flag - from the shell indicating it is not an option. The later information - is only used when the used in the GNU libc. */ -#if defined _LIBC && defined USE_NONOPTION_FLAGS -# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \ - || (optind < nonoption_flags_len \ - && __getopt_nonoption_flags[optind] == '1')) -#else -# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0') -#endif - - if (nextchar == NULL || *nextchar == '\0') - { - /* Advance to the next ARGV-element. */ - - /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been - moved back by the user (who may also have changed the arguments). */ - if (last_nonopt > optind) - last_nonopt = optind; - if (first_nonopt > optind) - first_nonopt = optind; - - if (ordering == PERMUTE) - { - /* If we have just processed some options following some non-options, - exchange them so that the options come first. */ - - if (first_nonopt != last_nonopt && last_nonopt != optind) - exchange ((char **) argv); - else if (last_nonopt != optind) - first_nonopt = optind; - - /* Skip any additional non-options - and extend the range of non-options previously skipped. */ - - while (optind < argc && NONOPTION_P) - optind++; - last_nonopt = optind; - } - - /* The special ARGV-element `--' means premature end of options. - Skip it like a null option, - then exchange with previous non-options as if it were an option, - then skip everything else like a non-option. */ - - if (optind != argc && !strcmp (argv[optind], "--")) - { - optind++; - - if (first_nonopt != last_nonopt && last_nonopt != optind) - exchange ((char **) argv); - else if (first_nonopt == last_nonopt) - first_nonopt = optind; - last_nonopt = argc; - - optind = argc; - } - - /* If we have done all the ARGV-elements, stop the scan - and back over any non-options that we skipped and permuted. */ - - if (optind == argc) - { - /* Set the next-arg-index to point at the non-options - that we previously skipped, so the caller will digest them. */ - if (first_nonopt != last_nonopt) - optind = first_nonopt; - return -1; - } - - /* If we have come to a non-option and did not permute it, - either stop the scan or describe it to the caller and pass it by. */ - - if (NONOPTION_P) - { - if (ordering == REQUIRE_ORDER) - return -1; - optarg = argv[optind++]; - return 1; - } - - /* We have found another option-ARGV-element. - Skip the initial punctuation. */ - - nextchar = (argv[optind] + 1 - + (longopts != NULL && argv[optind][1] == '-')); - } - - /* Decode the current option-ARGV-element. */ - - /* Check whether the ARGV-element is a long option. - - If long_only and the ARGV-element has the form "-f", where f is - a valid short option, don't consider it an abbreviated form of - a long option that starts with f. Otherwise there would be no - way to give the -f short option. - - On the other hand, if there's a long option "fubar" and - the ARGV-element is "-fu", do consider that an abbreviation of - the long option, just like "--fu", and not "-f" with arg "u". - - This distinction seems to be the most useful approach. */ - - if (longopts != NULL - && (argv[optind][1] == '-' - || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1]))))) - { - char *nameend; - const struct option *p; - const struct option *pfound = NULL; - int exact = 0; - int ambig = 0; - int indfound = -1; - int option_index; - - for (nameend = nextchar; *nameend && *nameend != '='; nameend++) - /* Do nothing. */ ; - - /* Test all long options for either exact match - or abbreviated matches. */ - for (p = longopts, option_index = 0; p->name; p++, option_index++) - if (!strncmp (p->name, nextchar, nameend - nextchar)) - { - if ((unsigned int) (nameend - nextchar) - == (unsigned int) strlen (p->name)) - { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } - else if (pfound == NULL) - { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } - else if (long_only - || pfound->has_arg != p->has_arg - || pfound->flag != p->flag - || pfound->val != p->val) - /* Second or later nonexact match found. */ - ambig = 1; - } - - if (ambig && !exact) - { - if (print_errors) - fprintf (stderr, _("%s: option `%s' is ambiguous\n"), - argv[0], argv[optind]); - nextchar += strlen (nextchar); - optind++; - optopt = 0; - return '?'; - } - - if (pfound != NULL) - { - option_index = indfound; - optind++; - if (*nameend) - { - /* Don't test has_arg with >, because some C compilers don't - allow it to be used on enums. */ - if (pfound->has_arg) - optarg = nameend + 1; - else - { - if (print_errors) - { - if (argv[optind - 1][1] == '-') - /* --option */ - fprintf (stderr, - _("%s: option `--%s' doesn't allow an argument\n"), - argv[0], pfound->name); - else - /* +option or -option */ - fprintf (stderr, - _("%s: option `%c%s' doesn't allow an argument\n"), - argv[0], argv[optind - 1][0], pfound->name); - } - - nextchar += strlen (nextchar); - - optopt = pfound->val; - return '?'; - } - } - else if (pfound->has_arg == 1) - { - if (optind < argc) - optarg = argv[optind++]; - else - { - if (print_errors) - fprintf (stderr, - _("%s: option `%s' requires an argument\n"), - argv[0], argv[optind - 1]); - nextchar += strlen (nextchar); - optopt = pfound->val; - return optstring[0] == ':' ? ':' : '?'; - } - } - nextchar += strlen (nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) - { - *(pfound->flag) = pfound->val; - return 0; - } - return pfound->val; - } - - /* Can't find it as a long option. If this is not getopt_long_only, - or the option starts with '--' or is not a valid short - option, then it's an error. - Otherwise interpret it as a short option. */ - if (!long_only || argv[optind][1] == '-' - || my_index (optstring, *nextchar) == NULL) - { - if (print_errors) - { - if (argv[optind][1] == '-') - /* --option */ - fprintf (stderr, _("%s: unrecognized option `--%s'\n"), - argv[0], nextchar); - else - /* +option or -option */ - fprintf (stderr, _("%s: unrecognized option `%c%s'\n"), - argv[0], argv[optind][0], nextchar); - } - nextchar = (char *) ""; - optind++; - optopt = 0; - return '?'; - } - } - - /* Look at and handle the next short option-character. */ - - { - char c = *nextchar++; - char *temp = my_index (optstring, c); - - /* Increment `optind' when we start to process its last character. */ - if (*nextchar == '\0') - ++optind; - - if (temp == NULL || c == ':') - { - if (print_errors) - { - if (posixly_correct) - /* 1003.2 specifies the format of this message. */ - fprintf (stderr, _("%s: illegal option -- %c\n"), - argv[0], c); - else - fprintf (stderr, _("%s: invalid option -- %c\n"), - argv[0], c); - } - optopt = c; - return '?'; - } - /* Convenience. Treat POSIX -W foo same as long option --foo */ - if (temp[0] == 'W' && temp[1] == ';') - { - char *nameend; - const struct option *p; - const struct option *pfound = NULL; - int exact = 0; - int ambig = 0; - int indfound = 0; - int option_index; - - /* This is an option that requires an argument. */ - if (*nextchar != '\0') - { - optarg = nextchar; - /* If we end this ARGV-element by taking the rest as an arg, - we must advance to the next element now. */ - optind++; - } - else if (optind == argc) - { - if (print_errors) - { - /* 1003.2 specifies the format of this message. */ - fprintf (stderr, _("%s: option requires an argument -- %c\n"), - argv[0], c); - } - optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = '?'; - return c; - } - else - /* We already incremented `optind' once; - increment it again when taking next ARGV-elt as argument. */ - optarg = argv[optind++]; - - /* optarg is now the argument, see if it's in the - table of longopts. */ - - for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++) - /* Do nothing. */ ; - - /* Test all long options for either exact match - or abbreviated matches. */ - for (p = longopts, option_index = 0; p->name; p++, option_index++) - if (!strncmp (p->name, nextchar, nameend - nextchar)) - { - if ((unsigned int) (nameend - nextchar) == strlen (p->name)) - { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } - else if (pfound == NULL) - { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } - else - /* Second or later nonexact match found. */ - ambig = 1; - } - if (ambig && !exact) - { - if (print_errors) - fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"), - argv[0], argv[optind]); - nextchar += strlen (nextchar); - optind++; - return '?'; - } - if (pfound != NULL) - { - option_index = indfound; - if (*nameend) - { - /* Don't test has_arg with >, because some C compilers don't - allow it to be used on enums. */ - if (pfound->has_arg) - optarg = nameend + 1; - else - { - if (print_errors) - fprintf (stderr, _("\ -%s: option `-W %s' doesn't allow an argument\n"), - argv[0], pfound->name); - - nextchar += strlen (nextchar); - return '?'; - } - } - else if (pfound->has_arg == 1) - { - if (optind < argc) - optarg = argv[optind++]; - else - { - if (print_errors) - fprintf (stderr, - _("%s: option `%s' requires an argument\n"), - argv[0], argv[optind - 1]); - nextchar += strlen (nextchar); - return optstring[0] == ':' ? ':' : '?'; - } - } - nextchar += strlen (nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) - { - *(pfound->flag) = pfound->val; - return 0; - } - return pfound->val; - } - nextchar = NULL; - return 'W'; /* Let the application handle it. */ - } - if (temp[1] == ':') - { - if (temp[2] == ':') - { - /* This is an option that accepts an argument optionally. */ - if (*nextchar != '\0') - { - optarg = nextchar; - optind++; - } - else - optarg = NULL; - nextchar = NULL; - } - else - { - /* This is an option that requires an argument. */ - if (*nextchar != '\0') - { - optarg = nextchar; - /* If we end this ARGV-element by taking the rest as an arg, - we must advance to the next element now. */ - optind++; - } - else if (optind == argc) - { - if (print_errors) - { - /* 1003.2 specifies the format of this message. */ - fprintf (stderr, - _("%s: option requires an argument -- %c\n"), - argv[0], c); - } - optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = '?'; - } - else - /* We already incremented `optind' once; - increment it again when taking next ARGV-elt as argument. */ - optarg = argv[optind++]; - nextchar = NULL; - } - } - return c; - } -} - -int -getopt (argc, argv, optstring) - int argc; - char *const *argv; - const char *optstring; -{ - return _getopt_internal (argc, argv, optstring, - (const struct option *) 0, - (int *) 0, - 0); -} - -#endif /* Not ELIDE_CODE. */ - -#ifdef TEST - -/* Compile with -DTEST to make an executable for use in testing - the above definition of `getopt'. */ - -int -main (argc, argv) - int argc; - char **argv; -{ - int c; - int digit_optind = 0; - - while (1) - { - int this_option_optind = optind ? optind : 1; - - c = getopt (argc, argv, "abc:d:0123456789"); - if (c == -1) - break; - - switch (c) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (digit_optind != 0 && digit_optind != this_option_optind) - printf ("digits occur in two different argv-elements.\n"); - digit_optind = this_option_optind; - printf ("option %c\n", c); - break; - - case 'a': - printf ("option a\n"); - break; - - case 'b': - printf ("option b\n"); - break; - - case 'c': - printf ("option c with value `%s'\n", optarg); - break; - - case '?': - break; - - default: - printf ("?? getopt returned character code 0%o ??\n", c); - } - } - - if (optind < argc) - { - printf ("non-option ARGV-elements: "); - while (optind < argc) - printf ("%s ", argv[optind++]); - printf ("\n"); - } - - exit (0); -} - -#endif /* TEST */ diff --git a/sgsnemu/getopt1.c b/sgsnemu/getopt1.c deleted file mode 100644 index 22a7efb..0000000 --- a/sgsnemu/getopt1.c +++ /dev/null @@ -1,188 +0,0 @@ -/* getopt_long and getopt_long_only entry points for GNU getopt. - Copyright (C) 1987,88,89,90,91,92,93,94,96,97,98 - Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include "getopt.h" - -#if !defined __STDC__ || !__STDC__ -/* This is a separate conditional since some stdc systems - reject `defined (const)'. */ -#ifndef const -#define const -#endif -#endif - -#include - -/* Comment out all this code if we are using the GNU C Library, and are not - actually compiling the library itself. This code is part of the GNU C - Library, but also included in many other GNU distributions. Compiling - and linking in this code is a waste when using the GNU C library - (especially if it is a shared library). Rather than having every GNU - program understand `configure --with-gnu-libc' and omit the object files, - it is simpler to just do this in the source for each such file. */ - -#define GETOPT_INTERFACE_VERSION 2 -#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2 -#include -#if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION -#define ELIDE_CODE -#endif -#endif - -#ifndef ELIDE_CODE - - -/* This needs to come after some library #include - to get __GNU_LIBRARY__ defined. */ -#ifdef __GNU_LIBRARY__ -#include -#endif - -#ifndef NULL -#define NULL 0 -#endif - -int -getopt_long (argc, argv, options, long_options, opt_index) - int argc; - char *const *argv; - const char *options; - const struct option *long_options; - int *opt_index; -{ - return _getopt_internal (argc, argv, options, long_options, opt_index, 0); -} - -/* Like getopt_long, but '-' as well as '--' can indicate a long option. - If an option that starts with '-' (not '--') doesn't match a long option, - but does match a short option, it is parsed as a short option - instead. */ - -int -getopt_long_only (argc, argv, options, long_options, opt_index) - int argc; - char *const *argv; - const char *options; - const struct option *long_options; - int *opt_index; -{ - return _getopt_internal (argc, argv, options, long_options, opt_index, 1); -} - - -#endif /* Not ELIDE_CODE. */ - -#ifdef TEST - -#include - -int -main (argc, argv) - int argc; - char **argv; -{ - int c; - int digit_optind = 0; - - while (1) - { - int this_option_optind = optind ? optind : 1; - int option_index = 0; - static struct option long_options[] = - { - {"add", 1, 0, 0}, - {"append", 0, 0, 0}, - {"delete", 1, 0, 0}, - {"verbose", 0, 0, 0}, - {"create", 0, 0, 0}, - {"file", 1, 0, 0}, - {0, 0, 0, 0} - }; - - c = getopt_long (argc, argv, "abc:d:0123456789", - long_options, &option_index); - if (c == -1) - break; - - switch (c) - { - case 0: - printf ("option %s", long_options[option_index].name); - if (optarg) - printf (" with arg %s", optarg); - printf ("\n"); - break; - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (digit_optind != 0 && digit_optind != this_option_optind) - printf ("digits occur in two different argv-elements.\n"); - digit_optind = this_option_optind; - printf ("option %c\n", c); - break; - - case 'a': - printf ("option a\n"); - break; - - case 'b': - printf ("option b\n"); - break; - - case 'c': - printf ("option c with value `%s'\n", optarg); - break; - - case 'd': - printf ("option d with value `%s'\n", optarg); - break; - - case '?': - break; - - default: - printf ("?? getopt returned character code 0%o ??\n", c); - } - } - - if (optind < argc) - { - printf ("non-option ARGV-elements: "); - while (optind < argc) - printf ("%s ", argv[optind++]); - printf ("\n"); - } - - exit (0); -} - -#endif /* TEST */ diff --git a/sgsnemu/gnugetopt.h b/sgsnemu/gnugetopt.h deleted file mode 100644 index a1b8dd6..0000000 --- a/sgsnemu/gnugetopt.h +++ /dev/null @@ -1,180 +0,0 @@ -/* Declarations for getopt. - Copyright (C) 1989-1994, 1996-1999, 2001 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in 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 - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, write to the Free - Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA - 02111-1307 USA. */ - -#ifndef _GETOPT_H - -#ifndef __need_getopt -# define _GETOPT_H 1 -#endif - -/* If __GNU_LIBRARY__ is not already defined, either we are being used - standalone, or this is the first header included in the source file. - If we are being used with glibc, we need to include , but - that does not exist if we are standalone. So: if __GNU_LIBRARY__ is - not defined, include , which will pull in for us - if it's from glibc. (Why ctype.h? It's guaranteed to exist and it - doesn't flood the namespace with stuff the way some other headers do.) */ -#if !defined __GNU_LIBRARY__ -# include -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/* For communication from `getopt' to the caller. - When `getopt' finds an option that takes an argument, - the argument value is returned here. - Also, when `ordering' is RETURN_IN_ORDER, - each non-option ARGV-element is returned here. */ - -extern char *optarg; - -/* Index in ARGV of the next element to be scanned. - This is used for communication to and from the caller - and for communication between successive calls to `getopt'. - - On entry to `getopt', zero means this is the first call; initialize. - - When `getopt' returns -1, this is the index of the first of the - non-option elements that the caller should itself scan. - - Otherwise, `optind' communicates from one call to the next - how much of ARGV has been scanned so far. */ - -extern int optind; - -/* Callers store zero here to inhibit the error message `getopt' prints - for unrecognized options. */ - -extern int opterr; - -/* Set to an option character which was unrecognized. */ - -extern int optopt; - -#ifndef __need_getopt -/* Describe the long-named options requested by the application. - The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector - of `struct option' terminated by an element containing a name which is - zero. - - The field `has_arg' is: - no_argument (or 0) if the option does not take an argument, - required_argument (or 1) if the option requires an argument, - optional_argument (or 2) if the option takes an optional argument. - - If the field `flag' is not NULL, it points to a variable that is set - to the value given in the field `val' when the option is found, but - left unchanged if the option is not found. - - To have a long-named option do something other than set an `int' to - a compiled-in constant, such as set a value from `optarg', set the - option's `flag' field to zero and its `val' field to a nonzero - value (the equivalent single-letter option character, if there is - one). For long options that have a zero `flag' field, `getopt' - returns the contents of the `val' field. */ - -struct option -{ -# if (defined __STDC__ && __STDC__) || defined __cplusplus - const char *name; -# else - char *name; -# endif - /* has_arg can't be an enum because some compilers complain about - type mismatches in all the code that assumes it is an int. */ - int has_arg; - int *flag; - int val; -}; - -/* Names for the values of the `has_arg' field of `struct option'. */ - -# define no_argument 0 -# define required_argument 1 -# define optional_argument 2 -#endif /* need getopt */ - - -/* Get definitions and prototypes for functions to process the - arguments in ARGV (ARGC of them, minus the program name) for - options given in OPTS. - - Return the option character from OPTS just read. Return -1 when - there are no more options. For unrecognized options, or options - missing arguments, `optopt' is set to the option letter, and '?' is - returned. - - The OPTS string is a list of characters which are recognized option - letters, optionally followed by colons, specifying that that letter - takes an argument, to be placed in `optarg'. - - If a letter in OPTS is followed by two colons, its argument is - optional. This behavior is specific to the GNU `getopt'. - - The argument `--' causes premature termination of argument - scanning, explicitly telling `getopt' that there are no more - options. - - If OPTS begins with `--', then non-option arguments are treated as - arguments to the option '\0'. This behavior is specific to the GNU - `getopt'. */ - -#if (defined __STDC__ && __STDC__) || defined __cplusplus -# ifdef __GNU_LIBRARY__ -/* Many other libraries have conflicting prototypes for getopt, with - differences in the consts, in stdlib.h. To avoid compilation - errors, only prototype getopt for the GNU C library. */ -extern int getopt (int __argc, char *const *__argv, const char *__shortopts); -# else /* not __GNU_LIBRARY__ */ -extern int getopt (); -# endif /* __GNU_LIBRARY__ */ - -# ifndef __need_getopt -extern int getopt_long (int __argc, char *const *__argv, const char *__shortopts, - const struct option *__longopts, int *__longind); -extern int getopt_long_only (int __argc, char *const *__argv, - const char *__shortopts, - const struct option *__longopts, int *__longind); - -/* Internal only. Users should not call this directly. */ -extern int _getopt_internal (int __argc, char *const *__argv, - const char *__shortopts, - const struct option *__longopts, int *__longind, - int __long_only); -# endif -#else /* not __STDC__ */ -extern int getopt (); -# ifndef __need_getopt -extern int getopt_long (); -extern int getopt_long_only (); - -extern int _getopt_internal (); -# endif -#endif /* __STDC__ */ - -#ifdef __cplusplus -} -#endif - -/* Make sure we later can get all the definitions and declarations. */ -#undef __need_getopt - -#endif /* getopt.h */ diff --git a/sgsnemu/ippool.c b/sgsnemu/ippool.c deleted file mode 100644 index fa3d8af..0000000 --- a/sgsnemu/ippool.c +++ /dev/null @@ -1,526 +0,0 @@ -/* - * IP address pool functions. - * Copyright (C) 2003, 2004 Mondru AB. - * - * The contents of this file may be used under the terms of the GNU - * General Public License Version 2, provided that the above copyright - * notice and this permission notice is included in all copies or - * substantial portions of the software. - * - */ - -#include -#include /* in_addr */ -#include /* calloc */ -#include /* sscanf */ -#include -#include -#include -#include -#include "syserr.h" -#include "ippool.h" -#include "lookup.h" - - -int ippool_printaddr(struct ippool_t *this) { - unsigned int n; - printf("ippool_printaddr\n"); - printf("Firstdyn %d\n", this->firstdyn - this->member); - printf("Lastdyn %d\n", this->lastdyn - this->member); - printf("Firststat %d\n", this->firststat - this->member); - printf("Laststat %d\n", this->laststat - this->member); - printf("Listsize %d\n", this->listsize); - - for (n=0; nlistsize; n++) { - printf("Unit %d inuse %d prev %d next %d addr %s %x\n", - n, - this->member[n].inuse, - this->member[n].prev - this->member, - this->member[n].next - this->member, - inet_ntoa(this->member[n].addr), - this->member[n].addr.s_addr - ); - } - return 0; -} - -int ippool_hashadd(struct ippool_t *this, struct ippoolm_t *member) { - uint32_t hash; - struct ippoolm_t *p; - struct ippoolm_t *p_prev = NULL; - - /* Insert into hash table */ - hash = ippool_hash4(&member->addr) & this->hashmask; - for (p = this->hash[hash]; p; p = p->nexthash) - p_prev = p; - if (!p_prev) - this->hash[hash] = member; - else - p_prev->nexthash = member; - return 0; /* Always OK to insert */ -} - -int ippool_hashdel(struct ippool_t *this, struct ippoolm_t *member) { - uint32_t hash; - struct ippoolm_t *p; - struct ippoolm_t *p_prev = NULL; - - /* Find in hash table */ - hash = ippool_hash4(&member->addr) & this->hashmask; - for (p = this->hash[hash]; p; p = p->nexthash) { - if (p == member) { - break; - } - p_prev = p; - } - - if (p!= member) { - sys_err(LOG_ERR, __FILE__, __LINE__, 0, - "ippool_hashdel: Tried to delete member not in hash table"); - return -1; - } - - if (!p_prev) - this->hash[hash] = p->nexthash; - else - p_prev->nexthash = p->nexthash; - - return 0; -} - - -unsigned long int ippool_hash4(struct in_addr *addr) { - return lookup((unsigned char*) &addr->s_addr, sizeof(addr->s_addr), 0); -} - -#ifndef IPPOOL_NOIP6 -unsigned long int ippool_hash6(struct in6_addr *addr) { - return lookup((unsigned char*) addr->u6_addr8, sizeof(addr->u6_addr8), 0); -} -#endif - - -/* Get IP address and mask */ -int ippool_aton(struct in_addr *addr, struct in_addr *mask, - char *pool, int number) { - - /* Parse only first instance of network for now */ - /* Eventually "number" will indicate the token which we want to parse */ - - unsigned int a1, a2, a3, a4; - unsigned int m1, m2, m3, m4; - int c; - int m; - int masklog; - - c = sscanf(pool, "%u.%u.%u.%u/%u.%u.%u.%u", - &a1, &a2, &a3, &a4, - &m1, &m2, &m3, &m4); - switch (c) { - case 4: - mask->s_addr = 0xffffffff; - break; - case 5: - if (m1 > 32) { - sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Invalid mask"); - return -1; /* Invalid mask */ - } - mask->s_addr = htonl(0xffffffff << (32 - m1)); - break; - case 8: - if (m1 >= 256 || m2 >= 256 || m3 >= 256 || m4 >= 256) { - sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Invalid mask"); - return -1; /* Wrong mask format */ - } - m = m1 * 0x1000000 + m2 * 0x10000 + m3 * 0x100 + m4; - for (masklog = 0; ((1 << masklog) < ((~m)+1)); masklog++); - if (((~m)+1) != (1 << masklog)) { - sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Invalid mask"); - return -1; /* Wrong mask format (not all ones followed by all zeros)*/ - } - mask->s_addr = htonl(m); - break; - default: - sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Invalid mask"); - return -1; /* Invalid mask */ - } - - if (a1 >= 256 || a2 >= 256 || a3 >= 256 || a4 >= 256) { - sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Wrong IP address format"); - return -1; - } - else - addr->s_addr = htonl(a1 * 0x1000000 + a2 * 0x10000 + a3 * 0x100 + a4); - - return 0; -} - -/* Create new address pool */ -int ippool_new(struct ippool_t **this, char *dyn, char *stat, - int allowdyn, int allowstat, int flags) { - - /* Parse only first instance of pool for now */ - - int i; - struct in_addr addr; - struct in_addr mask; - struct in_addr stataddr; - struct in_addr statmask; - unsigned int m; - int listsize; - int dynsize; - unsigned int statsize; - - if (!allowdyn) { - dynsize = 0; - } - else { - if (ippool_aton(&addr, &mask, dyn, 0)) { - sys_err(LOG_ERR, __FILE__, __LINE__, 0, - "Failed to parse dynamic pool"); - return -1; - } - - /* Set IPPOOL_NONETWORK if IPPOOL_NOGATEWAY is set */ - if (flags & IPPOOL_NOGATEWAY) { - flags |= IPPOOL_NONETWORK; - } - - m = ntohl(mask.s_addr); - dynsize = ((~m)+1); - if (flags & IPPOOL_NONETWORK) /* Exclude network address from pool */ - dynsize--; - if (flags & IPPOOL_NOGATEWAY) /* Exclude gateway address from pool */ - dynsize--; - if (flags & IPPOOL_NOBROADCAST) /* Exclude broadcast address from pool */ - dynsize--; - } - - if (!allowstat) { - statsize = 0; - stataddr.s_addr = 0; - statmask.s_addr = 0; - } - else { - if (ippool_aton(&stataddr, &statmask, stat, 0)) { - sys_err(LOG_ERR, __FILE__, __LINE__, 0, - "Failed to parse static range"); - return -1; - } - - m = ntohl(statmask.s_addr); - statsize = ((~m)+1); - if (statsize > IPPOOL_STATSIZE) statsize = IPPOOL_STATSIZE; - } - - listsize = dynsize + statsize; /* Allocate space for static IP addresses */ - - if (!(*this = calloc(sizeof(struct ippool_t), 1))) { - sys_err(LOG_ERR, __FILE__, __LINE__, 0, - "Failed to allocate memory for ippool"); - return -1; - } - - (*this)->allowdyn = allowdyn; - (*this)->allowstat = allowstat; - (*this)->stataddr = stataddr; - (*this)->statmask = statmask; - - (*this)->listsize += listsize; - if (!((*this)->member = calloc(sizeof(struct ippoolm_t), listsize))){ - sys_err(LOG_ERR, __FILE__, __LINE__, 0, - "Failed to allocate memory for members in ippool"); - return -1; - } - - for ((*this)->hashlog = 0; - ((1 << (*this)->hashlog) < listsize); - (*this)->hashlog++); - - /* printf ("Hashlog %d %d %d\n", (*this)->hashlog, listsize, (1 << (*this)->hashlog)); */ - - /* Determine hashsize */ - (*this)->hashsize = 1 << (*this)->hashlog; /* Fails if mask=0: All Internet*/ - (*this)->hashmask = (*this)->hashsize -1; - - /* Allocate hash table */ - if (!((*this)->hash = calloc(sizeof(struct ippoolm_t), (*this)->hashsize))){ - sys_err(LOG_ERR, __FILE__, __LINE__, 0, - "Failed to allocate memory for hash members in ippool"); - return -1; - } - - (*this)->firstdyn = NULL; - (*this)->lastdyn = NULL; - for (i = 0; imember[i].addr.s_addr = htonl(ntohl(addr.s_addr) + i + 2); - else if (flags & IPPOOL_NONETWORK) - (*this)->member[i].addr.s_addr = htonl(ntohl(addr.s_addr) + i + 1); - else - (*this)->member[i].addr.s_addr = htonl(ntohl(addr.s_addr) + i); - - (*this)->member[i].inuse = 0; - - /* Insert into list of unused */ - (*this)->member[i].prev = (*this)->lastdyn; - if ((*this)->lastdyn) { - (*this)->lastdyn->next = &((*this)->member[i]); - } - else { - (*this)->firstdyn = &((*this)->member[i]); - } - (*this)->lastdyn = &((*this)->member[i]); - (*this)->member[i].next = NULL; /* Redundant */ - - ( void)ippool_hashadd(*this, &(*this)->member[i]); - } - - (*this)->firststat = NULL; - (*this)->laststat = NULL; - for (i = dynsize; imember[i].addr.s_addr = 0; - (*this)->member[i].inuse = 0; - - /* Insert into list of unused */ - (*this)->member[i].prev = (*this)->laststat; - if ((*this)->laststat) { - (*this)->laststat->next = &((*this)->member[i]); - } - else { - (*this)->firststat = &((*this)->member[i]); - } - (*this)->laststat = &((*this)->member[i]); - (*this)->member[i].next = NULL; /* Redundant */ - } - - if (0) (void)ippool_printaddr(*this); - return 0; -} - - - -/* Delete existing address pool */ -int ippool_free(struct ippool_t *this) { - free(this->hash); - free(this->member); - free(this); - return 0; /* Always OK */ -} - -/* Find an IP address in the pool */ -int ippool_getip(struct ippool_t *this, struct ippoolm_t **member, - struct in_addr *addr) { - struct ippoolm_t *p; - uint32_t hash; - - /* Find in hash table */ - hash = ippool_hash4(addr) & this->hashmask; - for (p = this->hash[hash]; p; p = p->nexthash) { - if ((p->addr.s_addr == addr->s_addr) && (p->inuse)) { - if (member) *member = p; - return 0; - } - } - if (member) *member = NULL; - /*sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Address could not be found");*/ - return -1; -} - -/** - * ippool_newip - * Get an IP address. If addr = 0.0.0.0 get a dynamic IP address. Otherwise - * check to see if the given address is available. If available within - * dynamic address space allocate it there, otherwise allocate within static - * address space. -**/ -int ippool_newip(struct ippool_t *this, struct ippoolm_t **member, - struct in_addr *addr, int statip) { - struct ippoolm_t *p; - struct ippoolm_t *p2 = NULL; - uint32_t hash; - - /* If static: - * Look in dynaddr. - * If found remove from firstdyn/lastdyn linked list. - * Else allocate from stataddr. - * Remove from firststat/laststat linked list. - * Insert into hash table. - * - * If dynamic - * Remove from firstdyn/lastdyn linked list. - * - */ - - if (0) (void)ippool_printaddr(this); - - /* First check to see if this type of address is allowed */ - if ((addr) && (addr->s_addr) && statip) { /* IP address given */ - if (!this->allowstat) { - sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Static IP address not allowed"); - return -1; - } - if ((addr->s_addr & this->statmask.s_addr) != this->stataddr.s_addr) { - sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Static out of range"); - return -1; - } - } - else { - if (!this->allowdyn) { - sys_err(LOG_ERR, __FILE__, __LINE__, 0, - "Dynamic IP address not allowed"); - return -1; - } - } - - /* If IP address given try to find it in dynamic address pool */ - if ((addr) && (addr->s_addr)) { /* IP address given */ - /* Find in hash table */ - hash = ippool_hash4(addr) & this->hashmask; - for (p = this->hash[hash]; p; p = p->nexthash) { - if ((p->addr.s_addr == addr->s_addr)) { - p2 = p; - break; - } - } - } - - /* If IP was already allocated we can not use it */ - if ((!statip) && (p2) && (p2->inuse)) { - p2 = NULL; - } - - /* If not found yet and dynamic IP then allocate dynamic IP */ - if ((!p2) && (!statip)) { - if (!this ->firstdyn) { - sys_err(LOG_ERR, __FILE__, __LINE__, 0, - "No more IP addresses available"); - return -1; - } - else - p2 = this ->firstdyn; - } - - if (p2) { /* Was allocated from dynamic address pool */ - if (p2->inuse) { - sys_err(LOG_ERR, __FILE__, __LINE__, 0, - "IP address allready in use"); - return -1; /* Allready in use / Should not happen */ - } - - /* Remove from linked list of free dynamic addresses */ - if (p2->prev) - p2->prev->next = p2->next; - else - this->firstdyn = p2->next; - if (p2->next) - p2->next->prev = p2->prev; - else - this->lastdyn = p2->prev; - p2->next = NULL; - p2->prev = NULL; - p2->inuse = 1; /* Dynamic address in use */ - - *member = p2; - if (0) (void)ippool_printaddr(this); - return 0; /* Success */ - } - - /* It was not possible to allocate from dynamic address pool */ - /* Try to allocate from static address space */ - - if ((addr) && (addr->s_addr) && (statip)) { /* IP address given */ - if (!this->firststat) { - sys_err(LOG_ERR, __FILE__, __LINE__, 0, - "No more IP addresses available"); - return -1; /* No more available */ - } - else - p2 = this ->firststat; - - /* Remove from linked list of free static addresses */ - if (p2->prev) - p2->prev->next = p2->next; - else - this->firststat = p2->next; - if (p2->next) - p2->next->prev = p2->prev; - else - this->laststat = p2->prev; - p2->next = NULL; - p2->prev = NULL; - p2->inuse = 2; /* Static address in use */ - memcpy(&p2->addr, addr, sizeof(addr)); - *member = p2; - (void)ippool_hashadd(this, *member); - if (0) (void)ippool_printaddr(this); - return 0; /* Success */ - } - - sys_err(LOG_ERR, __FILE__, __LINE__, 0, - "Could not allocate IP address"); - return -1; /* Should never get here. TODO: Bad code */ -} - - -int ippool_freeip(struct ippool_t *this, struct ippoolm_t *member) { - - if (0) (void)ippool_printaddr(this); - - if (!member->inuse) { - sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Address not in use"); - return -1; /* Not in use: Should not happen */ - } - - switch (member->inuse) { - case 0: /* Not in use: Should not happen */ - sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Address not in use"); - return -1; - case 1: /* Allocated from dynamic address space */ - /* Insert into list of unused */ - member->prev = this->lastdyn; - if (this->lastdyn) { - this->lastdyn->next = member; - } - else { - this->firstdyn = member; - } - this->lastdyn = member; - - member->inuse = 0; - member->peer = NULL; - if (0) (void)ippool_printaddr(this); - return 0; - case 2: /* Allocated from static address space */ - if (ippool_hashdel(this, member)) - return -1; - /* Insert into list of unused */ - member->prev = this->laststat; - if (this->laststat) { - this->laststat->next = member; - } - else { - this->firststat = member; - } - this->laststat = member; - - member->inuse = 0; - member->addr.s_addr = 0; - member->peer = NULL; - member->nexthash = NULL; - if (0) (void)ippool_printaddr(this); - return 0; - default: /* Should not happen */ - sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Could not free IP address"); - return -1; - } -} - - -#ifndef IPPOOL_NOIP6 -extern unsigned long int ippool_hash6(struct in6_addr *addr); -extern int ippool_getip6(struct ippool_t *this, struct in6_addr *addr); -extern int ippool_returnip6(struct ippool_t *this, struct in6_addr *addr); -#endif diff --git a/sgsnemu/ippool.h b/sgsnemu/ippool.h deleted file mode 100644 index 02691a6..0000000 --- a/sgsnemu/ippool.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * IP address pool functions. - * Copyright (C) 2003, 2004 Mondru AB. - * - * The contents of this file may be used under the terms of the GNU - * General Public License Version 2, provided that the above copyright - * notice and this permission notice is included in all copies or - * substantial portions of the software. - * - */ - -#ifndef _IPPOOL_H -#define _IPPOOL_H - -/* Assuming that the address space is fragmented we need a hash table - in order to return the addresses. - - The list pool should provide for both IPv4 and IPv6 addresses. - - When initialising a new address pool it should be possible to pass - a string of CIDR format networks: "10.0.0.0/24 10.15.0.0/20" would - translate to 256 addresses starting at 10.0.0.0 and 1024 addresses - starting at 10.15.0.0. - - The above also applies to IPv6 which can be specified as described - in RFC2373. -*/ - -#define IPPOOL_NOIP6 - -#define IPPOOL_NONETWORK 0x01 -#define IPPOOL_NOBROADCAST 0x02 -#define IPPOOL_NOGATEWAY 0x04 - -#define IPPOOL_STATSIZE 0x10000 - -struct ippoolm_t; /* Forward declaration */ - -struct ippool_t { - unsigned int listsize; /* Total number of addresses */ - int allowdyn; /* Allow dynamic IP address allocation */ - int allowstat; /* Allow static IP address allocation */ - struct in_addr stataddr; /* Static address range network address */ - struct in_addr statmask; /* Static address range network mask */ - struct ippoolm_t *member; /* Listsize array of members */ - unsigned int hashsize; /* Size of hash table */ - int hashlog; /* Log2 size of hash table */ - int hashmask; /* Bitmask for calculating hash */ - struct ippoolm_t **hash; /* Hashsize array of pointer to member */ - struct ippoolm_t *firstdyn; /* Pointer to first free dynamic member */ - struct ippoolm_t *lastdyn; /* Pointer to last free dynamic member */ - struct ippoolm_t *firststat; /* Pointer to first free static member */ - struct ippoolm_t *laststat; /* Pointer to last free static member */ -}; - -struct ippoolm_t { -#ifndef IPPOOL_NOIP6 - struct in6_addr addr; /* IP address of this member */ -#else - struct in_addr addr; /* IP address of this member */ -#endif - int inuse; /* 0=available; 1= dynamic; 2 = static */ - struct ippoolm_t *nexthash; /* Linked list part of hash table */ - struct ippoolm_t *prev, *next; /* Linked list of free dynamic or static */ - void *peer; /* Pointer to peer protocol handler */ -}; - -/* The above structures require approximately 20+4 = 24 bytes for - each address (IPv4). For IPv6 the corresponding value is 32+4 = 36 - bytes for each address. */ - -/* Hash an IP address using code based on Bob Jenkins lookupa */ -extern unsigned long int ippool_hash4(struct in_addr *addr); - -/* Create new address pool */ -extern int ippool_new(struct ippool_t **this, char *dyn, char *stat, - int allowdyn, int allowstat, int flags); - -/* Delete existing address pool */ -extern int ippool_free(struct ippool_t *this); - -/* Find an IP address in the pool */ -extern int ippool_getip(struct ippool_t *this, struct ippoolm_t **member, - struct in_addr *addr); - -/* Get an IP address. If addr = 0.0.0.0 get a dynamic IP address. Otherwise - check to see if the given address is available */ -extern int ippool_newip(struct ippool_t *this, struct ippoolm_t **member, - struct in_addr *addr, int statip); - -/* Return a previously allocated IP address */ -extern int ippool_freeip(struct ippool_t *this, struct ippoolm_t *member); - -/* Get net and mask based on ascii string */ -extern int ippool_aton(struct in_addr *addr, struct in_addr *mask, - char *pool, int number); - - -#ifndef IPPOOL_NOIP6 -extern unsigned long int ippool_hash6(struct in6_addr *addr); -extern int ippool_getip6(struct ippool_t *this, struct in6_addr *addr); -extern int ippool_returnip6(struct ippool_t *this, struct in6_addr *addr); -#endif - -#endif /* !_IPPOOL_H */ diff --git a/sgsnemu/lookup.c b/sgsnemu/lookup.c deleted file mode 100755 index 02e2491..0000000 --- a/sgsnemu/lookup.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Hash lookup function. - * Copyright (C) 2003, 2004 Mondru AB. - * - * The contents of this file may be used under the terms of the GNU - * General Public License Version 2, provided that the above copyright - * notice and this permission notice is included in all copies or - * substantial portions of the software. - * - */ - -/** - * lookup() - * Generates a 32 bit hash. - * Based on public domain code by Bob Jenkins - * It should be one of the best hash functions around in terms of both - * statistical properties and speed. It is NOT recommended for cryptographic - * purposes. - **/ -unsigned long int lookup( k, length, level) -register unsigned char *k; /* the key */ -register unsigned long int length; /* the length of the key */ -register unsigned long int level; /* the previous hash, or an arbitrary value*/ -{ - -#define mix(a,b,c) \ -{ \ - a -= b; a -= c; a ^= (c>>13); \ - b -= c; b -= a; b ^= (a<<8); \ - c -= a; c -= b; c ^= (b>>13); \ - a -= b; a -= c; a ^= (c>>12); \ - b -= c; b -= a; b ^= (a<<16); \ - c -= a; c -= b; c ^= (b>>5); \ - a -= b; a -= c; a ^= (c>>3); \ - b -= c; b -= a; b ^= (a<<10); \ - c -= a; c -= b; c ^= (b>>15); \ -} - - typedef unsigned long int ub4; /* unsigned 4-byte quantities */ - typedef unsigned char ub1; /* unsigned 1-byte quantities */ - register unsigned long int a,b,c,len; - - /* Set up the internal state */ - len = length; - a = b = 0x9e3779b9; /* the golden ratio; an arbitrary value */ - c = level; /* the previous hash value */ - - /*---------------------------------------- handle most of the key */ - while (len >= 12) - { - a += (k[0] +((ub4)k[1]<<8) +((ub4)k[2]<<16) +((ub4)k[3]<<24)); - b += (k[4] +((ub4)k[5]<<8) +((ub4)k[6]<<16) +((ub4)k[7]<<24)); - c += (k[8] +((ub4)k[9]<<8) +((ub4)k[10]<<16)+((ub4)k[11]<<24)); - mix(a,b,c); - k += 12; len -= 12; - } - - /*------------------------------------- handle the last 11 bytes */ - c += length; - switch(len) /* all the case statements fall through */ - { - case 11: c+=((ub4)k[10]<<24); - case 10: c+=((ub4)k[9]<<16); - case 9 : c+=((ub4)k[8]<<8); - /* the first byte of c is reserved for the length */ - case 8 : b+=((ub4)k[7]<<24); - case 7 : b+=((ub4)k[6]<<16); - case 6 : b+=((ub4)k[5]<<8); - case 5 : b+=k[4]; - case 4 : a+=((ub4)k[3]<<24); - case 3 : a+=((ub4)k[2]<<16); - case 2 : a+=((ub4)k[1]<<8); - case 1 : a+=k[0]; - /* case 0: nothing left to add */ - } - mix(a,b,c); - /*-------------------------------------------- report the result */ - return c; -} - diff --git a/sgsnemu/lookup.h b/sgsnemu/lookup.h deleted file mode 100755 index 18b94c1..0000000 --- a/sgsnemu/lookup.h +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Hash lookup function. - * Copyright (C) 2003, 2004 Mondru AB. - * - * The contents of this file may be used under the terms of the GNU - * General Public License Version 2, provided that the above copyright - * notice and this permission notice is included in all copies or - * substantial portions of the software. - * - */ - -/** - * lookup() - * Generates a 32 bit hash. - * Based on public domain code by Bob Jenkins - * It should be one of the best hash functions around in terms of both - * statistical properties and speed. It is NOT recommended for cryptographic - * purposes. - **/ - -#ifndef _LOOKUP_H -#define _LOOKUP_H -unsigned long int lookup( unsigned char *k, unsigned long int length, unsigned long int level); - -#endif /* !_LOOKUP_H */ diff --git a/sgsnemu/sgsnemu.c b/sgsnemu/sgsnemu.c index ead8839..2675c0f 100644 --- a/sgsnemu/sgsnemu.c +++ b/sgsnemu/sgsnemu.c @@ -44,9 +44,9 @@ #include #include "config.h" -#include "tun.h" -#include "ippool.h" -#include "syserr.h" +#include "../lib/tun.h" +#include "../lib/ippool.h" +#include "../lib/syserr.h" #include "../gtp/pdp.h" #include "../gtp/gtp.h" #include "cmdline.h" diff --git a/sgsnemu/syserr.c b/sgsnemu/syserr.c deleted file mode 100644 index 002d8c3..0000000 --- a/sgsnemu/syserr.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Syslog functions. - * Copyright (C) 2003, 2004 Mondru AB. - * - * The contents of this file may be used under the terms of the GNU - * General Public License Version 2, provided that the above copyright - * notice and this permission notice is included in all copies or - * substantial portions of the software. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "syserr.h" - - -void sys_err(int pri, char *fn, int ln, int en, char *fmt, ...) { - va_list args; - char buf[SYSERR_MSGSIZE]; - - va_start(args, fmt); - vsnprintf(buf, SYSERR_MSGSIZE, fmt, args); - va_end(args); - buf[SYSERR_MSGSIZE-1] = 0; /* Make sure it is null terminated */ - if (en) - syslog(pri, "%s: %d: %d (%s) %s", fn, ln, en, strerror(en), buf); - else - syslog(pri, "%s: %d: %s", fn, ln, buf); -} - -void sys_errpack(int pri, char *fn, int ln, int en, struct sockaddr_in *peer, - void *pack, unsigned len, char *fmt, ...) { - - va_list args; - char buf[SYSERR_MSGSIZE]; - char buf2[SYSERR_MSGSIZE]; - unsigned int n; - int pos; - - va_start(args, fmt); - vsnprintf(buf, SYSERR_MSGSIZE, fmt, args); - va_end(args); - buf[SYSERR_MSGSIZE-1] = 0; - - snprintf(buf2, SYSERR_MSGSIZE, "Packet from %s:%u, length: %d, content:", - inet_ntoa(peer->sin_addr), - ntohs(peer->sin_port), - len); - buf2[SYSERR_MSGSIZE-1] = 0; - pos = strlen(buf2); - for(n=0; n -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined(__linux__) -#include -#include -#include -#include - -#elif defined (__FreeBSD__) -#include -#include - -#elif defined (__APPLE__) -#include - -#elif defined (__sun__) -#include -#include -#include -#include -/*#include "sun_if_tun.h"*/ - -#else -#error "Unknown platform!" -#endif - - -#include "tun.h" -#include "syserr.h" - - -#if defined(__linux__) - -int tun_nlattr(struct nlmsghdr *n, int nsize, int type, void *d, int dlen) -{ - int len = RTA_LENGTH(dlen); - int alen = NLMSG_ALIGN(n->nlmsg_len); - struct rtattr *rta = (struct rtattr*) (((void*)n) + alen); - if (alen + len > nsize) - return -1; - rta->rta_len = len; - rta->rta_type = type; - memcpy(RTA_DATA(rta), d, dlen); - n->nlmsg_len = alen + len; - return 0; -} - -int tun_gifindex(struct tun_t *this, int *index) { - struct ifreq ifr; - int fd; - - memset (&ifr, '\0', sizeof (ifr)); - ifr.ifr_addr.sa_family = AF_INET; - ifr.ifr_dstaddr.sa_family = AF_INET; - ifr.ifr_netmask.sa_family = AF_INET; - strncpy(ifr.ifr_name, this->devname, IFNAMSIZ); - ifr.ifr_name[IFNAMSIZ-1] = 0; /* Make sure to terminate */ - if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - sys_err(LOG_ERR, __FILE__, __LINE__, errno, - "socket() failed"); - } - if (ioctl(fd, SIOCGIFINDEX, &ifr)) { - sys_err(LOG_ERR, __FILE__, __LINE__, errno, - "ioctl() failed"); - close(fd); - return -1; - } - close(fd); - *index = ifr.ifr_ifindex; - return 0; -} -#endif - -int tun_sifflags(struct tun_t *this, int flags) { - struct ifreq ifr; - int fd; - - memset (&ifr, '\0', sizeof (ifr)); - ifr.ifr_flags = flags; - strncpy(ifr.ifr_name, this->devname, IFNAMSIZ); - ifr.ifr_name[IFNAMSIZ-1] = 0; /* Make sure to terminate */ - if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - sys_err(LOG_ERR, __FILE__, __LINE__, errno, - "socket() failed"); - } - if (ioctl(fd, SIOCSIFFLAGS, &ifr)) { - sys_err(LOG_ERR, __FILE__, __LINE__, errno, - "ioctl(SIOCSIFFLAGS) failed"); - close(fd); - return -1; - } - close(fd); - return 0; -} - - -/* Currently unused -int tun_addroute2(struct tun_t *this, - struct in_addr *dst, - struct in_addr *gateway, - struct in_addr *mask) { - - struct { - struct nlmsghdr n; - struct rtmsg r; - char buf[TUN_NLBUFSIZE]; - } req; - - struct sockaddr_nl local; - int addr_len; - int fd; - int status; - struct sockaddr_nl nladdr; - struct iovec iov; - struct msghdr msg; - - memset(&req, 0, sizeof(req)); - req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)); - req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE; - req.n.nlmsg_type = RTM_NEWROUTE; - req.r.rtm_family = AF_INET; - req.r.rtm_table = RT_TABLE_MAIN; - req.r.rtm_protocol = RTPROT_BOOT; - req.r.rtm_scope = RT_SCOPE_UNIVERSE; - req.r.rtm_type = RTN_UNICAST; - tun_nlattr(&req.n, sizeof(req), RTA_DST, dst, 4); - tun_nlattr(&req.n, sizeof(req), RTA_GATEWAY, gateway, 4); - - if ((fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) < 0) { - sys_err(LOG_ERR, __FILE__, __LINE__, errno, - "socket() failed"); - return -1; - } - - memset(&local, 0, sizeof(local)); - local.nl_family = AF_NETLINK; - local.nl_groups = 0; - - if (bind(fd, (struct sockaddr*)&local, sizeof(local)) < 0) { - sys_err(LOG_ERR, __FILE__, __LINE__, errno, - "bind() failed"); - close(fd); - return -1; - } - - addr_len = sizeof(local); - if (getsockname(fd, (struct sockaddr*)&local, &addr_len) < 0) { - sys_err(LOG_ERR, __FILE__, __LINE__, errno, - "getsockname() failed"); - close(fd); - return -1; - } - - if (addr_len != sizeof(local)) { - sys_err(LOG_ERR, __FILE__, __LINE__, 0, - "Wrong address length %d", addr_len); - close(fd); - return -1; - } - - if (local.nl_family != AF_NETLINK) { - sys_err(LOG_ERR, __FILE__, __LINE__, 0, - "Wrong address family %d", local.nl_family); - close(fd); - return -1; - } - - iov.iov_base = (void*)&req.n; - iov.iov_len = req.n.nlmsg_len; - - msg.msg_name = (void*)&nladdr; - msg.msg_namelen = sizeof(nladdr), - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_flags = 0; - - memset(&nladdr, 0, sizeof(nladdr)); - nladdr.nl_family = AF_NETLINK; - nladdr.nl_pid = 0; - nladdr.nl_groups = 0; - - req.n.nlmsg_seq = 0; - req.n.nlmsg_flags |= NLM_F_ACK; - - status = sendmsg(fd, &msg, 0); * TODO: Error check * - close(fd); - return 0; -} -*/ - -int tun_addaddr(struct tun_t *this, - struct in_addr *addr, - struct in_addr *dstaddr, - struct in_addr *netmask) { - -#if defined(__linux__) - struct { - struct nlmsghdr n; - struct ifaddrmsg i; - char buf[TUN_NLBUFSIZE]; - } req; - - struct sockaddr_nl local; - socklen_t addr_len; - int fd; - int status; - - struct sockaddr_nl nladdr; - struct iovec iov; - struct msghdr msg; - - if (!this->addrs) /* Use ioctl for first addr to make ping work */ - return tun_setaddr(this, addr, dstaddr, netmask); - - memset(&req, 0, sizeof(req)); - req.n.nlmsg_len = NLMSG_LENGTH(sizeof(struct ifaddrmsg)); - req.n.nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE; - req.n.nlmsg_type = RTM_NEWADDR; - req.i.ifa_family = AF_INET; - req.i.ifa_prefixlen = 32; /* 32 FOR IPv4 */ - req.i.ifa_flags = 0; - req.i.ifa_scope = RT_SCOPE_HOST; /* TODO or 0 */ - if (tun_gifindex(this, &req.i.ifa_index)) { - return -1; - } - - tun_nlattr(&req.n, sizeof(req), IFA_ADDRESS, addr, sizeof(addr)); - tun_nlattr(&req.n, sizeof(req), IFA_LOCAL, dstaddr, sizeof(dstaddr)); - - if ((fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) < 0) { - sys_err(LOG_ERR, __FILE__, __LINE__, errno, - "socket() failed"); - return -1; - } - - memset(&local, 0, sizeof(local)); - local.nl_family = AF_NETLINK; - local.nl_groups = 0; - - if (bind(fd, (struct sockaddr*)&local, sizeof(local)) < 0) { - sys_err(LOG_ERR, __FILE__, __LINE__, errno, - "bind() failed"); - close(fd); - return -1; - } - - addr_len = sizeof(local); - if (getsockname(fd, (struct sockaddr*)&local, &addr_len) < 0) { - sys_err(LOG_ERR, __FILE__, __LINE__, errno, - "getsockname() failed"); - close(fd); - return -1; - } - - if (addr_len != sizeof(local)) { - sys_err(LOG_ERR, __FILE__, __LINE__, 0, - "Wrong address length %d", addr_len); - close(fd); - return -1; - } - - if (local.nl_family != AF_NETLINK) { - sys_err(LOG_ERR, __FILE__, __LINE__, 0, - "Wrong address family %d", local.nl_family); - close(fd); - return -1; - } - - iov.iov_base = (void*)&req.n; - iov.iov_len = req.n.nlmsg_len; - - msg.msg_name = (void*)&nladdr; - msg.msg_namelen = sizeof(nladdr), - msg.msg_iov = &iov; - msg.msg_iovlen = 1; - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_flags = 0; - - memset(&nladdr, 0, sizeof(nladdr)); - nladdr.nl_family = AF_NETLINK; - nladdr.nl_pid = 0; - nladdr.nl_groups = 0; - - req.n.nlmsg_seq = 0; - req.n.nlmsg_flags |= NLM_F_ACK; - - status = sendmsg(fd, &msg, 0); /* TODO Error check */ - - tun_sifflags(this, IFF_UP | IFF_RUNNING); /* TODO */ - close(fd); - this->addrs++; - return 0; - -#elif defined (__FreeBSD__) || defined (__APPLE__) - - int fd; - struct ifaliasreq areq; - - /* TODO: Is this needed on FreeBSD? */ - if (!this->addrs) /* Use ioctl for first addr to make ping work */ - return tun_setaddr(this, addr, dstaddr, netmask); /* TODO dstaddr */ - - memset(&areq, 0, sizeof(areq)); - - /* Set up interface name */ - strncpy(areq.ifra_name, this->devname, IFNAMSIZ); - areq.ifra_name[IFNAMSIZ-1] = 0; /* Make sure to terminate */ - - ((struct sockaddr_in*) &areq.ifra_addr)->sin_family = AF_INET; - ((struct sockaddr_in*) &areq.ifra_addr)->sin_len = sizeof(areq.ifra_addr); - ((struct sockaddr_in*) &areq.ifra_addr)->sin_addr.s_addr = addr->s_addr; - - ((struct sockaddr_in*) &areq.ifra_mask)->sin_family = AF_INET; - ((struct sockaddr_in*) &areq.ifra_mask)->sin_len = sizeof(areq.ifra_mask); - ((struct sockaddr_in*) &areq.ifra_mask)->sin_addr.s_addr = netmask->s_addr; - - /* For some reason FreeBSD uses ifra_broadcast for specifying dstaddr */ - ((struct sockaddr_in*) &areq.ifra_broadaddr)->sin_family = AF_INET; - ((struct sockaddr_in*) &areq.ifra_broadaddr)->sin_len = - sizeof(areq.ifra_broadaddr); - ((struct sockaddr_in*) &areq.ifra_broadaddr)->sin_addr.s_addr = - dstaddr->s_addr; - - /* Create a channel to the NET kernel. */ - if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - sys_err(LOG_ERR, __FILE__, __LINE__, errno, - "socket() failed"); - return -1; - } - - if (ioctl(fd, SIOCAIFADDR, (void *) &areq) < 0) { - sys_err(LOG_ERR, __FILE__, __LINE__, errno, - "ioctl(SIOCAIFADDR) failed"); - close(fd); - return -1; - } - - close(fd); - this->addrs++; - return 0; - -#elif defined (__sun__) - - if (!this->addrs) /* Use ioctl for first addr to make ping work */ - return tun_setaddr(this, addr, dstaddr, netmask); - - sys_err(LOG_ERR, __FILE__, __LINE__, errno, - "Setting multiple addresses not possible on Solaris"); - return -1; - -#else -#error "Unknown platform!" -#endif - -} - - -int tun_setaddr(struct tun_t *this, - struct in_addr *addr, - struct in_addr *dstaddr, - struct in_addr *netmask) -{ - struct ifreq ifr; - int fd; - - memset (&ifr, '\0', sizeof (ifr)); - ifr.ifr_addr.sa_family = AF_INET; - ifr.ifr_dstaddr.sa_family = AF_INET; - -#if defined(__linux__) - ifr.ifr_netmask.sa_family = AF_INET; - -#elif defined(__FreeBSD__) || defined (__APPLE__) - ((struct sockaddr_in *) &ifr.ifr_addr)->sin_len = - sizeof (struct sockaddr_in); - ((struct sockaddr_in *) &ifr.ifr_dstaddr)->sin_len = - sizeof (struct sockaddr_in); -#endif - - strncpy(ifr.ifr_name, this->devname, IFNAMSIZ); - ifr.ifr_name[IFNAMSIZ-1] = 0; /* Make sure to terminate */ - - /* Create a channel to the NET kernel. */ - if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - sys_err(LOG_ERR, __FILE__, __LINE__, errno, - "socket() failed"); - return -1; - } - - if (addr) { /* Set the interface address */ - this->addr.s_addr = addr->s_addr; - ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = addr->s_addr; - if (ioctl(fd, SIOCSIFADDR, (void *) &ifr) < 0) { - if (errno != EEXIST) { - sys_err(LOG_ERR, __FILE__, __LINE__, errno, - "ioctl(SIOCSIFADDR) failed"); - } - else { - sys_err(LOG_WARNING, __FILE__, __LINE__, errno, - "ioctl(SIOCSIFADDR): Address already exists"); - } - close(fd); - return -1; - } - } - - if (dstaddr) { /* Set the destination address */ - this->dstaddr.s_addr = dstaddr->s_addr; - ((struct sockaddr_in *) &ifr.ifr_dstaddr)->sin_addr.s_addr = - dstaddr->s_addr; - if (ioctl(fd, SIOCSIFDSTADDR, (caddr_t) &ifr) < 0) { - sys_err(LOG_ERR, __FILE__, __LINE__, errno, - "ioctl(SIOCSIFDSTADDR) failed"); - close(fd); - return -1; - } - } - - if (netmask) { /* Set the netmask */ - this->netmask.s_addr = netmask->s_addr; -#if defined(__linux__) - ((struct sockaddr_in *) &ifr.ifr_netmask)->sin_addr.s_addr = - netmask->s_addr; - -#elif defined(__FreeBSD__) || defined (__APPLE__) - ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = - netmask->s_addr; - -#elif defined(__sun__) - ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr.s_addr = - netmask->s_addr; -#else -#error "Unknown platform!" -#endif - - if (ioctl(fd, SIOCSIFNETMASK, (void *) &ifr) < 0) { - sys_err(LOG_ERR, __FILE__, __LINE__, errno, - "ioctl(SIOCSIFNETMASK) failed"); - close(fd); - return -1; - } - } - - close(fd); - this->addrs++; - - /* On linux the route to the interface is set automatically - on FreeBSD we have to do this manually */ - - /* TODO: How does it work on Solaris? */ - - tun_sifflags(this, IFF_UP | IFF_RUNNING); - -#if defined(__FreeBSD__) || defined (__APPLE__) - tun_addroute(this, dstaddr, addr, netmask); - this->routes = 1; -#endif - - return 0; -} - -int tun_route(struct tun_t *this, - struct in_addr *dst, - struct in_addr *gateway, - struct in_addr *mask, - int delete) -{ - - - /* TODO: Learn how to set routing table on sun */ - -#if defined(__linux__) - - struct rtentry r; - int fd; - - memset (&r, '\0', sizeof (r)); - r.rt_flags = RTF_UP | RTF_GATEWAY; /* RTF_HOST not set */ - - /* Create a channel to the NET kernel. */ - if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - sys_err(LOG_ERR, __FILE__, __LINE__, errno, - "socket() failed"); - return -1; - } - - r.rt_dst.sa_family = AF_INET; - r.rt_gateway.sa_family = AF_INET; - r.rt_genmask.sa_family = AF_INET; - ((struct sockaddr_in *) &r.rt_dst)->sin_addr.s_addr = dst->s_addr; - ((struct sockaddr_in *) &r.rt_gateway)->sin_addr.s_addr = gateway->s_addr; - ((struct sockaddr_in *) &r.rt_genmask)->sin_addr.s_addr = mask->s_addr; - - if (delete) { - if (ioctl(fd, SIOCDELRT, (void *) &r) < 0) { - sys_err(LOG_ERR, __FILE__, __LINE__, errno, - "ioctl(SIOCDELRT) failed"); - close(fd); - return -1; - } - } - else { - if (ioctl(fd, SIOCADDRT, (void *) &r) < 0) { - sys_err(LOG_ERR, __FILE__, __LINE__, errno, - "ioctl(SIOCADDRT) failed"); - close(fd); - return -1; - } - } - close(fd); - return 0; - -#elif defined(__FreeBSD__) || defined (__APPLE__) - -struct { - struct rt_msghdr rt; - struct sockaddr_in dst; - struct sockaddr_in gate; - struct sockaddr_in mask; -} req; - - int fd; - struct rt_msghdr *rtm; - - if((fd = socket(AF_ROUTE, SOCK_RAW, 0)) == -1) { - sys_err(LOG_ERR, __FILE__, __LINE__, errno, - "socket() failed"); - return -1; - } - - memset(&req, 0x00, sizeof(req)); - - rtm = &req.rt; - - rtm->rtm_msglen = sizeof(req); - rtm->rtm_version = RTM_VERSION; - if (delete) { - rtm->rtm_type = RTM_DELETE; - } - else { - rtm->rtm_type = RTM_ADD; - } - rtm->rtm_flags = RTF_UP | RTF_GATEWAY | RTF_STATIC; /* TODO */ - rtm->rtm_addrs = RTA_DST | RTA_GATEWAY | RTA_NETMASK; - rtm->rtm_pid = getpid(); - rtm->rtm_seq = 0044; /* TODO */ - - req.dst.sin_family = AF_INET; - req.dst.sin_len = sizeof(req.dst); - req.mask.sin_family = AF_INET; - req.mask.sin_len = sizeof(req.mask); - req.gate.sin_family = AF_INET; - req.gate.sin_len = sizeof(req.gate); - - req.dst.sin_addr.s_addr = dst->s_addr; - req.mask.sin_addr.s_addr = mask->s_addr; - req.gate.sin_addr.s_addr = gateway->s_addr; - - if(write(fd, rtm, rtm->rtm_msglen) < 0) { - sys_err(LOG_ERR, __FILE__, __LINE__, errno, - "write() failed"); - close(fd); - return -1; - } - close(fd); - return 0; - -#elif defined(__sun__) - sys_err(LOG_WARNING, __FILE__, __LINE__, errno, - "Could not set up routing on Solaris. Please add route manually."); - return 0; - -#else -#error "Unknown platform!" -#endif - -} - -int tun_addroute(struct tun_t *this, - struct in_addr *dst, - struct in_addr *gateway, - struct in_addr *mask) -{ - return tun_route(this, dst, gateway, mask, 0); -} - -int tun_delroute(struct tun_t *this, - struct in_addr *dst, - struct in_addr *gateway, - struct in_addr *mask) -{ - return tun_route(this, dst, gateway, mask, 1); -} - - -int tun_new(struct tun_t **tun) -{ - -#if defined(__linux__) - struct ifreq ifr; - -#elif defined(__FreeBSD__) || defined (__APPLE__) - char devname[IFNAMSIZ+5]; /* "/dev/" + ifname */ - int devnum; - struct ifaliasreq areq; - int fd; - -#elif defined(__sun__) - int if_fd, ppa = -1; - static int ip_fd = 0; - int muxid; - struct ifreq ifr; - -#else -#error "Unknown platform!" -#endif - - if (!(*tun = calloc(1, sizeof(struct tun_t)))) { - sys_err(LOG_ERR, __FILE__, __LINE__, errno, "calloc() failed"); - return EOF; - } - - (*tun)->cb_ind = NULL; - (*tun)->addrs = 0; - (*tun)->routes = 0; - -#if defined(__linux__) - /* Open the actual tun device */ - if (((*tun)->fd = open("/dev/net/tun", O_RDWR)) < 0) { - sys_err(LOG_ERR, __FILE__, __LINE__, errno, "open() failed"); - return -1; - } - - /* Set device flags. For some weird reason this is also the method - used to obtain the network interface name */ - memset(&ifr, 0, sizeof(ifr)); - ifr.ifr_flags = IFF_TUN | IFF_NO_PI; /* Tun device, no packet info */ - if (ioctl((*tun)->fd, TUNSETIFF, (void *) &ifr) < 0) { - sys_err(LOG_ERR, __FILE__, __LINE__, errno, "ioctl() failed"); - close((*tun)->fd); - return -1; - } - - strncpy((*tun)->devname, ifr.ifr_name, IFNAMSIZ); - (*tun)->devname[IFNAMSIZ] = 0; - - ioctl((*tun)->fd, TUNSETNOCSUM, 1); /* Disable checksums */ - return 0; - -#elif defined(__FreeBSD__) || defined (__APPLE__) - - /* Find suitable device */ - for (devnum = 0; devnum < 255; devnum++) { /* TODO 255 */ - snprintf(devname, sizeof(devname), "/dev/tun%d", devnum); - devname[sizeof(devname)] = 0; - if (((*tun)->fd = open(devname, O_RDWR)) >= 0) break; - if (errno != EBUSY) break; - } - if ((*tun)->fd < 0) { - sys_err(LOG_ERR, __FILE__, __LINE__, errno, "Can't find tunnel device"); - return -1; - } - - snprintf((*tun)->devname, sizeof((*tun)->devname), "tun%d", devnum); - (*tun)->devname[sizeof((*tun)->devname)] = 0; - - /* The tun device we found might have "old" IP addresses allocated */ - /* We need to delete those. This problem is not present on Linux */ - - memset(&areq, 0, sizeof(areq)); - - /* Set up interface name */ - strncpy(areq.ifra_name, (*tun)->devname, IFNAMSIZ); - areq.ifra_name[IFNAMSIZ-1] = 0; /* Make sure to terminate */ - - /* Create a channel to the NET kernel. */ - if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - sys_err(LOG_ERR, __FILE__, __LINE__, errno, - "socket() failed"); - return -1; - } - - /* Delete any IP addresses until SIOCDIFADDR fails */ - while (ioctl(fd, SIOCDIFADDR, (void *) &areq) != -1); - - close(fd); - return 0; - -#elif defined(__sun__) - - if( (ip_fd = open("/dev/udp", O_RDWR, 0)) < 0){ - sys_err(LOG_ERR, __FILE__, __LINE__, errno, "Can't open /dev/udp"); - return -1; - } - - if( ((*tun)->fd = open("/dev/tun", O_RDWR, 0)) < 0){ - sys_err(LOG_ERR, __FILE__, __LINE__, errno, "Can't open /dev/tun"); - return -1; - } - - /* Assign a new PPA and get its unit number. */ - if( (ppa = ioctl((*tun)->fd, TUNNEWPPA, -1)) < 0){ - sys_err(LOG_ERR, __FILE__, __LINE__, errno, "Can't assign new interface"); - return -1; - } - - if( (if_fd = open("/dev/tun", O_RDWR, 0)) < 0){ - sys_err(LOG_ERR, __FILE__, __LINE__, errno, "Can't open /dev/tun (2)"); - return -1; - } - if(ioctl(if_fd, I_PUSH, "ip") < 0){ - sys_err(LOG_ERR, __FILE__, __LINE__, errno, "Can't push IP module"); - return -1; - } - - /* Assign ppa according to the unit number returned by tun device */ - if(ioctl(if_fd, IF_UNITSEL, (char *)&ppa) < 0){ - sys_err(LOG_ERR, __FILE__, __LINE__, errno, "Can't set PPA %d", ppa); - return -1; - } - - /* Link the two streams */ - if ((muxid = ioctl(ip_fd, I_LINK, if_fd)) < 0) { - sys_err(LOG_ERR, __FILE__, __LINE__, errno, "Can't link TUN device to IP"); - return -1; - } - - close (if_fd); - - snprintf((*tun)->devname, sizeof((*tun)->devname), "tun%d", ppa); - (*tun)->devname[sizeof((*tun)->devname)] = 0; - - memset(&ifr, 0, sizeof(ifr)); - strcpy(ifr.ifr_name, (*tun)->devname); - ifr.ifr_ip_muxid = muxid; - - if (ioctl(ip_fd, SIOCSIFMUXID, &ifr) < 0) { - ioctl(ip_fd, I_PUNLINK, muxid); - sys_err(LOG_ERR, __FILE__, __LINE__, errno, "Can't set multiplexor id"); - return -1; - } - - /* if (fcntl (fd, F_SETFL, O_NONBLOCK) < 0) - msg (M_ERR, "Set file descriptor to non-blocking failed"); */ - - return 0; - -#else -#error "Unknown platform!" -#endif - -} - -int tun_free(struct tun_t *tun) -{ - - if (tun->routes) { - tun_delroute(tun, &tun->dstaddr, &tun->addr, &tun->netmask); - } - - if (close(tun->fd)) { - sys_err(LOG_ERR, __FILE__, __LINE__, errno, "close() failed"); - } - - /* TODO: For solaris we need to unlink streams */ - - free(tun); - return 0; -} - - -int tun_set_cb_ind(struct tun_t *this, - int (*cb_ind) (struct tun_t *tun, void *pack, unsigned len)) { - this->cb_ind = cb_ind; - return 0; -} - - -int tun_decaps(struct tun_t *this) -{ - -#if defined(__linux__) || defined (__FreeBSD__) || defined (__APPLE__) - - unsigned char buffer[PACKET_MAX]; - int status; - - if ((status = read(this->fd, buffer, sizeof(buffer))) <= 0) { - sys_err(LOG_ERR, __FILE__, __LINE__, errno, "read() failed"); - return -1; - } - - if (this->cb_ind) - return this->cb_ind(this, buffer, status); - - return 0; - -#elif defined (__sun__) - - unsigned char buffer[PACKET_MAX]; - struct strbuf sbuf; - int f = 0; - - sbuf.maxlen = PACKET_MAX; - sbuf.buf = buffer; - if (getmsg(this->fd, NULL, &sbuf, &f) < 0) { - sys_err(LOG_ERR, __FILE__, __LINE__, errno, "getmsg() failed"); - return -1; - } - - if (this->cb_ind) - return this->cb_ind(this, buffer, sbuf.len); - - return 0; - -#endif - -} - - -int tun_encaps(struct tun_t *tun, void *pack, unsigned len) -{ - -#if defined(__linux__) || defined (__FreeBSD__) || defined (__APPLE__) - - return write(tun->fd, pack, len); - -#elif defined (__sun__) - - struct strbuf sbuf; - sbuf.len = len; - sbuf.buf = pack; - return putmsg(tun->fd, NULL, &sbuf, 0); - -#endif -} - -int tun_runscript(struct tun_t *tun, char* script) { - - char buf[TUN_SCRIPTSIZE]; - char snet[TUN_ADDRSIZE]; - char smask[TUN_ADDRSIZE]; - - strncpy(snet, inet_ntoa(tun->addr), sizeof(snet)); - snet[sizeof(snet)-1] = 0; - strncpy(smask, inet_ntoa(tun->netmask), sizeof(smask)); - smask[sizeof(smask)-1] = 0; - - /* system("ipup /dev/tun0 192.168.0.10 255.255.255.0"); */ - snprintf(buf, sizeof(buf), "%s %s %s %s", - script, tun->devname, snet, smask); - buf[sizeof(buf)-1] = 0; - system(buf); - return 0; -} diff --git a/sgsnemu/tun.h b/sgsnemu/tun.h deleted file mode 100644 index 7972c53..0000000 --- a/sgsnemu/tun.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * TUN interface functions. - * Copyright (C) 2002, 2003 Mondru AB. - * - * The contents of this file may be used under the terms of the GNU - * General Public License Version 2, provided that the above copyright - * notice and this permission notice is included in all copies or - * substantial portions of the software. - * - */ - -#ifndef _TUN_H -#define _TUN_H - -#define PACKET_MAX 8196 /* Maximum packet size we receive */ -#define TUN_SCRIPTSIZE 256 -#define TUN_ADDRSIZE 128 -#define TUN_NLBUFSIZE 1024 - -struct tun_packet_t { - unsigned int ver:4; - unsigned int ihl:4; - unsigned int dscp:6; - unsigned int ecn:2; - unsigned int length:16; - unsigned int id:16; - unsigned int flags:3; - unsigned int fragment:13; - unsigned int ttl:8; - unsigned int protocol:8; - unsigned int check:16; - unsigned int src:32; - unsigned int dst:32; -}; - - -/* *********************************************************** - * Information storage for each tun instance - *************************************************************/ - -struct tun_t { - int fd; /* File descriptor to tun interface */ - struct in_addr addr; - struct in_addr dstaddr; - struct in_addr netmask; - int addrs; /* Number of allocated IP addresses */ - int routes; /* One if we allocated an automatic route */ - char devname[IFNAMSIZ];/* Name of the tun device */ - int (*cb_ind) (struct tun_t *tun, void *pack, unsigned len); -}; - - -extern int tun_new(struct tun_t **tun); -extern int tun_free(struct tun_t *tun); -extern int tun_decaps(struct tun_t *this); -extern int tun_encaps(struct tun_t *tun, void *pack, unsigned len); - -extern int tun_addaddr(struct tun_t *this, struct in_addr *addr, - struct in_addr *dstaddr, struct in_addr *netmask); - - -extern int tun_setaddr(struct tun_t *this, struct in_addr *our_adr, - struct in_addr *his_adr, struct in_addr *net_mask); - -int tun_addroute(struct tun_t *this, struct in_addr *dst, - struct in_addr *gateway, struct in_addr *mask); - -extern int tun_set_cb_ind(struct tun_t *this, - int (*cb_ind) (struct tun_t *tun, void *pack, unsigned len)); - - -extern int tun_runscript(struct tun_t *tun, char* script); - -#endif /* !_TUN_H */