aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AUTHORS0
-rw-r--r--COPYING339
-rw-r--r--ChangeLog0
-rw-r--r--Makefile330
-rw-r--r--Makefile.am2
-rw-r--r--Makefile.in330
-rw-r--r--NEWS0
-rw-r--r--README144
-rw-r--r--aclocal.m4522
-rw-r--r--config.cache48
-rw-r--r--config.h.in65
-rw-r--r--config.log84
-rwxr-xr-xconfig.status182
-rwxr-xr-xconfigure2625
-rw-r--r--configure.in32
-rw-r--r--configure.scan27
-rw-r--r--doc/Makefile0
-rw-r--r--examples/ggsn.conf69
-rw-r--r--examples/sgsnemu.conf102
-rw-r--r--ggsn/.deps/cmdline.P33
-rw-r--r--ggsn/.deps/ggsn.P146
-rw-r--r--ggsn/.deps/ggsnopt.P33
-rw-r--r--ggsn/.deps/tun.P108
-rw-r--r--ggsn/Makefile343
-rw-r--r--ggsn/Makefile.am11
-rw-r--r--ggsn/Makefile.in343
-rw-r--r--ggsn/cmdline.c529
-rw-r--r--ggsn/cmdline.ggo29
-rw-r--r--ggsn/cmdline.h61
-rw-r--r--ggsn/ggsn.c424
-rw-r--r--ggsn/tun.c128
-rw-r--r--ggsn/tun.h48
-rw-r--r--gtp/.deps/gtp.P111
-rw-r--r--gtp/.deps/gtpie.P52
-rw-r--r--gtp/.deps/lookupa.P3
-rw-r--r--gtp/.deps/pdp.P53
-rw-r--r--gtp/.deps/queue.P64
-rw-r--r--gtp/Makefile339
-rw-r--r--gtp/Makefile.am9
-rw-r--r--gtp/Makefile.in339
-rw-r--r--gtp/gtp.c1917
-rw-r--r--gtp/gtp.h339
-rw-r--r--gtp/gtpie.c513
-rw-r--r--gtp/gtpie.h279
-rw-r--r--gtp/lookupa.c246
-rw-r--r--gtp/lookupa.h29
-rw-r--r--gtp/pdp.c320
-rw-r--r--gtp/pdp.h203
-rw-r--r--gtp/queue.c249
-rw-r--r--gtp/queue.h77
-rw-r--r--intl/Makefile0
-rw-r--r--intl/Makefile.in0
-rwxr-xr-xlibtool4288
-rw-r--r--po/Makefile0
-rw-r--r--sgsnemu/.deps/cmdline.P33
-rw-r--r--sgsnemu/.deps/pptpstuff.P107
-rw-r--r--sgsnemu/.deps/sgsnemu.P157
-rw-r--r--sgsnemu/.deps/sgsnemuopt.P33
-rw-r--r--sgsnemu/.deps/tun.P108
-rw-r--r--sgsnemu/Makefile343
-rw-r--r--sgsnemu/Makefile.am11
-rw-r--r--sgsnemu/Makefile.in343
-rw-r--r--sgsnemu/cmdline.c776
-rw-r--r--sgsnemu/cmdline.ggo37
-rw-r--r--sgsnemu/cmdline.h77
-rw-r--r--sgsnemu/ggsn_restart1
-rw-r--r--sgsnemu/sgsnemu.c754
-rw-r--r--sgsnemu/sgsnemu.pid1
-rw-r--r--sgsnemu/tun.c128
-rw-r--r--sgsnemu/tun.h48
-rw-r--r--src/Makefile0
-rw-r--r--tests/Makefile0
-rw-r--r--tests/Makefile.in0
-rwxr-xr-xversion24
74 files changed, 19548 insertions, 0 deletions
diff --git a/AUTHORS b/AUTHORS
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/AUTHORS
diff --git a/COPYING b/COPYING
new file mode 100644
index 0000000..a43ea21
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ Appendix: How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/ChangeLog b/ChangeLog
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/ChangeLog
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..bc944de
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,330 @@
+# Generated automatically from Makefile.in by configure.
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = /bin/sh
+
+srcdir = .
+top_srcdir = .
+prefix = /usr/local
+exec_prefix = ${prefix}
+
+bindir = ${exec_prefix}/bin
+sbindir = ${exec_prefix}/sbin
+libexecdir = ${exec_prefix}/libexec
+datadir = ${prefix}/share
+sysconfdir = ${prefix}/etc
+sharedstatedir = ${prefix}/com
+localstatedir = ${prefix}/var
+libdir = ${exec_prefix}/lib
+infodir = ${prefix}/info
+mandir = ${prefix}/man
+includedir = ${prefix}/include
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/OpenGGSN
+pkglibdir = $(libdir)/OpenGGSN
+pkgincludedir = $(includedir)/OpenGGSN
+
+top_builddir = .
+
+ACLOCAL = aclocal
+AUTOCONF = autoconf
+AUTOMAKE = automake
+AUTOHEADER = autoheader
+
+INSTALL = /usr/bin/install -c
+INSTALL_PROGRAM = ${INSTALL} $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = ${INSTALL} -m 644
+INSTALL_SCRIPT = ${INSTALL_PROGRAM}
+transform = s,x,x,
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = i686-pc-linux
+host_triplet = i686-pc-linux-gnu
+AS = @AS@
+AWK = gawk
+CC = gcc
+DLLTOOL = @DLLTOOL@
+LIBTOOL = $(SHELL) $(top_builddir)/libtool
+LN_S = ln -s
+MAKEINFO = makeinfo
+OBJDUMP = @OBJDUMP@
+PACKAGE = OpenGGSN
+RANLIB = ranlib
+VERSION = 0.5
+
+SUBDIRS = gtp ggsn sgsnemu
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_CLEAN_FILES =
+DIST_COMMON = README AUTHORS COPYING ChangeLog INSTALL Makefile.am \
+Makefile.in NEWS aclocal.m4 config.guess config.sub configure \
+configure.in install-sh ltconfig ltmain.sh missing mkinstalldirs
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = gtar
+GZIP_ENV = --best
+all: all-redirect
+.SUFFIXES:
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
+ cd $(top_builddir) \
+ && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+$(ACLOCAL_M4): configure.in
+ cd $(srcdir) && $(ACLOCAL)
+
+config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ $(SHELL) ./config.status --recheck
+$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
+ cd $(srcdir) && $(AUTOCONF)
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+
+
+
+all-recursive install-data-recursive install-exec-recursive \
+installdirs-recursive install-recursive uninstall-recursive \
+check-recursive installcheck-recursive info-recursive dvi-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
+ rev="$$subdir $$rev"; \
+ test "$$subdir" = "." && dot_seen=yes; \
+ done; \
+ test "$$dot_seen" = "no" && rev=". $$rev"; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+
+# This target untars the dist file and tries a VPATH configuration. Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+ -rm -rf $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz
+ mkdir $(distdir)/=build
+ mkdir $(distdir)/=inst
+ dc_install_base=`cd $(distdir)/=inst && pwd`; \
+ cd $(distdir)/=build \
+ && ../configure --srcdir=.. --prefix=$$dc_install_base \
+ && $(MAKE) $(AM_MAKEFLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) dvi \
+ && $(MAKE) $(AM_MAKEFLAGS) check \
+ && $(MAKE) $(AM_MAKEFLAGS) install \
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+ && $(MAKE) $(AM_MAKEFLAGS) dist
+ -rm -rf $(distdir)
+ @banner="$(distdir).tar.gz is ready for distribution"; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"
+dist: distdir
+ -chmod -R a+r $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+ -rm -rf $(distdir)
+dist-all: distdir
+ -chmod -R a+r $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+ -rm -rf $(distdir)
+distdir: $(DISTFILES)
+ -rm -rf $(distdir)
+ mkdir $(distdir)
+ -chmod 777 $(distdir)
+ here=`cd $(top_builddir) && pwd`; \
+ top_distdir=`cd $(distdir) && pwd`; \
+ distdir=`cd $(distdir) && pwd`; \
+ cd $(top_srcdir) \
+ && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu Makefile
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$d/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ for subdir in $(SUBDIRS); do \
+ if test "$$subdir" = .; then :; else \
+ test -d $(distdir)/$$subdir \
+ || mkdir $(distdir)/$$subdir \
+ || exit 1; \
+ chmod 777 $(distdir)/$$subdir; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \
+ || exit 1; \
+ fi; \
+ done
+info-am:
+info: info-recursive
+dvi-am:
+dvi: dvi-recursive
+check-am: all-am
+check: check-recursive
+installcheck-am:
+installcheck: installcheck-recursive
+install-exec-am:
+install-exec: install-exec-recursive
+
+install-data-am:
+install-data: install-data-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-recursive
+uninstall-am:
+uninstall: uninstall-recursive
+all-am: Makefile
+all-redirect: all-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs: installdirs-recursive
+installdirs-am:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-tags mostlyclean-generic
+
+mostlyclean: mostlyclean-recursive
+
+clean-am: clean-tags clean-generic mostlyclean-am
+
+clean: clean-recursive
+
+distclean-am: distclean-tags distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-recursive
+ -rm -f config.status
+
+maintainer-clean-am: maintainer-clean-tags maintainer-clean-generic \
+ distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f config.status
+
+.PHONY: install-data-recursive uninstall-data-recursive \
+install-exec-recursive uninstall-exec-recursive installdirs-recursive \
+uninstalldirs-recursive all-recursive check-recursive \
+installcheck-recursive info-recursive dvi-recursive \
+mostlyclean-recursive distclean-recursive clean-recursive \
+maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
+dvi-am dvi check check-am installcheck-am installcheck install-exec-am \
+install-exec install-data-am install-data install-am install \
+uninstall-am uninstall all-redirect all-am all installdirs-am \
+installdirs mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/Makefile.am b/Makefile.am
new file mode 100644
index 0000000..2f6d1c1
--- /dev/null
+++ b/Makefile.am
@@ -0,0 +1,2 @@
+## Process this file with automake to produce Makefile.in
+SUBDIRS = gtp ggsn sgsnemu
diff --git a/Makefile.in b/Makefile.in
new file mode 100644
index 0000000..48ad937
--- /dev/null
+++ b/Makefile.in
@@ -0,0 +1,330 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = .
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AS = @AS@
+AWK = @AWK@
+CC = @CC@
+DLLTOOL = @DLLTOOL@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+MAKEINFO = @MAKEINFO@
+OBJDUMP = @OBJDUMP@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+
+SUBDIRS = gtp ggsn sgsnemu
+ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_CLEAN_FILES =
+DIST_COMMON = README AUTHORS COPYING ChangeLog INSTALL Makefile.am \
+Makefile.in NEWS aclocal.m4 config.guess config.sub configure \
+configure.in install-sh ltconfig ltmain.sh missing mkinstalldirs
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = gtar
+GZIP_ENV = --best
+all: all-redirect
+.SUFFIXES:
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --gnu Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
+ cd $(top_builddir) \
+ && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+$(ACLOCAL_M4): configure.in
+ cd $(srcdir) && $(ACLOCAL)
+
+config.status: $(srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ $(SHELL) ./config.status --recheck
+$(srcdir)/configure: $(srcdir)/configure.in $(ACLOCAL_M4) $(CONFIGURE_DEPENDENCIES)
+ cd $(srcdir) && $(AUTOCONF)
+
+# This directory's subdirectories are mostly independent; you can cd
+# into them and run `make' without going through this Makefile.
+# To change the values of `make' variables: instead of editing Makefiles,
+# (1) if the variable is set in `config.status', edit `config.status'
+# (which will cause the Makefiles to be regenerated when you run `make');
+# (2) otherwise, pass the desired values on the `make' command line.
+
+@SET_MAKE@
+
+all-recursive install-data-recursive install-exec-recursive \
+installdirs-recursive install-recursive uninstall-recursive \
+check-recursive installcheck-recursive info-recursive dvi-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ target=`echo $@ | sed s/-recursive//`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ dot_seen=yes; \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done; \
+ if test "$$dot_seen" = "no"; then \
+ $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
+ fi; test -z "$$fail"
+
+mostlyclean-recursive clean-recursive distclean-recursive \
+maintainer-clean-recursive:
+ @set fnord $(MAKEFLAGS); amf=$$2; \
+ dot_seen=no; \
+ rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
+ rev="$$subdir $$rev"; \
+ test "$$subdir" = "." && dot_seen=yes; \
+ done; \
+ test "$$dot_seen" = "no" && rev=". $$rev"; \
+ target=`echo $@ | sed s/-recursive//`; \
+ for subdir in $$rev; do \
+ echo "Making $$target in $$subdir"; \
+ if test "$$subdir" = "."; then \
+ local_target="$$target-am"; \
+ else \
+ local_target="$$target"; \
+ fi; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
+ || case "$$amf" in *=*) exit 1;; *k*) fail=yes;; *) exit 1;; esac; \
+ done && test -z "$$fail"
+tags-recursive:
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ test "$$subdir" = . || (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
+ done
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SUBDIRS)'; for subdir in $$list; do \
+ if test "$$subdir" = .; then :; else \
+ test -f $$subdir/TAGS && tags="$$tags -i $$here/$$subdir/TAGS"; \
+ fi; \
+ done; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(PACKAGE)-$(VERSION)
+top_distdir = $(distdir)
+
+# This target untars the dist file and tries a VPATH configuration. Then
+# it guarantees that the distribution is self-contained by making another
+# tarfile.
+distcheck: dist
+ -rm -rf $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) zxf $(distdir).tar.gz
+ mkdir $(distdir)/=build
+ mkdir $(distdir)/=inst
+ dc_install_base=`cd $(distdir)/=inst && pwd`; \
+ cd $(distdir)/=build \
+ && ../configure --srcdir=.. --prefix=$$dc_install_base \
+ && $(MAKE) $(AM_MAKEFLAGS) \
+ && $(MAKE) $(AM_MAKEFLAGS) dvi \
+ && $(MAKE) $(AM_MAKEFLAGS) check \
+ && $(MAKE) $(AM_MAKEFLAGS) install \
+ && $(MAKE) $(AM_MAKEFLAGS) installcheck \
+ && $(MAKE) $(AM_MAKEFLAGS) dist
+ -rm -rf $(distdir)
+ @banner="$(distdir).tar.gz is ready for distribution"; \
+ dashes=`echo "$$banner" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ echo "$$dashes"
+dist: distdir
+ -chmod -R a+r $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+ -rm -rf $(distdir)
+dist-all: distdir
+ -chmod -R a+r $(distdir)
+ GZIP=$(GZIP_ENV) $(TAR) chozf $(distdir).tar.gz $(distdir)
+ -rm -rf $(distdir)
+distdir: $(DISTFILES)
+ -rm -rf $(distdir)
+ mkdir $(distdir)
+ -chmod 777 $(distdir)
+ here=`cd $(top_builddir) && pwd`; \
+ top_distdir=`cd $(distdir) && pwd`; \
+ distdir=`cd $(distdir) && pwd`; \
+ cd $(top_srcdir) \
+ && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu Makefile
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$d/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+ for subdir in $(SUBDIRS); do \
+ if test "$$subdir" = .; then :; else \
+ test -d $(distdir)/$$subdir \
+ || mkdir $(distdir)/$$subdir \
+ || exit 1; \
+ chmod 777 $(distdir)/$$subdir; \
+ (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir=../$(distdir) distdir=../$(distdir)/$$subdir distdir) \
+ || exit 1; \
+ fi; \
+ done
+info-am:
+info: info-recursive
+dvi-am:
+dvi: dvi-recursive
+check-am: all-am
+check: check-recursive
+installcheck-am:
+installcheck: installcheck-recursive
+install-exec-am:
+install-exec: install-exec-recursive
+
+install-data-am:
+install-data: install-data-recursive
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-recursive
+uninstall-am:
+uninstall: uninstall-recursive
+all-am: Makefile
+all-redirect: all-recursive
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs: installdirs-recursive
+installdirs-am:
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-tags mostlyclean-generic
+
+mostlyclean: mostlyclean-recursive
+
+clean-am: clean-tags clean-generic mostlyclean-am
+
+clean: clean-recursive
+
+distclean-am: distclean-tags distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-recursive
+ -rm -f config.status
+
+maintainer-clean-am: maintainer-clean-tags maintainer-clean-generic \
+ distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-recursive
+ -rm -f config.status
+
+.PHONY: install-data-recursive uninstall-data-recursive \
+install-exec-recursive uninstall-exec-recursive installdirs-recursive \
+uninstalldirs-recursive all-recursive check-recursive \
+installcheck-recursive info-recursive dvi-recursive \
+mostlyclean-recursive distclean-recursive clean-recursive \
+maintainer-clean-recursive tags tags-recursive mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir info-am info \
+dvi-am dvi check check-am installcheck-am installcheck install-exec-am \
+install-exec install-data-am install-data install-am install \
+uninstall-am uninstall all-redirect all-am all installdirs-am \
+installdirs mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/NEWS
diff --git a/README b/README
new file mode 100644
index 0000000..69edce3
--- /dev/null
+++ b/README
@@ -0,0 +1,144 @@
+*** QuickStart ***
+
+REQUIREMENTS
+
+Linux
+OpenGGSN was developed and tested using Redhat 7.1 and Redhat
+7.2. It should run also on other Linux distributions as well as
+FreeBSD and Solaris, but this is untested. Please tell me of any
+testing results.
+
+Tun
+Both ggsn and sgsnemu uses the tun package. You need at least tun
+version 1.1. See http://vtun.sourceforge.net/tun/ for instructions on
+installation. Tun should be included from linux kernel version 2.4, so
+you might not need to manually install tun.
+
+COMPILATION
+./configure
+make clean
+make
+
+INSTALLATION
+Need to be root to do this
+make install
+Add /usr/local/lib to /etc/ld.so.conf
+Run ldconfig
+
+RUNNING
+
+sgsnemu
+Edit the configuration file sgsnemu.conf found under
+openggsn/examples.
+Start the emulator using the command:
+
+ sgsnemu -c examples/sgsnemu.conf -l 10.20.30.50 -r 10.20.30.40 --apn internet
+
+This will cause the sgsn emulator to bind to local address 10.20.30.50
+and connect to the ggsn found at 10.20.30.40. It will first send off
+an ECHO_REQUEST message. After this it will attemt to establish a pdp
+context. If successful it will create a local interface and set up
+routing. Now you should be able to ping through the connection. Use a
+network analysator such as ethereal to monitor the traffic.
+
+ggsn
+Edit the configuration file ggsn.conf found under openggsn/examples.
+Start the ggsn using the command:
+ ggsn --fg -c examples/ggsn.conf -l 10.20.30.40
+This will run the ggsn in foreground using the local interface
+10.20.30.40
+
+
+*** Features ***
+
+OpenGGSN is an open source implementation of GPRS Support Nodes
+(GSNs). It implements the GPRS tunneling protocol (GTP) version 0.
+
+OpenGGSN provides 3 components:
+* gtplib
+* ggsn
+* sgsnemu
+
+gtplib
+This library contain all functionality retating to the GTP
+protocol. Use this libraty if you want to implement your own
+GSN. Currently gtplib supports GTPv0.
+
+ggsn
+The ggsn implements a Gateway GPRS Support Node. The GGSN is a
+small application which is provided in order to test and demonstrate
+the use of gtplib. It is fully compliant to the 3GPP standards, but
+lack important functionality such as charging and management. Use this
+application as a starting point if you want to build your own GGSN
+with your own fancy VPN, management and charging functionality.
+
+sgsnemu This application emulates a Serving GPRS Support Node. sgsnemu
+enable you to test your 3GPP core network without the need to invest
+in a 3G radio access network. An important application of sgsnemu is
+the testing of roaming connectivity through a GPRS roaming exchange.
+
+*** Required software ***
+
+TUN
+http://vtun.sourceforge.net/tun/
+
+Both ggsn and sgsnemu uses the tun package. You need at least tun
+version 1.1. See the above web page for instructions on installation.
+
+GENGETOPT
+http://www.gnu.org/software/gengetopt/gengetopt.html
+
+Gengetopt is required if you want to change the options defined in the
+cmdline.ggo source file. You need at least gengetopt version 2.8 (Not
+released yet 2002-12-12).
+
+If you are just going to compile the programs you don't need
+gengetopt.
+
+To use gengetopt do the following:
+cd ggsn
+../../gengetopt-2.8rc/src/gengetopt < cmdline.ggo --conf-parser
+insert #define _GNU_SOURCE in the top of cmdline.c to get rid of warnings.
+
+To use gengetopt do the following:
+cd sgsnemu
+../../gengetopt-2.8rc/src/gengetopt < cmdline.ggo --conf-parser
+insert #define _GNU_SOURCE in the top of cmdline.c to get rid of warnings.
+
+libPropList-0.10.1 (??? I can't remember if I use this???)
+ftp://ftp.windowmaker.org/pub/libs
+
+*** Compilation and Installation ***
+
+To generate everything:
+See http://sources.redhat.com/autobook/autobook/autobook_25.html#SEC25
+ 1 edit configure.in
+ 2 run aclocal
+ 3 run autoheader
+ (run automake --add-missing)
+ 4 run automake
+ 5 run autoconf
+ 6 run ./configure
+ 7 rin make clean
+ 8 run make
+ 9 run make install
+10 Add /usr/local/lib to /etc/ld.so.conf
+11 run ldconfig
+
+
+*** Installation of libraries
+
+cd gtp
+make install
+Add /usr/local/lib to /etc/ld.so.conf
+run ldconfig
+
+On RedHat add /usr/local/lib to /etc/ld.so.conf
+http://www.dwheeler.com/program-library/Program-Library-HOWTO/shared-libraries.html
+
+*** Running ggsn ***
+Use ggsn -h for a list of available options.
+
+*** Running sgsnemu ***
+Use sgsnemu -h for a list of available options.
+
diff --git a/aclocal.m4 b/aclocal.m4
new file mode 100644
index 0000000..1f00df6
--- /dev/null
+++ b/aclocal.m4
@@ -0,0 +1,522 @@
+dnl aclocal.m4 generated automatically by aclocal 1.4
+
+dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl This program is distributed in the hope that it will be useful,
+dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+dnl PARTICULAR PURPOSE.
+
+
+# serial 40 AC_PROG_LIBTOOL
+AC_DEFUN(AC_PROG_LIBTOOL,
+[AC_REQUIRE([AC_LIBTOOL_SETUP])dnl
+
+# Save cache, so that ltconfig can load it
+AC_CACHE_SAVE
+
+# Actually configure libtool. ac_aux_dir is where install-sh is found.
+CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
+LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \
+DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $lt_target \
+|| AC_MSG_ERROR([libtool configure failed])
+
+# Reload cache, that may have been modified by ltconfig
+AC_CACHE_LOAD
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+AC_SUBST(LIBTOOL)dnl
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+])
+
+AC_DEFUN(AC_LIBTOOL_SETUP,
+[AC_PREREQ(2.13)dnl
+AC_REQUIRE([AC_ENABLE_SHARED])dnl
+AC_REQUIRE([AC_ENABLE_STATIC])dnl
+AC_REQUIRE([AC_ENABLE_FAST_INSTALL])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+AC_REQUIRE([AC_PROG_RANLIB])dnl
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_PROG_LD])dnl
+AC_REQUIRE([AC_PROG_NM])dnl
+AC_REQUIRE([AC_PROG_LN_S])dnl
+dnl
+
+case "$target" in
+NONE) lt_target="$host" ;;
+*) lt_target="$target" ;;
+esac
+
+# Check for any special flags to pass to ltconfig.
+#
+# the following will cause an existing older ltconfig to fail, so
+# we ignore this at the expense of the cache file... Checking this
+# will just take longer ... bummer!
+#libtool_flags="--cache-file=$cache_file"
+#
+test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
+test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
+test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install"
+test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+ifdef([AC_PROVIDE_AC_LIBTOOL_DLOPEN],
+[libtool_flags="$libtool_flags --enable-dlopen"])
+ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL],
+[libtool_flags="$libtool_flags --enable-win32-dll"])
+AC_ARG_ENABLE(libtool-lock,
+ [ --disable-libtool-lock avoid locking (might break parallel builds)])
+test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock"
+test x"$silent" = xyes && libtool_flags="$libtool_flags --silent"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case "$lt_target" in
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+ if AC_TRY_EVAL(ac_compile); then
+ case "`/usr/bin/file conftest.o`" in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ AC_CACHE_CHECK([whether the C compiler needs -belf], lt_cv_cc_needs_belf,
+ [AC_TRY_LINK([],[],[lt_cv_cc_needs_belf=yes],[lt_cv_cc_needs_belf=no])])
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+
+ifdef([AC_PROVIDE_AC_LIBTOOL_WIN32_DLL],
+[*-*-cygwin* | *-*-mingw*)
+ AC_CHECK_TOOL(DLLTOOL, dlltool, false)
+ AC_CHECK_TOOL(AS, as, false)
+ AC_CHECK_TOOL(OBJDUMP, objdump, false)
+ ;;
+])
+esac
+])
+
+# AC_LIBTOOL_DLOPEN - enable checks for dlopen support
+AC_DEFUN(AC_LIBTOOL_DLOPEN, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])])
+
+# AC_LIBTOOL_WIN32_DLL - declare package support for building win32 dll's
+AC_DEFUN(AC_LIBTOOL_WIN32_DLL, [AC_BEFORE([$0], [AC_LIBTOOL_SETUP])])
+
+# AC_ENABLE_SHARED - implement the --enable-shared flag
+# Usage: AC_ENABLE_SHARED[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN(AC_ENABLE_SHARED, [dnl
+define([AC_ENABLE_SHARED_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(shared,
+changequote(<<, >>)dnl
+<< --enable-shared[=PKGS] build shared libraries [default=>>AC_ENABLE_SHARED_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_shared=AC_ENABLE_SHARED_DEFAULT)dnl
+])
+
+# AC_DISABLE_SHARED - set the default shared flag to --disable-shared
+AC_DEFUN(AC_DISABLE_SHARED, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_SHARED(no)])
+
+# AC_ENABLE_STATIC - implement the --enable-static flag
+# Usage: AC_ENABLE_STATIC[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN(AC_ENABLE_STATIC, [dnl
+define([AC_ENABLE_STATIC_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(static,
+changequote(<<, >>)dnl
+<< --enable-static[=PKGS] build static libraries [default=>>AC_ENABLE_STATIC_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_static=AC_ENABLE_STATIC_DEFAULT)dnl
+])
+
+# AC_DISABLE_STATIC - set the default static flag to --disable-static
+AC_DEFUN(AC_DISABLE_STATIC, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_STATIC(no)])
+
+
+# AC_ENABLE_FAST_INSTALL - implement the --enable-fast-install flag
+# Usage: AC_ENABLE_FAST_INSTALL[(DEFAULT)]
+# Where DEFAULT is either `yes' or `no'. If omitted, it defaults to
+# `yes'.
+AC_DEFUN(AC_ENABLE_FAST_INSTALL, [dnl
+define([AC_ENABLE_FAST_INSTALL_DEFAULT], ifelse($1, no, no, yes))dnl
+AC_ARG_ENABLE(fast-install,
+changequote(<<, >>)dnl
+<< --enable-fast-install[=PKGS] optimize for fast installation [default=>>AC_ENABLE_FAST_INSTALL_DEFAULT],
+changequote([, ])dnl
+[p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac],
+enable_fast_install=AC_ENABLE_FAST_INSTALL_DEFAULT)dnl
+])
+
+# AC_ENABLE_FAST_INSTALL - set the default to --disable-fast-install
+AC_DEFUN(AC_DISABLE_FAST_INSTALL, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+AC_ENABLE_FAST_INSTALL(no)])
+
+# AC_PROG_LD - find the path to the GNU or non-GNU linker
+AC_DEFUN(AC_PROG_LD,
+[AC_ARG_WITH(gnu-ld,
+[ --with-gnu-ld assume the C compiler uses GNU ld [default=no]],
+test "$withval" = no || with_gnu_ld=yes, with_gnu_ld=no)
+AC_REQUIRE([AC_PROG_CC])dnl
+AC_REQUIRE([AC_CANONICAL_HOST])dnl
+AC_REQUIRE([AC_CANONICAL_BUILD])dnl
+ac_prog=ld
+if test "$ac_cv_prog_gcc" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ AC_MSG_CHECKING([for ld used by GCC])
+ ac_prog=`($CC -print-prog-name=ld) 2>&5`
+ case "$ac_prog" in
+ # Accept absolute paths.
+changequote(,)dnl
+ [\\/]* | [A-Za-z]:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+changequote([,])dnl
+ # Canonicalize the path of ld
+ ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ AC_MSG_CHECKING([for GNU ld])
+else
+ AC_MSG_CHECKING([for non-GNU ld])
+fi
+AC_CACHE_VAL(ac_cv_path_LD,
+[if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ ac_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+ test "$with_gnu_ld" != no && break
+ else
+ test "$with_gnu_ld" != yes && break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+else
+ ac_cv_path_LD="$LD" # Let the user override the test with a path.
+fi])
+LD="$ac_cv_path_LD"
+if test -n "$LD"; then
+ AC_MSG_RESULT($LD)
+else
+ AC_MSG_RESULT(no)
+fi
+test -z "$LD" && AC_MSG_ERROR([no acceptable ld found in \$PATH])
+AC_PROG_LD_GNU
+])
+
+AC_DEFUN(AC_PROG_LD_GNU,
+[AC_CACHE_CHECK([if the linker ($LD) is GNU ld], ac_cv_prog_gnu_ld,
+[# I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+ ac_cv_prog_gnu_ld=yes
+else
+ ac_cv_prog_gnu_ld=no
+fi])
+])
+
+# AC_PROG_NM - find the path to a BSD-compatible name lister
+AC_DEFUN(AC_PROG_NM,
+[AC_MSG_CHECKING([for BSD-compatible nm])
+AC_CACHE_VAL(ac_cv_path_NM,
+[if test -n "$NM"; then
+ # Let the user override the test.
+ ac_cv_path_NM="$NM"
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+ for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -B"
+ break
+ elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -p"
+ break
+ else
+ ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
+fi])
+NM="$ac_cv_path_NM"
+AC_MSG_RESULT([$NM])
+])
+
+# AC_CHECK_LIBM - check for math library
+AC_DEFUN(AC_CHECK_LIBM,
+[AC_REQUIRE([AC_CANONICAL_HOST])dnl
+LIBM=
+case "$lt_target" in
+*-*-beos* | *-*-cygwin*)
+ # These system don't have libm
+ ;;
+*-ncr-sysv4.3*)
+ AC_CHECK_LIB(mw, _mwvalidcheckl, LIBM="-lmw")
+ AC_CHECK_LIB(m, main, LIBM="$LIBM -lm")
+ ;;
+*)
+ AC_CHECK_LIB(m, main, LIBM="-lm")
+ ;;
+esac
+])
+
+# AC_LIBLTDL_CONVENIENCE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl convenience library and INCLTDL to the include flags for
+# the libltdl header and adds --enable-ltdl-convenience to the
+# configure arguments. Note that LIBLTDL and INCLTDL are not
+# AC_SUBSTed, nor is AC_CONFIG_SUBDIRS called. If DIR is not
+# provided, it is assumed to be `libltdl'. LIBLTDL will be prefixed
+# with '${top_builddir}/' and INCLTDL will be prefixed with
+# '${top_srcdir}/' (note the single quotes!). If your package is not
+# flat and you're not using automake, define top_builddir and
+# top_srcdir appropriately in the Makefiles.
+AC_DEFUN(AC_LIBLTDL_CONVENIENCE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+ case "$enable_ltdl_convenience" in
+ no) AC_MSG_ERROR([this package needs a convenience libltdl]) ;;
+ "") enable_ltdl_convenience=yes
+ ac_configure_args="$ac_configure_args --enable-ltdl-convenience" ;;
+ esac
+ LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdlc.la
+ INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
+])
+
+# AC_LIBLTDL_INSTALLABLE[(dir)] - sets LIBLTDL to the link flags for
+# the libltdl installable library and INCLTDL to the include flags for
+# the libltdl header and adds --enable-ltdl-install to the configure
+# arguments. Note that LIBLTDL and INCLTDL are not AC_SUBSTed, nor is
+# AC_CONFIG_SUBDIRS called. If DIR is not provided and an installed
+# libltdl is not found, it is assumed to be `libltdl'. LIBLTDL will
+# be prefixed with '${top_builddir}/' and INCLTDL will be prefixed
+# with '${top_srcdir}/' (note the single quotes!). If your package is
+# not flat and you're not using automake, define top_builddir and
+# top_srcdir appropriately in the Makefiles.
+# In the future, this macro may have to be called after AC_PROG_LIBTOOL.
+AC_DEFUN(AC_LIBLTDL_INSTALLABLE, [AC_BEFORE([$0],[AC_LIBTOOL_SETUP])dnl
+ AC_CHECK_LIB(ltdl, main,
+ [test x"$enable_ltdl_install" != xyes && enable_ltdl_install=no],
+ [if test x"$enable_ltdl_install" = xno; then
+ AC_MSG_WARN([libltdl not installed, but installation disabled])
+ else
+ enable_ltdl_install=yes
+ fi
+ ])
+ if test x"$enable_ltdl_install" = x"yes"; then
+ ac_configure_args="$ac_configure_args --enable-ltdl-install"
+ LIBLTDL='${top_builddir}/'ifelse($#,1,[$1],['libltdl'])/libltdl.la
+ INCLTDL='-I${top_srcdir}/'ifelse($#,1,[$1],['libltdl'])
+ else
+ ac_configure_args="$ac_configure_args --enable-ltdl-install=no"
+ LIBLTDL="-lltdl"
+ INCLTDL=
+ fi
+])
+
+dnl old names
+AC_DEFUN(AM_PROG_LIBTOOL, [indir([AC_PROG_LIBTOOL])])dnl
+AC_DEFUN(AM_ENABLE_SHARED, [indir([AC_ENABLE_SHARED], $@)])dnl
+AC_DEFUN(AM_ENABLE_STATIC, [indir([AC_ENABLE_STATIC], $@)])dnl
+AC_DEFUN(AM_DISABLE_SHARED, [indir([AC_DISABLE_SHARED], $@)])dnl
+AC_DEFUN(AM_DISABLE_STATIC, [indir([AC_DISABLE_STATIC], $@)])dnl
+AC_DEFUN(AM_PROG_LD, [indir([AC_PROG_LD])])dnl
+AC_DEFUN(AM_PROG_NM, [indir([AC_PROG_NM])])dnl
+
+dnl This is just to silence aclocal about the macro not being used
+ifelse([AC_DISABLE_FAST_INSTALL])dnl
+
+# Do all the work for Automake. This macro actually does too much --
+# some checks are only needed if your package does certain things.
+# But this isn't really a big deal.
+
+# serial 1
+
+dnl Usage:
+dnl AM_INIT_AUTOMAKE(package,version, [no-define])
+
+AC_DEFUN(AM_INIT_AUTOMAKE,
+[AC_REQUIRE([AC_PROG_INSTALL])
+PACKAGE=[$1]
+AC_SUBST(PACKAGE)
+VERSION=[$2]
+AC_SUBST(VERSION)
+dnl test to see if srcdir already configured
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+ AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
+fi
+ifelse([$3],,
+AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
+AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package]))
+AC_REQUIRE([AM_SANITY_CHECK])
+AC_REQUIRE([AC_ARG_PROGRAM])
+dnl FIXME This is truly gross.
+missing_dir=`cd $ac_aux_dir && pwd`
+AM_MISSING_PROG(ACLOCAL, aclocal, $missing_dir)
+AM_MISSING_PROG(AUTOCONF, autoconf, $missing_dir)
+AM_MISSING_PROG(AUTOMAKE, automake, $missing_dir)
+AM_MISSING_PROG(AUTOHEADER, autoheader, $missing_dir)
+AM_MISSING_PROG(MAKEINFO, makeinfo, $missing_dir)
+AC_REQUIRE([AC_PROG_MAKE_SET])])
+
+#
+# Check to make sure that the build environment is sane.
+#
+
+AC_DEFUN(AM_SANITY_CHECK,
+[AC_MSG_CHECKING([whether build environment is sane])
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+ if test "[$]*" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftestfile`
+ fi
+ if test "[$]*" != "X $srcdir/configure conftestfile" \
+ && test "[$]*" != "X conftestfile $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
+alias in your environment])
+ fi
+
+ test "[$]2" = conftestfile
+ )
+then
+ # Ok.
+ :
+else
+ AC_MSG_ERROR([newly created file is older than distributed files!
+Check your system clock])
+fi
+rm -f conftest*
+AC_MSG_RESULT(yes)])
+
+dnl AM_MISSING_PROG(NAME, PROGRAM, DIRECTORY)
+dnl The program must properly implement --version.
+AC_DEFUN(AM_MISSING_PROG,
+[AC_MSG_CHECKING(for working $2)
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if ($2 --version) < /dev/null > /dev/null 2>&1; then
+ $1=$2
+ AC_MSG_RESULT(found)
+else
+ $1="$3/missing $2"
+ AC_MSG_RESULT(missing)
+fi
+AC_SUBST($1)])
+
diff --git a/config.cache b/config.cache
new file mode 100644
index 0000000..99016f3
--- /dev/null
+++ b/config.cache
@@ -0,0 +1,48 @@
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+ac_cv_c_const=${ac_cv_c_const=yes}
+ac_cv_func_select=${ac_cv_func_select=yes}
+ac_cv_func_socket=${ac_cv_func_socket=yes}
+ac_cv_func_strdup=${ac_cv_func_strdup=yes}
+ac_cv_func_strerror=${ac_cv_func_strerror=yes}
+ac_cv_func_strtoul=${ac_cv_func_strtoul=yes}
+ac_cv_func_vfork_works=${ac_cv_func_vfork_works=yes}
+ac_cv_header_fcntl_h=${ac_cv_header_fcntl_h=yes}
+ac_cv_header_stdc=${ac_cv_header_stdc=yes}
+ac_cv_header_strings_h=${ac_cv_header_strings_h=yes}
+ac_cv_header_sys_ioctl_h=${ac_cv_header_sys_ioctl_h=yes}
+ac_cv_header_sys_time_h=${ac_cv_header_sys_time_h=yes}
+ac_cv_header_sys_wait_h=${ac_cv_header_sys_wait_h=yes}
+ac_cv_header_syslog_h=${ac_cv_header_syslog_h=yes}
+ac_cv_header_time=${ac_cv_header_time=yes}
+ac_cv_header_unistd_h=${ac_cv_header_unistd_h=yes}
+ac_cv_header_vfork_h=${ac_cv_header_vfork_h=no}
+ac_cv_path_LD=${ac_cv_path_LD=/usr/bin/ld}
+ac_cv_path_NM=${ac_cv_path_NM='/usr/bin/nm -B'}
+ac_cv_path_install=${ac_cv_path_install='/usr/bin/install -c'}
+ac_cv_prog_AWK=${ac_cv_prog_AWK=gawk}
+ac_cv_prog_CC=${ac_cv_prog_CC=gcc}
+ac_cv_prog_CPP=${ac_cv_prog_CPP='gcc -E'}
+ac_cv_prog_LN_S=${ac_cv_prog_LN_S='ln -s'}
+ac_cv_prog_RANLIB=${ac_cv_prog_RANLIB=ranlib}
+ac_cv_prog_cc_cross=${ac_cv_prog_cc_cross=no}
+ac_cv_prog_cc_g=${ac_cv_prog_cc_g=yes}
+ac_cv_prog_cc_works=${ac_cv_prog_cc_works=yes}
+ac_cv_prog_gcc=${ac_cv_prog_gcc=yes}
+ac_cv_prog_gcc_traditional=${ac_cv_prog_gcc_traditional=no}
+ac_cv_prog_gnu_ld=${ac_cv_prog_gnu_ld=yes}
+ac_cv_prog_make_make_set=${ac_cv_prog_make_make_set=yes}
+ac_cv_type_pid_t=${ac_cv_type_pid_t=yes}
+ac_cv_type_size_t=${ac_cv_type_size_t=yes}
diff --git a/config.h.in b/config.h.in
new file mode 100644
index 0000000..d387a03
--- /dev/null
+++ b/config.h.in
@@ -0,0 +1,65 @@
+/* config.h.in. Generated automatically from configure.in by autoheader. */
+
+/* Define to empty if the keyword does not work. */
+#undef const
+
+/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define if you have <vfork.h>. */
+#undef HAVE_VFORK_H
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef pid_t
+
+/* Define to `unsigned' if <sys/types.h> doesn't define. */
+#undef size_t
+
+/* Define if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
+
+/* Define vfork as fork if vfork does not work. */
+#undef vfork
+
+/* Define if you have the select function. */
+#undef HAVE_SELECT
+
+/* Define if you have the socket function. */
+#undef HAVE_SOCKET
+
+/* Define if you have the strdup function. */
+#undef HAVE_STRDUP
+
+/* Define if you have the strerror function. */
+#undef HAVE_STRERROR
+
+/* Define if you have the strtoul function. */
+#undef HAVE_STRTOUL
+
+/* Define if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define if you have the <sys/ioctl.h> header file. */
+#undef HAVE_SYS_IOCTL_H
+
+/* Define if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
+/* Define if you have the <syslog.h> header file. */
+#undef HAVE_SYSLOG_H
+
+/* Define if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Name of package */
+#undef PACKAGE
+
+/* Version number of package */
+#undef VERSION
+
diff --git a/config.log b/config.log
new file mode 100644
index 0000000..d8cf5e6
--- /dev/null
+++ b/config.log
@@ -0,0 +1,84 @@
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+
+configure:541: checking for gawk
+configure:573: checking for gcc
+configure:686: checking whether the C compiler (gcc ) works
+configure:702: gcc -o conftest conftest.c 1>&5
+configure:728: checking whether the C compiler (gcc ) is a cross-compiler
+configure:733: checking whether we are using GNU C
+configure:761: checking whether gcc accepts -g
+configure:823: checking for a BSD compatible install
+configure:876: checking whether ln -s works
+configure:973: checking host system type
+configure:994: checking build system type
+configure:1014: checking for ranlib
+configure:1053: checking for ld used by GCC
+configure:1115: checking if the linker (/usr/bin/ld) is GNU ld
+configure:1131: checking for BSD-compatible nm
+ltconfig:603: checking for object suffix
+ltconfig:604: gcc -c -g -O2 conftest.c 1>&5
+ltconfig:629: checking for executable suffix
+ltconfig:630: gcc -o conftest -g -O2 conftest.c 1>&5
+ltconfig:776: checking if gcc PIC flag -fPIC works
+ltconfig:777: gcc -c -g -O2 -fPIC -DPIC conftest.c 1>&5
+ltconfig:829: checking if gcc supports -c -o file.o
+ltconfig:830: gcc -c -g -O2 -o out/conftest2.o conftest.c 1>&5
+ltconfig:862: checking if gcc supports -c -o file.lo
+ltconfig:863: gcc -c -g -O2 -c -o conftest.lo conftest.c 1>&5
+ltconfig:914: checking if gcc supports -fno-rtti -fno-exceptions
+ltconfig:915: gcc -c -g -O2 -fno-rtti -fno-exceptions -c conftest.c conftest.c 1>&5
+ltconfig:958: checking if gcc static flag -static works
+ltconfig:959: gcc -o conftest -g -O2 -static conftest.c 1>&5
+GNU ld version 2.10.91 (with BFD 2.10.91.0.2)
+ltconfig:1653: checking if global_symbol_pipe works
+ltconfig:1654: gcc -c -g -O2 conftest.c 1>&5
+ltconfig:1657: eval "/usr/bin/nm -B conftest.o | sed -n -e 's/^.*[ ]\([ABCDGISTW]\)[ ][ ]*\(\)\([_A-Za-z][_A-Za-z0-9]*\)$/\1 \2\3 \3/p' > conftest.nm"
+ltconfig:1709: gcc -o conftest -g -O2 -fno-builtin -fno-rtti -fno-exceptions conftest.c conftstm.o 1>&5
+ltconfig:603: checking for object suffix
+ltconfig:604: gcc -c -g -O2 conftest.c 1>&5
+ltconfig:629: checking for executable suffix
+ltconfig:630: gcc -o conftest -g -O2 conftest.c 1>&5
+ltconfig:776: checking if gcc PIC flag -fPIC works
+ltconfig:777: gcc -c -g -O2 -fPIC -DPIC conftest.c 1>&5
+ltconfig:829: checking if gcc supports -c -o file.o
+ltconfig:830: gcc -c -g -O2 -o out/conftest2.o conftest.c 1>&5
+ltconfig:862: checking if gcc supports -c -o file.lo
+ltconfig:863: gcc -c -g -O2 -c -o conftest.lo conftest.c 1>&5
+ltconfig:914: checking if gcc supports -fno-rtti -fno-exceptions
+ltconfig:915: gcc -c -g -O2 -fno-rtti -fno-exceptions -c conftest.c conftest.c 1>&5
+ltconfig:958: checking if gcc static flag -static works
+ltconfig:959: gcc -o conftest -g -O2 -static conftest.c 1>&5
+GNU ld version 2.10.91 (with BFD 2.10.91.0.2)
+ltconfig:1653: checking if global_symbol_pipe works
+ltconfig:1654: gcc -c -g -O2 conftest.c 1>&5
+ltconfig:1657: eval "/usr/bin/nm -B conftest.o | sed -n -e 's/^.*[ ]\([ABCDGISTW]\)[ ][ ]*\(\)\([_A-Za-z][_A-Za-z0-9]*\)$/\1 \2\3 \3/p' > conftest.nm"
+ltconfig:1709: gcc -o conftest -g -O2 -fno-builtin -fno-rtti -fno-exceptions conftest.c conftstm.o 1>&5
+configure:1417: checking how to run the C preprocessor
+configure:1497: checking for ANSI C header files
+configure:1601: checking for sys/wait.h that is POSIX.1 compatible
+configure:1646: checking for fcntl.h
+configure:1646: checking for strings.h
+configure:1646: checking for sys/ioctl.h
+configure:1646: checking for sys/time.h
+configure:1646: checking for syslog.h
+configure:1646: checking for unistd.h
+configure:1684: checking for working const
+configure:1759: checking for size_t
+configure:1792: checking whether time.h and sys/time.h may both be included
+configure:1829: checking whether gcc needs -traditional
+configure:1875: checking for pid_t
+configure:1909: checking for vfork.h
+configure:1944: checking for working vfork
+configure:2120: checking for select
+configure:2120: checking for socket
+configure:2120: checking for strdup
+configure:2120: checking for strerror
+configure:2120: checking for strtoul
+configure:2174: checking whether build environment is sane
+configure:2231: checking whether make sets ${MAKE}
+configure:2277: checking for working aclocal
+configure:2290: checking for working autoconf
+configure:2303: checking for working automake
+configure:2316: checking for working autoheader
+configure:2329: checking for working makeinfo
diff --git a/config.status b/config.status
new file mode 100755
index 0000000..2add899
--- /dev/null
+++ b/config.status
@@ -0,0 +1,182 @@
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host oslo:
+#
+# ./configure
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: ./config.status [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running ${CONFIG_SHELL-/bin/sh} ./configure --no-create --no-recursion"
+ exec ${CONFIG_SHELL-/bin/sh} ./configure --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "./config.status generated by autoconf version 2.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "$ac_cs_usage"; exit 0 ;;
+ *) echo "$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=.
+ac_given_INSTALL="/usr/bin/install -c"
+
+trap 'rm -fr doc/Makefile po/Makefile intl/Makefile Makefile tests/Makefile src/Makefile gtp/Makefile ggsn/Makefile sgsnemu/Makefile conftest*; exit 1' 1 2 15
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g$/@g/; /@g$/s/[\\&%]/\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g$/%g/' > conftest.subs <<\CEOF
+/^[ ]*VPATH[ ]*=[^:]*$/d
+
+s%@SHELL@%/bin/sh%g
+s%@CFLAGS@%-g -O2%g
+s%@CPPFLAGS@%%g
+s%@CXXFLAGS@%%g
+s%@FFLAGS@%%g
+s%@DEFS@% -DSTDC_HEADERS=1 -DHAVE_SYS_WAIT_H=1 -DHAVE_FCNTL_H=1 -DHAVE_STRINGS_H=1 -DHAVE_SYS_IOCTL_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYSLOG_H=1 -DHAVE_UNISTD_H=1 -DTIME_WITH_SYS_TIME=1 -DHAVE_SELECT=1 -DHAVE_SOCKET=1 -DHAVE_STRDUP=1 -DHAVE_STRERROR=1 -DHAVE_STRTOUL=1 -DPACKAGE=\"OpenGGSN\" -DVERSION=\"0.5\" %g
+s%@LDFLAGS@%%g
+s%@LIBS@%%g
+s%@exec_prefix@%${prefix}%g
+s%@prefix@%/usr/local%g
+s%@program_transform_name@%s,x,x,%g
+s%@bindir@%${exec_prefix}/bin%g
+s%@sbindir@%${exec_prefix}/sbin%g
+s%@libexecdir@%${exec_prefix}/libexec%g
+s%@datadir@%${prefix}/share%g
+s%@sysconfdir@%${prefix}/etc%g
+s%@sharedstatedir@%${prefix}/com%g
+s%@localstatedir@%${prefix}/var%g
+s%@libdir@%${exec_prefix}/lib%g
+s%@includedir@%${prefix}/include%g
+s%@oldincludedir@%/usr/include%g
+s%@infodir@%${prefix}/info%g
+s%@mandir@%${prefix}/man%g
+s%@AWK@%gawk%g
+s%@CC@%gcc%g
+s%@INSTALL_PROGRAM@%${INSTALL}%g
+s%@INSTALL_SCRIPT@%${INSTALL_PROGRAM}%g
+s%@INSTALL_DATA@%${INSTALL} -m 644%g
+s%@LN_S@%ln -s%g
+s%@host@%i686-pc-linux-gnu%g
+s%@host_alias@%i686-pc-linux%g
+s%@host_cpu@%i686%g
+s%@host_vendor@%pc%g
+s%@host_os@%linux-gnu%g
+s%@build@%i686-pc-linux-gnu%g
+s%@build_alias@%i686-pc-linux%g
+s%@build_cpu@%i686%g
+s%@build_vendor@%pc%g
+s%@build_os@%linux-gnu%g
+s%@RANLIB@%ranlib%g
+s%@LIBTOOL@%$(SHELL) $(top_builddir)/libtool%g
+s%@CPP@%gcc -E%g
+s%@PACKAGE@%OpenGGSN%g
+s%@VERSION@%0.5%g
+s%@ACLOCAL@%aclocal%g
+s%@AUTOCONF@%autoconf%g
+s%@AUTOMAKE@%automake%g
+s%@AUTOHEADER@%autoheader%g
+s%@MAKEINFO@%makeinfo%g
+s%@SET_MAKE@%%g
+
+CEOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+
+CONFIG_FILES=${CONFIG_FILES-"doc/Makefile po/Makefile intl/Makefile Makefile tests/Makefile src/Makefile gtp/Makefile ggsn/Makefile sgsnemu/Makefile"}
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+ case "$ac_given_INSTALL" in
+ [/$]*) INSTALL="$ac_given_INSTALL" ;;
+ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+ esac
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+
+
+exit 0
diff --git a/configure b/configure
new file mode 100755
index 0000000..c5a480d
--- /dev/null
+++ b/configure
@@ -0,0 +1,2625 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_help="$ac_help
+ --enable-shared[=PKGS] build shared libraries [default=yes]"
+ac_help="$ac_help
+ --enable-static[=PKGS] build static libraries [default=yes]"
+ac_help="$ac_help
+ --enable-fast-install[=PKGS] optimize for fast installation [default=yes]"
+ac_help="$ac_help
+ --with-gnu-ld assume the C compiler uses GNU ld [default=no]"
+ac_help="$ac_help
+ --disable-libtool-lock avoid locking (might break parallel builds)"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir="$ac_optarg" ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file="$ac_optarg" ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
+EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$ac_optarg" ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir="$ac_optarg" ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir="$ac_optarg" ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir="$ac_optarg" ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir="$ac_optarg" ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir="$ac_optarg" ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir="$ac_optarg" ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir="$ac_optarg" ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir="$ac_optarg" ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir="$ac_optarg" ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir="$ac_optarg" ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir="$ac_optarg" ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=gtp/gtp.c ggsn/ggsn.c sgsnemu/sgsnemu.c
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+for ac_prog in gawk mawk nawk awk
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:541: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_AWK'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$AWK"; then
+ ac_cv_prog_AWK="$AWK" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_AWK="$ac_prog"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+AWK="$ac_cv_prog_AWK"
+if test -n "$AWK"; then
+ echo "$ac_t""$AWK" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+test -n "$AWK" && break
+done
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:573: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:603: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_prog_rejected=no
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test -z "$CC"; then
+ case "`uname -s`" in
+ *win32* | *WIN32*)
+ # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:654: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="cl"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ ;;
+ esac
+ fi
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:686: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 697 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:702: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:728: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:733: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:742: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:761: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+
+ac_aux_dir=
+for ac_dir in $srcdir $srcdir/.. $srcdir/../..; do
+ if test -f $ac_dir/install-sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install-sh -c"
+ break
+ elif test -f $ac_dir/install.sh; then
+ ac_aux_dir=$ac_dir
+ ac_install_sh="$ac_aux_dir/install.sh -c"
+ break
+ fi
+done
+if test -z "$ac_aux_dir"; then
+ { echo "configure: error: can not find install-sh or install.sh in $srcdir $srcdir/.. $srcdir/../.." 1>&2; exit 1; }
+fi
+ac_config_guess=$ac_aux_dir/config.guess
+ac_config_sub=$ac_aux_dir/config.sub
+ac_configure=$ac_aux_dir/configure # This should be Cygnus configure.
+
+# Find a good install program. We prefer a C program (faster),
+# so one script is as good as another. But avoid the broken or
+# incompatible versions:
+# SysV /etc/install, /usr/sbin/install
+# SunOS /usr/etc/install
+# IRIX /sbin/install
+# AIX /bin/install
+# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag
+# AFS /usr/afsws/bin/install, which mishandles nonexistent args
+# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
+# ./install, which can be erroneously created by make from ./install.sh.
+echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
+echo "configure:823: checking for a BSD compatible install" >&5
+if test -z "$INSTALL"; then
+if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ IFS="${IFS= }"; ac_save_IFS="$IFS"; IFS=":"
+ for ac_dir in $PATH; do
+ # Account for people who put trailing slashes in PATH elements.
+ case "$ac_dir/" in
+ /|./|.//|/etc/*|/usr/sbin/*|/usr/etc/*|/sbin/*|/usr/afsws/bin/*|/usr/ucb/*) ;;
+ *)
+ # OSF1 and SCO ODT 3.0 have their own names for install.
+ # Don't use installbsd from OSF since it installs stuff as root
+ # by default.
+ for ac_prog in ginstall scoinst install; do
+ if test -f $ac_dir/$ac_prog; then
+ if test $ac_prog = install &&
+ grep dspmsg $ac_dir/$ac_prog >/dev/null 2>&1; then
+ # AIX install. It has an incompatible calling convention.
+ :
+ else
+ ac_cv_path_install="$ac_dir/$ac_prog -c"
+ break 2
+ fi
+ fi
+ done
+ ;;
+ esac
+ done
+ IFS="$ac_save_IFS"
+
+fi
+ if test "${ac_cv_path_install+set}" = set; then
+ INSTALL="$ac_cv_path_install"
+ else
+ # As a last resort, use the slow shell script. We don't cache a
+ # path for INSTALL within a source directory, because that will
+ # break other packages using the cache if that directory is
+ # removed, or if the path is relative.
+ INSTALL="$ac_install_sh"
+ fi
+fi
+echo "$ac_t""$INSTALL" 1>&6
+
+# Use test -z because SunOS4 sh mishandles braces in ${var-val}.
+# It thinks the first close brace ends the variable substitution.
+test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}'
+
+test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}'
+
+test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
+
+echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
+echo "configure:876: checking whether ln -s works" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ rm -f conftestdata
+if ln -s X conftestdata 2>/dev/null
+then
+ rm -f conftestdata
+ ac_cv_prog_LN_S="ln -s"
+else
+ ac_cv_prog_LN_S=ln
+fi
+fi
+LN_S="$ac_cv_prog_LN_S"
+if test "$ac_cv_prog_LN_S" = "ln -s"; then
+ echo "$ac_t""yes" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+# Check whether --enable-shared or --disable-shared was given.
+if test "${enable_shared+set}" = set; then
+ enableval="$enable_shared"
+ p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_shared=yes ;;
+no) enable_shared=no ;;
+*)
+ enable_shared=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_shared=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_shared=yes
+fi
+
+# Check whether --enable-static or --disable-static was given.
+if test "${enable_static+set}" = set; then
+ enableval="$enable_static"
+ p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_static=yes ;;
+no) enable_static=no ;;
+*)
+ enable_static=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_static=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_static=yes
+fi
+
+# Check whether --enable-fast-install or --disable-fast-install was given.
+if test "${enable_fast_install+set}" = set; then
+ enableval="$enable_fast_install"
+ p=${PACKAGE-default}
+case "$enableval" in
+yes) enable_fast_install=yes ;;
+no) enable_fast_install=no ;;
+*)
+ enable_fast_install=no
+ # Look at the argument we got. We use all the common list separators.
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}:,"
+ for pkg in $enableval; do
+ if test "X$pkg" = "X$p"; then
+ enable_fast_install=yes
+ fi
+ done
+ IFS="$ac_save_ifs"
+ ;;
+esac
+else
+ enable_fast_install=yes
+fi
+
+
+# Make sure we can run config.sub.
+if ${CONFIG_SHELL-/bin/sh} $ac_config_sub sun4 >/dev/null 2>&1; then :
+else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking host system type""... $ac_c" 1>&6
+echo "configure:973: checking host system type" >&5
+
+host_alias=$host
+case "$host_alias" in
+NONE)
+ case $nonopt in
+ NONE)
+ if host_alias=`${CONFIG_SHELL-/bin/sh} $ac_config_guess`; then :
+ else { echo "configure: error: can not guess host type; you must specify one" 1>&2; exit 1; }
+ fi ;;
+ *) host_alias=$nonopt ;;
+ esac ;;
+esac
+
+host=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $host_alias`
+host_cpu=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+host_vendor=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+host_os=`echo $host | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$host" 1>&6
+
+echo $ac_n "checking build system type""... $ac_c" 1>&6
+echo "configure:994: checking build system type" >&5
+
+build_alias=$build
+case "$build_alias" in
+NONE)
+ case $nonopt in
+ NONE) build_alias=$host_alias ;;
+ *) build_alias=$nonopt ;;
+ esac ;;
+esac
+
+build=`${CONFIG_SHELL-/bin/sh} $ac_config_sub $build_alias`
+build_cpu=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
+build_vendor=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
+build_os=`echo $build | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
+echo "$ac_t""$build" 1>&6
+
+# Extract the first word of "ranlib", so it can be a program name with args.
+set dummy ranlib; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:1014: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$RANLIB"; then
+ ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_RANLIB="ranlib"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_RANLIB" && ac_cv_prog_RANLIB=":"
+fi
+fi
+RANLIB="$ac_cv_prog_RANLIB"
+if test -n "$RANLIB"; then
+ echo "$ac_t""$RANLIB" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+# Check whether --with-gnu-ld or --without-gnu-ld was given.
+if test "${with_gnu_ld+set}" = set; then
+ withval="$with_gnu_ld"
+ test "$withval" = no || with_gnu_ld=yes
+else
+ with_gnu_ld=no
+fi
+
+ac_prog=ld
+if test "$ac_cv_prog_gcc" = yes; then
+ # Check if gcc -print-prog-name=ld gives a path.
+ echo $ac_n "checking for ld used by GCC""... $ac_c" 1>&6
+echo "configure:1053: checking for ld used by GCC" >&5
+ ac_prog=`($CC -print-prog-name=ld) 2>&5`
+ case "$ac_prog" in
+ # Accept absolute paths.
+ [\\/]* | [A-Za-z]:[\\/]*)
+ re_direlt='/[^/][^/]*/\.\./'
+ # Canonicalize the path of ld
+ ac_prog=`echo $ac_prog| sed 's%\\\\%/%g'`
+ while echo $ac_prog | grep "$re_direlt" > /dev/null 2>&1; do
+ ac_prog=`echo $ac_prog| sed "s%$re_direlt%/%"`
+ done
+ test -z "$LD" && LD="$ac_prog"
+ ;;
+ "")
+ # If it fails, then pretend we aren't using GCC.
+ ac_prog=ld
+ ;;
+ *)
+ # If it is relative, then search for the first ld in PATH.
+ with_gnu_ld=unknown
+ ;;
+ esac
+elif test "$with_gnu_ld" = yes; then
+ echo $ac_n "checking for GNU ld""... $ac_c" 1>&6
+echo "configure:1077: checking for GNU ld" >&5
+else
+ echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6
+echo "configure:1080: checking for non-GNU ld" >&5
+fi
+if eval "test \"`echo '$''{'ac_cv_path_LD'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -z "$LD"; then
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+ for ac_dir in $PATH; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then
+ ac_cv_path_LD="$ac_dir/$ac_prog"
+ # Check to see if the program is GNU ld. I'd rather use --version,
+ # but apparently some GNU ld's only accept -v.
+ # Break only if it was the GNU/non-GNU ld that we prefer.
+ if "$ac_cv_path_LD" -v 2>&1 < /dev/null | egrep '(GNU|with BFD)' > /dev/null; then
+ test "$with_gnu_ld" != no && break
+ else
+ test "$with_gnu_ld" != yes && break
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+else
+ ac_cv_path_LD="$LD" # Let the user override the test with a path.
+fi
+fi
+
+LD="$ac_cv_path_LD"
+if test -n "$LD"; then
+ echo "$ac_t""$LD" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; }
+echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6
+echo "configure:1115: checking if the linker ($LD) is GNU ld" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gnu_ld'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # I'd rather use --version here, but apparently some GNU ld's only accept -v.
+if $LD -v 2>&1 </dev/null | egrep '(GNU|with BFD)' 1>&5; then
+ ac_cv_prog_gnu_ld=yes
+else
+ ac_cv_prog_gnu_ld=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gnu_ld" 1>&6
+
+
+echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6
+echo "configure:1131: checking for BSD-compatible nm" >&5
+if eval "test \"`echo '$''{'ac_cv_path_NM'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$NM"; then
+ # Let the user override the test.
+ ac_cv_path_NM="$NM"
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS="${IFS}${PATH_SEPARATOR-:}"
+ for ac_dir in $PATH /usr/ccs/bin /usr/ucb /bin; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/nm || test -f $ac_dir/nm$ac_exeext ; then
+ # Check to see if the nm accepts a BSD-compat flag.
+ # Adding the `sed 1q' prevents false positives on HP-UX, which says:
+ # nm: unknown option "B" ignored
+ if ($ac_dir/nm -B /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -B"
+ break
+ elif ($ac_dir/nm -p /dev/null 2>&1 | sed '1q'; exit 0) | egrep /dev/null >/dev/null; then
+ ac_cv_path_NM="$ac_dir/nm -p"
+ break
+ else
+ ac_cv_path_NM=${ac_cv_path_NM="$ac_dir/nm"} # keep the first match, but
+ continue # so that we can try to find one that supports BSD flags
+ fi
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_path_NM" && ac_cv_path_NM=nm
+fi
+fi
+
+NM="$ac_cv_path_NM"
+echo "$ac_t""$NM" 1>&6
+
+
+case "$target" in
+NONE) lt_target="$host" ;;
+*) lt_target="$target" ;;
+esac
+
+# Check for any special flags to pass to ltconfig.
+#
+# the following will cause an existing older ltconfig to fail, so
+# we ignore this at the expense of the cache file... Checking this
+# will just take longer ... bummer!
+#libtool_flags="--cache-file=$cache_file"
+#
+test "$enable_shared" = no && libtool_flags="$libtool_flags --disable-shared"
+test "$enable_static" = no && libtool_flags="$libtool_flags --disable-static"
+test "$enable_fast_install" = no && libtool_flags="$libtool_flags --disable-fast-install"
+test "$ac_cv_prog_gcc" = yes && libtool_flags="$libtool_flags --with-gcc"
+test "$ac_cv_prog_gnu_ld" = yes && libtool_flags="$libtool_flags --with-gnu-ld"
+
+
+# Check whether --enable-libtool-lock or --disable-libtool-lock was given.
+if test "${enable_libtool_lock+set}" = set; then
+ enableval="$enable_libtool_lock"
+ :
+fi
+
+test "x$enable_libtool_lock" = xno && libtool_flags="$libtool_flags --disable-lock"
+test x"$silent" = xyes && libtool_flags="$libtool_flags --silent"
+
+# Some flags need to be propagated to the compiler or linker for good
+# libtool support.
+case "$lt_target" in
+*-*-irix6*)
+ # Find out which ABI we are using.
+ echo '#line 1200 "configure"' > conftest.$ac_ext
+ if { (eval echo configure:1201: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ case "`/usr/bin/file conftest.o`" in
+ *32-bit*)
+ LD="${LD-ld} -32"
+ ;;
+ *N32*)
+ LD="${LD-ld} -n32"
+ ;;
+ *64-bit*)
+ LD="${LD-ld} -64"
+ ;;
+ esac
+ fi
+ rm -rf conftest*
+ ;;
+
+*-*-sco3.2v5*)
+ # On SCO OpenServer 5, we need -belf to get full-featured binaries.
+ SAVE_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -belf"
+ echo $ac_n "checking whether the C compiler needs -belf""... $ac_c" 1>&6
+echo "configure:1222: checking whether the C compiler needs -belf" >&5
+if eval "test \"`echo '$''{'lt_cv_cc_needs_belf'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1227 "configure"
+#include "confdefs.h"
+
+int main() {
+
+; return 0; }
+EOF
+if { (eval echo configure:1234: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ lt_cv_cc_needs_belf=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ lt_cv_cc_needs_belf=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$lt_cv_cc_needs_belf" 1>&6
+ if test x"$lt_cv_cc_needs_belf" != x"yes"; then
+ # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf
+ CFLAGS="$SAVE_CFLAGS"
+ fi
+ ;;
+
+
+esac
+
+
+# Save cache, so that ltconfig can load it
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+
+# Actually configure libtool. ac_aux_dir is where install-sh is found.
+CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
+LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \
+DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $lt_target \
+|| { echo "configure: error: libtool configure failed" 1>&2; exit 1; }
+
+# Reload cache, that may have been modified by ltconfig
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+
+
+# Save cache, so that ltconfig can load it
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+
+# Actually configure libtool. ac_aux_dir is where install-sh is found.
+CC="$CC" CFLAGS="$CFLAGS" CPPFLAGS="$CPPFLAGS" \
+LD="$LD" LDFLAGS="$LDFLAGS" LIBS="$LIBS" \
+LN_S="$LN_S" NM="$NM" RANLIB="$RANLIB" \
+DLLTOOL="$DLLTOOL" AS="$AS" OBJDUMP="$OBJDUMP" \
+${CONFIG_SHELL-/bin/sh} $ac_aux_dir/ltconfig --no-reexec \
+$libtool_flags --no-verify $ac_aux_dir/ltmain.sh $lt_target \
+|| { echo "configure: error: libtool configure failed" 1>&2; exit 1; }
+
+# Reload cache, that may have been modified by ltconfig
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+
+# This can be used to rebuild libtool when needed
+LIBTOOL_DEPS="$ac_aux_dir/ltconfig $ac_aux_dir/ltmain.sh"
+
+# Always use our own libtool.
+LIBTOOL='$(SHELL) $(top_builddir)/libtool'
+
+# Redirect the config.log output again, so that the ltconfig log is not
+# clobbered by the next message.
+exec 5>>./config.log
+
+
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:1417: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 1432 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1438: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 1449 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1455: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -nologo -E"
+ cat > conftest.$ac_ext <<EOF
+#line 1466 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1472: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:1497: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1502 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1510: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ ac_cv_header_stdc=yes
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1527 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "memchr" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1545 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "free" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+ :
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1566 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:1577: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+ cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6
+echo "configure:1601: checking for sys/wait.h that is POSIX.1 compatible" >&5
+if eval "test \"`echo '$''{'ac_cv_header_sys_wait_h'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1606 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/wait.h>
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
+#endif
+#ifndef WIFEXITED
+#define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
+#endif
+int main() {
+int s;
+wait (&s);
+s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
+; return 0; }
+EOF
+if { (eval echo configure:1622: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_header_sys_wait_h=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_sys_wait_h=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_sys_wait_h" 1>&6
+if test $ac_cv_header_sys_wait_h = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_SYS_WAIT_H 1
+EOF
+
+fi
+
+for ac_hdr in fcntl.h strings.h sys/ioctl.h sys/time.h syslog.h unistd.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1646: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1651 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1656: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+echo $ac_n "checking for working const""... $ac_c" 1>&6
+echo "configure:1684: checking for working const" >&5
+if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1689 "configure"
+#include "confdefs.h"
+
+int main() {
+
+/* Ultrix mips cc rejects this. */
+typedef int charset[2]; const charset x;
+/* SunOS 4.1.1 cc rejects this. */
+char const *const *ccp;
+char **p;
+/* NEC SVR4.0.2 mips cc rejects this. */
+struct point {int x, y;};
+static struct point const zero = {0,0};
+/* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in an arm
+ of an if-expression whose if-part is not a constant expression */
+const char *g = "string";
+ccp = &g + (g ? g-g : 0);
+/* HPUX 7.0 cc rejects these. */
+++ccp;
+p = (char**) ccp;
+ccp = (char const *const *) p;
+{ /* SCO 3.2v4 cc rejects this. */
+ char *t;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+}
+{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+}
+{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+}
+{ /* AIX XL C 1.02.0.0 rejects this saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; };
+ struct s *b; b->j = 5;
+}
+{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+}
+
+; return 0; }
+EOF
+if { (eval echo configure:1738: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_const=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_c_const=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_c_const" 1>&6
+if test $ac_cv_c_const = no; then
+ cat >> confdefs.h <<\EOF
+#define const
+EOF
+
+fi
+
+echo $ac_n "checking for size_t""... $ac_c" 1>&6
+echo "configure:1759: checking for size_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1764 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_size_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_size_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_size_t" 1>&6
+if test $ac_cv_type_size_t = no; then
+ cat >> confdefs.h <<\EOF
+#define size_t unsigned
+EOF
+
+fi
+
+echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
+echo "configure:1792: checking whether time.h and sys/time.h may both be included" >&5
+if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1797 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+int main() {
+struct tm *tp;
+; return 0; }
+EOF
+if { (eval echo configure:1806: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_header_time=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_time=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_time" 1>&6
+if test $ac_cv_header_time = yes; then
+ cat >> confdefs.h <<\EOF
+#define TIME_WITH_SYS_TIME 1
+EOF
+
+fi
+
+
+if test $ac_cv_prog_gcc = yes; then
+ echo $ac_n "checking whether ${CC-cc} needs -traditional""... $ac_c" 1>&6
+echo "configure:1829: checking whether ${CC-cc} needs -traditional" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc_traditional'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_pattern="Autoconf.*'x'"
+ cat > conftest.$ac_ext <<EOF
+#line 1835 "configure"
+#include "confdefs.h"
+#include <sgtty.h>
+Autoconf TIOCGETP
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "$ac_pattern" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_prog_gcc_traditional=yes
+else
+ rm -rf conftest*
+ ac_cv_prog_gcc_traditional=no
+fi
+rm -f conftest*
+
+
+ if test $ac_cv_prog_gcc_traditional = no; then
+ cat > conftest.$ac_ext <<EOF
+#line 1853 "configure"
+#include "confdefs.h"
+#include <termio.h>
+Autoconf TCGETA
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "$ac_pattern" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_prog_gcc_traditional=yes
+fi
+rm -f conftest*
+
+ fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc_traditional" 1>&6
+ if test $ac_cv_prog_gcc_traditional = yes; then
+ CC="$CC -traditional"
+ fi
+fi
+
+echo $ac_n "checking for pid_t""... $ac_c" 1>&6
+echo "configure:1875: checking for pid_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1880 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])pid_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_pid_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_pid_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_pid_t" 1>&6
+if test $ac_cv_type_pid_t = no; then
+ cat >> confdefs.h <<\EOF
+#define pid_t int
+EOF
+
+fi
+
+ac_safe=`echo "vfork.h" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for vfork.h""... $ac_c" 1>&6
+echo "configure:1909: checking for vfork.h" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1914 "configure"
+#include "confdefs.h"
+#include <vfork.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1919: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_VFORK_H 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking for working vfork""... $ac_c" 1>&6
+echo "configure:1944: checking for working vfork" >&5
+if eval "test \"`echo '$''{'ac_cv_func_vfork_works'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ echo $ac_n "checking for vfork""... $ac_c" 1>&6
+echo "configure:1950: checking for vfork" >&5
+if eval "test \"`echo '$''{'ac_cv_func_vfork'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1955 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char vfork(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char vfork();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_vfork) || defined (__stub___vfork)
+choke me
+#else
+vfork();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:1978: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_vfork=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_vfork=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'vfork`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ :
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ac_cv_func_vfork_works=$ac_cv_func_vfork
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2000 "configure"
+#include "confdefs.h"
+/* Thanks to Paul Eggert for this test. */
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_VFORK_H
+#include <vfork.h>
+#endif
+/* On some sparc systems, changes by the child to local and incoming
+ argument registers are propagated back to the parent.
+ The compiler is told about this with #include <vfork.h>,
+ but some compilers (e.g. gcc -O) don't grok <vfork.h>.
+ Test for this by using a static variable whose address
+ is put into a register that is clobbered by the vfork. */
+static
+#ifdef __cplusplus
+sparc_address_test (int arg)
+#else
+sparc_address_test (arg) int arg;
+#endif
+{
+ static pid_t child;
+ if (!child) {
+ child = vfork ();
+ if (child < 0) {
+ perror ("vfork");
+ _exit(2);
+ }
+ if (!child) {
+ arg = getpid();
+ write(-1, "", 0);
+ _exit (arg);
+ }
+ }
+}
+main() {
+ pid_t parent = getpid ();
+ pid_t child;
+
+ sparc_address_test ();
+
+ child = vfork ();
+
+ if (child == 0) {
+ /* Here is another test for sparc vfork register problems.
+ This test uses lots of local variables, at least
+ as many local variables as main has allocated so far
+ including compiler temporaries. 4 locals are enough for
+ gcc 1.40.3 on a Solaris 4.1.3 sparc, but we use 8 to be safe.
+ A buggy compiler should reuse the register of parent
+ for one of the local variables, since it will think that
+ parent can't possibly be used any more in this routine.
+ Assigning to the local variable will thus munge parent
+ in the parent process. */
+ pid_t
+ p = getpid(), p1 = getpid(), p2 = getpid(), p3 = getpid(),
+ p4 = getpid(), p5 = getpid(), p6 = getpid(), p7 = getpid();
+ /* Convince the compiler that p..p7 are live; otherwise, it might
+ use the same hardware register for all 8 local variables. */
+ if (p != p1 || p != p2 || p != p3 || p != p4
+ || p != p5 || p != p6 || p != p7)
+ _exit(1);
+
+ /* On some systems (e.g. IRIX 3.3),
+ vfork doesn't separate parent from child file descriptors.
+ If the child closes a descriptor before it execs or exits,
+ this munges the parent's descriptor as well.
+ Test for this by closing stdout in the child. */
+ _exit(close(fileno(stdout)) != 0);
+ } else {
+ int status;
+ struct stat st;
+
+ while (wait(&status) != child)
+ ;
+ exit(
+ /* Was there some problem with vforking? */
+ child < 0
+
+ /* Did the child fail? (This shouldn't happen.) */
+ || status
+
+ /* Did the vfork/compiler bug occur? */
+ || parent != getpid()
+
+ /* Did the file descriptor bug occur? */
+ || fstat(fileno(stdout), &st) != 0
+ );
+ }
+}
+EOF
+if { (eval echo configure:2095: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_func_vfork_works=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_func_vfork_works=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_func_vfork_works" 1>&6
+if test $ac_cv_func_vfork_works = no; then
+ cat >> confdefs.h <<\EOF
+#define vfork fork
+EOF
+
+fi
+
+for ac_func in select socket strdup strerror strtoul
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2120: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2125 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2148: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+echo $ac_n "checking whether build environment is sane""... $ac_c" 1>&6
+echo "configure:2174: checking whether build environment is sane" >&5
+# Just in case
+sleep 1
+echo timestamp > conftestfile
+# Do `set' in a subshell so we don't clobber the current shell's
+# arguments. Must try -L first in case configure is actually a
+# symlink; some systems play weird games with the mod time of symlinks
+# (eg FreeBSD returns the mod time of the symlink's containing
+# directory).
+if (
+ set X `ls -Lt $srcdir/configure conftestfile 2> /dev/null`
+ if test "$*" = "X"; then
+ # -L didn't work.
+ set X `ls -t $srcdir/configure conftestfile`
+ fi
+ if test "$*" != "X $srcdir/configure conftestfile" \
+ && test "$*" != "X conftestfile $srcdir/configure"; then
+
+ # If neither matched, then we have a broken ls. This can happen
+ # if, for instance, CONFIG_SHELL is bash and it inherits a
+ # broken ls alias from the environment. This has actually
+ # happened. Such a system could not be considered "sane".
+ { echo "configure: error: ls -t appears to fail. Make sure there is not a broken
+alias in your environment" 1>&2; exit 1; }
+ fi
+
+ test "$2" = conftestfile
+ )
+then
+ # Ok.
+ :
+else
+ { echo "configure: error: newly created file is older than distributed files!
+Check your system clock" 1>&2; exit 1; }
+fi
+rm -f conftest*
+echo "$ac_t""yes" 1>&6
+if test "$program_transform_name" = s,x,x,; then
+ program_transform_name=
+else
+ # Double any \ or $. echo might interpret backslashes.
+ cat <<\EOF_SED > conftestsed
+s,\\,\\\\,g; s,\$,$$,g
+EOF_SED
+ program_transform_name="`echo $program_transform_name|sed -f conftestsed`"
+ rm -f conftestsed
+fi
+test "$program_prefix" != NONE &&
+ program_transform_name="s,^,${program_prefix},; $program_transform_name"
+# Use a double $ so make ignores it.
+test "$program_suffix" != NONE &&
+ program_transform_name="s,\$\$,${program_suffix},; $program_transform_name"
+
+# sed with no file args requires a program.
+test "$program_transform_name" = "" && program_transform_name="s,x,x,"
+
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:2231: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftestmake <<\EOF
+all:
+ @echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+ eval ac_cv_prog_make_${ac_make}_set=yes
+else
+ eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ SET_MAKE=
+else
+ echo "$ac_t""no" 1>&6
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+
+PACKAGE=OpenGGSN
+
+VERSION=0.5
+
+if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
+ { echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; }
+fi
+cat >> confdefs.h <<EOF
+#define PACKAGE "$PACKAGE"
+EOF
+
+cat >> confdefs.h <<EOF
+#define VERSION "$VERSION"
+EOF
+
+
+
+missing_dir=`cd $ac_aux_dir && pwd`
+echo $ac_n "checking for working aclocal""... $ac_c" 1>&6
+echo "configure:2277: checking for working aclocal" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (aclocal --version) < /dev/null > /dev/null 2>&1; then
+ ACLOCAL=aclocal
+ echo "$ac_t""found" 1>&6
+else
+ ACLOCAL="$missing_dir/missing aclocal"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoconf""... $ac_c" 1>&6
+echo "configure:2290: checking for working autoconf" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (autoconf --version) < /dev/null > /dev/null 2>&1; then
+ AUTOCONF=autoconf
+ echo "$ac_t""found" 1>&6
+else
+ AUTOCONF="$missing_dir/missing autoconf"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working automake""... $ac_c" 1>&6
+echo "configure:2303: checking for working automake" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (automake --version) < /dev/null > /dev/null 2>&1; then
+ AUTOMAKE=automake
+ echo "$ac_t""found" 1>&6
+else
+ AUTOMAKE="$missing_dir/missing automake"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working autoheader""... $ac_c" 1>&6
+echo "configure:2316: checking for working autoheader" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (autoheader --version) < /dev/null > /dev/null 2>&1; then
+ AUTOHEADER=autoheader
+ echo "$ac_t""found" 1>&6
+else
+ AUTOHEADER="$missing_dir/missing autoheader"
+ echo "$ac_t""missing" 1>&6
+fi
+
+echo $ac_n "checking for working makeinfo""... $ac_c" 1>&6
+echo "configure:2329: checking for working makeinfo" >&5
+# Run test in a subshell; some versions of sh will print an error if
+# an executable is not found, even if stderr is redirected.
+# Redirect stdin to placate older versions of autoconf. Sigh.
+if (makeinfo --version) < /dev/null > /dev/null 2>&1; then
+ MAKEINFO=makeinfo
+ echo "$ac_t""found" 1>&6
+else
+ MAKEINFO="$missing_dir/missing makeinfo"
+ echo "$ac_t""missing" 1>&6
+fi
+
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+# Transform confdefs.h into DEFS.
+# Protect against shell expansion while executing Makefile rules.
+# Protect against Makefile macro expansion.
+cat > conftest.defs <<\EOF
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%-D\1=\2%g
+s%[ `~#$^&*(){}\\|;'"<>?]%\\&%g
+s%\[%\\&%g
+s%\]%\\&%g
+s%\$%$$%g
+EOF
+DEFS=`sed -f conftest.defs confdefs.h | tr '\012' ' '`
+rm -f conftest.defs
+
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+ac_given_INSTALL="$INSTALL"
+
+trap 'rm -fr `echo "doc/Makefile po/Makefile intl/Makefile Makefile tests/Makefile src/Makefile gtp/Makefile ggsn/Makefile sgsnemu/Makefile" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@AWK@%$AWK%g
+s%@CC@%$CC%g
+s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g
+s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g
+s%@INSTALL_DATA@%$INSTALL_DATA%g
+s%@LN_S@%$LN_S%g
+s%@host@%$host%g
+s%@host_alias@%$host_alias%g
+s%@host_cpu@%$host_cpu%g
+s%@host_vendor@%$host_vendor%g
+s%@host_os@%$host_os%g
+s%@build@%$build%g
+s%@build_alias@%$build_alias%g
+s%@build_cpu@%$build_cpu%g
+s%@build_vendor@%$build_vendor%g
+s%@build_os@%$build_os%g
+s%@RANLIB@%$RANLIB%g
+s%@LIBTOOL@%$LIBTOOL%g
+s%@CPP@%$CPP%g
+s%@PACKAGE@%$PACKAGE%g
+s%@VERSION@%$VERSION%g
+s%@ACLOCAL@%$ACLOCAL%g
+s%@AUTOCONF@%$AUTOCONF%g
+s%@AUTOMAKE@%$AUTOMAKE%g
+s%@AUTOHEADER@%$AUTOHEADER%g
+s%@MAKEINFO@%$MAKEINFO%g
+s%@SET_MAKE@%$SET_MAKE%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"doc/Makefile po/Makefile intl/Makefile Makefile tests/Makefile src/Makefile gtp/Makefile ggsn/Makefile sgsnemu/Makefile"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+ case "$ac_given_INSTALL" in
+ [/$]*) INSTALL="$ac_given_INSTALL" ;;
+ *) INSTALL="$ac_dots$ac_given_INSTALL" ;;
+ esac
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+s%@INSTALL@%$INSTALL%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/configure.in b/configure.in
new file mode 100644
index 0000000..61a41ab
--- /dev/null
+++ b/configure.in
@@ -0,0 +1,32 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_INIT(gtp/gtp.c ggsn/ggsn.c sgsnemu/sgsnemu.c)
+
+dnl Checks for programs.
+AC_PROG_AWK
+AC_PROG_CC
+AC_PROG_INSTALL
+AC_PROG_LN_S
+
+AC_PROG_LIBTOOL
+AM_PROG_LIBTOOL
+
+dnl Checks for libraries.
+
+dnl Checks for header files.
+AC_HEADER_STDC
+AC_HEADER_SYS_WAIT
+AC_CHECK_HEADERS(fcntl.h strings.h sys/ioctl.h sys/time.h syslog.h unistd.h)
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_TYPE_SIZE_T
+AC_HEADER_TIME
+
+dnl Checks for library functions.
+AC_PROG_GCC_TRADITIONAL
+AC_FUNC_VFORK
+AC_CHECK_FUNCS(select socket strdup strerror strtoul)
+
+AM_INIT_AUTOMAKE(OpenGGSN,0.5)
+
+AC_OUTPUT(doc/Makefile po/Makefile intl/Makefile Makefile tests/Makefile src/Makefile gtp/Makefile ggsn/Makefile sgsnemu/Makefile)
diff --git a/configure.scan b/configure.scan
new file mode 100644
index 0000000..fce2c5d
--- /dev/null
+++ b/configure.scan
@@ -0,0 +1,27 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_INIT(src/cmdline.c)
+
+dnl Checks for programs.
+AC_PROG_AWK
+AC_PROG_CC
+AC_PROG_INSTALL
+AC_PROG_LN_S
+
+dnl Checks for libraries.
+
+dnl Checks for header files.
+AC_HEADER_STDC
+AC_HEADER_SYS_WAIT
+AC_CHECK_HEADERS(fcntl.h strings.h sys/ioctl.h sys/time.h syslog.h unistd.h)
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_TYPE_SIZE_T
+AC_HEADER_TIME
+
+dnl Checks for library functions.
+AC_PROG_GCC_TRADITIONAL
+AC_FUNC_VFORK
+AC_CHECK_FUNCS(select socket strdup strerror strtoul)
+
+AC_OUTPUT(doc/Makefile po/Makefile intl/Makefile Makefile tests/Makefile src/Makefile)
diff --git a/doc/Makefile b/doc/Makefile
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/doc/Makefile
diff --git a/examples/ggsn.conf b/examples/ggsn.conf
new file mode 100644
index 0000000..ad2dcd6
--- /dev/null
+++ b/examples/ggsn.conf
@@ -0,0 +1,69 @@
+##############################################################################
+#
+# Sample ggsn configuration file
+#
+##############################################################################
+
+# TAG: fg
+# Include this flag if process is to run in the foreground
+#
+fg
+
+# TAG: debug
+# Include this flag to include debug information.
+#debug
+
+
+# TAG: conf
+# Configuration file to use. This file is the configuration file,
+# so changing this parameter in the configuration file does not make
+# sense. Use it on the command line instead.
+
+# TAG: pidfile
+# File to store information about the process id of the program.
+# The program must have write access to this file/directory.
+#pidfile /var/run/ggsn.pid
+
+# TAG: statedir
+# Directory to use for nonvolatile storage.
+# The program must have write access to this directory.
+#pidfile /var/lib/ggsn/
+
+
+# TAG: listen
+# Specifies the local IP address to listen to
+listen 10.0.0.240
+
+# TAG: net
+# IP network address of external packet data network
+# Used to allocate dynamic IP addresses and set up routing.
+#net 192.168.0.0
+
+# TAG: mask
+# IP network mask of external packet data network
+# Used to allocate dynamic IP addresses and set up routing.
+#mask 255.255.255.0
+
+
+# TAG: timelimit
+# Exit after timelimit seconds.
+# Setting timelimit to zero will cause the program not to exit.
+#timelimit 0
+
+
+# TAG: qos
+# Use of this tag is EXPERIMENTAL
+# Requested Quality of Service used when run in client mode.
+# 3 bytes corresponding to ????
+#qos 0x0b921f
+
+# TAG: apn
+# Use of this tag is EXPERIMENTAL
+# Access point name to connect to when run in client mode.
+#apn internet
+
+
+
+
+
+
diff --git a/examples/sgsnemu.conf b/examples/sgsnemu.conf
new file mode 100644
index 0000000..c378da1
--- /dev/null
+++ b/examples/sgsnemu.conf
@@ -0,0 +1,102 @@
+##############################################################################
+#
+# Sample sgsnemu configuration file
+#
+##############################################################################
+
+# TAG: fg
+# Include this flag if process is to run in the foreground
+#
+fg
+
+# TAG: debug
+# Include this flag to include debug information.
+#debug
+
+
+# TAG: conf
+# Configuration file to use. This file is the configuration file,
+# so changing this parameter in the configuration file does not make
+# sense. Use it on the command line instead.
+
+# TAG: pidfile
+# File to store information about the pricess id of the program.
+# The program must have write access to this file/directory.
+#pidfile ./sgsnemu.pid
+
+# TAG: statedir
+# Directory to use for nonvolatile storage.
+# The program must have write access to this directory.
+#pidfile ./sgsnemu.pid
+
+
+# TAG: dns
+# DNS server to use for ns lookups.
+# If this tag is not set the system default DNS will be used.
+#pidfile ./sgsnemu.pid
+
+# TAG: listen
+# Specifies the local IP address to listen to
+listen 10.0.0.220
+
+# TAG: remote
+# Specifies the remote IP address to connect to
+# If DNS is setup correctly it should be possible to specify the
+# access point name (APN) as the remote address.
+remote 10.0.0.240
+
+# TAG: net
+# IP network address of external packet data network
+# This tag is used for setting up routing at the emulator
+#net 192.168.0.0
+
+# TAG: mask
+# IP network mask of external packet data network
+# This tag is used for setting up routing at the emulator
+#mask 255.255.255.0
+
+
+# TAG: contexts
+# Use of this tag is EXPERIMENTAL
+# Number of contexts to establish from the emulator to the ggsn.
+# Set this tag to zero to not establish any contexts.
+#contexts 1
+
+# TAG: static
+# Use of this tag is EXPERIMENTAL
+# Use this flag if you do not want to set dynamic tun interfaces.
+# If this flag is set a single network interface is established.
+#contexts 1
+
+# TAG: timelimit
+# Disconnect contexts after timelimit seconds, and exit the program.
+# Setting timelimit to zero will cause the program not to disconnect.
+#timelimit 0
+
+
+# TAG: apn
+# Access point name to connect to when run in client mode.
+#apn internet
+
+# TAG: imsi
+# IMSI number used when run in client mode.
+#imsi 2400101234567890
+
+# TAG: msisdn
+# MSISDN number used when run in client mode.
+#msisdn 46702123456
+
+# TAG: qos
+# Requested Quality of Service used when run in client mode.
+# 3 bytes corresponding to ????
+#qos 0x0b921f
+
+# TAG: uid
+# User ID used when run in client mode.
+#uid mig
+
+# TAG: pwd
+# Password used when run in client mode.
+#pwd hemlig
+
+
diff --git a/ggsn/.deps/cmdline.P b/ggsn/.deps/cmdline.P
new file mode 100644
index 0000000..f8c0fb9
--- /dev/null
+++ b/ggsn/.deps/cmdline.P
@@ -0,0 +1,33 @@
+cmdline.o: cmdline.c /usr/include/stdio.h /usr/include/features.h \
+ /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h \
+ /usr/include/bits/types.h /usr/include/libio.h /usr/include/_G_config.h \
+ /usr/include/wchar.h /usr/include/bits/wchar.h /usr/include/gconv.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h \
+ /usr/include/bits/stdio_lim.h /usr/include/bits/stdio.h \
+ /usr/include/stdlib.h /usr/include/string.h /usr/include/bits/string.h \
+ /usr/include/bits/string2.h /usr/include/endian.h \
+ /usr/include/bits/endian.h /usr/include/getopt.h cmdline.h
+cmdline.c :
+/usr/include/stdio.h :
+/usr/include/features.h :
+/usr/include/sys/cdefs.h :
+/usr/include/gnu/stubs.h :
+/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h :
+/usr/include/bits/types.h :
+/usr/include/libio.h :
+/usr/include/_G_config.h :
+/usr/include/wchar.h :
+/usr/include/bits/wchar.h :
+/usr/include/gconv.h :
+/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h :
+/usr/include/bits/stdio_lim.h :
+/usr/include/bits/stdio.h :
+/usr/include/stdlib.h :
+/usr/include/string.h :
+/usr/include/bits/string.h :
+/usr/include/bits/string2.h :
+/usr/include/endian.h :
+/usr/include/bits/endian.h :
+/usr/include/getopt.h :
+cmdline.h :
diff --git a/ggsn/.deps/ggsn.P b/ggsn/.deps/ggsn.P
new file mode 100644
index 0000000..3d4612e
--- /dev/null
+++ b/ggsn/.deps/ggsn.P
@@ -0,0 +1,146 @@
+ggsn.o: ggsn.c /usr/include/syslog.h /usr/include/sys/syslog.h \
+ /usr/include/features.h /usr/include/sys/cdefs.h \
+ /usr/include/gnu/stubs.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h \
+ /usr/include/ctype.h /usr/include/bits/types.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h \
+ /usr/include/bits/pthreadtypes.h /usr/include/bits/sched.h \
+ /usr/include/endian.h /usr/include/bits/endian.h /usr/include/xlocale.h \
+ /usr/include/netdb.h /usr/include/netinet/in.h /usr/include/stdint.h \
+ /usr/include/bits/wchar.h /usr/include/bits/wordsize.h \
+ /usr/include/bits/socket.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/limits.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/syslimits.h \
+ /usr/include/limits.h /usr/include/bits/posix1_lim.h \
+ /usr/include/bits/local_lim.h /usr/include/linux/limits.h \
+ /usr/include/bits/posix2_lim.h /usr/include/bits/xopen_lim.h \
+ /usr/include/bits/stdio_lim.h /usr/include/sys/types.h \
+ /usr/include/time.h /usr/include/sys/select.h \
+ /usr/include/bits/select.h /usr/include/bits/sigset.h \
+ /usr/include/bits/time.h /usr/include/sys/sysmacros.h \
+ /usr/include/bits/sockaddr.h /usr/include/asm/socket.h \
+ /usr/include/asm/sockios.h /usr/include/bits/in.h \
+ /usr/include/bits/byteswap.h /usr/include/rpc/netdb.h \
+ /usr/include/bits/siginfo.h /usr/include/bits/netdb.h \
+ /usr/include/signal.h /usr/include/bits/signum.h \
+ /usr/include/bits/sigaction.h /usr/include/bits/sigcontext.h \
+ /usr/include/asm/sigcontext.h /usr/include/bits/sigstack.h \
+ /usr/include/ucontext.h /usr/include/sys/ucontext.h \
+ /usr/include/bits/sigthread.h /usr/include/stdio.h /usr/include/libio.h \
+ /usr/include/_G_config.h /usr/include/wchar.h /usr/include/gconv.h \
+ /usr/include/bits/stdio.h /usr/include/string.h \
+ /usr/include/bits/string.h /usr/include/bits/string2.h \
+ /usr/include/stdlib.h /usr/include/bits/waitflags.h \
+ /usr/include/bits/waitstatus.h /usr/include/alloca.h \
+ /usr/include/sys/socket.h /usr/include/sys/uio.h \
+ /usr/include/bits/uio.h /usr/include/arpa/inet.h \
+ /usr/include/sys/wait.h /usr/include/sys/resource.h \
+ /usr/include/bits/resource.h /usr/include/sys/stat.h \
+ /usr/include/bits/stat.h /usr/include/unistd.h \
+ /usr/include/bits/posix_opt.h /usr/include/bits/environments.h \
+ /usr/include/bits/confname.h /usr/include/getopt.h \
+ /usr/include/sys/ioctl.h /usr/include/bits/ioctls.h \
+ /usr/include/asm/ioctls.h /usr/include/asm/ioctl.h \
+ /usr/include/bits/ioctl-types.h /usr/include/sys/ttydefaults.h \
+ /usr/include/net/if.h /usr/include/errno.h /usr/include/bits/errno.h \
+ /usr/include/linux/errno.h /usr/include/asm/errno.h \
+ /usr/include/asm/types.h /usr/include/linux/netlink.h tun.h \
+ ../gtp/pdp.h ../gtp/gtp.h cmdline.h
+ggsn.c :
+/usr/include/syslog.h :
+/usr/include/sys/syslog.h :
+/usr/include/features.h :
+/usr/include/sys/cdefs.h :
+/usr/include/gnu/stubs.h :
+/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h :
+/usr/include/ctype.h :
+/usr/include/bits/types.h :
+/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h :
+/usr/include/bits/pthreadtypes.h :
+/usr/include/bits/sched.h :
+/usr/include/endian.h :
+/usr/include/bits/endian.h :
+/usr/include/xlocale.h :
+/usr/include/netdb.h :
+/usr/include/netinet/in.h :
+/usr/include/stdint.h :
+/usr/include/bits/wchar.h :
+/usr/include/bits/wordsize.h :
+/usr/include/bits/socket.h :
+/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/limits.h :
+/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/syslimits.h :
+/usr/include/limits.h :
+/usr/include/bits/posix1_lim.h :
+/usr/include/bits/local_lim.h :
+/usr/include/linux/limits.h :
+/usr/include/bits/posix2_lim.h :
+/usr/include/bits/xopen_lim.h :
+/usr/include/bits/stdio_lim.h :
+/usr/include/sys/types.h :
+/usr/include/time.h :
+/usr/include/sys/select.h :
+/usr/include/bits/select.h :
+/usr/include/bits/sigset.h :
+/usr/include/bits/time.h :
+/usr/include/sys/sysmacros.h :
+/usr/include/bits/sockaddr.h :
+/usr/include/asm/socket.h :
+/usr/include/asm/sockios.h :
+/usr/include/bits/in.h :
+/usr/include/bits/byteswap.h :
+/usr/include/rpc/netdb.h :
+/usr/include/bits/siginfo.h :
+/usr/include/bits/netdb.h :
+/usr/include/signal.h :
+/usr/include/bits/signum.h :
+/usr/include/bits/sigaction.h :
+/usr/include/bits/sigcontext.h :
+/usr/include/asm/sigcontext.h :
+/usr/include/bits/sigstack.h :
+/usr/include/ucontext.h :
+/usr/include/sys/ucontext.h :
+/usr/include/bits/sigthread.h :
+/usr/include/stdio.h :
+/usr/include/libio.h :
+/usr/include/_G_config.h :
+/usr/include/wchar.h :
+/usr/include/gconv.h :
+/usr/include/bits/stdio.h :
+/usr/include/string.h :
+/usr/include/bits/string.h :
+/usr/include/bits/string2.h :
+/usr/include/stdlib.h :
+/usr/include/bits/waitflags.h :
+/usr/include/bits/waitstatus.h :
+/usr/include/alloca.h :
+/usr/include/sys/socket.h :
+/usr/include/sys/uio.h :
+/usr/include/bits/uio.h :
+/usr/include/arpa/inet.h :
+/usr/include/sys/wait.h :
+/usr/include/sys/resource.h :
+/usr/include/bits/resource.h :
+/usr/include/sys/stat.h :
+/usr/include/bits/stat.h :
+/usr/include/unistd.h :
+/usr/include/bits/posix_opt.h :
+/usr/include/bits/environments.h :
+/usr/include/bits/confname.h :
+/usr/include/getopt.h :
+/usr/include/sys/ioctl.h :
+/usr/include/bits/ioctls.h :
+/usr/include/asm/ioctls.h :
+/usr/include/asm/ioctl.h :
+/usr/include/bits/ioctl-types.h :
+/usr/include/sys/ttydefaults.h :
+/usr/include/net/if.h :
+/usr/include/errno.h :
+/usr/include/bits/errno.h :
+/usr/include/linux/errno.h :
+/usr/include/asm/errno.h :
+/usr/include/asm/types.h :
+/usr/include/linux/netlink.h :
+tun.h :
+../gtp/pdp.h :
+../gtp/gtp.h :
+cmdline.h :
diff --git a/ggsn/.deps/ggsnopt.P b/ggsn/.deps/ggsnopt.P
new file mode 100644
index 0000000..f96b6f3
--- /dev/null
+++ b/ggsn/.deps/ggsnopt.P
@@ -0,0 +1,33 @@
+ggsnopt.o: ggsnopt.c /usr/include/stdio.h /usr/include/features.h \
+ /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h \
+ /usr/include/bits/types.h /usr/include/libio.h /usr/include/_G_config.h \
+ /usr/include/wchar.h /usr/include/bits/wchar.h /usr/include/gconv.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h \
+ /usr/include/bits/stdio_lim.h /usr/include/bits/stdio.h \
+ /usr/include/stdlib.h /usr/include/string.h /usr/include/bits/string.h \
+ /usr/include/bits/string2.h /usr/include/endian.h \
+ /usr/include/bits/endian.h /usr/include/getopt.h ggsnopt.h
+ggsnopt.c :
+/usr/include/stdio.h :
+/usr/include/features.h :
+/usr/include/sys/cdefs.h :
+/usr/include/gnu/stubs.h :
+/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h :
+/usr/include/bits/types.h :
+/usr/include/libio.h :
+/usr/include/_G_config.h :
+/usr/include/wchar.h :
+/usr/include/bits/wchar.h :
+/usr/include/gconv.h :
+/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h :
+/usr/include/bits/stdio_lim.h :
+/usr/include/bits/stdio.h :
+/usr/include/stdlib.h :
+/usr/include/string.h :
+/usr/include/bits/string.h :
+/usr/include/bits/string2.h :
+/usr/include/endian.h :
+/usr/include/bits/endian.h :
+/usr/include/getopt.h :
+ggsnopt.h :
diff --git a/ggsn/.deps/tun.P b/ggsn/.deps/tun.P
new file mode 100644
index 0000000..29f9cf4
--- /dev/null
+++ b/ggsn/.deps/tun.P
@@ -0,0 +1,108 @@
+tun.o: tun.c /usr/include/syslog.h /usr/include/sys/syslog.h \
+ /usr/include/features.h /usr/include/sys/cdefs.h \
+ /usr/include/gnu/stubs.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h \
+ /usr/include/stdio.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h \
+ /usr/include/bits/types.h /usr/include/libio.h /usr/include/_G_config.h \
+ /usr/include/wchar.h /usr/include/bits/wchar.h /usr/include/gconv.h \
+ /usr/include/bits/stdio_lim.h /usr/include/bits/stdio.h \
+ /usr/include/stdlib.h /usr/include/sys/types.h /usr/include/time.h \
+ /usr/include/sys/socket.h /usr/include/sys/uio.h \
+ /usr/include/bits/uio.h /usr/include/bits/socket.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/limits.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/syslimits.h \
+ /usr/include/limits.h /usr/include/bits/sockaddr.h \
+ /usr/include/asm/socket.h /usr/include/asm/sockios.h \
+ /usr/include/netinet/in.h /usr/include/stdint.h \
+ /usr/include/bits/wordsize.h /usr/include/bits/in.h \
+ /usr/include/endian.h /usr/include/bits/endian.h \
+ /usr/include/bits/byteswap.h /usr/include/arpa/inet.h \
+ /usr/include/sys/stat.h /usr/include/bits/stat.h \
+ /usr/include/sys/time.h /usr/include/bits/time.h \
+ /usr/include/sys/select.h /usr/include/bits/select.h \
+ /usr/include/bits/sigset.h /usr/include/unistd.h \
+ /usr/include/bits/posix_opt.h /usr/include/bits/confname.h \
+ /usr/include/string.h /usr/include/bits/string.h \
+ /usr/include/bits/string2.h /usr/include/errno.h \
+ /usr/include/bits/errno.h /usr/include/linux/errno.h \
+ /usr/include/asm/errno.h /usr/include/fcntl.h /usr/include/bits/fcntl.h \
+ /usr/include/sys/ioctl.h /usr/include/bits/ioctls.h \
+ /usr/include/asm/ioctls.h /usr/include/asm/ioctl.h \
+ /usr/include/bits/ioctl-types.h /usr/include/sys/ttydefaults.h \
+ /usr/include/linux/if.h /usr/include/linux/types.h \
+ /usr/include/linux/posix_types.h /usr/include/linux/stddef.h \
+ /usr/include/asm/posix_types.h /usr/include/asm/types.h \
+ /usr/include/linux/socket.h /usr/include/linux/if_tun.h tun.h
+tun.c :
+/usr/include/syslog.h :
+/usr/include/sys/syslog.h :
+/usr/include/features.h :
+/usr/include/sys/cdefs.h :
+/usr/include/gnu/stubs.h :
+/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h :
+/usr/include/stdio.h :
+/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h :
+/usr/include/bits/types.h :
+/usr/include/libio.h :
+/usr/include/_G_config.h :
+/usr/include/wchar.h :
+/usr/include/bits/wchar.h :
+/usr/include/gconv.h :
+/usr/include/bits/stdio_lim.h :
+/usr/include/bits/stdio.h :
+/usr/include/stdlib.h :
+/usr/include/sys/types.h :
+/usr/include/time.h :
+/usr/include/sys/socket.h :
+/usr/include/sys/uio.h :
+/usr/include/bits/uio.h :
+/usr/include/bits/socket.h :
+/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/limits.h :
+/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/syslimits.h :
+/usr/include/limits.h :
+/usr/include/bits/sockaddr.h :
+/usr/include/asm/socket.h :
+/usr/include/asm/sockios.h :
+/usr/include/netinet/in.h :
+/usr/include/stdint.h :
+/usr/include/bits/wordsize.h :
+/usr/include/bits/in.h :
+/usr/include/endian.h :
+/usr/include/bits/endian.h :
+/usr/include/bits/byteswap.h :
+/usr/include/arpa/inet.h :
+/usr/include/sys/stat.h :
+/usr/include/bits/stat.h :
+/usr/include/sys/time.h :
+/usr/include/bits/time.h :
+/usr/include/sys/select.h :
+/usr/include/bits/select.h :
+/usr/include/bits/sigset.h :
+/usr/include/unistd.h :
+/usr/include/bits/posix_opt.h :
+/usr/include/bits/confname.h :
+/usr/include/string.h :
+/usr/include/bits/string.h :
+/usr/include/bits/string2.h :
+/usr/include/errno.h :
+/usr/include/bits/errno.h :
+/usr/include/linux/errno.h :
+/usr/include/asm/errno.h :
+/usr/include/fcntl.h :
+/usr/include/bits/fcntl.h :
+/usr/include/sys/ioctl.h :
+/usr/include/bits/ioctls.h :
+/usr/include/asm/ioctls.h :
+/usr/include/asm/ioctl.h :
+/usr/include/bits/ioctl-types.h :
+/usr/include/sys/ttydefaults.h :
+/usr/include/linux/if.h :
+/usr/include/linux/types.h :
+/usr/include/linux/posix_types.h :
+/usr/include/linux/stddef.h :
+/usr/include/asm/posix_types.h :
+/usr/include/asm/types.h :
+/usr/include/linux/socket.h :
+/usr/include/linux/if_tun.h :
+tun.h :
diff --git a/ggsn/Makefile b/ggsn/Makefile
new file mode 100644
index 0000000..1403f43
--- /dev/null
+++ b/ggsn/Makefile
@@ -0,0 +1,343 @@
+# Generated automatically from Makefile.in by configure.
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = /bin/sh
+
+srcdir = .
+top_srcdir = ..
+prefix = /usr/local
+exec_prefix = ${prefix}
+
+bindir = ${exec_prefix}/bin
+sbindir = ${exec_prefix}/sbin
+libexecdir = ${exec_prefix}/libexec
+datadir = ${prefix}/share
+sysconfdir = ${prefix}/etc
+sharedstatedir = ${prefix}/com
+localstatedir = ${prefix}/var
+libdir = ${exec_prefix}/lib
+infodir = ${prefix}/info
+mandir = ${prefix}/man
+includedir = ${prefix}/include
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/OpenGGSN
+pkglibdir = $(libdir)/OpenGGSN
+pkgincludedir = $(includedir)/OpenGGSN
+
+top_builddir = ..
+
+ACLOCAL = aclocal
+AUTOCONF = autoconf
+AUTOMAKE = automake
+AUTOHEADER = autoheader
+
+INSTALL = /usr/bin/install -c
+INSTALL_PROGRAM = ${INSTALL} $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = ${INSTALL} -m 644
+INSTALL_SCRIPT = ${INSTALL_PROGRAM}
+transform = s,x,x,
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = i686-pc-linux
+host_triplet = i686-pc-linux-gnu
+AS = @AS@
+AWK = gawk
+CC = gcc
+DLLTOOL = @DLLTOOL@
+LIBTOOL = $(SHELL) $(top_builddir)/libtool
+LN_S = ln -s
+MAKEINFO = makeinfo
+OBJDUMP = @OBJDUMP@
+PACKAGE = OpenGGSN
+RANLIB = ranlib
+VERSION = 0.5
+
+bin_PROGRAMS = ggsn
+
+CFLAGS = -O2 -fno-builtin -Wall -ansi -DSBINDIR='"$(sbindir)"' -lgtp
+
+ggsn_SOURCES = ggsn.c tun.c tun.h cmdline.c cmdline.h
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_CLEAN_FILES =
+PROGRAMS = $(bin_PROGRAMS)
+
+
+DEFS = -DSTDC_HEADERS=1 -DHAVE_SYS_WAIT_H=1 -DHAVE_FCNTL_H=1 -DHAVE_STRINGS_H=1 -DHAVE_SYS_IOCTL_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYSLOG_H=1 -DHAVE_UNISTD_H=1 -DTIME_WITH_SYS_TIME=1 -DHAVE_SELECT=1 -DHAVE_SOCKET=1 -DHAVE_STRDUP=1 -DHAVE_STRERROR=1 -DHAVE_STRTOUL=1 -DPACKAGE=\"OpenGGSN\" -DVERSION=\"0.5\" -I. -I$(srcdir)
+CPPFLAGS =
+LDFLAGS =
+LIBS =
+ggsn_OBJECTS = ggsn.o tun.o cmdline.o
+ggsn_LDADD = $(LDADD)
+ggsn_DEPENDENCIES =
+ggsn_LDFLAGS =
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON = Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = gtar
+GZIP_ENV = --best
+DEP_FILES = .deps/cmdline.P .deps/ggsn.P .deps/tun.P
+SOURCES = $(ggsn_SOURCES)
+OBJECTS = $(ggsn_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .lo .o .s
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --gnu ggsn/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-binPROGRAMS:
+
+clean-binPROGRAMS:
+ -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+
+distclean-binPROGRAMS:
+
+maintainer-clean-binPROGRAMS:
+
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ list='$(bin_PROGRAMS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ done
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+ggsn: $(ggsn_OBJECTS) $(ggsn_DEPENDENCIES)
+ @rm -f ggsn
+ $(LINK) $(ggsn_LDFLAGS) $(ggsn_OBJECTS) $(ggsn_LDADD) $(LIBS)
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = ggsn
+
+distdir: $(DISTFILES)
+ here=`cd $(top_builddir) && pwd`; \
+ top_distdir=`cd $(top_distdir) && pwd`; \
+ distdir=`cd $(distdir) && pwd`; \
+ cd $(top_srcdir) \
+ && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu ggsn/Makefile
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$d/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+ -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+ @echo '$(COMPILE) -c $<'; \
+ $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.c
+ @echo '$(LTCOMPILE) -c $<'; \
+ $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am: install-binPROGRAMS
+install-exec: install-exec-am
+
+install-data-am:
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-binPROGRAMS
+uninstall: uninstall-am
+all-am: Makefile $(PROGRAMS)
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-binPROGRAMS mostlyclean-compile \
+ mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
+ mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-binPROGRAMS clean-compile clean-libtool clean-tags \
+ clean-depend clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-binPROGRAMS distclean-compile distclean-libtool \
+ distclean-tags distclean-depend distclean-generic \
+ clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-binPROGRAMS \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-tags maintainer-clean-depend \
+ maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \
+maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile mostlyclean-libtool distclean-libtool \
+clean-libtool maintainer-clean-libtool tags mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir \
+mostlyclean-depend distclean-depend clean-depend \
+maintainer-clean-depend info-am info dvi-am dvi check check-am \
+installcheck-am installcheck install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+cmdline.c: cmdline.ggo
+ gengetopt < cmdline.ggo --unamed-opts
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/ggsn/Makefile.am b/ggsn/Makefile.am
new file mode 100644
index 0000000..05211a6
--- /dev/null
+++ b/ggsn/Makefile.am
@@ -0,0 +1,11 @@
+bin_PROGRAMS = ggsn
+
+CFLAGS = -O2 -fno-builtin -Wall -ansi -DSBINDIR='"$(sbindir)"' -lgtp
+
+ggsn_SOURCES = ggsn.c tun.c tun.h cmdline.c cmdline.h
+
+cmdline.c: cmdline.ggo
+ gengetopt < cmdline.ggo --unamed-opts
+
+
+
diff --git a/ggsn/Makefile.in b/ggsn/Makefile.in
new file mode 100644
index 0000000..6fc4bcd
--- /dev/null
+++ b/ggsn/Makefile.in
@@ -0,0 +1,343 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AS = @AS@
+AWK = @AWK@
+CC = @CC@
+DLLTOOL = @DLLTOOL@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+MAKEINFO = @MAKEINFO@
+OBJDUMP = @OBJDUMP@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+
+bin_PROGRAMS = ggsn
+
+CFLAGS = -O2 -fno-builtin -Wall -ansi -DSBINDIR='"$(sbindir)"' -lgtp
+
+ggsn_SOURCES = ggsn.c tun.c tun.h cmdline.c cmdline.h
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_CLEAN_FILES =
+PROGRAMS = $(bin_PROGRAMS)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir)
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+ggsn_OBJECTS = ggsn.o tun.o cmdline.o
+ggsn_LDADD = $(LDADD)
+ggsn_DEPENDENCIES =
+ggsn_LDFLAGS =
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON = Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = gtar
+GZIP_ENV = --best
+DEP_FILES = .deps/cmdline.P .deps/ggsn.P .deps/tun.P
+SOURCES = $(ggsn_SOURCES)
+OBJECTS = $(ggsn_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .lo .o .s
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --gnu ggsn/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-binPROGRAMS:
+
+clean-binPROGRAMS:
+ -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+
+distclean-binPROGRAMS:
+
+maintainer-clean-binPROGRAMS:
+
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ list='$(bin_PROGRAMS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ done
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+ggsn: $(ggsn_OBJECTS) $(ggsn_DEPENDENCIES)
+ @rm -f ggsn
+ $(LINK) $(ggsn_LDFLAGS) $(ggsn_OBJECTS) $(ggsn_LDADD) $(LIBS)
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = ggsn
+
+distdir: $(DISTFILES)
+ here=`cd $(top_builddir) && pwd`; \
+ top_distdir=`cd $(top_distdir) && pwd`; \
+ distdir=`cd $(distdir) && pwd`; \
+ cd $(top_srcdir) \
+ && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu ggsn/Makefile
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$d/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+ -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+ @echo '$(COMPILE) -c $<'; \
+ $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.c
+ @echo '$(LTCOMPILE) -c $<'; \
+ $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am: install-binPROGRAMS
+install-exec: install-exec-am
+
+install-data-am:
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-binPROGRAMS
+uninstall: uninstall-am
+all-am: Makefile $(PROGRAMS)
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-binPROGRAMS mostlyclean-compile \
+ mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
+ mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-binPROGRAMS clean-compile clean-libtool clean-tags \
+ clean-depend clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-binPROGRAMS distclean-compile distclean-libtool \
+ distclean-tags distclean-depend distclean-generic \
+ clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-binPROGRAMS \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-tags maintainer-clean-depend \
+ maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \
+maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile mostlyclean-libtool distclean-libtool \
+clean-libtool maintainer-clean-libtool tags mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir \
+mostlyclean-depend distclean-depend clean-depend \
+maintainer-clean-depend info-am info dvi-am dvi check check-am \
+installcheck-am installcheck install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+cmdline.c: cmdline.ggo
+ gengetopt < cmdline.ggo --unamed-opts
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/ggsn/cmdline.c b/ggsn/cmdline.c
new file mode 100644
index 0000000..2d07644
--- /dev/null
+++ b/ggsn/cmdline.c
@@ -0,0 +1,529 @@
+/*
+ File autogenerated by gengetopt version 2.8rc
+ generated with the following command:
+ ../../gengetopt-2.8rc/src/gengetopt --conf-parser
+
+ The developers of gengetopt consider the fixed text that goes in all
+ gengetopt output files to be in the public domain:
+ we make no copyright claims on it.
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+/* If we use autoconf. */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+/* Check for configure's getopt check result. */
+#ifndef HAVE_GETOPT_LONG
+#include "getopt.h"
+#else
+#include <getopt.h>
+#endif
+
+#ifndef HAVE_STRDUP
+#define strdup gengetopt_strdup
+#endif /* HAVE_STRDUP */
+
+#include "cmdline.h"
+
+
+void
+cmdline_parser_print_version (void)
+{
+ printf ("%s %s\n", PACKAGE, VERSION);
+}
+
+void
+cmdline_parser_print_help (void)
+{
+ cmdline_parser_print_version ();
+ printf("\n"
+ "Usage: %s [OPTIONS]...\n", PACKAGE);
+ printf(" -h --help Print help and exit\n");
+ printf(" -V --version Print version and exit\n");
+ printf(" -f --fg Run in foreground (default=off)\n");
+ printf(" -d --debug Run in debug mode (default=off)\n");
+ printf(" -cSTRING --conf=STRING Read configuration file (default='/etc/ggsn.conf')\n");
+ printf(" --pidfile=STRING Filename of process id file (default='/var/run/ggsn.pid')\n");
+ printf(" --statedir=STRING Directory of nonvolatile data (default='/var/lib/ggsn/')\n");
+ printf(" -lSTRING --listen=STRING Local interface\n");
+ printf(" -nSTRING --net=STRING Network (default='192.168.0.0')\n");
+ printf(" --mask=STRING Network mask (default='255.255.255.0')\n");
+ printf(" --timelimit=INT Exit after timelimit seconds (default='0')\n");
+ printf(" -aSTRING --apn=STRING Access point name (default='internet')\n");
+ printf(" -qINT --qos=INT Requested quality of service (default='0x0b921f')\n");
+}
+
+
+#ifndef HAVE_STRDUP
+/* gengetopt_strdup(): automatically generated from strdup.c. */
+/* strdup.c replacement of strdup, which is not standard */
+static char *
+gengetopt_strdup (const char *s)
+{
+ char *result = (char*)malloc(strlen(s) + 1);
+ if (result == (char*)0)
+ return (char*)0;
+ strcpy(result, s);
+ return result;
+}
+#endif /* HAVE_STRDUP */
+
+int
+cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_info)
+{
+ int c; /* Character of the parsed option. */
+ int missing_required_options = 0;
+
+ args_info->help_given = 0 ;
+ args_info->version_given = 0 ;
+ args_info->fg_given = 0 ;
+ args_info->debug_given = 0 ;
+ args_info->conf_given = 0 ;
+ args_info->pidfile_given = 0 ;
+ args_info->statedir_given = 0 ;
+ args_info->listen_given = 0 ;
+ args_info->net_given = 0 ;
+ args_info->mask_given = 0 ;
+ args_info->timelimit_given = 0 ;
+ args_info->apn_given = 0 ;
+ args_info->qos_given = 0 ;
+#define clear_args() { \
+ args_info->fg_flag = 0;\
+ args_info->debug_flag = 0;\
+ args_info->conf_arg = strdup("/etc/ggsn.conf") ;\
+ args_info->pidfile_arg = strdup("/var/run/ggsn.pid") ;\
+ args_info->statedir_arg = strdup("/var/lib/ggsn/") ;\
+ args_info->listen_arg = NULL; \
+ args_info->net_arg = strdup("192.168.0.0") ;\
+ args_info->mask_arg = strdup("255.255.255.0") ;\
+ args_info->timelimit_arg = 0 ;\
+ args_info->apn_arg = strdup("internet") ;\
+ args_info->qos_arg = 0x0b921f ;\
+}
+
+ clear_args();
+
+ optarg = 0;
+ optind = 1;
+ opterr = 1;
+ optopt = '?';
+
+ while (1)
+ {
+ int option_index = 0;
+ char *stop_char;
+ static struct option long_options[] = {
+ { "help", 0, NULL, 'h' },
+ { "version", 0, NULL, 'V' },
+ { "fg", 0, NULL, 'f' },
+ { "debug", 0, NULL, 'd' },
+ { "conf", 1, NULL, 'c' },
+ { "pidfile", 1, NULL, 0 },
+ { "statedir", 1, NULL, 0 },
+ { "listen", 1, NULL, 'l' },
+ { "net", 1, NULL, 'n' },
+ { "mask", 1, NULL, 0 },
+ { "timelimit", 1, NULL, 0 },
+ { "apn", 1, NULL, 'a' },
+ { "qos", 1, NULL, 'q' },
+ { NULL, 0, NULL, 0 }
+ };
+
+ c = getopt_long (argc, argv, "hVfdc:l:n:a:q:", long_options, &option_index);
+
+ if (c == -1) break; /* Exit from `while (1)' loop. */
+
+ switch (c)
+ {
+ case 'h': /* Print help and exit. */
+ clear_args ();
+ cmdline_parser_print_help ();
+ exit (EXIT_SUCCESS);
+
+ case 'V': /* Print version and exit. */
+ clear_args ();
+ cmdline_parser_print_version ();
+ exit (EXIT_SUCCESS);
+
+ case 'f': /* Run in foreground. */
+ if (args_info->fg_given)
+ {
+ fprintf (stderr, "%s: `--fg' (`-f') option given more than once\n", PACKAGE);
+ clear_args ();
+ exit (EXIT_FAILURE);
+ }
+ args_info->fg_given = 1;
+ args_info->fg_flag = !(args_info->fg_flag);
+ break;
+
+ case 'd': /* Run in debug mode. */
+ if (args_info->debug_given)
+ {
+ fprintf (stderr, "%s: `--debug' (`-d') option given more than once\n", PACKAGE);
+ clear_args ();
+ exit (EXIT_FAILURE);
+ }
+ args_info->debug_given = 1;
+ args_info->debug_flag = !(args_info->debug_flag);
+ break;
+
+ case 'c': /* Read configuration file. */
+ if (args_info->conf_given)
+ {
+ fprintf (stderr, "%s: `--conf' (`-c') option given more than once\n", PACKAGE);
+ clear_args ();
+ exit (EXIT_FAILURE);
+ }
+ args_info->conf_given = 1;
+ args_info->conf_arg = strdup (optarg);
+ break;
+
+ case 'l': /* Local interface. */
+ if (args_info->listen_given)
+ {
+ fprintf (stderr, "%s: `--listen' (`-l') option given more than once\n", PACKAGE);
+ clear_args ();
+ exit (EXIT_FAILURE);
+ }
+ args_info->listen_given = 1;
+ args_info->listen_arg = strdup (optarg);
+ break;
+
+ case 'n': /* Network. */
+ if (args_info->net_given)
+ {
+ fprintf (stderr, "%s: `--net' (`-n') option given more than once\n", PACKAGE);
+ clear_args ();
+ exit (EXIT_FAILURE);
+ }
+ args_info->net_given = 1;
+ args_info->net_arg = strdup (optarg);
+ break;
+
+ case 'a': /* Access point name. */
+ if (args_info->apn_given)
+ {
+ fprintf (stderr, "%s: `--apn' (`-a') option given more than once\n", PACKAGE);
+ clear_args ();
+ exit (EXIT_FAILURE);
+ }
+ args_info->apn_given = 1;
+ args_info->apn_arg = strdup (optarg);
+ break;
+
+ case 'q': /* Requested quality of service. */
+ if (args_info->qos_given)
+ {
+ fprintf (stderr, "%s: `--qos' (`-q') option given more than once\n", PACKAGE);
+ clear_args ();
+ exit (EXIT_FAILURE);
+ }
+ args_info->qos_given = 1;
+ args_info->qos_arg = strtol (optarg,&stop_char,0);
+ break;
+
+
+ case 0: /* Long option with no short option */
+ /* Filename of process id file. */
+ if (strcmp (long_options[option_index].name, "pidfile") == 0)
+ {
+ if (args_info->pidfile_given)
+ {
+ fprintf (stderr, "%s: `--pidfile' option given more than once\n", PACKAGE);
+ clear_args ();
+ exit (EXIT_FAILURE);
+ }
+ args_info->pidfile_given = 1;
+ args_info->pidfile_arg = strdup (optarg);
+ break;
+ }
+ /* Directory of nonvolatile data. */
+ else if (strcmp (long_options[option_index].name, "statedir") == 0)
+ {
+ if (args_info->statedir_given)
+ {
+ fprintf (stderr, "%s: `--statedir' option given more than once\n", PACKAGE);
+ clear_args ();
+ exit (EXIT_FAILURE);
+ }
+ args_info->statedir_given = 1;
+ args_info->statedir_arg = strdup (optarg);
+ break;
+ }
+ /* Network mask. */
+ else if (strcmp (long_options[option_index].name, "mask") == 0)
+ {
+ if (args_info->mask_given)
+ {
+ fprintf (stderr, "%s: `--mask' option given more than once\n", PACKAGE);
+ clear_args ();
+ exit (EXIT_FAILURE);
+ }
+ args_info->mask_given = 1;
+ args_info->mask_arg = strdup (optarg);
+ break;
+ }
+ /* Exit after timelimit seconds. */
+ else if (strcmp (long_options[option_index].name, "timelimit") == 0)
+ {
+ if (args_info->timelimit_given)
+ {
+ fprintf (stderr, "%s: `--timelimit' option given more than once\n", PACKAGE);
+ clear_args ();
+ exit (EXIT_FAILURE);
+ }
+ args_info->timelimit_given = 1;
+ args_info->timelimit_arg = strtol (optarg,&stop_char,0);
+ break;
+ }
+
+ case '?': /* Invalid option. */
+ /* `getopt_long' already printed an error message. */
+ exit (EXIT_FAILURE);
+
+ default: /* bug: option not considered. */
+ fprintf (stderr, "%s: option unknown: %c\n", PACKAGE, c);
+ abort ();
+ } /* switch */
+ } /* while */
+
+
+ if ( missing_required_options )
+ exit (EXIT_FAILURE);
+
+ return 0;
+}
+
+#define CONFIGPARSERBUFSIZE 1024
+
+int
+cmdline_parser_configfile (char * const filename, struct gengetopt_args_info *args_info, int override)
+{
+ FILE* file;
+ char linebuf[CONFIGPARSERBUFSIZE];
+ int line_num = 0;
+ int len;
+ int fnum;
+ char fopt[CONFIGPARSERBUFSIZE], farg[CONFIGPARSERBUFSIZE];
+ char *stop_char;
+
+ if ((file = fopen(filename, "r")) == NULL)
+ {
+ fprintf (stderr, "%s: Error opening configuration file '%s'\n",
+ PACKAGE, filename);
+ exit (EXIT_FAILURE);
+ }
+
+ while ((fgets(linebuf, CONFIGPARSERBUFSIZE, file)) != NULL)
+ {
+ ++line_num;
+ len = strlen(linebuf);
+ if (len == CONFIGPARSERBUFSIZE-1)
+ {
+ fprintf (stderr, "%s: Line longer than %d characters found in configuration file '%s'\n",
+ PACKAGE, CONFIGPARSERBUFSIZE, filename);
+ exit (EXIT_FAILURE);
+ }
+
+ if (linebuf[0] == '#')
+ continue; /* Line was a comment */
+
+ /* Get the option */
+ if ((fnum = sscanf(linebuf, "%s %s", fopt, farg)) > 0)
+ {
+ if (!strcmp(fopt, "help"))
+ {
+ if (override || !args_info->help_given)
+ {
+ args_info->help_given = 1;
+
+ }
+ continue;
+ }
+ if (!strcmp(fopt, "version"))
+ {
+ if (override || !args_info->version_given)
+ {
+ args_info->version_given = 1;
+
+ }
+ continue;
+ }
+ if (!strcmp(fopt, "fg"))
+ {
+ if (override || !args_info->fg_given)
+ {
+ args_info->fg_given = 1;
+ args_info->fg_flag = !(args_info->fg_flag);
+ }
+ continue;
+ }
+ if (!strcmp(fopt, "debug"))
+ {
+ if (override || !args_info->debug_given)
+ {
+ args_info->debug_given = 1;
+ args_info->debug_flag = !(args_info->debug_flag);
+ }
+ continue;
+ }
+ if (!strcmp(fopt, "conf"))
+ {
+ if (override || !args_info->conf_given)
+ {
+ args_info->conf_given = 1;
+ if (fnum == 2)
+ args_info->conf_arg = strdup (farg);
+ else
+ {
+ fprintf (stderr, "%s:%d: required <option_name> <option_val>\n",
+ filename, line_num);
+ exit (EXIT_FAILURE);
+ }
+ }
+ continue;
+ }
+ if (!strcmp(fopt, "pidfile"))
+ {
+ if (override || !args_info->pidfile_given)
+ {
+ args_info->pidfile_given = 1;
+ if (fnum == 2)
+ args_info->pidfile_arg = strdup (farg);
+ else
+ {
+ fprintf (stderr, "%s:%d: required <option_name> <option_val>\n",
+ filename, line_num);
+ exit (EXIT_FAILURE);
+ }
+ }
+ continue;
+ }
+ if (!strcmp(fopt, "statedir"))
+ {
+ if (override || !args_info->statedir_given)
+ {
+ args_info->statedir_given = 1;
+ if (fnum == 2)
+ args_info->statedir_arg = strdup (farg);
+ else
+ {
+ fprintf (stderr, "%s:%d: required <option_name> <option_val>\n",
+ filename, line_num);
+ exit (EXIT_FAILURE);
+ }
+ }
+ continue;
+ }
+ if (!strcmp(fopt, "listen"))
+ {
+ if (override || !args_info->listen_given)
+ {
+ args_info->listen_given = 1;
+ if (fnum == 2)
+ args_info->listen_arg = strdup (farg);
+ else
+ {
+ fprintf (stderr, "%s:%d: required <option_name> <option_val>\n",
+ filename, line_num);
+ exit (EXIT_FAILURE);
+ }
+ }
+ continue;
+ }
+ if (!strcmp(fopt, "net"))
+ {
+ if (override || !args_info->net_given)
+ {
+ args_info->net_given = 1;
+ if (fnum == 2)
+ args_info->net_arg = strdup (farg);
+ else
+ {
+ fprintf (stderr, "%s:%d: required <option_name> <option_val>\n",
+ filename, line_num);
+ exit (EXIT_FAILURE);
+ }
+ }
+ continue;
+ }
+ if (!strcmp(fopt, "mask"))
+ {
+ if (override || !args_info->mask_given)
+ {
+ args_info->mask_given = 1;
+ if (fnum == 2)
+ args_info->mask_arg = strdup (farg);
+ else
+ {
+ fprintf (stderr, "%s:%d: required <option_name> <option_val>\n",
+ filename, line_num);
+ exit (EXIT_FAILURE);
+ }
+ }
+ continue;
+ }
+ if (!strcmp(fopt, "timelimit"))
+ {
+ if (override || !args_info->timelimit_given)
+ {
+ args_info->timelimit_given = 1;
+ if (fnum == 2)
+ args_info->timelimit_arg = strtol (farg,&stop_char,0);
+ else
+ {
+ fprintf (stderr, "%s:%d: required <option_name> <option_val>\n",
+ filename, line_num);
+ exit (EXIT_FAILURE);
+ }
+ }
+ continue;
+ }
+ if (!strcmp(fopt, "apn"))
+ {
+ if (override || !args_info->apn_given)
+ {
+ args_info->apn_given = 1;
+ if (fnum == 2)
+ args_info->apn_arg = strdup (farg);
+ else
+ {
+ fprintf (stderr, "%s:%d: required <option_name> <option_val>\n",
+ filename, line_num);
+ exit (EXIT_FAILURE);
+ }
+ }
+ continue;
+ }
+ if (!strcmp(fopt, "qos"))
+ {
+ if (override || !args_info->qos_given)
+ {
+ args_info->qos_given = 1;
+ if (fnum == 2)
+ args_info->qos_arg = strtol (farg,&stop_char,0);
+ else
+ {
+ fprintf (stderr, "%s:%d: required <option_name> <option_val>\n",
+ filename, line_num);
+ exit (EXIT_FAILURE);
+ }
+ }
+ continue;
+ }
+
+
+ /* Tried all known options. This one is unknown! */
+ fprintf (stderr, "%s: Unknown option '%s' found in %s\n",
+ PACKAGE, fopt, filename);
+ exit (EXIT_FAILURE);
+ }
+ } /* while */
+ fclose(file); /* No error checking on close */
+
+ return 0;
+}
diff --git a/ggsn/cmdline.ggo b/ggsn/cmdline.ggo
new file mode 100644
index 0000000..5d3e601
--- /dev/null
+++ b/ggsn/cmdline.ggo
@@ -0,0 +1,29 @@
+# OpenGGSN - Gateway GPRS Support Node
+# Copyright (C) 2002 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.
+#
+# The initial developer of the original code is
+# Jens Jakobsen <jj@openggsn.org>
+#
+# Contributor(s):
+
+
+option "fg" f "Run in foreground" flag off
+option "debug" d "Run in debug mode" flag off
+
+option "conf" c "Read configuration file" string default="/etc/ggsn.conf" no
+option "pidfile" - "Filename of process id file" string default="/var/run/ggsn.pid" no
+option "statedir" - "Directory of nonvolatile data" string default="/var/lib/ggsn/" no
+
+option "listen" l "Local interface" string no
+option "net" n "Network" string default="192.168.0.0" no
+option "mask" - "Network mask" string default="255.255.255.0" no
+
+option "timelimit" - "Exit after timelimit seconds" int default="0" no
+
+option "apn" a "Access point name" string default="internet" no
+option "qos" q "Requested quality of service" int default="0x0b921f" no
diff --git a/ggsn/cmdline.h b/ggsn/cmdline.h
new file mode 100644
index 0000000..e08cfe8
--- /dev/null
+++ b/ggsn/cmdline.h
@@ -0,0 +1,61 @@
+/* cmdline.h */
+
+/* File autogenerated by gengetopt version 2.8rc */
+
+#ifndef _cmdline_h
+#define _cmdline_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Don't define PACKAGE and VERSION if we use automake. */
+#ifndef PACKAGE
+#define PACKAGE ""
+#endif
+
+#ifndef VERSION
+#define VERSION ""
+#endif
+
+struct gengetopt_args_info
+{
+ int fg_flag; /* Run in foreground (default=off). */
+ int debug_flag; /* Run in debug mode (default=off). */
+ char * conf_arg; /* Read configuration file (default='/etc/ggsn.conf'). */
+ char * pidfile_arg; /* Filename of process id file (default='/var/run/ggsn.pid'). */
+ char * statedir_arg; /* Directory of nonvolatile data (default='/var/lib/ggsn/'). */
+ char * listen_arg; /* Local interface. */
+ char * net_arg; /* Network (default='192.168.0.0'). */
+ char * mask_arg; /* Network mask (default='255.255.255.0'). */
+ int timelimit_arg; /* Exit after timelimit seconds (default='0'). */
+ char * apn_arg; /* Access point name (default='internet'). */
+ int qos_arg; /* Requested quality of service (default='0x0b921f'). */
+
+ int help_given ; /* Whether help was given. */
+ int version_given ; /* Whether version was given. */
+ int fg_given ; /* Whether fg was given. */
+ int debug_given ; /* Whether debug was given. */
+ int conf_given ; /* Whether conf was given. */
+ int pidfile_given ; /* Whether pidfile was given. */
+ int statedir_given ; /* Whether statedir was given. */
+ int listen_given ; /* Whether listen was given. */
+ int net_given ; /* Whether net was given. */
+ int mask_given ; /* Whether mask was given. */
+ int timelimit_given ; /* Whether timelimit was given. */
+ int apn_given ; /* Whether apn was given. */
+ int qos_given ; /* Whether qos was given. */
+
+} ;
+
+int cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_info);
+
+void cmdline_parser_print_help(void);
+void cmdline_parser_print_version(void);
+
+int cmdline_parser_configfile (char * const filename, struct gengetopt_args_info *args_info, int override);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* _cmdline_h */
diff --git a/ggsn/ggsn.c b/ggsn/ggsn.c
new file mode 100644
index 0000000..a850de8
--- /dev/null
+++ b/ggsn/ggsn.c
@@ -0,0 +1,424 @@
+/*
+ * OpenGGSN - Gateway GPRS Support Node
+ * Copyright (C) 2002 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.
+ *
+ * The initial developer of the original code is
+ * Jens Jakobsen <jj@openggsn.org>
+ *
+ * Contributor(s):
+ *
+ */
+
+/* ggsn.c
+ *
+ */
+
+#ifdef __linux__
+#define _GNU_SOURCE 1 /* strdup() prototype, broken arpa/inet.h */
+#endif
+
+
+#include <syslog.h>
+#include <ctype.h>
+#include <netdb.h>
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <features.h>
+
+#include <errno.h>
+
+#include <asm/types.h>
+#include <sys/socket.h>
+#include <linux/netlink.h>
+
+#include <time.h>
+
+#include "tun.h"
+#include "../gtp/pdp.h"
+#include "../gtp/gtp.h"
+#include "cmdline.h"
+
+
+int maxfd = 0; /* For select() */
+int tun_fd = -1; /* Network file descriptor */
+struct tun_t *tun; /* TUN instance */
+struct in_addr net, mask; /* Network interface */
+int debug; /* Print debug output */
+
+
+/* Used to write process ID to file. Assume someone else will delete */
+void log_pid(char *pidfile) {
+ FILE *file;
+ mode_t oldmask;
+
+ oldmask = umask(022);
+ file = fopen(pidfile, "w");
+ umask(oldmask);
+ if(!file)
+ return;
+ fprintf(file, "%d\n", getpid());
+ fclose(file);
+}
+
+
+int encaps_printf(void *p, void *packet, unsigned len)
+{
+ int i;
+ if (debug) {
+ printf("The packet looks like this:\n");
+ for( i=0; i<len; i++) {
+ printf("%02x ", (unsigned char)*(char *)(packet+i));
+ if (!((i+1)%16)) printf("\n");
+ };
+ printf("\n");
+ }
+ return 0;
+}
+
+int getip(struct pdp_t *pdp, void* ipif, struct ul66_t *eua,
+ struct in_addr *net, struct in_addr *mask) {
+ struct in_addr addr;
+ uint32_t ip_start, ip_end, ip_cur;
+ struct pdp_t *pdp_;
+ struct ul66_t eua_;
+
+ if (debug) {
+ printf("Begin getip %d %d %2x%2x%2x%2x\n", (unsigned)ipif, eua->l,
+ eua->v[2],eua->v[3],eua->v[4],eua->v[5]);
+ }
+
+ ip_start = ntoh32(net->s_addr & mask->s_addr);
+ ip_end = ntoh32(hton32(ip_start) | ~mask->s_addr);
+
+ /* By convention the first address is the network address, and the last */
+ /* address is the broadcast address. This way two IP addresses are "lost" */
+ ip_start++;
+
+ if (eua->l == 0) { /* No address supplied. Find one that is available! */
+ /* This routine does linear search. In order to support millions of
+ * addresses we should instead keep a linked list of available adresses */
+ for (ip_cur = ip_start; ip_cur < ip_end; ip_cur++) {
+ addr.s_addr = hton32(ip_cur);
+ pdp_ntoeua(&addr, &eua_);
+ if (pdp_ipget(&pdp_, ipif, &eua_) == -1) {
+ pdp_ntoeua(&addr, &pdp->eua);
+ pdp->ipif = ipif;
+ return 0;
+ };
+ }
+ return EOF; /* No addresses available */
+ }
+ else { /* Address supplied */
+ if (pdp_ipget(&pdp_, ipif, eua) == -1) {
+ pdp->ipif = ipif;
+ pdp->eua.l = eua->l;
+ memcpy(pdp->eua.v, eua->v, eua->l);
+ return 0;
+ }
+ else return EOF; /* Specified address not available */
+ }
+}
+
+
+int delete_context(struct pdp_t *pdp) {
+ pdp_ipdel(pdp);
+ return 0;
+}
+
+
+
+int create_context(struct pdp_t *pdp) {
+
+ if (debug) printf("Received create PDP context request\n");
+
+ pdp->eua.l=0; /* TODO: Indicates dynamic IP */
+
+ /* ulcpy(&pdp->qos_neg, &pdp->qos_req, sizeof(pdp->qos_req.v)); */
+ memcpy(pdp->qos_neg0, pdp->qos_req0, sizeof(pdp->qos_neg));
+
+ getip(pdp, tun, &pdp->eua, &net, &mask);
+ pdp_ipset(pdp, pdp->ipif, &pdp->eua);
+
+ return 0; /* Success */
+}
+
+
+
+int create_tun() {
+ char buf[1024];
+ char snet[100], smask[100];
+
+ if ((tun_fd = tun_newtun((struct tun_t**) &tun)) > maxfd)
+ maxfd = tun_fd;
+
+ if (tun_fd == -1) {
+ printf("Failed to open tun\n");
+ exit(1);
+ }
+
+ strncpy(snet, inet_ntoa(net), 100);
+ strncpy(smask, inet_ntoa(mask), 100);
+
+ sprintf(buf, "ifconfig %s %s mtu 1450 netmask %s",
+ tun->devname, snet, smask);
+ if (debug) printf("%s\n", buf);
+ system(buf);
+
+ system("echo 1 > /proc/sys/net/ipv4/ip_forward");
+
+ return 0;
+}
+
+
+int encaps_gtp(void *gsn, struct tun_t *tun, void *pack, unsigned len) {
+ struct pdp_t *pdp;
+ struct in_addr addr;
+ struct ul66_t eua;
+ /*printf("encaps_gtp. Packet received: forwarding to gtp.\n");*/
+ /* First we need to extract the IP destination address */
+ memcpy(&addr.s_addr, pack+16, 4); /* This ought to be dest addr */
+ pdp_ntoeua(&addr, &eua);
+ if (pdp_ipget(&pdp, tun, &eua) == 0) {
+ return gtp_gpdu((struct gsn_t*) gsn, pdp, pack, len);
+ }
+ else {
+ if (debug) printf("Received packet with no destination!!!\n");
+ return 0;
+ }
+}
+
+
+int encaps_tun(struct pdp_t *pdp, void *pack, unsigned len) {
+ /* printf("encaps_tun. Packet received: forwarding to tun\n");*/
+ return tun_encaps((struct tun_t*) pdp->ipif, pack, len);
+}
+
+
+int main(int argc, char **argv)
+{
+ /* gengeopt declarations */
+ struct gengetopt_args_info args_info;
+
+ struct hostent *host;
+
+ struct in_addr listen;
+
+ int gtpfd = -1; /* Network file descriptor */
+ struct gsn_t *gsn; /* GSN instance */
+
+ fd_set fds; /* For select() */
+ struct timeval idleTime; /* How long to select() */
+ int i; /* for loop */
+
+ struct ul_t qos, apn;
+ unsigned char qosh[3], apnh[256];
+
+ int timelimit; /* Number of seconds to be connected */
+ int starttime; /* Time program was started */
+
+ /* open a connection to the syslog daemon */
+ /*openlog(PACKAGE, LOG_PID, LOG_DAEMON);*/
+ openlog(PACKAGE, (LOG_PID | LOG_PERROR), LOG_DAEMON);
+
+ if (cmdline_parser (argc, argv, &args_info) != 0)
+ exit(1);
+ if (args_info.debug_flag) {
+ printf("listen: %s\n", args_info.listen_arg);
+ printf("conf: %s\n", args_info.conf_arg);
+ printf("fg: %d\n", args_info.fg_flag);
+ printf("debug: %d\n", args_info.debug_flag);
+ printf("qos: %#08x\n", args_info.qos_arg);
+ printf("apn: %s\n", args_info.apn_arg);
+ printf("net: %s\n", args_info.net_arg);
+ printf("mask: %s\n", args_info.mask_arg);
+ printf("pidfile: %s\n", args_info.pidfile_arg);
+ printf("statedir: %s\n", args_info.statedir_arg);
+ printf("timelimit: %d\n", args_info.timelimit_arg);
+ }
+
+ /* Try out our new parser */
+
+ if (cmdline_parser_configfile (args_info.conf_arg, &args_info, 0) != 0)
+ exit(1);
+ if (args_info.debug_flag) {
+ printf("cmdline_parser_configfile\n");
+ printf("listen: %s\n", args_info.listen_arg);
+ printf("conf: %s\n", args_info.conf_arg);
+ printf("fg: %d\n", args_info.fg_flag);
+ printf("debug: %d\n", args_info.debug_flag);
+ printf("qos: %#08x\n", args_info.qos_arg);
+ printf("apn: %s\n", args_info.apn_arg);
+ printf("net: %s\n", args_info.net_arg);
+ printf("mask: %s\n", args_info.mask_arg);
+ printf("pidfile: %s\n", args_info.pidfile_arg);
+ printf("statedir: %s\n", args_info.statedir_arg);
+ printf("timelimit: %d\n", args_info.timelimit_arg);
+ }
+
+ /* Handle each option */
+
+ /* foreground */
+ /* If flag not given run as a daemon */
+ if (!args_info.fg_flag)
+ {
+ closelog();
+ /* Close the standard file descriptors. */
+ /* Is this really needed ? */
+ freopen("/dev/null", "w", stdout);
+ freopen("/dev/null", "w", stderr);
+ freopen("/dev/null", "r", stdin);
+ daemon(0, 0);
+ /* Open log again. This time with new pid */
+ openlog(PACKAGE, LOG_PID, LOG_DAEMON);
+ }
+
+ /* debug */
+ debug = args_info.debug_flag;
+
+ /* pidfile */
+ /* This has to be done after we have our final pid */
+ if (args_info.pidfile_arg) {
+ log_pid(args_info.pidfile_arg);
+ }
+
+ /* listen */
+ /* If no listen option is specified listen to any local port */
+ /* Do hostname lookup to translate hostname to IP address */
+ if (args_info.listen_arg) {
+ if (!(host = gethostbyname(args_info.listen_arg))) {
+ fprintf(stderr, "%s: Invalid listening address: %s!\n",
+ PACKAGE, args_info.listen_arg);
+ syslog(LOG_ERR, "Invalid listening address: %s!",
+ args_info.listen_arg);
+ return 1;
+ }
+ else {
+ memcpy(&listen.s_addr, host->h_addr, host->h_length);
+ }
+ }
+ else {
+ listen.s_addr = htonl(INADDR_ANY);
+ }
+
+ /* net */
+ /* Store net as in_addr */
+ if (args_info.net_arg) {
+ if (!inet_aton(args_info.net_arg, &net)) {
+ fprintf(stderr, "%s: Invalid network address: %s!\n",
+ PACKAGE, args_info.net_arg);
+ syslog(LOG_ERR, "Invalid network address: %s!",
+ args_info.net_arg);
+ return 1;
+ }
+ }
+
+ /* mask */
+ /* Store mask as in_addr */
+ if (args_info.mask_arg) {
+ if (!inet_aton(args_info.mask_arg, &mask)) {
+ fprintf(stderr, "%s: Invalid network mask: %s!\n",
+ PACKAGE, args_info.mask_arg);
+ syslog(LOG_ERR, "Invalid network mask: %s!",
+ args_info.mask_arg);
+ return 1;
+ }
+ }
+
+ /* Timelimit */
+ timelimit = args_info.timelimit_arg;
+ starttime = time(NULL);
+
+ /* qos */
+ qos.l = 3;
+ qos.v = qosh;
+ qos.v[2] = (args_info.qos_arg) & 0xff;
+ qos.v[1] = ((args_info.qos_arg) >> 8) & 0xff;
+ qos.v[0] = ((args_info.qos_arg) >> 16) & 0xff;
+
+ /* apn */
+ if (strlen(args_info.apn_arg)>255) {
+ printf("invalid APN\n");
+ exit(1);
+ }
+ apn.l = strlen(args_info.apn_arg) + 1;
+ apn.v = apnh;
+ apn.v[0] = (char) strlen(args_info.apn_arg);
+ strncpy(&apn.v[1], args_info.apn_arg, 255);
+
+ if (debug) printf("gtpclient: Initialising GTP tunnel\n");
+
+ if ((gtpfd = gtp_new(&gsn, args_info.statedir_arg, &listen)) > maxfd)
+ maxfd = gtpfd;
+
+ if ((gtpfd = gtp_fd(gsn)) > maxfd)
+ maxfd = gtpfd;
+
+
+ gtp_set_cb_gpdu(gsn, encaps_tun);
+ gtp_set_cb_delete_context(gsn, delete_context);
+
+ gtp_set_cb_create_context(gsn, create_context);
+ create_tun();
+
+ /******************************************************************/
+ /* Main select loop */
+ /******************************************************************/
+
+ while (((starttime + timelimit) > time(NULL)) || (0 == timelimit)) {
+
+ FD_ZERO(&fds);
+ if (tun_fd != -1) FD_SET(tun_fd, &fds);
+ if (gtpfd != -1) FD_SET(gtpfd, &fds);
+
+ gtp_retranstimeout(gsn, &idleTime);
+ switch (select(maxfd + 1, &fds, NULL, NULL, &idleTime)) {
+ case -1: /* Error with select() *
+ if (errno != EINTR)
+ syslog(LOG_ERR, "CTRL: Error with select(), quitting");
+ *goto leave_clear_call;*/
+ syslog(LOG_ERR, "GGSN: select = -1");
+ break;
+ case 0:
+ gtp_retrans(gsn); /* Only retransmit if nothing else */
+ break;
+ default:
+ break;
+ }
+
+ if (tun_fd != -1 && FD_ISSET(tun_fd, &fds) &&
+ tun_decaps(tun, encaps_gtp, gsn) < 0) {
+ syslog(LOG_ERR, "TUN read failed (fd)=(%d)", tun_fd);
+ }
+
+ if (gtpfd != -1 && FD_ISSET(gtpfd, &fds) &&
+ gtp_decaps(gsn) < 0) {
+ syslog(LOG_ERR, "GTP read failed (gre)=(%d)", gtpfd);
+ }
+
+
+ }
+
+ gtp_free(gsn);
+
+ return 1;
+
+}
+
diff --git a/ggsn/tun.c b/ggsn/tun.c
new file mode 100644
index 0000000..72ea264
--- /dev/null
+++ b/ggsn/tun.c
@@ -0,0 +1,128 @@
+/*
+ * OpenGGSN - Gateway GPRS Support Node
+ * Copyright (C) 2002 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.
+ *
+ * The initial developer of the original code is
+ * Jens Jakobsen <jj@openggsn.org>
+ *
+ * Contributor(s):
+ *
+ */
+
+/*
+ * tun.c: Contains all TUN functionality. Should be able to handle multiple
+ * tunnels in the same program. Each tunnel is identified by the socket.
+ * I suppose that no other state information than the socket is needed.
+ *
+ * - tun_newtun: Initialise TUN tunnel.
+ * - tun_freetun: Free a device previously created with tun_newtun.
+ * - tun_encaps: Encapsulate packet in TUN tunnel and send off
+ * - tun_decaps: Extract packet from TUN tunnel and call function to
+ * ship it off as GTP encapsulated packet.
+ *
+ * TODO:
+ * - Do we need to handle fragmentation?
+ */
+
+
+#include <syslog.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <linux/if.h>
+#include <errno.h>
+#include <linux/if_tun.h>
+
+
+#include "tun.h"
+
+
+int tun_newtun(struct tun_t **tun)
+{
+ struct ifreq ifr;
+
+ if (!(*tun = calloc(1, sizeof(struct tun_t)))) {
+ syslog(LOG_ERR, "%s %d. calloc(nmemb=%d, size=%d) failed: Error = %s(%d)",
+ __FILE__, __LINE__, 1, sizeof(struct tun_t),
+ strerror(errno), errno);
+ return EOF;
+ }
+
+ if (((*tun)->fd = open("/dev/net/tun", O_RDWR)) < 0) {
+ syslog(LOG_ERR, "TUN: open() failed");
+ return -1;
+ }
+
+ memset(&ifr, 0, sizeof(ifr));
+ ifr.ifr_flags = IFF_TUN | IFF_NO_PI; /* Tun device, no packet info */
+ strncpy(ifr.ifr_name, (*tun)->devname, IFNAMSIZ);
+
+ if (ioctl((*tun)->fd, TUNSETIFF, (void *) &ifr) < 0) {
+ syslog(LOG_ERR, "TUN: ioctl() failed");
+ close((*tun)->fd);
+ return -1;
+ }
+
+ ioctl((*tun)->fd, TUNSETNOCSUM, 1); /* Disable checksums */
+
+ strncpy((*tun)->devname, ifr.ifr_name, IFNAMSIZ);
+
+ return (*tun)->fd;
+}
+
+int tun_freetun(struct tun_t *tun)
+{
+ if (close(tun->fd)) {
+ syslog(LOG_ERR, "%s %d. close(fd=%d) failed: Error = %s",
+ __FILE__, __LINE__, tun->fd, strerror(errno));
+ return EOF;
+ }
+ free(tun);
+ return 0;
+}
+
+
+int tun_decaps(struct tun_t *tun,
+ int (*cb) (void *cl, struct tun_t*, void *pack, unsigned len),
+ void *cl)
+{
+ unsigned char buffer[PACKET_MAX + 64 /*TODO: ip header */ ];
+ int status;
+
+
+ if ((status = read(tun->fd, buffer, sizeof(buffer))) <= 0) {
+ syslog(LOG_ERR, "TUN: read(fd=%d,buffer=%lx,len=%d) from network failed: status = %d error = %s",
+ tun->fd, (unsigned long) buffer, sizeof(buffer), status, status ? strerror(errno) : "No error");
+ return -1;
+ }
+
+ /* Need to include code to verify packet src and dest addresses */
+ return cb(cl, tun, buffer, status);
+}
+
+int tun_encaps(struct tun_t *tun, void *pack, unsigned len)
+{
+ return write(tun->fd, pack, len);
+}
diff --git a/ggsn/tun.h b/ggsn/tun.h
new file mode 100644
index 0000000..03dc7df
--- /dev/null
+++ b/ggsn/tun.h
@@ -0,0 +1,48 @@
+/*
+ * OpenGGSN - Gateway GPRS Support Node
+ * Copyright (C) 2002 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.
+ *
+ * The initial developer of the original code is
+ * Jens Jakobsen <jj@openggsn.org>
+ *
+ * Contributor(s):
+ *
+ */
+
+#ifndef _TUN_H
+#define _TUN_H
+
+#define hton8(x) (x)
+#define ntoh8(x) (x)
+#define hton16(x) htons(x)
+#define ntoh16(x) ntohs(x)
+#define hton32(x) htonl(x)
+#define ntoh32(x) ntohl(x)
+
+#define PACKET_MAX 8196 /* TODO */
+
+/* ***********************************************************
+ * Information storage for each tun instance
+ *************************************************************/
+
+struct tun_t {
+ int fd; /* File descriptor to network interface */
+ struct in_addr addr; /* IP address of tun interface */
+ char devname[IFNAMSIZ];/* Name of the tun device */
+};
+
+
+extern int tun_newtun(struct tun_t **tun);
+extern int tun_freetun(struct tun_t *tun);
+extern int tun_decaps(struct tun_t *tun,
+ int (*cb) (void *cl, struct tun_t*, void *pack, unsigned len),
+ void *cl);
+extern int tun_encaps(struct tun_t *tun, void *pack, unsigned len);
+
+
+#endif /* !_TUN_H */
diff --git a/gtp/.deps/gtp.P b/gtp/.deps/gtp.P
new file mode 100644
index 0000000..bb8ee3c
--- /dev/null
+++ b/gtp/.deps/gtp.P
@@ -0,0 +1,111 @@
+gtp.lo gtp.o : gtp.c /usr/include/syslog.h /usr/include/sys/syslog.h \
+ /usr/include/features.h /usr/include/sys/cdefs.h \
+ /usr/include/gnu/stubs.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h \
+ /usr/include/stdio.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h \
+ /usr/include/bits/types.h /usr/include/bits/pthreadtypes.h \
+ /usr/include/bits/sched.h /usr/include/libio.h /usr/include/_G_config.h \
+ /usr/include/wchar.h /usr/include/bits/wchar.h /usr/include/gconv.h \
+ /usr/include/bits/stdio_lim.h /usr/include/bits/stdio.h \
+ /usr/include/stdlib.h /usr/include/bits/waitflags.h \
+ /usr/include/bits/waitstatus.h /usr/include/endian.h \
+ /usr/include/bits/endian.h /usr/include/xlocale.h \
+ /usr/include/sys/types.h /usr/include/time.h /usr/include/sys/select.h \
+ /usr/include/bits/select.h /usr/include/bits/sigset.h \
+ /usr/include/bits/time.h /usr/include/sys/sysmacros.h \
+ /usr/include/alloca.h /usr/include/sys/time.h /usr/include/sys/socket.h \
+ /usr/include/sys/uio.h /usr/include/bits/uio.h \
+ /usr/include/bits/socket.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/limits.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/syslimits.h \
+ /usr/include/limits.h /usr/include/bits/posix1_lim.h \
+ /usr/include/bits/local_lim.h /usr/include/linux/limits.h \
+ /usr/include/bits/posix2_lim.h /usr/include/bits/xopen_lim.h \
+ /usr/include/bits/wordsize.h /usr/include/bits/sockaddr.h \
+ /usr/include/asm/socket.h /usr/include/asm/sockios.h \
+ /usr/include/netinet/in.h /usr/include/stdint.h /usr/include/bits/in.h \
+ /usr/include/bits/byteswap.h /usr/include/arpa/inet.h \
+ /usr/include/sys/stat.h /usr/include/bits/stat.h /usr/include/unistd.h \
+ /usr/include/bits/posix_opt.h /usr/include/bits/environments.h \
+ /usr/include/bits/confname.h /usr/include/getopt.h \
+ /usr/include/string.h /usr/include/bits/string.h \
+ /usr/include/bits/string2.h /usr/include/errno.h \
+ /usr/include/bits/errno.h /usr/include/linux/errno.h \
+ /usr/include/asm/errno.h /usr/include/fcntl.h /usr/include/bits/fcntl.h \
+ pdp.h gtp.h gtpie.h queue.h
+gtp.c :
+/usr/include/syslog.h :
+/usr/include/sys/syslog.h :
+/usr/include/features.h :
+/usr/include/sys/cdefs.h :
+/usr/include/gnu/stubs.h :
+/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h :
+/usr/include/stdio.h :
+/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h :
+/usr/include/bits/types.h :
+/usr/include/bits/pthreadtypes.h :
+/usr/include/bits/sched.h :
+/usr/include/libio.h :
+/usr/include/_G_config.h :
+/usr/include/wchar.h :
+/usr/include/bits/wchar.h :
+/usr/include/gconv.h :
+/usr/include/bits/stdio_lim.h :
+/usr/include/bits/stdio.h :
+/usr/include/stdlib.h :
+/usr/include/bits/waitflags.h :
+/usr/include/bits/waitstatus.h :
+/usr/include/endian.h :
+/usr/include/bits/endian.h :
+/usr/include/xlocale.h :
+/usr/include/sys/types.h :
+/usr/include/time.h :
+/usr/include/sys/select.h :
+/usr/include/bits/select.h :
+/usr/include/bits/sigset.h :
+/usr/include/bits/time.h :
+/usr/include/sys/sysmacros.h :
+/usr/include/alloca.h :
+/usr/include/sys/time.h :
+/usr/include/sys/socket.h :
+/usr/include/sys/uio.h :
+/usr/include/bits/uio.h :
+/usr/include/bits/socket.h :
+/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/limits.h :
+/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/syslimits.h :
+/usr/include/limits.h :
+/usr/include/bits/posix1_lim.h :
+/usr/include/bits/local_lim.h :
+/usr/include/linux/limits.h :
+/usr/include/bits/posix2_lim.h :
+/usr/include/bits/xopen_lim.h :
+/usr/include/bits/wordsize.h :
+/usr/include/bits/sockaddr.h :
+/usr/include/asm/socket.h :
+/usr/include/asm/sockios.h :
+/usr/include/netinet/in.h :
+/usr/include/stdint.h :
+/usr/include/bits/in.h :
+/usr/include/bits/byteswap.h :
+/usr/include/arpa/inet.h :
+/usr/include/sys/stat.h :
+/usr/include/bits/stat.h :
+/usr/include/unistd.h :
+/usr/include/bits/posix_opt.h :
+/usr/include/bits/environments.h :
+/usr/include/bits/confname.h :
+/usr/include/getopt.h :
+/usr/include/string.h :
+/usr/include/bits/string.h :
+/usr/include/bits/string2.h :
+/usr/include/errno.h :
+/usr/include/bits/errno.h :
+/usr/include/linux/errno.h :
+/usr/include/asm/errno.h :
+/usr/include/fcntl.h :
+/usr/include/bits/fcntl.h :
+pdp.h :
+gtp.h :
+gtpie.h :
+queue.h :
diff --git a/gtp/.deps/gtpie.P b/gtp/.deps/gtpie.P
new file mode 100644
index 0000000..646efea
--- /dev/null
+++ b/gtp/.deps/gtpie.P
@@ -0,0 +1,52 @@
+gtpie.lo gtpie.o : gtpie.c /usr/include/stdio.h /usr/include/features.h \
+ /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h \
+ /usr/include/bits/types.h /usr/include/libio.h /usr/include/_G_config.h \
+ /usr/include/wchar.h /usr/include/bits/wchar.h /usr/include/gconv.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h \
+ /usr/include/bits/stdio_lim.h /usr/include/bits/stdio.h \
+ /usr/include/sys/types.h /usr/include/time.h /usr/include/netinet/in.h \
+ /usr/include/stdint.h /usr/include/bits/wordsize.h \
+ /usr/include/bits/socket.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/limits.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/syslimits.h \
+ /usr/include/limits.h /usr/include/bits/sockaddr.h \
+ /usr/include/asm/socket.h /usr/include/asm/sockios.h \
+ /usr/include/bits/in.h /usr/include/endian.h /usr/include/bits/endian.h \
+ /usr/include/bits/byteswap.h /usr/include/string.h \
+ /usr/include/bits/string.h /usr/include/bits/string2.h gtpie.h
+gtpie.c :
+/usr/include/stdio.h :
+/usr/include/features.h :
+/usr/include/sys/cdefs.h :
+/usr/include/gnu/stubs.h :
+/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h :
+/usr/include/bits/types.h :
+/usr/include/libio.h :
+/usr/include/_G_config.h :
+/usr/include/wchar.h :
+/usr/include/bits/wchar.h :
+/usr/include/gconv.h :
+/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h :
+/usr/include/bits/stdio_lim.h :
+/usr/include/bits/stdio.h :
+/usr/include/sys/types.h :
+/usr/include/time.h :
+/usr/include/netinet/in.h :
+/usr/include/stdint.h :
+/usr/include/bits/wordsize.h :
+/usr/include/bits/socket.h :
+/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/limits.h :
+/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/syslimits.h :
+/usr/include/limits.h :
+/usr/include/bits/sockaddr.h :
+/usr/include/asm/socket.h :
+/usr/include/asm/sockios.h :
+/usr/include/bits/in.h :
+/usr/include/endian.h :
+/usr/include/bits/endian.h :
+/usr/include/bits/byteswap.h :
+/usr/include/string.h :
+/usr/include/bits/string.h :
+/usr/include/bits/string2.h :
+gtpie.h :
diff --git a/gtp/.deps/lookupa.P b/gtp/.deps/lookupa.P
new file mode 100644
index 0000000..046263b
--- /dev/null
+++ b/gtp/.deps/lookupa.P
@@ -0,0 +1,3 @@
+lookupa.lo lookupa.o : lookupa.c lookupa.h
+lookupa.c :
+lookupa.h :
diff --git a/gtp/.deps/pdp.P b/gtp/.deps/pdp.P
new file mode 100644
index 0000000..1231e52
--- /dev/null
+++ b/gtp/.deps/pdp.P
@@ -0,0 +1,53 @@
+pdp.lo pdp.o : pdp.c /usr/include/stdio.h /usr/include/features.h \
+ /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h \
+ /usr/include/bits/types.h /usr/include/libio.h /usr/include/_G_config.h \
+ /usr/include/wchar.h /usr/include/bits/wchar.h /usr/include/gconv.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h \
+ /usr/include/bits/stdio_lim.h /usr/include/bits/stdio.h \
+ /usr/include/sys/types.h /usr/include/time.h /usr/include/netinet/in.h \
+ /usr/include/stdint.h /usr/include/bits/wordsize.h \
+ /usr/include/bits/socket.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/limits.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/syslimits.h \
+ /usr/include/limits.h /usr/include/bits/sockaddr.h \
+ /usr/include/asm/socket.h /usr/include/asm/sockios.h \
+ /usr/include/bits/in.h /usr/include/endian.h /usr/include/bits/endian.h \
+ /usr/include/bits/byteswap.h /usr/include/string.h \
+ /usr/include/bits/string.h /usr/include/bits/string2.h pdp.h lookupa.h
+pdp.c :
+/usr/include/stdio.h :
+/usr/include/features.h :
+/usr/include/sys/cdefs.h :
+/usr/include/gnu/stubs.h :
+/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h :
+/usr/include/bits/types.h :
+/usr/include/libio.h :
+/usr/include/_G_config.h :
+/usr/include/wchar.h :
+/usr/include/bits/wchar.h :
+/usr/include/gconv.h :
+/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h :
+/usr/include/bits/stdio_lim.h :
+/usr/include/bits/stdio.h :
+/usr/include/sys/types.h :
+/usr/include/time.h :
+/usr/include/netinet/in.h :
+/usr/include/stdint.h :
+/usr/include/bits/wordsize.h :
+/usr/include/bits/socket.h :
+/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/limits.h :
+/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/syslimits.h :
+/usr/include/limits.h :
+/usr/include/bits/sockaddr.h :
+/usr/include/asm/socket.h :
+/usr/include/asm/sockios.h :
+/usr/include/bits/in.h :
+/usr/include/endian.h :
+/usr/include/bits/endian.h :
+/usr/include/bits/byteswap.h :
+/usr/include/string.h :
+/usr/include/bits/string.h :
+/usr/include/bits/string2.h :
+pdp.h :
+lookupa.h :
diff --git a/gtp/.deps/queue.P b/gtp/.deps/queue.P
new file mode 100644
index 0000000..04bbd67
--- /dev/null
+++ b/gtp/.deps/queue.P
@@ -0,0 +1,64 @@
+queue.lo queue.o : queue.c /usr/include/stdlib.h /usr/include/features.h \
+ /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h \
+ /usr/include/stdio.h /usr/include/bits/types.h /usr/include/libio.h \
+ /usr/include/_G_config.h /usr/include/wchar.h /usr/include/bits/wchar.h \
+ /usr/include/gconv.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h \
+ /usr/include/bits/stdio_lim.h /usr/include/bits/stdio.h \
+ /usr/include/sys/types.h /usr/include/time.h /usr/include/sys/time.h \
+ /usr/include/bits/time.h /usr/include/sys/select.h \
+ /usr/include/bits/select.h /usr/include/bits/sigset.h \
+ /usr/include/netinet/in.h /usr/include/stdint.h \
+ /usr/include/bits/wordsize.h /usr/include/bits/socket.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/limits.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/syslimits.h \
+ /usr/include/limits.h /usr/include/bits/sockaddr.h \
+ /usr/include/asm/socket.h /usr/include/asm/sockios.h \
+ /usr/include/bits/in.h /usr/include/endian.h /usr/include/bits/endian.h \
+ /usr/include/bits/byteswap.h /usr/include/string.h \
+ /usr/include/bits/string.h /usr/include/bits/string2.h pdp.h gtp.h \
+ queue.h
+queue.c :
+/usr/include/stdlib.h :
+/usr/include/features.h :
+/usr/include/sys/cdefs.h :
+/usr/include/gnu/stubs.h :
+/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h :
+/usr/include/stdio.h :
+/usr/include/bits/types.h :
+/usr/include/libio.h :
+/usr/include/_G_config.h :
+/usr/include/wchar.h :
+/usr/include/bits/wchar.h :
+/usr/include/gconv.h :
+/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h :
+/usr/include/bits/stdio_lim.h :
+/usr/include/bits/stdio.h :
+/usr/include/sys/types.h :
+/usr/include/time.h :
+/usr/include/sys/time.h :
+/usr/include/bits/time.h :
+/usr/include/sys/select.h :
+/usr/include/bits/select.h :
+/usr/include/bits/sigset.h :
+/usr/include/netinet/in.h :
+/usr/include/stdint.h :
+/usr/include/bits/wordsize.h :
+/usr/include/bits/socket.h :
+/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/limits.h :
+/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/syslimits.h :
+/usr/include/limits.h :
+/usr/include/bits/sockaddr.h :
+/usr/include/asm/socket.h :
+/usr/include/asm/sockios.h :
+/usr/include/bits/in.h :
+/usr/include/endian.h :
+/usr/include/bits/endian.h :
+/usr/include/bits/byteswap.h :
+/usr/include/string.h :
+/usr/include/bits/string.h :
+/usr/include/bits/string2.h :
+pdp.h :
+gtp.h :
+queue.h :
diff --git a/gtp/Makefile b/gtp/Makefile
new file mode 100644
index 0000000..535c07d
--- /dev/null
+++ b/gtp/Makefile
@@ -0,0 +1,339 @@
+# Generated automatically from Makefile.in by configure.
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = /bin/sh
+
+srcdir = .
+top_srcdir = ..
+prefix = /usr/local
+exec_prefix = ${prefix}
+
+bindir = ${exec_prefix}/bin
+sbindir = ${exec_prefix}/sbin
+libexecdir = ${exec_prefix}/libexec
+datadir = ${prefix}/share
+sysconfdir = ${prefix}/etc
+sharedstatedir = ${prefix}/com
+localstatedir = ${prefix}/var
+libdir = ${exec_prefix}/lib
+infodir = ${prefix}/info
+mandir = ${prefix}/man
+includedir = ${prefix}/include
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/OpenGGSN
+pkglibdir = $(libdir)/OpenGGSN
+pkgincludedir = $(includedir)/OpenGGSN
+
+top_builddir = ..
+
+ACLOCAL = aclocal
+AUTOCONF = autoconf
+AUTOMAKE = automake
+AUTOHEADER = autoheader
+
+INSTALL = /usr/bin/install -c
+INSTALL_PROGRAM = ${INSTALL} $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = ${INSTALL} -m 644
+INSTALL_SCRIPT = ${INSTALL_PROGRAM}
+transform = s,x,x,
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = i686-pc-linux
+host_triplet = i686-pc-linux-gnu
+AS = @AS@
+AWK = gawk
+CC = gcc
+DLLTOOL = @DLLTOOL@
+LIBTOOL = $(SHELL) $(top_builddir)/libtool
+LN_S = ln -s
+MAKEINFO = makeinfo
+OBJDUMP = @OBJDUMP@
+PACKAGE = OpenGGSN
+RANLIB = ranlib
+VERSION = 0.5
+
+lib_LTLIBRARIES = libgtp.la
+
+CFLAGS = -O2 -fno-builtin -Wall -ansi -DSBINDIR='"$(sbindir)"'
+
+libgtp_la_SOURCES = gtp.c gtp.h gtpie.c gtpie.h pdp.c pdp.h lookupa.c lookupa.h queue.c queue.h
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(lib_LTLIBRARIES)
+
+
+DEFS = -DSTDC_HEADERS=1 -DHAVE_SYS_WAIT_H=1 -DHAVE_FCNTL_H=1 -DHAVE_STRINGS_H=1 -DHAVE_SYS_IOCTL_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYSLOG_H=1 -DHAVE_UNISTD_H=1 -DTIME_WITH_SYS_TIME=1 -DHAVE_SELECT=1 -DHAVE_SOCKET=1 -DHAVE_STRDUP=1 -DHAVE_STRERROR=1 -DHAVE_STRTOUL=1 -DPACKAGE=\"OpenGGSN\" -DVERSION=\"0.5\" -I. -I$(srcdir)
+CPPFLAGS =
+LDFLAGS =
+LIBS =
+libgtp_la_LDFLAGS =
+libgtp_la_LIBADD =
+libgtp_la_OBJECTS = gtp.lo gtpie.lo pdp.lo lookupa.lo queue.lo
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON = Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = gtar
+GZIP_ENV = --best
+DEP_FILES = .deps/gtp.P .deps/gtpie.P .deps/lookupa.P .deps/pdp.P \
+.deps/queue.P
+SOURCES = $(libgtp_la_SOURCES)
+OBJECTS = $(libgtp_la_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .lo .o .s
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --gnu gtp/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-libLTLIBRARIES:
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+
+distclean-libLTLIBRARIES:
+
+maintainer-clean-libLTLIBRARIES:
+
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(libdir)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo "$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p"; \
+ $(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p; \
+ else :; fi; \
+ done
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \
+ done
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+libgtp.la: $(libgtp_la_OBJECTS) $(libgtp_la_DEPENDENCIES)
+ $(LINK) -rpath $(libdir) $(libgtp_la_LDFLAGS) $(libgtp_la_OBJECTS) $(libgtp_la_LIBADD) $(LIBS)
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = gtp
+
+distdir: $(DISTFILES)
+ here=`cd $(top_builddir) && pwd`; \
+ top_distdir=`cd $(top_distdir) && pwd`; \
+ distdir=`cd $(distdir) && pwd`; \
+ cd $(top_srcdir) \
+ && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu gtp/Makefile
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$d/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+ -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+ @echo '$(COMPILE) -c $<'; \
+ $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.c
+ @echo '$(LTCOMPILE) -c $<'; \
+ $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am: install-libLTLIBRARIES
+install-exec: install-exec-am
+
+install-data-am:
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-libLTLIBRARIES
+uninstall: uninstall-am
+all-am: Makefile $(LTLIBRARIES)
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(libdir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-libLTLIBRARIES mostlyclean-compile \
+ mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
+ mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-libLTLIBRARIES clean-compile clean-libtool clean-tags \
+ clean-depend clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-libLTLIBRARIES distclean-compile \
+ distclean-libtool distclean-tags distclean-depend \
+ distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-libLTLIBRARIES \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-tags maintainer-clean-depend \
+ maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-libLTLIBRARIES distclean-libLTLIBRARIES \
+clean-libLTLIBRARIES maintainer-clean-libLTLIBRARIES \
+uninstall-libLTLIBRARIES install-libLTLIBRARIES mostlyclean-compile \
+distclean-compile clean-compile maintainer-clean-compile \
+mostlyclean-libtool distclean-libtool clean-libtool \
+maintainer-clean-libtool tags mostlyclean-tags distclean-tags \
+clean-tags maintainer-clean-tags distdir mostlyclean-depend \
+distclean-depend clean-depend maintainer-clean-depend info-am info \
+dvi-am dvi check check-am installcheck-am installcheck install-exec-am \
+install-exec install-data-am install-data install-am install \
+uninstall-am uninstall all-redirect all-am all installdirs \
+mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/gtp/Makefile.am b/gtp/Makefile.am
new file mode 100644
index 0000000..88131cc
--- /dev/null
+++ b/gtp/Makefile.am
@@ -0,0 +1,9 @@
+lib_LTLIBRARIES = libgtp.la
+
+CFLAGS = -O2 -fno-builtin -Wall -ansi -DSBINDIR='"$(sbindir)"'
+
+libgtp_la_SOURCES = gtp.c gtp.h gtpie.c gtpie.h pdp.c pdp.h lookupa.c lookupa.h queue.c queue.h
+
+
+
+
diff --git a/gtp/Makefile.in b/gtp/Makefile.in
new file mode 100644
index 0000000..0dbace6
--- /dev/null
+++ b/gtp/Makefile.in
@@ -0,0 +1,339 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AS = @AS@
+AWK = @AWK@
+CC = @CC@
+DLLTOOL = @DLLTOOL@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+MAKEINFO = @MAKEINFO@
+OBJDUMP = @OBJDUMP@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+
+lib_LTLIBRARIES = libgtp.la
+
+CFLAGS = -O2 -fno-builtin -Wall -ansi -DSBINDIR='"$(sbindir)"'
+
+libgtp_la_SOURCES = gtp.c gtp.h gtpie.c gtpie.h pdp.c pdp.h lookupa.c lookupa.h queue.c queue.h
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_CLEAN_FILES =
+LTLIBRARIES = $(lib_LTLIBRARIES)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir)
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+libgtp_la_LDFLAGS =
+libgtp_la_LIBADD =
+libgtp_la_OBJECTS = gtp.lo gtpie.lo pdp.lo lookupa.lo queue.lo
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON = Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = gtar
+GZIP_ENV = --best
+DEP_FILES = .deps/gtp.P .deps/gtpie.P .deps/lookupa.P .deps/pdp.P \
+.deps/queue.P
+SOURCES = $(libgtp_la_SOURCES)
+OBJECTS = $(libgtp_la_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .lo .o .s
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --gnu gtp/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-libLTLIBRARIES:
+
+clean-libLTLIBRARIES:
+ -test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
+
+distclean-libLTLIBRARIES:
+
+maintainer-clean-libLTLIBRARIES:
+
+install-libLTLIBRARIES: $(lib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(libdir)
+ @list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo "$(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p"; \
+ $(LIBTOOL) --mode=install $(INSTALL) $$p $(DESTDIR)$(libdir)/$$p; \
+ else :; fi; \
+ done
+
+uninstall-libLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ list='$(lib_LTLIBRARIES)'; for p in $$list; do \
+ $(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/$$p; \
+ done
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+libgtp.la: $(libgtp_la_OBJECTS) $(libgtp_la_DEPENDENCIES)
+ $(LINK) -rpath $(libdir) $(libgtp_la_LDFLAGS) $(libgtp_la_OBJECTS) $(libgtp_la_LIBADD) $(LIBS)
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = gtp
+
+distdir: $(DISTFILES)
+ here=`cd $(top_builddir) && pwd`; \
+ top_distdir=`cd $(top_distdir) && pwd`; \
+ distdir=`cd $(distdir) && pwd`; \
+ cd $(top_srcdir) \
+ && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu gtp/Makefile
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$d/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+ -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+ @echo '$(COMPILE) -c $<'; \
+ $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.c
+ @echo '$(LTCOMPILE) -c $<'; \
+ $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am: install-libLTLIBRARIES
+install-exec: install-exec-am
+
+install-data-am:
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-libLTLIBRARIES
+uninstall: uninstall-am
+all-am: Makefile $(LTLIBRARIES)
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(libdir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-libLTLIBRARIES mostlyclean-compile \
+ mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
+ mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-libLTLIBRARIES clean-compile clean-libtool clean-tags \
+ clean-depend clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-libLTLIBRARIES distclean-compile \
+ distclean-libtool distclean-tags distclean-depend \
+ distclean-generic clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-libLTLIBRARIES \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-tags maintainer-clean-depend \
+ maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-libLTLIBRARIES distclean-libLTLIBRARIES \
+clean-libLTLIBRARIES maintainer-clean-libLTLIBRARIES \
+uninstall-libLTLIBRARIES install-libLTLIBRARIES mostlyclean-compile \
+distclean-compile clean-compile maintainer-clean-compile \
+mostlyclean-libtool distclean-libtool clean-libtool \
+maintainer-clean-libtool tags mostlyclean-tags distclean-tags \
+clean-tags maintainer-clean-tags distdir mostlyclean-depend \
+distclean-depend clean-depend maintainer-clean-depend info-am info \
+dvi-am dvi check check-am installcheck-am installcheck install-exec-am \
+install-exec install-data-am install-data install-am install \
+uninstall-am uninstall all-redirect all-am all installdirs \
+mostlyclean-generic distclean-generic clean-generic \
+maintainer-clean-generic clean mostlyclean distclean maintainer-clean
+
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/gtp/gtp.c b/gtp/gtp.c
new file mode 100644
index 0000000..e00168c
--- /dev/null
+++ b/gtp/gtp.c
@@ -0,0 +1,1917 @@
+/*
+ * OpenGGSN - Gateway GPRS Support Node
+ * Copyright (C) 2002 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.
+ *
+ * The initial developer of the original code is
+ * Jens Jakobsen <jj@openggsn.org>
+ *
+ * Contributor(s):
+ *
+ */
+
+/*
+ * gtp.c: Contains all GTP functionality. Should be able to handle multiple
+ * tunnels in the same program.
+ *
+ * TODO:
+ * - Do we need to handle fragmentation?
+ */
+
+
+#ifdef __linux__
+#define _GNU_SOURCE 1
+#endif
+
+
+#include <syslog.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include <arpa/inet.h>
+
+#include <stdint.h> /* ISO C99 types */
+
+#include "pdp.h"
+#include "gtp.h"
+#include "gtpie.h"
+#include "queue.h"
+
+
+struct gtp0_header gtp0_default;
+struct gtp1_header_long gtp1_default;
+
+/* API Functions */
+
+const char* gtp_version()
+{
+ return VERSION;
+}
+
+/* gtp_new */
+/* gtp_free */
+
+int gtp_newpdp(struct gsn_t* gsn, struct pdp_t **pdp,
+ uint64_t imsi, uint8_t nsapi) {
+ return pdp_newpdp(pdp, imsi, nsapi, NULL);
+}
+
+int gtp_freepdp(struct gsn_t* gsn, struct pdp_t *pdp) {
+ return pdp_freepdp(pdp);
+}
+
+int gtp_create_context(struct gsn_t *gsn, struct pdp_t *pdp, void *aid,
+ struct in_addr* inetaddr) {
+ int version = 0;
+
+ return gtp_create_pdp_req(gsn, version, aid, inetaddr, pdp);
+}
+
+int gtp_update_context(struct gsn_t *gsn, struct pdp_t *pdp, void *aid,
+ struct in_addr* inetaddr) {
+ int version = 0;
+
+ return gtp_update_pdp_req(gsn, version, aid, inetaddr, pdp);
+}
+
+int gtp_delete_context(struct gsn_t *gsn, struct pdp_t *pdp, void *aid) {
+ int version = 0;
+ return gtp_delete_pdp_req(gsn, version, aid, pdp);
+}
+
+/* gtp_gpdu */
+
+extern int gtp_fd(struct gsn_t *gsn) {
+ return gsn->fd;
+}
+
+/* gtp_decaps */
+/* gtp_retrans */
+/* gtp_retranstimeout */
+
+int gtp_set_cb_delete_context(struct gsn_t *gsn,
+ int (*cb_delete_context) (struct pdp_t* pdp))
+{
+ gsn->cb_delete_context = cb_delete_context;
+ return 0;
+}
+
+int gtp_set_cb_create_context(struct gsn_t *gsn,
+ int (*cb_create_context) (struct pdp_t* pdp))
+{
+ gsn->cb_create_context = cb_create_context;
+ return 0;
+}
+
+/*
+
+ int gtp_set_cb_create_pdp_conf(struct gsn_t *gsn,
+ int (*cb) (struct pdp_t*, int))
+ {
+ gsn->cb_create_pdp_conf = cb;
+ return 0;
+ }
+
+ int gtp_set_cb_update_pdp_conf(struct gsn_t *gsn,
+ int (*cb) (struct pdp_t*, int, int))
+ {
+ gsn->cb_update_pdp_conf = cb;
+ return 0;
+}
+
+in t gtp_set_cb_delete_pdp_conf(struct gsn_t *gsn,
+int (*cb) (struct pdp_t*, int))
+ {
+gsn->cb_delete_pdp_conf = cb;
+return 0;
+}
+
+*/
+
+int gtp_set_cb_conf(struct gsn_t *gsn,
+ int (*cb) (int type, int cause,
+ struct pdp_t* pdp, void *aid)) {
+ gsn->cb_conf = cb;
+ return 0;
+}
+
+extern int gtp_set_cb_gpdu(struct gsn_t *gsn,
+ int (*cb_gpdu) (struct pdp_t* pdp,
+ void* pack,
+ unsigned len))
+{
+ gsn->cb_gpdu = cb_gpdu;
+ return 0;
+}
+
+
+
+void get_default_gtp(int version, void *packet) {
+ switch (version) {
+ case 0:
+ memcpy(packet, &gtp0_default, sizeof(gtp0_default));
+ break;
+ case 1:
+ memcpy(packet, &gtp1_default, sizeof(gtp1_default));
+ break;
+ }
+}
+
+int print_packet(void *packet, unsigned len)
+{
+ int i;
+ printf("The packet looks like this (%d bytes):\n", len);
+ for( i=0; i<len; i++) {
+ printf("%02x ", (unsigned char)*(char *)(packet+i));
+ if (!((i+1)%16)) printf("\n");
+ };
+ printf("\n");
+ return 0;
+}
+
+char* snprint_packet(struct gsn_t *gsn, struct sockaddr_in *peer,
+ void *pack, unsigned len, char *buf, int size) {
+ int n;
+ int pos;
+ snprintf(buf, size, "Packet from %s:%u, length: %d, content:",
+ inet_ntoa(peer->sin_addr),
+ ntohs(peer->sin_port),
+ len);
+ pos = strlen(buf);
+ for(n=0; n<len; n++) {
+ if ((pos+4)<size) {
+ sprintf((buf+pos), " %02hhx", ((unsigned char*)pack)[n]);
+ pos += 3;
+ }
+ }
+ buf[pos] = 0;
+ return buf;
+}
+
+void gtp_err(int priority, char *filename, int linenum, char *fmt, ...) {
+ va_list args;
+ char buf[ERRMSG_SIZE];
+
+ va_start(args, fmt);
+ vsnprintf(buf, ERRMSG_SIZE, fmt, args);
+ va_end(args);
+
+ syslog(priority, "%s: %d: %s", filename, linenum, buf);
+}
+
+void gtp_errpack(int pri, char *fn, int ln, struct sockaddr_in *peer,
+ void *pack, unsigned len, char *fmt, ...) {
+
+ va_list args;
+ char buf[ERRMSG_SIZE];
+ char buf2[ERRMSG_SIZE];
+ int n;
+ int pos;
+
+ va_start(args, fmt);
+ vsnprintf(buf, ERRMSG_SIZE, fmt, args);
+ va_end(args);
+
+ snprintf(buf2, ERRMSG_SIZE, "Packet from %s:%u, length: %d, content:",
+ inet_ntoa(peer->sin_addr),
+ ntohs(peer->sin_port),
+ len);
+ pos = strlen(buf2);
+ for(n=0; n<len; n++) {
+ if ((pos+4)<ERRMSG_SIZE) {
+ sprintf((buf2+pos), " %02hhx", ((unsigned char*)pack)[n]);
+ pos += 3;
+ }
+ }
+ buf2[pos] = 0;
+
+ syslog(pri, "%s: %d: %s. %s", fn, ln, buf, buf2);
+
+}
+
+
+/* ***********************************************************
+ * Reliable delivery of signalling messages
+ *
+ * Sequence numbers are used for both signalling messages and
+ * data messages.
+ *
+ * For data messages each tunnel maintains a sequence counter,
+ * which is incremented by one each time a new data message
+ * is sent. The sequence number starts at (0) zero at tunnel
+ * establishment, and wraps around at 65535 (29.060 9.3.1.1
+ * and 09.60 8.1.1.1). The sequence numbers are either ignored,
+ * or can be used to check the validity of the message in the
+ * receiver, or for reordering af packets.
+ *
+ * For signalling messages the sequence number is used by
+ * signalling messages for which a response is defined. A response
+ * message should copy the sequence from the corresponding request
+ * message. The sequence number "unambiguously" identifies a request
+ * message within a given path, with a path being defined as a set of
+ * two endpoints (29.060 8.2, 29.060 7.6, 09.60 7.8). "All request
+ * messages shall be responded to, and all response messages associated
+ * with a certain request shall always include the same information"
+ *
+ * We take this to mean that the GSN transmitting a request is free to
+ * choose the sequence number, as long as it is unique within a given path.
+ * It means that we are allowed to count backwards, or roll over at 17
+ * if we prefer that. It also means that we can use the same counter for
+ * all paths. This has the advantage that the transmitted request sequence
+ * numbers are unique within each GSN, and also we dont have to mess around
+ * with path setup and teardown.
+ *
+ * If a response message is lost, the request will be retransmitted, and
+ * the receiving GSN will receive a "duplicated" request. The standard
+ * requires the receiving GSN to send a response, with the same information
+ * as in the original response. For most messages this happens automatically:
+ *
+ * Echo: Automatically dublicates the original response
+ * Create pdp context: The SGSN may send create context request even if
+ * a context allready exist (imsi+nsapi?). This means that the reply will
+ automatically dublicate the original response. It might however have
+ * sideeffects in the application which is asked twice to allocate
+ * validate the login.
+ * Update pdp context: Automatically dublicates the original response???
+ * Delete pdp context. Automatically in gtp0, but in gtp1 will generate
+ * a nonexist reply message.
+ *
+ * The correct solution will be to make a queue containing response messages.
+ * This queue should be checked whenever a request is received. If the
+ * response is allready in the queue that response should be transmitted.
+ * It should be possible to find messages in this queue on the basis of
+ * the sequence number and peer GSN IP address (The sequense number is unique
+ * within each path). This need to be implemented by a hash table. Furthermore
+ * it should be possibly to delete messages based on a timeout. This can be
+ * achieved by means of a linked list. The timeout value need to be larger
+ * than T3-RESPONSE * N3-REQUESTS (recommended value 5). These timers are
+ * set in the peer GSN, so there is no way to know these parameters. On the
+ * other hand the timeout value need to be so small that we do not receive
+ * wraparound sequence numbere before the message is deleted. 60 seconds is
+ * probably not a bad choise.
+ *
+ * This queue however is first really needed from gtp1.
+ *
+ * gtp_req:
+ * Send off a signalling message with appropiate sequence
+ * number. Store packet in queue.
+ * gtp_conf:
+ * Remove an incoming confirmation from the queue
+ * gtp_resp:
+ * Send off a responce to a request. Use the same sequence
+ * number in the response as in the request.
+ * gtp_retrans:
+ * Retransmit any outstanding packets which have exceeded
+ * a predefined timeout.
+ *************************************************************/
+
+int gtp_req(struct gsn_t *gsn, int version, union gtp_packet *packet,
+ int len, struct in_addr *inetaddr, void *aid) {
+ struct sockaddr_in addr;
+ struct qmsg_t *qmsg;
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_addr = *inetaddr;
+ addr.sin_port = htons(GTP0_PORT);
+
+ packet->gtp0.h.seq = hton16(gsn->seq_next);
+
+ if (sendto(gsn->fd, packet, len, 0,
+ (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+ gsn->err_sendto++;
+ gtp_err(LOG_ERR, __FILE__, __LINE__, "Sendto(fd=%d, msg=%lx, len=%d) failed: Error = %s", gsn->fd, (unsigned long) &packet, len, strerror(errno));
+ return -1;
+ }
+
+ /* Use new queue structure */
+ if (queue_newmsg(gsn->queue_req, &qmsg, &addr, gsn->seq_next)) {
+ gsn->err_queuefull++;
+ gtp_err(LOG_ERR, __FILE__, __LINE__, "Retransmit queue is full");
+ }
+ else {
+ memcpy(&qmsg->p, packet, sizeof(union gtp_packet));
+ qmsg->l = len;
+ qmsg->timeout = time(NULL) + 3; /* When to timeout */
+ qmsg->retrans = 0; /* No retransmissions so far */
+ qmsg->aid = aid;
+ qmsg->type = ntoh8(packet->gtp0.h.type);
+ }
+ gsn->seq_next++; /* Count up this time */
+ return 0;
+}
+
+/* gtp_conf
+ * Remove signalling packet from retransmission queue.
+ * return 0 on success, EOF if packet was not found */
+
+int gtp_conf(struct gsn_t *gsn, int version, struct sockaddr_in *peer,
+ union gtp_packet *packet, int len, uint8_t *type, void **aid) {
+ int seq = ntoh16(packet->gtp0.h.seq);
+
+ if (queue_freemsg_seq(gsn->queue_req, peer, seq, type, aid)) {
+ gsn->err_seq++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, packet, len,
+ "Confirmation packet not found in queue");
+ return EOF;
+ }
+
+ return 0;
+}
+
+int gtp_retrans(struct gsn_t *gsn) {
+ /* Retransmit any outstanding packets */
+ /* Remove from queue if maxretrans exceeded */
+ time_t now;
+ struct qmsg_t *qmsg;
+ now = time(NULL);
+ /*printf("Retrans: New beginning %d\n", (int) now);*/
+
+ while ((!queue_getfirst(gsn->queue_req, &qmsg)) &&
+ (qmsg->timeout <= now)) {
+ /*printf("Retrans timeout found: %d\n", (int) time(NULL));*/
+ if (qmsg->retrans > 3) { /* To many retrans */
+ if (gsn->cb_conf) gsn->cb_conf(qmsg->type, EOF, NULL, qmsg->aid);
+ queue_freemsg(gsn->queue_req, qmsg);
+ }
+ else {
+ if (sendto(gsn->fd, &qmsg->p, qmsg->l, 0,
+ (struct sockaddr *) &qmsg->peer, sizeof(struct sockaddr_in)) < 0) {
+ gsn->err_sendto++;
+ gtp_err(LOG_ERR, __FILE__, __LINE__, "Sendto(fd=%d, msg=%lx, len=%d) failed: Error = %s", gsn->fd, (unsigned long) &qmsg->p, qmsg->l, strerror(errno));
+ }
+ queue_back(gsn->queue_req, qmsg);
+ qmsg->timeout = now + 3;
+ qmsg->retrans++;
+ }
+ }
+
+ /* Also clean up reply timeouts */
+ while ((!queue_getfirst(gsn->queue_resp, &qmsg)) &&
+ (qmsg->timeout < now)) {
+ /*printf("Retrans (reply) timeout found: %d\n", (int) time(NULL));*/
+ queue_freemsg(gsn->queue_resp, qmsg);
+ }
+
+ return 0;
+}
+
+int gtp_retranstimeout(struct gsn_t *gsn, struct timeval *timeout) {
+ time_t now, later;
+ struct qmsg_t *qmsg;
+
+ if (queue_getfirst(gsn->queue_req, &qmsg)) {
+ timeout->tv_sec = 10;
+ timeout->tv_usec = 0;
+ }
+ else {
+ now = time(NULL);
+ later = qmsg->timeout;
+ timeout->tv_sec = later - now;
+ timeout->tv_usec = 0;
+ if (timeout->tv_sec < 0) timeout->tv_sec = 0; /* No negative allowed */
+ if (timeout->tv_sec > 10) timeout->tv_sec = 10; /* Max sleep for 10 sec*/
+ }
+ return 0;
+}
+
+int gtp_resp(int version, struct gsn_t *gsn, union gtp_packet *packet,
+ int len, struct sockaddr_in *peer) {
+ struct qmsg_t *qmsg;
+ uint16_t seq;
+
+ seq = ntoh16(packet->gtp0.h.seq);
+
+ /* print message */
+ /*
+ printf("gtp_resp: to %s:UDP%u\n",
+ inet_ntoa(peer->sin_addr),
+ ntohs(peer->sin_port));
+ print_packet(packet, len);
+ */
+
+ if (sendto(gsn->fd, packet, len, 0,
+ (struct sockaddr *) peer, sizeof(struct sockaddr_in)) < 0) {
+ gsn->err_sendto++;
+ gtp_err(LOG_ERR, __FILE__, __LINE__, "Sendto(fd=%d, msg=%lx, len=%d) failed: Error = %s", gsn->fd, (unsigned long) &packet, len, strerror(errno));
+ return -1;
+ }
+
+ /* Use new queue structure */
+ if (queue_newmsg(gsn->queue_resp, &qmsg, peer, seq)) {
+ gsn->err_queuefull++;
+ gtp_err(LOG_ERR, __FILE__, __LINE__, "Retransmit queue is full");
+ }
+ else {
+ memcpy(&qmsg->p, packet, sizeof(union gtp_packet));
+ qmsg->l = len;
+ qmsg->timeout = time(NULL) + 60; /* When to timeout */
+ qmsg->retrans = 0; /* No retransmissions so far */
+ qmsg->aid = NULL;
+ qmsg->type = 0;
+ }
+ return 0;
+}
+
+int gtp_dublicate(struct gsn_t *gsn, int version,
+ struct sockaddr_in *peer, uint16_t seq) {
+ struct qmsg_t *qmsg;
+
+ if(queue_seqget(gsn->queue_resp, &qmsg, peer, seq)) {
+ return EOF; /* Notfound */
+ }
+ else {
+ /* print message */
+
+ /*printf("gtp_dublicate: to %s:UDP%u\n",
+ inet_ntoa(peer->sin_addr),
+ ntohs(peer->sin_port));
+ print_packet(&qmsg->p, qmsg->l);
+ */
+ if (sendto(gsn->fd, &qmsg->p, qmsg->l, 0,
+ (struct sockaddr *) peer, sizeof(struct sockaddr_in)) < 0) {
+ gsn->err_sendto++;
+ gtp_err(LOG_ERR, __FILE__, __LINE__, "Sendto(fd=%d, msg=%lx, len=%d) failed: Error = %s", gsn->fd, (unsigned long) &qmsg->p, qmsg->l, strerror(errno));
+ }
+ return 0;
+ }
+}
+
+
+
+/* Perform restoration and recovery error handling as described in 29.060 */
+static void log_restart(struct gsn_t *gsn) {
+ FILE *f;
+ int i;
+ int counter = 0;
+ char filename[NAMESIZE];
+
+ filename[NAMESIZE-1] = 0; /* No null term. guarantee by strncpy */
+ strncpy(filename, gsn->statedir, NAMESIZE-1);
+ strncat(filename, RESTART_FILE,
+ NAMESIZE-1-sizeof(RESTART_FILE));
+
+ i = umask(022);
+
+ /* We try to open file. On failure we will later try to create file */
+ if (!(f = fopen(filename, "r"))) {
+ gtp_err(LOG_ERR, __FILE__, __LINE__, "fopen(path=%s, mode=%s) failed: Error = %s", filename, "r", strerror(errno));
+ }
+ else {
+ umask(i);
+ fscanf(f, "%d", &counter);
+ if (fclose(f)) {
+ gtp_err(LOG_ERR, __FILE__, __LINE__, "fclose failed: Error = %s", strerror(errno));
+ }
+ }
+
+ gsn->restart_counter = (unsigned char) counter;
+ gsn->restart_counter++;
+
+ if (!(f = fopen(filename, "w"))) {
+ gtp_err(LOG_ERR, __FILE__, __LINE__, "fopen(path=%s, mode=%s) failed: Error = %s", filename, "w", strerror(errno));
+ return;
+ }
+
+ umask(i);
+ fprintf(f, "%d\n", gsn->restart_counter);
+ if (fclose(f)) {
+ gtp_err(LOG_ERR, __FILE__, __LINE__, "fclose failed: Error = %s", strerror(errno));
+ return;
+ }
+}
+
+
+
+int gtp_new(struct gsn_t **gsn, char *statedir, struct in_addr *listen)
+{
+ struct sockaddr_in addr;
+ int gtp_fd;
+
+ syslog(LOG_ERR, "GTP: gtp_newgsn() started");
+
+ *gsn = calloc(sizeof(struct gsn_t), 1); /* TODO */
+
+ (*gsn)->statedir = statedir;
+ log_restart(*gsn);
+
+ /* Initialise request retransmit queue */
+ queue_new(&(*gsn)->queue_req);
+ queue_new(&(*gsn)->queue_resp);
+
+ /* Initialise pdp table */
+ pdp_init();
+
+ /* Initialise call back functions */
+ (*gsn)->cb_create_context = 0;
+ (*gsn)->cb_delete_context = 0;
+ (*gsn)->cb_conf = 0;
+ (*gsn)->cb_gpdu = 0;
+
+ if ((gtp_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
+ (*gsn)->err_socket++;
+ gtp_err(LOG_ERR, __FILE__, __LINE__, "socket(domain=%d, type=%d, protocol=%d) failed: Error = %s", AF_INET, SOCK_DGRAM, 0, strerror(errno));
+ return -1;
+ }
+ (*gsn)->fd = gtp_fd;
+
+ /* syslog(LOG_ERR, "GTP: gtp_init() after socket");*/
+
+ (*gsn)->gsnc = *listen;
+ (*gsn)->gsnu = *listen;
+
+ memset(&addr, 0, sizeof(addr));
+
+ addr.sin_family = AF_INET;
+ /* addr.sin_addr = *inetaddr; */
+ addr.sin_addr = *listen; /* Same IP for user traffic and signalling*/
+ addr.sin_port = htons(GTP0_PORT);
+
+ if (bind(gtp_fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+ (*gsn)->err_socket++;
+ gtp_err(LOG_ERR, __FILE__, __LINE__, "bind(fd=%d, addr=%lx, len=%d) failed: Error = %s", gtp_fd, (unsigned long) &addr, sizeof(addr), strerror(errno));
+ return -1;
+ }
+
+ /* Initialise "standard" GTP0 header */
+ memset(&gtp0_default, 0, sizeof(gtp0_default));
+ gtp0_default.flags=0x1e;
+ gtp0_default.spare1=0xff;
+ gtp0_default.spare2=0xff;
+ gtp0_default.spare3=0xff;
+ gtp0_default.number=0xff;
+
+ /* Initialise "standard" GTP1 header */
+ memset(&gtp1_default, 0, sizeof(gtp1_default));
+ gtp0_default.flags=0x1e;
+
+ return 0;
+}
+
+int gtp_free(struct gsn_t *gsn) {
+
+ /* Clean up retransmit queues */
+ queue_free(gsn->queue_req);
+ queue_free(gsn->queue_resp);
+
+ free(gsn);
+ return 0;
+}
+
+/* ***********************************************************
+ * Path management messages
+ * Messages: echo and version not supported.
+ * A path is connection between two UDP/IP endpoints
+ *
+ * A path is either using GTP0 or GTP1. A path can be
+ * established by any kind of GTP message??
+
+ * Which source port to use?
+ * GTP-C request destination port is 2123/3386
+ * GTP-U request destination port is 2152/3386
+ * T-PDU destination port is 2152/3386.
+ * For the above messages the source port is locally allocated.
+ * For response messages src=rx-dst and dst=rx-src.
+ * For simplicity we should probably use 2123+2152/3386 as
+ * src port even for the cases where src can be locally
+ * allocated. This also means that we have to listen only to
+ * the same ports.
+ * For response messages we need to be able to respond to
+ * the relevant src port even if it is locally allocated by
+ * the peer.
+ *
+ * The need for path management!
+ * We might need to keep a list of active paths. This might
+ * be in the form of remote IP address + UDP port numbers.
+ * (We will consider a path astablished if we have a context
+ * with the node in question)
+ *************************************************************/
+
+/* Send off an echo request */
+int gtp_echo_req(struct gsn_t *gsn, struct in_addr *inetaddr)
+{
+ union gtp_packet packet;
+
+ get_default_gtp(0, &packet);
+ packet.gtp0.h.type = hton8(GTP_ECHO_REQ);
+ packet.gtp0.h.length = hton16(0);
+
+ return gtp_req(gsn, 0, &packet, GTP0_HEADER_SIZE, inetaddr, NULL);
+}
+
+/* Send of an echo reply */
+int gtp_echo_resp(struct gsn_t *gsn, struct sockaddr_in *peer,
+ void *pack, unsigned len)
+{
+ union gtp_packet packet;
+ int length = 0;
+
+ get_default_gtp(0, &packet);
+
+ gtpie_tv1(packet.gtp0.p, &length, GTP_MAX, GTPIE_RECOVERY,
+ gsn->restart_counter);
+
+ packet.gtp0.h.type = hton8(GTP_ECHO_RSP);
+ packet.gtp0.h.length = hton16(length);
+ packet.gtp0.h.seq = ((union gtp_packet*)pack)->gtp0.h.seq;
+
+ return gtp_resp(0, gsn, &packet, GTP0_HEADER_SIZE+length, peer);
+}
+
+
+/* Handle a received echo request */
+int gtp_echo_ind(struct gsn_t *gsn, struct sockaddr_in *peer,
+ void *pack, unsigned len) {
+
+ uint16_t seq = ntoh16(((union gtp_packet*)pack)->gtp0.h.seq);
+
+ if(!gtp_dublicate(gsn, 0, peer, seq)) {
+ return 0; /* We allready send of response once */
+ }
+
+
+ /* Now send off a reply to the peer */
+ return gtp_echo_resp(gsn, peer, pack, len);
+}
+
+/* Handle a received echo reply */
+int gtp_echo_conf(struct gsn_t *gsn, struct sockaddr_in *peer,
+ void *pack, unsigned len) {
+ union gtpie_member *ie[GTPIE_SIZE];
+ unsigned char recovery;
+ void *aid = NULL;
+ uint8_t type = 0;
+
+ /* Remove packet from queue */
+ if (gtp_conf(gsn, 0, peer, pack, len, &type, &aid)) return EOF;
+
+ if (gtpie_decaps(ie, pack+sizeof(struct gtp0_header), len-sizeof(struct gtp0_header))) {
+ gsn->invalid++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Invalid message format");
+ return EOF;
+ }
+
+ if (gtpie_gettv1(ie, GTPIE_RECOVERY, 0, &recovery)) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing mandatory field");
+ return EOF;
+ }
+
+ if (gsn->cb_conf) gsn->cb_conf(type, 0, NULL, aid); /* TODO: Should return recovery in callback */
+
+ return 0;
+}
+
+/* Send off a Version Not Supported message */
+/* This message is somewhat special in that it actually is a
+ * response to some other message with unsupported GTP version
+ * For this reason it has parameters like a response, and does
+ * its own message transmission. No signalling queue is used
+ * The reply is sent to the peer IP and peer UDP. This means that
+ * the peer will be receiving a GTP0 message on a GTP1 port!
+ * In practice however this will never happen as a GTP0 GSN will
+ * only listen to the GTP0 port, and therefore will never receive
+ * anything else than GTP0 */
+
+int gtp_unsup_resp(struct gsn_t *gsn, struct sockaddr_in *peer,
+ void *pack, unsigned len)
+{
+ union gtp_packet packet;
+ int length = 0;
+
+ get_default_gtp(0, &packet);
+ packet.gtp0.h.type = hton8(GTP_NOT_SUPPORTED);
+ packet.gtp0.h.length = hton16(0);
+
+ return gtp_resp(0, gsn, &packet, GTP0_HEADER_SIZE+length, peer);
+}
+
+/* Handle a Version Not Supported message */
+int gtp_unsup_conf(struct gsn_t *gsn, struct sockaddr_in *peer, void *pack, unsigned len) {
+
+ /* TODO: Need to check the validity of header and information elements */
+ /* TODO: Implement callback to application */
+ /* As long as we only support GTP0 we should never receive this message */
+ /* Should be implemented as part of GTP1 support */
+
+ /* print received message */
+ /*
+ printf("gtp_unsup_ind: from %s:UDP%u\n",
+ inet_ntoa(peer->sin_addr),
+ ntohs(peer->sin_port));
+ print_packet(pack, len);
+ */
+ return 0;
+}
+
+/* ***********************************************************
+ * Session management messages
+ * Messages: create, update and delete PDP context
+ *
+ * Information storage
+ * Information storage for each PDP context is defined in
+ * 23.060 section 13.3. Includes IMSI, MSISDN, APN, PDP-type,
+ * PDP-address (IP address), sequence numbers, charging ID.
+ * For the SGSN it also includes radio related mobility
+ * information.
+ *************************************************************/
+
+/* Send Create PDP Context Request */
+extern int gtp_create_pdp_req(struct gsn_t *gsn, int version, void *aid,
+ struct in_addr* inetaddr, struct pdp_t *pdp) {
+ union gtp_packet packet;
+ int length = 0;
+
+ get_default_gtp(0, &packet);
+
+ if (0==0) { /* Always GTP0 */
+
+ gtpie_tv0(packet.gtp0.p, &length, GTP_MAX, GTPIE_QOS_PROFILE0,
+ sizeof(pdp->qos_req0), pdp->qos_req0);
+ gtpie_tv1(packet.gtp0.p, &length, GTP_MAX, GTPIE_RECOVERY,
+ gsn->restart_counter);
+ gtpie_tv1(packet.gtp0.p, &length, GTP_MAX, GTPIE_SELECTION_MODE,
+ pdp->selmode);
+ gtpie_tv2(packet.gtp0.p, &length, GTP_MAX, GTPIE_FL_DI,
+ pdp->fllu);
+ gtpie_tv2(packet.gtp0.p, &length, GTP_MAX, GTPIE_FL_C,
+ pdp->fllc);
+ gtpie_tlv(packet.gtp0.p, &length, GTP_MAX, GTPIE_EUA,
+ pdp->eua.l, pdp->eua.v);
+ gtpie_tlv(packet.gtp0.p, &length, GTP_MAX, GTPIE_APN,
+ pdp->apn_use.l, pdp->apn_use.v);
+
+ if (pdp->pco_req.l) { /* Optional PCO */
+ gtpie_tlv(packet.gtp0.p, &length, GTP_MAX, GTPIE_PCO,
+ pdp->pco_req.l, pdp->pco_req.v);
+ }
+
+ gtpie_tlv(packet.gtp0.p, &length, GTP_MAX, GTPIE_GSN_ADDR,
+ pdp->gsnlc.l, pdp->gsnlc.v);
+ gtpie_tlv(packet.gtp0.p, &length, GTP_MAX, GTPIE_GSN_ADDR,
+ pdp->gsnlu.l, pdp->gsnlu.v);
+ gtpie_tlv(packet.gtp0.p, &length, GTP_MAX, GTPIE_MSISDN,
+ pdp->msisdn.l, pdp->msisdn.v);
+
+
+
+ } else { /* GTP1 */
+ gtpie_tv0(packet.gtp1s.p, &length, GTP_MAX, GTPIE_IMSI,
+ sizeof(pdp->imsi), (uint8_t*) &pdp->imsi);
+ gtpie_tv1(packet.gtp1s.p, &length, GTP_MAX, GTPIE_RECOVERY,
+ gsn->restart_counter);
+ gtpie_tv1(packet.gtp1s.p, &length, GTP_MAX, GTPIE_SELECTION_MODE,
+ pdp->selmode);
+ gtpie_tv4(packet.gtp1s.p, &length, GTP_MAX, GTPIE_TEI_DI,
+ pdp->teid_own);
+ gtpie_tv4(packet.gtp1s.p, &length, GTP_MAX, GTPIE_TEI_C,
+ pdp->teic_own);
+ gtpie_tv1(packet.gtp1s.p, &length, GTP_MAX, GTPIE_NSAPI,
+ pdp->nsapi);
+ /*gtpie_tv1(packet.gtp1s.p, &length, GTP_MAX, GTPIE_NSAPI,
+ pdp->nsapil); For use by several QoS profiles for the same address */
+ gtpie_tv2(packet.gtp1s.p, &length, GTP_MAX, GTPIE_CHARGING_C,
+ pdp->cch_pdp);
+ gtpie_tv2(packet.gtp1s.p, &length, GTP_MAX, GTPIE_TRACE_REF,
+ pdp->traceref);
+ gtpie_tv2(packet.gtp1s.p, &length, GTP_MAX, GTPIE_TRACE_TYPE,
+ pdp->tracetype);
+ gtpie_tlv(packet.gtp1s.p, &length, GTP_MAX, GTPIE_EUA,
+ pdp->eua.l, pdp->eua.v);
+ gtpie_tlv(packet.gtp1s.p, &length, GTP_MAX, GTPIE_APN,
+ pdp->apn_use.l, pdp->apn_use.v);
+ gtpie_tlv(packet.gtp1s.p, &length, GTP_MAX, GTPIE_PCO,
+ pdp->pco_req.l, pdp->pco_req.v);
+ gtpie_tlv(packet.gtp1s.p, &length, GTP_MAX, GTPIE_GSN_ADDR,
+ pdp->gsnlc.l, pdp->gsnlc.v);
+ gtpie_tlv(packet.gtp1s.p, &length, GTP_MAX, GTPIE_GSN_ADDR,
+ pdp->gsnlu.l, pdp->gsnlu.v);
+ gtpie_tlv(packet.gtp1s.p, &length, GTP_MAX, GTPIE_MSISDN,
+ pdp->msisdn.l, pdp->msisdn.v);
+ gtpie_tlv(packet.gtp1s.p, &length, GTP_MAX, GTPIE_QOS_PROFILE,
+ pdp->qos_req.l, pdp->qos_req.v);
+ gtpie_tlv(packet.gtp1s.p, &length, GTP_MAX, GTPIE_TFT,
+ pdp->tft.l, pdp->tft.v);
+ gtpie_tlv(packet.gtp1s.p, &length, GTP_MAX, GTPIE_TRIGGER_ID,
+ pdp->triggerid.l, pdp->triggerid.v);
+ gtpie_tlv(packet.gtp1s.p, &length, GTP_MAX, GTPIE_OMC_ID,
+ pdp->omcid.l, pdp->omcid.v);
+ }
+ packet.gtp0.h.type = hton8(GTP_CREATE_PDP_REQ);
+ packet.gtp0.h.length = hton16(length);
+ packet.gtp0.h.flow = 0;
+ packet.gtp0.h.tid = pdp->tid;
+
+ gtp_req(gsn, 0, &packet, GTP0_HEADER_SIZE+length, inetaddr, aid);
+
+ return 0;
+}
+
+/* Send Create PDP Context Response */
+int gtp_create_pdp_resp(struct gsn_t *gsn, int version,
+ struct sockaddr_in *peer,
+ void *pack, unsigned len,
+ struct pdp_t *pdp, uint8_t cause)
+{
+ union gtp_packet packet;
+ int length = 0;
+
+ get_default_gtp(0, &packet);
+
+ gtpie_tv1(packet.gtp0.p, &length, GTP_MAX, GTPIE_CAUSE, cause);
+
+ if (cause == GTPCAUSE_ACC_REQ) {
+ gtpie_tv0(packet.gtp0.p, &length, GTP_MAX, GTPIE_QOS_PROFILE0,
+ sizeof(pdp->qos_neg0), pdp->qos_neg0);
+ gtpie_tv1(packet.gtp0.p, &length, GTP_MAX, GTPIE_REORDER,
+ pdp->reorder);
+ gtpie_tv1(packet.gtp0.p, &length, GTP_MAX, GTPIE_RECOVERY,
+ gsn->restart_counter);
+ gtpie_tv2(packet.gtp0.p, &length, GTP_MAX, GTPIE_FL_DI,
+ pdp->fllu);
+ gtpie_tv2(packet.gtp0.p, &length, GTP_MAX, GTPIE_FL_C,
+ pdp->fllc);
+ gtpie_tv4(packet.gtp0.p, &length, GTP_MAX, GTPIE_CHARGING_ID,
+ 0x12345678);
+ gtpie_tlv(packet.gtp0.p, &length, GTP_MAX, GTPIE_EUA,
+ pdp->eua.l, pdp->eua.v);
+
+ if (pdp->pco_neg.l) { /* Optional PCO */
+ gtpie_tlv(packet.gtp0.p, &length, GTP_MAX, GTPIE_PCO,
+ pdp->pco_neg.l, pdp->pco_neg.v);
+ }
+
+ gtpie_tlv(packet.gtp0.p, &length, GTP_MAX, GTPIE_GSN_ADDR,
+ pdp->gsnlc.l, pdp->gsnlc.v);
+ gtpie_tlv(packet.gtp0.p, &length, GTP_MAX, GTPIE_GSN_ADDR,
+ pdp->gsnlu.l, pdp->gsnlu.v);
+ }
+
+ packet.gtp0.h.type = hton8(GTP_CREATE_PDP_RSP);
+ packet.gtp0.h.length = hton16(length);
+ packet.gtp0.h.flow = hton16(pdp->flrc);
+ packet.gtp0.h.seq = ((union gtp_packet*)pack)->gtp0.h.seq;
+ packet.gtp0.h.tid = ((union gtp_packet*)pack)->gtp0.h.tid;
+
+ return gtp_resp(0, gsn, &packet, GTP0_HEADER_SIZE+length, peer);
+}
+
+/* Handle Create PDP Context Request */
+int gtp_create_pdp_ind(struct gsn_t *gsn, int version,
+ struct sockaddr_in *peer, void *pack, unsigned len) {
+ struct pdp_t *pdp, *pdp_old;
+ struct pdp_t pdp_buf;
+ union gtpie_member* ie[GTPIE_SIZE];
+ uint8_t recovery;
+ uint64_t imsi;
+ uint8_t nsapi;
+ int auth = 0; /* Allow access if no callback is defined */
+
+ uint16_t seq = ntoh16(((union gtp_packet*)pack)->gtp0.h.seq);
+
+ if(!gtp_dublicate(gsn, 0, peer, seq)) {
+ return 0; /* We allready send of response once */
+ }
+
+ /* Decode information elements */
+ if (gtpie_decaps(ie, pack+GTP0_HEADER_SIZE, len-GTP0_HEADER_SIZE)) {
+ gsn->invalid++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Invalid message format");
+ if (0 == version)
+ return EOF;
+ else
+ return gtp_create_pdp_resp(gsn, version, peer, pack, len, pdp,
+ GTPCAUSE_INVALID_MESSAGE);
+ }
+
+ pdp = &pdp_buf;
+ memset(pdp, 0, sizeof(struct pdp_t));
+
+ /* Extract IMSI and NSAPI from header */
+ imsi = ((union gtp_packet*)pack)->gtp0.h.tid & 0x0fffffffffffffff;
+ nsapi = (((union gtp_packet*)pack)->gtp0.h.tid & 0xf000000000000000) >> 60;
+
+ /* pdp_newpdp(&pdp, imsi, nsapi); TODO: Need to remove again */
+
+ if (gtpie_gettv0(ie, GTPIE_QOS_PROFILE0, 0,
+ pdp->qos_req0, sizeof(pdp->qos_req0))) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing mandatory information field");
+ return gtp_create_pdp_resp(gsn, version, peer, pack, len, pdp,
+ GTPCAUSE_MAN_IE_MISSING);
+ }
+
+ /* Extract recovery (optional) */
+ if (!gtpie_gettv1(ie, GTPIE_RECOVERY, 0, &recovery)) {
+ /* TODO: Handle received recovery IE */
+ }
+
+ if (gtpie_gettv0(ie, GTPIE_SELECTION_MODE, 0,
+ &pdp->selmode, sizeof(pdp->selmode))) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing mandatory information field");
+ return gtp_create_pdp_resp(gsn, version, peer, pack, len, pdp,
+ GTPCAUSE_MAN_IE_MISSING);
+ }
+
+ if (gtpie_gettv2(ie, GTPIE_FL_DI, 0, &pdp->flru)) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing mandatory information field");
+ return gtp_create_pdp_resp(gsn, version, peer, pack, len, pdp,
+ GTPCAUSE_MAN_IE_MISSING);
+ }
+
+ if (gtpie_gettv2(ie, GTPIE_FL_C, 0, &pdp->flrc)) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing mandatory information field");
+ return gtp_create_pdp_resp(gsn, version, peer, pack, len, pdp,
+ GTPCAUSE_MAN_IE_MISSING);
+ }
+
+ if (gtpie_gettlv(ie, GTPIE_EUA, 0, &pdp->eua.l,
+ &pdp->eua.v, sizeof(pdp->eua.v))) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing mandatory information field");
+ return gtp_create_pdp_resp(gsn, version, peer, pack, len, pdp,
+ GTPCAUSE_MAN_IE_MISSING);
+ }
+
+ if (gtpie_gettlv(ie, GTPIE_APN, 0, &pdp->apn_req.l,
+ &pdp->apn_req.v, sizeof(pdp->apn_req.v))) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing mandatory information field");
+ return gtp_create_pdp_resp(gsn, version, peer, pack, len, pdp,
+ GTPCAUSE_MAN_IE_MISSING);
+ }
+
+ /* Extract protocol configuration options (optional) */
+ if (!gtpie_gettlv(ie, GTPIE_PCO, 0, &pdp->pco_req.l,
+ &pdp->pco_req.v, sizeof(pdp->pco_req.v))) {
+ /* TODO: Handle PCO IE */
+ }
+
+ if (gtpie_gettlv(ie, GTPIE_GSN_ADDR, 0, &pdp->gsnrc.l,
+ &pdp->gsnrc.v, sizeof(pdp->gsnrc.v))) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing mandatory information field");
+ return gtp_create_pdp_resp(gsn, version, peer, pack, len, pdp,
+ GTPCAUSE_MAN_IE_MISSING);
+ }
+
+ if (gtpie_gettlv(ie, GTPIE_GSN_ADDR, 1, &pdp->gsnru.l,
+ &pdp->gsnru.v, sizeof(pdp->gsnru.v))) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing mandatory information field");
+ return gtp_create_pdp_resp(gsn, version, peer, pack, len, pdp,
+ GTPCAUSE_MAN_IE_MISSING);
+ }
+
+ if (gtpie_gettlv(ie, GTPIE_MSISDN, 0, &pdp->msisdn.l,
+ &pdp->msisdn.v, sizeof(pdp->msisdn.v))) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing mandatory information field");
+ return gtp_create_pdp_resp(gsn, version, peer, pack, len, pdp,
+ GTPCAUSE_MAN_IE_MISSING);
+ }
+
+ in_addr2gsna(&pdp->gsnlc, &gsn->gsnc);
+ in_addr2gsna(&pdp->gsnlu, &gsn->gsnu);
+
+ if (!pdp_tidget(&pdp_old, ((union gtp_packet*)pack)->gtp0.h.tid)) {
+ /* Found old pdp with same tid. Now the voodoo begins! */
+ /* We check that the APN, selection mode and MSISDN is the same */
+ if ( (pdp->apn_req.l == pdp_old->apn_req.l)
+ && (!memcmp(pdp->apn_req.v, pdp_old->apn_req.v, pdp->apn_req.l))
+ && (pdp->selmode == pdp_old->selmode)
+ && (pdp->msisdn.l == pdp_old->msisdn.l)
+ && (!memcmp(pdp->msisdn.v, pdp_old->msisdn.v, pdp->msisdn.l))) {
+ /* OK! We are dealing with the same APN. We will copy new
+ * parameters to the old pdp and send off confirmation
+ * We ignore the following information elements:
+ * QoS: MS will get originally negotiated QoS.
+ * End user address (EUA). MS will get old EUA anyway.
+ * Protocol configuration option (PCO): Only application can verify */
+
+ /* Copy remote flow label */
+ pdp_old->flru = pdp->flru;
+ pdp_old->flrc = pdp->flrc;
+
+ /* Copy peer GSN address */
+ pdp_old->gsnrc.l = pdp->gsnrc.l;
+ memcpy(&pdp_old->gsnrc.v, &pdp->gsnrc.v, pdp->gsnrc.l);
+ pdp_old->gsnru.l = pdp->gsnru.l;
+ memcpy(&pdp_old->gsnru.v, &pdp->gsnru.v, pdp->gsnru.l);
+
+ /* pdp_freepdp(pdp); not nessasary anymore since never allocated */
+ pdp = pdp_old;
+
+ /* Confirm to peer that things were "successful" */
+ return gtp_create_pdp_resp(gsn, version, peer, pack, len, pdp,
+ GTPCAUSE_ACC_REQ);
+ }
+ else { /* This is not the same PDP context. Delete the old one. */
+
+ if (gsn->cb_delete_context) gsn->cb_delete_context(pdp_old);
+ pdp_freepdp(pdp_old);
+
+ }
+ }
+
+ pdp_newpdp(&pdp, imsi, nsapi, pdp);
+
+ /* Callback function to validata login */
+ if (gsn->cb_create_context !=0)
+ auth = gsn->cb_create_context(pdp);
+
+ /* Now send off a reply to the peer */
+ if (!auth) {
+ return gtp_create_pdp_resp(gsn, version, peer, pack, len, pdp,
+ GTPCAUSE_ACC_REQ);
+ }
+ else {
+ gtp_create_pdp_resp(gsn, version, peer, pack, len, pdp,
+ GTPCAUSE_USER_AUTH_FAIL);
+ pdp_freepdp(pdp);
+ return 0;
+ }
+}
+
+
+/* Handle Create PDP Context Response */
+int gtp_create_pdp_conf(struct gsn_t *gsn, int version,
+ struct sockaddr_in *peer,
+ void *pack, unsigned len) {
+ struct pdp_t *pdp;
+ union gtpie_member *ie[GTPIE_SIZE];
+ uint8_t cause, recovery;
+ void *aid = NULL;
+ uint8_t type = 0;
+
+ /* Remove packet from queue */
+ if (gtp_conf(gsn, 0, peer, pack, len, &type, &aid)) return EOF;
+
+ /* Find the context in question */
+ if (pdp_getgtp0(&pdp, ntoh16(((union gtp_packet*)pack)->gtp0.h.flow))) {
+ gsn->err_unknownpdp++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Unknown PDP context");
+ if (gsn->cb_conf) gsn->cb_conf(type, EOF, NULL, aid);
+ return EOF;
+ }
+
+ /* Decode information elements */
+ if (gtpie_decaps(ie, pack+GTP0_HEADER_SIZE, len-GTP0_HEADER_SIZE)) {
+ gsn->invalid++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Invalid message format");
+ if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, aid);
+ return EOF;
+ }
+
+ /* Extract cause value (mandatory) */
+ if (gtpie_gettv1(ie, GTPIE_CAUSE, 0, &cause)) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing mandatory information field");
+ if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, aid);
+ return EOF;
+ }
+
+ /* Extract recovery (optional) */
+ if (!gtpie_gettv1(ie, GTPIE_RECOVERY, 0, &recovery)) {
+ /* TODO: Handle received recovery IE */
+ }
+
+ /* Extract protocol configuration options (optional) */
+ if (!gtpie_gettlv(ie, GTPIE_PCO, 0, &pdp->pco_req.l,
+ &pdp->pco_req.v, sizeof(pdp->pco_req.v))) {
+ /* TODO: Handle PCO IE */
+ }
+
+ /* Check all conditional information elements */
+ if (GTPCAUSE_ACC_REQ == cause) {
+
+ if (gtpie_gettv0(ie, GTPIE_QOS_PROFILE0, 0, /* TODO: HACK only gtp0 */
+ &pdp->qos_neg0, sizeof(pdp->qos_neg0))) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing conditional information field");
+ if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, aid);
+ return EOF;
+ }
+ /* pdp->qos_neg.l = 3; * TODO: HACK only gtp0 */
+
+ if (gtpie_gettv1(ie, GTPIE_REORDER, 0, &pdp->reorder)) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing conditional information field");
+ if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, aid);
+ return EOF;
+ }
+
+ if (gtpie_gettv2(ie, GTPIE_FL_DI, 0, &pdp->flru)) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing conditional information field");
+ if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, aid);
+ return EOF;
+ }
+
+ if (gtpie_gettv2(ie, GTPIE_FL_C, 0, &pdp->flrc)) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing conditional information field");
+ if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, aid);
+ return EOF;
+ }
+
+ if (gtpie_gettv4(ie, GTPIE_CHARGING_ID, 0, &pdp->cid)) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing conditional information field");
+ if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, aid);
+ return gtp_create_pdp_resp(gsn, version, peer, pack, len, pdp,
+ GTPCAUSE_MAN_IE_MISSING);
+ }
+
+ if (gtpie_gettlv(ie, GTPIE_EUA, 0, &pdp->eua.l,
+ &pdp->eua.v, sizeof(pdp->eua.v))) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing conditional information field");
+ if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, aid);
+ return EOF;
+ }
+
+ if (gtpie_gettlv(ie, GTPIE_GSN_ADDR, 0, &pdp->gsnrc.l,
+ &pdp->gsnrc.v, sizeof(pdp->gsnrc.v))) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing conditional information field");
+ if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, aid);
+ return EOF;
+ }
+
+ if (gtpie_gettlv(ie, GTPIE_GSN_ADDR, 1, &pdp->gsnru.l,
+ &pdp->gsnru.v, sizeof(pdp->gsnru.v))) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing conditional information field");
+ if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, aid);
+ return EOF;
+ }
+ }
+
+ if (gsn->cb_conf) gsn->cb_conf(type, cause, pdp, aid);
+
+ return 0;
+}
+
+/* Send Update PDP Context Request */
+extern int gtp_update_pdp_req(struct gsn_t *gsn, int version, void *aid,
+ struct in_addr* inetaddr, struct pdp_t *pdp) {
+ union gtp_packet packet;
+ int length = 0;
+
+ get_default_gtp(0, &packet);
+
+ gtpie_tv0(packet.gtp0.p, &length, GTP_MAX, GTPIE_QOS_PROFILE0,
+ sizeof(pdp->qos_req0), pdp->qos_req0);
+ gtpie_tv1(packet.gtp0.p, &length, GTP_MAX, GTPIE_RECOVERY,
+ gsn->restart_counter);
+ gtpie_tv2(packet.gtp0.p, &length, GTP_MAX, GTPIE_FL_DI,
+ pdp->fllu);
+ gtpie_tv2(packet.gtp0.p, &length, GTP_MAX, GTPIE_FL_C,
+ pdp->fllc);
+ gtpie_tlv(packet.gtp0.p, &length, GTP_MAX, GTPIE_GSN_ADDR,
+ pdp->gsnlc.l, pdp->gsnlc.v);
+ gtpie_tlv(packet.gtp0.p, &length, GTP_MAX, GTPIE_GSN_ADDR,
+ pdp->gsnlu.l, pdp->gsnlu.v);
+
+ packet.gtp0.h.type = hton8(GTP_UPDATE_PDP_REQ);
+ packet.gtp0.h.length = hton16(length);
+ packet.gtp0.h.flow = 0;
+ packet.gtp0.h.tid = (pdp->imsi & 0x0fffffffffffffff) + ((uint64_t)pdp->nsapi << 60);
+
+ return gtp_req(gsn, 0, &packet, GTP0_HEADER_SIZE+length, inetaddr, aid);
+}
+
+/* Send Update PDP Context Response */
+int gtp_update_pdp_resp(struct gsn_t *gsn, int version,
+ struct sockaddr_in *peer,
+ void *pack, unsigned len,
+ struct pdp_t *pdp, uint8_t cause)
+{
+ union gtp_packet packet;
+ int length = 0;
+
+ get_default_gtp(0, &packet);
+
+ gtpie_tv1(packet.gtp0.p, &length, GTP_MAX, GTPIE_CAUSE, cause);
+
+ if (cause == GTPCAUSE_ACC_REQ) {
+ gtpie_tv0(packet.gtp0.p, &length, GTP_MAX, GTPIE_QOS_PROFILE0,
+ sizeof(pdp->qos_sub0), pdp->qos_sub0);
+ gtpie_tv1(packet.gtp0.p, &length, GTP_MAX, GTPIE_RECOVERY,
+ gsn->restart_counter);
+ gtpie_tv2(packet.gtp0.p, &length, GTP_MAX, GTPIE_FL_DI,
+ pdp->fllu);
+ gtpie_tv2(packet.gtp0.p, &length, GTP_MAX, GTPIE_FL_C,
+ pdp->fllc);
+ gtpie_tv4(packet.gtp0.p, &length, GTP_MAX, GTPIE_CHARGING_ID,
+ 0x12345678);
+ gtpie_tlv(packet.gtp0.p, &length, GTP_MAX, GTPIE_GSN_ADDR,
+ pdp->gsnlc.l, pdp->gsnlc.v);
+ gtpie_tlv(packet.gtp0.p, &length, GTP_MAX, GTPIE_GSN_ADDR,
+ pdp->gsnlu.l, pdp->gsnlu.v);
+ }
+
+ packet.gtp0.h.type = hton8(GTP_UPDATE_PDP_RSP);
+ packet.gtp0.h.length = hton16(length);
+ packet.gtp0.h.flow = hton16(pdp->flrc);
+ packet.gtp0.h.seq = ((union gtp_packet*)pack)->gtp0.h.seq;
+ packet.gtp0.h.tid = (pdp->imsi & 0x0fffffffffffffff) + ((uint64_t)pdp->nsapi << 60);
+
+ return gtp_resp(0, gsn, &packet, GTP0_HEADER_SIZE+length, peer);
+}
+
+/* Handle Update PDP Context Request */
+int gtp_update_pdp_ind(struct gsn_t *gsn, int version,
+ struct sockaddr_in *peer, void *pack, unsigned len) {
+ struct pdp_t *pdp, *pdp2;
+ struct pdp_t pdp_buf;
+ union gtpie_member* ie[GTPIE_SIZE];
+ uint8_t recovery;
+
+ uint16_t seq = ntoh16(((union gtp_packet*)pack)->gtp0.h.seq);
+
+ /* Is this a dublicate ? */
+ if(!gtp_dublicate(gsn, 0, peer, seq)) {
+ return 0; /* We allready send of response once */
+ }
+
+ /* Find the pdp context in question */
+ if (pdp_getgtp0(&pdp, ntoh16(((union gtp_packet*)pack)->gtp0.h.flow))) {
+ gsn->err_unknownpdp++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Unknown PDP context");
+ return gtp_update_pdp_resp(gsn, version, peer, pack, len, NULL,
+ GTPCAUSE_NON_EXIST);
+ }
+
+ /* Decode information elements */
+ if (gtpie_decaps(ie, pack+GTP0_HEADER_SIZE, len-GTP0_HEADER_SIZE)) {
+ gsn->invalid++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Invalid message format");
+ if (0 == version)
+ return EOF;
+ else
+ return gtp_update_pdp_resp(gsn, version, peer, pack, len, pdp,
+ GTPCAUSE_INVALID_MESSAGE);
+ }
+
+ pdp2 = &pdp_buf;
+ memcpy(pdp2, pdp, sizeof (struct pdp_t)); /* Generate local copy */
+
+ if (gtpie_gettv0(ie, GTPIE_QOS_PROFILE0, 0, /* TODO: HACK only gtp0 */
+ &pdp2->qos_req0, sizeof(pdp2->qos_req0))) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing mandatory information field");
+ return gtp_update_pdp_resp(gsn, version, peer, pack, len, pdp2,
+ GTPCAUSE_MAN_IE_MISSING);
+ }
+ /* pdp2->qos_req.l = 3; * TODO: HACK only gtp0 */
+
+ /* Extract recovery (optional) */
+ if (!gtpie_gettv1(ie, GTPIE_RECOVERY, 0, &recovery)) {
+ /* TODO: Handle received recovery IE */
+ }
+
+ if (gtpie_gettv2(ie, GTPIE_FL_DI, 0, &pdp2->flru)) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing mandatory information field");
+ return gtp_update_pdp_resp(gsn, version, peer, pack, len, pdp2,
+ GTPCAUSE_MAN_IE_MISSING);
+ }
+
+ if (gtpie_gettv2(ie, GTPIE_FL_C, 0, &pdp2->flrc)) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing mandatory information field");
+ return gtp_update_pdp_resp(gsn, version, peer, pack, len, pdp2,
+ GTPCAUSE_MAN_IE_MISSING);
+ }
+
+ if (gtpie_gettlv(ie, GTPIE_GSN_ADDR, 0, &pdp2->gsnrc.l,
+ &pdp2->gsnrc.v, sizeof(pdp2->gsnrc.v))) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing mandatory information field");
+ return gtp_update_pdp_resp(gsn, version, peer, pack, len, pdp2,
+ GTPCAUSE_MAN_IE_MISSING);
+ }
+
+ if (gtpie_gettlv(ie, GTPIE_GSN_ADDR, 1, &pdp2->gsnru.l,
+ &pdp2->gsnru.v, sizeof(pdp2->gsnru.v))) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing mandatory information field");
+ return gtp_update_pdp_resp(gsn, version, peer, pack, len, pdp2,
+ GTPCAUSE_MAN_IE_MISSING);
+ }
+
+ /* OK! It seames as if we received a valid message */
+
+ memcpy(pdp, pdp2, sizeof (struct pdp_t)); /* Update original pdp */
+
+ /* Confirm to peer that things were "successful" */
+ return gtp_update_pdp_resp(gsn, version, peer, pack, len, pdp,
+ GTPCAUSE_ACC_REQ);
+}
+
+
+/* Handle Update PDP Context Response */
+int gtp_update_pdp_conf(struct gsn_t *gsn, int version,
+ struct sockaddr_in *peer,
+ void *pack, unsigned len) {
+ struct pdp_t *pdp;
+ union gtpie_member *ie[GTPIE_SIZE];
+ uint8_t cause, recovery;
+ void *aid = NULL;
+ uint8_t type = 0;
+
+ /* Remove packet from queue */
+ if (gtp_conf(gsn, 0, peer, pack, len, &type, &aid)) return EOF;
+
+ /* Find the context in question */
+ if (pdp_getgtp0(&pdp, ntoh16(((union gtp_packet*)pack)->gtp0.h.flow))) {
+ gsn->err_unknownpdp++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Unknown PDP context");
+ if (gsn->cb_conf) gsn->cb_conf(type, cause, NULL, aid);
+ return EOF;
+ }
+
+ /* Decode information elements */
+ if (gtpie_decaps(ie, pack+GTP0_HEADER_SIZE, len-GTP0_HEADER_SIZE)) {
+ gsn->invalid++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Invalid message format");
+ if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, aid);
+ if (gsn->cb_delete_context) gsn->cb_delete_context(pdp);
+ pdp_freepdp(pdp);
+ return EOF;
+ }
+
+ /* Extract cause value (mandatory) */
+ if (gtpie_gettv1(ie, GTPIE_CAUSE, 0, &cause)) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing mandatory information field");
+ if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, aid);
+ if (gsn->cb_delete_context) gsn->cb_delete_context(pdp);
+ pdp_freepdp(pdp);
+ return EOF;
+ }
+
+ /* Extract recovery (optional) */
+ if (!gtpie_gettv1(ie, GTPIE_RECOVERY, 0, &recovery)) {
+ /* TODO: Handle received recovery IE */
+ }
+
+ /* Check all conditional information elements */
+ if (GTPCAUSE_ACC_REQ != cause) {
+ if (gsn->cb_conf) gsn->cb_conf(type, cause, pdp, aid);
+ if (gsn->cb_delete_context) gsn->cb_delete_context(pdp);
+ pdp_freepdp(pdp);
+ return 0;
+ }
+ else {
+ /* Check for missing conditionary information elements */
+ if (!(gtpie_exist(ie, GTPIE_QOS_PROFILE0, 0) &&
+ gtpie_exist(ie, GTPIE_REORDER, 0) &&
+ gtpie_exist(ie, GTPIE_FL_DI, 0) &&
+ gtpie_exist(ie, GTPIE_FL_C, 0) &&
+ gtpie_exist(ie, GTPIE_CHARGING_ID, 0) &&
+ gtpie_exist(ie, GTPIE_EUA, 0) &&
+ gtpie_exist(ie, GTPIE_GSN_ADDR, 0) &&
+ gtpie_exist(ie, GTPIE_GSN_ADDR, 1))) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing conditional information field");
+ if (gsn->cb_conf) gsn->cb_conf(type, EOF, pdp, aid);
+ if (gsn->cb_delete_context) gsn->cb_delete_context(pdp);
+ pdp_freepdp(pdp);
+ return EOF;
+ }
+
+ /* Update pdp with new values */
+ gtpie_gettv0(ie, GTPIE_QOS_PROFILE0, 0,
+ pdp->qos_neg0, sizeof(pdp->qos_neg0));
+ gtpie_gettv1(ie, GTPIE_REORDER, 0, &pdp->reorder);
+ gtpie_gettv2(ie, GTPIE_FL_DI, 0, &pdp->flru);
+ gtpie_gettv2(ie, GTPIE_FL_C, 0, &pdp->flrc);
+ gtpie_gettv4(ie, GTPIE_CHARGING_ID, 0, &pdp->cid);
+ gtpie_gettlv(ie, GTPIE_EUA, 0, &pdp->eua.l,
+ &pdp->eua.v, sizeof(pdp->eua.v));
+ gtpie_gettlv(ie, GTPIE_GSN_ADDR, 0, &pdp->gsnrc.l,
+ &pdp->gsnrc.v, sizeof(pdp->gsnrc.v));
+ gtpie_gettlv(ie, GTPIE_GSN_ADDR, 1, &pdp->gsnru.l,
+ &pdp->gsnru.v, sizeof(pdp->gsnru.v));
+
+ if (gsn->cb_conf) gsn->cb_conf(type, cause, pdp, aid);
+ return 0; /* Succes */
+ }
+}
+
+/* Send Delete PDP Context Request */
+extern int gtp_delete_pdp_req(struct gsn_t *gsn, int version, void *aid,
+ struct pdp_t *pdp) {
+ union gtp_packet packet;
+ int length = 0;
+ struct in_addr addr;
+
+ if (gsna2in_addr(&addr, &pdp->gsnrc)) {
+ gsn->err_address++;
+ gtp_err(LOG_ERR, __FILE__, __LINE__, "GSN address conversion failed");
+ return EOF;
+ }
+
+ get_default_gtp(0, &packet);
+
+ packet.gtp0.h.type = hton8(GTP_DELETE_PDP_REQ);
+ packet.gtp0.h.length = hton16(length);
+ packet.gtp0.h.flow = hton16(pdp->flrc);
+ packet.gtp0.h.tid = (pdp->imsi & 0x0fffffffffffffff) + ((uint64_t)pdp->nsapi << 60);
+
+ return gtp_req(gsn, 0, &packet, GTP0_HEADER_SIZE+length, &addr, aid);
+}
+
+/* Send Delete PDP Context Response */
+int gtp_delete_pdp_resp(struct gsn_t *gsn, int version,
+ struct sockaddr_in *peer,
+ void *pack, unsigned len,
+ struct pdp_t *pdp, uint8_t cause)
+{
+ union gtp_packet packet;
+ int length = 0;
+ uint16_t flow = 0;
+
+ if (pdp) flow = hton16(pdp->flrc);
+
+ get_default_gtp(0, &packet);
+
+ gtpie_tv1(packet.gtp0.p, &length, GTP_MAX, GTPIE_CAUSE, cause);
+
+ packet.gtp0.h.type = hton8(GTP_DELETE_PDP_RSP);
+ packet.gtp0.h.length = hton16(length);
+ packet.gtp0.h.flow = flow;
+ packet.gtp0.h.seq = ((union gtp_packet*)pack)->gtp0.h.seq;
+ packet.gtp0.h.tid = ((union gtp_packet*)pack)->gtp0.h.tid;
+
+ if (pdp) {
+ /* Callback function to allow application to clean up */
+ if (gsn->cb_delete_context) gsn->cb_delete_context(pdp);
+ pdp_freepdp(pdp); /* Clean up PDP context */
+ }
+
+ return gtp_resp(0, gsn, &packet, GTP0_HEADER_SIZE+length, peer);
+}
+
+/* Handle Delete PDP Context Request */
+int gtp_delete_pdp_ind(struct gsn_t *gsn, int version,
+ struct sockaddr_in *peer, void *pack, unsigned len) {
+ struct pdp_t *pdp;
+ union gtpie_member* ie[GTPIE_SIZE];
+ uint16_t seq = ntoh16(((union gtp_packet*)pack)->gtp0.h.seq);
+
+ /* Is this a dublicate ? */
+ if(!gtp_dublicate(gsn, 0, peer, seq)) {
+ return 0;
+ }
+
+ /* Find the pdp context in question */
+ if (pdp_getgtp0(&pdp, ntoh16(((union gtp_packet*)pack)->gtp0.h.flow))) {
+ gsn->err_unknownpdp++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Unknown PDP context");
+ if (0 == version)
+ return gtp_delete_pdp_resp(gsn, version, peer, pack, len, NULL,
+ GTPCAUSE_ACC_REQ);
+ else
+ return gtp_delete_pdp_resp(gsn, version, peer, pack, len, NULL,
+ GTPCAUSE_NON_EXIST);
+ }
+
+ /* Decode information elements */
+ if (gtpie_decaps(ie, pack+GTP0_HEADER_SIZE, len-GTP0_HEADER_SIZE)) {
+ gsn->invalid++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Invalid message format");
+ if (0 == version)
+ return EOF;
+ else
+ return gtp_delete_pdp_resp(gsn, version, peer, pack, len, pdp,
+ GTPCAUSE_INVALID_MESSAGE);
+ }
+
+ return gtp_delete_pdp_resp(gsn, version, peer, pack, len, pdp,
+ GTPCAUSE_ACC_REQ);
+}
+
+
+/* Handle Delete PDP Context Response */
+int gtp_delete_pdp_conf(struct gsn_t *gsn, int version,
+ struct sockaddr_in *peer,
+ void *pack, unsigned len) {
+ struct pdp_t *pdp;
+ union gtpie_member *ie[GTPIE_SIZE];
+ uint8_t cause;
+ void *aid = NULL;
+ uint8_t type = 0;
+
+ /* Remove packet from queue */
+ if (gtp_conf(gsn, 0, peer, pack, len, &type, &aid)) return EOF;
+
+ /* Find the context in question */
+ if (pdp_getgtp0(&pdp, ntoh16(((union gtp_packet*)pack)->gtp0.h.flow))) {
+ gsn->err_unknownpdp++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Unknown PDP context");
+ return EOF;
+ }
+
+ /* Decode information elements */
+ if (gtpie_decaps(ie, pack+GTP0_HEADER_SIZE, len-GTP0_HEADER_SIZE)) {
+ gsn->invalid++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Invalid message format");
+ return EOF;
+ }
+
+ /* Extract cause value */
+ if (gtpie_gettv1(ie, GTPIE_CAUSE, 0, &cause)) {
+ gsn->missing++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Missing mandatory information field");
+ return EOF;
+ }
+
+ /* Check the cause value */
+ if ((GTPCAUSE_ACC_REQ != cause) && (GTPCAUSE_NON_EXIST != cause)) {
+ gsn->err_cause++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Unexpected cause value received: %d", cause);
+ return EOF;
+ }
+
+ /* Callback function to allow application to clean up */
+ if (gsn->cb_conf) gsn->cb_conf(type, cause, pdp, aid);
+
+ if (gsn->cb_delete_context) gsn->cb_delete_context(pdp);
+ pdp_freepdp(pdp);
+
+ return 0;
+}
+
+/* Send Error Indication (response to a GPDU message */
+int gtp_error_ind_resp(struct gsn_t *gsn, int version,
+ struct sockaddr_in *peer,
+ void *pack, unsigned len)
+{
+ union gtp_packet packet;
+ int length = 0;
+
+ get_default_gtp(0, &packet);
+
+ packet.gtp0.h.type = hton8(GTP_ERROR);
+ packet.gtp0.h.length = hton16(length);
+ packet.gtp0.h.flow = 0;
+ packet.gtp0.h.seq = ((union gtp_packet*)pack)->gtp0.h.seq;
+ packet.gtp0.h.tid = ((union gtp_packet*)pack)->gtp0.h.tid;
+
+ return gtp_resp(0, gsn, &packet, GTP0_HEADER_SIZE+length, peer);
+}
+
+/* Handle Error Indication */
+int gtp_error_ind_conf(struct gsn_t *gsn, int version,
+ struct sockaddr_in *peer,
+ void *pack, unsigned len) {
+ struct pdp_t *pdp;
+
+ /* Find the context in question */
+ if (pdp_tidget(&pdp, ((union gtp_packet*)pack)->gtp0.h.tid)) {
+ gsn->err_unknownpdp++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Unknown PDP context");
+ return EOF;
+ }
+
+ gsn->err_unknownpdp++; /* TODO: Change counter */
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Received Error Indication");
+
+ if (gsn->cb_delete_context) gsn->cb_delete_context(pdp);
+ pdp_freepdp(pdp);
+ return 0;
+}
+
+int gtp_gpdu_ind(struct gsn_t *gsn, int version,
+ struct sockaddr_in *peer,
+ void *pack,
+ unsigned len) {
+
+ /* Need to include code to verify packet src and dest addresses */
+ struct pdp_t *pdp;
+
+ if (pdp_getgtp0(&pdp, ntoh16(((union gtp_packet*)pack)->gtp0.h.flow))) {
+ gsn->err_unknownpdp++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, peer, pack, len,
+ "Unknown PDP context");
+ return gtp_error_ind_resp(gsn, version, peer, pack, len);
+
+ }
+
+ /* Callback function */
+ if (gsn->cb_gpdu !=0)
+ return gsn->cb_gpdu(pdp, pack+20, len-20); /* TODO ???? */
+
+ return 0;
+}
+
+
+/* Receives GTP packet and sends off for further processing
+ * Function will check the validity of the header. If the header
+ * is not valid the packet is either dropped or a version not
+ * supported is returned to the peer.
+ * TODO: Need to decide on return values! */
+int gtp_decaps(struct gsn_t *gsn)
+{
+ unsigned char buffer[PACKET_MAX + 64 /*TODO: ip header */ ];
+ int status, ip_len = 0;
+ struct sockaddr_in peer;
+ int peerlen;
+ struct gtp0_header *pheader;
+ int version = 0; /* GTP version should be determined from header!*/
+
+ peerlen = sizeof(peer);
+ if ((status =
+ recvfrom(gsn->fd, buffer, sizeof(buffer), 0,
+ (struct sockaddr *) &peer, &peerlen)) < 0 ) {
+ gsn->err_readfrom++;
+ gtp_err(LOG_ERR, __FILE__, __LINE__, "recvfrom(fd=%d, buffer=%lx, len=%d) failed: status = %d error = %s", gsn->fd, (unsigned long) buffer, sizeof(buffer), status, status ? strerror(errno) : "No error");
+ return -1;
+ }
+
+ /* Strip off IP header, if present: TODO Is this nessesary? */
+ if ((buffer[0] & 0xF0) == 0x40) {
+ ip_len = (buffer[0] & 0xF) * 4;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, &peer, buffer, status,
+ "IP header found in return from read");
+ return -1;
+ }
+
+ /* Need at least 1 byte in order to check version */
+ if (status < (1)) {
+ gsn->empty++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, &peer, buffer, status,
+ "Discarding packet - too small");
+ return -1;
+ }
+
+ /* TODO: Remove these ERROR MESSAGES
+ gtp_err(LOG_ERR, __FILE__, __LINE__, "Discarding packet - too small");
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, &peer, buffer, status,
+ "Discarding packet - too small"); */
+
+ pheader = (struct gtp0_header *) (buffer + ip_len);
+
+ /* Version should be gtp0 (or earlier in theory) */
+ if (((pheader->flags & 0xe0) > 0x00)) {
+ gsn->unsup++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, &peer, buffer, status,
+ "Unsupported GTP version");
+ return gtp_unsup_resp(gsn, &peer, buffer, status); /* 29.60: 11.1.1 */
+ }
+
+ /* Check length of gtp0 packet */
+ if (((pheader->flags & 0xe0) == 0x00) && (status < GTP0_HEADER_SIZE)) {
+ gsn->tooshort++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, &peer, buffer, status,
+ "GTP0 packet too short");
+ return -1; /* Silently discard 29.60: 11.1.2 */
+ }
+
+ switch (pheader->type) {
+ case GTP_ECHO_REQ:
+ return gtp_echo_ind(gsn, &peer, buffer+ip_len, status - ip_len);
+ case GTP_ECHO_RSP:
+ return gtp_echo_conf(gsn, &peer, buffer+ip_len, status - ip_len);
+ case GTP_NOT_SUPPORTED:
+ return gtp_unsup_conf(gsn, &peer, buffer+ip_len, status - ip_len);
+ case GTP_CREATE_PDP_REQ:
+ return gtp_create_pdp_ind(gsn, version, &peer, buffer+ip_len,
+ status - ip_len);
+ case GTP_CREATE_PDP_RSP:
+ return gtp_create_pdp_conf(gsn, version, &peer, buffer+ip_len,
+ status - ip_len);
+ case GTP_UPDATE_PDP_REQ:
+ return gtp_update_pdp_ind(gsn, version, &peer, buffer+ip_len,
+ status - ip_len);
+ case GTP_UPDATE_PDP_RSP:
+ return gtp_update_pdp_conf(gsn, version, &peer, buffer+ip_len,
+ status - ip_len);
+ case GTP_DELETE_PDP_REQ:
+ return gtp_delete_pdp_ind(gsn, version, &peer, buffer+ip_len,
+ status - ip_len);
+ case GTP_DELETE_PDP_RSP:
+ return gtp_delete_pdp_conf(gsn, version, &peer, buffer+ip_len,
+ status - ip_len);
+ case GTP_ERROR:
+ return gtp_error_ind_conf(gsn, version, &peer, buffer+ip_len,
+ status - ip_len);
+ case GTP_GPDU:
+ return gtp_gpdu_ind(gsn, version, &peer, buffer+ip_len, status - ip_len);
+ default:
+ {
+ gsn->unknown++;
+ gtp_errpack(LOG_ERR, __FILE__, __LINE__, &peer, buffer, status,
+ "Unknown GTP message type received");
+ return -1;
+ }
+ }
+}
+
+int gtp_gpdu(struct gsn_t *gsn, struct pdp_t* pdp,
+ void *pack, unsigned len)
+{
+ union gtp_packet packet;
+ struct sockaddr_in addr;
+
+ /*printf("gtp_encaps start\n");
+ print_packet(pack, len);*/
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+
+ memcpy(&addr.sin_addr, pdp->gsnru.v,pdp->gsnru.l); /* TODO range check */
+ addr.sin_port = htons(GTP0_PORT);
+
+ get_default_gtp(0, &packet);
+ packet.gtp0.h.type = hton8(GTP_GPDU);
+ packet.gtp0.h.length = hton16(len);
+ packet.gtp0.h.seq = hton16(pdp->gtpsntx++);
+ packet.gtp0.h.flow = hton16(pdp->flru);
+ packet.gtp0.h.tid = (pdp->imsi & 0x0fffffffffffffff) + ((uint64_t)pdp->nsapi << 60);
+
+ if (len > sizeof (union gtp_packet) - sizeof(struct gtp0_header)) {
+ gsn->err_memcpy++;
+ gtp_err(LOG_ERR, __FILE__, __LINE__,
+ "Memcpy failed");
+ return EOF;
+ }
+
+ memcpy(packet.gtp0.p, pack, len); /* TODO Should be avoided! */
+
+ if (sendto(gsn->fd, &packet, GTP0_HEADER_SIZE+len, 0,
+ (struct sockaddr *) &addr, sizeof(addr)) < 0) {
+ gsn->err_sendto++;
+ gtp_err(LOG_ERR, __FILE__, __LINE__, "Sendto(fd=%d, msg=%lx, len=%d) failed: Error = %s", gsn->fd, (unsigned long) &packet, GTP0_HEADER_SIZE+len, strerror(errno));
+ return EOF;
+ }
+ return 0;
+}
+
+
+/* ***********************************************************
+ * Conversion functions
+ *************************************************************/
+
+int char2ul_t(char* src, struct ul_t dst) {
+ dst.l = strlen(src)+1;
+ dst.v = malloc(dst.l);
+ dst.v[0] = dst.l - 1;
+ memcpy(&dst.v[1], src, dst.v[0]);
+ return 0;
+}
+
+/* ***********************************************************
+ * IP address conversion functions
+ * There exist several types of address representations:
+ * - eua: End User Address. (29.060, 7.7.27, message type 128)
+ * Used for signalling address to mobile station. Supports IPv4
+ * IPv6 x.25 etc. etc.
+ * - gsna: GSN Address. (29.060, 7.7.32, message type 133): IP address
+ * of GSN. If length is 4 it is IPv4. If length is 16 it is IPv6.
+ * - in_addr: IPv4 address struct.
+ * - sockaddr_in: Socket API representation of IP address and
+ * port number.
+ *************************************************************/
+
+int ipv42eua(struct ul66_t *eua, struct in_addr *src) {
+ eua->v[0] = 0xf1; /* IETF */
+ eua->v[1] = 0x21; /* IPv4 */
+ if (src) {
+ eua->l = 6;
+ memcpy(&eua->v[2], src, 4);
+ }
+ else
+ {
+ eua->l = 2;
+ }
+ return 0;
+}
+
+int eua2ipv4(struct in_addr *dst, struct ul66_t *eua) {
+ if ((eua->l != 6) ||
+ (eua->v[0] != 0xf1) ||
+ (eua->v[1] = 0x21))
+ return -1; /* Not IPv4 address*/
+ memcpy(dst, &eua->v[2], 4);
+ return 0;
+}
+
+int gsna2in_addr(struct in_addr *dst, struct ul16_t *gsna) {
+ memset(dst, 0, sizeof(struct in_addr));
+ if (gsna->l != 4) return EOF; /* Return if not IPv4 */
+ memcpy(dst, gsna->v, gsna->l);
+ return 0;
+}
+
+int in_addr2gsna(struct ul16_t *gsna, struct in_addr *src) {
+ memset(gsna, 0, sizeof(struct ul16_t));
+ gsna->l = 4;
+ memcpy(gsna->v, src, gsna->l);
+ return 0;
+}
+
diff --git a/gtp/gtp.h b/gtp/gtp.h
new file mode 100644
index 0000000..2a4e57a
--- /dev/null
+++ b/gtp/gtp.h
@@ -0,0 +1,339 @@
+/*
+ * OpenGGSN - Gateway GPRS Support Node
+ * Copyright (C) 2002 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.
+ *
+ * The initial developer of the original code is
+ * Jens Jakobsen <jj@openggsn.org>
+ *
+ * Contributor(s):
+ *
+ */
+
+#ifndef _GTP_H
+#define _GTP_H
+
+#define GTP0_PORT 3386
+#define GTP1C_PORT 2123
+#define GTP1U_PORT 2152
+#define PACKET_MAX 8196
+
+#define GTP_MAX 0xffff /* TODO: Choose right number */
+#define GTP0_HEADER_SIZE 20
+#define GTP1_HEADER_SIZE_SHORT 8
+#define GTP1_HEADER_SIZE_LONG 12
+
+#define SYSLOG_PRINTSIZE 255
+#define ERRMSG_SIZE 255
+
+#define RESTART_FILE "gsn_restart"
+#define NAMESIZE 1024
+
+/* GTP version 1 message type definitions. Also covers version 0 except *
+ * for anonymous PDP context which was superceded in version 1 */
+
+/* 0 For future use. */
+#define GTP_ECHO_REQ 1 /* Echo Request */
+#define GTP_ECHO_RSP 2 /* Echo Response */
+#define GTP_NOT_SUPPORTED 3 /* Version Not Supported */
+#define GTP_ALIVE_REQ 4 /* Node Alive Request */
+#define GTP_ALIVE_RSP 5 /* Node Alive Response */
+#define GTP_REDIR_REQ 6 /* Redirection Request */
+#define GTP_REDIR_RSP 7 /* Redirection Response */
+/* 8-15 For future use. */
+#define GTP_CREATE_PDP_REQ 16 /* Create PDP Context Request */
+#define GTP_CREATE_PDP_RSP 17 /* Create PDP Context Response */
+#define GTP_UPDATE_PDP_REQ 18 /* Update PDP Context Request */
+#define GTP_UPDATE_PDP_RSP 19 /* Update PDP Context Response */
+#define GTP_DELETE_PDP_REQ 20 /* Delete PDP Context Request */
+#define GTP_DELETE_PDP_RSP 21 /* Delete PDP Context Response */
+/* 22-25 For future use. */ /* In version GTP 1 anonomous PDP context */
+#define GTP_ERROR 26 /* Error Indication */
+#define GTP_PDU_NOT_REQ 27 /* PDU Notification Request */
+#define GTP_PDU_NOT_RSP 28 /* PDU Notification Response */
+#define GTP_PDU_NOT_REJ_REQ 29 /* PDU Notification Reject Request */
+#define GTP_PDU_NOT_REJ_RSP 30 /* PDU Notification Reject Response */
+#define GTP_SUPP_EXT_HEADER 31 /* Supported Extension Headers Notification */
+#define GTP_SND_ROUTE_REQ 32 /* Send Routeing Information for GPRS Request */
+#define GTP_SND_ROUTE_RSP 33 /* Send Routeing Information for GPRS Response */
+#define GTP_FAILURE_REQ 34 /* Failure Report Request */
+#define GTP_FAILURE_RSP 35 /* Failure Report Response */
+#define GTP_MS_PRESENT_REQ 36 /* Note MS GPRS Present Request */
+#define GTP_MS_PRESENT_RSP 37 /* Note MS GPRS Present Response */
+/* 38-47 For future use. */
+#define GTP_IDEN_REQ 48 /* Identification Request */
+#define GTP_IDEN_RSP 49 /* Identification Response */
+#define GTP_SGSN_CONTEXT_REQ 50 /* SGSN Context Request */
+#define GTP_SGSN_CONTEXT_RSP 51 /* SGSN Context Response */
+#define GTP_SGSN_CONTEXT_ACK 52 /* SGSN Context Acknowledge */
+#define GTP_FWD_RELOC_REQ 53 /* Forward Relocation Request */
+#define GTP_FWD_RELOC_RSP 54 /* Forward Relocation Response */
+#define GTP_FWD_RELOC_COMPL 55 /* Forward Relocation Complete */
+#define GTP_RELOC_CANCEL_REQ 56 /* Relocation Cancel Request */
+#define GTP_RELOC_CANCEL_RSP 57 /* Relocation Cancel Response */
+#define GTP_FWD_SRNS 58 /* Forward SRNS Context */
+#define GTP_FWD_RELOC_ACK 59 /* Forward Relocation Complete Acknowledge */
+#define GTP_FWD_SRNS_ACK 60 /* Forward SRNS Context Acknowledge */
+/* 61-239 For future use. */
+#define GTP_DATA_TRAN_REQ 240 /* Data Record Transfer Request */
+#define GTP_DATA_TRAN_RSP 241 /* Data Record Transfer Response */
+/* 242-254 For future use. */
+#define GTP_GPDU 255 /* G-PDU */
+
+/* GTP 0 header.
+ * Explanation to some of the fields:
+ * SNDCP NPDU Number flag = 0 except for inter SGSN handover situations
+ * SNDCP N-PDU LCC Number 0 = 0xff except for inter SGSN handover situations
+ * Sequence number. Used for reliable delivery of signalling messages, and
+ * to discard "illegal" data messages.
+ * Flow label. Is used to point a particular PDP context. Is used in data
+ * messages as well as signalling messages related to a particular context.
+ * Tunnel ID is IMSI+NSAPI. Unique identifier of PDP context. Is somewhat
+ * redundant because the header also includes flow. */
+
+struct gtp0_header { /* Descriptions from 3GPP 09.60 */
+ u_int8_t flags; /* 01 bitfield, with typical values */
+ /* 000..... Version: 1 (0) */
+ /* ...1111. Spare (7) */
+ /* .......0 SNDCP N-PDU Number flag (0) */
+ u_int8_t type; /* 02 Message type. T-PDU = 0xff */
+ u_int16_t length; /* 03 Length (of G-PDU excluding header) */
+ u_int16_t seq; /* 05 Sequence Number */
+ u_int16_t flow; /* 07 Flow Label ( = 0 for signalling) */
+ u_int8_t number; /* 09 SNDCP N-PDU LCC Number ( 0 = 0xff) */
+ u_int8_t spare1; /* 10 Spare */
+ u_int8_t spare2; /* 11 Spare */
+ u_int8_t spare3; /* 12 Spare */
+ u_int64_t tid; /* 13 Tunnel ID */
+}; /* 20 */
+
+struct gtp1_header_short { /* Descriptions from 3GPP 29060 */
+ u_int8_t flags; /* 01 bitfield, with typical values */
+ /* 000..... Version: 1 */
+ /* ...1.... Protocol Type: GTP=1, GTP'=0 */
+ /* ....1... Spare = 1 */
+ /* .....1.. Extension header flag: 1 */
+ /* ......1. Sequence number flag: 1 */
+ /* .......0 PN: N-PDU Number flag */
+ u_int8_t type; /* 02 Message type. T-PDU = 0xff */
+ u_int16_t length; /* 03 Length (of IP packet or signalling) */
+ u_int64_t tid; /* 05 - 08 Tunnel ID */
+};
+
+struct gtp1_header_long { /* Descriptions from 3GPP 29060 */
+ u_int8_t flags; /* 01 bitfield, with typical values */
+ /* 000..... Version: 1 */
+ /* ...1.... Protocol Type: GTP=1, GTP'=0 */
+ /* ....1... Spare = 1 */
+ /* .....1.. Extension header flag: 1 */
+ /* ......1. Sequence number flag: 1 */
+ /* .......0 PN: N-PDU Number flag */
+ u_int8_t type; /* 02 Message type. T-PDU = 0xff */
+ u_int16_t length; /* 03 Length (of IP packet or signalling) */
+ u_int64_t tid; /* 05 Tunnel ID */
+ u_int16_t seq; /* 10 Sequence Number */
+ u_int8_t npdu; /* 11 N-PDU Number */
+ u_int8_t next; /* 12 Next extension header type. Empty = 0 */
+};
+
+struct gtp0_packet {
+ struct gtp0_header h;
+ u_int8_t p[GTP_MAX];
+} __attribute__((packed));
+
+struct gtp1_packet_short {
+ struct gtp1_header_short h;
+ u_int8_t p[GTP_MAX];
+} __attribute__((packed));
+
+struct gtp1_packet_long {
+ struct gtp1_header_long h;
+ u_int8_t p[GTP_MAX];
+} __attribute__((packed));
+
+union gtp_packet {
+ u_int8_t flags;
+ struct gtp0_packet gtp0;
+ struct gtp1_packet_short gtp1s;
+ struct gtp1_packet_long gtp1l;
+} __attribute__((packed)) h;
+
+
+
+
+/* ***********************************************************
+ * Information storage for each gsn instance
+ *
+ * Normally each instance of the application corresponds to
+ * one instance of a gsn.
+ *
+ * In order to avoid global variables in the application, and
+ * also in order to allow several instances of a gsn in the same
+ * application this struct is provided in order to store all
+ * relevant information related to the gsn.
+ *
+ * Note that this does not include information storage for '
+ * each pdp context. This is stored in another struct.
+ *************************************************************/
+
+struct gsn_t {
+ /* Parameters related to the network interface */
+
+ int fd; /* File descriptor to network interface */
+ struct in_addr gsnc; /* IP address of this gsn for signalling */
+ struct in_addr gsnu; /* IP address of this gsn for user traffic */
+
+ /* Parameters related to signalling messages */
+ uint16_t seq_next; /* Next sequence number to use */
+ int seq_first; /* First packet in queue (oldest timeout) */
+ int seq_last; /* Last packet in queue (youngest timeout) */
+
+ unsigned char restart_counter; /* Increment on restart. Stored on disk */
+ char *statedir; /* Disk location for permanent storage */
+
+ struct queue_t *queue_req; /* Request queue */
+ struct queue_t *queue_resp; /* Response queue */
+
+ /* Call back functions */
+ int (*cb_delete_context) (struct pdp_t*);
+ int (*cb_create_context) (struct pdp_t*);
+ int (*cb_conf) (int type, int cause, struct pdp_t *pdp, void* aid);
+ int (*cb_gpdu) (struct pdp_t* pdp, void* pack, unsigned len);
+
+ /* Counters */
+
+ uint64_t err_socket; /* Number of socket errors */
+ uint64_t err_readfrom; /* Number of readfrom errors */
+ uint64_t err_sendto; /* Number of sendto errors */
+ uint64_t err_memcpy; /* Number of memcpy */
+ uint64_t err_queuefull; /* Number of times queue was full */
+ uint64_t err_seq; /* Number of seq out of range */
+ uint64_t err_address; /* GSN address conversion failed */
+ uint64_t err_unknownpdp; /* GSN address conversion failed */
+ uint64_t err_unknowntid; /* Application supplied unknown imsi+nsapi */
+ uint64_t err_cause; /* Unexpected cause value received */
+ uint64_t err_outofpdp; /* Out of storage for PDP contexts */
+
+ uint64_t empty; /* Number of empty packets */
+ uint64_t unsup; /* Number of unsupported version 29.60 11.1.1 */
+ uint64_t tooshort; /* Number of too short headers 29.60 11.1.2 */
+ uint64_t unknown; /* Number of unknown messages 29.60 11.1.3 */
+ uint64_t unexpect; /* Number of unexpected messages 29.60 11.1.4 */
+ uint64_t dublicate; /* Number of dublicate or unsolicited replies */
+ uint64_t missing; /* Number of missing mandatory field messages */
+ uint64_t invalid; /* Number of invalid message format messages */
+};
+
+
+/* External API functions */
+
+extern const char* gtp_version();
+extern int gtp_new(struct gsn_t **gsn, char *statedir, struct in_addr *listen);
+extern int gtp_free(struct gsn_t *gsn);
+
+extern int gtp_newpdp(struct gsn_t *gsn, struct pdp_t **pdp,
+ uint64_t imsi, uint8_t nsapi);
+extern int gtp_freepdp(struct gsn_t *gsn, struct pdp_t *pdp);
+
+extern int gtp_create_context(struct gsn_t *gsn, struct pdp_t *pdp, void *aid,
+ struct in_addr* inetaddr);
+extern int gtp_update_context(struct gsn_t *gsn, struct pdp_t *pdp, void *aid,
+ struct in_addr* inetaddr);
+extern int gtp_delete_context(struct gsn_t *gsn, struct pdp_t *pdp, void *aid);
+
+extern int gtp_gpdu(struct gsn_t *gsn, struct pdp_t *pdp,
+ void *pack, unsigned len);
+
+extern int gtp_fd(struct gsn_t *gsn);
+extern int gtp_decaps(struct gsn_t *gsn);
+extern int gtp_retrans(struct gsn_t *gsn);
+extern int gtp_retranstimeout(struct gsn_t *gsn, struct timeval *timeout);
+
+/*
+extern int gtp_set_cb_newpdp(struct gsn_t *gsn,
+ int (*cb) (struct pdp_t*));
+extern int gtp_set_cb_freepdp(struct gsn_t *gsn,
+ int (*cb) (struct pdp_t*));
+extern int gtp_set_cb_create_pdp_ind(struct gsn_t *gsn,
+ int (*cb) (struct pdp_t*));
+extern int gtp_set_cb_create_pdp_conf(struct gsn_t *gsn,
+ int (*cb) (struct pdp_t*, int));
+extern int gtp_set_cb_update_pdp_conf(struct gsn_t *gsn,
+ int (*cb) (struct pdp_t*, int, int));
+extern int gtp_set_cb_delete_pdp_ind(struct gsn_t *gsn,
+ int (*cb) (struct pdp_t*));
+extern int gtp_set_cb_delete_pdp_conf(struct gsn_t *gsn,
+ int (*cb) (struct pdp_t*, int));
+*/
+
+extern int gtp_set_cb_delete_context(struct gsn_t *gsn,
+ int (*cb_delete_context) (struct pdp_t* pdp));
+extern int gtp_set_cb_create_context(struct gsn_t *gsn,
+ int (*cb_create_context) (struct pdp_t* pdp));
+extern int gtp_set_cb_conf(struct gsn_t *gsn,
+ int (*cb) (int type, int cause, struct pdp_t* pdp, void *aid));
+extern int gtp_set_cb_gpdu(struct gsn_t *gsn,
+ int (*cb_gpdu) (struct pdp_t* pdp, void* pack, unsigned len));
+
+
+/* Internal functions (not part of the API */
+
+extern int gtp_echo_req(struct gsn_t *gsn, struct in_addr *inetaddrs);
+extern int gtp_echo_resp(struct gsn_t *gsn, struct sockaddr_in *peer,
+ void *pack, unsigned len);
+extern int gtp_echo_ind(struct gsn_t *gsn, struct sockaddr_in *peer,
+ void *pack, unsigned len);
+extern int gtp_echo_conf(struct gsn_t *gsn, struct sockaddr_in *peer,
+ void *pack, unsigned len);
+
+extern int gtp_unsup_resp(struct gsn_t *gsn, struct sockaddr_in *peer,
+ void *pack, unsigned len);
+extern int gtp_unsup_conf(struct gsn_t *gsn, struct sockaddr_in *peer,
+ void *pack, unsigned len);
+
+extern int gtp_create_pdp_req(struct gsn_t *gsn, int version, void *aid,
+ struct in_addr* inetaddr, struct pdp_t *pdp);
+
+extern int gtp_create_pdp_resp(struct gsn_t *gsn, int version,
+ struct sockaddr_in *peer,
+ void *pack, unsigned len,
+ struct pdp_t *pdp, uint8_t cause);
+
+extern int gtp_create_pdp_ind(struct gsn_t *gsn, int version,
+ struct sockaddr_in *peer,
+ void *pack, unsigned len);
+
+extern int gtp_create_pdp_conf(struct gsn_t *gsn, int version,
+ struct sockaddr_in *peer,
+ void *pack, unsigned len);
+
+extern int gtp_update_pdp_req(struct gsn_t *gsn, int version, void *aid,
+ struct in_addr* inetaddr, struct pdp_t *pdp);
+
+extern int gtp_delete_pdp_req(struct gsn_t *gsn, int version, void *aid,
+ struct pdp_t *pdp);
+
+extern int gtp_delete_pdp_resp(struct gsn_t *gsn, int version,
+ struct sockaddr_in *peer,
+ void *pack, unsigned len,
+ struct pdp_t *pdp, uint8_t cause);
+
+extern int gtp_delete_pdp_ind(struct gsn_t *gsn, int version,
+ struct sockaddr_in *peer,
+ void *pack, unsigned len);
+
+extern int gtp_delete_pdp_conf(struct gsn_t *gsn, int version,
+ struct sockaddr_in *peer,
+ void *pack, unsigned len);
+
+
+extern int ipv42eua(struct ul66_t *eua, struct in_addr *src);
+extern int eua2ipv4(struct in_addr *dst, struct ul66_t *eua);
+extern int gsna2in_addr(struct in_addr *dst, struct ul16_t *gsna);
+extern int in_addr2gsna(struct ul16_t *gsna, struct in_addr *src);
+
+#endif /* !_GTP_H */
diff --git a/gtp/gtpie.c b/gtp/gtpie.c
new file mode 100644
index 0000000..8fd4a20
--- /dev/null
+++ b/gtp/gtpie.c
@@ -0,0 +1,513 @@
+/*
+ * OpenGGSN - Gateway GPRS Support Node
+ * Copyright (C) 2002 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.
+ *
+ * The initial developer of the original code is
+ * Jens Jakobsen <jj@openggsn.org>
+ *
+ * Contributor(s):
+ *
+ */
+
+/*
+ * gtpie.c: Contains functions to encapsulate and decapsulate GTP
+ * information elements
+ *
+ *
+ * Encapsulation
+ * - gtpie_tlv, gtpie_tv0, gtpie_tv1, gtpie_tv2 ... Adds information
+ * elements to a buffer.
+ *
+ * Decapsulation
+ * - gtpie_decaps: Returns array with pointers to information elements.
+ * - getie_getie: Returns the pointer of a particular element.
+ * - gtpie_gettlv: Copies tlv information element. Return 0 on success.
+ * - gtpie_gettv: Copies tv information element. Return 0 on success.
+ *
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <string.h>
+
+#include "gtpie.h"
+
+int gtpie_tlv(void *p, int *length, int size, u_int8_t t, int l, void *v) {
+ if ((*length + 3 + l) >= size) return 1;
+ ((union gtpie_member*) (p + *length))->tlv.t = hton8(t);
+ ((union gtpie_member*) (p + *length))->tlv.l = hton16(l);
+ memcpy((void*) (p + *length +3), v, l);
+ *length += 3 + l;
+ return 0;
+}
+
+int gtpie_tv0(void *p, int *length, int size, u_int8_t t, int l, u_int8_t *v) {
+ if ((*length + 1 + l) >= size) return 1;
+ ((union gtpie_member*) (p + *length))->tv0.t = hton8(t);
+ memcpy((void*) (p + *length +1), v, l);
+ *length += 1 + l;
+ return 0;
+}
+
+int gtpie_tv1(void *p, int *length, int size, u_int8_t t, u_int8_t v) {
+ if ((*length + 2) >= size) return 1;
+ ((union gtpie_member*) (p + *length))->tv1.t = hton8(t);
+ ((union gtpie_member*) (p + *length))->tv1.v = hton8(v);
+ *length += 2;
+ return 0;
+}
+
+int gtpie_tv2(void *p, int *length, int size, u_int8_t t, u_int16_t v) {
+ if ((*length + 3) >= size) return 1;
+ ((union gtpie_member*) (p + *length))->tv2.t = hton8(t);
+ ((union gtpie_member*) (p + *length))->tv2.v = hton16(v);
+ *length += 3;
+ return 0;
+}
+
+int gtpie_tv4(void *p, int *length, int size, u_int8_t t, u_int32_t v) {
+ if ((*length + 5) >= size) return 1;
+ ((union gtpie_member*) (p + *length))->tv4.t = hton8(t);
+ ((union gtpie_member*) (p + *length))->tv4.v = hton32(v);
+ *length += 5;
+ return 0;
+}
+
+int gtpie_getie(union gtpie_member* ie[], int type, int instance) {
+ int j;
+ for (j=0; j< GTPIE_SIZE; j++) {
+ if ((ie[j] != 0) && (ie[j]->t == type)) {
+ if (instance-- == 0) return j;
+ }
+ }
+ return -1;
+}
+
+int gtpie_exist(union gtpie_member* ie[], int type, int instance) {
+ int j;
+ for (j=0; j< GTPIE_SIZE; j++) {
+ if ((ie[j] != 0) && (ie[j]->t == type)) {
+ if (instance-- == 0) return 1;
+ }
+ }
+ return 0;
+}
+
+int gtpie_gettlv(union gtpie_member* ie[], int type, int instance,
+ int *length, void *dst, int size){
+ int ien;
+ ien = gtpie_getie(ie, type, instance);
+ if (ien>=0) {
+ *length = ntoh16(ie[ien]->tlv.l);
+ if (*length <= size)
+ memcpy(dst, ie[ien]->tlv.v, *length);
+ else
+ return EOF;
+ }
+ return 0;
+}
+
+int gtpie_gettv0(union gtpie_member* ie[], int type, int instance,
+ void *dst, int size){
+ int ien;
+ ien = gtpie_getie(ie, type, instance);
+ if (ien>=0)
+ memcpy(dst, ie[ien]->tv0.v, size);
+ else
+ return EOF;
+ return 0;
+}
+
+int gtpie_gettv1(union gtpie_member* ie[], int type, int instance,
+ uint8_t *dst){
+ int ien;
+ ien = gtpie_getie(ie, type, instance);
+ if (ien>=0)
+ *dst = ntoh8(ie[ien]->tv1.v);
+ else
+ return EOF;
+ return 0;
+}
+
+int gtpie_gettv2(union gtpie_member* ie[], int type, int instance,
+ uint16_t *dst){
+ int ien;
+ ien = gtpie_getie(ie, type, instance);
+ if (ien>=0)
+ *dst = ntoh16(ie[ien]->tv2.v);
+ else
+ return EOF;
+ return 0;
+}
+
+int gtpie_gettv4(union gtpie_member* ie[], int type, int instance,
+ uint32_t *dst){
+ int ien;
+ ien = gtpie_getie(ie, type, instance);
+ if (ien>=0)
+ *dst = ntoh32(ie[ien]->tv4.v);
+ else
+ return EOF;
+ return 0;
+}
+
+int gtpie_decaps(union gtpie_member* ie[], void *pack, unsigned len) {
+ int i;
+ int j = 0;
+ unsigned char *p;
+ unsigned char *end;
+
+ end = (unsigned char*) pack + len;
+ p = pack;
+
+ memset(ie, 0, 4 * GTPIE_SIZE);
+
+ while (p<end) {
+ if (GTPIE_DEBUG) {
+ printf("The packet looks like this:\n");
+ for( i=0; i<(end-p); i++) {
+ printf("%02x ", (unsigned char)*(char *)(p+i));
+ if (!((i+1)%16)) printf("\n");
+ };
+ printf("\n");
+ }
+
+ switch (*p) {
+ case GTPIE_CAUSE: /* TV GTPIE types with value length 1 */
+ case GTPIE_REORDER:
+ case GTPIE_MAP_CAUSE:
+ case GTPIE_MS_VALIDATED:
+ case GTPIE_RECOVERY:
+ case GTPIE_SELECTION_MODE:
+ case GTPIE_TEARDOWN:
+ case GTPIE_NSAPI:
+ case GTPIE_RANAP_CAUSE:
+ case GTPIE_RP_SMS:
+ case GTPIE_RP:
+ case GTPIE_MS_NOT_REACH:
+ if (j<GTPIE_SIZE) {
+ ie[j] = (union gtpie_member*) p;
+ if (GTPIE_DEBUG) printf("GTPIE TV1 found. Type %d, value %d\n",
+ ie[j]->tv1.t, ie[j]->tv1.v);
+ p+= 1 + 1;
+ j++;
+ }
+ break;
+ case GTPIE_FL_DI: /* TV GTPIE types with value length 2 */
+ case GTPIE_FL_C:
+ case GTPIE_PFI:
+ case GTPIE_CHARGING_C:
+ case GTPIE_TRACE_REF:
+ case GTPIE_TRACE_TYPE:
+ if (j<GTPIE_SIZE) {
+ ie[j] = (union gtpie_member*) p;
+ if (GTPIE_DEBUG) printf("GTPIE TV2 found. Type %d, value %d\n",
+ ie[j]->tv2.t, ie[j]->tv2.v);
+ p+= 1 + 2;
+ j++;
+ }
+ break;
+ case GTPIE_QOS_PROFILE0: /* TV GTPIE types with value length 3 */
+ case GTPIE_P_TMSI_S:
+ if (j<GTPIE_SIZE) {
+ ie[j] = (union gtpie_member*) p;
+ if (GTPIE_DEBUG) printf("GTPIE TV 3 found. Type %d, value %d, %d, %d\n",
+ ie[j]->tv0.t, ie[j]->tv0.v[0],
+ ie[j]->tv0.v[1], ie[j]->tv0.v[2]);
+ p+= 1 + 3;
+ j++;
+ }
+ break;
+ case GTPIE_TLLI: /* TV GTPIE types with value length 4 */
+ case GTPIE_P_TMSI:
+ case GTPIE_CHARGING_ID:
+ if (j<GTPIE_SIZE) {
+ /* case GTPIE_TEI_DI: gtp1 */
+ /* case GTPIE_TEI_C: gtp1 */
+ ie[j] = (union gtpie_member*) p;
+ if (GTPIE_DEBUG) printf("GTPIE TV 4 found. Type %d, value %d\n",
+ ie[j]->tv4.t, ie[j]->tv4.v);
+ p+= 1 + 4;
+ j++;
+ }
+ break;
+ case GTPIE_TEI_DII: /* TV GTPIE types with value length 5 */
+ if (j<GTPIE_SIZE) {
+ ie[j] = (union gtpie_member*) p;
+ if (GTPIE_DEBUG) printf("GTPIE TV 5 found. Type %d\n", ie[j]->tv0.t);
+ p+= 1 + 5;
+ j++;
+ }
+ break;
+ case GTPIE_RAB_CONTEXT: /* TV GTPIE types with value length 7 */
+ if (j<GTPIE_SIZE) {
+ ie[j] = (union gtpie_member*) p;
+ if (GTPIE_DEBUG) printf("GTPIE TV 7 found. Type %d\n", ie[j]->tv0.t);
+ p+= 1 + 7;
+ j++;
+ }
+ break;
+ case GTPIE_IMSI: /* TV GTPIE types with value length 8 */
+ case GTPIE_RAI:
+ if (j<GTPIE_SIZE) {
+ ie[j] = (union gtpie_member*) p;
+ if (GTPIE_DEBUG) printf("GTPIE TV 8 found. Type %d, value 0x%llx\n",
+ ie[j]->tv0.t, ie[j]->tv8.v);
+ p+= 1 + 8;
+ j++;
+ }
+ break;
+ case GTPIE_AUTH_TRIPLET: /* TV GTPIE types with value length 28 */
+ if (j<GTPIE_SIZE) {
+ ie[j] = (union gtpie_member*) p;
+ if (GTPIE_DEBUG) printf("GTPIE TV 28 found. Type %d\n", ie[j]->tv0.t);
+ p+= 1 + 28;
+ j++;
+ }
+ break;
+ case GTPIE_EXT_HEADER_T: /* GTP extension header */
+ if (j<GTPIE_SIZE) {
+ ie[j] = (union gtpie_member*) p;
+ if (GTPIE_DEBUG) printf("GTPIE GTP extension header found. Type %d\n",
+ ie[j]->ext.t);
+ p+= 2 + ntoh8(ie[j]->ext.l);
+ j++;
+ }
+ break;
+ case GTPIE_EUA: /* TLV GTPIE types with variable length */
+ case GTPIE_MM_CONTEXT:
+ case GTPIE_PDP_CONTEXT:
+ case GTPIE_APN:
+ case GTPIE_PCO:
+ case GTPIE_GSN_ADDR:
+ case GTPIE_MSISDN:
+ case GTPIE_QOS_PROFILE:
+ case GTPIE_AUTH_QUINTUP:
+ case GTPIE_TFT:
+ case GTPIE_TARGET_INF:
+ case GTPIE_UTRAN_TRANS:
+ case GTPIE_RAB_SETUP:
+ case GTPIE_TRIGGER_ID:
+ case GTPIE_OMC_ID:
+ case GTPIE_CHARGING_ADDR:
+ case GTPIE_PRIVATE:
+ if (j<GTPIE_SIZE) {
+ ie[j] = (union gtpie_member*) p;
+ if (GTPIE_DEBUG) printf("GTPIE TLV found. Type %d\n", ie[j]->tlv.t);
+ p+= 3 + ntoh16(ie[j]->tlv.l);
+ j++;
+ }
+ break;
+ default:
+ if (GTPIE_DEBUG) printf("GTPIE something unknown. Type %d\n", *p);
+ return EOF; /* We received something unknown */
+ }
+ }
+ if (p==end) {
+ if (GTPIE_DEBUG) printf("GTPIE normal return. %lx %lx\n",
+ (unsigned long) p, (unsigned long) end);
+ return 0; /* We landed at the end of the packet: OK */
+ }
+ else {
+ if (GTPIE_DEBUG) printf("GTPIE exceeded end of packet. %lx %lx\n",
+ (unsigned long) p, (unsigned long) end);
+ return EOF; /* We exceeded the end of the packet: Error */
+ }
+}
+
+int gtpie_encaps(union gtpie_member *ie[], void *pack, unsigned *len) {
+ int i;
+ unsigned char *p;
+ unsigned char *end;
+ union gtpie_member *m;
+ int iesize;
+
+ p = pack;
+
+ memset(pack, 0, GTPIE_MAX);
+ end = p + GTPIE_MAX;
+ for (i=1; i<GTPIE_SIZE; i++) if (ie[i] != 0) {
+ if (GTPIE_DEBUG) printf("gtpie_encaps. Type %d\n", i);
+ m=(union gtpie_member *)p;
+ switch (i) {
+ case GTPIE_CAUSE: /* TV GTPIE types with value length 1 */
+ case GTPIE_REORDER:
+ case GTPIE_MAP_CAUSE:
+ case GTPIE_MS_VALIDATED:
+ case GTPIE_RECOVERY:
+ case GTPIE_SELECTION_MODE:
+ case GTPIE_TEARDOWN:
+ case GTPIE_NSAPI:
+ case GTPIE_RANAP_CAUSE:
+ case GTPIE_RP_SMS:
+ case GTPIE_RP:
+ case GTPIE_MS_NOT_REACH:
+ iesize = 2;
+ break;
+ case GTPIE_FL_DI: /* TV GTPIE types with value length 2 */
+ case GTPIE_FL_C:
+ case GTPIE_PFI:
+ case GTPIE_CHARGING_C:
+ case GTPIE_TRACE_REF:
+ case GTPIE_TRACE_TYPE:
+ iesize = 3;
+ break;
+ case GTPIE_QOS_PROFILE0: /* TV GTPIE types with value length 3 */
+ case GTPIE_P_TMSI_S:
+ iesize = 4;
+ break;
+ case GTPIE_TLLI: /* TV GTPIE types with value length 4 */
+ case GTPIE_P_TMSI:
+ /* case GTPIE_TEI_DI: only in gtp1*/
+ /* case GTPIE_TEI_C: only in gtp1*/
+ case GTPIE_CHARGING_ID:
+ iesize = 5;
+ break;
+ case GTPIE_TEI_DII: /* TV GTPIE types with value length 5 */
+ iesize = 6;
+ break;
+ case GTPIE_RAB_CONTEXT: /* TV GTPIE types with value length 7 */
+ iesize = 8;
+ break;
+ case GTPIE_IMSI: /* TV GTPIE types with value length 8 */
+ case GTPIE_RAI:
+ iesize = 9;
+ break;
+ case GTPIE_AUTH_TRIPLET: /* TV GTPIE types with value length 28 */
+ iesize = 29;
+ break;
+ case GTPIE_EXT_HEADER_T: /* GTP extension header */
+ iesize = 2 + hton8(ie[i]->ext.l);
+ break;
+ case GTPIE_EUA: /* TLV GTPIE types with length length 2 */
+ case GTPIE_MM_CONTEXT:
+ case GTPIE_PDP_CONTEXT:
+ case GTPIE_APN:
+ case GTPIE_PCO:
+ case GTPIE_GSN_ADDR:
+ case GTPIE_MSISDN:
+ case GTPIE_QOS_PROFILE:
+ case GTPIE_AUTH_QUINTUP:
+ case GTPIE_TFT:
+ case GTPIE_TARGET_INF:
+ case GTPIE_UTRAN_TRANS:
+ case GTPIE_RAB_SETUP:
+ case GTPIE_TRIGGER_ID:
+ case GTPIE_OMC_ID:
+ case GTPIE_CHARGING_ADDR:
+ case GTPIE_PRIVATE:
+ iesize = 3 + hton16(ie[i]->tlv.l);
+ break;
+ default:
+ return 2; /* We received something unknown */
+ }
+ if (p+iesize < end) {
+ memcpy(p, ie[i], iesize);
+ p += iesize;
+ *len += iesize;
+ }
+ else return 2; /* Out of space */
+ }
+ return 0;
+}
+
+int gtpie_encaps2(union gtpie_member ie[], int size,
+ void *pack, unsigned *len) {
+ int i, j;
+ unsigned char *p;
+ unsigned char *end;
+ union gtpie_member *m;
+ int iesize;
+
+ p = pack;
+
+ memset(pack, 0, GTPIE_MAX);
+ end = p + GTPIE_MAX;
+ for (j=0; j<GTPIE_SIZE; j++) for (i=0; i<size; i++) if (ie[i].t == j) {
+ if (GTPIE_DEBUG) printf("gtpie_encaps. Number %d, Type %d\n", i, ie[i].t);
+ m=(union gtpie_member *)p;
+ switch (ie[i].t) {
+ case GTPIE_CAUSE: /* TV GTPIE types with value length 1 */
+ case GTPIE_REORDER:
+ case GTPIE_MAP_CAUSE:
+ case GTPIE_MS_VALIDATED:
+ case GTPIE_RECOVERY:
+ case GTPIE_SELECTION_MODE:
+ case GTPIE_TEARDOWN:
+ case GTPIE_NSAPI:
+ case GTPIE_RANAP_CAUSE:
+ case GTPIE_RP_SMS:
+ case GTPIE_RP:
+ case GTPIE_MS_NOT_REACH:
+ iesize = 2;
+ break;
+ case GTPIE_PFI: /* TV GTPIE types with value length 2 */
+ case GTPIE_CHARGING_C:
+ case GTPIE_TRACE_REF:
+ case GTPIE_TRACE_TYPE:
+ iesize = 3;
+ break;
+ case GTPIE_QOS_PROFILE0: /* TV GTPIE types with value length 3 */
+ case GTPIE_P_TMSI_S:
+ iesize = 4;
+ break;
+ case GTPIE_TLLI: /* TV GTPIE types with value length 4 */
+ case GTPIE_P_TMSI:
+ case GTPIE_TEI_DI:
+ case GTPIE_TEI_C:
+ iesize = 5;
+ break;
+ case GTPIE_TEI_DII: /* TV GTPIE types with value length 5 */
+ iesize = 6;
+ break;
+ case GTPIE_RAB_CONTEXT: /* TV GTPIE types with value length 7 */
+ iesize = 8;
+ break;
+ case GTPIE_IMSI: /* TV GTPIE types with value length 8 */
+ case GTPIE_RAI:
+ iesize = 9;
+ break;
+ case GTPIE_AUTH_TRIPLET: /* TV GTPIE types with value length 28 */
+ iesize = 29;
+ break;
+ case GTPIE_EXT_HEADER_T: /* GTP extension header */
+ iesize = 2 + hton8(ie[i].ext.l);
+ break;
+ case GTPIE_CHARGING_ID: /* TLV GTPIE types with length length 2 */
+ case GTPIE_EUA:
+ case GTPIE_MM_CONTEXT:
+ case GTPIE_PDP_CONTEXT:
+ case GTPIE_APN:
+ case GTPIE_PCO:
+ case GTPIE_GSN_ADDR:
+ case GTPIE_MSISDN:
+ case GTPIE_QOS_PROFILE:
+ case GTPIE_AUTH_QUINTUP:
+ case GTPIE_TFT:
+ case GTPIE_TARGET_INF:
+ case GTPIE_UTRAN_TRANS:
+ case GTPIE_RAB_SETUP:
+ case GTPIE_TRIGGER_ID:
+ case GTPIE_OMC_ID:
+ case GTPIE_CHARGING_ADDR:
+ case GTPIE_PRIVATE:
+ iesize = 3 + hton16(ie[i].tlv.l);
+ break;
+ default:
+ return 2; /* We received something unknown */
+ }
+ if (p+iesize < end) {
+ memcpy(p, &ie[i], iesize);
+ p += iesize;
+ *len += iesize;
+ }
+ else return 2; /* Out of space */
+ }
+ return 0;
+}
diff --git a/gtp/gtpie.h b/gtp/gtpie.h
new file mode 100644
index 0000000..3a798ae
--- /dev/null
+++ b/gtp/gtpie.h
@@ -0,0 +1,279 @@
+/*
+ * OpenGGSN - Gateway GPRS Support Node
+ * Copyright (C) 2002 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.
+ *
+ * The initial developer of the original code is
+ * Jens Jakobsen <jj@openggsn.org>
+ *
+ * Contributor(s):
+ *
+ */
+
+#ifndef _GTPIE_H
+#define _GTPIE_H
+
+/* Macroes for conversion between host and network byte order */
+#define hton8(x) (x)
+#define ntoh8(x) (x)
+#define hton16(x) htons(x)
+#define ntoh16(x) ntohs(x)
+#define hton32(x) htonl(x)
+#define ntoh32(x) ntohl(x)
+
+#define GTPIE_SIZE 256 /* Max number of information elements */
+#define GTPIE_MAX 0xffff /* Max length of information elements */
+#define GTPIE_MAX_TV 28 /* Max length of type value pair */
+#define GTPIE_MAX_TLV 0xffff-3 /* Max length of TLV (GTP length is 16 bit) */
+
+#define GTPIE_DEBUG 0 /* Print debug information */
+
+/* GTP Information elements from 29.060 v3.9.0 7.7 Information Elements */
+/* Also covers version 0. Note that version 0 6: QOS Profile was superceded *
+ * by 135: QOS Profile in version 1 */
+
+#define GTPIE_CAUSE 1 /* Cause 1 */
+#define GTPIE_IMSI 2 /* International Mobile Subscriber Identity 8 */
+#define GTPIE_RAI 3 /* Routing Area Identity (RAI) 8 */
+#define GTPIE_TLLI 4 /* Temporary Logical Link Identity (TLLI) 4 */
+#define GTPIE_P_TMSI 5 /* Packet TMSI (P-TMSI) 4 */
+#define GTPIE_QOS_PROFILE0 6 /* Quality of Service Profile GTP version 0 3*/
+ /* 6-7 SPARE */ /* 6 is QoS Profile vers 0 */
+#define GTPIE_REORDER 8 /* Reordering Required 1 */
+#define GTPIE_AUTH_TRIPLET 9 /* Authentication Triplet 28 */
+ /* 10 SPARE */
+#define GTPIE_MAP_CAUSE 11 /* MAP Cause 1 */
+#define GTPIE_P_TMSI_S 12 /* P-TMSI Signature 3 */
+#define GTPIE_MS_VALIDATED 13 /* MS Validated 1 */
+#define GTPIE_RECOVERY 14 /* Recovery 1 */
+#define GTPIE_SELECTION_MODE 15 /* Selection Mode 1 */
+#define GTPIE_FL_DI 16 /* Flow Label Data I 2 */
+#define GTPIE_TEI_DI 16 /* Tunnel Endpoint Identifier Data I 4 */
+#define GTPIE_TEI_C 17 /* Tunnel Endpoint Identifier Control Plane 4 */
+#define GTPIE_FL_C 17 /* Flow Label Signalling 2 */
+#define GTPIE_TEI_DII 18 /* Tunnel Endpoint Identifier Data II 5 */
+#define GTPIE_TEARDOWN 19 /* Teardown Ind 1 */
+#define GTPIE_NSAPI 20 /* NSAPI 1 */
+#define GTPIE_RANAP_CAUSE 21 /* RANAP Cause 1 */
+#define GTPIE_RAB_CONTEXT 22 /* RAB Context 7 */
+#define GTPIE_RP_SMS 23 /* Radio Priority SMS 1 */
+#define GTPIE_RP 24 /* Radio Priority 1 */
+#define GTPIE_PFI 25 /* Packet Flow Id 2 */
+#define GTPIE_CHARGING_C 26 /* Charging Characteristics 2 */
+#define GTPIE_TRACE_REF 27 /* Trace Reference 2 */
+#define GTPIE_TRACE_TYPE 28 /* Trace Type 2 */
+#define GTPIE_MS_NOT_REACH 29 /* MS Not Reachable Reason 1 */
+ /* 30-116 UNUSED */
+/* 117-126 Reserved for the GPRS charging protocol (see GTP' in GSM 12.15) */
+#define GTPIE_CHARGING_ID 127 /* Charging ID 4 */
+#define GTPIE_EUA 128 /* End User Address */
+#define GTPIE_MM_CONTEXT 129 /* MM Context */
+#define GTPIE_PDP_CONTEXT 130 /* PDP Context */
+#define GTPIE_APN 131 /* Access Point Name */
+#define GTPIE_PCO 132 /* Protocol Configuration Options */
+#define GTPIE_GSN_ADDR 133 /* GSN Address */
+#define GTPIE_MSISDN 134 /* MS International PSTN/ISDN Number */
+#define GTPIE_QOS_PROFILE 135 /* Quality of Service Profile */
+#define GTPIE_AUTH_QUINTUP 136 /* Authentication Quintuplet */
+#define GTPIE_TFT 137 /* Traffic Flow Template */
+#define GTPIE_TARGET_INF 138 /* Target Identification */
+#define GTPIE_UTRAN_TRANS 139 /* UTRAN Transparent Container */
+#define GTPIE_RAB_SETUP 140 /* RAB Setup Information */
+#define GTPIE_EXT_HEADER_T 141 /* Extension Header Type List */
+#define GTPIE_TRIGGER_ID 142 /* Trigger Id */
+#define GTPIE_OMC_ID 143 /* OMC Identity */
+/* 239-250 Reserved for the GPRS charging protocol (see GTP' in GSM 12.15) */
+#define GTPIE_CHARGING_ADDR 251 /* Charging Gateway Address */
+/* 252-254 Reserved for the GPRS charging protocol (see GTP' in GSM 12.15) */
+#define GTPIE_PRIVATE 255 /* Private Extension */
+
+/* GTP information element cause codes from 29.060 v3.9.0 7.7 */
+/* */
+#define GTPCAUSE_REQ_IMSI 0 /* Request IMSI */
+#define GTPCAUSE_REQ_IMEI 1 /* Request IMEI */
+#define GTPCAUSE_REQ_IMSI_IMEI 2 /* Request IMSI and IMEI */
+#define GTPCAUSE_NO_ID_NEEDED 3 /* No identity needed */
+#define GTPCAUSE_MS_REFUSES 4 /* MS refuses */
+#define GTPCAUSE_MS_NOT_RESP 5 /* MS is not GPRS responding */
+#define GTPCAUSE_006 6 /* For future use 6-48 */
+#define GTPCAUSE_049 49 /* Cause values reserved for GPRS charging protocol use (See GTP' in GSM 12.15) 49-63 */
+#define GTPCAUSE_064 64 /* For future use 64-127 */
+#define GTPCAUSE_ACC_REQ 128 /* Request accepted */
+#define GTPCAUSE_129 129 /* For future use 129-176 */
+#define GTPCAUSE_177 177 /* Cause values reserved for GPRS charging protocol use (See GTP' In GSM 12.15) 177-191 */
+#define GTPCAUSE_NON_EXIST 192 /* Non-existent */
+#define GTPCAUSE_INVALID_MESSAGE 193 /* Invalid message format */
+#define GTPCAUSE_IMSI_NOT_KNOWN 194 /* IMSI not known */
+#define GTPCAUSE_MS_DETACHED 195 /* MS is GPRS detached */
+#define GTPCAUSE_MS_NOT_RESP 196 /* MS is not GPRS responding */
+#define GTPCAUSE_MS_REFUSES 197 /* MS refuses */
+#define GTPCAUSE_198 198 /* For future use */
+#define GTPCAUSE_NO_RESOURCES 199 /* No resources available */
+#define GTPCAUSE_NOT_SUPPORTED 200 /* Service not supported */
+#define GTPCAUSE_MAN_IE_INCORRECT 201 /* Mandatory IE incorrect */
+#define GTPCAUSE_MAN_IE_MISSING 202 /* Mandatory IE missing */
+#define GTPCAUSE_OPT_IE_INCORRECT 203 /* Optional IE incorrect */
+#define GTPCAUSE_SYS_FAIL 204 /* System failure */
+#define GTPCAUSE_ROAMING_REST 205 /* Roaming Restriction */
+#define GTPCAUSE_PTIMSI_MISMATCH 206 /* P-TMSI signature mismatch */
+#define GTPCAUSE_CONN_SUSP 207 /* GPRS connection suspended */
+#define GTPCAUSE_AUTH_FAIL 208 /* Authentication failure */
+#define GTPCAUSE_USER_AUTH_FAIL 209 /* User authentication failed */
+#define GTPCAUSE_CONTEXT_NOT_FOUND 210 /* Context not found */
+#define GTPCAUSE_ADDR_OCCUPIED 211 /* All dynamic PDP addresses are occupied */
+#define GTPCAUSE_NO_MEMORY 212 /* No memory is available */
+#define GTPCAUSE_RELOC_FAIL 213 /* Relocation failure */
+#define GTPCAUSE_UNKNOWN_MAN_EXTHEADER 214 /* Unknown mandatory extension header */
+#define GTPCAUSE_SEM_ERR_TFT 215 /* Semantic error in the TFT operation */
+#define GTPCAUSE_SYN_ERR_TFT 216 /* Syntactic error in the TFT operation */
+#define GTPCAUSE_SEM_ERR_FILTER 217 /* Semantic errors in packet filter(s) */
+#define GTPCAUSE_SYN_ERR_FILTER 218 /* Syntactic errors in packet filter(s) */
+#define GTPCAUSE_MISSING_APN 219 /* Missing or unknown APN*/
+#define GTPCAUSE_UNKNOWN_PDP 220 /* Unknown PDP address or PDP type */
+#define GTPCAUSE_221 221 /* For Future Use 221-240 */
+#define GTPCAUSE_241 241 /* Cause Values Reserved For Gprs Charging Protocol Use (See Gtp' In Gsm 12.15) 241-255 */
+
+
+/* GTP information element structs in network order */
+struct gtpie_ext { /* Extension header */
+ u_int8_t t; /* Type */
+ u_int8_t l; /* Length */
+ u_int8_t *p; /* Value */
+} __attribute__((packed));
+
+struct gtpie_tlv { /* Type length value pair */
+ u_int8_t t; /* Type */
+ u_int16_t l; /* Length */
+ u_int8_t v[GTPIE_MAX_TLV]; /* Value */
+} __attribute__((packed));
+
+struct gtpie_tv0 { /* 1 byte type value pair */
+ u_int8_t t; /* Type */
+ u_int8_t v[GTPIE_MAX_TV]; /* Pointer to value */
+}__attribute__((packed));
+
+struct gtpie_tv1 { /* 1 byte type value pair */
+ u_int8_t t; /* Type */
+ u_int8_t v; /* Value */
+}__attribute__((packed));
+
+struct gtpie_tv2 { /* 2 byte type value pair */
+ u_int8_t t; /* Type */
+ u_int16_t v; /* Value */
+}__attribute__((packed));
+
+struct gtpie_tv4 { /* 4 byte type value pair */
+ u_int8_t t; /* Type */
+ u_int32_t v; /* Value */
+}__attribute__((packed));
+
+struct gtpie_tv8 { /* 8 byte type value pair */
+ u_int8_t t; /* Type */
+ u_int64_t v; /* Value */
+}__attribute__((packed));
+
+
+union gtpie_member {
+ u_int8_t t;
+ struct gtpie_ext ext;
+ struct gtpie_tlv tlv;
+ struct gtpie_tv0 tv0;
+ struct gtpie_tv1 tv1;
+ struct gtpie_tv2 tv2;
+ struct gtpie_tv4 tv4;
+ struct gtpie_tv8 tv8;
+}__attribute__((packed));
+
+/*
+cause
+imsi
+rai
+tlli
+p_tmsi
+qos_profile0
+reorder
+auth
+map_cause
+p_tmsi_s
+ms_validated
+recovery
+selection_mode
+tei_di
+tei_c
+tei_dii
+teardown
+nsapi
+ranap_cause
+rab_context
+rp_sms
+rp
+pfi
+charging_c
+trace_ref
+trace_type
+ms_not_reach
+charging_id
+eua
+mm_context
+pdp_context
+apn
+pco
+gsn_addr
+msisdn
+qos_profile
+auth
+tft
+target_inf
+utran_trans
+rab_setup
+ext_header_t
+trigger_id
+omc_id
+charging_addr
+private
+*/
+
+struct tlv1 {
+ u_int8_t type;
+ u_int8_t length;
+}__attribute__((packed));
+
+struct tlv2 {
+ u_int8_t type;
+ u_int16_t length;
+}__attribute__((packed));
+
+extern int gtpie_tlv(void *p, int *length, int size,
+ u_int8_t t, int l, void *v);
+extern int gtpie_tv0(void *p, int *length, int size,
+ u_int8_t t, int l, u_int8_t *v);
+extern int gtpie_tv1(void *p, int *length, int size, u_int8_t t, u_int8_t v);
+extern int gtpie_tv2(void *p, int *length, int size, u_int8_t t, u_int16_t v);
+extern int gtpie_tv4(void *p, int *length, int size, u_int8_t t, u_int32_t v);
+extern int gtpie_tv8(void *p, int *length, int size, u_int8_t t, u_int64_t v);
+extern int gtpie_getie(union gtpie_member* ie[], int type, int instance);
+extern int gtpie_exist(union gtpie_member* ie[], int type, int instance);
+extern int gtpie_gettlv(union gtpie_member* ie[], int type, int instance,
+ int *length, void *dst, int size);
+extern int gtpie_gettv0(union gtpie_member* ie[], int type, int instance,
+ void *dst, int size);
+extern int gtpie_gettv1(union gtpie_member* ie[], int type, int instance,
+ uint8_t *dst);
+extern int gtpie_gettv2(union gtpie_member* ie[], int type, int instance,
+ uint16_t *dst);
+extern int gtpie_gettv4(union gtpie_member* ie[], int type, int instance,
+ uint32_t *dst);
+
+extern int gtpie_decaps(union gtpie_member* ie[], void *pack, unsigned len);
+extern int gtpie_encaps(union gtpie_member* ie[], void *pack, unsigned *len);
+extern int gtpie_encaps2(union gtpie_member ie[], int size,
+ void *pack, unsigned *len);
+
+
+#endif /* !_GTPIE_H */
+
+
diff --git a/gtp/lookupa.c b/gtp/lookupa.c
new file mode 100644
index 0000000..8ff114b
--- /dev/null
+++ b/gtp/lookupa.c
@@ -0,0 +1,246 @@
+/*
+--------------------------------------------------------------------
+lookupa.c, by Bob Jenkins, December 1996. Same as lookup2.c
+Use this code however you wish. Public Domain. No warranty.
+Source is http://burtleburtle.net/bob/c/lookupa.c
+--------------------------------------------------------------------
+*/
+#ifndef STANDARD
+/*
+#include "standard.h"
+*/
+#endif
+#ifndef LOOKUPA
+#include "lookupa.h"
+#endif
+
+/*
+--------------------------------------------------------------------
+mix -- mix 3 32-bit values reversibly.
+For every delta with one or two bit set, and the deltas of all three
+ high bits or all three low bits, whether the original value of a,b,c
+ is almost all zero or is uniformly distributed,
+* If mix() is run forward or backward, at least 32 bits in a,b,c
+ have at least 1/4 probability of changing.
+* If mix() is run forward, every bit of c will change between 1/3 and
+ 2/3 of the time. (Well, 22/100 and 78/100 for some 2-bit deltas.)
+mix() was built out of 36 single-cycle latency instructions in a
+ structure that could supported 2x parallelism, like so:
+ a -= b;
+ a -= c; x = (c>>13);
+ b -= c; a ^= x;
+ b -= a; x = (a<<8);
+ c -= a; b ^= x;
+ c -= b; x = (b>>13);
+ ...
+ Unfortunately, superscalar Pentiums and Sparcs can't take advantage
+ of that parallelism. They've also turned some of those single-cycle
+ latency instructions into multi-cycle latency instructions. Still,
+ this is the fastest good hash I could find. There were about 2^^68
+ to choose from. I only looked at a billion or so.
+--------------------------------------------------------------------
+*/
+#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); \
+}
+
+/*
+--------------------------------------------------------------------
+lookup() -- hash a variable-length key into a 32-bit value
+ k : the key (the unaligned variable-length array of bytes)
+ len : the length of the key, counting by bytes
+ level : can be any 4-byte value
+Returns a 32-bit value. Every bit of the key affects every bit of
+the return value. Every 1-bit and 2-bit delta achieves avalanche.
+About 6len+35 instructions.
+
+The best hash table sizes are powers of 2. There is no need to do
+mod a prime (mod is sooo slow!). If you need less than 32 bits,
+use a bitmask. For example, if you need only 10 bits, do
+ h = (h & hashmask(10));
+In which case, the hash table should have hashsize(10) elements.
+
+If you are hashing n strings (ub1 **)k, do it like this:
+ for (i=0, h=0; i<n; ++i) h = lookup( k[i], len[i], h);
+
+By Bob Jenkins, 1996. bob_jenkins@burtleburtle.net. You may use this
+code any way you wish, private, educational, or commercial.
+
+See http://burtleburtle.net/bob/hash/evahash.html
+Use for hash table lookup, or anything where one collision in 2^32 is
+acceptable. Do NOT use for cryptographic purposes.
+--------------------------------------------------------------------
+*/
+
+ub4 lookup( k, length, level)
+register ub1 *k; /* the key */
+register ub4 length; /* the length of the key */
+register ub4 level; /* the previous hash, or an arbitrary value */
+{
+ register ub4 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;
+}
+
+
+/*
+--------------------------------------------------------------------
+mixc -- mixc 8 4-bit values as quickly and thoroughly as possible.
+Repeating mix() three times achieves avalanche.
+Repeating mix() four times eliminates all funnels and all
+ characteristics stronger than 2^{-11}.
+--------------------------------------------------------------------
+*/
+#define mixc(a,b,c,d,e,f,g,h) \
+{ \
+ a^=b<<11; d+=a; b+=c; \
+ b^=c>>2; e+=b; c+=d; \
+ c^=d<<8; f+=c; d+=e; \
+ d^=e>>16; g+=d; e+=f; \
+ e^=f<<10; h+=e; f+=g; \
+ f^=g>>4; a+=f; g+=h; \
+ g^=h<<8; b+=g; h+=a; \
+ h^=a>>9; c+=h; a+=b; \
+}
+
+/*
+--------------------------------------------------------------------
+checksum() -- hash a variable-length key into a 256-bit value
+ k : the key (the unaligned variable-length array of bytes)
+ len : the length of the key, counting by bytes
+ state : an array of CHECKSTATE 4-byte values (256 bits)
+The state is the checksum. Every bit of the key affects every bit of
+the state. There are no funnels. About 112+6.875len instructions.
+
+If you are hashing n strings (ub1 **)k, do it like this:
+ for (i=0; i<8; ++i) state[i] = 0x9e3779b9;
+ for (i=0, h=0; i<n; ++i) checksum( k[i], len[i], state);
+
+(c) Bob Jenkins, 1996. bob_jenkins@burtleburtle.net. You may use this
+code any way you wish, private, educational, or commercial, as long
+as this whole comment accompanies it.
+
+See http://burtleburtle.net/bob/hash/evahash.html
+Use to detect changes between revisions of documents, assuming nobody
+is trying to cause collisions. Do NOT use for cryptography.
+--------------------------------------------------------------------
+*/
+void checksum( k, len, state)
+register ub1 *k;
+register ub4 len;
+register ub4 *state;
+{
+ register ub4 a,b,c,d,e,f,g,h,length;
+
+ /* Use the length and level; add in the golden ratio. */
+ length = len;
+ a=state[0]; b=state[1]; c=state[2]; d=state[3];
+ e=state[4]; f=state[5]; g=state[6]; h=state[7];
+
+ /*---------------------------------------- handle most of the key */
+ while (len >= 32)
+ {
+ a += (k[0] +(k[1]<<8) +(k[2]<<16) +(k[3]<<24));
+ b += (k[4] +(k[5]<<8) +(k[6]<<16) +(k[7]<<24));
+ c += (k[8] +(k[9]<<8) +(k[10]<<16)+(k[11]<<24));
+ d += (k[12]+(k[13]<<8)+(k[14]<<16)+(k[15]<<24));
+ e += (k[16]+(k[17]<<8)+(k[18]<<16)+(k[19]<<24));
+ f += (k[20]+(k[21]<<8)+(k[22]<<16)+(k[23]<<24));
+ g += (k[24]+(k[25]<<8)+(k[26]<<16)+(k[27]<<24));
+ h += (k[28]+(k[29]<<8)+(k[30]<<16)+(k[31]<<24));
+ mixc(a,b,c,d,e,f,g,h);
+ mixc(a,b,c,d,e,f,g,h);
+ mixc(a,b,c,d,e,f,g,h);
+ mixc(a,b,c,d,e,f,g,h);
+ k += 32; len -= 32;
+ }
+
+ /*------------------------------------- handle the last 31 bytes */
+ h += length;
+ switch(len)
+ {
+ case 31: h+=(k[30]<<24);
+ case 30: h+=(k[29]<<16);
+ case 29: h+=(k[28]<<8);
+ case 28: g+=(k[27]<<24);
+ case 27: g+=(k[26]<<16);
+ case 26: g+=(k[25]<<8);
+ case 25: g+=k[24];
+ case 24: f+=(k[23]<<24);
+ case 23: f+=(k[22]<<16);
+ case 22: f+=(k[21]<<8);
+ case 21: f+=k[20];
+ case 20: e+=(k[19]<<24);
+ case 19: e+=(k[18]<<16);
+ case 18: e+=(k[17]<<8);
+ case 17: e+=k[16];
+ case 16: d+=(k[15]<<24);
+ case 15: d+=(k[14]<<16);
+ case 14: d+=(k[13]<<8);
+ case 13: d+=k[12];
+ case 12: c+=(k[11]<<24);
+ case 11: c+=(k[10]<<16);
+ case 10: c+=(k[9]<<8);
+ case 9 : c+=k[8];
+ case 8 : b+=(k[7]<<24);
+ case 7 : b+=(k[6]<<16);
+ case 6 : b+=(k[5]<<8);
+ case 5 : b+=k[4];
+ case 4 : a+=(k[3]<<24);
+ case 3 : a+=(k[2]<<16);
+ case 2 : a+=(k[1]<<8);
+ case 1 : a+=k[0];
+ }
+ mixc(a,b,c,d,e,f,g,h);
+ mixc(a,b,c,d,e,f,g,h);
+ mixc(a,b,c,d,e,f,g,h);
+ mixc(a,b,c,d,e,f,g,h);
+
+ /*-------------------------------------------- report the result */
+ state[0]=a; state[1]=b; state[2]=c; state[3]=d;
+ state[4]=e; state[5]=f; state[6]=g; state[7]=h;
+}
diff --git a/gtp/lookupa.h b/gtp/lookupa.h
new file mode 100644
index 0000000..16784a9
--- /dev/null
+++ b/gtp/lookupa.h
@@ -0,0 +1,29 @@
+/*
+------------------------------------------------------------------------------
+By Bob Jenkins, September 1996.
+lookupa.h, a hash function for table lookup, same function as lookup.c.
+Use this code in any way you wish. Public Domain. It has no warranty.
+Source is http://burtleburtle.net/bob/c/lookupa.h
+------------------------------------------------------------------------------
+*/
+
+/* Uncommented by Jens Jakobsen 20020717
+#ifndef STANDARD
+#include "standard.h"
+#endif
+*/
+
+#ifndef LOOKUPA
+#define LOOKUPA
+
+typedef unsigned long int ub4; /* unsigned 4-byte quantities */
+typedef unsigned char ub1;
+
+#define CHECKSTATE 8
+#define hashsize(n) ((ub4)1<<(n))
+#define hashmask(n) (hashsize(n)-1)
+
+ub4 lookup(/*_ ub1 *k, ub4 length, ub4 level _*/);
+void checksum(/*_ ub1 *k, ub4 length, ub4 *state _*/);
+
+#endif /* LOOKUPA */
diff --git a/gtp/pdp.c b/gtp/pdp.c
new file mode 100644
index 0000000..3e5951e
--- /dev/null
+++ b/gtp/pdp.c
@@ -0,0 +1,320 @@
+/*
+ * OpenGGSN - Gateway GPRS Support Node
+ * Copyright (C) 2002 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.
+ *
+ * The initial developer of the original code is
+ * Jens Jakobsen <jj@openggsn.org>
+ *
+ * Contributor(s):
+ *
+ */
+
+/*
+ * pdp.c:
+ *
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <string.h>
+#include "pdp.h"
+#include "lookupa.h"
+
+/* ***********************************************************
+ * Global variables TODO: most should be moved to gsn_t
+ *************************************************************/
+
+struct pdp_t pdpa[PDP_MAX]; /* PDP storage */
+struct pdp_t* hashtid[PDP_MAX];/* Hash table for IMSI + NSAPI */
+struct pdp_t* haship[PDP_MAX]; /* Hash table for IP and network interface */
+
+/* ***********************************************************
+ * Functions related to PDP storage
+ *
+ * Lifecycle
+ * For a GGSN pdp context life begins with the reception of a
+ * create pdp context request. It normally ends with the reception
+ * of a delete pdp context request, but will also end with the
+ * reception of an error indication message.
+ * Provisions should probably be made for terminating pdp contexts
+ * based on either idle timeout, or by sending downlink probe
+ * messages (ping?) to see if the MS is still responding.
+ *
+ * For an SGSN pdp context life begins with the application just
+ * before sending off a create pdp context request. It normally
+ * ends when a delete pdp context response message is received
+ * from the GGSN, but should also end when with the reception of
+ * an error indication message.
+ *
+ *
+ * HASH Tables
+ *
+ * Downlink packets received in the GGSN are identified only by their
+ * network interface together with their destination IP address (Two
+ * network interfaces can use the same private IP address). Each IMSI
+ * (mobile station) can have several PDP contexts using the same IP
+ * address. In this case the traffic flow template (TFT) is used to
+ * determine the correct PDP context for a particular IMSI. Also it
+ * should be possible for each PDP context to use several IP adresses
+ * For fixed wireless access a mobile station might need a full class
+ * C network. Even in the case of several IP adresses the PDP context
+ * should be determined on the basis of the network IP address.
+ * Thus we need a hash table based on network interface + IP address.
+ *
+ * Uplink packets are for GTP0 identified by their IMSI and NSAPI, which
+ * is collectively called the tunnel identifier. There is also a 16 bit
+ * flow label that can be used for identification of uplink packets. This
+ * however is quite useless as it limits the number of contexts to 65536.
+ * For GTP1 uplink packets are identified by a Tunnel Endpoint Identifier
+ * (32 bit), or in some cases by the combination of IMSI and NSAPI.
+ * For GTP1 delete context requests there is a need to find the PDP
+ * contexts with the same IP address. This however can be done by using
+ * the IP hash table.
+ * Thus we need a hash table based on TID (IMSI and NSAPI). The TEID will
+ * be used for directly addressing the PDP context.
+
+ * pdp_newpdp
+ * Gives you a pdp context with no hash references In some way
+ * this should have a limited lifetime.
+ *
+ * pdp_freepdp
+ * Frees a context that was previously allocated with
+ * pdp_newpdp
+ *
+ *
+ * pdp_getpdpIP
+ * An incoming IP packet is uniquely identified by a pointer
+ * to a network connection (void *) and an IP address
+ * (struct in_addr)
+ *
+ * pdp_getpdpGTP
+ * An incoming GTP packet is uniquely identified by a the
+ * TID (imsi + nsapi (8 octets)) in or by the Flow Label
+ * (2 octets) in gtp0 or by the Tunnel Endpoint Identifier
+ * (4 octets) in gtp1.
+ *
+ * This leads to an architecture where the receiving GSN
+ * chooses a Flow Label or a Tunnel Endpoint Identifier
+ * when the connection is setup.
+ * Thus no hash table is needed for GTP lookups.
+ *
+ *************************************************************/
+
+int pdp_init() {
+ memset(&pdpa, 0, sizeof(pdpa));
+ memset(&hashtid, 0, sizeof(hashtid));
+ memset(&haship, 0, sizeof(haship));
+
+ return 0;
+}
+
+int pdp_newpdp(struct pdp_t **pdp, uint64_t imsi, uint8_t nsapi,
+ struct pdp_t *pdp_old){
+ int n;
+ for (n=0; n<PDP_MAX; n++) { /* TODO: Need to do better than linear search */
+ if (pdpa[n].inuse == 0) {
+ *pdp = &pdpa[n];
+ if (NULL != pdp_old) memcpy(*pdp, pdp_old, sizeof(struct pdp_t));
+ else memset(*pdp, 0, sizeof(struct pdp_t));
+ (*pdp)->inuse = 1;
+ (*pdp)->imsi = imsi;
+ (*pdp)->nsapi = nsapi;
+ (*pdp)->fllc = (uint16_t) n;
+ (*pdp)->fllu = (uint16_t) n;
+ (*pdp)->teic_own = (uint32_t) n;
+ (*pdp)->teic_own = (uint32_t) n;
+ pdp_tidset(*pdp, pdp_gettid(imsi, nsapi));
+ return 0;
+ }
+ }
+ return EOF; /* No more available */
+}
+
+int pdp_freepdp(struct pdp_t *pdp){
+ pdp_tiddel(pdp);
+ memset(pdp, 0, sizeof(struct pdp_t));
+ /* Also need to clean up IP hash tables */
+ return 0;
+}
+
+int pdp_getpdp(struct pdp_t **pdp){
+ *pdp = &pdpa[0];
+ return 0;
+}
+
+int pdp_getgtp0(struct pdp_t **pdp, uint16_t fl){
+ if (fl>=PDP_MAX) {
+ return EOF; /* Not found */
+ }
+ else {
+ *pdp = &pdpa[fl];
+ if ((*pdp)->inuse) return 0;
+ else return EOF;
+ /* Context exists. We do no further validity checking. */
+ }
+}
+
+int pdp_getgtp1(struct pdp_t **pdp, uint32_t teid){
+ if (teid>=PDP_MAX) {
+ return -1; /* Not found */
+ }
+ else {
+ *pdp = &pdpa[teid];
+ return 0; /* We do no validity checking. */
+ }
+}
+
+
+int pdp_tidhash(uint64_t tid) {
+ return (lookup(&tid, sizeof(tid), 0) % PDP_MAX);
+}
+
+int pdp_tidset(struct pdp_t *pdp, uint64_t tid) {
+ int hash = pdp_tidhash(tid);
+ struct pdp_t *pdp2;
+ struct pdp_t *pdp_prev = NULL;
+ if (PDP_DEBUG) printf("Begin pdp_tidset tid = %llx\n", tid);
+ pdp->tid = tid;
+ for (pdp2 = hashtid[hash]; pdp2; pdp2 = pdp2->tidnext)
+ pdp_prev = pdp2;
+ if (!pdp_prev)
+ hashtid[hash] = pdp;
+ else
+ pdp_prev->tidnext = pdp;
+ if (PDP_DEBUG) printf("End pdp_tidset\n");
+ return 0;
+}
+
+int pdp_tiddel(struct pdp_t *pdp) {
+ int hash = pdp_tidhash(pdp->tid);
+ struct pdp_t *pdp2;
+ struct pdp_t *pdp_prev = NULL;
+ if (PDP_DEBUG) printf("Begin pdp_tiddel tid = %llx\n", pdp->tid);
+ for (pdp2 = hashtid[hash]; pdp2; pdp2 = pdp2->tidnext) {
+ if (pdp2 == pdp) {
+ if (!pdp_prev)
+ hashtid[hash] = pdp2->tidnext;
+ else
+ pdp_prev->tidnext = pdp2->tidnext;
+ if (PDP_DEBUG) printf("End pdp_tidset: PDP found\n");
+ return 0;
+ }
+ pdp_prev = pdp2;
+ }
+ if (PDP_DEBUG) printf("End pdp_tidset: PDP not found\n");
+ return EOF; /* End of linked list and not found */
+}
+
+int pdp_tidget(struct pdp_t **pdp, uint64_t tid) {
+ int hash = pdp_tidhash(tid);
+ struct pdp_t *pdp2;
+ if (PDP_DEBUG) printf("Begin pdp_tidget tid = %llx\n", tid);
+ for (pdp2 = hashtid[hash]; pdp2; pdp2 = pdp2->tidnext) {
+ if (pdp2->tid == tid) {
+ *pdp = pdp2;
+ if (PDP_DEBUG) printf("Begin pdp_tidget. Found\n");
+ return 0;
+ }
+ }
+ if (PDP_DEBUG) printf("Begin pdp_tidget. Not found\n");
+ return EOF; /* End of linked list and not found */
+}
+
+int pdp_iphash(void* ipif, struct ul66_t *eua) {
+ /*printf("IPhash %ld\n", lookup(eua->v, eua->l, ipif) % PDP_MAX);*/
+ return (lookup(eua->v, eua->l, ipif) % PDP_MAX);
+}
+
+int pdp_ipset(struct pdp_t *pdp, void* ipif, struct ul66_t *eua) {
+ int hash;
+ struct pdp_t *pdp2;
+ struct pdp_t *pdp_prev = NULL;
+
+ if (PDP_DEBUG) printf("Begin pdp_ipset %d %d %2x%2x%2x%2x\n",
+ (unsigned) ipif, eua->l,
+ eua->v[2], eua->v[3],
+ eua->v[4], eua->v[5]);
+
+ pdp->ipif = ipif;
+ pdp->eua.l = eua->l;
+ memcpy(pdp->eua.v, eua->v, eua->l);
+
+ hash = pdp_iphash(pdp->ipif, &pdp->eua);
+
+ for (pdp2 = haship[hash]; pdp2; pdp2 = pdp2->ipnext)
+ pdp_prev = pdp2;
+ if (!pdp_prev)
+ haship[hash] = pdp;
+ else
+ pdp_prev->ipnext = pdp;
+ if (PDP_DEBUG) printf("End pdp_ipset\n");
+ return 0;
+}
+
+int pdp_ipdel(struct pdp_t *pdp) {
+ int hash = pdp_iphash(pdp->ipif, &pdp->eua);
+ struct pdp_t *pdp2;
+ struct pdp_t *pdp_prev = NULL;
+ if (PDP_DEBUG) printf("Begin pdp_ipdel\n");
+ for (pdp2 = haship[hash]; pdp2; pdp2 = pdp2->ipnext) {
+ if (pdp2 == pdp) {
+ if (!pdp_prev)
+ haship[hash] = pdp2->ipnext;
+ else
+ pdp_prev->ipnext = pdp2->ipnext;
+ if (PDP_DEBUG) printf("End pdp_ipdel: PDP found\n");
+ return 0;
+ }
+ pdp_prev = pdp2;
+ }
+ if (PDP_DEBUG) printf("End pdp_ipdel: PDP not found\n");
+ return EOF; /* End of linked list and not found */
+}
+
+int pdp_ipget(struct pdp_t **pdp, void* ipif, struct ul66_t *eua) {
+ int hash = pdp_iphash(ipif, eua);
+ struct pdp_t *pdp2;
+ /*printf("Begin pdp_ipget %d %d %2x%2x%2x%2x\n", (unsigned)ipif, eua->l,
+ eua->v[2],eua->v[3],eua->v[4],eua->v[5]);*/
+ for (pdp2 = haship[hash]; pdp2; pdp2 = pdp2->ipnext) {
+ if ((pdp2->ipif == ipif) && (pdp2->eua.l == eua->l) &&
+ (memcmp(&pdp2->eua.v, &eua->v, eua->l) == 0)) {
+ *pdp = pdp2;
+ /*printf("End pdp_ipget. Found\n");*/
+ return 0;
+ }
+ }
+ if (PDP_DEBUG) printf("End pdp_ipget Notfound %d %d %2x%2x%2x%2x\n",
+ (unsigned)ipif, eua->l, eua->v[2],eua->v[3],eua->v[4],eua->v[5]);
+ return EOF; /* End of linked list and not found */
+}
+
+/* Various conversion functions */
+
+int pdp_ntoeua(struct in_addr *src, struct ul66_t *eua) {
+ eua->l=6;
+ eua->v[0]=0xf1; /* IETF */
+ eua->v[1]=0x21; /* IPv4 */
+ memcpy(&eua->v[2], src, 4); /* Copy a 4 byte address */
+ return 0;
+}
+
+uint64_t pdp_gettid(uint64_t imsi, uint8_t nsapi) {
+ return (imsi & 0x0fffffffffffffff) + ((uint64_t)nsapi << 60);
+}
+
+int ulcpy(void* dst, void* src, size_t size) {
+ if (((struct ul255_t*)src)->l <= size) {
+ ((struct ul255_t*)dst)->l = ((struct ul255_t*)src)->l;
+ memcpy(((struct ul255_t*)dst)->v, ((struct ul255_t*)src)->v,
+ ((struct ul255_t*)dst)->l);
+ return 0;
+ }
+ else return EOF;
+}
diff --git a/gtp/pdp.h b/gtp/pdp.h
new file mode 100644
index 0000000..b9ca62a
--- /dev/null
+++ b/gtp/pdp.h
@@ -0,0 +1,203 @@
+/*
+ * OpenGGSN - Gateway GPRS Support Node
+ * Copyright (C) 2002 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.
+ *
+ * The initial developer of the original code is
+ * Jens Jakobsen <jj@openggsn.org>
+ *
+ * Contributor(s):
+ *
+ */
+
+#ifndef _PDP_H
+#define _PDP_H
+
+#define PDP_MAX 1024 /* Max number of PDP contexts */
+
+#define PDP_DEBUG 0 /* Print debug information */
+
+/* GTP Information elements from 29.060 v3.9.0 7.7 Information Elements */
+/* Also covers version 0. Note that version 0 6: QOS Profile was superceded *
+ * by 135: QOS Profile in version 1 */
+
+
+struct sl_t {
+int l;
+char *v;
+};
+
+struct ul_t {
+int l;
+unsigned char *v;
+};
+
+struct ul16_t {
+int l;
+unsigned char v[16];
+};
+
+struct ul66_t {
+int l;
+unsigned char v[66];
+};
+
+struct ul255_t {
+int l;
+unsigned char v[255];
+};
+
+
+/* ***********************************************************
+ * Information storage for each PDP context
+ *
+ * Information storage for each PDP context is defined in
+ * 23.060 section 13.3 and 03.60. Includes IMSI, MSISDN, APN,
+ * PDP-type, PDP-address (IP address), sequence numbers, charging ID.
+ * For the SGSN it also includes radio related mobility
+ * information.
+ * The following structure is a combination of the storage
+ * requirements for each PDP context for the GGSN and SGSN.
+ * It contains both 23.060 as well as 03.60 parameters.
+ * Information is stored in the format for information elements
+ * described in 29.060 and 09.60.
+ * 31 * 4 + 15 structs + = 120 + 15 structs ~ 2k / context
+ * Structs: IP address 16+4 bytes (6), APN 255 bytes (2)
+ * QOS: 255 bytes (3), msisdn 16 bytes (1),
+ *
+ * TODO: We need to consider who manages the pdp_t hash tables
+ * Is it gtp_lib, or is it the application?
+ * I suppose that it will be gtp_lib.
+ * SGSN will ask gtplib for new pdp_t. Fill out the fields,
+ * and pass it on to gtp_create_pdp_req.
+ * GGSN will receive gtp_create_pdp_ind, create new pdp_t and
+ * send responce to SGSN.
+ * SGSN will receive response and gtplib will find the
+ * original pdp_t corresponding to the request. This will be
+ * passed on to the application.
+ * Eventually the SGSN will close the connection, and the
+ * pdp_t will be freed by gtplib in SGSN and GGSN
+ * This means that gtplib need to have functions to
+ * allocate, free, sort and find pdp_t
+ * (newpdp, freepdp, getpdp)
+ * Hash tables: TID, IMSI, IP etc.)
+ *************************************************************/
+
+struct pdp_t {
+ /* Parameter determining if this PDP is in use. */
+ uint8_t inuse; /* 0=free. 1=used by somebody */
+
+ /* Pointers related to hash tables */
+ struct pdp_t *tidnext;
+ struct pdp_t *ipnext;
+
+ /* Parameters shared by all PDP context belonging to the same MS */
+
+ void *ipif; /* IP network interface */
+ void *asap; /* Application specific service access point */
+
+ uint64_t imsi; /* International Mobile Subscriber Identity.*/
+ struct ul16_t msisdn; /* The basic MSISDN of the MS. */
+ uint8_t mnrg; /* Indicates whether the MS is marked as not reachable for PS at the HLR. (1 bit, not transmitted) */
+ uint8_t cch_sub; /* The charging characteristics for the MS, e.g. normal, prepaid, flat-rate, and/or hot billing subscription. (not transmitted) */
+ uint16_t traceref; /* Identifies a record or a collection of records for a particular trace. */
+ uint16_t tracetype;/* Indicates the type of trace. */
+ struct ul_t triggerid;/* Identifies the entity that initiated the trace. */
+ struct ul_t omcid; /* Identifies the OMC that shall receive the trace record(s). */
+ uint8_t rec_hlr; /* Indicates if HLR or VLR is performing database recovery. (1 bit, not transmitted) */
+
+ /* Parameters specific to each individual PDP context */
+
+ uint8_t pdp_id; /* Index of the PDP context. (PDP context identifier) */
+ uint8_t pdp_state;/* PDP State Packet data protocol state, INACTIVE or ACTIVE. (1 bit, not transmitted) */
+ /* struct ul_t pdp_type; * PDP type; e.g. PPP or IP. */
+ /* struct ul_t pdp_addr; * PDP address; e.g. an IP address. */
+ struct ul66_t eua; /* End user address. PDP type and address combined */
+ uint8_t pdp_dyn; /* Indicates whether PDP Address is static or dynamic. (1 bit, not transmitted) */
+ struct ul255_t apn_req;/* The APN requested. */
+ struct ul255_t apn_sub;/* The APN received from the HLR. */
+ struct ul255_t apn_use;/* The APN Network Identifier currently used. */
+ uint8_t nsapi; /* Network layer Service Access Point Identifier. (4 bit) */
+ uint16_t ti; /* Transaction Identifier. (4 or 12 bit) */
+
+ uint32_t teic_own; /* (Own Tunnel Endpoint Identifier Control) */
+ uint32_t teid_own; /* (Own Tunnel Endpoint Identifier Data I) */
+ uint32_t teic_gn; /* Tunnel Endpoint Identifier for the Gn and Gp interfaces. (Control plane) */
+ uint32_t teid_gn; /* Tunnel Endpoint Identifier for the Gn and Gp interfaces. (Data I) */
+ uint32_t tei_iu; /* Tunnel Endpoint Identifier for the Iu interface. */
+
+ uint16_t fllc; /* (Local Flow Label Control, gtp0) */
+ uint16_t fllu; /* (Local Flow Label Data I, gtp0) */
+ uint16_t flrc; /* (Remote gn/gp Flow Label Control, gtp0) */
+ uint16_t flru; /* (Remote gn/gp Flow Label Data I, gtp0) */
+
+ struct ul_t tft; /* Traffic flow template. */
+ /*struct ul16_t sgsnc; * The IP address of the SGSN currently serving this MS. (Control plane) */
+ /*struct ul16_t sgsnu; * The IP address of the SGSN currently serving this MS. (User plane) */
+ /*struct ul16_t ggsnc; * The IP address of the GGSN currently used. (Control plane) */
+ /*struct ul16_t ggsnu; * The IP address of the GGSN currently used. (User plane) */
+
+ struct ul16_t gsnlc; /* The IP address of the local GSN. (Control plane) */
+ struct ul16_t gsnlu; /* The IP address of the local GSN. (User plane) */
+ struct ul16_t gsnrc; /* The IP address of the remote GSN. (Control plane) */
+ struct ul16_t gsnru; /* The IP address of the remote GSN. (User plane) */
+
+ uint8_t vplmn_allow; /* Specifies whether the MS is allowed to use the APN in the domain of the HPLMN only, or additionally the APN in the domain of the VPLMN. (1 bit) */
+ uint8_t qos_sub0[3]; /* The quality of service profile subscribed. */
+ uint8_t qos_req0[3]; /* The quality of service profile requested. */
+ uint8_t qos_neg0[3]; /* The quality of service profile negotiated. */
+ struct ul255_t qos_sub; /* The quality of service profile subscribed. */
+ struct ul255_t qos_req; /* The quality of service profile requested. */
+ struct ul255_t qos_neg; /* The quality of service profile negotiated. */
+ uint8_t radio_pri;/* The RLC/MAC radio priority level for uplink user data transmission. (4 bit) */
+ uint16_t flow_id; /* Packet flow identifier. */
+ /* struct ul_t bssqos_neg; * The aggregate BSS quality of service profile negotiated for the packet flow that this PDP context belongs to. (NOT GTP)*/
+ uint8_t sndcpd; /* SNDCP sequence number of the next downlink N-PDU to be sent to the MS. */
+ uint8_t sndcpu; /* SNDCP sequence number of the next uplink N-PDU expected from the MS. */
+ uint8_t rec_sgsn; /* Indicates if the SGSN is performing database recovery. (1 bit, not transmitted) */
+/* uint16_t gtpsnd; GTP-U sequence number of the next downlink N-PDU to be sent to the SGSN / received from the GGSN. */
+/* uint16_t gtpsnu; GTP-U sequence number of the next uplink N-PDU to be received from the SGSN / sent to the GGSN */
+ uint16_t gtpsntx; /* GTP-U sequence number of the next downlink N-PDU to be sent (09.60 section 8.1.1.1) */
+ uint16_t gtpsnrx; /* GTP-U sequence number of the next uplink N-PDU to be received (09.60 section 8.1.1.1) */
+ uint8_t pdcpsndd; /* Sequence number of the next downlink in-sequence PDCP-PDU to be sent to the MS. */
+ uint8_t pdcpsndu; /* Sequence number of the next uplink in-sequence PDCP-PDU expected from the MS. */
+ uint32_t cid; /* Charging identifier, identifies charging records generated by SGSN and GGSN. */
+ uint16_t cch_pdp; /* The charging characteristics for this PDP context, e.g. normal, prepaid, flat-rate, and/or hot billing. */
+ struct ul16_t rnc_addr;/* The IP address of the RNC currently used. */
+ uint8_t reorder; /* Specifies whether the GGSN shall reorder N-PDUs received from the SGSN / Specifies whether the SGSN shall reorder N-PDUs before delivering the N-PSUs to the MS. (1 bit) */
+ struct ul255_t pco_req; /* Requested packet control options. */
+ struct ul255_t pco_neg; /* Negotiated packet control options. */
+ uint32_t selmode; /* Selection mode. */
+ uint64_t tid; /* (Combination of imsi and nsapi) */
+};
+
+
+/* functions related to pdp_t management */
+int pdp_init();
+int pdp_newpdp(struct pdp_t **pdp, uint64_t imsi, uint8_t nsapi,
+ struct pdp_t *pdp_old);
+int pdp_freepdp(struct pdp_t *pdp);
+int pdp_getpdp(struct pdp_t **pdp);
+
+int pdp_getgtp0(struct pdp_t **pdp, uint16_t fl);
+int pdp_getgtp1(struct pdp_t **pdp, uint32_t teid);
+
+int pdp_tidhash(uint64_t tid);
+int pdp_tidset(struct pdp_t *pdp, uint64_t tid);
+int pdp_tiddel(struct pdp_t *pdp);
+int pdp_tidget(struct pdp_t **pdp, uint64_t tid);
+
+int pdp_iphash(void* ipif, struct ul66_t *eua);
+int pdp_ipset(struct pdp_t *pdp, void* ipif, struct ul66_t *eua);
+int pdp_ipdel(struct pdp_t *pdp);
+int pdp_ipget(struct pdp_t **pdp, void* ipif, struct ul66_t *eua);
+
+int pdp_ntoeua(struct in_addr *src, struct ul66_t *eua);
+uint64_t pdp_gettid(uint64_t imsi, uint8_t nsapi);
+int ulcpy(void* dst, void* src, size_t size);
+
+#endif /* !_PDP_H */
diff --git a/gtp/queue.c b/gtp/queue.c
new file mode 100644
index 0000000..0080e43
--- /dev/null
+++ b/gtp/queue.c
@@ -0,0 +1,249 @@
+/*
+ * OpenGGSN - Gateway GPRS Support Node
+ * Copyright (C) 2002 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.
+ *
+ * The initial developer of the original code is
+ * Jens Jakobsen <jj@openggsn.org>
+ *
+ * Contributor(s):
+ *
+ */
+
+/*
+ * Queue.c
+ * Reliable delivery of signalling messages
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <string.h>
+#include "pdp.h"
+#include "gtp.h"
+#include "queue.h"
+
+int queue_print(struct queue_t *queue) {
+ int n;
+ printf("Queue: %x Next: %d First: %d Last: %d\n", (int) queue, queue->next, queue->first, queue->last);
+ printf("# State seq next prev timeout retrans\n");
+ for (n=0; n<QUEUE_SIZE; n++) {
+ printf("%d %d %d %d %d %d %d\n",
+ n,
+ queue->qmsga[n].state,
+ queue->qmsga[n].seq,
+ queue->qmsga[n].next,
+ queue->qmsga[n].prev,
+ (int) queue->qmsga[n].timeout,
+ queue->qmsga[n].retrans);
+ }
+ return 0;
+}
+
+int queue_seqhash(struct sockaddr_in *peer, uint16_t seq) {
+ /* With QUEUE_HASH_SIZE = 2^16 this describes all possible
+ seq values. Thus we have perfect hash for the request queue.
+ For the response queue we might have collisions, but not very
+ often.
+ For performance optimisation we should remove the modulus
+ operator, but this is only valid for QUEUE_HASH_SIZE = 2^16 */
+ return seq % QUEUE_HASH_SIZE;
+}
+
+int queue_seqset(struct queue_t *queue, struct qmsg_t *qmsg,
+ struct sockaddr_in *peer, uint16_t seq) {
+ int hash = queue_seqhash(peer, seq);
+ struct qmsg_t *qmsg2;
+ struct qmsg_t *qmsg_prev = NULL;
+
+ if (QUEUE_DEBUG) printf("Begin queue_seqset seq = %d\n", (int) seq);
+ if (QUEUE_DEBUG) printf("SIZEOF PEER %d, *PEER %d\n", sizeof(peer), sizeof(*peer));
+
+ qmsg->seq = seq;
+ memcpy(&qmsg->peer, peer, sizeof(*peer));
+
+ for (qmsg2 = queue->hashseq[hash]; qmsg2; qmsg2 = qmsg2->seqnext)
+ qmsg_prev = qmsg2;
+ if (!qmsg_prev)
+ queue->hashseq[hash] = qmsg;
+ else
+ qmsg_prev->seqnext = qmsg;
+ if (QUEUE_DEBUG) printf("End queue_seqset\n");
+ return 0;
+}
+int queue_seqdel(struct queue_t *queue, struct qmsg_t *qmsg) {
+ int hash = queue_seqhash(&qmsg->peer, qmsg->seq);
+ struct qmsg_t *qmsg2;
+ struct qmsg_t *qmsg_prev = NULL;
+ if (QUEUE_DEBUG) printf("Begin queue_seqdel seq = %d\n", (int) qmsg->seq);
+
+ for (qmsg2 = queue->hashseq[hash]; qmsg2; qmsg2 = qmsg2->seqnext) {
+ if (qmsg == qmsg) {
+ if (!qmsg_prev)
+ queue->hashseq[hash] = qmsg2->seqnext;
+ else
+ qmsg_prev->seqnext = qmsg2->seqnext;
+ if (QUEUE_DEBUG) printf("End queue_seqset: SEQ found\n");
+ return 0;
+ }
+ qmsg_prev = qmsg2;
+ }
+ printf("End queue_seqset: SEQ not found\n");
+ return EOF; /* End of linked list and not found */
+}
+
+
+/* Allocates and initialises new queue structure */
+int queue_new(struct queue_t **queue) {
+ if (QUEUE_DEBUG) printf("queue_new\n");
+ *queue = calloc(1, sizeof(struct queue_t));
+ (*queue)->next = 0;
+ (*queue)->first = -1;
+ (*queue)->last = -1;
+
+ if (QUEUE_DEBUG) queue_print(*queue);
+ if (*queue) return 0;
+ else return EOF;
+}
+
+/* Deallocates queue structure */
+int queue_free(struct queue_t *queue) {
+ if (QUEUE_DEBUG) printf("queue_free\n");
+ if (QUEUE_DEBUG) queue_print(queue);
+ free(queue);
+ return 0;
+}
+
+int queue_newmsg(struct queue_t *queue, struct qmsg_t **qmsg,
+ struct sockaddr_in *peer, uint16_t seq) {
+ if (QUEUE_DEBUG) printf("queue_newmsg %d\n", (int) seq);
+ if (queue->qmsga[queue->next].state == 1) {
+ return EOF; /* Queue is full */
+ }
+ else {
+ *qmsg = &queue->qmsga[queue->next];
+ queue_seqset(queue, *qmsg, peer, seq);
+ (*qmsg)->state = 1; /* Space taken */
+ (*qmsg)->this = queue->next;
+ (*qmsg)->next=-1; /* End of the queue */
+ (*qmsg)->prev=queue->last; /* Link to the previous */
+ queue->qmsga[queue->last].next=queue->next; /* Link previous to us */
+ queue->last = queue->next; /* End of queue */
+ if (queue->first == -1) queue->first = queue->next;
+ queue->next = (queue->next+1) % QUEUE_SIZE; /* Increment */
+ if (QUEUE_DEBUG) queue_print(queue);
+ return 0;
+ }
+}
+
+int queue_freemsg(struct queue_t *queue, struct qmsg_t *qmsg) {
+ if (QUEUE_DEBUG) printf("queue_freemsg\n");
+ if (qmsg->state != 1) {
+ return EOF; /* Not in queue */
+ }
+
+ queue_seqdel(queue, qmsg);
+
+ if (qmsg->next == -1) /* Are we the last in queue? */
+ queue->last = qmsg->prev;
+ else
+ queue->qmsga[qmsg->next].prev = qmsg->prev;
+
+ if (qmsg->prev == -1) /* Are we the first in queue? */
+ queue->first = qmsg->next;
+ else
+ queue->qmsga[qmsg->prev].next = qmsg->next;
+
+ memset(qmsg, 0, sizeof(struct qmsg_t)); /* Just to be safe */
+
+ if (QUEUE_DEBUG) queue_print(queue);
+
+ return 0;
+}
+
+int queue_back(struct queue_t *queue, struct qmsg_t *qmsg) {
+ if (QUEUE_DEBUG) printf("queue_back\n");
+ if (qmsg->state != 1) {
+ return EOF; /* Not in queue */
+ }
+
+ /* Insert stuff to maintain hash table */
+
+ if (qmsg->next != -1) {/* Only swop if there are others */
+ queue->qmsga[qmsg->next].prev = qmsg->prev;
+ queue->first = qmsg->next;
+
+ qmsg->next = -1;
+ qmsg->prev = queue->last;
+ if (queue->last != -1) queue->qmsga[queue->last].next = qmsg->this;
+ queue->last = qmsg->this;
+ }
+ if (QUEUE_DEBUG) queue_print(queue);
+ return 0;
+}
+
+/* Get the element with a particular sequence number */
+int queue_getfirst(struct queue_t *queue, struct qmsg_t **qmsg) {
+ /*printf("queue_getfirst\n");*/
+ if (queue->first == -1) {
+ *qmsg = NULL;
+ return EOF; /* End of queue = queue is empty. */
+ }
+ *qmsg = &queue->qmsga[queue->first];
+ if (QUEUE_DEBUG) queue_print(queue);
+ return 0;
+}
+
+int queue_getseqx(struct queue_t *queue, struct qmsg_t **qmsg,
+ struct sockaddr_in *peer, uint16_t seq) {
+ int n;
+ if (QUEUE_DEBUG) printf("queue_getseq, %d\n", (int) seq);
+ if (QUEUE_DEBUG) queue_print(queue);
+ for (n=0; n<QUEUE_SIZE; n++) {
+ if ((queue->qmsga[n].seq == seq) &&
+ (!memcmp(&queue->qmsga[n].peer, peer, sizeof(*peer)))) {
+ *qmsg = &queue->qmsga[n];
+ return 0;
+ }
+ }
+ return EOF; /* Not found */
+}
+
+int queue_seqget(struct queue_t *queue, struct qmsg_t **qmsg,
+ struct sockaddr_in *peer, uint16_t seq) {
+ int hash = queue_seqhash(peer, seq);
+ struct qmsg_t *qmsg2;
+ if (QUEUE_DEBUG) printf("Begin queue_seqget seq = %d\n", (int) seq);
+ for (qmsg2 = queue->hashseq[hash]; qmsg2; qmsg2 = qmsg2->seqnext) {
+ if ((qmsg2->seq == seq) &&
+ (!memcmp(&qmsg2->peer, peer, sizeof(*peer)))) {
+ *qmsg = qmsg2;
+ if (QUEUE_DEBUG) printf("End queue_seqget. Found\n");
+ return 0;
+ }
+ }
+ if (QUEUE_DEBUG) printf("End queue_seqget. Not found\n");
+ return EOF; /* End of linked list and not found */
+}
+
+int queue_freemsg_seq(struct queue_t *queue, struct sockaddr_in *peer,
+ uint16_t seq, uint8_t *type, void **aid) {
+ struct qmsg_t *qmsg;
+ if (queue_seqget(queue, &qmsg, peer, seq)) {
+ *aid = NULL;
+ *type = 0;
+ return EOF;
+ }
+ *aid = qmsg->aid;
+ *type = qmsg->type;
+ if (queue_freemsg(queue, qmsg)) {
+ return EOF;
+ }
+ return 0;
+}
diff --git a/gtp/queue.h b/gtp/queue.h
new file mode 100644
index 0000000..076a3ef
--- /dev/null
+++ b/gtp/queue.h
@@ -0,0 +1,77 @@
+/*
+ * OpenGGSN - Gateway GPRS Support Node
+ * Copyright (C) 2002 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.
+ *
+ * The initial developer of the original code is
+ * Jens Jakobsen <jj@openggsn.org>
+ *
+ * Contributor(s):
+ *
+ */
+
+/*
+ * Queue.c
+ * Reliable delivery of signalling messages
+ */
+
+#ifndef _QUEUE_H
+#define _QUEUE_H
+
+#define QUEUE_DEBUG 0 /* Print debug information */
+
+#define QUEUE_SIZE 256 /* Size of retransmission queue */
+#define QUEUE_HASH_SIZE 65536 /* Size of hash table (2^16) */
+
+struct qmsg_t { /* Holder for queued packets */
+ int state; /* 0=empty, 1=full */
+ uint16_t seq; /* The sequence number */
+ u_int8_t type; /* The type of packet */
+ void *aid; /* Application specific pointer */
+ union gtp_packet p; /* The packet stored */
+ int l; /* Length of the packet */
+ struct sockaddr_in peer;/* Address packet was sent to / received from */
+ struct qmsg_t *seqnext; /* Pointer to next in sequence hash list */
+ int next; /* Pointer to the next in queue. -1: Last */
+ int prev; /* Pointer to the previous in queue. -1: First */
+ int this; /* Pointer to myself */
+ time_t timeout; /* When do we retransmit this packet? */
+ int retrans; /* How many times did we retransmit this? */
+};
+
+struct queue_t {
+ struct qmsg_t qmsga[QUEUE_SIZE]; /* Array holding signalling messages */
+ void *hashseq[QUEUE_HASH_SIZE]; /* Hash array */
+ int next; /* Next location in queue to use */
+ int first; /* First packet in queue (oldest timeout) */
+ int last; /* Last packet in queue (youngest timeout) */
+};
+
+
+/* Allocates and initialises new queue structure */
+int queue_new(struct queue_t **queue);
+/* Deallocates queue structure */
+int queue_free(struct queue_t *queue);
+/* Find a new queue element. Return EOF if allready full */
+int queue_newmsg(struct queue_t *queue, struct qmsg_t **qmsg,
+ struct sockaddr_in *peer, uint16_t seq);
+/* Remove an element from the queue. */
+int queue_freemsg(struct queue_t *queue, struct qmsg_t *qmsg);
+/* Move an element to the back of the queue */
+int queue_back(struct queue_t *queue, struct qmsg_t *qmsg);
+/* Get the first element in the queue (oldest) */
+int queue_getfirst(struct queue_t *queue, struct qmsg_t **qmsg);
+/* Get the element with a particular sequence number */
+int queue_seqget(struct queue_t *queue, struct qmsg_t **qmsg,
+ struct sockaddr_in *peer, uint16_t seq);
+/* Free message based on sequence number */
+int queue_freemsg_seq(struct queue_t *queue, struct sockaddr_in *peer,
+ uint16_t seq, uint8_t *type, void **aid);
+
+
+#endif /* !_QUEUE_H */
+
diff --git a/intl/Makefile b/intl/Makefile
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/intl/Makefile
diff --git a/intl/Makefile.in b/intl/Makefile.in
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/intl/Makefile.in
diff --git a/libtool b/libtool
new file mode 100755
index 0000000..114f141
--- /dev/null
+++ b/libtool
@@ -0,0 +1,4288 @@
+#! /bin/sh
+
+# libtool - Provide generalized library-building support services.
+# Generated automatically by ltconfig (GNU libtool 1.3.5 (1.385.2.206 2000/05/27 11:12:27))
+# NOTE: Changes made to this file will be lost: look at ltconfig or ltmain.sh.
+#
+# Copyright (C) 1996-1999 Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Sed that helps us avoid accidentally triggering echo(1) options like -n.
+Xsed="sed -e s/^X//"
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test "X${CDPATH+set}" = Xset; then CDPATH=:; export CDPATH; fi
+
+### BEGIN LIBTOOL CONFIG
+# Libtool was configured as follows, on host oslo:
+#
+# CC="gcc" CFLAGS="-g -O2" CPPFLAGS="" \
+# LD="/usr/bin/ld" LDFLAGS="" LIBS="" \
+# NM="/usr/bin/nm -B" RANLIB="ranlib" LN_S="ln -s" \
+# DLLTOOL="" OBJDUMP="" AS="" \
+# ./ltconfig --with-gcc --with-gnu-ld --no-verify ./ltmain.sh i686-pc-linux-gnu
+#
+# Compiler and other test output produced by ltconfig, useful for
+# debugging ltconfig, is in ./config.log if it exists.
+
+# The version of ltconfig that generated this script.
+LTCONFIG_VERSION="1.3.5"
+
+# Shell to use when invoking shell scripts.
+SHELL="/bin/sh"
+
+# Whether or not to build shared libraries.
+build_libtool_libs=yes
+
+# Whether or not to build static libraries.
+build_old_libs=yes
+
+# Whether or not to optimize for fast installation.
+fast_install=yes
+
+# The host system.
+host_alias=i686-pc-linux-gnu
+host=i686-pc-linux-gnu
+
+# An echo program that does not interpret backslashes.
+echo="echo"
+
+# The archiver.
+AR="ar"
+
+# The default C compiler.
+CC="gcc"
+
+# The linker used to build libraries.
+LD="/usr/bin/ld"
+
+# Whether we need hard or soft links.
+LN_S="ln -s"
+
+# A BSD-compatible nm program.
+NM="/usr/bin/nm -B"
+
+# Used on cygwin: DLL creation program.
+DLLTOOL="dlltool"
+
+# Used on cygwin: object dumper.
+OBJDUMP="objdump"
+
+# Used on cygwin: assembler.
+AS="as"
+
+# The name of the directory that contains temporary libtool files.
+objdir=.libs
+
+# How to create reloadable object files.
+reload_flag=" -r"
+reload_cmds="\$LD\$reload_flag -o \$output\$reload_objs"
+
+# How to pass a linker flag through the compiler.
+wl="-Wl,"
+
+# Object file suffix (normally "o").
+objext="o"
+
+# Old archive suffix (normally "a").
+libext="a"
+
+# Executable file suffix (normally "").
+exeext=""
+
+# Additional compiler flags for building library objects.
+pic_flag=" -fPIC"
+
+# Does compiler simultaneously support -c and -o options?
+compiler_c_o="yes"
+
+# Can we write directly to a .lo ?
+compiler_o_lo="yes"
+
+# Must we lock files when doing compilation ?
+need_locks="no"
+
+# Do we need the lib prefix for modules?
+need_lib_prefix=no
+
+# Do we need a version for libraries?
+need_version=no
+
+# Whether dlopen is supported.
+dlopen=unknown
+
+# Whether dlopen of programs is supported.
+dlopen_self=unknown
+
+# Whether dlopen of statically linked programs is supported.
+dlopen_self_static=unknown
+
+# Compiler flag to prevent dynamic linking.
+link_static_flag="-static"
+
+# Compiler flag to turn off builtin functions.
+no_builtin_flag=" -fno-builtin -fno-rtti -fno-exceptions"
+
+# Compiler flag to allow reflexive dlopens.
+export_dynamic_flag_spec="\${wl}--export-dynamic"
+
+# Compiler flag to generate shared objects directly from archives.
+whole_archive_flag_spec="\${wl}--whole-archive\$convenience \${wl}--no-whole-archive"
+
+# Compiler flag to generate thread-safe objects.
+thread_safe_flag_spec=""
+
+# Library versioning type.
+version_type=linux
+
+# Format of library name prefix.
+libname_spec="lib\$name"
+
+# List of archive names. First name is the real one, the rest are links.
+# The last name is the one that the linker finds with -lNAME.
+library_names_spec="\${libname}\${release}.so\$versuffix \${libname}\${release}.so\$major \$libname.so"
+
+# The coded name of the library, if different from the real name.
+soname_spec="\${libname}\${release}.so\$major"
+
+# Commands used to build and install an old-style archive.
+RANLIB="ranlib"
+old_archive_cmds="\$AR cru \$oldlib\$oldobjs~\$RANLIB \$oldlib"
+old_postinstall_cmds="\$RANLIB \$oldlib~chmod 644 \$oldlib"
+old_postuninstall_cmds=""
+
+# Create an old-style archive from a shared archive.
+old_archive_from_new_cmds=""
+
+# Commands used to build and install a shared archive.
+archive_cmds="\$CC -shared \$libobjs \$deplibs \$linkopts \${wl}-soname \$wl\$soname -o \$lib"
+archive_expsym_cmds="\$CC -shared \$libobjs \$deplibs \$linkopts \${wl}-soname \$wl\$soname \${wl}-retain-symbols-file \$wl\$export_symbols -o \$lib"
+postinstall_cmds=""
+postuninstall_cmds=""
+
+# Method to check whether dependent libraries are shared objects.
+deplibs_check_method="pass_all"
+
+# Command to use when deplibs_check_method == file_magic.
+file_magic_cmd=""
+
+# Flag that allows shared libraries with undefined symbols to be built.
+allow_undefined_flag=""
+
+# Flag that forces no undefined symbols.
+no_undefined_flag=""
+
+# Commands used to finish a libtool library installation in a directory.
+finish_cmds="PATH=\\\"\\\$PATH:/sbin\\\" ldconfig -n \$libdir"
+
+# Same as above, but a single script fragment to be evaled but not shown.
+finish_eval=""
+
+# Take the output of nm and produce a listing of raw symbols and C names.
+global_symbol_pipe="sed -n -e 's/^.*[ ]\\([ABCDGISTW]\\)[ ][ ]*\\(\\)\\([_A-Za-z][_A-Za-z0-9]*\\)\$/\\1 \\2\\3 \\3/p'"
+
+# Transform the output of nm in a proper C declaration
+global_symbol_to_cdecl="sed -n -e 's/^. .* \\(.*\\)\$/extern char \\1;/p'"
+
+# This is the shared library runtime path variable.
+runpath_var=LD_RUN_PATH
+
+# This is the shared library path variable.
+shlibpath_var=LD_LIBRARY_PATH
+
+# Is shlibpath searched before the hard-coded library search path?
+shlibpath_overrides_runpath=no
+
+# How to hardcode a shared library path into an executable.
+hardcode_action=immediate
+
+# Flag to hardcode $libdir into a binary during linking.
+# This must work even if $libdir does not exist.
+hardcode_libdir_flag_spec="\${wl}--rpath \${wl}\$libdir"
+
+# Whether we need a single -rpath flag with a separated argument.
+hardcode_libdir_separator=""
+
+# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
+# resulting binary.
+hardcode_direct=no
+
+# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
+# resulting binary.
+hardcode_minus_L=no
+
+# Set to yes if using SHLIBPATH_VAR=DIR during linking hardcodes DIR into
+# the resulting binary.
+hardcode_shlibpath_var=unsupported
+
+# Compile-time system search path for libraries
+sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib"
+
+# Run-time system search path for libraries
+sys_lib_dlsearch_path_spec="/lib /usr/lib"
+
+# Fix the shell variable $srcfile for the compiler.
+fix_srcfile_path=""
+
+# Set to yes if exported symbols are required.
+always_export_symbols=no
+
+# The commands to list exported symbols.
+export_symbols_cmds="\$NM \$libobjs \$convenience | \$global_symbol_pipe | sed 's/.* //' | sort | uniq > \$export_symbols"
+
+# Symbols that should not be listed in the preloaded symbols.
+exclude_expsyms="_GLOBAL_OFFSET_TABLE_"
+
+# Symbols that must always be exported.
+include_expsyms=""
+
+### END LIBTOOL CONFIG
+
+# ltmain.sh - Provide generalized library-building support services.
+# NOTE: Changing this file will not affect anything until you rerun ltconfig.
+#
+# Copyright (C) 1996-1999 Free Software Foundation, Inc.
+# Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Check that we have a working $echo.
+if test "X$1" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+elif test "X$1" = X--fallback-echo; then
+ # Avoid inline document here, it may be left over
+ :
+elif test "X`($echo '\t') 2>/dev/null`" = 'X\t'; then
+ # Yippee, $echo works!
+ :
+else
+ # Restart under the correct shell, and then maybe $echo will work.
+ exec $SHELL "$0" --no-reexec ${1+"$@"}
+fi
+
+if test "X$1" = X--fallback-echo; then
+ # used as fallback echo
+ shift
+ cat <<EOF
+$*
+EOF
+ exit 0
+fi
+
+# The name of this program.
+progname=`$echo "$0" | sed 's%^.*/%%'`
+modename="$progname"
+
+# Constants.
+PROGRAM=ltmain.sh
+PACKAGE=libtool
+VERSION=1.3.5
+TIMESTAMP=" (1.385.2.206 2000/05/27 11:12:27)"
+
+default_mode=
+help="Try \`$progname --help' for more information."
+magic="%%%MAGIC variable%%%"
+mkdir="mkdir"
+mv="mv -f"
+rm="rm -f"
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e 1s/^X//'
+sed_quote_subst='s/\([\\`\\"$\\\\]\)/\\\1/g'
+SP2NL='tr \040 \012'
+NL2SP='tr \015\012 \040\040'
+
+# NLS nuisances.
+# Only set LANG and LC_ALL to C if already set.
+# These must not be set unconditionally because not all systems understand
+# e.g. LANG=C (notably SCO).
+# We save the old values to restore during execute mode.
+if test "${LC_ALL+set}" = set; then
+ save_LC_ALL="$LC_ALL"; LC_ALL=C; export LC_ALL
+fi
+if test "${LANG+set}" = set; then
+ save_LANG="$LANG"; LANG=C; export LANG
+fi
+
+if test "$LTCONFIG_VERSION" != "$VERSION"; then
+ echo "$modename: ltconfig version \`$LTCONFIG_VERSION' does not match $PROGRAM version \`$VERSION'" 1>&2
+ echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2
+ exit 1
+fi
+
+if test "$build_libtool_libs" != yes && test "$build_old_libs" != yes; then
+ echo "$modename: not configured to build any kind of library" 1>&2
+ echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2
+ exit 1
+fi
+
+# Global variables.
+mode=$default_mode
+nonopt=
+prev=
+prevopt=
+run=
+show="$echo"
+show_help=
+execute_dlfiles=
+lo2o="s/\\.lo\$/.${objext}/"
+o2lo="s/\\.${objext}\$/.lo/"
+
+# Parse our command line options once, thoroughly.
+while test $# -gt 0
+do
+ arg="$1"
+ shift
+
+ case "$arg" in
+ -*=*) optarg=`$echo "X$arg" | $Xsed -e 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) optarg= ;;
+ esac
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$prev"; then
+ case "$prev" in
+ execute_dlfiles)
+ eval "$prev=\"\$$prev \$arg\""
+ ;;
+ *)
+ eval "$prev=\$arg"
+ ;;
+ esac
+
+ prev=
+ prevopt=
+ continue
+ fi
+
+ # Have we seen a non-optional argument yet?
+ case "$arg" in
+ --help)
+ show_help=yes
+ ;;
+
+ --version)
+ echo "$PROGRAM (GNU $PACKAGE) $VERSION$TIMESTAMP"
+ exit 0
+ ;;
+
+ --config)
+ sed -e '1,/^### BEGIN LIBTOOL CONFIG/d' -e '/^### END LIBTOOL CONFIG/,$d' $0
+ exit 0
+ ;;
+
+ --debug)
+ echo "$progname: enabling shell trace mode"
+ set -x
+ ;;
+
+ --dry-run | -n)
+ run=:
+ ;;
+
+ --features)
+ echo "host: $host"
+ if test "$build_libtool_libs" = yes; then
+ echo "enable shared libraries"
+ else
+ echo "disable shared libraries"
+ fi
+ if test "$build_old_libs" = yes; then
+ echo "enable static libraries"
+ else
+ echo "disable static libraries"
+ fi
+ exit 0
+ ;;
+
+ --finish) mode="finish" ;;
+
+ --mode) prevopt="--mode" prev=mode ;;
+ --mode=*) mode="$optarg" ;;
+
+ --quiet | --silent)
+ show=:
+ ;;
+
+ -dlopen)
+ prevopt="-dlopen"
+ prev=execute_dlfiles
+ ;;
+
+ -*)
+ $echo "$modename: unrecognized option \`$arg'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+
+ *)
+ nonopt="$arg"
+ break
+ ;;
+ esac
+done
+
+if test -n "$prevopt"; then
+ $echo "$modename: option \`$prevopt' requires an argument" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+fi
+
+if test -z "$show_help"; then
+
+ # Infer the operation mode.
+ if test -z "$mode"; then
+ case "$nonopt" in
+ *cc | *++ | gcc* | *-gcc*)
+ mode=link
+ for arg
+ do
+ case "$arg" in
+ -c)
+ mode=compile
+ break
+ ;;
+ esac
+ done
+ ;;
+ *db | *dbx | *strace | *truss)
+ mode=execute
+ ;;
+ *install*|cp|mv)
+ mode=install
+ ;;
+ *rm)
+ mode=uninstall
+ ;;
+ *)
+ # If we have no mode, but dlfiles were specified, then do execute mode.
+ test -n "$execute_dlfiles" && mode=execute
+
+ # Just use the default operation mode.
+ if test -z "$mode"; then
+ if test -n "$nonopt"; then
+ $echo "$modename: warning: cannot infer operation mode from \`$nonopt'" 1>&2
+ else
+ $echo "$modename: warning: cannot infer operation mode without MODE-ARGS" 1>&2
+ fi
+ fi
+ ;;
+ esac
+ fi
+
+ # Only execute mode is allowed to have -dlopen flags.
+ if test -n "$execute_dlfiles" && test "$mode" != execute; then
+ $echo "$modename: unrecognized option \`-dlopen'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ # Change the help message to a mode-specific one.
+ generic_help="$help"
+ help="Try \`$modename --help --mode=$mode' for more information."
+
+ # These modes are in order of execution frequency so that they run quickly.
+ case "$mode" in
+ # libtool compile mode
+ compile)
+ modename="$modename: compile"
+ # Get the compilation command and the source file.
+ base_compile=
+ lastarg=
+ srcfile="$nonopt"
+ suppress_output=
+
+ user_target=no
+ for arg
+ do
+ # Accept any command-line options.
+ case "$arg" in
+ -o)
+ if test "$user_target" != "no"; then
+ $echo "$modename: you cannot specify \`-o' more than once" 1>&2
+ exit 1
+ fi
+ user_target=next
+ ;;
+
+ -static)
+ build_old_libs=yes
+ continue
+ ;;
+ esac
+
+ case "$user_target" in
+ next)
+ # The next one is the -o target name
+ user_target=yes
+ continue
+ ;;
+ yes)
+ # We got the output file
+ user_target=set
+ libobj="$arg"
+ continue
+ ;;
+ esac
+
+ # Accept the current argument as the source file.
+ lastarg="$srcfile"
+ srcfile="$arg"
+
+ # Aesthetically quote the previous argument.
+
+ # Backslashify any backslashes, double quotes, and dollar signs.
+ # These are the only characters that are still specially
+ # interpreted inside of double-quoted scrings.
+ lastarg=`$echo "X$lastarg" | $Xsed -e "$sed_quote_subst"`
+
+ # Double-quote args containing other shell metacharacters.
+ # Many Bourne shells cannot handle close brackets correctly in scan
+ # sets, so we specify it separately.
+ case "$lastarg" in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ lastarg="\"$lastarg\""
+ ;;
+ esac
+
+ # Add the previous argument to base_compile.
+ if test -z "$base_compile"; then
+ base_compile="$lastarg"
+ else
+ base_compile="$base_compile $lastarg"
+ fi
+ done
+
+ case "$user_target" in
+ set)
+ ;;
+ no)
+ # Get the name of the library object.
+ libobj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%'`
+ ;;
+ *)
+ $echo "$modename: you must specify a target with \`-o'" 1>&2
+ exit 1
+ ;;
+ esac
+
+ # Recognize several different file suffixes.
+ # If the user specifies -o file.o, it is replaced with file.lo
+ xform='[cCFSfmso]'
+ case "$libobj" in
+ *.ada) xform=ada ;;
+ *.adb) xform=adb ;;
+ *.ads) xform=ads ;;
+ *.asm) xform=asm ;;
+ *.c++) xform=c++ ;;
+ *.cc) xform=cc ;;
+ *.cpp) xform=cpp ;;
+ *.cxx) xform=cxx ;;
+ *.f90) xform=f90 ;;
+ *.for) xform=for ;;
+ esac
+
+ libobj=`$echo "X$libobj" | $Xsed -e "s/\.$xform$/.lo/"`
+
+ case "$libobj" in
+ *.lo) obj=`$echo "X$libobj" | $Xsed -e "$lo2o"` ;;
+ *)
+ $echo "$modename: cannot determine name of library object from \`$libobj'" 1>&2
+ exit 1
+ ;;
+ esac
+
+ if test -z "$base_compile"; then
+ $echo "$modename: you must specify a compilation command" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ # Delete any leftover library objects.
+ if test "$build_old_libs" = yes; then
+ removelist="$obj $libobj"
+ else
+ removelist="$libobj"
+ fi
+
+ $run $rm $removelist
+ trap "$run $rm $removelist; exit 1" 1 2 15
+
+ # Calculate the filename of the output object if compiler does
+ # not support -o with -c
+ if test "$compiler_c_o" = no; then
+ output_obj=`$echo "X$srcfile" | $Xsed -e 's%^.*/%%' -e 's%\..*$%%'`.${objext}
+ lockfile="$output_obj.lock"
+ removelist="$removelist $output_obj $lockfile"
+ trap "$run $rm $removelist; exit 1" 1 2 15
+ else
+ need_locks=no
+ lockfile=
+ fi
+
+ # Lock this critical section if it is needed
+ # We use this script file to make the link, it avoids creating a new file
+ if test "$need_locks" = yes; then
+ until ln "$0" "$lockfile" 2>/dev/null; do
+ $show "Waiting for $lockfile to be removed"
+ sleep 2
+ done
+ elif test "$need_locks" = warn; then
+ if test -f "$lockfile"; then
+ echo "\
+*** ERROR, $lockfile exists and contains:
+`cat $lockfile 2>/dev/null`
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $run $rm $removelist
+ exit 1
+ fi
+ echo $srcfile > "$lockfile"
+ fi
+
+ if test -n "$fix_srcfile_path"; then
+ eval srcfile=\"$fix_srcfile_path\"
+ fi
+
+ # Only build a PIC object if we are building libtool libraries.
+ if test "$build_libtool_libs" = yes; then
+ # Without this assignment, base_compile gets emptied.
+ fbsd_hideous_sh_bug=$base_compile
+
+ # All platforms use -DPIC, to notify preprocessed assembler code.
+ command="$base_compile $srcfile $pic_flag -DPIC"
+ if test "$build_old_libs" = yes; then
+ lo_libobj="$libobj"
+ dir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$dir" = "X$libobj"; then
+ dir="$objdir"
+ else
+ dir="$dir/$objdir"
+ fi
+ libobj="$dir/"`$echo "X$libobj" | $Xsed -e 's%^.*/%%'`
+
+ if test -d "$dir"; then
+ $show "$rm $libobj"
+ $run $rm $libobj
+ else
+ $show "$mkdir $dir"
+ $run $mkdir $dir
+ status=$?
+ if test $status -ne 0 && test ! -d $dir; then
+ exit $status
+ fi
+ fi
+ fi
+ if test "$compiler_o_lo" = yes; then
+ output_obj="$libobj"
+ command="$command -o $output_obj"
+ elif test "$compiler_c_o" = yes; then
+ output_obj="$obj"
+ command="$command -o $output_obj"
+ fi
+
+ $run $rm "$output_obj"
+ $show "$command"
+ if $run eval "$command"; then :
+ else
+ test -n "$output_obj" && $run $rm $removelist
+ exit 1
+ fi
+
+ if test "$need_locks" = warn &&
+ test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then
+ echo "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $run $rm $removelist
+ exit 1
+ fi
+
+ # Just move the object if needed, then go on to compile the next one
+ if test x"$output_obj" != x"$libobj"; then
+ $show "$mv $output_obj $libobj"
+ if $run $mv $output_obj $libobj; then :
+ else
+ error=$?
+ $run $rm $removelist
+ exit $error
+ fi
+ fi
+
+ # If we have no pic_flag, then copy the object into place and finish.
+ if test -z "$pic_flag" && test "$build_old_libs" = yes; then
+ # Rename the .lo from within objdir to obj
+ if test -f $obj; then
+ $show $rm $obj
+ $run $rm $obj
+ fi
+
+ $show "$mv $libobj $obj"
+ if $run $mv $libobj $obj; then :
+ else
+ error=$?
+ $run $rm $removelist
+ exit $error
+ fi
+
+ xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$xdir" = "X$obj"; then
+ xdir="."
+ else
+ xdir="$xdir"
+ fi
+ baseobj=`$echo "X$obj" | $Xsed -e "s%.*/%%"`
+ libobj=`$echo "X$baseobj" | $Xsed -e "$o2lo"`
+ # Now arrange that obj and lo_libobj become the same file
+ $show "(cd $xdir && $LN_S $baseobj $libobj)"
+ if $run eval '(cd $xdir && $LN_S $baseobj $libobj)'; then
+ exit 0
+ else
+ error=$?
+ $run $rm $removelist
+ exit $error
+ fi
+ fi
+
+ # Allow error messages only from the first compilation.
+ suppress_output=' >/dev/null 2>&1'
+ fi
+
+ # Only build a position-dependent object if we build old libraries.
+ if test "$build_old_libs" = yes; then
+ command="$base_compile $srcfile"
+ if test "$compiler_c_o" = yes; then
+ command="$command -o $obj"
+ output_obj="$obj"
+ fi
+
+ # Suppress compiler output if we already did a PIC compilation.
+ command="$command$suppress_output"
+ $run $rm "$output_obj"
+ $show "$command"
+ if $run eval "$command"; then :
+ else
+ $run $rm $removelist
+ exit 1
+ fi
+
+ if test "$need_locks" = warn &&
+ test x"`cat $lockfile 2>/dev/null`" != x"$srcfile"; then
+ echo "\
+*** ERROR, $lockfile contains:
+`cat $lockfile 2>/dev/null`
+
+but it should contain:
+$srcfile
+
+This indicates that another process is trying to use the same
+temporary object file, and libtool could not work around it because
+your compiler does not support \`-c' and \`-o' together. If you
+repeat this compilation, it may succeed, by chance, but you had better
+avoid parallel builds (make -j) in this platform, or get a better
+compiler."
+
+ $run $rm $removelist
+ exit 1
+ fi
+
+ # Just move the object if needed
+ if test x"$output_obj" != x"$obj"; then
+ $show "$mv $output_obj $obj"
+ if $run $mv $output_obj $obj; then :
+ else
+ error=$?
+ $run $rm $removelist
+ exit $error
+ fi
+ fi
+
+ # Create an invalid libtool object if no PIC, so that we do not
+ # accidentally link it into a program.
+ if test "$build_libtool_libs" != yes; then
+ $show "echo timestamp > $libobj"
+ $run eval "echo timestamp > \$libobj" || exit $?
+ else
+ # Move the .lo from within objdir
+ $show "$mv $libobj $lo_libobj"
+ if $run $mv $libobj $lo_libobj; then :
+ else
+ error=$?
+ $run $rm $removelist
+ exit $error
+ fi
+ fi
+ fi
+
+ # Unlock the critical section if it was locked
+ if test "$need_locks" != no; then
+ $rm "$lockfile"
+ fi
+
+ exit 0
+ ;;
+
+ # libtool link mode
+ link)
+ modename="$modename: link"
+ case "$host" in
+ *-*-cygwin* | *-*-mingw* | *-*-os2*)
+ # It is impossible to link a dll without this setting, and
+ # we shouldn't force the makefile maintainer to figure out
+ # which system we are compiling for in order to pass an extra
+ # flag for every libtool invokation.
+ # allow_undefined=no
+
+ # FIXME: Unfortunately, there are problems with the above when trying
+ # to make a dll which has undefined symbols, in which case not
+ # even a static library is built. For now, we need to specify
+ # -no-undefined on the libtool link line when we can be certain
+ # that all symbols are satisfied, otherwise we get a static library.
+ allow_undefined=yes
+
+ # This is a source program that is used to create dlls on Windows
+ # Don't remove nor modify the starting and closing comments
+# /* ltdll.c starts here */
+# #define WIN32_LEAN_AND_MEAN
+# #include <windows.h>
+# #undef WIN32_LEAN_AND_MEAN
+# #include <stdio.h>
+#
+# #ifndef __CYGWIN__
+# # ifdef __CYGWIN32__
+# # define __CYGWIN__ __CYGWIN32__
+# # endif
+# #endif
+#
+# #ifdef __cplusplus
+# extern "C" {
+# #endif
+# BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved);
+# #ifdef __cplusplus
+# }
+# #endif
+#
+# #ifdef __CYGWIN__
+# #include <cygwin/cygwin_dll.h>
+# DECLARE_CYGWIN_DLL( DllMain );
+# #endif
+# HINSTANCE __hDllInstance_base;
+#
+# BOOL APIENTRY
+# DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved)
+# {
+# __hDllInstance_base = hInst;
+# return TRUE;
+# }
+# /* ltdll.c ends here */
+ # This is a source program that is used to create import libraries
+ # on Windows for dlls which lack them. Don't remove nor modify the
+ # starting and closing comments
+# /* impgen.c starts here */
+# /* Copyright (C) 1999 Free Software Foundation, Inc.
+#
+# This file is part of GNU libtool.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+# */
+#
+# #include <stdio.h> /* for printf() */
+# #include <unistd.h> /* for open(), lseek(), read() */
+# #include <fcntl.h> /* for O_RDONLY, O_BINARY */
+# #include <string.h> /* for strdup() */
+#
+# static unsigned int
+# pe_get16 (fd, offset)
+# int fd;
+# int offset;
+# {
+# unsigned char b[2];
+# lseek (fd, offset, SEEK_SET);
+# read (fd, b, 2);
+# return b[0] + (b[1]<<8);
+# }
+#
+# static unsigned int
+# pe_get32 (fd, offset)
+# int fd;
+# int offset;
+# {
+# unsigned char b[4];
+# lseek (fd, offset, SEEK_SET);
+# read (fd, b, 4);
+# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
+# }
+#
+# static unsigned int
+# pe_as32 (ptr)
+# void *ptr;
+# {
+# unsigned char *b = ptr;
+# return b[0] + (b[1]<<8) + (b[2]<<16) + (b[3]<<24);
+# }
+#
+# int
+# main (argc, argv)
+# int argc;
+# char *argv[];
+# {
+# int dll;
+# unsigned long pe_header_offset, opthdr_ofs, num_entries, i;
+# unsigned long export_rva, export_size, nsections, secptr, expptr;
+# unsigned long name_rvas, nexp;
+# unsigned char *expdata, *erva;
+# char *filename, *dll_name;
+#
+# filename = argv[1];
+#
+# dll = open(filename, O_RDONLY|O_BINARY);
+# if (!dll)
+# return 1;
+#
+# dll_name = filename;
+#
+# for (i=0; filename[i]; i++)
+# if (filename[i] == '/' || filename[i] == '\\' || filename[i] == ':')
+# dll_name = filename + i +1;
+#
+# pe_header_offset = pe_get32 (dll, 0x3c);
+# opthdr_ofs = pe_header_offset + 4 + 20;
+# num_entries = pe_get32 (dll, opthdr_ofs + 92);
+#
+# if (num_entries < 1) /* no exports */
+# return 1;
+#
+# export_rva = pe_get32 (dll, opthdr_ofs + 96);
+# export_size = pe_get32 (dll, opthdr_ofs + 100);
+# nsections = pe_get16 (dll, pe_header_offset + 4 +2);
+# secptr = (pe_header_offset + 4 + 20 +
+# pe_get16 (dll, pe_header_offset + 4 + 16));
+#
+# expptr = 0;
+# for (i = 0; i < nsections; i++)
+# {
+# char sname[8];
+# unsigned long secptr1 = secptr + 40 * i;
+# unsigned long vaddr = pe_get32 (dll, secptr1 + 12);
+# unsigned long vsize = pe_get32 (dll, secptr1 + 16);
+# unsigned long fptr = pe_get32 (dll, secptr1 + 20);
+# lseek(dll, secptr1, SEEK_SET);
+# read(dll, sname, 8);
+# if (vaddr <= export_rva && vaddr+vsize > export_rva)
+# {
+# expptr = fptr + (export_rva - vaddr);
+# if (export_rva + export_size > vaddr + vsize)
+# export_size = vsize - (export_rva - vaddr);
+# break;
+# }
+# }
+#
+# expdata = (unsigned char*)malloc(export_size);
+# lseek (dll, expptr, SEEK_SET);
+# read (dll, expdata, export_size);
+# erva = expdata - export_rva;
+#
+# nexp = pe_as32 (expdata+24);
+# name_rvas = pe_as32 (expdata+32);
+#
+# printf ("EXPORTS\n");
+# for (i = 0; i<nexp; i++)
+# {
+# unsigned long name_rva = pe_as32 (erva+name_rvas+i*4);
+# printf ("\t%s @ %ld ;\n", erva+name_rva, 1+ i);
+# }
+#
+# return 0;
+# }
+# /* impgen.c ends here */
+ ;;
+ *)
+ allow_undefined=yes
+ ;;
+ esac
+ compile_command="$nonopt"
+ finalize_command="$nonopt"
+
+ compile_rpath=
+ finalize_rpath=
+ compile_shlibpath=
+ finalize_shlibpath=
+ convenience=
+ old_convenience=
+ deplibs=
+ linkopts=
+
+ if test -n "$shlibpath_var"; then
+ # get the directories listed in $shlibpath_var
+ eval lib_search_path=\`\$echo \"X \${$shlibpath_var}\" \| \$Xsed -e \'s/:/ /g\'\`
+ else
+ lib_search_path=
+ fi
+ # now prepend the system-specific ones
+ eval lib_search_path=\"$sys_lib_search_path_spec\$lib_search_path\"
+ eval sys_lib_dlsearch_path=\"$sys_lib_dlsearch_path_spec\"
+
+ avoid_version=no
+ dlfiles=
+ dlprefiles=
+ dlself=no
+ export_dynamic=no
+ export_symbols=
+ export_symbols_regex=
+ generated=
+ libobjs=
+ link_against_libtool_libs=
+ ltlibs=
+ module=no
+ objs=
+ prefer_static_libs=no
+ preload=no
+ prev=
+ prevarg=
+ release=
+ rpath=
+ xrpath=
+ perm_rpath=
+ temp_rpath=
+ thread_safe=no
+ vinfo=
+
+ # We need to know -static, to get the right output filenames.
+ for arg
+ do
+ case "$arg" in
+ -all-static | -static)
+ if test "X$arg" = "X-all-static"; then
+ if test "$build_libtool_libs" = yes && test -z "$link_static_flag"; then
+ $echo "$modename: warning: complete static linking is impossible in this configuration" 1>&2
+ fi
+ if test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ else
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ dlopen_self=$dlopen_self_static
+ fi
+ fi
+ build_libtool_libs=no
+ build_old_libs=yes
+ prefer_static_libs=yes
+ break
+ ;;
+ esac
+ done
+
+ # See if our shared archives depend on static archives.
+ test -n "$old_archive_from_new_cmds" && build_old_libs=yes
+
+ # Go through the arguments, transforming them on the way.
+ while test $# -gt 0; do
+ arg="$1"
+ shift
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$prev"; then
+ case "$prev" in
+ output)
+ compile_command="$compile_command @OUTPUT@"
+ finalize_command="$finalize_command @OUTPUT@"
+ ;;
+ esac
+
+ case "$prev" in
+ dlfiles|dlprefiles)
+ if test "$preload" = no; then
+ # Add the symbol object into the linking commands.
+ compile_command="$compile_command @SYMFILE@"
+ finalize_command="$finalize_command @SYMFILE@"
+ preload=yes
+ fi
+ case "$arg" in
+ *.la | *.lo) ;; # We handle these cases below.
+ force)
+ if test "$dlself" = no; then
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ self)
+ if test "$prev" = dlprefiles; then
+ dlself=yes
+ elif test "$prev" = dlfiles && test "$dlopen_self" != yes; then
+ dlself=yes
+ else
+ dlself=needless
+ export_dynamic=yes
+ fi
+ prev=
+ continue
+ ;;
+ *)
+ if test "$prev" = dlfiles; then
+ dlfiles="$dlfiles $arg"
+ else
+ dlprefiles="$dlprefiles $arg"
+ fi
+ prev=
+ ;;
+ esac
+ ;;
+ expsyms)
+ export_symbols="$arg"
+ if test ! -f "$arg"; then
+ $echo "$modename: symbol file \`$arg' does not exist"
+ exit 1
+ fi
+ prev=
+ continue
+ ;;
+ expsyms_regex)
+ export_symbols_regex="$arg"
+ prev=
+ continue
+ ;;
+ release)
+ release="-$arg"
+ prev=
+ continue
+ ;;
+ rpath | xrpath)
+ # We need an absolute path.
+ case "$arg" in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ $echo "$modename: only absolute run-paths are allowed" 1>&2
+ exit 1
+ ;;
+ esac
+ if test "$prev" = rpath; then
+ case "$rpath " in
+ *" $arg "*) ;;
+ *) rpath="$rpath $arg" ;;
+ esac
+ else
+ case "$xrpath " in
+ *" $arg "*) ;;
+ *) xrpath="$xrpath $arg" ;;
+ esac
+ fi
+ prev=
+ continue
+ ;;
+ *)
+ eval "$prev=\"\$arg\""
+ prev=
+ continue
+ ;;
+ esac
+ fi
+
+ prevarg="$arg"
+
+ case "$arg" in
+ -all-static)
+ if test -n "$link_static_flag"; then
+ compile_command="$compile_command $link_static_flag"
+ finalize_command="$finalize_command $link_static_flag"
+ fi
+ continue
+ ;;
+
+ -allow-undefined)
+ # FIXME: remove this flag sometime in the future.
+ $echo "$modename: \`-allow-undefined' is deprecated because it is the default" 1>&2
+ continue
+ ;;
+
+ -avoid-version)
+ avoid_version=yes
+ continue
+ ;;
+
+ -dlopen)
+ prev=dlfiles
+ continue
+ ;;
+
+ -dlpreopen)
+ prev=dlprefiles
+ continue
+ ;;
+
+ -export-dynamic)
+ export_dynamic=yes
+ continue
+ ;;
+
+ -export-symbols | -export-symbols-regex)
+ if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+ $echo "$modename: not more than one -exported-symbols argument allowed"
+ exit 1
+ fi
+ if test "X$arg" = "X-export-symbols"; then
+ prev=expsyms
+ else
+ prev=expsyms_regex
+ fi
+ continue
+ ;;
+
+ -L*)
+ dir=`$echo "X$arg" | $Xsed -e 's/^-L//'`
+ # We need an absolute path.
+ case "$dir" in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ if test -z "$absdir"; then
+ $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2
+ $echo "$modename: passing it literally to the linker, although it might fail" 1>&2
+ absdir="$dir"
+ fi
+ dir="$absdir"
+ ;;
+ esac
+ case " $deplibs " in
+ *" $arg "*) ;;
+ *) deplibs="$deplibs $arg";;
+ esac
+ case " $lib_search_path " in
+ *" $dir "*) ;;
+ *) lib_search_path="$lib_search_path $dir";;
+ esac
+ case "$host" in
+ *-*-cygwin* | *-*-mingw* | *-*-os2*)
+ dllsearchdir=`cd "$dir" && pwd || echo "$dir"`
+ case ":$dllsearchpath:" in
+ ::) dllsearchpath="$dllsearchdir";;
+ *":$dllsearchdir:"*) ;;
+ *) dllsearchpath="$dllsearchpath:$dllsearchdir";;
+ esac
+ ;;
+ esac
+ ;;
+
+ -l*)
+ if test "$arg" = "-lc"; then
+ case "$host" in
+ *-*-cygwin* | *-*-mingw* | *-*-os2* | *-*-beos*)
+ # These systems don't actually have c library (as such)
+ continue
+ ;;
+ esac
+ elif test "$arg" = "-lm"; then
+ case "$host" in
+ *-*-cygwin* | *-*-beos*)
+ # These systems don't actually have math library (as such)
+ continue
+ ;;
+ esac
+ fi
+ deplibs="$deplibs $arg"
+ ;;
+
+ -module)
+ module=yes
+ continue
+ ;;
+
+ -no-undefined)
+ allow_undefined=no
+ continue
+ ;;
+
+ -o) prev=output ;;
+
+ -release)
+ prev=release
+ continue
+ ;;
+
+ -rpath)
+ prev=rpath
+ continue
+ ;;
+
+ -R)
+ prev=xrpath
+ continue
+ ;;
+
+ -R*)
+ dir=`$echo "X$arg" | $Xsed -e 's/^-R//'`
+ # We need an absolute path.
+ case "$dir" in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ $echo "$modename: only absolute run-paths are allowed" 1>&2
+ exit 1
+ ;;
+ esac
+ case "$xrpath " in
+ *" $dir "*) ;;
+ *) xrpath="$xrpath $dir" ;;
+ esac
+ continue
+ ;;
+
+ -static)
+ # If we have no pic_flag, then this is the same as -all-static.
+ if test -z "$pic_flag" && test -n "$link_static_flag"; then
+ compile_command="$compile_command $link_static_flag"
+ finalize_command="$finalize_command $link_static_flag"
+ fi
+ continue
+ ;;
+
+ -thread-safe)
+ thread_safe=yes
+ continue
+ ;;
+
+ -version-info)
+ prev=vinfo
+ continue
+ ;;
+
+ # Some other compiler flag.
+ -* | +*)
+ # Unknown arguments in both finalize_command and compile_command need
+ # to be aesthetically quoted because they are evaled later.
+ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+ case "$arg" in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ arg="\"$arg\""
+ ;;
+ esac
+ ;;
+
+ *.o | *.obj | *.a | *.lib)
+ # A standard object.
+ objs="$objs $arg"
+ ;;
+
+ *.lo)
+ # A library object.
+ if test "$prev" = dlfiles; then
+ dlfiles="$dlfiles $arg"
+ if test "$build_libtool_libs" = yes && test "$dlopen" = yes; then
+ prev=
+ continue
+ else
+ # If libtool objects are unsupported, then we need to preload.
+ prev=dlprefiles
+ fi
+ fi
+
+ if test "$prev" = dlprefiles; then
+ # Preload the old-style object.
+ dlprefiles="$dlprefiles "`$echo "X$arg" | $Xsed -e "$lo2o"`
+ prev=
+ fi
+ libobjs="$libobjs $arg"
+ ;;
+
+ *.la)
+ # A libtool-controlled library.
+
+ dlname=
+ libdir=
+ library_names=
+ old_library=
+
+ # Check to see that this really is a libtool archive.
+ if (sed -e '2q' $arg | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+ else
+ $echo "$modename: \`$arg' is not a valid libtool archive" 1>&2
+ exit 1
+ fi
+
+ # If the library was installed with an old release of libtool,
+ # it will not redefine variable installed.
+ installed=yes
+
+ # Read the .la file
+ # If there is no directory component, then add one.
+ case "$arg" in
+ */* | *\\*) . $arg ;;
+ *) . ./$arg ;;
+ esac
+
+ # Get the name of the library we link against.
+ linklib=
+ for l in $old_library $library_names; do
+ linklib="$l"
+ done
+
+ if test -z "$linklib"; then
+ $echo "$modename: cannot find name of link library for \`$arg'" 1>&2
+ exit 1
+ fi
+
+ # Find the relevant object directory and library name.
+ name=`$echo "X$arg" | $Xsed -e 's%^.*/%%' -e 's/\.la$//' -e 's/^lib//'`
+
+ if test "X$installed" = Xyes; then
+ dir="$libdir"
+ else
+ dir=`$echo "X$arg" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$dir" = "X$arg"; then
+ dir="$objdir"
+ else
+ dir="$dir/$objdir"
+ fi
+ fi
+
+ if test -n "$dependency_libs"; then
+ # Extract -R and -L from dependency_libs
+ temp_deplibs=
+ for deplib in $dependency_libs; do
+ case "$deplib" in
+ -R*) temp_xrpath=`$echo "X$deplib" | $Xsed -e 's/^-R//'`
+ case " $rpath $xrpath " in
+ *" $temp_xrpath "*) ;;
+ *) xrpath="$xrpath $temp_xrpath";;
+ esac;;
+ -L*) case "$compile_command $temp_deplibs " in
+ *" $deplib "*) ;;
+ *) temp_deplibs="$temp_deplibs $deplib";;
+ esac
+ temp_dir=`$echo "X$deplib" | $Xsed -e 's/^-L//'`
+ case " $lib_search_path " in
+ *" $temp_dir "*) ;;
+ *) lib_search_path="$lib_search_path $temp_dir";;
+ esac
+ ;;
+ *) temp_deplibs="$temp_deplibs $deplib";;
+ esac
+ done
+ dependency_libs="$temp_deplibs"
+ fi
+
+ if test -z "$libdir"; then
+ # It is a libtool convenience library, so add in its objects.
+ convenience="$convenience $dir/$old_library"
+ old_convenience="$old_convenience $dir/$old_library"
+ deplibs="$deplibs$dependency_libs"
+ compile_command="$compile_command $dir/$old_library$dependency_libs"
+ finalize_command="$finalize_command $dir/$old_library$dependency_libs"
+ continue
+ fi
+
+ # This library was specified with -dlopen.
+ if test "$prev" = dlfiles; then
+ dlfiles="$dlfiles $arg"
+ if test -z "$dlname" || test "$dlopen" != yes || test "$build_libtool_libs" = no; then
+ # If there is no dlname, no dlopen support or we're linking statically,
+ # we need to preload.
+ prev=dlprefiles
+ else
+ # We should not create a dependency on this library, but we
+ # may need any libraries it requires.
+ compile_command="$compile_command$dependency_libs"
+ finalize_command="$finalize_command$dependency_libs"
+ prev=
+ continue
+ fi
+ fi
+
+ # The library was specified with -dlpreopen.
+ if test "$prev" = dlprefiles; then
+ # Prefer using a static library (so that no silly _DYNAMIC symbols
+ # are required to link).
+ if test -n "$old_library"; then
+ dlprefiles="$dlprefiles $dir/$old_library"
+ else
+ dlprefiles="$dlprefiles $dir/$linklib"
+ fi
+ prev=
+ fi
+
+ if test -n "$library_names" &&
+ { test "$prefer_static_libs" = no || test -z "$old_library"; }; then
+ link_against_libtool_libs="$link_against_libtool_libs $arg"
+ if test -n "$shlibpath_var"; then
+ # Make sure the rpath contains only unique directories.
+ case "$temp_rpath " in
+ *" $dir "*) ;;
+ *) temp_rpath="$temp_rpath $dir" ;;
+ esac
+ fi
+
+ # We need an absolute path.
+ case "$dir" in
+ [\\/] | [A-Za-z]:[\\/]*) absdir="$dir" ;;
+ *)
+ absdir=`cd "$dir" && pwd`
+ if test -z "$absdir"; then
+ $echo "$modename: warning: cannot determine absolute directory name of \`$dir'" 1>&2
+ $echo "$modename: passing it literally to the linker, although it might fail" 1>&2
+ absdir="$dir"
+ fi
+ ;;
+ esac
+
+ # This is the magic to use -rpath.
+ # Skip directories that are in the system default run-time
+ # search path, unless they have been requested with -R.
+ case " $sys_lib_dlsearch_path " in
+ *" $absdir "*) ;;
+ *)
+ case "$compile_rpath " in
+ *" $absdir "*) ;;
+ *) compile_rpath="$compile_rpath $absdir"
+ esac
+ ;;
+ esac
+
+ case " $sys_lib_dlsearch_path " in
+ *" $libdir "*) ;;
+ *)
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_rpath="$finalize_rpath $libdir"
+ esac
+ ;;
+ esac
+
+ lib_linked=yes
+ case "$hardcode_action" in
+ immediate | unsupported)
+ if test "$hardcode_direct" = no; then
+ compile_command="$compile_command $dir/$linklib"
+ deplibs="$deplibs $dir/$linklib"
+ case "$host" in
+ *-*-cygwin* | *-*-mingw* | *-*-os2*)
+ dllsearchdir=`cd "$dir" && pwd || echo "$dir"`
+ if test -n "$dllsearchpath"; then
+ dllsearchpath="$dllsearchpath:$dllsearchdir"
+ else
+ dllsearchpath="$dllsearchdir"
+ fi
+ ;;
+ esac
+ elif test "$hardcode_minus_L" = no; then
+ case "$host" in
+ *-*-sunos*)
+ compile_shlibpath="$compile_shlibpath$dir:"
+ ;;
+ esac
+ case "$compile_command " in
+ *" -L$dir "*) ;;
+ *) compile_command="$compile_command -L$dir";;
+ esac
+ compile_command="$compile_command -l$name"
+ deplibs="$deplibs -L$dir -l$name"
+ elif test "$hardcode_shlibpath_var" = no; then
+ case ":$compile_shlibpath:" in
+ *":$dir:"*) ;;
+ *) compile_shlibpath="$compile_shlibpath$dir:";;
+ esac
+ compile_command="$compile_command -l$name"
+ deplibs="$deplibs -l$name"
+ else
+ lib_linked=no
+ fi
+ ;;
+
+ relink)
+ if test "$hardcode_direct" = yes; then
+ compile_command="$compile_command $absdir/$linklib"
+ deplibs="$deplibs $absdir/$linklib"
+ elif test "$hardcode_minus_L" = yes; then
+ case "$compile_command " in
+ *" -L$absdir "*) ;;
+ *) compile_command="$compile_command -L$absdir";;
+ esac
+ compile_command="$compile_command -l$name"
+ deplibs="$deplibs -L$absdir -l$name"
+ elif test "$hardcode_shlibpath_var" = yes; then
+ case ":$compile_shlibpath:" in
+ *":$absdir:"*) ;;
+ *) compile_shlibpath="$compile_shlibpath$absdir:";;
+ esac
+ compile_command="$compile_command -l$name"
+ deplibs="$deplibs -l$name"
+ else
+ lib_linked=no
+ fi
+ ;;
+
+ *)
+ lib_linked=no
+ ;;
+ esac
+
+ if test "$lib_linked" != yes; then
+ $echo "$modename: configuration error: unsupported hardcode properties"
+ exit 1
+ fi
+
+ # Finalize command for both is simple: just hardcode it.
+ if test "$hardcode_direct" = yes; then
+ finalize_command="$finalize_command $libdir/$linklib"
+ elif test "$hardcode_minus_L" = yes; then
+ case "$finalize_command " in
+ *" -L$libdir "*) ;;
+ *) finalize_command="$finalize_command -L$libdir";;
+ esac
+ finalize_command="$finalize_command -l$name"
+ elif test "$hardcode_shlibpath_var" = yes; then
+ case ":$finalize_shlibpath:" in
+ *":$libdir:"*) ;;
+ *) finalize_shlibpath="$finalize_shlibpath$libdir:";;
+ esac
+ finalize_command="$finalize_command -l$name"
+ else
+ # We cannot seem to hardcode it, guess we'll fake it.
+ case "$finalize_command " in
+ *" -L$dir "*) ;;
+ *) finalize_command="$finalize_command -L$libdir";;
+ esac
+ finalize_command="$finalize_command -l$name"
+ fi
+ else
+ # Transform directly to old archives if we don't build new libraries.
+ if test -n "$pic_flag" && test -z "$old_library"; then
+ $echo "$modename: cannot find static library for \`$arg'" 1>&2
+ exit 1
+ fi
+
+ # Here we assume that one of hardcode_direct or hardcode_minus_L
+ # is not unsupported. This is valid on all known static and
+ # shared platforms.
+ if test "$hardcode_direct" != unsupported; then
+ test -n "$old_library" && linklib="$old_library"
+ compile_command="$compile_command $dir/$linklib"
+ finalize_command="$finalize_command $dir/$linklib"
+ else
+ case "$compile_command " in
+ *" -L$dir "*) ;;
+ *) compile_command="$compile_command -L$dir";;
+ esac
+ compile_command="$compile_command -l$name"
+ case "$finalize_command " in
+ *" -L$dir "*) ;;
+ *) finalize_command="$finalize_command -L$dir";;
+ esac
+ finalize_command="$finalize_command -l$name"
+ fi
+ fi
+
+ # Add in any libraries that this one depends upon.
+ compile_command="$compile_command$dependency_libs"
+ finalize_command="$finalize_command$dependency_libs"
+ continue
+ ;;
+
+ # Some other compiler argument.
+ *)
+ # Unknown arguments in both finalize_command and compile_command need
+ # to be aesthetically quoted because they are evaled later.
+ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+ case "$arg" in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ arg="\"$arg\""
+ ;;
+ esac
+ ;;
+ esac
+
+ # Now actually substitute the argument into the commands.
+ if test -n "$arg"; then
+ compile_command="$compile_command $arg"
+ finalize_command="$finalize_command $arg"
+ fi
+ done
+
+ if test -n "$prev"; then
+ $echo "$modename: the \`$prevarg' option requires an argument" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ if test "$export_dynamic" = yes && test -n "$export_dynamic_flag_spec"; then
+ eval arg=\"$export_dynamic_flag_spec\"
+ compile_command="$compile_command $arg"
+ finalize_command="$finalize_command $arg"
+ fi
+
+ oldlibs=
+ # calculate the name of the file, without its directory
+ outputname=`$echo "X$output" | $Xsed -e 's%^.*/%%'`
+ libobjs_save="$libobjs"
+
+ case "$output" in
+ "")
+ $echo "$modename: you must specify an output file" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+
+ *.a | *.lib)
+ if test -n "$link_against_libtool_libs"; then
+ $echo "$modename: error: cannot link libtool libraries into archives" 1>&2
+ exit 1
+ fi
+
+ if test -n "$deplibs"; then
+ $echo "$modename: warning: \`-l' and \`-L' are ignored for archives" 1>&2
+ fi
+
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ $echo "$modename: warning: \`-dlopen' is ignored for archives" 1>&2
+ fi
+
+ if test -n "$rpath"; then
+ $echo "$modename: warning: \`-rpath' is ignored for archives" 1>&2
+ fi
+
+ if test -n "$xrpath"; then
+ $echo "$modename: warning: \`-R' is ignored for archives" 1>&2
+ fi
+
+ if test -n "$vinfo"; then
+ $echo "$modename: warning: \`-version-info' is ignored for archives" 1>&2
+ fi
+
+ if test -n "$release"; then
+ $echo "$modename: warning: \`-release' is ignored for archives" 1>&2
+ fi
+
+ if test -n "$export_symbols" || test -n "$export_symbols_regex"; then
+ $echo "$modename: warning: \`-export-symbols' is ignored for archives" 1>&2
+ fi
+
+ # Now set the variables for building old libraries.
+ build_libtool_libs=no
+ oldlibs="$output"
+ ;;
+
+ *.la)
+ # Make sure we only generate libraries of the form `libNAME.la'.
+ case "$outputname" in
+ lib*)
+ name=`$echo "X$outputname" | $Xsed -e 's/\.la$//' -e 's/^lib//'`
+ eval libname=\"$libname_spec\"
+ ;;
+ *)
+ if test "$module" = no; then
+ $echo "$modename: libtool library \`$output' must begin with \`lib'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+ if test "$need_lib_prefix" != no; then
+ # Add the "lib" prefix for modules if required
+ name=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
+ eval libname=\"$libname_spec\"
+ else
+ libname=`$echo "X$outputname" | $Xsed -e 's/\.la$//'`
+ fi
+ ;;
+ esac
+
+ output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$output_objdir" = "X$output"; then
+ output_objdir="$objdir"
+ else
+ output_objdir="$output_objdir/$objdir"
+ fi
+
+ if test -n "$objs"; then
+ $echo "$modename: cannot build libtool library \`$output' from non-libtool objects:$objs" 2>&1
+ exit 1
+ fi
+
+ # How the heck are we supposed to write a wrapper for a shared library?
+ if test -n "$link_against_libtool_libs"; then
+ $echo "$modename: error: cannot link shared libraries into libtool libraries" 1>&2
+ exit 1
+ fi
+
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ $echo "$modename: warning: \`-dlopen' is ignored for libtool libraries" 1>&2
+ fi
+
+ set dummy $rpath
+ if test $# -gt 2; then
+ $echo "$modename: warning: ignoring multiple \`-rpath's for a libtool library" 1>&2
+ fi
+ install_libdir="$2"
+
+ oldlibs=
+ if test -z "$rpath"; then
+ if test "$build_libtool_libs" = yes; then
+ # Building a libtool convenience library.
+ libext=al
+ oldlibs="$output_objdir/$libname.$libext $oldlibs"
+ build_libtool_libs=convenience
+ build_old_libs=yes
+ fi
+ dependency_libs="$deplibs"
+
+ if test -n "$vinfo"; then
+ $echo "$modename: warning: \`-version-info' is ignored for convenience libraries" 1>&2
+ fi
+
+ if test -n "$release"; then
+ $echo "$modename: warning: \`-release' is ignored for convenience libraries" 1>&2
+ fi
+ else
+
+ # Parse the version information argument.
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS=':'
+ set dummy $vinfo 0 0 0
+ IFS="$save_ifs"
+
+ if test -n "$8"; then
+ $echo "$modename: too many parameters to \`-version-info'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ current="$2"
+ revision="$3"
+ age="$4"
+
+ # Check that each of the things are valid numbers.
+ case "$current" in
+ [0-9]*) ;;
+ *)
+ $echo "$modename: CURRENT \`$current' is not a nonnegative integer" 1>&2
+ $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+ exit 1
+ ;;
+ esac
+
+ case "$revision" in
+ [0-9]*) ;;
+ *)
+ $echo "$modename: REVISION \`$revision' is not a nonnegative integer" 1>&2
+ $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+ exit 1
+ ;;
+ esac
+
+ case "$age" in
+ [0-9]*) ;;
+ *)
+ $echo "$modename: AGE \`$age' is not a nonnegative integer" 1>&2
+ $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+ exit 1
+ ;;
+ esac
+
+ if test $age -gt $current; then
+ $echo "$modename: AGE \`$age' is greater than the current interface number \`$current'" 1>&2
+ $echo "$modename: \`$vinfo' is not valid version information" 1>&2
+ exit 1
+ fi
+
+ # Calculate the version variables.
+ major=
+ versuffix=
+ verstring=
+ case "$version_type" in
+ none) ;;
+
+ irix)
+ major=`expr $current - $age + 1`
+ versuffix="$major.$revision"
+ verstring="sgi$major.$revision"
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$revision
+ while test $loop != 0; do
+ iface=`expr $revision - $loop`
+ loop=`expr $loop - 1`
+ verstring="sgi$major.$iface:$verstring"
+ done
+ ;;
+
+ linux)
+ major=.`expr $current - $age`
+ versuffix="$major.$age.$revision"
+ ;;
+
+ osf)
+ major=`expr $current - $age`
+ versuffix=".$current.$age.$revision"
+ verstring="$current.$age.$revision"
+
+ # Add in all the interfaces that we are compatible with.
+ loop=$age
+ while test $loop != 0; do
+ iface=`expr $current - $loop`
+ loop=`expr $loop - 1`
+ verstring="$verstring:${iface}.0"
+ done
+
+ # Make executables depend on our current version.
+ verstring="$verstring:${current}.0"
+ ;;
+
+ sunos)
+ major=".$current"
+ versuffix=".$current.$revision"
+ ;;
+
+ freebsd-aout)
+ major=".$current"
+ versuffix=".$current.$revision";
+ ;;
+
+ freebsd-elf)
+ major=".$current"
+ versuffix=".$current";
+ ;;
+
+ windows)
+ # Like Linux, but with '-' rather than '.', since we only
+ # want one extension on Windows 95.
+ major=`expr $current - $age`
+ versuffix="-$major-$age-$revision"
+ ;;
+
+ *)
+ $echo "$modename: unknown library version type \`$version_type'" 1>&2
+ echo "Fatal configuration error. See the $PACKAGE docs for more information." 1>&2
+ exit 1
+ ;;
+ esac
+
+ # Clear the version info if we defaulted, and they specified a release.
+ if test -z "$vinfo" && test -n "$release"; then
+ major=
+ verstring="0.0"
+ if test "$need_version" = no; then
+ versuffix=
+ else
+ versuffix=".0.0"
+ fi
+ fi
+
+ # Remove version info from name if versioning should be avoided
+ if test "$avoid_version" = yes && test "$need_version" = no; then
+ major=
+ versuffix=
+ verstring=""
+ fi
+
+ # Check to see if the archive will have undefined symbols.
+ if test "$allow_undefined" = yes; then
+ if test "$allow_undefined_flag" = unsupported; then
+ $echo "$modename: warning: undefined symbols not allowed in $host shared libraries" 1>&2
+ build_libtool_libs=no
+ build_old_libs=yes
+ fi
+ else
+ # Don't allow undefined symbols.
+ allow_undefined_flag="$no_undefined_flag"
+ fi
+
+ dependency_libs="$deplibs"
+ case "$host" in
+ *-*-cygwin* | *-*-mingw* | *-*-os2* | *-*-beos*)
+ # these systems don't actually have a c library (as such)!
+ ;;
+ *-*-rhapsody*)
+ # rhapsody is a little odd...
+ deplibs="$deplibs -framework System"
+ ;;
+ *)
+ # Add libc to deplibs on all other systems.
+ deplibs="$deplibs -lc"
+ ;;
+ esac
+ fi
+
+ # Create the output directory, or remove our outputs if we need to.
+ if test -d $output_objdir; then
+ $show "${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*"
+ $run ${rm}r $output_objdir/$outputname $output_objdir/$libname.* $output_objdir/${libname}${release}.*
+ else
+ $show "$mkdir $output_objdir"
+ $run $mkdir $output_objdir
+ status=$?
+ if test $status -ne 0 && test ! -d $output_objdir; then
+ exit $status
+ fi
+ fi
+
+ # Now set the variables for building old libraries.
+ if test "$build_old_libs" = yes && test "$build_libtool_libs" != convenience ; then
+ oldlibs="$oldlibs $output_objdir/$libname.$libext"
+
+ # Transform .lo files to .o files.
+ oldobjs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e "$lo2o" | $NL2SP`
+ fi
+
+ if test "$build_libtool_libs" = yes; then
+ # Transform deplibs into only deplibs that can be linked in shared.
+ name_save=$name
+ libname_save=$libname
+ release_save=$release
+ versuffix_save=$versuffix
+ major_save=$major
+ # I'm not sure if I'm treating the release correctly. I think
+ # release should show up in the -l (ie -lgmp5) so we don't want to
+ # add it in twice. Is that correct?
+ release=""
+ versuffix=""
+ major=""
+ newdeplibs=
+ droppeddeps=no
+ case "$deplibs_check_method" in
+ pass_all)
+ # Don't check for shared/static. Everything works.
+ # This might be a little naive. We might want to check
+ # whether the library exists or not. But this is on
+ # osf3 & osf4 and I'm not really sure... Just
+ # implementing what was already the behaviour.
+ newdeplibs=$deplibs
+ ;;
+ test_compile)
+ # This code stresses the "libraries are programs" paradigm to its
+ # limits. Maybe even breaks it. We compile a program, linking it
+ # against the deplibs as a proxy for the library. Then we can check
+ # whether they linked in statically or dynamically with ldd.
+ $rm conftest.c
+ cat > conftest.c <<EOF
+ int main() { return 0; }
+EOF
+ $rm conftest
+ $CC -o conftest conftest.c $deplibs
+ if test $? -eq 0 ; then
+ ldd_output=`ldd conftest`
+ for i in $deplibs; do
+ name="`expr $i : '-l\(.*\)'`"
+ # If $name is empty we are operating on a -L argument.
+ if test "$name" != "" ; then
+ libname=`eval \\$echo \"$libname_spec\"`
+ deplib_matches=`eval \\$echo \"$library_names_spec\"`
+ set dummy $deplib_matches
+ deplib_match=$2
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+ newdeplibs="$newdeplibs $i"
+ else
+ droppeddeps=yes
+ echo
+ echo "*** Warning: This library needs some functionality provided by $i."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have."
+ fi
+ else
+ newdeplibs="$newdeplibs $i"
+ fi
+ done
+ else
+ # Error occured in the first compile. Let's try to salvage the situation:
+ # Compile a seperate program for each library.
+ for i in $deplibs; do
+ name="`expr $i : '-l\(.*\)'`"
+ # If $name is empty we are operating on a -L argument.
+ if test "$name" != "" ; then
+ $rm conftest
+ $CC -o conftest conftest.c $i
+ # Did it work?
+ if test $? -eq 0 ; then
+ ldd_output=`ldd conftest`
+ libname=`eval \\$echo \"$libname_spec\"`
+ deplib_matches=`eval \\$echo \"$library_names_spec\"`
+ set dummy $deplib_matches
+ deplib_match=$2
+ if test `expr "$ldd_output" : ".*$deplib_match"` -ne 0 ; then
+ newdeplibs="$newdeplibs $i"
+ else
+ droppeddeps=yes
+ echo
+ echo "*** Warning: This library needs some functionality provided by $i."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have."
+ fi
+ else
+ droppeddeps=yes
+ echo
+ echo "*** Warning! Library $i is needed by this library but I was not able to"
+ echo "*** make it link in! You will probably need to install it or some"
+ echo "*** library that it depends on before this library will be fully"
+ echo "*** functional. Installing it before continuing would be even better."
+ fi
+ else
+ newdeplibs="$newdeplibs $i"
+ fi
+ done
+ fi
+ ;;
+ file_magic*)
+ set dummy $deplibs_check_method
+ file_magic_regex="`expr \"$deplibs_check_method\" : \"$2 \(.*\)\"`"
+ for a_deplib in $deplibs; do
+ name="`expr $a_deplib : '-l\(.*\)'`"
+ # If $name is empty we are operating on a -L argument.
+ if test "$name" != "" ; then
+ libname=`eval \\$echo \"$libname_spec\"`
+ for i in $lib_search_path; do
+ potential_libs=`ls $i/$libname[.-]* 2>/dev/null`
+ for potent_lib in $potential_libs; do
+ # Follow soft links.
+ if ls -lLd "$potent_lib" 2>/dev/null \
+ | grep " -> " >/dev/null; then
+ continue
+ fi
+ # The statement above tries to avoid entering an
+ # endless loop below, in case of cyclic links.
+ # We might still enter an endless loop, since a link
+ # loop can be closed while we follow links,
+ # but so what?
+ potlib="$potent_lib"
+ while test -h "$potlib" 2>/dev/null; do
+ potliblink=`ls -ld $potlib | sed 's/.* -> //'`
+ case "$potliblink" in
+ [\\/]* | [A-Za-z]:[\\/]*) potlib="$potliblink";;
+ *) potlib=`$echo "X$potlib" | $Xsed -e 's,[^/]*$,,'`"$potliblink";;
+ esac
+ done
+ if eval $file_magic_cmd \"\$potlib\" 2>/dev/null \
+ | sed 10q \
+ | egrep "$file_magic_regex" > /dev/null; then
+ newdeplibs="$newdeplibs $a_deplib"
+ a_deplib=""
+ break 2
+ fi
+ done
+ done
+ if test -n "$a_deplib" ; then
+ droppeddeps=yes
+ echo
+ echo "*** Warning: This library needs some functionality provided by $a_deplib."
+ echo "*** I have the capability to make that library automatically link in when"
+ echo "*** you link to this library. But I can only do this if you have a"
+ echo "*** shared version of the library, which you do not appear to have."
+ fi
+ else
+ # Add a -L argument.
+ newdeplibs="$newdeplibs $a_deplib"
+ fi
+ done # Gone through all deplibs.
+ ;;
+ none | unknown | *)
+ newdeplibs=""
+ if $echo "X $deplibs" | $Xsed -e 's/ -lc$//' \
+ -e 's/ -[LR][^ ]*//g' -e 's/[ ]//g' |
+ grep . >/dev/null; then
+ echo
+ if test "X$deplibs_check_method" = "Xnone"; then
+ echo "*** Warning: inter-library dependencies are not supported in this platform."
+ else
+ echo "*** Warning: inter-library dependencies are not known to be supported."
+ fi
+ echo "*** All declared inter-library dependencies are being dropped."
+ droppeddeps=yes
+ fi
+ ;;
+ esac
+ versuffix=$versuffix_save
+ major=$major_save
+ release=$release_save
+ libname=$libname_save
+ name=$name_save
+
+ if test "$droppeddeps" = yes; then
+ if test "$module" = yes; then
+ echo
+ echo "*** Warning: libtool could not satisfy all declared inter-library"
+ echo "*** dependencies of module $libname. Therefore, libtool will create"
+ echo "*** a static module, that should work as long as the dlopening"
+ echo "*** application is linked with the -dlopen flag."
+ if test -z "$global_symbol_pipe"; then
+ echo
+ echo "*** However, this would only work if libtool was able to extract symbol"
+ echo "*** lists from a program, using \`nm' or equivalent, but libtool could"
+ echo "*** not find such a program. So, this module is probably useless."
+ echo "*** \`nm' from GNU binutils and a full rebuild may help."
+ fi
+ if test "$build_old_libs" = no; then
+ oldlibs="$output_objdir/$libname.$libext"
+ build_libtool_libs=module
+ build_old_libs=yes
+ else
+ build_libtool_libs=no
+ fi
+ else
+ echo "*** The inter-library dependencies that have been dropped here will be"
+ echo "*** automatically added whenever a program is linked with this library"
+ echo "*** or is declared to -dlopen it."
+ fi
+ fi
+ # Done checking deplibs!
+ deplibs=$newdeplibs
+ fi
+
+ # All the library-specific variables (install_libdir is set above).
+ library_names=
+ old_library=
+ dlname=
+
+ # Test again, we may have decided not to build it any more
+ if test "$build_libtool_libs" = yes; then
+ # Get the real and link names of the library.
+ eval library_names=\"$library_names_spec\"
+ set dummy $library_names
+ realname="$2"
+ shift; shift
+
+ if test -n "$soname_spec"; then
+ eval soname=\"$soname_spec\"
+ else
+ soname="$realname"
+ fi
+
+ lib="$output_objdir/$realname"
+ for link
+ do
+ linknames="$linknames $link"
+ done
+
+ # Ensure that we have .o objects for linkers which dislike .lo
+ # (e.g. aix) in case we are running --disable-static
+ for obj in $libobjs; do
+ xdir=`$echo "X$obj" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$xdir" = "X$obj"; then
+ xdir="."
+ else
+ xdir="$xdir"
+ fi
+ baseobj=`$echo "X$obj" | $Xsed -e 's%^.*/%%'`
+ oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"`
+ if test ! -f $xdir/$oldobj; then
+ $show "(cd $xdir && ${LN_S} $baseobj $oldobj)"
+ $run eval '(cd $xdir && ${LN_S} $baseobj $oldobj)' || exit $?
+ fi
+ done
+
+ # Use standard objects if they are pic
+ test -z "$pic_flag" && libobjs=`$echo "X$libobjs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ if test "$always_export_symbols" = yes || test -n "$export_symbols_regex"; then
+ $show "generating symbol list for \`$libname.la'"
+ export_symbols="$output_objdir/$libname.exp"
+ $run $rm $export_symbols
+ eval cmds=\"$export_symbols_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ if test -n "$export_symbols_regex"; then
+ $show "egrep -e \"$export_symbols_regex\" \"$export_symbols\" > \"${export_symbols}T\""
+ $run eval 'egrep -e "$export_symbols_regex" "$export_symbols" > "${export_symbols}T"'
+ $show "$mv \"${export_symbols}T\" \"$export_symbols\""
+ $run eval '$mv "${export_symbols}T" "$export_symbols"'
+ fi
+ fi
+ fi
+
+ if test -n "$export_symbols" && test -n "$include_expsyms"; then
+ $run eval '$echo "X$include_expsyms" | $SP2NL >> "$export_symbols"'
+ fi
+
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec"; then
+ eval libobjs=\"\$libobjs $whole_archive_flag_spec\"
+ else
+ gentop="$output_objdir/${outputname}x"
+ $show "${rm}r $gentop"
+ $run ${rm}r "$gentop"
+ $show "mkdir $gentop"
+ $run mkdir "$gentop"
+ status=$?
+ if test $status -ne 0 && test ! -d "$gentop"; then
+ exit $status
+ fi
+ generated="$generated $gentop"
+
+ for xlib in $convenience; do
+ # Extract the objects.
+ case "$xlib" in
+ [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
+ *) xabs=`pwd`"/$xlib" ;;
+ esac
+ xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+ xdir="$gentop/$xlib"
+
+ $show "${rm}r $xdir"
+ $run ${rm}r "$xdir"
+ $show "mkdir $xdir"
+ $run mkdir "$xdir"
+ status=$?
+ if test $status -ne 0 && test ! -d "$xdir"; then
+ exit $status
+ fi
+ $show "(cd $xdir && $AR x $xabs)"
+ $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+
+ libobjs="$libobjs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP`
+ done
+ fi
+ fi
+
+ if test "$thread_safe" = yes && test -n "$thread_safe_flag_spec"; then
+ eval flag=\"$thread_safe_flag_spec\"
+ linkopts="$linkopts $flag"
+ fi
+
+ # Do each of the archive commands.
+ if test -n "$export_symbols" && test -n "$archive_expsym_cmds"; then
+ eval cmds=\"$archive_expsym_cmds\"
+ else
+ eval cmds=\"$archive_cmds\"
+ fi
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+
+ # Create links to the real library.
+ for linkname in $linknames; do
+ if test "$realname" != "$linkname"; then
+ $show "(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)"
+ $run eval '(cd $output_objdir && $rm $linkname && $LN_S $realname $linkname)' || exit $?
+ fi
+ done
+
+ # If -module or -export-dynamic was specified, set the dlname.
+ if test "$module" = yes || test "$export_dynamic" = yes; then
+ # On all known operating systems, these are identical.
+ dlname="$soname"
+ fi
+ fi
+ ;;
+
+ *.lo | *.o | *.obj)
+ if test -n "$link_against_libtool_libs"; then
+ $echo "$modename: error: cannot link libtool libraries into objects" 1>&2
+ exit 1
+ fi
+
+ if test -n "$deplibs"; then
+ $echo "$modename: warning: \`-l' and \`-L' are ignored for objects" 1>&2
+ fi
+
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ $echo "$modename: warning: \`-dlopen' is ignored for objects" 1>&2
+ fi
+
+ if test -n "$rpath"; then
+ $echo "$modename: warning: \`-rpath' is ignored for objects" 1>&2
+ fi
+
+ if test -n "$xrpath"; then
+ $echo "$modename: warning: \`-R' is ignored for objects" 1>&2
+ fi
+
+ if test -n "$vinfo"; then
+ $echo "$modename: warning: \`-version-info' is ignored for objects" 1>&2
+ fi
+
+ if test -n "$release"; then
+ $echo "$modename: warning: \`-release' is ignored for objects" 1>&2
+ fi
+
+ case "$output" in
+ *.lo)
+ if test -n "$objs"; then
+ $echo "$modename: cannot build library object \`$output' from non-libtool objects" 1>&2
+ exit 1
+ fi
+ libobj="$output"
+ obj=`$echo "X$output" | $Xsed -e "$lo2o"`
+ ;;
+ *)
+ libobj=
+ obj="$output"
+ ;;
+ esac
+
+ # Delete the old objects.
+ $run $rm $obj $libobj
+
+ # Objects from convenience libraries. This assumes
+ # single-version convenience libraries. Whenever we create
+ # different ones for PIC/non-PIC, this we'll have to duplicate
+ # the extraction.
+ reload_conv_objs=
+ gentop=
+ # reload_cmds runs $LD directly, so let us get rid of
+ # -Wl from whole_archive_flag_spec
+ wl=
+
+ if test -n "$convenience"; then
+ if test -n "$whole_archive_flag_spec"; then
+ eval reload_conv_objs=\"\$reload_objs $whole_archive_flag_spec\"
+ else
+ gentop="$output_objdir/${obj}x"
+ $show "${rm}r $gentop"
+ $run ${rm}r "$gentop"
+ $show "mkdir $gentop"
+ $run mkdir "$gentop"
+ status=$?
+ if test $status -ne 0 && test ! -d "$gentop"; then
+ exit $status
+ fi
+ generated="$generated $gentop"
+
+ for xlib in $convenience; do
+ # Extract the objects.
+ case "$xlib" in
+ [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
+ *) xabs=`pwd`"/$xlib" ;;
+ esac
+ xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+ xdir="$gentop/$xlib"
+
+ $show "${rm}r $xdir"
+ $run ${rm}r "$xdir"
+ $show "mkdir $xdir"
+ $run mkdir "$xdir"
+ status=$?
+ if test $status -ne 0 && test ! -d "$xdir"; then
+ exit $status
+ fi
+ $show "(cd $xdir && $AR x $xabs)"
+ $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+
+ reload_conv_objs="$reload_objs "`find $xdir -name \*.o -print -o -name \*.lo -print | $NL2SP`
+ done
+ fi
+ fi
+
+ # Create the old-style object.
+ reload_objs="$objs "`$echo "X$libobjs" | $SP2NL | $Xsed -e '/\.'${libext}$'/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`" $reload_conv_objs"
+
+ output="$obj"
+ eval cmds=\"$reload_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+
+ # Exit if we aren't doing a library object file.
+ if test -z "$libobj"; then
+ if test -n "$gentop"; then
+ $show "${rm}r $gentop"
+ $run ${rm}r $gentop
+ fi
+
+ exit 0
+ fi
+
+ if test "$build_libtool_libs" != yes; then
+ if test -n "$gentop"; then
+ $show "${rm}r $gentop"
+ $run ${rm}r $gentop
+ fi
+
+ # Create an invalid libtool object if no PIC, so that we don't
+ # accidentally link it into a program.
+ $show "echo timestamp > $libobj"
+ $run eval "echo timestamp > $libobj" || exit $?
+ exit 0
+ fi
+
+ if test -n "$pic_flag"; then
+ # Only do commands if we really have different PIC objects.
+ reload_objs="$libobjs $reload_conv_objs"
+ output="$libobj"
+ eval cmds=\"$reload_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ else
+ # Just create a symlink.
+ $show $rm $libobj
+ $run $rm $libobj
+ xdir=`$echo "X$libobj" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$xdir" = "X$libobj"; then
+ xdir="."
+ else
+ xdir="$xdir"
+ fi
+ baseobj=`$echo "X$libobj" | $Xsed -e 's%^.*/%%'`
+ oldobj=`$echo "X$baseobj" | $Xsed -e "$lo2o"`
+ $show "(cd $xdir && $LN_S $oldobj $baseobj)"
+ $run eval '(cd $xdir && $LN_S $oldobj $baseobj)' || exit $?
+ fi
+
+ if test -n "$gentop"; then
+ $show "${rm}r $gentop"
+ $run ${rm}r $gentop
+ fi
+
+ exit 0
+ ;;
+
+ # Anything else should be a program.
+ *)
+ if test -n "$vinfo"; then
+ $echo "$modename: warning: \`-version-info' is ignored for programs" 1>&2
+ fi
+
+ if test -n "$release"; then
+ $echo "$modename: warning: \`-release' is ignored for programs" 1>&2
+ fi
+
+ if test "$preload" = yes; then
+ if test "$dlopen" = unknown && test "$dlopen_self" = unknown &&
+ test "$dlopen_self_static" = unknown; then
+ $echo "$modename: warning: \`AC_LIBTOOL_DLOPEN' not used. Assuming no dlopen support."
+ fi
+ fi
+
+ if test -n "$rpath$xrpath"; then
+ # If the user specified any rpath flags, then add them.
+ for libdir in $rpath $xrpath; do
+ # This is the magic to use -rpath.
+ case "$compile_rpath " in
+ *" $libdir "*) ;;
+ *) compile_rpath="$compile_rpath $libdir" ;;
+ esac
+ case "$finalize_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_rpath="$finalize_rpath $libdir" ;;
+ esac
+ done
+ fi
+
+ # Now hardcode the library paths
+ rpath=
+ hardcode_libdirs=
+ for libdir in $compile_rpath $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ rpath="$rpath $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$perm_rpath " in
+ *" $libdir "*) ;;
+ *) perm_rpath="$perm_rpath $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ compile_rpath="$rpath"
+
+ rpath=
+ hardcode_libdirs=
+ for libdir in $finalize_rpath; do
+ if test -n "$hardcode_libdir_flag_spec"; then
+ if test -n "$hardcode_libdir_separator"; then
+ if test -z "$hardcode_libdirs"; then
+ hardcode_libdirs="$libdir"
+ else
+ # Just accumulate the unique libdirs.
+ case "$hardcode_libdir_separator$hardcode_libdirs$hardcode_libdir_separator" in
+ *"$hardcode_libdir_separator$libdir$hardcode_libdir_separator"*)
+ ;;
+ *)
+ hardcode_libdirs="$hardcode_libdirs$hardcode_libdir_separator$libdir"
+ ;;
+ esac
+ fi
+ else
+ eval flag=\"$hardcode_libdir_flag_spec\"
+ rpath="$rpath $flag"
+ fi
+ elif test -n "$runpath_var"; then
+ case "$finalize_perm_rpath " in
+ *" $libdir "*) ;;
+ *) finalize_perm_rpath="$finalize_perm_rpath $libdir" ;;
+ esac
+ fi
+ done
+ # Substitute the hardcoded libdirs into the rpath.
+ if test -n "$hardcode_libdir_separator" &&
+ test -n "$hardcode_libdirs"; then
+ libdir="$hardcode_libdirs"
+ eval rpath=\" $hardcode_libdir_flag_spec\"
+ fi
+ finalize_rpath="$rpath"
+
+ output_objdir=`$echo "X$output" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$output_objdir" = "X$output"; then
+ output_objdir="$objdir"
+ else
+ output_objdir="$output_objdir/$objdir"
+ fi
+
+ # Create the binary in the object directory, then wrap it.
+ if test ! -d $output_objdir; then
+ $show "$mkdir $output_objdir"
+ $run $mkdir $output_objdir
+ status=$?
+ if test $status -ne 0 && test ! -d $output_objdir; then
+ exit $status
+ fi
+ fi
+
+ if test -n "$libobjs" && test "$build_old_libs" = yes; then
+ # Transform all the library objects into standard objects.
+ compile_command=`$echo "X$compile_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+ finalize_command=`$echo "X$finalize_command" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+ fi
+
+ dlsyms=
+ if test -n "$dlfiles$dlprefiles" || test "$dlself" != no; then
+ if test -n "$NM" && test -n "$global_symbol_pipe"; then
+ dlsyms="${outputname}S.c"
+ else
+ $echo "$modename: not configured to extract global symbols from dlpreopened files" 1>&2
+ fi
+ fi
+
+ if test -n "$dlsyms"; then
+ case "$dlsyms" in
+ "") ;;
+ *.c)
+ # Discover the nlist of each of the dlfiles.
+ nlist="$output_objdir/${outputname}.nm"
+
+ $show "$rm $nlist ${nlist}S ${nlist}T"
+ $run $rm "$nlist" "${nlist}S" "${nlist}T"
+
+ # Parse the name list into a source file.
+ $show "creating $output_objdir/$dlsyms"
+
+ test -z "$run" && $echo > "$output_objdir/$dlsyms" "\
+/* $dlsyms - symbol resolution table for \`$outputname' dlsym emulation. */
+/* Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP */
+
+#ifdef __cplusplus
+extern \"C\" {
+#endif
+
+/* Prevent the only kind of declaration conflicts we can make. */
+#define lt_preloaded_symbols some_other_symbol
+
+/* External symbol declarations for the compiler. */\
+"
+
+ if test "$dlself" = yes; then
+ $show "generating symbol list for \`$output'"
+
+ test -z "$run" && $echo ': @PROGRAM@ ' > "$nlist"
+
+ # Add our own program objects to the symbol list.
+ progfiles=`$echo "X$objs" | $SP2NL | $Xsed -e "$lo2o" | $NL2SP`
+ for arg in $progfiles; do
+ $show "extracting global C symbols from \`$arg'"
+ $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+ done
+
+ if test -n "$exclude_expsyms"; then
+ $run eval 'egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T'
+ $run eval '$mv "$nlist"T "$nlist"'
+ fi
+
+ if test -n "$export_symbols_regex"; then
+ $run eval 'egrep -e "$export_symbols_regex" "$nlist" > "$nlist"T'
+ $run eval '$mv "$nlist"T "$nlist"'
+ fi
+
+ # Prepare the list of exported symbols
+ if test -z "$export_symbols"; then
+ export_symbols="$output_objdir/$output.exp"
+ $run $rm $export_symbols
+ $run eval "sed -n -e '/^: @PROGRAM@$/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"'
+ else
+ $run eval "sed -e 's/\([][.*^$]\)/\\\1/g' -e 's/^/ /' -e 's/$/$/'"' < "$export_symbols" > "$output_objdir/$output.exp"'
+ $run eval 'grep -f "$output_objdir/$output.exp" < "$nlist" > "$nlist"T'
+ $run eval 'mv "$nlist"T "$nlist"'
+ fi
+ fi
+
+ for arg in $dlprefiles; do
+ $show "extracting global C symbols from \`$arg'"
+ name=`echo "$arg" | sed -e 's%^.*/%%'`
+ $run eval 'echo ": $name " >> "$nlist"'
+ $run eval "$NM $arg | $global_symbol_pipe >> '$nlist'"
+ done
+
+ if test -z "$run"; then
+ # Make sure we have at least an empty file.
+ test -f "$nlist" || : > "$nlist"
+
+ if test -n "$exclude_expsyms"; then
+ egrep -v " ($exclude_expsyms)$" "$nlist" > "$nlist"T
+ $mv "$nlist"T "$nlist"
+ fi
+
+ # Try sorting and uniquifying the output.
+ if grep -v "^: " < "$nlist" | sort +2 | uniq > "$nlist"S; then
+ :
+ else
+ grep -v "^: " < "$nlist" > "$nlist"S
+ fi
+
+ if test -f "$nlist"S; then
+ eval "$global_symbol_to_cdecl"' < "$nlist"S >> "$output_objdir/$dlsyms"'
+ else
+ echo '/* NONE */' >> "$output_objdir/$dlsyms"
+ fi
+
+ $echo >> "$output_objdir/$dlsyms" "\
+
+#undef lt_preloaded_symbols
+
+#if defined (__STDC__) && __STDC__
+# define lt_ptr_t void *
+#else
+# define lt_ptr_t char *
+# define const
+#endif
+
+/* The mapping between symbol names and symbols. */
+const struct {
+ const char *name;
+ lt_ptr_t address;
+}
+lt_preloaded_symbols[] =
+{\
+"
+
+ sed -n -e 's/^: \([^ ]*\) $/ {\"\1\", (lt_ptr_t) 0},/p' \
+ -e 's/^. \([^ ]*\) \([^ ]*\)$/ {"\2", (lt_ptr_t) \&\2},/p' \
+ < "$nlist" >> "$output_objdir/$dlsyms"
+
+ $echo >> "$output_objdir/$dlsyms" "\
+ {0, (lt_ptr_t) 0}
+};
+
+/* This works around a problem in FreeBSD linker */
+#ifdef FREEBSD_WORKAROUND
+static const void *lt_preloaded_setup() {
+ return lt_preloaded_symbols;
+}
+#endif
+
+#ifdef __cplusplus
+}
+#endif\
+"
+ fi
+
+ pic_flag_for_symtable=
+ case "$host" in
+ # compiling the symbol table file with pic_flag works around
+ # a FreeBSD bug that causes programs to crash when -lm is
+ # linked before any other PIC object. But we must not use
+ # pic_flag when linking with -static. The problem exists in
+ # FreeBSD 2.2.6 and is fixed in FreeBSD 3.1.
+ *-*-freebsd2*|*-*-freebsd3.0*|*-*-freebsdelf3.0*)
+ case "$compile_command " in
+ *" -static "*) ;;
+ *) pic_flag_for_symtable=" $pic_flag -DPIC -DFREEBSD_WORKAROUND";;
+ esac;;
+ *-*-hpux*)
+ case "$compile_command " in
+ *" -static "*) ;;
+ *) pic_flag_for_symtable=" $pic_flag -DPIC";;
+ esac
+ esac
+
+ # Now compile the dynamic symbol file.
+ $show "(cd $output_objdir && $CC -c$no_builtin_flag$pic_flag_for_symtable \"$dlsyms\")"
+ $run eval '(cd $output_objdir && $CC -c$no_builtin_flag$pic_flag_for_symtable "$dlsyms")' || exit $?
+
+ # Clean up the generated files.
+ $show "$rm $output_objdir/$dlsyms $nlist ${nlist}S ${nlist}T"
+ $run $rm "$output_objdir/$dlsyms" "$nlist" "${nlist}S" "${nlist}T"
+
+ # Transform the symbol file into the correct name.
+ compile_command=`$echo "X$compile_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+ finalize_command=`$echo "X$finalize_command" | $Xsed -e "s%@SYMFILE@%$output_objdir/${outputname}S.${objext}%"`
+ ;;
+ *)
+ $echo "$modename: unknown suffix for \`$dlsyms'" 1>&2
+ exit 1
+ ;;
+ esac
+ else
+ # We keep going just in case the user didn't refer to
+ # lt_preloaded_symbols. The linker will fail if global_symbol_pipe
+ # really was required.
+
+ # Nullify the symbol file.
+ compile_command=`$echo "X$compile_command" | $Xsed -e "s% @SYMFILE@%%"`
+ finalize_command=`$echo "X$finalize_command" | $Xsed -e "s% @SYMFILE@%%"`
+ fi
+
+ if test -z "$link_against_libtool_libs" || test "$build_libtool_libs" != yes; then
+ # Replace the output file specification.
+ compile_command=`$echo "X$compile_command" | $Xsed -e 's%@OUTPUT@%'"$output"'%g'`
+ link_command="$compile_command$compile_rpath"
+
+ # We have no uninstalled library dependencies, so finalize right now.
+ $show "$link_command"
+ $run eval "$link_command"
+ status=$?
+
+ # Delete the generated files.
+ if test -n "$dlsyms"; then
+ $show "$rm $output_objdir/${outputname}S.${objext}"
+ $run $rm "$output_objdir/${outputname}S.${objext}"
+ fi
+
+ exit $status
+ fi
+
+ if test -n "$shlibpath_var"; then
+ # We should set the shlibpath_var
+ rpath=
+ for dir in $temp_rpath; do
+ case "$dir" in
+ [\\/]* | [A-Za-z]:[\\/]*)
+ # Absolute path.
+ rpath="$rpath$dir:"
+ ;;
+ *)
+ # Relative path: add a thisdir entry.
+ rpath="$rpath\$thisdir/$dir:"
+ ;;
+ esac
+ done
+ temp_rpath="$rpath"
+ fi
+
+ if test -n "$compile_shlibpath$finalize_shlibpath"; then
+ compile_command="$shlibpath_var=\"$compile_shlibpath$finalize_shlibpath\$$shlibpath_var\" $compile_command"
+ fi
+ if test -n "$finalize_shlibpath"; then
+ finalize_command="$shlibpath_var=\"$finalize_shlibpath\$$shlibpath_var\" $finalize_command"
+ fi
+
+ compile_var=
+ finalize_var=
+ if test -n "$runpath_var"; then
+ if test -n "$perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $perm_rpath; do
+ rpath="$rpath$dir:"
+ done
+ compile_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ if test -n "$finalize_perm_rpath"; then
+ # We should set the runpath_var.
+ rpath=
+ for dir in $finalize_perm_rpath; do
+ rpath="$rpath$dir:"
+ done
+ finalize_var="$runpath_var=\"$rpath\$$runpath_var\" "
+ fi
+ fi
+
+ if test "$hardcode_action" = relink; then
+ # Fast installation is not supported
+ link_command="$compile_var$compile_command$compile_rpath"
+ relink_command="$finalize_var$finalize_command$finalize_rpath"
+
+ $echo "$modename: warning: this platform does not like uninstalled shared libraries" 1>&2
+ $echo "$modename: \`$output' will be relinked during installation" 1>&2
+ else
+ if test "$fast_install" != no; then
+ link_command="$finalize_var$compile_command$finalize_rpath"
+ if test "$fast_install" = yes; then
+ relink_command=`$echo "X$compile_var$compile_command$compile_rpath" | $Xsed -e 's%@OUTPUT@%\$progdir/\$file%g'`
+ else
+ # fast_install is set to needless
+ relink_command=
+ fi
+ else
+ link_command="$compile_var$compile_command$compile_rpath"
+ relink_command="$finalize_var$finalize_command$finalize_rpath"
+ fi
+ fi
+
+ # Replace the output file specification.
+ link_command=`$echo "X$link_command" | $Xsed -e 's%@OUTPUT@%'"$output_objdir/$outputname"'%g'`
+
+ # Delete the old output files.
+ $run $rm $output $output_objdir/$outputname $output_objdir/lt-$outputname
+
+ $show "$link_command"
+ $run eval "$link_command" || exit $?
+
+ # Now create the wrapper script.
+ $show "creating $output"
+
+ # Quote the relink command for shipping.
+ if test -n "$relink_command"; then
+ relink_command=`$echo "X$relink_command" | $Xsed -e "$sed_quote_subst"`
+ fi
+
+ # Quote $echo for shipping.
+ if test "X$echo" = "X$SHELL $0 --fallback-echo"; then
+ case "$0" in
+ [\\/]* | [A-Za-z]:[\\/]*) qecho="$SHELL $0 --fallback-echo";;
+ *) qecho="$SHELL `pwd`/$0 --fallback-echo";;
+ esac
+ qecho=`$echo "X$qecho" | $Xsed -e "$sed_quote_subst"`
+ else
+ qecho=`$echo "X$echo" | $Xsed -e "$sed_quote_subst"`
+ fi
+
+ # Only actually do things if our run command is non-null.
+ if test -z "$run"; then
+ # win32 will think the script is a binary if it has
+ # a .exe suffix, so we strip it off here.
+ case $output in
+ *.exe) output=`echo $output|sed 's,.exe$,,'` ;;
+ esac
+ $rm $output
+ trap "$rm $output; exit 1" 1 2 15
+
+ $echo > $output "\
+#! $SHELL
+
+# $output - temporary wrapper script for $objdir/$outputname
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# The $output program cannot be directly executed until all the libtool
+# libraries that it depends on are installed.
+#
+# This wrapper script should never be moved out of the build directory.
+# If it is, it will not operate correctly.
+
+# Sed substitution that helps us do robust quoting. It backslashifies
+# metacharacters that are still active within double-quoted strings.
+Xsed='sed -e 1s/^X//'
+sed_quote_subst='$sed_quote_subst'
+
+# The HP-UX ksh and POSIX shell print the target directory to stdout
+# if CDPATH is set.
+if test \"\${CDPATH+set}\" = set; then CDPATH=:; export CDPATH; fi
+
+relink_command=\"$relink_command\"
+
+# This environment variable determines our operation mode.
+if test \"\$libtool_install_magic\" = \"$magic\"; then
+ # install mode needs the following variable:
+ link_against_libtool_libs='$link_against_libtool_libs'
+else
+ # When we are sourced in execute mode, \$file and \$echo are already set.
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ echo=\"$qecho\"
+ file=\"\$0\"
+ # Make sure echo works.
+ if test \"X\$1\" = X--no-reexec; then
+ # Discard the --no-reexec flag, and continue.
+ shift
+ elif test \"X\`(\$echo '\t') 2>/dev/null\`\" = 'X\t'; then
+ # Yippee, \$echo works!
+ :
+ else
+ # Restart under the correct shell, and then maybe \$echo will work.
+ exec $SHELL \"\$0\" --no-reexec \${1+\"\$@\"}
+ fi
+ fi\
+"
+ $echo >> $output "\
+
+ # Find the directory that this script lives in.
+ thisdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*$%%'\`
+ test \"x\$thisdir\" = \"x\$file\" && thisdir=.
+
+ # Follow symbolic links until we get to the real thisdir.
+ file=\`ls -ld \"\$file\" | sed -n 's/.*-> //p'\`
+ while test -n \"\$file\"; do
+ destdir=\`\$echo \"X\$file\" | \$Xsed -e 's%/[^/]*\$%%'\`
+
+ # If there was a directory component, then change thisdir.
+ if test \"x\$destdir\" != \"x\$file\"; then
+ case \"\$destdir\" in
+ [\\/]* | [A-Za-z]:[\\/]*) thisdir=\"\$destdir\" ;;
+ *) thisdir=\"\$thisdir/\$destdir\" ;;
+ esac
+ fi
+
+ file=\`\$echo \"X\$file\" | \$Xsed -e 's%^.*/%%'\`
+ file=\`ls -ld \"\$thisdir/\$file\" | sed -n 's/.*-> //p'\`
+ done
+
+ # Try to get the absolute directory name.
+ absdir=\`cd \"\$thisdir\" && pwd\`
+ test -n \"\$absdir\" && thisdir=\"\$absdir\"
+"
+
+ if test "$fast_install" = yes; then
+ echo >> $output "\
+ program=lt-'$outputname'
+ progdir=\"\$thisdir/$objdir\"
+
+ if test ! -f \"\$progdir/\$program\" || \\
+ { file=\`ls -1dt \"\$progdir/\$program\" \"\$progdir/../\$program\" 2>/dev/null | sed 1q\`; \\
+ test \"X\$file\" != \"X\$progdir/\$program\"; }; then
+
+ file=\"\$\$-\$program\"
+
+ if test ! -d \"\$progdir\"; then
+ $mkdir \"\$progdir\"
+ else
+ $rm \"\$progdir/\$file\"
+ fi"
+
+ echo >> $output "\
+
+ # relink executable if necessary
+ if test -n \"\$relink_command\"; then
+ if (cd \"\$thisdir\" && eval \$relink_command); then :
+ else
+ $rm \"\$progdir/\$file\"
+ exit 1
+ fi
+ fi
+
+ $mv \"\$progdir/\$file\" \"\$progdir/\$program\" 2>/dev/null ||
+ { $rm \"\$progdir/\$program\";
+ $mv \"\$progdir/\$file\" \"\$progdir/\$program\"; }
+ $rm \"\$progdir/\$file\"
+ fi"
+ else
+ echo >> $output "\
+ program='$outputname'
+ progdir=\"\$thisdir/$objdir\"
+"
+ fi
+
+ echo >> $output "\
+
+ if test -f \"\$progdir/\$program\"; then"
+
+ # Export our shlibpath_var if we have one.
+ if test "$shlibpath_overrides_runpath" = yes && test -n "$shlibpath_var" && test -n "$temp_rpath"; then
+ $echo >> $output "\
+ # Add our own library path to $shlibpath_var
+ $shlibpath_var=\"$temp_rpath\$$shlibpath_var\"
+
+ # Some systems cannot cope with colon-terminated $shlibpath_var
+ # The second colon is a workaround for a bug in BeOS R4 sed
+ $shlibpath_var=\`\$echo \"X\$$shlibpath_var\" | \$Xsed -e 's/::*\$//'\`
+
+ export $shlibpath_var
+"
+ fi
+
+ # fixup the dll searchpath if we need to.
+ if test -n "$dllsearchpath"; then
+ $echo >> $output "\
+ # Add the dll search path components to the executable PATH
+ PATH=$dllsearchpath:\$PATH
+"
+ fi
+
+ $echo >> $output "\
+ if test \"\$libtool_execute_magic\" != \"$magic\"; then
+ # Run the actual program with our arguments.
+"
+ case $host in
+ # win32 systems need to use the prog path for dll
+ # lookup to work
+ *-*-cygwin*)
+ $echo >> $output "\
+ exec \$progdir/\$program \${1+\"\$@\"}
+"
+ ;;
+
+ # Backslashes separate directories on plain windows
+ *-*-mingw | *-*-os2*)
+ $echo >> $output "\
+ exec \$progdir\\\\\$program \${1+\"\$@\"}
+"
+ ;;
+
+ *)
+ $echo >> $output "\
+ # Export the path to the program.
+ PATH=\"\$progdir:\$PATH\"
+ export PATH
+
+ exec \$program \${1+\"\$@\"}
+"
+ ;;
+ esac
+ $echo >> $output "\
+ \$echo \"\$0: cannot exec \$program \${1+\"\$@\"}\"
+ exit 1
+ fi
+ else
+ # The program doesn't exist.
+ \$echo \"\$0: error: \$progdir/\$program does not exist\" 1>&2
+ \$echo \"This script is just a wrapper for \$program.\" 1>&2
+ echo \"See the $PACKAGE documentation for more information.\" 1>&2
+ exit 1
+ fi
+fi\
+"
+ chmod +x $output
+ fi
+ exit 0
+ ;;
+ esac
+
+ # See if we need to build an old-fashioned archive.
+ for oldlib in $oldlibs; do
+
+ if test "$build_libtool_libs" = convenience; then
+ oldobjs="$libobjs_save"
+ addlibs="$convenience"
+ build_libtool_libs=no
+ else
+ if test "$build_libtool_libs" = module; then
+ oldobjs="$libobjs_save"
+ build_libtool_libs=no
+ else
+ oldobjs="$objs "`$echo "X$libobjs_save" | $SP2NL | $Xsed -e '/\.'${libext}'$/d' -e '/\.lib$/d' -e "$lo2o" | $NL2SP`
+ fi
+ addlibs="$old_convenience"
+ fi
+
+ if test -n "$addlibs"; then
+ gentop="$output_objdir/${outputname}x"
+ $show "${rm}r $gentop"
+ $run ${rm}r "$gentop"
+ $show "mkdir $gentop"
+ $run mkdir "$gentop"
+ status=$?
+ if test $status -ne 0 && test ! -d "$gentop"; then
+ exit $status
+ fi
+ generated="$generated $gentop"
+
+ # Add in members from convenience archives.
+ for xlib in $addlibs; do
+ # Extract the objects.
+ case "$xlib" in
+ [\\/]* | [A-Za-z]:[\\/]*) xabs="$xlib" ;;
+ *) xabs=`pwd`"/$xlib" ;;
+ esac
+ xlib=`$echo "X$xlib" | $Xsed -e 's%^.*/%%'`
+ xdir="$gentop/$xlib"
+
+ $show "${rm}r $xdir"
+ $run ${rm}r "$xdir"
+ $show "mkdir $xdir"
+ $run mkdir "$xdir"
+ status=$?
+ if test $status -ne 0 && test ! -d "$xdir"; then
+ exit $status
+ fi
+ $show "(cd $xdir && $AR x $xabs)"
+ $run eval "(cd \$xdir && $AR x \$xabs)" || exit $?
+
+ oldobjs="$oldobjs "`find $xdir -name \*.${objext} -print -o -name \*.lo -print | $NL2SP`
+ done
+ fi
+
+ # Do each command in the archive commands.
+ if test -n "$old_archive_from_new_cmds" && test "$build_libtool_libs" = yes; then
+ eval cmds=\"$old_archive_from_new_cmds\"
+ else
+ # Ensure that we have .o objects in place in case we decided
+ # not to build a shared library, and have fallen back to building
+ # static libs even though --disable-static was passed!
+ for oldobj in $oldobjs; do
+ if test ! -f $oldobj; then
+ xdir=`$echo "X$oldobj" | $Xsed -e 's%/[^/]*$%%'`
+ if test "X$xdir" = "X$oldobj"; then
+ xdir="."
+ else
+ xdir="$xdir"
+ fi
+ baseobj=`$echo "X$oldobj" | $Xsed -e 's%^.*/%%'`
+ obj=`$echo "X$baseobj" | $Xsed -e "$o2lo"`
+ $show "(cd $xdir && ${LN_S} $obj $baseobj)"
+ $run eval '(cd $xdir && ${LN_S} $obj $baseobj)' || exit $?
+ fi
+ done
+
+ eval cmds=\"$old_archive_cmds\"
+ fi
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ done
+
+ if test -n "$generated"; then
+ $show "${rm}r$generated"
+ $run ${rm}r$generated
+ fi
+
+ # Now create the libtool archive.
+ case "$output" in
+ *.la)
+ old_library=
+ test "$build_old_libs" = yes && old_library="$libname.$libext"
+ $show "creating $output"
+
+ if test -n "$xrpath"; then
+ temp_xrpath=
+ for libdir in $xrpath; do
+ temp_xrpath="$temp_xrpath -R$libdir"
+ done
+ dependency_libs="$temp_xrpath $dependency_libs"
+ fi
+
+ # Only create the output if not a dry run.
+ if test -z "$run"; then
+ for installed in no yes; do
+ if test "$installed" = yes; then
+ if test -z "$install_libdir"; then
+ break
+ fi
+ output="$output_objdir/$outputname"i
+ fi
+ $rm $output
+ $echo > $output "\
+# $outputname - a libtool library file
+# Generated by $PROGRAM - GNU $PACKAGE $VERSION$TIMESTAMP
+#
+# Please DO NOT delete this file!
+# It is necessary for linking the library.
+
+# The name that we can dlopen(3).
+dlname='$dlname'
+
+# Names of this library.
+library_names='$library_names'
+
+# The name of the static archive.
+old_library='$old_library'
+
+# Libraries that this one depends upon.
+dependency_libs='$dependency_libs'
+
+# Version information for $libname.
+current=$current
+age=$age
+revision=$revision
+
+# Is this an already installed library?
+installed=$installed
+
+# Directory that this library needs to be installed in:
+libdir='$install_libdir'\
+"
+ done
+ fi
+
+ # Do a symbolic link so that the libtool archive can be found in
+ # LD_LIBRARY_PATH before the program is installed.
+ $show "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)"
+ $run eval "(cd $output_objdir && $rm $outputname && $LN_S ../$outputname $outputname)" || exit $?
+ ;;
+ esac
+ exit 0
+ ;;
+
+ # libtool install mode
+ install)
+ modename="$modename: install"
+
+ # There may be an optional sh(1) argument at the beginning of
+ # install_prog (especially on Windows NT).
+ if test "$nonopt" = "$SHELL" || test "$nonopt" = /bin/sh; then
+ # Aesthetically quote it.
+ arg=`$echo "X$nonopt" | $Xsed -e "$sed_quote_subst"`
+ case "$arg" in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ arg="\"$arg\""
+ ;;
+ esac
+ install_prog="$arg "
+ arg="$1"
+ shift
+ else
+ install_prog=
+ arg="$nonopt"
+ fi
+
+ # The real first argument should be the name of the installation program.
+ # Aesthetically quote it.
+ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+ case "$arg" in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ arg="\"$arg\""
+ ;;
+ esac
+ install_prog="$install_prog$arg"
+
+ # We need to accept at least all the BSD install flags.
+ dest=
+ files=
+ opts=
+ prev=
+ install_type=
+ isdir=no
+ stripme=
+ for arg
+ do
+ if test -n "$dest"; then
+ files="$files $dest"
+ dest="$arg"
+ continue
+ fi
+
+ case "$arg" in
+ -d) isdir=yes ;;
+ -f) prev="-f" ;;
+ -g) prev="-g" ;;
+ -m) prev="-m" ;;
+ -o) prev="-o" ;;
+ -s)
+ stripme=" -s"
+ continue
+ ;;
+ -*) ;;
+
+ *)
+ # If the previous option needed an argument, then skip it.
+ if test -n "$prev"; then
+ prev=
+ else
+ dest="$arg"
+ continue
+ fi
+ ;;
+ esac
+
+ # Aesthetically quote the argument.
+ arg=`$echo "X$arg" | $Xsed -e "$sed_quote_subst"`
+ case "$arg" in
+ *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*)
+ arg="\"$arg\""
+ ;;
+ esac
+ install_prog="$install_prog $arg"
+ done
+
+ if test -z "$install_prog"; then
+ $echo "$modename: you must specify an install program" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ if test -n "$prev"; then
+ $echo "$modename: the \`$prev' option requires an argument" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ if test -z "$files"; then
+ if test -z "$dest"; then
+ $echo "$modename: no file or destination specified" 1>&2
+ else
+ $echo "$modename: you must specify a destination" 1>&2
+ fi
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ # Strip any trailing slash from the destination.
+ dest=`$echo "X$dest" | $Xsed -e 's%/$%%'`
+
+ # Check to see that the destination is a directory.
+ test -d "$dest" && isdir=yes
+ if test "$isdir" = yes; then
+ destdir="$dest"
+ destname=
+ else
+ destdir=`$echo "X$dest" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$destdir" = "X$dest" && destdir=.
+ destname=`$echo "X$dest" | $Xsed -e 's%^.*/%%'`
+
+ # Not a directory, so check to see that there is only one file specified.
+ set dummy $files
+ if test $# -gt 2; then
+ $echo "$modename: \`$dest' is not a directory" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+ fi
+ case "$destdir" in
+ [\\/]* | [A-Za-z]:[\\/]*) ;;
+ *)
+ for file in $files; do
+ case "$file" in
+ *.lo) ;;
+ *)
+ $echo "$modename: \`$destdir' must be an absolute directory name" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+ esac
+ done
+ ;;
+ esac
+
+ # This variable tells wrapper scripts just to set variables rather
+ # than running their programs.
+ libtool_install_magic="$magic"
+
+ staticlibs=
+ future_libdirs=
+ current_libdirs=
+ for file in $files; do
+
+ # Do each installation.
+ case "$file" in
+ *.a | *.lib)
+ # Do the static libraries later.
+ staticlibs="$staticlibs $file"
+ ;;
+
+ *.la)
+ # Check to see that this really is a libtool archive.
+ if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+ else
+ $echo "$modename: \`$file' is not a valid libtool archive" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ library_names=
+ old_library=
+ # If there is no directory component, then add one.
+ case "$file" in
+ */* | *\\*) . $file ;;
+ *) . ./$file ;;
+ esac
+
+ # Add the libdir to current_libdirs if it is the destination.
+ if test "X$destdir" = "X$libdir"; then
+ case "$current_libdirs " in
+ *" $libdir "*) ;;
+ *) current_libdirs="$current_libdirs $libdir" ;;
+ esac
+ else
+ # Note the libdir as a future libdir.
+ case "$future_libdirs " in
+ *" $libdir "*) ;;
+ *) future_libdirs="$future_libdirs $libdir" ;;
+ esac
+ fi
+
+ dir="`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`/"
+ test "X$dir" = "X$file/" && dir=
+ dir="$dir$objdir"
+
+ # See the names of the shared library.
+ set dummy $library_names
+ if test -n "$2"; then
+ realname="$2"
+ shift
+ shift
+
+ # Install the shared library and build the symlinks.
+ $show "$install_prog $dir/$realname $destdir/$realname"
+ $run eval "$install_prog $dir/$realname $destdir/$realname" || exit $?
+
+ if test $# -gt 0; then
+ # Delete the old symlinks, and create new ones.
+ for linkname
+ do
+ if test "$linkname" != "$realname"; then
+ $show "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
+ $run eval "(cd $destdir && $rm $linkname && $LN_S $realname $linkname)"
+ fi
+ done
+ fi
+
+ # Do each command in the postinstall commands.
+ lib="$destdir/$realname"
+ eval cmds=\"$postinstall_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ fi
+
+ # Install the pseudo-library for information purposes.
+ name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+ instname="$dir/$name"i
+ $show "$install_prog $instname $destdir/$name"
+ $run eval "$install_prog $instname $destdir/$name" || exit $?
+
+ # Maybe install the static library, too.
+ test -n "$old_library" && staticlibs="$staticlibs $dir/$old_library"
+ ;;
+
+ *.lo)
+ # Install (i.e. copy) a libtool object.
+
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile="$destdir/$destname"
+ else
+ destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+ destfile="$destdir/$destfile"
+ fi
+
+ # Deduce the name of the destination old-style object file.
+ case "$destfile" in
+ *.lo)
+ staticdest=`$echo "X$destfile" | $Xsed -e "$lo2o"`
+ ;;
+ *.o | *.obj)
+ staticdest="$destfile"
+ destfile=
+ ;;
+ *)
+ $echo "$modename: cannot copy a libtool object to \`$destfile'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+ esac
+
+ # Install the libtool object if requested.
+ if test -n "$destfile"; then
+ $show "$install_prog $file $destfile"
+ $run eval "$install_prog $file $destfile" || exit $?
+ fi
+
+ # Install the old object if enabled.
+ if test "$build_old_libs" = yes; then
+ # Deduce the name of the old-style object file.
+ staticobj=`$echo "X$file" | $Xsed -e "$lo2o"`
+
+ $show "$install_prog $staticobj $staticdest"
+ $run eval "$install_prog \$staticobj \$staticdest" || exit $?
+ fi
+ exit 0
+ ;;
+
+ *)
+ # Figure out destination file name, if it wasn't already specified.
+ if test -n "$destname"; then
+ destfile="$destdir/$destname"
+ else
+ destfile=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+ destfile="$destdir/$destfile"
+ fi
+
+ # Do a test to see if this is really a libtool program.
+ if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+ link_against_libtool_libs=
+ relink_command=
+
+ # If there is no directory component, then add one.
+ case "$file" in
+ */* | *\\*) . $file ;;
+ *) . ./$file ;;
+ esac
+
+ # Check the variables that should have been set.
+ if test -z "$link_against_libtool_libs"; then
+ $echo "$modename: invalid libtool wrapper script \`$file'" 1>&2
+ exit 1
+ fi
+
+ finalize=yes
+ for lib in $link_against_libtool_libs; do
+ # Check to see that each library is installed.
+ libdir=
+ if test -f "$lib"; then
+ # If there is no directory component, then add one.
+ case "$lib" in
+ */* | *\\*) . $lib ;;
+ *) . ./$lib ;;
+ esac
+ fi
+ libfile="$libdir/`$echo "X$lib" | $Xsed -e 's%^.*/%%g'`"
+ if test -n "$libdir" && test ! -f "$libfile"; then
+ $echo "$modename: warning: \`$lib' has not been installed in \`$libdir'" 1>&2
+ finalize=no
+ fi
+ done
+
+ outputname=
+ if test "$fast_install" = no && test -n "$relink_command"; then
+ if test "$finalize" = yes && test -z "$run"; then
+ tmpdir="/tmp"
+ test -n "$TMPDIR" && tmpdir="$TMPDIR"
+ tmpdir=`mktemp -d $tmpdir/libtool-XXXXXX 2> /dev/null`
+ if test $? = 0 ; then :
+ else
+ tmpdir="$tmpdir/libtool-$$"
+ fi
+ if $mkdir -p "$tmpdir" && chmod 700 "$tmpdir"; then :
+ else
+ $echo "$modename: error: cannot create temporary directory \`$tmpdir'" 1>&2
+ continue
+ fi
+ outputname="$tmpdir/$file"
+ # Replace the output file specification.
+ relink_command=`$echo "X$relink_command" | $Xsed -e 's%@OUTPUT@%'"$outputname"'%g'`
+
+ $show "$relink_command"
+ if $run eval "$relink_command"; then :
+ else
+ $echo "$modename: error: relink \`$file' with the above command before installing it" 1>&2
+ ${rm}r "$tmpdir"
+ continue
+ fi
+ file="$outputname"
+ else
+ $echo "$modename: warning: cannot relink \`$file'" 1>&2
+ fi
+ else
+ # Install the binary that we compiled earlier.
+ file=`$echo "X$file" | $Xsed -e "s%\([^/]*\)$%$objdir/\1%"`
+ fi
+ fi
+
+ $show "$install_prog$stripme $file $destfile"
+ $run eval "$install_prog\$stripme \$file \$destfile" || exit $?
+ test -n "$outputname" && ${rm}r "$tmpdir"
+ ;;
+ esac
+ done
+
+ for file in $staticlibs; do
+ name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+
+ # Set up the ranlib parameters.
+ oldlib="$destdir/$name"
+
+ $show "$install_prog $file $oldlib"
+ $run eval "$install_prog \$file \$oldlib" || exit $?
+
+ # Do each command in the postinstall commands.
+ eval cmds=\"$old_postinstall_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || exit $?
+ done
+ IFS="$save_ifs"
+ done
+
+ if test -n "$future_libdirs"; then
+ $echo "$modename: warning: remember to run \`$progname --finish$future_libdirs'" 1>&2
+ fi
+
+ if test -n "$current_libdirs"; then
+ # Maybe just do a dry run.
+ test -n "$run" && current_libdirs=" -n$current_libdirs"
+ exec $SHELL $0 --finish$current_libdirs
+ exit 1
+ fi
+
+ exit 0
+ ;;
+
+ # libtool finish mode
+ finish)
+ modename="$modename: finish"
+ libdirs="$nonopt"
+ admincmds=
+
+ if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then
+ for dir
+ do
+ libdirs="$libdirs $dir"
+ done
+
+ for libdir in $libdirs; do
+ if test -n "$finish_cmds"; then
+ # Do each command in the finish commands.
+ eval cmds=\"$finish_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd" || admincmds="$admincmds
+ $cmd"
+ done
+ IFS="$save_ifs"
+ fi
+ if test -n "$finish_eval"; then
+ # Do the single finish_eval.
+ eval cmds=\"$finish_eval\"
+ $run eval "$cmds" || admincmds="$admincmds
+ $cmds"
+ fi
+ done
+ fi
+
+ # Exit here if they wanted silent mode.
+ test "$show" = : && exit 0
+
+ echo "----------------------------------------------------------------------"
+ echo "Libraries have been installed in:"
+ for libdir in $libdirs; do
+ echo " $libdir"
+ done
+ echo
+ echo "If you ever happen to want to link against installed libraries"
+ echo "in a given directory, LIBDIR, you must either use libtool, and"
+ echo "specify the full pathname of the library, or use \`-LLIBDIR'"
+ echo "flag during linking and do at least one of the following:"
+ if test -n "$shlibpath_var"; then
+ echo " - add LIBDIR to the \`$shlibpath_var' environment variable"
+ echo " during execution"
+ fi
+ if test -n "$runpath_var"; then
+ echo " - add LIBDIR to the \`$runpath_var' environment variable"
+ echo " during linking"
+ fi
+ if test -n "$hardcode_libdir_flag_spec"; then
+ libdir=LIBDIR
+ eval flag=\"$hardcode_libdir_flag_spec\"
+
+ echo " - use the \`$flag' linker flag"
+ fi
+ if test -n "$admincmds"; then
+ echo " - have your system administrator run these commands:$admincmds"
+ fi
+ if test -f /etc/ld.so.conf; then
+ echo " - have your system administrator add LIBDIR to \`/etc/ld.so.conf'"
+ fi
+ echo
+ echo "See any operating system documentation about shared libraries for"
+ echo "more information, such as the ld(1) and ld.so(8) manual pages."
+ echo "----------------------------------------------------------------------"
+ exit 0
+ ;;
+
+ # libtool execute mode
+ execute)
+ modename="$modename: execute"
+
+ # The first argument is the command name.
+ cmd="$nonopt"
+ if test -z "$cmd"; then
+ $echo "$modename: you must specify a COMMAND" 1>&2
+ $echo "$help"
+ exit 1
+ fi
+
+ # Handle -dlopen flags immediately.
+ for file in $execute_dlfiles; do
+ if test ! -f "$file"; then
+ $echo "$modename: \`$file' is not a file" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ dir=
+ case "$file" in
+ *.la)
+ # Check to see that this really is a libtool archive.
+ if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then :
+ else
+ $echo "$modename: \`$lib' is not a valid libtool archive" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ # Read the libtool library.
+ dlname=
+ library_names=
+
+ # If there is no directory component, then add one.
+ case "$file" in
+ */* | *\\*) . $file ;;
+ *) . ./$file ;;
+ esac
+
+ # Skip this library if it cannot be dlopened.
+ if test -z "$dlname"; then
+ # Warn if it was a shared library.
+ test -n "$library_names" && $echo "$modename: warning: \`$file' was not linked with \`-export-dynamic'"
+ continue
+ fi
+
+ dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$dir" = "X$file" && dir=.
+
+ if test -f "$dir/$objdir/$dlname"; then
+ dir="$dir/$objdir"
+ else
+ $echo "$modename: cannot find \`$dlname' in \`$dir' or \`$dir/$objdir'" 1>&2
+ exit 1
+ fi
+ ;;
+
+ *.lo)
+ # Just add the directory containing the .lo file.
+ dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$dir" = "X$file" && dir=.
+ ;;
+
+ *)
+ $echo "$modename: warning \`-dlopen' is ignored for non-libtool libraries and objects" 1>&2
+ continue
+ ;;
+ esac
+
+ # Get the absolute pathname.
+ absdir=`cd "$dir" && pwd`
+ test -n "$absdir" && dir="$absdir"
+
+ # Now add the directory to shlibpath_var.
+ if eval "test -z \"\$$shlibpath_var\""; then
+ eval "$shlibpath_var=\"\$dir\""
+ else
+ eval "$shlibpath_var=\"\$dir:\$$shlibpath_var\""
+ fi
+ done
+
+ # This variable tells wrapper scripts just to set shlibpath_var
+ # rather than running their programs.
+ libtool_execute_magic="$magic"
+
+ # Check if any of the arguments is a wrapper script.
+ args=
+ for file
+ do
+ case "$file" in
+ -*) ;;
+ *)
+ # Do a test to see if this is really a libtool program.
+ if (sed -e '4q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+ # If there is no directory component, then add one.
+ case "$file" in
+ */* | *\\*) . $file ;;
+ *) . ./$file ;;
+ esac
+
+ # Transform arg to wrapped name.
+ file="$progdir/$program"
+ fi
+ ;;
+ esac
+ # Quote arguments (to preserve shell metacharacters).
+ file=`$echo "X$file" | $Xsed -e "$sed_quote_subst"`
+ args="$args \"$file\""
+ done
+
+ if test -z "$run"; then
+ if test -n "$shlibpath_var"; then
+ # Export the shlibpath_var.
+ eval "export $shlibpath_var"
+ fi
+
+ # Restore saved enviroment variables
+ if test "${save_LC_ALL+set}" = set; then
+ LC_ALL="$save_LC_ALL"; export LC_ALL
+ fi
+ if test "${save_LANG+set}" = set; then
+ LANG="$save_LANG"; export LANG
+ fi
+
+ # Now actually exec the command.
+ eval "exec \$cmd$args"
+
+ $echo "$modename: cannot exec \$cmd$args"
+ exit 1
+ else
+ # Display what would be done.
+ if test -n "$shlibpath_var"; then
+ eval "\$echo \"\$shlibpath_var=\$$shlibpath_var\""
+ $echo "export $shlibpath_var"
+ fi
+ $echo "$cmd$args"
+ exit 0
+ fi
+ ;;
+
+ # libtool uninstall mode
+ uninstall)
+ modename="$modename: uninstall"
+ rm="$nonopt"
+ files=
+
+ for arg
+ do
+ case "$arg" in
+ -*) rm="$rm $arg" ;;
+ *) files="$files $arg" ;;
+ esac
+ done
+
+ if test -z "$rm"; then
+ $echo "$modename: you must specify an RM program" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ fi
+
+ for file in $files; do
+ dir=`$echo "X$file" | $Xsed -e 's%/[^/]*$%%'`
+ test "X$dir" = "X$file" && dir=.
+ name=`$echo "X$file" | $Xsed -e 's%^.*/%%'`
+
+ rmfiles="$file"
+
+ case "$name" in
+ *.la)
+ # Possibly a libtool archive, so verify it.
+ if (sed -e '2q' $file | egrep "^# Generated by .*$PACKAGE") >/dev/null 2>&1; then
+ . $dir/$name
+
+ # Delete the libtool libraries and symlinks.
+ for n in $library_names; do
+ rmfiles="$rmfiles $dir/$n"
+ done
+ test -n "$old_library" && rmfiles="$rmfiles $dir/$old_library"
+
+ $show "$rm $rmfiles"
+ $run $rm $rmfiles
+
+ if test -n "$library_names"; then
+ # Do each command in the postuninstall commands.
+ eval cmds=\"$postuninstall_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd"
+ done
+ IFS="$save_ifs"
+ fi
+
+ if test -n "$old_library"; then
+ # Do each command in the old_postuninstall commands.
+ eval cmds=\"$old_postuninstall_cmds\"
+ IFS="${IFS= }"; save_ifs="$IFS"; IFS='~'
+ for cmd in $cmds; do
+ IFS="$save_ifs"
+ $show "$cmd"
+ $run eval "$cmd"
+ done
+ IFS="$save_ifs"
+ fi
+
+ # FIXME: should reinstall the best remaining shared library.
+ fi
+ ;;
+
+ *.lo)
+ if test "$build_old_libs" = yes; then
+ oldobj=`$echo "X$name" | $Xsed -e "$lo2o"`
+ rmfiles="$rmfiles $dir/$oldobj"
+ fi
+ $show "$rm $rmfiles"
+ $run $rm $rmfiles
+ ;;
+
+ *)
+ $show "$rm $rmfiles"
+ $run $rm $rmfiles
+ ;;
+ esac
+ done
+ exit 0
+ ;;
+
+ "")
+ $echo "$modename: you must specify a MODE" 1>&2
+ $echo "$generic_help" 1>&2
+ exit 1
+ ;;
+ esac
+
+ $echo "$modename: invalid operation mode \`$mode'" 1>&2
+ $echo "$generic_help" 1>&2
+ exit 1
+fi # test -z "$show_help"
+
+# We need to display help for each of the modes.
+case "$mode" in
+"") $echo \
+"Usage: $modename [OPTION]... [MODE-ARG]...
+
+Provide generalized library-building support services.
+
+ --config show all configuration variables
+ --debug enable verbose shell tracing
+-n, --dry-run display commands without modifying any files
+ --features display basic configuration information and exit
+ --finish same as \`--mode=finish'
+ --help display this help message and exit
+ --mode=MODE use operation mode MODE [default=inferred from MODE-ARGS]
+ --quiet same as \`--silent'
+ --silent don't print informational messages
+ --version print version information
+
+MODE must be one of the following:
+
+ compile compile a source file into a libtool object
+ execute automatically set library path, then run a program
+ finish complete the installation of libtool libraries
+ install install libraries or executables
+ link create a library or an executable
+ uninstall remove libraries from an installed directory
+
+MODE-ARGS vary depending on the MODE. Try \`$modename --help --mode=MODE' for
+a more detailed description of MODE."
+ exit 0
+ ;;
+
+compile)
+ $echo \
+"Usage: $modename [OPTION]... --mode=compile COMPILE-COMMAND... SOURCEFILE
+
+Compile a source file into a libtool library object.
+
+This mode accepts the following additional options:
+
+ -o OUTPUT-FILE set the output file name to OUTPUT-FILE
+ -static always build a \`.o' file suitable for static linking
+
+COMPILE-COMMAND is a command to be used in creating a \`standard' object file
+from the given SOURCEFILE.
+
+The output file name is determined by removing the directory component from
+SOURCEFILE, then substituting the C source code suffix \`.c' with the
+library object suffix, \`.lo'."
+ ;;
+
+execute)
+ $echo \
+"Usage: $modename [OPTION]... --mode=execute COMMAND [ARGS]...
+
+Automatically set library path, then run a program.
+
+This mode accepts the following additional options:
+
+ -dlopen FILE add the directory containing FILE to the library path
+
+This mode sets the library path environment variable according to \`-dlopen'
+flags.
+
+If any of the ARGS are libtool executable wrappers, then they are translated
+into their corresponding uninstalled binary, and any of their required library
+directories are added to the library path.
+
+Then, COMMAND is executed, with ARGS as arguments."
+ ;;
+
+finish)
+ $echo \
+"Usage: $modename [OPTION]... --mode=finish [LIBDIR]...
+
+Complete the installation of libtool libraries.
+
+Each LIBDIR is a directory that contains libtool libraries.
+
+The commands that this mode executes may require superuser privileges. Use
+the \`--dry-run' option if you just want to see what would be executed."
+ ;;
+
+install)
+ $echo \
+"Usage: $modename [OPTION]... --mode=install INSTALL-COMMAND...
+
+Install executables or libraries.
+
+INSTALL-COMMAND is the installation command. The first component should be
+either the \`install' or \`cp' program.
+
+The rest of the components are interpreted as arguments to that command (only
+BSD-compatible install options are recognized)."
+ ;;
+
+link)
+ $echo \
+"Usage: $modename [OPTION]... --mode=link LINK-COMMAND...
+
+Link object files or libraries together to form another library, or to
+create an executable program.
+
+LINK-COMMAND is a command using the C compiler that you would use to create
+a program from several object files.
+
+The following components of LINK-COMMAND are treated specially:
+
+ -all-static do not do any dynamic linking at all
+ -avoid-version do not add a version suffix if possible
+ -dlopen FILE \`-dlpreopen' FILE if it cannot be dlopened at runtime
+ -dlpreopen FILE link in FILE and add its symbols to lt_preloaded_symbols
+ -export-dynamic allow symbols from OUTPUT-FILE to be resolved with dlsym(3)
+ -export-symbols SYMFILE
+ try to export only the symbols listed in SYMFILE
+ -export-symbols-regex REGEX
+ try to export only the symbols matching REGEX
+ -LLIBDIR search LIBDIR for required installed libraries
+ -lNAME OUTPUT-FILE requires the installed library libNAME
+ -module build a library that can dlopened
+ -no-undefined declare that a library does not refer to external symbols
+ -o OUTPUT-FILE create OUTPUT-FILE from the specified objects
+ -release RELEASE specify package release information
+ -rpath LIBDIR the created library will eventually be installed in LIBDIR
+ -R[ ]LIBDIR add LIBDIR to the runtime path of programs and libraries
+ -static do not do any dynamic linking of libtool libraries
+ -version-info CURRENT[:REVISION[:AGE]]
+ specify library version info [each variable defaults to 0]
+
+All other options (arguments beginning with \`-') are ignored.
+
+Every other argument is treated as a filename. Files ending in \`.la' are
+treated as uninstalled libtool libraries, other files are standard or library
+object files.
+
+If the OUTPUT-FILE ends in \`.la', then a libtool library is created,
+only library objects (\`.lo' files) may be specified, and \`-rpath' is
+required, except when creating a convenience library.
+
+If OUTPUT-FILE ends in \`.a' or \`.lib', then a standard library is created
+using \`ar' and \`ranlib', or on Windows using \`lib'.
+
+If OUTPUT-FILE ends in \`.lo' or \`.${objext}', then a reloadable object file
+is created, otherwise an executable program is created."
+ ;;
+
+uninstall)
+ $echo \
+"Usage: $modename [OPTION]... --mode=uninstall RM [RM-OPTION]... FILE...
+
+Remove libraries from an installation directory.
+
+RM is the name of the program to use to delete files associated with each FILE
+(typically \`/bin/rm'). RM-OPTIONS are options (such as \`-f') to be passed
+to RM.
+
+If FILE is a libtool library, all the files associated with it are deleted.
+Otherwise, only FILE itself is deleted using RM."
+ ;;
+
+*)
+ $echo "$modename: invalid operation mode \`$mode'" 1>&2
+ $echo "$help" 1>&2
+ exit 1
+ ;;
+esac
+
+echo
+$echo "Try \`$modename --help' for more information about other modes."
+
+exit 0
+
+# Local Variables:
+# mode:shell-script
+# sh-indentation:2
+# End:
diff --git a/po/Makefile b/po/Makefile
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/po/Makefile
diff --git a/sgsnemu/.deps/cmdline.P b/sgsnemu/.deps/cmdline.P
new file mode 100644
index 0000000..f8c0fb9
--- /dev/null
+++ b/sgsnemu/.deps/cmdline.P
@@ -0,0 +1,33 @@
+cmdline.o: cmdline.c /usr/include/stdio.h /usr/include/features.h \
+ /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h \
+ /usr/include/bits/types.h /usr/include/libio.h /usr/include/_G_config.h \
+ /usr/include/wchar.h /usr/include/bits/wchar.h /usr/include/gconv.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h \
+ /usr/include/bits/stdio_lim.h /usr/include/bits/stdio.h \
+ /usr/include/stdlib.h /usr/include/string.h /usr/include/bits/string.h \
+ /usr/include/bits/string2.h /usr/include/endian.h \
+ /usr/include/bits/endian.h /usr/include/getopt.h cmdline.h
+cmdline.c :
+/usr/include/stdio.h :
+/usr/include/features.h :
+/usr/include/sys/cdefs.h :
+/usr/include/gnu/stubs.h :
+/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h :
+/usr/include/bits/types.h :
+/usr/include/libio.h :
+/usr/include/_G_config.h :
+/usr/include/wchar.h :
+/usr/include/bits/wchar.h :
+/usr/include/gconv.h :
+/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h :
+/usr/include/bits/stdio_lim.h :
+/usr/include/bits/stdio.h :
+/usr/include/stdlib.h :
+/usr/include/string.h :
+/usr/include/bits/string.h :
+/usr/include/bits/string2.h :
+/usr/include/endian.h :
+/usr/include/bits/endian.h :
+/usr/include/getopt.h :
+cmdline.h :
diff --git a/sgsnemu/.deps/pptpstuff.P b/sgsnemu/.deps/pptpstuff.P
new file mode 100644
index 0000000..4699f4f
--- /dev/null
+++ b/sgsnemu/.deps/pptpstuff.P
@@ -0,0 +1,107 @@
+pptpstuff.o: pptpstuff.c /usr/include/syslog.h /usr/include/sys/syslog.h \
+ /usr/include/features.h /usr/include/sys/cdefs.h \
+ /usr/include/gnu/stubs.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h \
+ /usr/include/ctype.h /usr/include/bits/types.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h \
+ /usr/include/endian.h /usr/include/bits/endian.h /usr/include/netdb.h \
+ /usr/include/netinet/in.h /usr/include/stdint.h \
+ /usr/include/bits/wchar.h /usr/include/bits/wordsize.h \
+ /usr/include/bits/socket.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/limits.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/syslimits.h \
+ /usr/include/limits.h /usr/include/sys/types.h /usr/include/time.h \
+ /usr/include/bits/sockaddr.h /usr/include/asm/socket.h \
+ /usr/include/asm/sockios.h /usr/include/bits/in.h \
+ /usr/include/bits/byteswap.h /usr/include/bits/netdb.h \
+ /usr/include/signal.h /usr/include/bits/sigset.h \
+ /usr/include/bits/signum.h /usr/include/stdio.h /usr/include/libio.h \
+ /usr/include/_G_config.h /usr/include/wchar.h /usr/include/gconv.h \
+ /usr/include/bits/stdio_lim.h /usr/include/bits/stdio.h \
+ /usr/include/string.h /usr/include/bits/string.h \
+ /usr/include/bits/string2.h /usr/include/stdlib.h \
+ /usr/include/sys/socket.h /usr/include/sys/uio.h \
+ /usr/include/bits/uio.h /usr/include/arpa/inet.h \
+ /usr/include/sys/wait.h /usr/include/sys/resource.h \
+ /usr/include/bits/resource.h /usr/include/bits/time.h \
+ /usr/include/bits/waitflags.h /usr/include/bits/waitstatus.h \
+ /usr/include/sys/stat.h /usr/include/bits/stat.h /usr/include/unistd.h \
+ /usr/include/bits/posix_opt.h /usr/include/bits/confname.h \
+ /usr/include/sys/ioctl.h /usr/include/bits/ioctls.h \
+ /usr/include/asm/ioctls.h /usr/include/asm/ioctl.h \
+ /usr/include/bits/ioctl-types.h /usr/include/sys/ttydefaults.h \
+ /usr/include/net/if.h /usr/include/errno.h /usr/include/bits/errno.h \
+ /usr/include/linux/errno.h /usr/include/asm/errno.h \
+ /usr/include/asm/types.h /usr/include/linux/netlink.h pptpstuff.h
+pptpstuff.c :
+/usr/include/syslog.h :
+/usr/include/sys/syslog.h :
+/usr/include/features.h :
+/usr/include/sys/cdefs.h :
+/usr/include/gnu/stubs.h :
+/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h :
+/usr/include/ctype.h :
+/usr/include/bits/types.h :
+/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h :
+/usr/include/endian.h :
+/usr/include/bits/endian.h :
+/usr/include/netdb.h :
+/usr/include/netinet/in.h :
+/usr/include/stdint.h :
+/usr/include/bits/wchar.h :
+/usr/include/bits/wordsize.h :
+/usr/include/bits/socket.h :
+/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/limits.h :
+/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/syslimits.h :
+/usr/include/limits.h :
+/usr/include/sys/types.h :
+/usr/include/time.h :
+/usr/include/bits/sockaddr.h :
+/usr/include/asm/socket.h :
+/usr/include/asm/sockios.h :
+/usr/include/bits/in.h :
+/usr/include/bits/byteswap.h :
+/usr/include/bits/netdb.h :
+/usr/include/signal.h :
+/usr/include/bits/sigset.h :
+/usr/include/bits/signum.h :
+/usr/include/stdio.h :
+/usr/include/libio.h :
+/usr/include/_G_config.h :
+/usr/include/wchar.h :
+/usr/include/gconv.h :
+/usr/include/bits/stdio_lim.h :
+/usr/include/bits/stdio.h :
+/usr/include/string.h :
+/usr/include/bits/string.h :
+/usr/include/bits/string2.h :
+/usr/include/stdlib.h :
+/usr/include/sys/socket.h :
+/usr/include/sys/uio.h :
+/usr/include/bits/uio.h :
+/usr/include/arpa/inet.h :
+/usr/include/sys/wait.h :
+/usr/include/sys/resource.h :
+/usr/include/bits/resource.h :
+/usr/include/bits/time.h :
+/usr/include/bits/waitflags.h :
+/usr/include/bits/waitstatus.h :
+/usr/include/sys/stat.h :
+/usr/include/bits/stat.h :
+/usr/include/unistd.h :
+/usr/include/bits/posix_opt.h :
+/usr/include/bits/confname.h :
+/usr/include/sys/ioctl.h :
+/usr/include/bits/ioctls.h :
+/usr/include/asm/ioctls.h :
+/usr/include/asm/ioctl.h :
+/usr/include/bits/ioctl-types.h :
+/usr/include/sys/ttydefaults.h :
+/usr/include/net/if.h :
+/usr/include/errno.h :
+/usr/include/bits/errno.h :
+/usr/include/linux/errno.h :
+/usr/include/asm/errno.h :
+/usr/include/asm/types.h :
+/usr/include/linux/netlink.h :
+pptpstuff.h :
diff --git a/sgsnemu/.deps/sgsnemu.P b/sgsnemu/.deps/sgsnemu.P
new file mode 100644
index 0000000..f96d1c6
--- /dev/null
+++ b/sgsnemu/.deps/sgsnemu.P
@@ -0,0 +1,157 @@
+sgsnemu.o: sgsnemu.c /usr/include/syslog.h /usr/include/sys/syslog.h \
+ /usr/include/features.h /usr/include/sys/cdefs.h \
+ /usr/include/gnu/stubs.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h \
+ /usr/include/ctype.h /usr/include/bits/types.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h \
+ /usr/include/bits/pthreadtypes.h /usr/include/bits/sched.h \
+ /usr/include/endian.h /usr/include/bits/endian.h /usr/include/xlocale.h \
+ /usr/include/netdb.h /usr/include/netinet/in.h /usr/include/stdint.h \
+ /usr/include/bits/wchar.h /usr/include/bits/wordsize.h \
+ /usr/include/bits/socket.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/limits.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/syslimits.h \
+ /usr/include/limits.h /usr/include/bits/posix1_lim.h \
+ /usr/include/bits/local_lim.h /usr/include/linux/limits.h \
+ /usr/include/bits/posix2_lim.h /usr/include/bits/xopen_lim.h \
+ /usr/include/bits/stdio_lim.h /usr/include/sys/types.h \
+ /usr/include/time.h /usr/include/sys/select.h \
+ /usr/include/bits/select.h /usr/include/bits/sigset.h \
+ /usr/include/bits/time.h /usr/include/sys/sysmacros.h \
+ /usr/include/bits/sockaddr.h /usr/include/asm/socket.h \
+ /usr/include/asm/sockios.h /usr/include/bits/in.h \
+ /usr/include/bits/byteswap.h /usr/include/rpc/netdb.h \
+ /usr/include/bits/siginfo.h /usr/include/bits/netdb.h \
+ /usr/include/signal.h /usr/include/bits/signum.h \
+ /usr/include/bits/sigaction.h /usr/include/bits/sigcontext.h \
+ /usr/include/asm/sigcontext.h /usr/include/bits/sigstack.h \
+ /usr/include/ucontext.h /usr/include/sys/ucontext.h \
+ /usr/include/bits/sigthread.h /usr/include/stdio.h /usr/include/libio.h \
+ /usr/include/_G_config.h /usr/include/wchar.h /usr/include/gconv.h \
+ /usr/include/bits/stdio.h /usr/include/string.h \
+ /usr/include/bits/string.h /usr/include/bits/string2.h \
+ /usr/include/stdlib.h /usr/include/bits/waitflags.h \
+ /usr/include/bits/waitstatus.h /usr/include/alloca.h \
+ /usr/include/sys/socket.h /usr/include/sys/uio.h \
+ /usr/include/bits/uio.h /usr/include/arpa/inet.h \
+ /usr/include/sys/wait.h /usr/include/sys/resource.h \
+ /usr/include/bits/resource.h /usr/include/sys/stat.h \
+ /usr/include/bits/stat.h /usr/include/unistd.h \
+ /usr/include/bits/posix_opt.h /usr/include/bits/environments.h \
+ /usr/include/bits/confname.h /usr/include/getopt.h \
+ /usr/include/sys/ioctl.h /usr/include/bits/ioctls.h \
+ /usr/include/asm/ioctls.h /usr/include/asm/ioctl.h \
+ /usr/include/bits/ioctl-types.h /usr/include/sys/ttydefaults.h \
+ /usr/include/net/if.h /usr/include/errno.h /usr/include/bits/errno.h \
+ /usr/include/linux/errno.h /usr/include/asm/errno.h \
+ /usr/include/asm/types.h /usr/include/linux/netlink.h \
+ /usr/include/resolv.h /usr/include/sys/param.h \
+ /usr/include/linux/param.h /usr/include/asm/param.h \
+ /usr/include/sys/bitypes.h /usr/include/arpa/nameser.h \
+ /usr/include/arpa/nameser_compat.h tun.h ../gtp/pdp.h ../gtp/gtp.h \
+ cmdline.h
+sgsnemu.c :
+/usr/include/syslog.h :
+/usr/include/sys/syslog.h :
+/usr/include/features.h :
+/usr/include/sys/cdefs.h :
+/usr/include/gnu/stubs.h :
+/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h :
+/usr/include/ctype.h :
+/usr/include/bits/types.h :
+/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h :
+/usr/include/bits/pthreadtypes.h :
+/usr/include/bits/sched.h :
+/usr/include/endian.h :
+/usr/include/bits/endian.h :
+/usr/include/xlocale.h :
+/usr/include/netdb.h :
+/usr/include/netinet/in.h :
+/usr/include/stdint.h :
+/usr/include/bits/wchar.h :
+/usr/include/bits/wordsize.h :
+/usr/include/bits/socket.h :
+/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/limits.h :
+/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/syslimits.h :
+/usr/include/limits.h :
+/usr/include/bits/posix1_lim.h :
+/usr/include/bits/local_lim.h :
+/usr/include/linux/limits.h :
+/usr/include/bits/posix2_lim.h :
+/usr/include/bits/xopen_lim.h :
+/usr/include/bits/stdio_lim.h :
+/usr/include/sys/types.h :
+/usr/include/time.h :
+/usr/include/sys/select.h :
+/usr/include/bits/select.h :
+/usr/include/bits/sigset.h :
+/usr/include/bits/time.h :
+/usr/include/sys/sysmacros.h :
+/usr/include/bits/sockaddr.h :
+/usr/include/asm/socket.h :
+/usr/include/asm/sockios.h :
+/usr/include/bits/in.h :
+/usr/include/bits/byteswap.h :
+/usr/include/rpc/netdb.h :
+/usr/include/bits/siginfo.h :
+/usr/include/bits/netdb.h :
+/usr/include/signal.h :
+/usr/include/bits/signum.h :
+/usr/include/bits/sigaction.h :
+/usr/include/bits/sigcontext.h :
+/usr/include/asm/sigcontext.h :
+/usr/include/bits/sigstack.h :
+/usr/include/ucontext.h :
+/usr/include/sys/ucontext.h :
+/usr/include/bits/sigthread.h :
+/usr/include/stdio.h :
+/usr/include/libio.h :
+/usr/include/_G_config.h :
+/usr/include/wchar.h :
+/usr/include/gconv.h :
+/usr/include/bits/stdio.h :
+/usr/include/string.h :
+/usr/include/bits/string.h :
+/usr/include/bits/string2.h :
+/usr/include/stdlib.h :
+/usr/include/bits/waitflags.h :
+/usr/include/bits/waitstatus.h :
+/usr/include/alloca.h :
+/usr/include/sys/socket.h :
+/usr/include/sys/uio.h :
+/usr/include/bits/uio.h :
+/usr/include/arpa/inet.h :
+/usr/include/sys/wait.h :
+/usr/include/sys/resource.h :
+/usr/include/bits/resource.h :
+/usr/include/sys/stat.h :
+/usr/include/bits/stat.h :
+/usr/include/unistd.h :
+/usr/include/bits/posix_opt.h :
+/usr/include/bits/environments.h :
+/usr/include/bits/confname.h :
+/usr/include/getopt.h :
+/usr/include/sys/ioctl.h :
+/usr/include/bits/ioctls.h :
+/usr/include/asm/ioctls.h :
+/usr/include/asm/ioctl.h :
+/usr/include/bits/ioctl-types.h :
+/usr/include/sys/ttydefaults.h :
+/usr/include/net/if.h :
+/usr/include/errno.h :
+/usr/include/bits/errno.h :
+/usr/include/linux/errno.h :
+/usr/include/asm/errno.h :
+/usr/include/asm/types.h :
+/usr/include/linux/netlink.h :
+/usr/include/resolv.h :
+/usr/include/sys/param.h :
+/usr/include/linux/param.h :
+/usr/include/asm/param.h :
+/usr/include/sys/bitypes.h :
+/usr/include/arpa/nameser.h :
+/usr/include/arpa/nameser_compat.h :
+tun.h :
+../gtp/pdp.h :
+../gtp/gtp.h :
+cmdline.h :
diff --git a/sgsnemu/.deps/sgsnemuopt.P b/sgsnemu/.deps/sgsnemuopt.P
new file mode 100644
index 0000000..233a15f
--- /dev/null
+++ b/sgsnemu/.deps/sgsnemuopt.P
@@ -0,0 +1,33 @@
+sgsnemuopt.o: sgsnemuopt.c /usr/include/stdio.h /usr/include/features.h \
+ /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h \
+ /usr/include/bits/types.h /usr/include/libio.h /usr/include/_G_config.h \
+ /usr/include/wchar.h /usr/include/bits/wchar.h /usr/include/gconv.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h \
+ /usr/include/bits/stdio_lim.h /usr/include/bits/stdio.h \
+ /usr/include/stdlib.h /usr/include/string.h /usr/include/bits/string.h \
+ /usr/include/bits/string2.h /usr/include/endian.h \
+ /usr/include/bits/endian.h /usr/include/getopt.h sgsnemuopt.h
+sgsnemuopt.c :
+/usr/include/stdio.h :
+/usr/include/features.h :
+/usr/include/sys/cdefs.h :
+/usr/include/gnu/stubs.h :
+/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h :
+/usr/include/bits/types.h :
+/usr/include/libio.h :
+/usr/include/_G_config.h :
+/usr/include/wchar.h :
+/usr/include/bits/wchar.h :
+/usr/include/gconv.h :
+/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h :
+/usr/include/bits/stdio_lim.h :
+/usr/include/bits/stdio.h :
+/usr/include/stdlib.h :
+/usr/include/string.h :
+/usr/include/bits/string.h :
+/usr/include/bits/string2.h :
+/usr/include/endian.h :
+/usr/include/bits/endian.h :
+/usr/include/getopt.h :
+sgsnemuopt.h :
diff --git a/sgsnemu/.deps/tun.P b/sgsnemu/.deps/tun.P
new file mode 100644
index 0000000..29f9cf4
--- /dev/null
+++ b/sgsnemu/.deps/tun.P
@@ -0,0 +1,108 @@
+tun.o: tun.c /usr/include/syslog.h /usr/include/sys/syslog.h \
+ /usr/include/features.h /usr/include/sys/cdefs.h \
+ /usr/include/gnu/stubs.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h \
+ /usr/include/stdio.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h \
+ /usr/include/bits/types.h /usr/include/libio.h /usr/include/_G_config.h \
+ /usr/include/wchar.h /usr/include/bits/wchar.h /usr/include/gconv.h \
+ /usr/include/bits/stdio_lim.h /usr/include/bits/stdio.h \
+ /usr/include/stdlib.h /usr/include/sys/types.h /usr/include/time.h \
+ /usr/include/sys/socket.h /usr/include/sys/uio.h \
+ /usr/include/bits/uio.h /usr/include/bits/socket.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/limits.h \
+ /usr/lib/gcc-lib/i386-redhat-linux/2.96/include/syslimits.h \
+ /usr/include/limits.h /usr/include/bits/sockaddr.h \
+ /usr/include/asm/socket.h /usr/include/asm/sockios.h \
+ /usr/include/netinet/in.h /usr/include/stdint.h \
+ /usr/include/bits/wordsize.h /usr/include/bits/in.h \
+ /usr/include/endian.h /usr/include/bits/endian.h \
+ /usr/include/bits/byteswap.h /usr/include/arpa/inet.h \
+ /usr/include/sys/stat.h /usr/include/bits/stat.h \
+ /usr/include/sys/time.h /usr/include/bits/time.h \
+ /usr/include/sys/select.h /usr/include/bits/select.h \
+ /usr/include/bits/sigset.h /usr/include/unistd.h \
+ /usr/include/bits/posix_opt.h /usr/include/bits/confname.h \
+ /usr/include/string.h /usr/include/bits/string.h \
+ /usr/include/bits/string2.h /usr/include/errno.h \
+ /usr/include/bits/errno.h /usr/include/linux/errno.h \
+ /usr/include/asm/errno.h /usr/include/fcntl.h /usr/include/bits/fcntl.h \
+ /usr/include/sys/ioctl.h /usr/include/bits/ioctls.h \
+ /usr/include/asm/ioctls.h /usr/include/asm/ioctl.h \
+ /usr/include/bits/ioctl-types.h /usr/include/sys/ttydefaults.h \
+ /usr/include/linux/if.h /usr/include/linux/types.h \
+ /usr/include/linux/posix_types.h /usr/include/linux/stddef.h \
+ /usr/include/asm/posix_types.h /usr/include/asm/types.h \
+ /usr/include/linux/socket.h /usr/include/linux/if_tun.h tun.h
+tun.c :
+/usr/include/syslog.h :
+/usr/include/sys/syslog.h :
+/usr/include/features.h :
+/usr/include/sys/cdefs.h :
+/usr/include/gnu/stubs.h :
+/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stdarg.h :
+/usr/include/stdio.h :
+/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/stddef.h :
+/usr/include/bits/types.h :
+/usr/include/libio.h :
+/usr/include/_G_config.h :
+/usr/include/wchar.h :
+/usr/include/bits/wchar.h :
+/usr/include/gconv.h :
+/usr/include/bits/stdio_lim.h :
+/usr/include/bits/stdio.h :
+/usr/include/stdlib.h :
+/usr/include/sys/types.h :
+/usr/include/time.h :
+/usr/include/sys/socket.h :
+/usr/include/sys/uio.h :
+/usr/include/bits/uio.h :
+/usr/include/bits/socket.h :
+/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/limits.h :
+/usr/lib/gcc-lib/i386-redhat-linux/2.96/include/syslimits.h :
+/usr/include/limits.h :
+/usr/include/bits/sockaddr.h :
+/usr/include/asm/socket.h :
+/usr/include/asm/sockios.h :
+/usr/include/netinet/in.h :
+/usr/include/stdint.h :
+/usr/include/bits/wordsize.h :
+/usr/include/bits/in.h :
+/usr/include/endian.h :
+/usr/include/bits/endian.h :
+/usr/include/bits/byteswap.h :
+/usr/include/arpa/inet.h :
+/usr/include/sys/stat.h :
+/usr/include/bits/stat.h :
+/usr/include/sys/time.h :
+/usr/include/bits/time.h :
+/usr/include/sys/select.h :
+/usr/include/bits/select.h :
+/usr/include/bits/sigset.h :
+/usr/include/unistd.h :
+/usr/include/bits/posix_opt.h :
+/usr/include/bits/confname.h :
+/usr/include/string.h :
+/usr/include/bits/string.h :
+/usr/include/bits/string2.h :
+/usr/include/errno.h :
+/usr/include/bits/errno.h :
+/usr/include/linux/errno.h :
+/usr/include/asm/errno.h :
+/usr/include/fcntl.h :
+/usr/include/bits/fcntl.h :
+/usr/include/sys/ioctl.h :
+/usr/include/bits/ioctls.h :
+/usr/include/asm/ioctls.h :
+/usr/include/asm/ioctl.h :
+/usr/include/bits/ioctl-types.h :
+/usr/include/sys/ttydefaults.h :
+/usr/include/linux/if.h :
+/usr/include/linux/types.h :
+/usr/include/linux/posix_types.h :
+/usr/include/linux/stddef.h :
+/usr/include/asm/posix_types.h :
+/usr/include/asm/types.h :
+/usr/include/linux/socket.h :
+/usr/include/linux/if_tun.h :
+tun.h :
diff --git a/sgsnemu/Makefile b/sgsnemu/Makefile
new file mode 100644
index 0000000..24a2b1c
--- /dev/null
+++ b/sgsnemu/Makefile
@@ -0,0 +1,343 @@
+# Generated automatically from Makefile.in by configure.
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = /bin/sh
+
+srcdir = .
+top_srcdir = ..
+prefix = /usr/local
+exec_prefix = ${prefix}
+
+bindir = ${exec_prefix}/bin
+sbindir = ${exec_prefix}/sbin
+libexecdir = ${exec_prefix}/libexec
+datadir = ${prefix}/share
+sysconfdir = ${prefix}/etc
+sharedstatedir = ${prefix}/com
+localstatedir = ${prefix}/var
+libdir = ${exec_prefix}/lib
+infodir = ${prefix}/info
+mandir = ${prefix}/man
+includedir = ${prefix}/include
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/OpenGGSN
+pkglibdir = $(libdir)/OpenGGSN
+pkgincludedir = $(includedir)/OpenGGSN
+
+top_builddir = ..
+
+ACLOCAL = aclocal
+AUTOCONF = autoconf
+AUTOMAKE = automake
+AUTOHEADER = autoheader
+
+INSTALL = /usr/bin/install -c
+INSTALL_PROGRAM = ${INSTALL} $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = ${INSTALL} -m 644
+INSTALL_SCRIPT = ${INSTALL_PROGRAM}
+transform = s,x,x,
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = i686-pc-linux
+host_triplet = i686-pc-linux-gnu
+AS = @AS@
+AWK = gawk
+CC = gcc
+DLLTOOL = @DLLTOOL@
+LIBTOOL = $(SHELL) $(top_builddir)/libtool
+LN_S = ln -s
+MAKEINFO = makeinfo
+OBJDUMP = @OBJDUMP@
+PACKAGE = OpenGGSN
+RANLIB = ranlib
+VERSION = 0.5
+
+bin_PROGRAMS = sgsnemu
+
+CFLAGS = -O2 -fno-builtin -Wall -ansi -DSBINDIR='"$(sbindir)"' -lgtp
+
+sgsnemu_SOURCES = sgsnemu.c tun.c tun.h cmdline.c cmdline.h
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_CLEAN_FILES =
+PROGRAMS = $(bin_PROGRAMS)
+
+
+DEFS = -DSTDC_HEADERS=1 -DHAVE_SYS_WAIT_H=1 -DHAVE_FCNTL_H=1 -DHAVE_STRINGS_H=1 -DHAVE_SYS_IOCTL_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYSLOG_H=1 -DHAVE_UNISTD_H=1 -DTIME_WITH_SYS_TIME=1 -DHAVE_SELECT=1 -DHAVE_SOCKET=1 -DHAVE_STRDUP=1 -DHAVE_STRERROR=1 -DHAVE_STRTOUL=1 -DPACKAGE=\"OpenGGSN\" -DVERSION=\"0.5\" -I. -I$(srcdir)
+CPPFLAGS =
+LDFLAGS =
+LIBS =
+sgsnemu_OBJECTS = sgsnemu.o tun.o cmdline.o
+sgsnemu_LDADD = $(LDADD)
+sgsnemu_DEPENDENCIES =
+sgsnemu_LDFLAGS =
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON = Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = gtar
+GZIP_ENV = --best
+DEP_FILES = .deps/cmdline.P .deps/sgsnemu.P .deps/tun.P
+SOURCES = $(sgsnemu_SOURCES)
+OBJECTS = $(sgsnemu_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .lo .o .s
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --gnu sgsnemu/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-binPROGRAMS:
+
+clean-binPROGRAMS:
+ -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+
+distclean-binPROGRAMS:
+
+maintainer-clean-binPROGRAMS:
+
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ list='$(bin_PROGRAMS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ done
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+sgsnemu: $(sgsnemu_OBJECTS) $(sgsnemu_DEPENDENCIES)
+ @rm -f sgsnemu
+ $(LINK) $(sgsnemu_LDFLAGS) $(sgsnemu_OBJECTS) $(sgsnemu_LDADD) $(LIBS)
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = sgsnemu
+
+distdir: $(DISTFILES)
+ here=`cd $(top_builddir) && pwd`; \
+ top_distdir=`cd $(top_distdir) && pwd`; \
+ distdir=`cd $(distdir) && pwd`; \
+ cd $(top_srcdir) \
+ && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu sgsnemu/Makefile
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$d/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+ -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+ @echo '$(COMPILE) -c $<'; \
+ $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.c
+ @echo '$(LTCOMPILE) -c $<'; \
+ $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am: install-binPROGRAMS
+install-exec: install-exec-am
+
+install-data-am:
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-binPROGRAMS
+uninstall: uninstall-am
+all-am: Makefile $(PROGRAMS)
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-binPROGRAMS mostlyclean-compile \
+ mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
+ mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-binPROGRAMS clean-compile clean-libtool clean-tags \
+ clean-depend clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-binPROGRAMS distclean-compile distclean-libtool \
+ distclean-tags distclean-depend distclean-generic \
+ clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-binPROGRAMS \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-tags maintainer-clean-depend \
+ maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \
+maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile mostlyclean-libtool distclean-libtool \
+clean-libtool maintainer-clean-libtool tags mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir \
+mostlyclean-depend distclean-depend clean-depend \
+maintainer-clean-depend info-am info dvi-am dvi check check-am \
+installcheck-am installcheck install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+cmdline.c: cmdline.ggo
+ gengetopt < cmdline.ggo --unamed-opts --conf-parser
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/sgsnemu/Makefile.am b/sgsnemu/Makefile.am
new file mode 100644
index 0000000..064f91f
--- /dev/null
+++ b/sgsnemu/Makefile.am
@@ -0,0 +1,11 @@
+bin_PROGRAMS = sgsnemu
+
+CFLAGS = -O2 -fno-builtin -Wall -ansi -DSBINDIR='"$(sbindir)"' -lgtp
+
+sgsnemu_SOURCES = sgsnemu.c tun.c tun.h cmdline.c cmdline.h
+
+cmdline.c: cmdline.ggo
+ gengetopt < cmdline.ggo --unamed-opts --conf-parser
+
+
+
diff --git a/sgsnemu/Makefile.in b/sgsnemu/Makefile.in
new file mode 100644
index 0000000..b99ad73
--- /dev/null
+++ b/sgsnemu/Makefile.in
@@ -0,0 +1,343 @@
+# Makefile.in generated automatically by automake 1.4 from Makefile.am
+
+# Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+
+SHELL = @SHELL@
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+oldincludedir = /usr/include
+
+DESTDIR =
+
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+
+top_builddir = ..
+
+ACLOCAL = @ACLOCAL@
+AUTOCONF = @AUTOCONF@
+AUTOMAKE = @AUTOMAKE@
+AUTOHEADER = @AUTOHEADER@
+
+INSTALL = @INSTALL@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@ $(AM_INSTALL_PROGRAM_FLAGS)
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+transform = @program_transform_name@
+
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+host_alias = @host_alias@
+host_triplet = @host@
+AS = @AS@
+AWK = @AWK@
+CC = @CC@
+DLLTOOL = @DLLTOOL@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+MAKEINFO = @MAKEINFO@
+OBJDUMP = @OBJDUMP@
+PACKAGE = @PACKAGE@
+RANLIB = @RANLIB@
+VERSION = @VERSION@
+
+bin_PROGRAMS = sgsnemu
+
+CFLAGS = -O2 -fno-builtin -Wall -ansi -DSBINDIR='"$(sbindir)"' -lgtp
+
+sgsnemu_SOURCES = sgsnemu.c tun.c tun.h cmdline.c cmdline.h
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_CLEAN_FILES =
+PROGRAMS = $(bin_PROGRAMS)
+
+
+DEFS = @DEFS@ -I. -I$(srcdir)
+CPPFLAGS = @CPPFLAGS@
+LDFLAGS = @LDFLAGS@
+LIBS = @LIBS@
+sgsnemu_OBJECTS = sgsnemu.o tun.o cmdline.o
+sgsnemu_LDADD = $(LDADD)
+sgsnemu_DEPENDENCIES =
+sgsnemu_LDFLAGS =
+COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(LDFLAGS) -o $@
+DIST_COMMON = Makefile.am Makefile.in
+
+
+DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
+
+TAR = gtar
+GZIP_ENV = --best
+DEP_FILES = .deps/cmdline.P .deps/sgsnemu.P .deps/tun.P
+SOURCES = $(sgsnemu_SOURCES)
+OBJECTS = $(sgsnemu_OBJECTS)
+
+all: all-redirect
+.SUFFIXES:
+.SUFFIXES: .S .c .lo .o .s
+$(srcdir)/Makefile.in: Makefile.am $(top_srcdir)/configure.in $(ACLOCAL_M4)
+ cd $(top_srcdir) && $(AUTOMAKE) --gnu sgsnemu/Makefile
+
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status $(BUILT_SOURCES)
+ cd $(top_builddir) \
+ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status
+
+
+mostlyclean-binPROGRAMS:
+
+clean-binPROGRAMS:
+ -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS)
+
+distclean-binPROGRAMS:
+
+maintainer-clean-binPROGRAMS:
+
+install-binPROGRAMS: $(bin_PROGRAMS)
+ @$(NORMAL_INSTALL)
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+ @list='$(bin_PROGRAMS)'; for p in $$list; do \
+ if test -f $$p; then \
+ echo " $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`"; \
+ $(LIBTOOL) --mode=install $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ else :; fi; \
+ done
+
+uninstall-binPROGRAMS:
+ @$(NORMAL_UNINSTALL)
+ list='$(bin_PROGRAMS)'; for p in $$list; do \
+ rm -f $(DESTDIR)$(bindir)/`echo $$p|sed 's/$(EXEEXT)$$//'|sed '$(transform)'|sed 's/$$/$(EXEEXT)/'`; \
+ done
+
+.s.o:
+ $(COMPILE) -c $<
+
+.S.o:
+ $(COMPILE) -c $<
+
+mostlyclean-compile:
+ -rm -f *.o core *.core
+
+clean-compile:
+
+distclean-compile:
+ -rm -f *.tab.c
+
+maintainer-clean-compile:
+
+.s.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+.S.lo:
+ $(LIBTOOL) --mode=compile $(COMPILE) -c $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+
+distclean-libtool:
+
+maintainer-clean-libtool:
+
+sgsnemu: $(sgsnemu_OBJECTS) $(sgsnemu_DEPENDENCIES)
+ @rm -f sgsnemu
+ $(LINK) $(sgsnemu_LDFLAGS) $(sgsnemu_OBJECTS) $(sgsnemu_LDADD) $(LIBS)
+
+tags: TAGS
+
+ID: $(HEADERS) $(SOURCES) $(LISP)
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ here=`pwd` && cd $(srcdir) \
+ && mkid -f$$here/ID $$unique $(LISP)
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS)'; \
+ unique=`for i in $$list; do echo $$i; done | \
+ awk ' { files[$$0] = 1; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(ETAGS_ARGS)$$unique$(LISP)$$tags" \
+ || (cd $(srcdir) && etags $(ETAGS_ARGS) $$tags $$unique $(LISP) -o $$here/TAGS)
+
+mostlyclean-tags:
+
+clean-tags:
+
+distclean-tags:
+ -rm -f TAGS ID
+
+maintainer-clean-tags:
+
+distdir = $(top_builddir)/$(PACKAGE)-$(VERSION)/$(subdir)
+
+subdir = sgsnemu
+
+distdir: $(DISTFILES)
+ here=`cd $(top_builddir) && pwd`; \
+ top_distdir=`cd $(top_distdir) && pwd`; \
+ distdir=`cd $(distdir) && pwd`; \
+ cd $(top_srcdir) \
+ && $(AUTOMAKE) --include-deps --build-dir=$$here --srcdir-name=$(top_srcdir) --output-dir=$$top_distdir --gnu sgsnemu/Makefile
+ @for file in $(DISTFILES); do \
+ d=$(srcdir); \
+ if test -d $$d/$$file; then \
+ cp -pr $$d/$$file $(distdir)/$$file; \
+ else \
+ test -f $(distdir)/$$file \
+ || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
+ || cp -p $$d/$$file $(distdir)/$$file || :; \
+ fi; \
+ done
+
+DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
+
+-include $(DEP_FILES)
+
+mostlyclean-depend:
+
+clean-depend:
+
+distclean-depend:
+ -rm -rf .deps
+
+maintainer-clean-depend:
+
+%.o: %.c
+ @echo '$(COMPILE) -c $<'; \
+ $(COMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-cp .deps/$(*F).pp .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm .deps/$(*F).pp
+
+%.lo: %.c
+ @echo '$(LTCOMPILE) -c $<'; \
+ $(LTCOMPILE) -Wp,-MD,.deps/$(*F).pp -c $<
+ @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \
+ < .deps/$(*F).pp > .deps/$(*F).P; \
+ tr ' ' '\012' < .deps/$(*F).pp \
+ | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \
+ >> .deps/$(*F).P; \
+ rm -f .deps/$(*F).pp
+info-am:
+info: info-am
+dvi-am:
+dvi: dvi-am
+check-am: all-am
+check: check-am
+installcheck-am:
+installcheck: installcheck-am
+install-exec-am: install-binPROGRAMS
+install-exec: install-exec-am
+
+install-data-am:
+install-data: install-data-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+install: install-am
+uninstall-am: uninstall-binPROGRAMS
+uninstall: uninstall-am
+all-am: Makefile $(PROGRAMS)
+all-redirect: all-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) AM_INSTALL_PROGRAM_FLAGS=-s install
+installdirs:
+ $(mkinstalldirs) $(DESTDIR)$(bindir)
+
+
+mostlyclean-generic:
+
+clean-generic:
+
+distclean-generic:
+ -rm -f Makefile $(CONFIG_CLEAN_FILES)
+ -rm -f config.cache config.log stamp-h stamp-h[0-9]*
+
+maintainer-clean-generic:
+mostlyclean-am: mostlyclean-binPROGRAMS mostlyclean-compile \
+ mostlyclean-libtool mostlyclean-tags mostlyclean-depend \
+ mostlyclean-generic
+
+mostlyclean: mostlyclean-am
+
+clean-am: clean-binPROGRAMS clean-compile clean-libtool clean-tags \
+ clean-depend clean-generic mostlyclean-am
+
+clean: clean-am
+
+distclean-am: distclean-binPROGRAMS distclean-compile distclean-libtool \
+ distclean-tags distclean-depend distclean-generic \
+ clean-am
+ -rm -f libtool
+
+distclean: distclean-am
+
+maintainer-clean-am: maintainer-clean-binPROGRAMS \
+ maintainer-clean-compile maintainer-clean-libtool \
+ maintainer-clean-tags maintainer-clean-depend \
+ maintainer-clean-generic distclean-am
+ @echo "This command is intended for maintainers to use;"
+ @echo "it deletes files that may require special tools to rebuild."
+
+maintainer-clean: maintainer-clean-am
+
+.PHONY: mostlyclean-binPROGRAMS distclean-binPROGRAMS clean-binPROGRAMS \
+maintainer-clean-binPROGRAMS uninstall-binPROGRAMS install-binPROGRAMS \
+mostlyclean-compile distclean-compile clean-compile \
+maintainer-clean-compile mostlyclean-libtool distclean-libtool \
+clean-libtool maintainer-clean-libtool tags mostlyclean-tags \
+distclean-tags clean-tags maintainer-clean-tags distdir \
+mostlyclean-depend distclean-depend clean-depend \
+maintainer-clean-depend info-am info dvi-am dvi check check-am \
+installcheck-am installcheck install-exec-am install-exec \
+install-data-am install-data install-am install uninstall-am uninstall \
+all-redirect all-am all installdirs mostlyclean-generic \
+distclean-generic clean-generic maintainer-clean-generic clean \
+mostlyclean distclean maintainer-clean
+
+
+cmdline.c: cmdline.ggo
+ gengetopt < cmdline.ggo --unamed-opts --conf-parser
+
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/sgsnemu/cmdline.c b/sgsnemu/cmdline.c
new file mode 100644
index 0000000..ede48bf
--- /dev/null
+++ b/sgsnemu/cmdline.c
@@ -0,0 +1,776 @@
+/*
+ File autogenerated by gengetopt version 2.8rc
+ generated with the following command:
+ ../../gengetopt-2.8rc/src/gengetopt --conf-parser
+
+ The developers of gengetopt consider the fixed text that goes in all
+ gengetopt output files to be in the public domain:
+ we make no copyright claims on it.
+*/
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+/* If we use autoconf. */
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+/* Check for configure's getopt check result. */
+#ifndef HAVE_GETOPT_LONG
+#include "getopt.h"
+#else
+#include <getopt.h>
+#endif
+
+#ifndef HAVE_STRDUP
+#define strdup gengetopt_strdup
+#endif /* HAVE_STRDUP */
+
+#include "cmdline.h"
+
+
+void
+cmdline_parser_print_version (void)
+{
+ printf ("%s %s\n", PACKAGE, VERSION);
+}
+
+void
+cmdline_parser_print_help (void)
+{
+ cmdline_parser_print_version ();
+ printf("\n"
+ "Usage: %s [OPTIONS]...\n", PACKAGE);
+ printf(" -h --help Print help and exit\n");
+ printf(" -V --version Print version and exit\n");
+ printf(" -f --fg Run in foreground (default=off)\n");
+ printf(" -d --debug Run in debug mode (default=off)\n");
+ printf(" -cSTRING --conf=STRING Read configuration file\n");
+ printf(" --pidfile=STRING Filename of process id file (default='./sgsnemu.pid')\n");
+ printf(" --statedir=STRING Directory of nonvolatile data (default='./')\n");
+ printf(" --dns=STRING DNS Server to use\n");
+ printf(" -lSTRING --listen=STRING Local interface\n");
+ printf(" -rSTRING --remote=STRING Remote host\n");
+ printf(" -nSTRING --net=STRING Network (default='192.168.0.0')\n");
+ printf(" --mask=STRING Network mask (default='255.255.255.0')\n");
+ printf(" --contexts=INT Number of contexts (default='1')\n");
+ printf(" --static Allocate static tun ifterface (default=off)\n");
+ printf(" --timelimit=INT Exit after timelimit seconds (default='0')\n");
+ printf(" -aSTRING --apn=STRING Access point name (default='internet')\n");
+ printf(" -iSTRING --imsi=STRING IMSI (default='240010123456789')\n");
+ printf(" -mSTRING --msisdn=STRING Mobile Station ISDN number (default='46702123456')\n");
+ printf(" -qINT --qos=INT Requested quality of service (default='0x0b921f')\n");
+ printf(" -uSTRING --uid=STRING Login user ID (default='mig')\n");
+ printf(" -pSTRING --pwd=STRING Login password (default='hemmelig')\n");
+}
+
+
+#ifndef HAVE_STRDUP
+/* gengetopt_strdup(): automatically generated from strdup.c. */
+/* strdup.c replacement of strdup, which is not standard */
+static char *
+gengetopt_strdup (const char *s)
+{
+ char *result = (char*)malloc(strlen(s) + 1);
+ if (result == (char*)0)
+ return (char*)0;
+ strcpy(result, s);
+ return result;
+}
+#endif /* HAVE_STRDUP */
+
+int
+cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_info)
+{
+ int c; /* Character of the parsed option. */
+ int missing_required_options = 0;
+
+ args_info->help_given = 0 ;
+ args_info->version_given = 0 ;
+ args_info->fg_given = 0 ;
+ args_info->debug_given = 0 ;
+ args_info->conf_given = 0 ;
+ args_info->pidfile_given = 0 ;
+ args_info->statedir_given = 0 ;
+ args_info->dns_given = 0 ;
+ args_info->listen_given = 0 ;
+ args_info->remote_given = 0 ;
+ args_info->net_given = 0 ;
+ args_info->mask_given = 0 ;
+ args_info->contexts_given = 0 ;
+ args_info->static_given = 0 ;
+ args_info->timelimit_given = 0 ;
+ args_info->apn_given = 0 ;
+ args_info->imsi_given = 0 ;
+ args_info->msisdn_given = 0 ;
+ args_info->qos_given = 0 ;
+ args_info->uid_given = 0 ;
+ args_info->pwd_given = 0 ;
+#define clear_args() { \
+ args_info->fg_flag = 0;\
+ args_info->debug_flag = 0;\
+ args_info->conf_arg = NULL; \
+ args_info->pidfile_arg = strdup("./sgsnemu.pid") ;\
+ args_info->statedir_arg = strdup("./") ;\
+ args_info->dns_arg = NULL; \
+ args_info->listen_arg = NULL; \
+ args_info->remote_arg = NULL; \
+ args_info->net_arg = strdup("192.168.0.0") ;\
+ args_info->mask_arg = strdup("255.255.255.0") ;\
+ args_info->contexts_arg = 1 ;\
+ args_info->static_flag = 0;\
+ args_info->timelimit_arg = 0 ;\
+ args_info->apn_arg = strdup("internet") ;\
+ args_info->imsi_arg = strdup("240010123456789") ;\
+ args_info->msisdn_arg = strdup("46702123456") ;\
+ args_info->qos_arg = 0x0b921f ;\
+ args_info->uid_arg = strdup("mig") ;\
+ args_info->pwd_arg = strdup("hemmelig") ;\
+}
+
+ clear_args();
+
+ optarg = 0;
+ optind = 1;
+ opterr = 1;
+ optopt = '?';
+
+ while (1)
+ {
+ int option_index = 0;
+ char *stop_char;
+ static struct option long_options[] = {
+ { "help", 0, NULL, 'h' },
+ { "version", 0, NULL, 'V' },
+ { "fg", 0, NULL, 'f' },
+ { "debug", 0, NULL, 'd' },
+ { "conf", 1, NULL, 'c' },
+ { "pidfile", 1, NULL, 0 },
+ { "statedir", 1, NULL, 0 },
+ { "dns", 1, NULL, 0 },
+ { "listen", 1, NULL, 'l' },
+ { "remote", 1, NULL, 'r' },
+ { "net", 1, NULL, 'n' },
+ { "mask", 1, NULL, 0 },
+ { "contexts", 1, NULL, 0 },
+ { "static", 0, NULL, 0 },
+ { "timelimit", 1, NULL, 0 },
+ { "apn", 1, NULL, 'a' },
+ { "imsi", 1, NULL, 'i' },
+ { "msisdn", 1, NULL, 'm' },
+ { "qos", 1, NULL, 'q' },
+ { "uid", 1, NULL, 'u' },
+ { "pwd", 1, NULL, 'p' },
+ { NULL, 0, NULL, 0 }
+ };
+
+ c = getopt_long (argc, argv, "hVfdc:l:r:n:a:i:m:q:u:p:", long_options, &option_index);
+
+ if (c == -1) break; /* Exit from `while (1)' loop. */
+
+ switch (c)
+ {
+ case 'h': /* Print help and exit. */
+ clear_args ();
+ cmdline_parser_print_help ();
+ exit (EXIT_SUCCESS);
+
+ case 'V': /* Print version and exit. */
+ clear_args ();
+ cmdline_parser_print_version ();
+ exit (EXIT_SUCCESS);
+
+ case 'f': /* Run in foreground. */
+ if (args_info->fg_given)
+ {
+ fprintf (stderr, "%s: `--fg' (`-f') option given more than once\n", PACKAGE);
+ clear_args ();
+ exit (EXIT_FAILURE);
+ }
+ args_info->fg_given = 1;
+ args_info->fg_flag = !(args_info->fg_flag);
+ break;
+
+ case 'd': /* Run in debug mode. */
+ if (args_info->debug_given)
+ {
+ fprintf (stderr, "%s: `--debug' (`-d') option given more than once\n", PACKAGE);
+ clear_args ();
+ exit (EXIT_FAILURE);
+ }
+ args_info->debug_given = 1;
+ args_info->debug_flag = !(args_info->debug_flag);
+ break;
+
+ case 'c': /* Read configuration file. */
+ if (args_info->conf_given)
+ {
+ fprintf (stderr, "%s: `--conf' (`-c') option given more than once\n", PACKAGE);
+ clear_args ();
+ exit (EXIT_FAILURE);
+ }
+ args_info->conf_given = 1;
+ args_info->conf_arg = strdup (optarg);
+ break;
+
+ case 'l': /* Local interface. */
+ if (args_info->listen_given)
+ {
+ fprintf (stderr, "%s: `--listen' (`-l') option given more than once\n", PACKAGE);
+ clear_args ();
+ exit (EXIT_FAILURE);
+ }
+ args_info->listen_given = 1;
+ args_info->listen_arg = strdup (optarg);
+ break;
+
+ case 'r': /* Remote host. */
+ if (args_info->remote_given)
+ {
+ fprintf (stderr, "%s: `--remote' (`-r') option given more than once\n", PACKAGE);
+ clear_args ();
+ exit (EXIT_FAILURE);
+ }
+ args_info->remote_given = 1;
+ args_info->remote_arg = strdup (optarg);
+ break;
+
+ case 'n': /* Network. */
+ if (args_info->net_given)
+ {
+ fprintf (stderr, "%s: `--net' (`-n') option given more than once\n", PACKAGE);
+ clear_args ();
+ exit (EXIT_FAILURE);
+ }
+ args_info->net_given = 1;
+ args_info->net_arg = strdup (optarg);
+ break;
+
+ case 'a': /* Access point name. */
+ if (args_info->apn_given)
+ {
+ fprintf (stderr, "%s: `--apn' (`-a') option given more than once\n", PACKAGE);
+ clear_args ();
+ exit (EXIT_FAILURE);
+ }
+ args_info->apn_given = 1;
+ args_info->apn_arg = strdup (optarg);
+ break;
+
+ case 'i': /* IMSI. */
+ if (args_info->imsi_given)
+ {
+ fprintf (stderr, "%s: `--imsi' (`-i') option given more than once\n", PACKAGE);
+ clear_args ();
+ exit (EXIT_FAILURE);
+ }
+ args_info->imsi_given = 1;
+ args_info->imsi_arg = strdup (optarg);
+ break;
+
+ case 'm': /* Mobile Station ISDN number. */
+ if (args_info->msisdn_given)
+ {
+ fprintf (stderr, "%s: `--msisdn' (`-m') option given more than once\n", PACKAGE);
+ clear_args ();
+ exit (EXIT_FAILURE);
+ }
+ args_info->msisdn_given = 1;
+ args_info->msisdn_arg = strdup (optarg);
+ break;
+
+ case 'q': /* Requested quality of service. */
+ if (args_info->qos_given)
+ {
+ fprintf (stderr, "%s: `--qos' (`-q') option given more than once\n", PACKAGE);
+ clear_args ();
+ exit (EXIT_FAILURE);
+ }
+ args_info->qos_given = 1;
+ args_info->qos_arg = strtol (optarg,&stop_char,0);
+ break;
+
+ case 'u': /* Login user ID. */
+ if (args_info->uid_given)
+ {
+ fprintf (stderr, "%s: `--uid' (`-u') option given more than once\n", PACKAGE);
+ clear_args ();
+ exit (EXIT_FAILURE);
+ }
+ args_info->uid_given = 1;
+ args_info->uid_arg = strdup (optarg);
+ break;
+
+ case 'p': /* Login password. */
+ if (args_info->pwd_given)
+ {
+ fprintf (stderr, "%s: `--pwd' (`-p') option given more than once\n", PACKAGE);
+ clear_args ();
+ exit (EXIT_FAILURE);
+ }
+ args_info->pwd_given = 1;
+ args_info->pwd_arg = strdup (optarg);
+ break;
+
+
+ case 0: /* Long option with no short option */
+ /* Filename of process id file. */
+ if (strcmp (long_options[option_index].name, "pidfile") == 0)
+ {
+ if (args_info->pidfile_given)
+ {
+ fprintf (stderr, "%s: `--pidfile' option given more than once\n", PACKAGE);
+ clear_args ();
+ exit (EXIT_FAILURE);
+ }
+ args_info->pidfile_given = 1;
+ args_info->pidfile_arg = strdup (optarg);
+ break;
+ }
+ /* Directory of nonvolatile data. */
+ else if (strcmp (long_options[option_index].name, "statedir") == 0)
+ {
+ if (args_info->statedir_given)
+ {
+ fprintf (stderr, "%s: `--statedir' option given more than once\n", PACKAGE);
+ clear_args ();
+ exit (EXIT_FAILURE);
+ }
+ args_info->statedir_given = 1;
+ args_info->statedir_arg = strdup (optarg);
+ break;
+ }
+ /* DNS Server to use. */
+ else if (strcmp (long_options[option_index].name, "dns") == 0)
+ {
+ if (args_info->dns_given)
+ {
+ fprintf (stderr, "%s: `--dns' option given more than once\n", PACKAGE);
+ clear_args ();
+ exit (EXIT_FAILURE);
+ }
+ args_info->dns_given = 1;
+ args_info->dns_arg = strdup (optarg);
+ break;
+ }
+ /* Network mask. */
+ else if (strcmp (long_options[option_index].name, "mask") == 0)
+ {
+ if (args_info->mask_given)
+ {
+ fprintf (stderr, "%s: `--mask' option given more than once\n", PACKAGE);
+ clear_args ();
+ exit (EXIT_FAILURE);
+ }
+ args_info->mask_given = 1;
+ args_info->mask_arg = strdup (optarg);
+ break;
+ }
+ /* Number of contexts. */
+ else if (strcmp (long_options[option_index].name, "contexts") == 0)
+ {
+ if (args_info->contexts_given)
+ {
+ fprintf (stderr, "%s: `--contexts' option given more than once\n", PACKAGE);
+ clear_args ();
+ exit (EXIT_FAILURE);
+ }
+ args_info->contexts_given = 1;
+ args_info->contexts_arg = strtol (optarg,&stop_char,0);
+ break;
+ }
+ /* Allocate static tun ifterface. */
+ else if (strcmp (long_options[option_index].name, "static") == 0)
+ {
+ if (args_info->static_given)
+ {
+ fprintf (stderr, "%s: `--static' option given more than once\n", PACKAGE);
+ clear_args ();
+ exit (EXIT_FAILURE);
+ }
+ args_info->static_given = 1;
+ args_info->static_flag = !(args_info->static_flag);
+ break;
+ }
+ /* Exit after timelimit seconds. */
+ else if (strcmp (long_options[option_index].name, "timelimit") == 0)
+ {
+ if (args_info->timelimit_given)
+ {
+ fprintf (stderr, "%s: `--timelimit' option given more than once\n", PACKAGE);
+ clear_args ();
+ exit (EXIT_FAILURE);
+ }
+ args_info->timelimit_given = 1;
+ args_info->timelimit_arg = strtol (optarg,&stop_char,0);
+ break;
+ }
+
+ case '?': /* Invalid option. */
+ /* `getopt_long' already printed an error message. */
+ exit (EXIT_FAILURE);
+
+ default: /* bug: option not considered. */
+ fprintf (stderr, "%s: option unknown: %c\n", PACKAGE, c);
+ abort ();
+ } /* switch */
+ } /* while */
+
+
+ if ( missing_required_options )
+ exit (EXIT_FAILURE);
+
+ return 0;
+}
+
+#define CONFIGPARSERBUFSIZE 1024
+
+int
+cmdline_parser_configfile (char * const filename, struct gengetopt_args_info *args_info, int override)
+{
+ FILE* file;
+ char linebuf[CONFIGPARSERBUFSIZE];
+ int line_num = 0;
+ int len;
+ int fnum;
+ char fopt[CONFIGPARSERBUFSIZE], farg[CONFIGPARSERBUFSIZE];
+ char *stop_char;
+
+ if ((file = fopen(filename, "r")) == NULL)
+ {
+ fprintf (stderr, "%s: Error opening configuration file '%s'\n",
+ PACKAGE, filename);
+ exit (EXIT_FAILURE);
+ }
+
+ while ((fgets(linebuf, CONFIGPARSERBUFSIZE, file)) != NULL)
+ {
+ ++line_num;
+ len = strlen(linebuf);
+ if (len == CONFIGPARSERBUFSIZE-1)
+ {
+ fprintf (stderr, "%s: Line longer than %d characters found in configuration file '%s'\n",
+ PACKAGE, CONFIGPARSERBUFSIZE, filename);
+ exit (EXIT_FAILURE);
+ }
+
+ if (linebuf[0] == '#')
+ continue; /* Line was a comment */
+
+ /* Get the option */
+ if ((fnum = sscanf(linebuf, "%s %s", fopt, farg)) > 0)
+ {
+ if (!strcmp(fopt, "help"))
+ {
+ if (override || !args_info->help_given)
+ {
+ args_info->help_given = 1;
+
+ }
+ continue;
+ }
+ if (!strcmp(fopt, "version"))
+ {
+ if (override || !args_info->version_given)
+ {
+ args_info->version_given = 1;
+
+ }
+ continue;
+ }
+ if (!strcmp(fopt, "fg"))
+ {
+ if (override || !args_info->fg_given)
+ {
+ args_info->fg_given = 1;
+ args_info->fg_flag = !(args_info->fg_flag);
+ }
+ continue;
+ }
+ if (!strcmp(fopt, "debug"))
+ {
+ if (override || !args_info->debug_given)
+ {
+ args_info->debug_given = 1;
+ args_info->debug_flag = !(args_info->debug_flag);
+ }
+ continue;
+ }
+ if (!strcmp(fopt, "conf"))
+ {
+ if (override || !args_info->conf_given)
+ {
+ args_info->conf_given = 1;
+ if (fnum == 2)
+ args_info->conf_arg = strdup (farg);
+ else
+ {
+ fprintf (stderr, "%s:%d: required <option_name> <option_val>\n",
+ filename, line_num);
+ exit (EXIT_FAILURE);
+ }
+ }
+ continue;
+ }
+ if (!strcmp(fopt, "pidfile"))
+ {
+ if (override || !args_info->pidfile_given)
+ {
+ args_info->pidfile_given = 1;
+ if (fnum == 2)
+ args_info->pidfile_arg = strdup (farg);
+ else
+ {
+ fprintf (stderr, "%s:%d: required <option_name> <option_val>\n",
+ filename, line_num);
+ exit (EXIT_FAILURE);
+ }
+ }
+ continue;
+ }
+ if (!strcmp(fopt, "statedir"))
+ {
+ if (override || !args_info->statedir_given)
+ {
+ args_info->statedir_given = 1;
+ if (fnum == 2)
+ args_info->statedir_arg = strdup (farg);
+ else
+ {
+ fprintf (stderr, "%s:%d: required <option_name> <option_val>\n",
+ filename, line_num);
+ exit (EXIT_FAILURE);
+ }
+ }
+ continue;
+ }
+ if (!strcmp(fopt, "dns"))
+ {
+ if (override || !args_info->dns_given)
+ {
+ args_info->dns_given = 1;
+ if (fnum == 2)
+ args_info->dns_arg = strdup (farg);
+ else
+ {
+ fprintf (stderr, "%s:%d: required <option_name> <option_val>\n",
+ filename, line_num);
+ exit (EXIT_FAILURE);
+ }
+ }
+ continue;
+ }
+ if (!strcmp(fopt, "listen"))
+ {
+ if (override || !args_info->listen_given)
+ {
+ args_info->listen_given = 1;
+ if (fnum == 2)
+ args_info->listen_arg = strdup (farg);
+ else
+ {
+ fprintf (stderr, "%s:%d: required <option_name> <option_val>\n",
+ filename, line_num);
+ exit (EXIT_FAILURE);
+ }
+ }
+ continue;
+ }
+ if (!strcmp(fopt, "remote"))
+ {
+ if (override || !args_info->remote_given)
+ {
+ args_info->remote_given = 1;
+ if (fnum == 2)
+ args_info->remote_arg = strdup (farg);
+ else
+ {
+ fprintf (stderr, "%s:%d: required <option_name> <option_val>\n",
+ filename, line_num);
+ exit (EXIT_FAILURE);
+ }
+ }
+ continue;
+ }
+ if (!strcmp(fopt, "net"))
+ {
+ if (override || !args_info->net_given)
+ {
+ args_info->net_given = 1;
+ if (fnum == 2)
+ args_info->net_arg = strdup (farg);
+ else
+ {
+ fprintf (stderr, "%s:%d: required <option_name> <option_val>\n",
+ filename, line_num);
+ exit (EXIT_FAILURE);
+ }
+ }
+ continue;
+ }
+ if (!strcmp(fopt, "mask"))
+ {
+ if (override || !args_info->mask_given)
+ {
+ args_info->mask_given = 1;
+ if (fnum == 2)
+ args_info->mask_arg = strdup (farg);
+ else
+ {
+ fprintf (stderr, "%s:%d: required <option_name> <option_val>\n",
+ filename, line_num);
+ exit (EXIT_FAILURE);
+ }
+ }
+ continue;
+ }
+ if (!strcmp(fopt, "contexts"))
+ {
+ if (override || !args_info->contexts_given)
+ {
+ args_info->contexts_given = 1;
+ if (fnum == 2)
+ args_info->contexts_arg = strtol (farg,&stop_char,0);
+ else
+ {
+ fprintf (stderr, "%s:%d: required <option_name> <option_val>\n",
+ filename, line_num);
+ exit (EXIT_FAILURE);
+ }
+ }
+ continue;
+ }
+ if (!strcmp(fopt, "static"))
+ {
+ if (override || !args_info->static_given)
+ {
+ args_info->static_given = 1;
+ args_info->static_flag = !(args_info->static_flag);
+ }
+ continue;
+ }
+ if (!strcmp(fopt, "timelimit"))
+ {
+ if (override || !args_info->timelimit_given)
+ {
+ args_info->timelimit_given = 1;
+ if (fnum == 2)
+ args_info->timelimit_arg = strtol (farg,&stop_char,0);
+ else
+ {
+ fprintf (stderr, "%s:%d: required <option_name> <option_val>\n",
+ filename, line_num);
+ exit (EXIT_FAILURE);
+ }
+ }
+ continue;
+ }
+ if (!strcmp(fopt, "apn"))
+ {
+ if (override || !args_info->apn_given)
+ {
+ args_info->apn_given = 1;
+ if (fnum == 2)
+ args_info->apn_arg = strdup (farg);
+ else
+ {
+ fprintf (stderr, "%s:%d: required <option_name> <option_val>\n",
+ filename, line_num);
+ exit (EXIT_FAILURE);
+ }
+ }
+ continue;
+ }
+ if (!strcmp(fopt, "imsi"))
+ {
+ if (override || !args_info->imsi_given)
+ {
+ args_info->imsi_given = 1;
+ if (fnum == 2)
+ args_info->imsi_arg = strdup (farg);
+ else
+ {
+ fprintf (stderr, "%s:%d: required <option_name> <option_val>\n",
+ filename, line_num);
+ exit (EXIT_FAILURE);
+ }
+ }
+ continue;
+ }
+ if (!strcmp(fopt, "msisdn"))
+ {
+ if (override || !args_info->msisdn_given)
+ {
+ args_info->msisdn_given = 1;
+ if (fnum == 2)
+ args_info->msisdn_arg = strdup (farg);
+ else
+ {
+ fprintf (stderr, "%s:%d: required <option_name> <option_val>\n",
+ filename, line_num);
+ exit (EXIT_FAILURE);
+ }
+ }
+ continue;
+ }
+ if (!strcmp(fopt, "qos"))
+ {
+ if (override || !args_info->qos_given)
+ {
+ args_info->qos_given = 1;
+ if (fnum == 2)
+ args_info->qos_arg = strtol (farg,&stop_char,0);
+ else
+ {
+ fprintf (stderr, "%s:%d: required <option_name> <option_val>\n",
+ filename, line_num);
+ exit (EXIT_FAILURE);
+ }
+ }
+ continue;
+ }
+ if (!strcmp(fopt, "uid"))
+ {
+ if (override || !args_info->uid_given)
+ {
+ args_info->uid_given = 1;
+ if (fnum == 2)
+ args_info->uid_arg = strdup (farg);
+ else
+ {
+ fprintf (stderr, "%s:%d: required <option_name> <option_val>\n",
+ filename, line_num);
+ exit (EXIT_FAILURE);
+ }
+ }
+ continue;
+ }
+ if (!strcmp(fopt, "pwd"))
+ {
+ if (override || !args_info->pwd_given)
+ {
+ args_info->pwd_given = 1;
+ if (fnum == 2)
+ args_info->pwd_arg = strdup (farg);
+ else
+ {
+ fprintf (stderr, "%s:%d: required <option_name> <option_val>\n",
+ filename, line_num);
+ exit (EXIT_FAILURE);
+ }
+ }
+ continue;
+ }
+
+
+ /* Tried all known options. This one is unknown! */
+ fprintf (stderr, "%s: Unknown option '%s' found in %s\n",
+ PACKAGE, fopt, filename);
+ exit (EXIT_FAILURE);
+ }
+ } /* while */
+ fclose(file); /* No error checking on close */
+
+ return 0;
+}
diff --git a/sgsnemu/cmdline.ggo b/sgsnemu/cmdline.ggo
new file mode 100644
index 0000000..6b21818
--- /dev/null
+++ b/sgsnemu/cmdline.ggo
@@ -0,0 +1,37 @@
+# OpenGGSN - Gateway GPRS Support Node
+# Copyright (C) 2002 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.
+#
+# The initial developer of the original code is
+# Jens Jakobsen <jj@openggsn.org>
+#
+# Contributor(s):
+
+option "fg" f "Run in foreground" flag off
+option "debug" d "Run in debug mode" flag off
+
+option "conf" c "Read configuration file" string no
+option "pidfile" - "Filename of process id file" string default="./sgsnemu.pid" no
+option "statedir" - "Directory of nonvolatile data" string default="./" no
+
+option "dns" - "DNS Server to use" string no
+option "listen" l "Local interface" string no
+option "remote" r "Remote host" string no
+option "net" n "Network" string default="192.168.0.0" no
+option "mask" - "Network mask" string default="255.255.255.0" no
+
+option "contexts" - "Number of contexts" int default="1" no
+option "static" - "Allocate static tun ifterface" flag off
+option "timelimit" - "Exit after timelimit seconds" int default="0" no
+
+option "apn" a "Access point name" string default="internet" no
+option "imsi" i "IMSI" string default="240010123456789" no
+option "msisdn" m "Mobile Station ISDN number" string default="46702123456" no
+option "qos" q "Requested quality of service" int default="0x0b921f" no
+option "uid" u "Login user ID" string default="mig" no
+option "pwd" p "Login password" string default="hemmelig" no
+
diff --git a/sgsnemu/cmdline.h b/sgsnemu/cmdline.h
new file mode 100644
index 0000000..cd4ac6e
--- /dev/null
+++ b/sgsnemu/cmdline.h
@@ -0,0 +1,77 @@
+/* cmdline.h */
+
+/* File autogenerated by gengetopt version 2.8rc */
+
+#ifndef _cmdline_h
+#define _cmdline_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+/* Don't define PACKAGE and VERSION if we use automake. */
+#ifndef PACKAGE
+#define PACKAGE ""
+#endif
+
+#ifndef VERSION
+#define VERSION ""
+#endif
+
+struct gengetopt_args_info
+{
+ int fg_flag; /* Run in foreground (default=off). */
+ int debug_flag; /* Run in debug mode (default=off). */
+ char * conf_arg; /* Read configuration file. */
+ char * pidfile_arg; /* Filename of process id file (default='./sgsnemu.pid'). */
+ char * statedir_arg; /* Directory of nonvolatile data (default='./'). */
+ char * dns_arg; /* DNS Server to use. */
+ char * listen_arg; /* Local interface. */
+ char * remote_arg; /* Remote host. */
+ char * net_arg; /* Network (default='192.168.0.0'). */
+ char * mask_arg; /* Network mask (default='255.255.255.0'). */
+ int contexts_arg; /* Number of contexts (default='1'). */
+ int static_flag; /* Allocate static tun ifterface (default=off). */
+ int timelimit_arg; /* Exit after timelimit seconds (default='0'). */
+ char * apn_arg; /* Access point name (default='internet'). */
+ char * imsi_arg; /* IMSI (default='240010123456789'). */
+ char * msisdn_arg; /* Mobile Station ISDN number (default='46702123456'). */
+ int qos_arg; /* Requested quality of service (default='0x0b921f'). */
+ char * uid_arg; /* Login user ID (default='mig'). */
+ char * pwd_arg; /* Login password (default='hemmelig'). */
+
+ int help_given ; /* Whether help was given. */
+ int version_given ; /* Whether version was given. */
+ int fg_given ; /* Whether fg was given. */
+ int debug_given ; /* Whether debug was given. */
+ int conf_given ; /* Whether conf was given. */
+ int pidfile_given ; /* Whether pidfile was given. */
+ int statedir_given ; /* Whether statedir was given. */
+ int dns_given ; /* Whether dns was given. */
+ int listen_given ; /* Whether listen was given. */
+ int remote_given ; /* Whether remote was given. */
+ int net_given ; /* Whether net was given. */
+ int mask_given ; /* Whether mask was given. */
+ int contexts_given ; /* Whether contexts was given. */
+ int static_given ; /* Whether static was given. */
+ int timelimit_given ; /* Whether timelimit was given. */
+ int apn_given ; /* Whether apn was given. */
+ int imsi_given ; /* Whether imsi was given. */
+ int msisdn_given ; /* Whether msisdn was given. */
+ int qos_given ; /* Whether qos was given. */
+ int uid_given ; /* Whether uid was given. */
+ int pwd_given ; /* Whether pwd was given. */
+
+} ;
+
+int cmdline_parser (int argc, char * const *argv, struct gengetopt_args_info *args_info);
+
+void cmdline_parser_print_help(void);
+void cmdline_parser_print_version(void);
+
+int cmdline_parser_configfile (char * const filename, struct gengetopt_args_info *args_info, int override);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* _cmdline_h */
diff --git a/sgsnemu/ggsn_restart b/sgsnemu/ggsn_restart
new file mode 100644
index 0000000..82cced2
--- /dev/null
+++ b/sgsnemu/ggsn_restart
@@ -0,0 +1 @@
+51
diff --git a/sgsnemu/sgsnemu.c b/sgsnemu/sgsnemu.c
new file mode 100644
index 0000000..b25fe87
--- /dev/null
+++ b/sgsnemu/sgsnemu.c
@@ -0,0 +1,754 @@
+/*
+ * OpenGGSN - Gateway GPRS Support Node
+ * Copyright (C) 2002 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.
+ *
+ * The initial developer of the original code is
+ * Jens Jakobsen <jj@openggsn.org>
+ *
+ * Contributor(s):
+ *
+ */
+
+/*
+ * sgsnemu.c
+ *
+ */
+
+
+#ifdef __linux__
+#define _GNU_SOURCE 1 /* strdup() prototype, broken arpa/inet.h */
+#endif
+
+
+#include <syslog.h>
+#include <ctype.h>
+#include <netdb.h>
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+#include <net/if.h>
+#include <features.h>
+#include <errno.h>
+#include <asm/types.h>
+#include <sys/socket.h>
+#include <linux/netlink.h>
+#include <resolv.h>
+#include <time.h>
+
+#include "tun.h"
+#include "../gtp/pdp.h"
+#include "../gtp/gtp.h"
+#include "cmdline.h"
+
+/* State variable */
+/* 0: Idle */
+/* 1: Wait_connect */
+/* 2: Connected */
+/* 3: Wait_disconnect */
+int state = 0;
+
+int maxfd = 0; /* For select() */
+int tun_fd = -1; /* Network file descriptor */
+struct tun_t *tun; /* TUN instance */
+struct tun_t *tun1, *tun2; /* TUN instance for client */
+int tun_fd1 = -1; /* Network file descriptor */
+int tun_fd2 = -1; /* Network file descriptor */
+struct in_addr net, mask; /* Network interface */
+int stattun; /* Allocate static tun */
+
+int debug; /* Print debug messages */
+
+int encaps_printf(void *p, void *packet, unsigned len)
+{
+ int i;
+ printf("The packet looks like this:\n");
+ for( i=0; i<len; i++) {
+ printf("%02x ", (unsigned char)*(char *)(packet+i));
+ if (!((i+1)%16)) printf("\n");
+ };
+ printf("\n");
+}
+
+/* Used to write process ID to file. Assume someone else will delete */
+void log_pid(char *pidfile) {
+ FILE *file;
+ mode_t oldmask;
+
+ oldmask = umask(022);
+ file = fopen(pidfile, "w");
+ umask(oldmask);
+ if(!file)
+ return;
+ fprintf(file, "%d\n", getpid());
+ fclose(file);
+}
+
+
+int create_tun() {
+ char buf[1024];
+ char snet[100], smask[100];
+
+ if ((tun_fd = tun_newtun((struct tun_t**) &tun)) > maxfd)
+ maxfd = tun_fd;
+
+ if (tun_fd == -1) {
+ printf("Failed to open tun\n");
+ exit(1);
+ }
+
+ strncpy(snet, inet_ntoa(net), 100);
+ strncpy(smask, inet_ntoa(mask), 100);
+
+ sprintf(buf, "ifconfig %s %s mtu 1450 netmask %s",
+ tun->devname, snet, smask);
+ if (debug) printf("%s\n", buf);
+ system(buf);
+
+ system("echo 1 > /proc/sys/net/ipv4/ip_forward");
+
+ return 0;
+}
+
+int getip(struct pdp_t *pdp, void* ipif, struct ul66_t *eua,
+ struct in_addr *net, struct in_addr *mask) {
+ struct in_addr addr;
+ uint32_t ip_start, ip_end, ip_cur;
+ struct pdp_t *pdp_;
+ struct ul66_t eua_;
+
+ printf("Begin getip %d %d %2x%2x%2x%2x\n", (unsigned)ipif, eua->l,
+ eua->v[2],eua->v[3],eua->v[4],eua->v[5]);
+
+ ip_start = ntoh32(net->s_addr & mask->s_addr);
+ ip_end = ntoh32(hton32(ip_start) | ~mask->s_addr);
+
+ /* By convention the first address is the network address, and the last */
+ /* address is the broadcast address. This way two IP addresses are "lost" */
+ ip_start++;
+
+ if (eua->l == 0) { /* No address supplied. Find one that is available! */
+ /* This routine does linear search. In order to support millions of
+ * addresses we should instead keep a linked list of available adresses */
+ for (ip_cur = ip_start; ip_cur < ip_end; ip_cur++) {
+ addr.s_addr = hton32(ip_cur);
+ pdp_ntoeua(&addr, &eua_);
+ if (pdp_ipget(&pdp_, ipif, &eua_) == -1) {
+ pdp_ntoeua(&addr, &pdp->eua);
+ pdp->ipif = ipif;
+ return 0;
+ };
+ }
+ return EOF; /* No addresses available */
+ }
+ else { /* Address supplied */
+ if (pdp_ipget(&pdp_, ipif, eua) == -1) {
+ pdp->ipif = ipif;
+ pdp->eua.l = eua->l;
+ memcpy(pdp->eua.v, eua->v, eua->l);
+ return 0;
+ }
+ else return EOF; /* Specified address not available */
+ }
+}
+
+int delete_context(struct pdp_t *pdp) {
+
+ if (!stattun) {
+ tun_freetun((struct tun_t*) pdp->ipif);
+
+ /* Clean up locally */
+ if (pdp->ipif == tun1) {
+ printf("Deleting tun interface\n");
+ tun_fd1=-1;
+ }
+ if (pdp->ipif == tun2) {
+ printf("Deleting tun interface\n");
+ tun_fd2=-1;
+ }
+ }
+
+ pdp_ipdel(pdp);
+ return 0;
+}
+
+int create_pdp_conf(struct pdp_t *pdp, int cause) {
+ char buf[1024];
+
+ printf("Received create PDP context response. Cause value: %d\n", cause);
+ if ((cause == 128) && (pdp->eua.l == 6)) {
+
+
+ if (stattun) {
+ pdp->ipif = tun1;
+ }
+ else {
+ printf("Setting up interface and routing\n");
+ if ((tun_fd = tun_newtun((struct tun_t**) &pdp->ipif)) > maxfd)
+ maxfd = tun_fd;
+
+ /* HACK: Only support select of up to two tun interfaces */
+ if (NULL == tun1) {
+ tun1 = pdp->ipif;
+ tun_fd1 = tun1->fd;
+ }
+ else {
+ tun2 = pdp->ipif;
+ tun_fd2 = tun2->fd;
+ }
+
+ /*system("ifconfig tun0 192.168.0.10");*/
+ sprintf(buf, "ifconfig %s %hu.%hu.%hu.%hu",
+ ((struct tun_t*) pdp->ipif)->devname,
+ pdp->eua.v[2], pdp->eua.v[3], pdp->eua.v[4], pdp->eua.v[5]);
+ printf(buf); printf("\n");
+ system(buf);
+
+
+ /*system("route add -net 192.168.0.0 netmask 255.255.255.0 gw 192.168.0.10");*/
+ sprintf(buf, "route add -net %hu.%hu.%hu.0 netmask 255.255.255.0 gw %hu.%hu.%hu.%hu",
+ pdp->eua.v[2], pdp->eua.v[3], pdp->eua.v[4],
+ pdp->eua.v[2], pdp->eua.v[3], pdp->eua.v[4], pdp->eua.v[5]);
+ printf(buf); printf("\n");
+ system(buf);
+
+ system("echo 1 > /proc/sys/net/ipv4/ip_forward");
+ }
+
+ pdp_ipset(pdp, pdp->ipif, &pdp->eua);
+
+ state = 2; /* Connected */
+ }
+ else {
+ state = 0;
+ }
+
+ printf("\n");
+
+ return 0;
+}
+
+
+int create_pdp_ind(struct pdp_t *pdp) {
+
+ printf("Received create PDP context request\n");
+
+ pdp->eua.l=0; /* TODO: Indicates dynamic IP */
+
+ /* ulcpy(&pdp->qos_neg, &pdp->qos_req, sizeof(pdp->qos_req.v)); */
+ memcpy(pdp->qos_neg0, pdp->qos_req0, sizeof(pdp->qos_neg));
+
+ getip(pdp, &tun, &pdp->eua, &net, &mask);
+ pdp_ipset(pdp, pdp->ipif, &pdp->eua);
+
+ return 0; /* Success */
+}
+
+
+int delete_pdp_conf(struct pdp_t *pdp, int cause) {
+ printf("Received delete PDP context response. Cause value: %d\n", cause);
+ return 0;
+}
+
+int echo_conf(struct pdp_t *pdp, int cause) {
+ printf("Received echo response. Cause value: %d\n", cause);
+ return 0;
+}
+
+int conf(int type, int cause, struct pdp_t* pdp, void *aid) {
+ /* if (cause < 0) return 0; Some error occurred. We don't care */
+ switch (type) {
+ case GTP_ECHO_REQ:
+ return echo_conf(pdp, cause);
+ case GTP_CREATE_PDP_REQ:
+ if (cause !=128) return 0; /* Request not accepted. We don't care */
+ return create_pdp_conf(pdp, cause);
+ case GTP_DELETE_PDP_REQ:
+ if (cause !=128) return 0; /* Request not accepted. We don't care */
+ return delete_pdp_conf(pdp, cause);
+ default:
+ return 0;
+ }
+}
+
+int encaps_gtp_client(void *gsn, struct tun_t *tun, void *pack, unsigned len) {
+ /* Special client version which checks for source address instead */
+ struct pdp_t *pdp;
+ struct in_addr addr;
+ struct ul66_t eua;
+ /*printf("encaps_gtp. Packet received: forwarding to gtp.\n");*/
+ /* First we need to extract the IP destination address */
+ memcpy(&addr.s_addr, pack+12, 4); /* This ought to be dest addr */
+ pdp_ntoeua(&addr, &eua);
+ if (pdp_ipget(&pdp, tun, &eua) == 0) {
+ return gtp_gpdu((struct gsn_t*) gsn, pdp, pack, len);
+ }
+ else {
+ printf("Received packet with no destination!!!\n");
+ return 0;
+ }
+}
+
+int encaps_tun(struct pdp_t *pdp, void *pack, unsigned len) {
+ /* printf("encaps_tun. Packet received: forwarding to tun\n");*/
+ return tun_encaps((struct tun_t*) pdp->ipif, pack, len);
+}
+
+int main(int argc, char **argv)
+{
+ /* gengeopt declarations */
+ struct gengetopt_args_info args_info;
+
+ /* function-local options */
+
+ struct hostent *host;
+
+ struct in_addr listen, remote;
+ struct in_addr dns;
+
+ int gtpfd = -1; /* Network file descriptor */
+ struct gsn_t *gsn; /* GSN instance */
+
+ fd_set fds; /* For select() */
+ struct timeval idleTime; /* How long to select() */
+
+ struct pdp_t *pdp[2];
+
+ int n; /* For counter */
+
+ int contexts; /* Number of contexts to create */
+ int timelimit; /* Number of seconds to be connected */
+ int starttime; /* Time program was started */
+
+ struct ul_t imsi, qos, apn, msisdn;
+ unsigned char qosh[3], imsih[8], apnh[256], msisdnh[256];
+ struct ul255_t pco;
+ uint64_t imsi3;
+
+ /* open a connection to the syslog daemon */
+ /*openlog(PACKAGE, LOG_PID, LOG_DAEMON);*/
+ openlog(PACKAGE, (LOG_PID | LOG_PERROR), LOG_DAEMON);
+
+ if (cmdline_parser (argc, argv, &args_info) != 0)
+ exit(1);
+ if (args_info.debug_flag) {
+ printf("remote: %s\n", args_info.remote_arg);
+ printf("listen: %s\n", args_info.listen_arg);
+ printf("conf: %s\n", args_info.conf_arg);
+ printf("fg: %d\n", args_info.fg_flag);
+ printf("debug: %d\n", args_info.debug_flag);
+ printf("imsi: %s\n", args_info.imsi_arg);
+ printf("qos: %#08x\n", args_info.qos_arg);
+ printf("apn: %s\n", args_info.apn_arg);
+ printf("msisdn: %s\n", args_info.msisdn_arg);
+ printf("uid: %s\n", args_info.uid_arg);
+ printf("pwd: %s\n", args_info.pwd_arg);
+ printf("static: %d\n", args_info.static_flag);
+ printf("net: %s\n", args_info.net_arg);
+ printf("mask: %s\n", args_info.mask_arg);
+ printf("pidfile: %s\n", args_info.pidfile_arg);
+ printf("statedir: %s\n", args_info.statedir_arg);
+ printf("dns: %s\n", args_info.dns_arg);
+ printf("contexts: %d\n", args_info.contexts_arg);
+ printf("timelimit: %d\n", args_info.timelimit_arg);
+ }
+
+ /* Try out our new parser */
+
+ if (args_info.conf_arg) {
+ if (cmdline_parser_configfile (args_info.conf_arg, &args_info, 0) != 0)
+ exit(1);
+ if (args_info.debug_flag) {
+ printf("cmdline_parser_configfile\n");
+ printf("remote: %s\n", args_info.remote_arg);
+ printf("listen: %s\n", args_info.listen_arg);
+ printf("conf: %s\n", args_info.conf_arg);
+ printf("fg: %d\n", args_info.fg_flag);
+ printf("debug: %d\n", args_info.debug_flag);
+ printf("imsi: %s\n", args_info.imsi_arg);
+ printf("qos: %#08x\n", args_info.qos_arg);
+ printf("apn: %s\n", args_info.apn_arg);
+ printf("msisdn: %s\n", args_info.msisdn_arg);
+ printf("uid: %s\n", args_info.uid_arg);
+ printf("pwd: %s\n", args_info.pwd_arg);
+ printf("static: %d\n", args_info.static_flag);
+ printf("net: %s\n", args_info.net_arg);
+ printf("mask: %s\n", args_info.mask_arg);
+ printf("pidfile: %s\n", args_info.pidfile_arg);
+ printf("statedir: %s\n", args_info.statedir_arg);
+ printf("dns: %s\n", args_info.dns_arg);
+ printf("contexts: %d\n", args_info.contexts_arg);
+ printf("timelimit: %d\n", args_info.timelimit_arg);
+ }
+ }
+
+ /* Handle each option */
+
+ /* foreground */
+ /* If flag not given run as a daemon */
+ if (!args_info.fg_flag)
+ {
+ closelog();
+ /* Close the standard file descriptors. Why? */
+ freopen("/dev/null", "w", stdout);
+ freopen("/dev/null", "w", stderr);
+ freopen("/dev/null", "r", stdin);
+ daemon(0, 0);
+ /* Open log again. This time with new pid */
+ openlog(PACKAGE, LOG_PID, LOG_DAEMON);
+ }
+
+ /* debug */
+ debug = args_info.debug_flag;
+
+ /* pidfile */
+ /* This has to be done after we have our final pid */
+ if (args_info.pidfile_arg) {
+ log_pid(args_info.pidfile_arg);
+ }
+
+ /* dns */
+ /* If no dns option is given use system default */
+ /* Do hostname lookup to translate hostname to IP address */
+ printf("\n");
+ if (args_info.dns_arg) {
+ if (!(host = gethostbyname(args_info.dns_arg))) {
+ fprintf(stderr, "%s: Invalid dns address: %s!\n",
+ PACKAGE, args_info.dns_arg);
+ syslog(LOG_ERR, "Invalid dns address: %s!",
+ args_info.dns_arg);
+ exit(1);
+ }
+ else {
+ memcpy(&dns.s_addr, host->h_addr, host->h_length);
+ _res.nscount = 1;
+ _res.nsaddr_list[0].sin_addr = dns;
+ printf("Using DNS server: %s (%s)\n", args_info.dns_arg, inet_ntoa(dns));
+ }
+ }
+ else {
+ dns.s_addr= 0;
+ printf("Using default DNS server\n");
+ }
+
+ /* listen */
+ /* If no listen option is specified listen to any local port */
+ /* Do hostname lookup to translate hostname to IP address */
+ if (args_info.listen_arg) {
+ if (!(host = gethostbyname(args_info.listen_arg))) {
+ fprintf(stderr, "%s: Invalid listening address: %s!\n",
+ PACKAGE, args_info.listen_arg);
+ syslog(LOG_ERR, "Invalid listening address: %s!",
+ args_info.listen_arg);
+ exit(1);
+ }
+ else {
+ memcpy(&listen.s_addr, host->h_addr, host->h_length);
+ printf("Local IP address is: %s (%s)\n", args_info.listen_arg, inet_ntoa(listen));
+ }
+ }
+ else {
+ fprintf(stderr, "%s: Listening address must be specified: %s!\n",
+ PACKAGE, args_info.listen_arg);
+ syslog(LOG_ERR, "Listening address must be specified: %s!",
+ args_info.listen_arg);
+ exit(1);
+ }
+
+
+ /* remote */
+ /* If no remote option is specified terminate */
+ /* Do hostname lookup to translate hostname to IP address */
+ if (args_info.remote_arg) {
+ if (!(host = gethostbyname(args_info.remote_arg))) {
+ fprintf(stderr, "%s: Invalid remote address: %s!\n",
+ PACKAGE, args_info.remote_arg);
+ syslog(LOG_ERR, "Invalid remote address: %s!",
+ args_info.remote_arg);
+ exit(1);
+ }
+ else {
+ memcpy(&remote.s_addr, host->h_addr, host->h_length);
+ printf("Remote IP address is: %s (%s)\n", args_info.remote_arg, inet_ntoa(remote));
+ }
+ }
+ else {
+ fprintf(stderr, "%s: No remote address given!\n",
+ PACKAGE);
+ syslog(LOG_ERR, "No remote address given!");
+ exit(1);
+ }
+
+
+ /* net */
+ /* Store net as in_addr */
+ if (args_info.net_arg) {
+ if (!inet_aton(args_info.net_arg, &net)) {
+ fprintf(stderr, "%s: Invalid network address: %s!\n",
+ PACKAGE, args_info.net_arg);
+ syslog(LOG_ERR, "Invalid network address: %s!",
+ args_info.net_arg);
+ exit(1);
+ }
+ }
+
+ /* mask */
+ /* Store mask as in_addr */
+ if (args_info.mask_arg) {
+ if (!inet_aton(args_info.mask_arg, &mask)) {
+ fprintf(stderr, "%s: Invalid network mask: %s!\n",
+ PACKAGE, args_info.mask_arg);
+ syslog(LOG_ERR, "Invalid network mask: %s!",
+ args_info.mask_arg);
+ exit(1);
+ }
+ }
+
+ /* imsi */
+ if (strlen(args_info.imsi_arg)!=15) {
+ printf("Invalid IMSI\n");
+ exit(1);
+ }
+ imsi.l = 8;
+ imsi.v = imsih;
+ imsi.v[0] = args_info.imsi_arg[0]-48 + (args_info.imsi_arg[1]-48)*16;
+ imsi.v[1] = args_info.imsi_arg[2]-48 + (args_info.imsi_arg[3]-48)*16;
+ imsi.v[2] = args_info.imsi_arg[4]-48 + (args_info.imsi_arg[5]-48)*16;
+ imsi.v[3] = args_info.imsi_arg[6]-48 + (args_info.imsi_arg[7]-48)*16;
+ imsi.v[4] = args_info.imsi_arg[8]-48 + (args_info.imsi_arg[9]-48)*16;
+ imsi.v[5] = args_info.imsi_arg[10]-48 + (args_info.imsi_arg[11]-48)*16;
+ imsi.v[6] = args_info.imsi_arg[12]-48 + (args_info.imsi_arg[13]-48)*16;
+ imsi.v[7] = args_info.imsi_arg[14]-48 + 0*16;
+
+ if (imsi.l > sizeof(imsi3)) {
+ printf("Invalid IMSI\n");
+ exit(1);
+ }
+ else {
+ memcpy(&imsi3, imsi.v, imsi.l);
+ printf("IMSI is: %s (%#08llx)\n", args_info.imsi_arg, imsi3);
+ }
+
+ /* qos */
+ qos.l = 3;
+ qos.v = qosh;
+ qos.v[2] = (args_info.qos_arg) & 0xff;
+ qos.v[1] = ((args_info.qos_arg) >> 8) & 0xff;
+ qos.v[0] = ((args_info.qos_arg) >> 16) & 0xff;
+
+ /* contexts */
+ contexts = args_info.contexts_arg;
+
+ /* Timelimit */
+ timelimit = args_info.timelimit_arg;
+ starttime = time(NULL);
+
+ /* apn */
+ if (strlen(args_info.apn_arg)>255) {
+ printf("Invalid APN\n");
+ exit(1);
+ }
+ apn.l = strlen(args_info.apn_arg) + 1;
+ apn.v = apnh;
+ apn.v[0] = (char) strlen(args_info.apn_arg);
+ strncpy(&apn.v[1], args_info.apn_arg, 255);
+ printf("Using APN: %s\n", args_info.apn_arg);
+
+ /* msisdn */
+ if (strlen(args_info.msisdn_arg)>255) {
+ printf("Invalid MSISDN\n");
+ exit(1);
+ }
+ msisdn.l = 1;
+ msisdn.v = msisdnh;
+ msisdn.v[0] = 0x91; /* International format */
+ for(n=0; n<strlen(args_info.msisdn_arg); n++) {
+ if ((n%2) == 0) {
+ msisdn.v[((int)n/2)+1] = args_info.msisdn_arg[n] - 48 + 0xf0;
+ msisdn.l += 1;
+ }
+ else {
+ msisdn.v[((int)n/2)+1] = (msisdn.v[((int)n/2)+1] & 0x0f) + (args_info.msisdn_arg[n] - 48) * 16;
+ }
+ }
+ printf("Using MSISDN: %s\n", args_info.msisdn_arg);
+
+ /* UID and PWD */
+ /* Might need to also insert stuff like DNS etc. */
+ if ((strlen(args_info.uid_arg) + strlen(args_info.pwd_arg) + 10)>255) {
+ printf("invalid UID and PWD\n");
+ exit(1);
+ }
+ pco.l = strlen(args_info.uid_arg) + strlen(args_info.pwd_arg) + 10;
+ pco.v[0] = 0x80; /* PPP */
+ pco.v[1] = 0xc0;
+ pco.v[2] = 0x23; /* PAP */
+ pco.v[3] = 0x12;
+ pco.v[4] = 0x01; /* Authenticate request */
+ pco.v[5] = 0x01;
+ pco.v[6] = 0x00; /* MSB of length */
+ pco.v[7] = strlen(args_info.uid_arg) + strlen(args_info.pwd_arg) + 6;
+ pco.v[8] = strlen(args_info.uid_arg);
+ memcpy(&pco.v[9], args_info.uid_arg, strlen(args_info.uid_arg));
+ pco.v[9+strlen(args_info.uid_arg)] = strlen(args_info.pwd_arg);
+ memcpy(&pco.v[10+strlen(args_info.uid_arg)], args_info.pwd_arg, strlen(args_info.pwd_arg));
+
+ /* static */
+ stattun = args_info.static_flag;
+
+ printf("\nInitialising GTP library\n");
+ if ((gtpfd = gtp_new(&gsn, args_info.statedir_arg, &listen)) > maxfd)
+ maxfd = gtpfd;
+
+ if ((gtpfd = gtp_fd(gsn)) > maxfd)
+ maxfd = gtpfd;
+
+ gtp_set_cb_gpdu(gsn, encaps_tun);
+ gtp_set_cb_delete_context(gsn, delete_context);
+
+ gtp_set_cb_conf(gsn, conf);
+ printf("Done initialising GTP library\n\n");
+
+ if (stattun) {
+ create_tun();
+ tun1 = tun;
+ tun_fd1 = tun1->fd;
+ }
+
+ /* See if anybody is there */
+ printf("Sending off echo request\n");
+ if (gtpfd != -1) gtp_echo_req(gsn, &remote); /* See if remote is alive ? */
+
+ for(n=0; n<contexts; n++) {
+ printf("Setting up PDP context #%d\n", n);
+
+ pdp_newpdp(&pdp[n], imsi3, n, NULL); /* Allocated here. Cleaned up in gtp.c: TODO Should be statically allocated! */
+
+ /*
+ if (qos.l > sizeof(pdp[n]->qos_req.v)) {
+ exit(1);
+ }
+ else {
+ pdp[n]->qos_req.l = qos.l;
+ memcpy(pdp[n]->qos_req.v, qos.v, qos.l);
+ }
+ */
+ memcpy(pdp[n]->qos_req0, qos.v, qos.l); /* TODO range check */
+
+ pdp[n]->selmode = 0x01; /* MS provided APN, subscription not verified */
+
+ if (apn.l > sizeof(pdp[n]->apn_use.v)) {
+ exit(1);
+ }
+ else {
+ pdp[n]->apn_use.l = apn.l;
+ memcpy(pdp[n]->apn_use.v, apn.v, apn.l);
+ }
+
+ pdp[n]->gsnlc.l = 4;
+ memcpy(pdp[n]->gsnlc.v, &listen, 4);
+ pdp[n]->gsnlu.l = 4;
+ memcpy(pdp[n]->gsnlu.v, &listen, 4);
+
+ if (msisdn.l > sizeof(pdp[n]->msisdn.v)) {
+ exit(1);
+ }
+ else {
+ pdp[n]->msisdn.l = msisdn.l;
+ memcpy(pdp[n]->msisdn.v, msisdn.v, msisdn.l);
+ }
+
+ ipv42eua(&pdp[n]->eua, NULL); /* Request dynamic IP address */
+
+ if (pco.l > sizeof(pdp[n]->pco_req.v)) {
+ exit(1);
+ }
+ else {
+ pdp[n]->pco_req.l = pco.l;
+ memcpy(pdp[n]->pco_req.v, pco.v, pco.l);
+ }
+
+ /* Create context */
+ /* We send this of once. Retransmissions are handled by gtplib */
+ if (gtpfd != -1) gtp_create_context(gsn, pdp[n], NULL, &remote);
+ }
+
+ state = 1; /* Enter wait_connection state */
+
+ printf("Waiting for response from ggsn........\n\n");
+
+
+ /******************************************************************/
+ /* Main select loop */
+ /******************************************************************/
+
+ while (((starttime + timelimit + 10) > time(NULL)) || (0 == timelimit)) {
+
+ /* Take down client connections at some stage */
+ if (((starttime + timelimit) <= time(NULL)) && (0 != timelimit) && (2 == state)) {
+ state = 3;
+ for(n=0; n<contexts; n++) {
+ /* Delete context */
+ printf("Disconnecting PDP context #%d\n", n);
+ if (gtpfd != -1) gtp_delete_context(gsn, pdp[n], NULL);
+ }
+ }
+
+ FD_ZERO(&fds);
+ if (tun_fd1 != -1) FD_SET(tun_fd1, &fds);
+ if (tun_fd2 != -1) FD_SET(tun_fd2, &fds);
+ if (gtpfd != -1) FD_SET(gtpfd, &fds);
+
+ gtp_retranstimeout(gsn, &idleTime);
+
+ switch (select(maxfd + 1, &fds, NULL, NULL, &idleTime)) {
+ case -1:
+ syslog(LOG_ERR, "sgsnemu: select = -1");
+ break;
+ case 0:
+ gtp_retrans(gsn); /* Only retransmit if nothing else */
+ break;
+ default:
+ break;
+ }
+
+ if (tun_fd1 != -1 &&
+ FD_ISSET(tun_fd1, &fds) &&
+ tun_decaps(tun1, encaps_gtp_client, gsn) < 0) {
+ syslog(LOG_ERR, "TUN read failed (fd)=(%d)", tun_fd1);
+ }
+
+ if (tun_fd2 != -1 &&
+ FD_ISSET(tun_fd2, &fds) &&
+ tun_decaps(tun2, encaps_gtp_client, gsn) < 0) {
+ syslog(LOG_ERR, "TUN read failed (fd)=(%d)", tun_fd2);
+ }
+
+ if (gtpfd != -1 && FD_ISSET(gtpfd, &fds) &&
+ gtp_decaps(gsn) < 0) {
+ syslog(LOG_ERR, "GTP read failed (gre)=(%d)", gtpfd);
+ }
+
+
+ }
+
+ gtp_free(gsn); /* Clean up the gsn instance */
+
+ return 1;
+
+}
+
diff --git a/sgsnemu/sgsnemu.pid b/sgsnemu/sgsnemu.pid
new file mode 100644
index 0000000..6673415
--- /dev/null
+++ b/sgsnemu/sgsnemu.pid
@@ -0,0 +1 @@
+14305
diff --git a/sgsnemu/tun.c b/sgsnemu/tun.c
new file mode 100644
index 0000000..72ea264
--- /dev/null
+++ b/sgsnemu/tun.c
@@ -0,0 +1,128 @@
+/*
+ * OpenGGSN - Gateway GPRS Support Node
+ * Copyright (C) 2002 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.
+ *
+ * The initial developer of the original code is
+ * Jens Jakobsen <jj@openggsn.org>
+ *
+ * Contributor(s):
+ *
+ */
+
+/*
+ * tun.c: Contains all TUN functionality. Should be able to handle multiple
+ * tunnels in the same program. Each tunnel is identified by the socket.
+ * I suppose that no other state information than the socket is needed.
+ *
+ * - tun_newtun: Initialise TUN tunnel.
+ * - tun_freetun: Free a device previously created with tun_newtun.
+ * - tun_encaps: Encapsulate packet in TUN tunnel and send off
+ * - tun_decaps: Extract packet from TUN tunnel and call function to
+ * ship it off as GTP encapsulated packet.
+ *
+ * TODO:
+ * - Do we need to handle fragmentation?
+ */
+
+
+#include <syslog.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include <stdio.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <linux/if.h>
+#include <errno.h>
+#include <linux/if_tun.h>
+
+
+#include "tun.h"
+
+
+int tun_newtun(struct tun_t **tun)
+{
+ struct ifreq ifr;
+
+ if (!(*tun = calloc(1, sizeof(struct tun_t)))) {
+ syslog(LOG_ERR, "%s %d. calloc(nmemb=%d, size=%d) failed: Error = %s(%d)",
+ __FILE__, __LINE__, 1, sizeof(struct tun_t),
+ strerror(errno), errno);
+ return EOF;
+ }
+
+ if (((*tun)->fd = open("/dev/net/tun", O_RDWR)) < 0) {
+ syslog(LOG_ERR, "TUN: open() failed");
+ return -1;
+ }
+
+ memset(&ifr, 0, sizeof(ifr));
+ ifr.ifr_flags = IFF_TUN | IFF_NO_PI; /* Tun device, no packet info */
+ strncpy(ifr.ifr_name, (*tun)->devname, IFNAMSIZ);
+
+ if (ioctl((*tun)->fd, TUNSETIFF, (void *) &ifr) < 0) {
+ syslog(LOG_ERR, "TUN: ioctl() failed");
+ close((*tun)->fd);
+ return -1;
+ }
+
+ ioctl((*tun)->fd, TUNSETNOCSUM, 1); /* Disable checksums */
+
+ strncpy((*tun)->devname, ifr.ifr_name, IFNAMSIZ);
+
+ return (*tun)->fd;
+}
+
+int tun_freetun(struct tun_t *tun)
+{
+ if (close(tun->fd)) {
+ syslog(LOG_ERR, "%s %d. close(fd=%d) failed: Error = %s",
+ __FILE__, __LINE__, tun->fd, strerror(errno));
+ return EOF;
+ }
+ free(tun);
+ return 0;
+}
+
+
+int tun_decaps(struct tun_t *tun,
+ int (*cb) (void *cl, struct tun_t*, void *pack, unsigned len),
+ void *cl)
+{
+ unsigned char buffer[PACKET_MAX + 64 /*TODO: ip header */ ];
+ int status;
+
+
+ if ((status = read(tun->fd, buffer, sizeof(buffer))) <= 0) {
+ syslog(LOG_ERR, "TUN: read(fd=%d,buffer=%lx,len=%d) from network failed: status = %d error = %s",
+ tun->fd, (unsigned long) buffer, sizeof(buffer), status, status ? strerror(errno) : "No error");
+ return -1;
+ }
+
+ /* Need to include code to verify packet src and dest addresses */
+ return cb(cl, tun, buffer, status);
+}
+
+int tun_encaps(struct tun_t *tun, void *pack, unsigned len)
+{
+ return write(tun->fd, pack, len);
+}
diff --git a/sgsnemu/tun.h b/sgsnemu/tun.h
new file mode 100644
index 0000000..03dc7df
--- /dev/null
+++ b/sgsnemu/tun.h
@@ -0,0 +1,48 @@
+/*
+ * OpenGGSN - Gateway GPRS Support Node
+ * Copyright (C) 2002 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.
+ *
+ * The initial developer of the original code is
+ * Jens Jakobsen <jj@openggsn.org>
+ *
+ * Contributor(s):
+ *
+ */
+
+#ifndef _TUN_H
+#define _TUN_H
+
+#define hton8(x) (x)
+#define ntoh8(x) (x)
+#define hton16(x) htons(x)
+#define ntoh16(x) ntohs(x)
+#define hton32(x) htonl(x)
+#define ntoh32(x) ntohl(x)
+
+#define PACKET_MAX 8196 /* TODO */
+
+/* ***********************************************************
+ * Information storage for each tun instance
+ *************************************************************/
+
+struct tun_t {
+ int fd; /* File descriptor to network interface */
+ struct in_addr addr; /* IP address of tun interface */
+ char devname[IFNAMSIZ];/* Name of the tun device */
+};
+
+
+extern int tun_newtun(struct tun_t **tun);
+extern int tun_freetun(struct tun_t *tun);
+extern int tun_decaps(struct tun_t *tun,
+ int (*cb) (void *cl, struct tun_t*, void *pack, unsigned len),
+ void *cl);
+extern int tun_encaps(struct tun_t *tun, void *pack, unsigned len);
+
+
+#endif /* !_TUN_H */
diff --git a/src/Makefile b/src/Makefile
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/Makefile
diff --git a/tests/Makefile b/tests/Makefile
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/Makefile
diff --git a/tests/Makefile.in b/tests/Makefile.in
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/Makefile.in
diff --git a/version b/version
new file mode 100755
index 0000000..61a783f
--- /dev/null
+++ b/version
@@ -0,0 +1,24 @@
+#!/bin/sh
+#
+# Little shell script to grab current version number from configure.in
+#
+# $Id: version,v 1.1 2002/12/16 13:33:52 jjako Exp $
+
+VER=`grep AM_INIT_AUTOMAKE configure.in | awk -F'[(),]' '{print $3}'`
+if [ "$1" == "-VERSION" ]
+then
+ echo $VER | awk -F'.' '{print $1}'
+ exit
+fi
+if [ "$1" == "-PATCHLEVEL" ]
+then
+ echo $VER | awk -F'.' '{print $2}'
+ exit
+fi
+if [ "$1" == "-SUBLEVEL" ]
+then
+ echo $VER | awk -F'.' '{print $3}'
+ exit
+fi
+echo $VER
+exit