From 52c2414f6cabefb0427475756e8ac4856180bc59 Mon Sep 17 00:00:00 2001 From: jjako Date: Mon, 16 Dec 2002 13:33:51 +0000 Subject: [PATCH] Initial revision --- AUTHORS | 0 COPYING | 339 +++ ChangeLog | 0 Makefile | 330 +++ Makefile.am | 2 + Makefile.in | 330 +++ NEWS | 0 README | 144 ++ aclocal.m4 | 522 +++++ config.cache | 48 + config.h.in | 65 + config.log | 84 + config.status | 182 ++ configure | 2625 ++++++++++++++++++++++ configure.in | 32 + configure.scan | 27 + doc/Makefile | 0 examples/ggsn.conf | 69 + examples/sgsnemu.conf | 102 + ggsn/.deps/cmdline.P | 33 + ggsn/.deps/ggsn.P | 146 ++ ggsn/.deps/ggsnopt.P | 33 + ggsn/.deps/tun.P | 108 + ggsn/Makefile | 343 +++ ggsn/Makefile.am | 11 + ggsn/Makefile.in | 343 +++ ggsn/cmdline.c | 529 +++++ ggsn/cmdline.ggo | 29 + ggsn/cmdline.h | 61 + ggsn/ggsn.c | 424 ++++ ggsn/tun.c | 128 ++ ggsn/tun.h | 48 + gtp/.deps/gtp.P | 111 + gtp/.deps/gtpie.P | 52 + gtp/.deps/lookupa.P | 3 + gtp/.deps/pdp.P | 53 + gtp/.deps/queue.P | 64 + gtp/Makefile | 339 +++ gtp/Makefile.am | 9 + gtp/Makefile.in | 339 +++ gtp/gtp.c | 1917 ++++++++++++++++ gtp/gtp.h | 339 +++ gtp/gtpie.c | 513 +++++ gtp/gtpie.h | 279 +++ gtp/lookupa.c | 246 +++ gtp/lookupa.h | 29 + gtp/pdp.c | 320 +++ gtp/pdp.h | 203 ++ gtp/queue.c | 249 +++ gtp/queue.h | 77 + intl/Makefile | 0 intl/Makefile.in | 0 libtool | 4288 ++++++++++++++++++++++++++++++++++++ po/Makefile | 0 sgsnemu/.deps/cmdline.P | 33 + sgsnemu/.deps/pptpstuff.P | 107 + sgsnemu/.deps/sgsnemu.P | 157 ++ sgsnemu/.deps/sgsnemuopt.P | 33 + sgsnemu/.deps/tun.P | 108 + sgsnemu/Makefile | 343 +++ sgsnemu/Makefile.am | 11 + sgsnemu/Makefile.in | 343 +++ sgsnemu/cmdline.c | 776 +++++++ sgsnemu/cmdline.ggo | 37 + sgsnemu/cmdline.h | 77 + sgsnemu/ggsn_restart | 1 + sgsnemu/sgsnemu.c | 754 +++++++ sgsnemu/sgsnemu.pid | 1 + sgsnemu/tun.c | 128 ++ sgsnemu/tun.h | 48 + src/Makefile | 0 tests/Makefile | 0 tests/Makefile.in | 0 version | 24 + 74 files changed, 19548 insertions(+) create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 ChangeLog create mode 100644 Makefile create mode 100644 Makefile.am create mode 100644 Makefile.in create mode 100644 NEWS create mode 100644 README create mode 100644 aclocal.m4 create mode 100644 config.cache create mode 100644 config.h.in create mode 100644 config.log create mode 100755 config.status create mode 100755 configure create mode 100644 configure.in create mode 100644 configure.scan create mode 100644 doc/Makefile create mode 100644 examples/ggsn.conf create mode 100644 examples/sgsnemu.conf create mode 100644 ggsn/.deps/cmdline.P create mode 100644 ggsn/.deps/ggsn.P create mode 100644 ggsn/.deps/ggsnopt.P create mode 100644 ggsn/.deps/tun.P create mode 100644 ggsn/Makefile create mode 100644 ggsn/Makefile.am create mode 100644 ggsn/Makefile.in create mode 100644 ggsn/cmdline.c create mode 100644 ggsn/cmdline.ggo create mode 100644 ggsn/cmdline.h create mode 100644 ggsn/ggsn.c create mode 100644 ggsn/tun.c create mode 100644 ggsn/tun.h create mode 100644 gtp/.deps/gtp.P create mode 100644 gtp/.deps/gtpie.P create mode 100644 gtp/.deps/lookupa.P create mode 100644 gtp/.deps/pdp.P create mode 100644 gtp/.deps/queue.P create mode 100644 gtp/Makefile create mode 100644 gtp/Makefile.am create mode 100644 gtp/Makefile.in create mode 100644 gtp/gtp.c create mode 100644 gtp/gtp.h create mode 100644 gtp/gtpie.c create mode 100644 gtp/gtpie.h create mode 100644 gtp/lookupa.c create mode 100644 gtp/lookupa.h create mode 100644 gtp/pdp.c create mode 100644 gtp/pdp.h create mode 100644 gtp/queue.c create mode 100644 gtp/queue.h create mode 100644 intl/Makefile create mode 100644 intl/Makefile.in create mode 100755 libtool create mode 100644 po/Makefile create mode 100644 sgsnemu/.deps/cmdline.P create mode 100644 sgsnemu/.deps/pptpstuff.P create mode 100644 sgsnemu/.deps/sgsnemu.P create mode 100644 sgsnemu/.deps/sgsnemuopt.P create mode 100644 sgsnemu/.deps/tun.P create mode 100644 sgsnemu/Makefile create mode 100644 sgsnemu/Makefile.am create mode 100644 sgsnemu/Makefile.in create mode 100644 sgsnemu/cmdline.c create mode 100644 sgsnemu/cmdline.ggo create mode 100644 sgsnemu/cmdline.h create mode 100644 sgsnemu/ggsn_restart create mode 100644 sgsnemu/sgsnemu.c create mode 100644 sgsnemu/sgsnemu.pid create mode 100644 sgsnemu/tun.c create mode 100644 sgsnemu/tun.h create mode 100644 src/Makefile create mode 100644 tests/Makefile create mode 100644 tests/Makefile.in create mode 100755 version diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..e69de29 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. + + + Copyright (C) 19yy + + 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. + + , 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 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 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 &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 that is POSIX.1 compatible. */ +#undef HAVE_SYS_WAIT_H + +/* Define if you have . */ +#undef HAVE_VFORK_H + +/* Define to `int' if doesn't define. */ +#undef pid_t + +/* Define to `unsigned' if 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 and . */ +#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 header file. */ +#undef HAVE_FCNTL_H + +/* Define if you have the header file. */ +#undef HAVE_STRINGS_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_IOCTL_H + +/* Define if you have the header file. */ +#undef HAVE_SYS_TIME_H + +/* Define if you have the header file. */ +#undef HAVE_SYSLOG_H + +/* Define if you have the 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 <&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 &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 <&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 < +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 < +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 < +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 < +#include +#include +#include +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 +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 +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 < +#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 < +#include +#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 +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 <&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 <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 < +#if STDC_HEADERS +#include +#include +#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 < +#include +#include +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 < +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 < +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 < +#if STDC_HEADERS +#include +#include +#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 +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 < +/* 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 < +#include +#include +#ifdef HAVE_UNISTD_H +#include +#endif +#ifdef HAVE_VFORK_H +#include +#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 , + but some compilers (e.g. gcc -O) don't grok . + 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 < +/* 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 <&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 <> confdefs.h <&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 </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 < 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 <> $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 <> $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 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 +#include +#include +/* 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 +#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 \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 \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 \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 \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 \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 \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 \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 \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 \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 +# +# 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 + * + * Contributor(s): + * + */ + +/* ggsn.c + * + */ + +#ifdef __linux__ +#define _GNU_SOURCE 1 /* strdup() prototype, broken arpa/inet.h */ +#endif + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include + +#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; il, + 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 + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#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 + * + * 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 + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include /* 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, >p0_default, sizeof(gtp0_default)); + break; + case 1: + memcpy(packet, >p1_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; isin_addr), + ntohs(peer->sin_port), + len); + pos = strlen(buf); + for(n=0; nsin_addr), + ntohs(peer->sin_port), + len); + pos = strlen(buf2); + for(n=0; ngtp0.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(>p0_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(>p1_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 + * + * 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 + * + * 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 +#include +#include +#include + +#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 (ptv1.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 (jtv2.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 (jtv0.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 (jtv4.t, ie[j]->tv4.v); + p+= 1 + 4; + j++; + } + break; + case GTPIE_TEI_DII: /* TV GTPIE types with value length 5 */ + if (jtv0.t); + p+= 1 + 5; + j++; + } + break; + case GTPIE_RAB_CONTEXT: /* TV GTPIE types with value length 7 */ + if (jtv0.t); + p+= 1 + 7; + j++; + } + break; + case GTPIE_IMSI: /* TV GTPIE types with value length 8 */ + case GTPIE_RAI: + if (jtv0.t, ie[j]->tv8.v); + p+= 1 + 8; + j++; + } + break; + case GTPIE_AUTH_TRIPLET: /* TV GTPIE types with value length 28 */ + if (jtv0.t); + p+= 1 + 28; + j++; + } + break; + case GTPIE_EXT_HEADER_T: /* GTP extension header */ + if (jext.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 (jtlv.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; iext.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 + * + * 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= 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= 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 + * + * Contributor(s): + * + */ + +/* + * pdp.c: + * + */ + +#include +#include +#include +#include +#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; ninuse = 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 + * + * 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 + * + * Contributor(s): + * + */ + +/* + * Queue.c + * Reliable delivery of signalling messages + */ + +#include +#include +#include +#include +#include +#include +#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; nqmsga[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; nqmsga[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 + * + * 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 diff --git a/intl/Makefile.in b/intl/Makefile.in new file mode 100644 index 0000000..e69de29 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 , 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 , 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 <&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 +# #undef WIN32_LEAN_AND_MEAN +# #include +# +# #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 +# 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 /* for printf() */ +# #include /* for open(), lseek(), read() */ +# #include /* for O_RDONLY, O_BINARY */ +# #include /* 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&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 </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 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 +#include +#include +/* 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 +#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 \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 \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 \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 \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 \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 \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 \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 \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 \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 \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 \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 \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 \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 \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 \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 \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 +# +# 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 + * + * Contributor(s): + * + */ + +/* + * sgsnemu.c + * + */ + + +#ifdef __linux__ +#define _GNU_SOURCE 1 /* strdup() prototype, broken arpa/inet.h */ +#endif + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 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; n255) { + 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 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 + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#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 + * + * 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 diff --git a/tests/Makefile b/tests/Makefile new file mode 100644 index 0000000..e69de29 diff --git a/tests/Makefile.in b/tests/Makefile.in new file mode 100644 index 0000000..e69de29 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