From: Adam Dickmeiss Date: Tue, 10 Mar 2009 20:59:27 +0000 (+0100) Subject: First. X-Git-Url: http://git.indexdata.com/?p=yaz-ziffy.git;a=commitdiff_plain;h=e80c331ea4fa31c903d03f533ec7ce02c454b6d3 First. --- e80c331ea4fa31c903d03f533ec7ce02c454b6d3 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ec6d941 --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +Makefile +Makefile.in +config.log +config.status +config.sub +config.guess +configure +.deps +autom4te.cache +config +build-stamp diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..f33fbb6 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,28 @@ + -*-text-*- +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +Original authors of ziffy + +Rocco Carbone +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + +ziffy exists because of Luca Deri , the author +of the popular and cool ntop program (http://www.ntop.org). +His great work suggested me the initial idea for implementing ziffy. + +I am waiting for many others who want to send me patches, bug fixes, +comments, wish-list and other stuff for ziffy. +ziffy will be much better because of them. +I will attempt to include folks on the Net who helped me in the following list. + +Contributors +============ +o Adam Dickmeiss + sent me a patch to make ziffy compatible with YAZ 1.6 and 1.7 + + +Credits +======= +o luca deri +o jama musse jama + + diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..3912109 --- /dev/null +++ b/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 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/Makefile.am b/Makefile.am new file mode 100644 index 0000000..471a627 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,19 @@ +# $Id: Makefile.am,v 1.2 2008-01-14 20:25:40 adam Exp $ + +AUTOMAKE_OPTIONS = foreign +ACLOCAL_AMFLAGS = -I m4 + +SUBDIRS = src + +EXTRA_DIST = COPYING NEWS README README.old buildconf.sh m4/yaz.m4 + +dist-hook: + if test -x /usr/bin/cvs2cl -a -d CVS; then cvs2cl ; cp ChangeLog $(distdir); fi + mkdir $(distdir)/debian + cp $(srcdir)/debian/changelog $(distdir)/debian + cp $(srcdir)/debian/control $(distdir)/debian + cp $(srcdir)/debian/rules $(distdir)/debian + cp $(srcdir)/debian/*.install $(distdir)/debian + cp $(srcdir)/debian/*.manpages $(distdir)/debian + cp $(srcdir)/debian/*.copyright $(distdir)/debian + diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..1a78b1c --- /dev/null +++ b/NEWS @@ -0,0 +1,30 @@ +2008-01-14 Adam Dickmeiss + * version 1.0 + +2001-06-27 Rocco Carbone + + * version 0.0.3 + Overview of changes in this version: + - adapted to compile with YAZ-1.7 by Index data + +1998-12-31 Rocco Carbone + + * version 0.0.2 lives free on the Net + + Overview of changes in this version: + - better GNU autoconf-ified distribution + - General documentation and a minimal web site have been prepared + - Command line argument fixes/upgrades + + +1998-12-18 Rocco Carbone + + * Initial public release + features: + - GNU autoconf-ified distribution + - Runs under Linux 2.0.x and Solaris 2.6 + - Requires libpcap (0.4a6 tested) + - Uses X/ASN1 (1.0.0 tested) + - Uses YAZ (1.4pl2 tested) + - Uses SNACC (1.3 tested) + - Initial support for filters diff --git a/README b/README new file mode 100644 index 0000000..ee0cbb9 --- /dev/null +++ b/README @@ -0,0 +1,16 @@ +The is ziffy for YAZ. ziffy is a promiscuous Z39.50 APDU sniffer + +Copyright (c) 1998-2007 Rocco Carbone +Copyright (c) 2007-2008 Index Data + +See README.old for Rocco's original introduction. + +ziffy is coverved by GPLv2. See COPYING for more information. + +In order to compile ziffy, a BSD like system with libpcap and libyaz3 +is required. When these components are installed, usually + ./configure + make + sudo make install +is sufficient to install ziffy (a program) and the man page ziffy.1 in +/usr/local or other prefix (if given). diff --git a/README.old b/README.old new file mode 100644 index 0000000..10d5754 --- /dev/null +++ b/README.old @@ -0,0 +1,135 @@ + -*-text-*- +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +ziffy, a promiscuous Z39.50 APDU sniffer + +Copyright (c) 1998-2001 R. Carbone + +This file includes: + + * General information + * Licensing + * Requirements + * Platforms + * Installation + * References + +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + +* General information + + ziffy is a promiscuous Z39.50 APDU sniffer, like the popular tcpdump. + ziffy can capture and show all Z39.50 traffic on your LAN segment. + + To perform its task ziffy needs at least two extra packages providing the + following functionalities: + + (a) a portable framework for low-level network capturing facility + (b) BER decoding, printing and freeing routines + + + I compiled and run ziffy on my `explosive' linux intel based box with: + + (a) libpcap 0.4a6 API, Copyright (c) 1993, 1994, 1995, 1996, 1997 + by The Regents of the University of California + + + (b) X/ASN.1 Toolkit 1.0.0, Copyright (c) 1989-1998 by Finsiel S.p.A. + (c) YAZ Toolkit 1.7 API, Copyright (c) 1995-2001 by Index Data + (d) SNACC Toolkit 1.3 API, Copyright (c) 1991, 1993 by Michael Sample and UCB + Copyright (c) 1994 1995 by Robert Joop and GMD Fokus + + + +* Licensing + + The ziffy program is released under the terms of the GNU GPL, read the file + COPYING for more information. + + +* Requirements + + ziffy depends on a couple of extra packages for working properly: + + - libpcap, the Packet Capture Library. It can be found at: + + ftp://ftp.ee.lbl.gov/libpcap.tar.Z + + + at least one of: + + - X/ASN.1 Toolkit from Finsiel S.p.A. + contact us at zeta@tlcpi.finsiel.it if you need more information + + + - YAZ Toolkit, the so popular "Yet Another Z39.50 Toolkit" from Index Data. + + You can find the YAZ Toolkit in: + + ftp://ftp.indexdata.dk/pub/yaz/yaz-1.7.tar.gz + + for more information about YAZ please visit: + http://www.indexdata.dk + + + - SNACC Toolkit, the "Sample Neufeld ASN.1 to C Compiler". + + You can find the most recent (1.3) version of SNACC at: + + ftp://ftp.fokus.gmd.de/pub/freeware/snacc/snacc-1.3.tar.gz + + [ + old version 1.1, but commonly used, is in: + ftp://ftp.cs.ucb.ca/pub/local/src/snacc/snacc-1.1.tar.Z + ] + + for more information visit SNACC home page: + http://www.fokus.gmd.de/ovma/freeware/snacc/entry.html + + + + If you know of other freeware ASN.1 Toolkits, please drop me a note. + I will try to include them in all future versions of ziffy. + + + + +* Platforms + + Sun Solaris 2.5.1 and/or 2.6 + ix?86 Linux 2.0.X (bug on it! be patient until I have time to fix it!) + + +* Installation + + o To compile ziffy, you need to build and install libpcap and the + YAZ Toolkit or SNACC Toolkit first, or both at your choice + + o Run "./configure" if you have libpcap and SNACC/YAZ Toolkit on standard + places. Otherwise, to build from source distributions, run: + + ./configure --with-pcap-dir=your_libpcap_location + --with-yaz-dir=your_yaz_location --with-snacc-dir=your_snacc_location + + "configure" will determine your system attributes and generate + an appropriate Makefile from Makefile.in. + + o Run "make". If everything is ok, you should have a binary + called "ziffy". + + o Run "make install". everything will go to the right places. + + +* References + + Importants RFC's you should read to fully understand what we are talking + about are: + + [] RFC 1729: Using the Z39.50 Information Retrieval Protocol + in the Internet Environment + + + + + Please send me patches for any modifications you need to compile, + install and run the program. + diff --git a/buildconf.sh b/buildconf.sh new file mode 100755 index 0000000..ec44e4c --- /dev/null +++ b/buildconf.sh @@ -0,0 +1,125 @@ +#!/bin/sh + +automake=automake +aclocal=aclocal +autoconf=autoconf +libtoolize=libtoolize +autoheader=autoheader + +test -d config || mkdir config +if [ -d .git ]; then + git submodule init + git submodule update +fi +if [ "`uname -s`" = FreeBSD ]; then + # FreeBSD intalls the various auto* tools with version numbers + echo "Using special configuration for FreeBSD ..." + automake=automake19 + aclocal="aclocal19 -I /usr/local/share/aclocal" + autoconf=autoconf259 + libtoolize=libtoolize15 + autoheader=autoheader259 +fi + +if [ "`uname -s`" = Darwin ]; then + echo "Using special configuration for Darwin/MacOS ..." + libtoolize=glibtoolize +fi + +if $automake --version|head -1 |grep '1\.[4-7]'; then + echo "automake 1.4-1.7 is active. You should use automake 1.8 or later" + if [ -f /etc/debian_version ]; then + echo " sudo apt-get install automake1.9" + echo " sudo update-alternatives --config automake" + fi + exit 1 +fi + +set -x +$aclocal -I m4 +if grep AC_CONFIG_HEADERS configure.ac >/dev/null; then + $autoheader +fi +$libtoolize --automake --force +$automake --add-missing +$autoconf +set - +if [ -f config.cache ]; then + rm config.cache +fi + +enable_configure=false +enable_help=true +sh_flags="" +conf_flags="" +case $1 in + -d) + sh_cflags="-g -Wall -Wdeclaration-after-statement -Wstrict-prototypes" + sh_cxxflags="-g -Wall" + enable_configure=true + enable_help=false + shift + ;; + -c) + sh_cflags="" + sh_cxxflags="" + enable_configure=true + enable_help=false + shift + ;; +esac + +if $enable_configure; then + if [ -n "$sh_cflags" ]; then + CFLAGS="$sh_cflags" CXXFLAGS="$sh_cxxflags" ./configure --disable-shared --enable-static $* + else + ./configure $* + fi +fi +if $enable_help; then + cat < + #endif + #if HAVE_SYS_SOCKET_H + #include + #endif + #if HAVE_NET_IF_H + #include + #endif + #if HAVE_NETINET_IN_H + #include + #endif +]) + +dnl ------ libpcap +AC_SUBST(PCAP_LIBS) +AC_SUBST(PCAP_CFLAGS) +AC_ARG_WITH(pcap, [ --with-pcap[=DIR] libpcap root dir located in (dir)], [PCAP_DIR="$withval"],[PCAP_DIR=default]) + +if test "${PCAP_DIR}" != "no"; then + if test "${ac_cv_header_netinet_if_ether_h}" = "no"; then + : + elif test "${PCAP_DIR}" != "yes" && test "${PCAP_DIR}" != "default"; then + PCAP_LIBS="-lpcap" + if test "$PCAP_DIR" != "/usr"; then + PCAP_LIBS="-L$PCAP_DIR $PCAP_LIBS" + PCAP_CFLAGS="-I$PCAP_DIR" + fi + else + oldLibs=$LIBS + AC_CHECK_LIB([pcap], [main]) + if test "$ac_cv_lib_pcap_main" = "yes"; then + AC_CHECK_HEADER([pcap.h]) + if test "$ac_cv_header_pcap_h" = "yes"; then + PCAP_LIBS="-lpcap" + fi + fi + LIBS=$oldLibs + fi +fi +AC_MSG_CHECKING([for libpcap (required for ziffy)]) +if test -z "${PCAP_LIBS}"; then + AC_MSG_ERROR([not found]) +else + AC_MSG_RESULT([found in $PCAP_DIR]) +fi + +dnl +dnl ------ Makefiles +dnl +AC_OUTPUT([Makefile src/Makefile]) + +dnl Local Variables: +dnl mode:shell-script +dnl sh-indentation: 2 +dnl sh-basic-offset: 4 +dnl End: diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..9e90203 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,6 @@ +yaz-ziffy (1.0-1) unstable; urgency=low + + * Upstream. + + -- Adam Dickmeiss Mon, 14 Jan 2008 20:25:25 +0100 + diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..c44442e --- /dev/null +++ b/debian/control @@ -0,0 +1,18 @@ +Source: yaz-ziffy +Section: devel +Standards-Version: 3.6.2 +Maintainer: Adam Dickmeiss +Priority: extra +Build-Depends: debhelper (>= 4), pkg-config, libpcap0.8-dev, libyaz3-dev + +Package: yaz-ziffy +Section: utils +Depends: ${shlibs:Depends} +Architecture: any +Description: ziffy: the promiscuous Z39.50 APDU sniffer + ziffy is a promiscuous Z39.50 APDU sniffer, like the popular tcpdump. + ziffy can capture and show all Z39.50 traffic on your LAN segment. + This packages is a special port of ziffy ported to YAZ. Note that ziffy + is licensed under the GPL by Rocco Carbone . + + diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000..e17fae6 --- /dev/null +++ b/debian/rules @@ -0,0 +1,107 @@ +#!/usr/bin/make -f +# -*- makefile -*- +# Sample debian/rules that uses debhelper. +# GNU copyright 1997 to 1999 by Joey Hess. + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +# Force compat level four +export DH_COMPAT=4 + +# These are used for cross-compiling and for saving the configure script +# from having to guess our platform (since we know it already) +DEB_HOST_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) +DEB_BUILD_GNU_TYPE ?= $(shell dpkg-architecture -qDEB_BUILD_GNU_TYPE) + + +CFLAGS = -Wall -g + +ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS))) + CFLAGS += -O0 +else + CFLAGS += -O2 +endif +ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS))) + INSTALL_PROGRAM += -s +endif + + +config.status: configure + dh_testdir + # Add here commands to configure the package. + CFLAGS="$(CFLAGS)" ./configure --host=$(DEB_HOST_GNU_TYPE) --build=$(DEB_BUILD_GNU_TYPE) --prefix=/usr --mandir=\$${prefix}/share/man --infodir=\$${prefix}/share/info --with-yaz=/usr/bin + + +build: build-stamp +build-stamp: config.status + dh_testdir + + # Add here commands to compile the package. + $(MAKE) + + touch build-stamp + +clean: + dh_testdir + dh_testroot + rm -f build-stamp + + # Add here commands to clean up after the build process. + -$(MAKE) distclean +ifneq "$(wildcard /usr/share/misc/config.sub)" "" + -cp -f /usr/share/misc/config.sub config.sub +endif +ifneq "$(wildcard /usr/share/misc/config.guess)" "" + -cp -f /usr/share/misc/config.guess config.guess +endif + + dh_clean + +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + + # Add here commands to install the package into debian/tmp + $(MAKE) install DESTDIR=$(CURDIR)/debian/tmp + + +# Build architecture-independent files here. +binary-indep: build install +# We have nothing to do by default. + +# Build architecture-dependent files here. +binary-arch: build install + dh_testdir + dh_testroot + dh_installdocs -A README + dh_installchangelogs + dh_installexamples + dh_install +# dh_installmenu +# dh_installdebconf +# dh_installlogrotate +# dh_installemacsen +# dh_installpam +# dh_installmime +# dh_installinit +# dh_installcron +# dh_installinfo + dh_installman + dh_link + dh_strip + dh_compress + dh_fixperms +# dh_perl +# dh_python +# dh_makeshlibs + dh_installdeb + dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install diff --git a/debian/yaz-ziffy.copyright b/debian/yaz-ziffy.copyright new file mode 100644 index 0000000..c547833 --- /dev/null +++ b/debian/yaz-ziffy.copyright @@ -0,0 +1,34 @@ +This package was debianized by Adam Dickmeiss on Mon Jan 14 21:02:30 CET 2008. + +This version was downloaded from < http://ftp.indexdata.dk/pub/yaz-ziffy/ > + + yaz-ziffy (and ziffy) was written by Rocco Carbone + + Adam Dickmeiss ported it for YAZ and Debian. + +Copyright: + + Copyright (C) 1998-2007 Rocco Carbone + Copyright (C) 2008, Adam Dickmeiss + + yaz-ziffy is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + yaz-ziffy 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 yaz-ziffy; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, + MA 02110-1301, USA. + + +On Debian systems, the full text of the GPL is also available at +/usr/share/common-licenses/GPL-2 + + + diff --git a/debian/yaz-ziffy.install b/debian/yaz-ziffy.install new file mode 100644 index 0000000..c8aa2ad --- /dev/null +++ b/debian/yaz-ziffy.install @@ -0,0 +1 @@ +debian/tmp/usr/bin/ziffy diff --git a/debian/yaz-ziffy.manpages b/debian/yaz-ziffy.manpages new file mode 100644 index 0000000..c65517c --- /dev/null +++ b/debian/yaz-ziffy.manpages @@ -0,0 +1 @@ +debian/tmp/usr/share/man/man1/ziffy.1 diff --git a/src/.cvsignore b/src/.cvsignore new file mode 100644 index 0000000..b0e67b8 --- /dev/null +++ b/src/.cvsignore @@ -0,0 +1,5 @@ +Makefile +Makefile.in +*.o +ziffy +.deps diff --git a/src/ANNOUNCEMENT-1 b/src/ANNOUNCEMENT-1 new file mode 100644 index 0000000..72e7dc2 --- /dev/null +++ b/src/ANNOUNCEMENT-1 @@ -0,0 +1,24 @@ +To: z3950iw@nervm.nerdc.ufl.edu +Cc: asf@cni.org +Subject: ANNOUNCE: ziffy - a promiscuous, and free, Z39.50 APDU sniffer +--text follows this line-- + + hi all, +I am pleased to announce the release 0.0.1 of the 'ziffy' tool, +a small utility program which can be of interest for the community. + +`ziffy' is a promiscuous, and free, Z39.50 APDU sniffer. +It is released under the GPL License. + +'ziffy' is available in source tarball format by anonymous FTP from: + +ftp://zeta.tlcpi.finsiel.it:/pub/z3950/ziffy/ziffy-0.0.1.tar.gz + + +I have tested this tool on Solaris 2.6 and Linux (Debian `slink' 2.1). + +Feel free to contact me for comments, suggestions, enhacements, .... + +Hope it helps! + +/rocco diff --git a/src/FAQ b/src/FAQ new file mode 100644 index 0000000..dab0fc9 --- /dev/null +++ b/src/FAQ @@ -0,0 +1,95 @@ + + -*-text-*- + +Q. Why did you implemented ziffy? +A. because of my own personal needs! + + +Q. What can ziffy do for me? +A. ziffy can promiscuously capture network packets from different interfaces, + including of course Ethernet, PPP and ISDN lines, and other interfaces + that your OS supports. Each packet, as read from the network, is stripped + from the lower-level protocols (Ethernet/IP/TCP) header information and + then passed to a Z39.50 ASN.1/BER Decoder. All valid Z39.50 packets are + passed to a pretty print function to show all the Z39.50 information + that the packet carries. + + +Q. Why I should use this program? +A. So, if you are interestered in Z39.50 APDUs, please give ziffy a chance + to run on your system. Perhaps you are interested in network statistics + collection, security monitoring, network debugging, etc. + + If you are a trusted user, ziffy is your friend! + + +Q. Why does ziffy use the Packet Capture Library libpcap? +A. Well, the libpcap package provides a portable framework for low-level + network monitoring. Its system-independent API helps in porting and + alleviates the need for several system-dependent packet capture modules. + libpcap is the choice by default for tools such as ziffy! + + +Q. Why does ziffy use the YAZ Toolkit by IndexData? +A. This is a long story. + To perform its task ziffy needs ASN.1 run-time BER decoding and printing + routines. + + The initial version was based on the ZETA Core Library by Finsiel S.p.A., + which in turn includes and uses the Finsiel X/ASN.1 Toolkit to perform + Z39.50 encoding/decoding/printing routines. + + I still have and maintain this version of the X/ASN.1 software. But I do not + have permissions to let this software run free on the Net because of + copyrigth restrictions. That is the reason I decided to port ziffy + on freeware ASN.1 Toolkits. + + The popular Yaz Toolkit: + o provides the required Z39.50 decoding and printing functionalities + o it is largely used in different contests by several people and organizations + o it is in the public domain + + So it is the choice by default. + Thanks to Sebastian Hammer and Adam Dickmeiss + for their superb and clean work + + +Q. Had ziffy been compiled against other public domain ASN.1 Toolkits? +A. Yes. + I have a version of ziffy written on top of the SNACC ASN.1 Toolkit, + that is not so popular in the Z39.50 community so the YAZ Toolkit does. + + If you know of other public domain ASN.1 Decoders with a pretty print + APDUs routines, please drop me a mail. + I will try to include different printing routines as run-time options + in the following releases of ziffy. + + +Q. Can I know the list of OSs and supported platforms ziffy run on? +A. I written and tested the program on my intel based linux box. + And I ported it on the Solaris 2.6. + I think it should be ported with minimal effort on + o Ultrix 4.1.3 + o Irix 6.2 + + AIX? who can say? it is a so different flavor of Unix + + NT? oh no, again! please don't ask. + + +Q. Where can I get the latest version of ziffy? +A. You can download it from ftp anonymous site: + ftp://zeta.tlcpi.finsiel.it/pub/z3950/ziffy + + +Q. Where can I get more information on ziffy? +A. Visit the ziffy official home page. + http://zeta.tlcpi.finsiel.it/z3950/ziffy + + +Q. Are there any mailinglist dedicated to ziffy? +A. No! for the time being. + + +Q. If I need support can I contact you? +A. Yes, but I am so busy. So send me a mail and please be patient! diff --git a/src/HACKING b/src/HACKING new file mode 100644 index 0000000..fe28d35 --- /dev/null +++ b/src/HACKING @@ -0,0 +1,36 @@ + -*-text-*- + +The ziffy utility started from its first version to use +GNU automake and autoconf utilities. + +If you want to hack on ziffy, it will make you life easier +to have the following packages installed: + + - GNU libtool 1.3.3 + - GNU automake 1.4 + - GNU autoconf 2.13 + +These should be available by ftp from ftp.gnu.org or any of the +fine GNU mirrors. Beta software can be found at ftp://alpha.gnu.org. + + +This means that you will need the usual GNU tools to build these in +maintainer mode from the development tree. You can simply type at +your prompt: + +> ./autogen.sh + +[a simple shell script that basically does the following for you: + + aclocal + autoheader + automake --add-missing --gnu + autoconf + configure + +] + + +have fun! + +/rocco diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..25beda6 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,18 @@ +## -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +## auto makefile for ziffy - a promiscuous Z39.50 APDU sniffer for Ethernet +## (this file is processed with 'automake' to produce Makefile.in) +## +## Copyright (c) 1998-2001 R. Carbone + +LDADD = $(YAZLIB) $(PCAP_LIBS) + +AM_CPPFLAGS = $(YAZINC) $(PCAP_CFLAGS) + +bin_PROGRAMS = ziffy + +man_MANS = ziffy.1 + +EXTRA_DIST = $(man_MANS) HACKING TODO FAQ ANNOUNCEMENT-1 + +ziffy_SOURCES = ziffy.c yaz.c fmemdmp.c hooks.c apdu.c apdu.h + diff --git a/src/NEWS b/src/NEWS new file mode 100644 index 0000000..775a07a --- /dev/null +++ b/src/NEWS @@ -0,0 +1,5 @@ + -*-text-*- + +1998-12-18 Rocco Carbone + + * First split version of this package diff --git a/src/TODO b/src/TODO new file mode 100644 index 0000000..9c29741 --- /dev/null +++ b/src/TODO @@ -0,0 +1,16 @@ + + -*-text-*- + +o dump the Ethernet/IP/TCP packets as options + +o implement timestamp presentation + +o find an optimal cutoff for the default snaplen + +o implement an APDU type filtering mechanism + +o implement a proxy capability + +o implement control of the program via the HTTP Protocol + +o porting code to Ultrix 4.1.3 and Irix 6.2 diff --git a/src/apdu.c b/src/apdu.c new file mode 100644 index 0000000..4e83052 --- /dev/null +++ b/src/apdu.c @@ -0,0 +1,180 @@ +/* + * -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + * apdu.c - + * + * Copyright (c) 1998-2001 R. Carbone - Finsiel S.p.A. + * -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + * + * 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. + */ + + +/* + * Operating System include files + */ +#include + +#include +#if HAVE_SYS_TIME_H +#include +#endif + +#include + +#include "apdu.h" + +/* + * The table of z3950 apdus + */ +static z3950apdu apdutable [] = +{ + { 20, "INIT request", -1, NULL, NULL, 0, NULL, 0 }, + { 21, "INIT response", -1, NULL, NULL, 0, NULL, 0 }, + { 22, "SEARCH request", -1, NULL, NULL, 0, NULL, 0 }, + { 23, "SEARCH response", -1, NULL, NULL, 0, NULL, 0 }, + { 24, "PRESENT request", -1, NULL, NULL, 0, NULL, 0 }, + { 25, "PRESENT response", -1, NULL, NULL, 0, NULL, 0 }, + { 26, "DELETE request", -1, NULL, NULL, 0, NULL, 0 }, + { 27, "DELETE response", -1, NULL, NULL, 0, NULL, 0 }, + { 28, "ACCESS request", -1, NULL, NULL, 0, NULL, 0 }, + { 29, "ACCESS response", -1, NULL, NULL, 0, NULL, 0 }, + { 30, "RESOURCE request", -1, NULL, NULL, 0, NULL, 0 }, + { 31, "RESOURCE response", -1, NULL, NULL, 0, NULL, 0 }, + { 32, "TRIGGER request", -1, NULL, NULL, 0, NULL, 0 }, + { 33, "REPORT request", -1, NULL, NULL, 0, NULL, 0 }, + { 34, "REPORT response", -1, NULL, NULL, 0, NULL, 0 }, + { 35, "SCAN request", -1, NULL, NULL, 0, NULL, 0 }, + { 36, "SCAN response", -1, NULL, NULL, 0, NULL, 0 }, + + { 43, "SORT request", -1, NULL, NULL, 0, NULL, 0 }, + { 44, "SORT response", -1, NULL, NULL, 0, NULL, 0 }, + { 45, "SEGMENT request", -1, NULL, NULL, 0, NULL, 0 }, + { 46, "EXTENDED request", -1, NULL, NULL, 0, NULL, 0 }, + { 47, "EXTENDED response", -1, NULL, NULL, 0, NULL, 0 }, + { 48, "CLOSE request", -1, NULL, NULL, 0, NULL, 0 }, + + { 0 }, +}; + + +z3950apdu * lookup (int tag) +{ + z3950apdu * found = apdutable; + + for (found = apdutable; found < apdutable + + (sizeof (apdutable) / sizeof (apdutable [0])); found ++) + if (found -> tag == tag) + break; + + return (found); +} + + +static int bertag (u_char * apdu) +{ + u_char * q = apdu; + int tag = * q & 0x1F; + + if (tag > 30) + { + tag = 0; + q ++; + do + { + tag <<= 7; + tag |= * q & 0X7F; + } + while (* q ++ & 0X80); + } + return (tag); +} + + +/* + * An euristic Z39.50 event check routine that simply + * looks for the first tag in the APDU + */ +z3950apdu * parseable (u_char * apdu, int len) +{ + if (! len) + return (0); + + return (lookup (bertag (apdu))); +} + + + +struct timeval current_apdu = {0}; +struct timeval first_apdu = {0}; +struct timeval last_apdu = {0}; + +/* + * The time difference in milliseconds + */ +time_t delta_time_in_milliseconds (const struct timeval * now, + const struct timeval * before) +{ + /* + * compute delta in second, 1/10's and 1/1000's second units + */ + time_t delta_seconds = now -> tv_sec - before -> tv_sec; + time_t delta_milliseconds = (now -> tv_usec - before -> tv_usec) / 1000; + + if (delta_milliseconds < 0) + { /* manually carry a one from the seconds field */ + delta_milliseconds += 1000; /* 1e3 */ + -- delta_seconds; + } + return ((delta_seconds * 1000) + delta_milliseconds); +} + + +/* + * return a well formatted timestamp + */ +char * timestamp (const struct timeval * t, int fmt) +{ + static char buf [16]; + + time_t now = time ((time_t *) 0); + struct tm * tm = localtime (& now); + + gettimeofday (& current_apdu, NULL); + + switch (fmt) + { + default: + case DELTA_FMT: + /* + * calculate the difference in milliseconds since the previous apdus was displayed + */ + sprintf (buf, "%10ld ms", delta_time_in_milliseconds (& current_apdu, & last_apdu)); + break; + + case ABS_FMT: + sprintf (buf, "%02d:%02d:%02d.%06d", + tm -> tm_hour, tm -> tm_min, tm -> tm_sec, (int) t -> tv_usec); + break; + + case RELATIVE_FMT: + /* + * calculate the difference in milliseconds since the previous apdus was displayed + */ + sprintf (buf, "%10ld ms", delta_time_in_milliseconds (& current_apdu, & first_apdu)); + break; + } + + return (buf); +} diff --git a/src/apdu.h b/src/apdu.h new file mode 100644 index 0000000..f4b3cec --- /dev/null +++ b/src/apdu.h @@ -0,0 +1,70 @@ +/* + * -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + * apdu.h - + * + * Copyright (c) 1998-2001 R. Carbone - Finsiel S.p.A. + * -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + * + * 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. + */ + + +extern unsigned long z3950_apduno; + +extern int aflag; + +extern int ethflag; +extern int ipflag; +extern int tcpflag; +extern int z3950flag; + + +extern struct timeval first_apdu; +extern struct timeval last_apdu; + + +/* + * The structure containing information about all the apdus + */ +typedef struct +{ + int tag; /* unique apdu tag identifier */ + char * name; /* user printable name of the apdu */ + int minlen; /* min length of bytes off wire (all optional fields absent) */ + const struct timeval * t; /* the time the apdu was captured */ + char * calling; /* source ip address */ + int srcport; /* source port */ + char * called; /* destination ip address */ + int dstport; /* source port */ +} z3950apdu; + + +z3950apdu * parseable (unsigned char * apdu, int len); + +char * srchost (void); +int srcport (void); +char * dsthost (void); +int dstport (void); + + +/* + * time stamp presentation formats + */ +#define DELTA_FMT 1 /* the time since receiving the previous apdu */ +#define ABS_FMT 2 /* the current time */ +#define RELATIVE_FMT 3 /* the time relative to the first apdu received */ + + +char * timestamp (const struct timeval * t, int fmt); diff --git a/src/fmemdmp.c b/src/fmemdmp.c new file mode 100644 index 0000000..630f7a8 --- /dev/null +++ b/src/fmemdmp.c @@ -0,0 +1,106 @@ +/* + * -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + * fmemdmp.c - tracing utilities + * + * Copyright (c) 1998-2001 R. Carbone + * -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + * + * 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. + */ + + + +/* + * Operating System include files + */ +#include +#include +#include +#include +#include + +#include +#if HAVE_SYS_TIME_H +# include +#endif + + +/* + * Pretty print function. + * + * This function dumps a buffer in memory in the (pretty !!) format : + * + * off: printable hexadecimal notation + * -------------------------------------------------------------------------- + * + * Dump of memory area at address 0x10000444 for 51 bytes + * 0: abcdefghijklmnop 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 + * 16: qrstuvzxyw012345 71 72 73 74 75 76 7a 78 79 77 30 31 32 33 34 35 + * 32: 6789~!@#$%^&*()_ 36 37 38 39 7e 21 40 23 24 25 5e 26 2a 28 29 5f + * 48: -+= 2d 2b 3d + * + * Dump of memory area at address 0x7fffbc03 for 16 bytes + * 0: rocco@tecsiel.it 72 6f 63 63 6f 40 74 65 63 73 69 65 6c 2e 69 74 + */ +void fmemdmp (FILE * fd, char * ptr, int size, char * text) +{ + int offset = 0; + int i = 0; + int bytes_in_a_line = 16; + unsigned int total; + + if (! ptr || size <= 0) + return; + + if (text && * text) + fprintf (fd, "\"%s\" at address %p for %d bytes\n", + text, ptr, size); + + for (total = 0; total < size; total += bytes_in_a_line) + { + /* + * Print the offset + */ + fprintf (fd, "%6d: ", offset); + /* + * Print the bytes in a line (each byte in ASCII notation) + */ + for (i = 0; i < bytes_in_a_line; i ++) + if (total + i < size) + fprintf (fd, "%c", + isprint (* (ptr + total + i) & 0x000000ff) + ? (* (ptr + total + i)) + : '.'); + else + fprintf (fd, " "); /* 1 blank character */ + /* + * Print the separator + */ + fprintf (fd, " "); + /* + * Print the bytes in a line (each byte in Hexadecimal notation) + */ + for (i = 0; i < bytes_in_a_line && i < size; i ++) + if (total + i < size) + fprintf (fd, "%02x ", + * (ptr + total + i) & 0x000000ff); + else + fprintf (fd, " "); /* 3 more blanks characters */ + + fprintf (fd, "\n"); + offset += bytes_in_a_line; + } + fflush (fd); +} diff --git a/src/hooks.c b/src/hooks.c new file mode 100644 index 0000000..54742aa --- /dev/null +++ b/src/hooks.c @@ -0,0 +1,317 @@ +/* + * -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + * hooks.c - a TCP/IP protocol filter for ziffy + * + * Copyright (c) 1998-2001 R. Carbone + * -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + * + * 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. + */ + +#define _BSD_SOURCE + + +/* + * Operating System include files + */ +#include +#include +#include +#include + +#include +#include + +#if HAVE_NET_IF_H +#include +#endif + +#if HAVE_NETINET_IN_H +#include +#endif + +#if HAVE_NETINET_IF_ETHER_H +#include +#endif + +#if HAVE_NETINET_IN_SYSTM_H +#include +#endif + +#include +#include + +#include "pcap.h" /* Packet Capture Library */ + +#include "apdu.h" + +void fmemdmp (FILE * fd, char * ptr, int size, char * text); + + +/* external */ +extern int dlt; + + +/* + * to allow a pretty-print of lower-layers address I save + * relevant pointers to all the protocol data units in global variables, + * rather than pass them across function calls. + * So, for example, if someone is interested in the paired source and + * destination IP addressed, they can be easily accessed by global 'ip' pointer. + */ + + +/* + * hooks to the known protocols in the ethernet packets + */ +static struct ether_header * e = NULL; +static struct ip * ip = NULL; +static struct tcphdr * tcp = NULL; +extern u_char * z3950; + +/* + * sizes of the known protocols in the ethernet packets + */ +static int eth_size = 0; +static int eth_hlen = 0; +static int ip_size = 0; +static int ip_hlen = 0; +static int tcp_size = 0; +static int tcp_hlen = 0; +extern int z3950_size; + + +char * srchost (void) +{ + static char buf [256]; /* should be enough for humans !!! */ + + struct hostent * host = NULL; + + if (aflag) + host = gethostbyaddr ((char *) & ip -> ip_src, sizeof (ip -> ip_src), AF_INET); + + sprintf (buf, "%s", host ? host -> h_name : inet_ntoa (ip -> ip_src)); + return (buf); +} + + +int srcport (void) +{ + return ((int) ntohs (tcp -> th_sport)); +} + + +char * dsthost (void) +{ + static char buf [256]; /* should be enough for humans !!! */ + + struct hostent * host = NULL; + + if (aflag) + host = gethostbyaddr ((char *) & ip -> ip_dst, sizeof (ip -> ip_dst), AF_INET); + + sprintf (buf, "%s", host ? host -> h_name : inet_ntoa (ip -> ip_dst)); + return (buf); +} + + +int dstport (void) +{ + return ((int) ntohs (tcp -> th_dport)); +} + + +/* + * stolen from the addrtoname.c in tcpdump + */ +static char hex [] = "0123456789abcdef"; + +static char * etheraddr_string (u_char * e) +{ + static char buf [sizeof ("00:00:00:00:00:00")]; + + int i; + int j; + char * p; + + strcpy (buf, "00:00:00:00:00:00"); + + /* + * hacked to manage DLT_NULL + */ + if (! e) + return (buf); + + p = buf; + if ((j = * e >> 4) != 0) + * p ++ = hex [j]; + * p ++ = hex [* e ++ & 0xf]; + for (i = 5; -- i >= 0; ) + { + * p ++ = ':'; + if ((j = * e >> 4) != 0) + * p ++ = hex [j]; + * p ++ = hex [* e ++ & 0xf]; + } + * p = '\0'; + return (buf); +} + + +/* + * Parse the incoming Ethernet Packet and set hooks to all pertinent data. + * + * 'h' is the pointer to the packet header (independent from interfaces) + * 'p' is the pointer to the packet data + * + * Warning: I really want libpcap to give me aligned packets + */ +z3950apdu * pduhook (const struct pcap_pkthdr * h, const u_char * p) +{ + static unsigned long ethno = 0; /* # of ethernet packets received by the decoder */ + static unsigned long ipno = 0; /* # of IP packets received by the decoder */ + static unsigned long tcpno = 0; /* # of TCP packets received by the decoder */ + + u_char * q; + + z3950apdu * apdu = NULL; + + /* + * Ethernet Protocol + */ + e = (struct ether_header *) p; + + /* + * Ethernet sizes + * + * The header is only 4 bytes long in case of no link-layer encapsulation (DLT_NULL). + * It contains a network order 32 bit integer that specifies the family, e.g. AF_INET + */ + eth_size = h -> len; + eth_hlen = dlt == DLT_NULL ? 4 : sizeof (struct ether_header); + + ++ ethno; + + if (ethflag) + printf ("ETHER: ----- Ether Header -----\n"), + printf ("ETHER:\n"), + printf ("ETHER: Packet %ld arrived at %s\n", ethno, timestamp (& h -> ts, ABS_FMT)), + printf ("ETHER: Total size = %d : header = %d : data = %d\n", + eth_size, eth_hlen, eth_size - eth_hlen), + printf ("ETHER: Source = %s\n", + etheraddr_string (dlt == DLT_NULL ? NULL : (u_char *) & e -> ether_shost)), + printf ("ETHER: Destination = %s\n", + etheraddr_string (dlt == DLT_NULL ? NULL : (u_char *) & e -> ether_dhost)), + fflush (stdout), + fmemdmp (stdout, (char *) e, eth_size, "Ethernet Packet"); + + /* + * Process only IP packets (or loopback packets when testing at home sweet home) + */ + if (dlt == DLT_NULL || ntohs (e -> ether_type) == ETHERTYPE_IP) + { + /* + * IP Protocol + */ + ip = (struct ip *) (p + eth_hlen); + + /* + * IP sizes + * + * ip->ip_hl*4 = size of the IP (Header Only) + * ntohs (ip->ip_len) = size of the IP (Full Packet) + * ip_size = eth_size - eth_hlen (better IMO) + */ + ip_size = eth_size - eth_hlen; + ip_hlen = ip -> ip_hl * 4; + + ++ ipno; + + if (ipflag) + printf ("IP: ----- IP Header -----\n"), + printf ("IP:\n"), + printf ("IP: Packet %ld arrived at %s\n", ipno, timestamp (& h -> ts, ABS_FMT)), + printf ("IP: Total size = %d : header = %d : data = %d\n", + ip_size, ip_hlen, ip_size - ip_hlen), + printf ("IP: Source = %s\n", inet_ntoa (ip -> ip_src)), + printf ("IP: Destination = %s\n", inet_ntoa (ip -> ip_dst)), + fflush (stdout); + +#if (0) + fmemdmp (stdout, (char *) ip, ip_size, "IP Packet"); +#endif + + /* + * i am looking for Z39.50 APDUs over TCP/IP. so... + */ + if (ip -> ip_p == IPPROTO_TCP) + { + /* + * TCP Protocol + */ + q = (u_char *) ip + ip_hlen; + tcp = (struct tcphdr *) q; + + /* + * TCP sizes + * + * tcp->th_off*4 = size of the TCP (Header Only) + */ + tcp_size = ip_size - ip_hlen; + tcp_hlen = tcp -> th_off * 4; + + ++ tcpno; + + if (tcpflag) + printf ("TCP: ----- TCP Header -----\n"), + printf ("TCP:\n"), + printf ("TCP: Packet %ld arrived at %s\n", tcpno, timestamp (& h -> ts, ABS_FMT)), + printf ("TCP: Total size = %d : header = %d : data = %d\n", + tcp_size, tcp_hlen, tcp_size - tcp_hlen), + printf ("TCP: Source = %d\n", ntohs (tcp -> th_sport)), + printf ("TCP: Destination = %d\n", ntohs (tcp -> th_dport)), + fflush (stdout), + fmemdmp (stdout, (char *) tcp, tcp_size, "TCP Packet"); + + /* + * Application Protocol + * (time to play with Z39.50 APDUs here) + */ + z3950 = (u_char *) e + eth_hlen + ip_hlen + tcp_hlen; + + /* + * Higher Protocol Packet Size + */ + z3950_size = tcp_size - tcp_hlen; + + apdu = parseable (z3950, z3950_size); + + if (tcpflag && apdu) + printf ("TCP: ----- TCP Header -----\n"), + printf ("TCP:\n"), + printf ("TCP: Packet %ld arrived at %s\n", tcpno, timestamp (& h -> ts, ABS_FMT)), + printf ("TCP: Total size = %d : header = %d : data = %d\n", + tcp_size, tcp_hlen, tcp_size - tcp_hlen), + printf ("TCP: Source = %d\n", ntohs (tcp -> th_sport)), + printf ("TCP: Destination = %d\n", ntohs (tcp -> th_dport)), + fflush (stdout), + fmemdmp (stdout, (char *) tcp, tcp_size, "TCP Packet"); + + + return (apdu); + } + } + return (NULL); +} diff --git a/src/yaz.c b/src/yaz.c new file mode 100644 index 0000000..6e9943e --- /dev/null +++ b/src/yaz.c @@ -0,0 +1,145 @@ +/* + * -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + * yaz.c - decoding and printing utility based on the YAZ Toolkit + * + * Copyright (c) 1998-2001 R. Carbone + * -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + * + * 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. + */ + + +/* + * Operating System include files + */ +#include +#include + +/* + * YAZ include files + */ +#include "yaz/odr.h" +#include "yaz/proto.h" + +#include "apdu.h" + + +void please_yaz_help_me (z3950apdu * hook) +{ + extern unsigned char * z3950; + extern int z3950_size; + + /* + * Variable to keep the Z39.50 APDUs. The definitions are in the + * the structures defined by the YAZ Toolkit. + */ + Z_APDU * apdu = NULL; + + /* + * Decoding/Printing streams + */ + ODR printing; + ODR decode; + + /* + * The stream used for decoding + */ +#define MAXBERSIZE (2048 * 2048) + unsigned char berbuffer [MAXBERSIZE]; + + /* + * Allocate a stream for input data + */ + decode = odr_createmem (ODR_DECODE); + if (! decode) + { + printf ("Not enough memory to create an input stream\n"); + return; + } + + /* + * Allocate a stream for printing data + */ + printing = odr_createmem (ODR_PRINT); + if (! printing) + { + printf ("Not enough memory to create a printing stream\n"); + odr_destroy (decode); + return; + } + + /* + * Initialize the decoding routines + */ + memcpy (berbuffer, z3950, z3950_size); + + odr_setbuf (decode, (char *) berbuffer, z3950_size, 0); + + /* + * Perform BER decoding + */ + if (z_APDU (decode, & apdu, 0, 0)) + { + ++ z3950_apduno; + + if (z3950flag) + printf ("Z3950: ----- Z39.50 APDU -----\n"), + printf ("Z3950: APDU %ld arrived at %s\n", z3950_apduno, + timestamp (hook -> t, ABS_FMT)), + printf ("Z3950: Total size = %d\n", z3950_size), + fflush (stdout); + + /* + * save the time the last apdu was displayed + */ + if (z3950_apduno == 1) + gettimeofday (& first_apdu, NULL); + + /* + * print standard summary information accordingly to the format + * + * id time source:port -> destination:port type + */ + printf ("Z3950: %5ld %s %s:%d -> %s:%d %s\n", + z3950_apduno, timestamp (hook -> t, DELTA_FMT), + hook -> calling, hook -> srcport, hook -> called, hook -> dstport, + hook -> name), + fflush (stdout); + + gettimeofday (& last_apdu, NULL); + +#if (0) + fmemdmp (stdout, z3950, z3950_size, "Z39.50 APDU"); +#endif + + /* + * Yup! We have the APDU now. Try to print it + */ + odr_setbuf (printing, (char *) berbuffer, z3950_size, 0); + fflush (stdout); + + z_APDU (printing, & apdu, 0, 0); + fflush (stderr); + + odr_reset (printing); + printing -> buf = NULL; + } + + /* + * release memory previously allocated + */ + odr_destroy (decode); + odr_destroy (printing); +} diff --git a/src/ziffy.1 b/src/ziffy.1 new file mode 100644 index 0000000..2ee3f5e --- /dev/null +++ b/src/ziffy.1 @@ -0,0 +1,186 @@ +.\" +.\" -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +.\" ziffy.1 - a promiscuous Z39.50 APDU sniffer for Ethernet +.\" +.\" Copyright (c) 1998 R. Carbone - Finsiel S.p.A. +.\" -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- +.\" +.\" 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. +.\" +.TH ZIFFY 1 "0.0.2" "28 December 1998" "The Z39.50 Network Sniffer" +.SH NAME +ziffy \- capture and display Z39.50 APDUs on a live network +.SH SYNOPSYS +.na +.B ziffy +[ +.B \-alloptionshere +] +.br +.ti +6 +[ +.B \-i +.I interface +] [ +.B \-r +.I file +] +[ +.B \-s +.I snaplen +] +.br +.ti +8 +[ +.B \-T +.I type +] +[ +.B \-w +.I file +] +[ +.I expression +] +.br +.ad +.SH DESCRIPTION +\fBziffy\fR is a Z39.50 protocol analyzer based on the \fBLIBPCAP\fR, +the current standard Unix library for packet capturing. It can be started both in interactive +mode to capture, decode and show all information in the Z39.50 APDUs from a live network, +and in batch mode to analyze the APDUs off-line from a previously created file. +\fBziffy\fR uses the standard BPF network packet filter for more reliable capture mechanism. +An additional expression can be given on the command line to capture only packets +for which \fIexpression\fP is `true'. +By default \fBziffy\fR displays Z39.50 APDUs in a single-line summary form. In this format +only the name of the captured APDU is displayed in the summary line while the underlaying TCP, +IP, and Ethernet frames information are discarded. +Multi-lines are also supported if either of verbose modes are enabled. +This allows an high degree of monitoring, from simple checks of functional processes down +to full APDUs hexacimal dump for interoperability and debugging testing phases. +.SH OPTIONS +.TP +.B \-a +Attempt to convert network addresses to names. By default, \fBziffy\fR will ___not___ +resolve IP addresses to FQDN's. +.TP +.B \-c +Capture a maximum of \fIcount\fP number of APDUs and then exit. +.TP +.B \-e +Enable the display of the link-level header. +.TP +.B \-f +Do not traslate `foreign' internet addresses. +.TP +.B \-h +Display a help screen and quit. +.TP +.B \-i +Define the name of the interface to use for live packet capture. It should match +one of the names listed in \*(L"\fBnetstat \-i\fR\*(R" or \*(L"\fBifconfig \-a\fR\*(R". +By default \fBziffy\fR will automatically choose the first non-loopback interface it finds. +.TP +.B \-l +Make stdout line buffered. Useful if you want to see the data while capturing it. +.TP +.B \-n +Disable domain name qualification of host names. +.TP +.B \-p +Set the interface in non-promiscuous mode. Only packets addressed to the local host machine +will be captured. +.TP +.B \-r +Read packet data from \fIfile\fR. Currently, \fBziffy\fR only understands +\fBpcap\fR / \fBtcpdump\fR formatted files. +.TP +.B \-s +Truncate each packet after \fIsnaplen\fP bytes when capturing live data. +No more than \fIsnaplen\fR bytes of each network packet will be read into memory, +or saved to disk. +.br +While 68 bytes is adequate for lower-level protocol such as IP, ICMP, TCP and UDP, +it is inadeguate for Z39.50 and the exact cut-off is not easy to determine. +The default value is set to 10K which should be enough for most networks. +You should limit \fIsnaplen\fP to the smallest number that will allow you to +capture all the Z39.50 protocol information. +.br +Note that taking larger snapshots both increases the amount of time it takes to +process packets and, effectively, decreases the amount of packet buffering. +This may cause packets to be lost. +.TP +.B \-t +Sets the format of the packet timestamp displayed. + +INSERIRE QUI LA SBRODOLATA PER I VARI FORMATI DI PRESENTAZIONE + +.TP +.B \-v +Print the program version and exit. +.TP +.B \-w +Write the raw Z39.50 APDUs to \fIfile\fR rather than printing them out. +They can later be printed with the \-r option. +Standard output is used if \fIfile\fR is ``-''. +.TP +.B \-1 +Set verbose output at level 1. +.TP +.B \-2 +Set verbose output at level 2. +.TP +.B \-T +With this option you can filter out certain APDU types from beeing +shown. For example, if you only wanted to see all APDU's except +"init" and "sort" you could use: +.B % \fBziffy\fR -T init -T sort +Currently known APDU types are: +\fBinit\fR +\fBseach\fR +\fBpresent\fR +\fBscan\fR +\fBsort\fR + + +.Sp +A display filter can be entered into the strip at the bottom. It must +have the same format as \fBtcpdump\fR filter strings, since both programs use +the same underlying library. +.SH EXAMPLES +.LP +To print all APDUs arriving at or departing from \fIzeta.tlcpi.finsiel.it\fP: +.RS +.nf +\fBziffy host zeta.tlcpi.finsiel.it\fP +.fi +.RE +.SH OUTPUT FORMAT +The output of \fIziffy\fP is Z39.50 APDU dependent. The following +gives a brief description and examples of most of the formats. +.SH WARNING +To run +.I ziffy +you must be root or it must be installed setuid to root. +.SH "SEE ALSO" +tcpdump(1), pcap(3), xasn1(3), yaz(7), snacc(3) +.SH NOTES +The latest version of \fBziffy\fR can be found at +\fBhttp://zeta.tlcpi.finsiel.it/ziffy\fR +.SH AUTHOR +Rocco Carbone +.SH BUGS +Please send bug reports to the author + diff --git a/src/ziffy.c b/src/ziffy.c new file mode 100644 index 0000000..c0743a1 --- /dev/null +++ b/src/ziffy.c @@ -0,0 +1,475 @@ +/* + * -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + * ziffy.c - a promiscuous Z39.50 APDU sniffer for Ethernet + * + * Copyright (c) 1998-2001 R. Carbone + * -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- + * + * 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. + */ + + +/* + * Operating System include files + */ +#include +#include +#include +#include +#include + +#include +#if HAVE_SYS_TIME_H +#include +#endif +#include + +#include + +#include "pcap.h" /* Packet Capture Library */ + +#include "apdu.h" + + +/* + * external + */ +z3950apdu * pduhook (const struct pcap_pkthdr * h, const u_char * p); + + +#if defined(HAVE_XASN1) +void please_finsiel_help_me (z3950apdu * hook); +#endif /* HAVE_XASN1 */ + +#if defined(HAVE_YAZ) +void please_yaz_help_me (z3950apdu * hook); +#endif /* HAVE_YAZ */ + +#if defined(HAVE_SNACC) +void please_snacc_help_me (z3950apdu * hook); +#endif /* HAVE_SNACC */ + + +/* + * global variables + */ +time_t now; /* current time */ +time_t start_time; /* time the program was started */ +time_t firstapdu_time; /* time the first APDU was received */ +time_t laststapdu_time; /* time the last APDU was received */ + +unsigned long int z3950_apduno = 0; /* # of z3950 apdus so far received */ +u_char * z3950 = NULL; /* pointer to the last apdu received */ +int z3950_size = 0; /* and its size */ + +/* + * I currently tested the program at home in a null networked environment + * and on ethernet 10M lan. the following variable keeps the data-link + * encapsulation type. more info in net/bpf.h + */ +int dlt = -1; + +int aflag = 0; /* attempt to convert numeric network addresses to FQDN */ + +int ethflag = 0; +int ipflag = 0; +int tcpflag = 0; +int z3950flag = 0; + + +/* + * Length of saved portion of packet + */ +#define DEFAULT_SNAPLEN 65536 /* This should be enough... */ +static int snaplen = DEFAULT_SNAPLEN; + +#define DEFAULT_MAXAPDUS -1 /* that means indefinite */ +static int maxapdus = DEFAULT_MAXAPDUS; + +/* + * A handler for pcap, it needs to be global because there is no other way to + * pass it to the signal handler, the same can be said about the file descriptor + * for SOCK_PACKET. + */ +pcap_t * ph = NULL; + + +/* + * package info + */ +static char __copyright__ [] = "Copyright (c) 1998-2001"; +static char __author__ [] = "R. Carbone "; +static char __version__ [] = "Version 0.0.3"; +static char __released__ [] = "June 2001"; + + +char ebuf [PCAP_ERRBUF_SIZE] = {0}; +struct pcap_stat pcapstats = {0}; + +/* + * signal handler + */ +void on_signal (int signo) +{ + /* + * time for statistics + */ + if (pcap_stats (ph, & pcapstats) != 0) + { + printf ("Cannot get the statistics due to %s\n", ebuf), + exit (-1); + } + else + { + printf ("\n\n"); + + printf ("%u packets received by decoder\n", pcapstats . ps_recv); + printf ("%u packets dropped by kernel\n", pcapstats . ps_drop); + } + + fflush (stdout); + + /* + * bye bye ! + */ + pcap_close (ph); + + exit (0); +} + + + +/* + * You are welcome! + */ +void welcome (char * progname) +{ + time_t now = ((time_t) time ((time_t *) 0)); + char * nowstring = ctime (& now); + struct utsname machine; + + nowstring [24] = '\0'; + uname (& machine); + + printf ("This is %s %s of %s\n", progname, __version__, __released__); + printf ("%s %s\n", __copyright__, __author__); + printf ("Started at %s on %s\n\n", nowstring, machine . nodename); + printf ("\n"); + fflush (stdout); + fflush (stderr); +} + + +/* + * Wrong. Please try again accordingly to .... + */ +void usage (char * progname) +{ + welcome (progname); + + printf ("Usage: %s [--help] [--version]\n\n", progname); + printf ("Options:\n"); + printf (" h, --help display this help and exit\n"); + printf (" v, --version output version information and exit\n"); + + printf (" , -- print filter code\n"); + printf (" , -- print ethernet header\n"); + printf (" , -- try to resolve ip addresses\n"); + printf (" , -- remove domains from printed host names\n"); + printf (" , -- don't translate _foreign_ IP address\n"); + printf (" , -- print packet arrival time\n"); + + printf (" s, --snaplen \n"); + printf (" N, --non-promiscuous capture APDUs addressed to the host machine\n"); + printf (" C, --maxcount capture maxcount APDUs and then terminate\n"); + + printf (" D, --dropped-packets display number of packets dropped during capture\n"); + fflush (stdout); +} + + +/* + * This is really the `main' function of the sniffer. + * + * Parse the incoming APDU, and when possible show all pertinent data. + * + * 'h' is the pointer to the packet header (independent from interfaces) + * 'p' is the pointer to the packet data + * 'caplen' is the number of bytes actually captured + * 'length' is the length of the packet off the wire + */ +void parse_pdu (u_char * user_data, + const struct pcap_pkthdr * h, + const u_char * p) +{ + z3950apdu * hook; + int done = 0; + + if (! (hook = pduhook (h, p))) + return; + + /* + * update the descriptor of the apdu + */ + hook -> t = & h -> ts; + hook -> calling = srchost (); + hook -> srcport = srcport (); + hook -> called = dsthost (); + hook -> dstport = dstport (); + +#if defined(HAVE_XASN1) + if (! done) + please_finsiel_help_me (hook); + done = 1; +#endif /* HAVE_XASN1 */ + +#if defined(HAVE_YAZ) + if (! done) + please_yaz_help_me (hook); + done = 1; +#endif /* HAVE_YAZ */ + +#if defined(HAVE_SNACC) + if (! done) + please_snacc_help_me (hook); + done = 1; +#endif /* HAVE_SNACC */ +} + + +/* + * Oh no! yet another main here + */ +int main (int argc, char * argv []) +{ + int option; + const char * optstr = "hvac:ef:i:lnprs:twxz"; + char *optarg; + + char * progname; + + char * interface = NULL; + char * filename = NULL; + + char * filter = NULL; + struct bpf_program program = {0}; + bpf_u_int32 network = {0}; + bpf_u_int32 netmask = {0}; + + + /* + * notice the program name + */ + progname = strrchr (argv [0], '/'); + if (! progname || ! * progname) + progname = * argv; + else + progname ++; + + /* + * Parse command-line options + */ + while ((option = options(optstr, argv, argc, &optarg)) != -2) + { + switch (option) + { + default: + usage (progname); + return (-1); + + case '?': + printf ("%s: unrecognized option %c\n", progname, optopt); + usage (progname); + return (-1); + + case ':': + printf ("%s: missing parameter %c\n", progname, optopt); + usage (progname); + return (-1); + + case 'h': + usage (progname); + return (0); + + case 'a': + aflag = 1; + break; + + case 'c': + maxapdus = atoi (optarg); + if (maxapdus <= 0) + printf ("malformed max apdus counter %s", optarg), maxapdus = DEFAULT_MAXAPDUS; + break; + + case 'e': + ethflag = 1; + break; + + case 'f': + filename = strdup (optarg); + break; + + case 'i': + interface = strdup (optarg); + break; + + case 'l': + break; + + case 'n': + break; + + case 'p': + break; + + case 'r': + break; + + case 's': + snaplen = atoi (optarg); + if (snaplen <= 0) + printf ("malformed snaplen %s", optarg), snaplen = DEFAULT_SNAPLEN; + break; + + case 't': + tcpflag = 1; + break; + + case 'w': + break; + + case 'x': + ipflag = 1; + break; + + case 'z': + z3950flag = 1; + break; + } + } + + /* + * You are welcome + */ + welcome (progname); + + + /* + * build a string from all remaining arguments + */ + filter = NULL; + { + int roomsize = 0; + while (optind < argc) + { + roomsize += (strlen (argv [optind]) + 1 + 1); + if (filter) + { + strcat (filter, " "); + filter = (char *) realloc (filter, roomsize); + strcat (filter, argv [optind ++]); + } + else + { + filter = (char *) malloc (roomsize); + strcpy (filter, argv [optind ++]); + } + } + } + + + /* + * find a suitable interface, if i don't have one + */ + if (! filename && ! interface && ! (interface = pcap_lookupdev (ebuf))) + { + printf ("No suitable interfaces found, please specify one with -i\n"); + exit (-1); + } + + + if ((getuid () && geteuid ()) || setuid (0)) + { + printf ("Sorry, you must be root in order to run this program.\n"); + exit (-1); + } + + /* + * time to initialize the libpcap + */ + ph = filename ? pcap_open_offline (filename, ebuf) : + pcap_open_live (interface, snaplen, 1, 1000, ebuf); + + if (! ph) + printf ("Cannot initialize the libpcap package due to %s\n", ebuf), + exit (-1); + + /* + * get the interface network number and its mask + * (unless we are reading data from a file) + */ + if (! filename && pcap_lookupnet (interface, & network, & netmask, ebuf) < 0) + printf ("Cannot lookup for the network due to %s\n", ebuf), + exit (-1); + + /* + * determine the type of the underlying network and the data-link encapsulation method + * (unless we are reading data from a file) + */ + dlt = pcap_datalink (ph); + + if (! filename && dlt != DLT_NULL && dlt != DLT_IEEE802 && dlt != DLT_EN10MB) + printf ("Unsupported data-link encapsulation %d\n", dlt), + exit (-1); + + /* + * compile an optional filter into a BPF program + */ + if (filter && pcap_compile (ph, & program, filter, 1, netmask) == -1) + printf ("Cannot compile the filter %s\n", filter), + exit (-1); + + /* + * apply the filter to the handler + */ + if (filter && pcap_setfilter (ph, & program) == -1) + printf ("Cannot set the filter %s\n", filter), + exit (-1); + + /* + * announce to the world + */ + printf ("%s %s: listening on %s\n", progname, __version__, interface); + fflush (stdout); + + /* + * Setup signal handlers + */ + signal (SIGTERM, on_signal); + signal (SIGINT, on_signal); + + + /* + * Go for fun! and handle any packet received + */ + if (pcap_loop (ph, -1, parse_pdu, NULL) == -1) + printf ("%s: error while capturing packets due to %s\n", progname, pcap_geterr (ph)), + exit (-1); + + pcap_close (ph); + + + return (0); +}