From e80c331ea4fa31c903d03f533ec7ce02c454b6d3 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Tue, 10 Mar 2009 21:59:27 +0100 Subject: [PATCH] First. --- .gitignore | 11 + AUTHORS | 28 +++ COPYING | 340 +++++++++++++++++++++++++++++++ Makefile.am | 19 ++ NEWS | 30 +++ README | 16 ++ README.old | 135 +++++++++++++ buildconf.sh | 125 ++++++++++++ configure.ac | 79 ++++++++ debian/changelog | 6 + debian/control | 18 ++ debian/rules | 107 ++++++++++ debian/yaz-ziffy.copyright | 34 ++++ debian/yaz-ziffy.install | 1 + debian/yaz-ziffy.manpages | 1 + src/.cvsignore | 5 + src/ANNOUNCEMENT-1 | 24 +++ src/FAQ | 95 +++++++++ src/HACKING | 36 ++++ src/Makefile.am | 18 ++ src/NEWS | 5 + src/TODO | 16 ++ src/apdu.c | 180 +++++++++++++++++ src/apdu.h | 70 +++++++ src/fmemdmp.c | 106 ++++++++++ src/hooks.c | 317 +++++++++++++++++++++++++++++ src/yaz.c | 145 ++++++++++++++ src/ziffy.1 | 186 +++++++++++++++++ src/ziffy.c | 475 ++++++++++++++++++++++++++++++++++++++++++++ 29 files changed, 2628 insertions(+) create mode 100644 .gitignore create mode 100644 AUTHORS create mode 100644 COPYING create mode 100644 Makefile.am create mode 100644 NEWS create mode 100644 README create mode 100644 README.old create mode 100755 buildconf.sh create mode 100644 configure.ac create mode 100644 debian/changelog create mode 100644 debian/control create mode 100755 debian/rules create mode 100644 debian/yaz-ziffy.copyright create mode 100644 debian/yaz-ziffy.install create mode 100644 debian/yaz-ziffy.manpages create mode 100644 src/.cvsignore create mode 100644 src/ANNOUNCEMENT-1 create mode 100644 src/FAQ create mode 100644 src/HACKING create mode 100644 src/Makefile.am create mode 100644 src/NEWS create mode 100644 src/TODO create mode 100644 src/apdu.c create mode 100644 src/apdu.h create mode 100644 src/fmemdmp.c create mode 100644 src/hooks.c create mode 100644 src/yaz.c create mode 100644 src/ziffy.1 create mode 100644 src/ziffy.c 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); +} -- 1.7.10.4