commit 52c2414f6cabefb0427475756e8ac4856180bc59 Author: jjako Date: Mon Dec 16 13:33:51 2002 +0000 Initial revision 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