net-acct-0.71-glibc2/ 40755 1750 144 0 6601002216 13247 5ustar phirateusersnet-acct-0.71-glibc2/README100644 1750 144 22465 6767070734 14304 0ustar phirateusersNET accounting for Linux and Solaris ==================================== *** NOTE: This is the original README file from version 0.5. Since the author, Ulrich Callmeier, has turned over development to the community, please do not send comments or bug reports to him anymore. The current maintainer is Richard Clark and the latest version of net-acct can be found at http://richard.iguana.co.nz/net-acct Thanks. Short description ----------------- This package logs network traffic. It provides a daemon (nacctd) that logs all traffic passing the machine it runs on (similiar to what tcpdump does). Capability is provided to associate traffic to slip/ppp users in case you run a slip/ppp server. Why would you want to use this? ------------------------------- - You are providing IP to customers and want to charge them based on the traffic they generate. - You are a statistics freak and want to see how much of your network traffic is for NetNews, FTP, WWW etc. Usage/Installation ------------------ If you don't want to compile for Linux, please set ARCH to an appropriate value before starting compilation. At the moment, besides Linux only pcap-solaris is supported. 1) go to source directory [e.g.: cd src] 2) do a "make" you must have your kernel sources installed properly to do this [e.g.: make] 3) copy naccttab.sample to /etc/naccttab this is the config file for pcap use naccttab.sample.pcap [e.g.: cp naccttab.sample /etc] 4) tune the options in naccttab to your needs the sample file is heavily documented so this should be easy 5) install nacctd in /usr/sbin or whereever you like [e.g.: cp nacctd /usr/sbin] 6) start nacctd [e.g.: /usr/sbin/nacctd] 7) subscribe to the net-acct-announce mailing list if you intend to use this on a regular basis (see below) Please read the rest of this README before sending me questions about usage/installation. Feel free to email me however if you read this file and still have a question. Contributions ------------- There is a contrib directory. It's very small yet, but it's a beginning. If you develop anything that has to do with nacctd and think someone else could use it or learn from it, please consider sending it to me for inclusion into the next release. Usage ----- You can control nacctd with signals. Here is what the signals do (one might call this abuse of signals ;-): SIGINT ends daemon SIGTERM ends daemon SIGUSR1 increases debugging level SIGUSR2 turns off debugging SIGWINCH prints some kind of version id SIGTSTP disables writing to file SIGCONT enables writing to file The last two (TSTP and CONT) are useful for an automated archival of the logfiles without terminating the daemon. Just send a SIGTSTP before moving the logfile and send a SIGCONT when you are done. Output ------ The level of detail of output is now configurable. At maximum detail you'll get a logfile with lines like this: Sample line: 786476591 6 193.98.158.1 119 192.76.152.9 2072 3 5370 eth0 unknown 1: time in seconds since 1.1.1970 (standard unix way of giving time) 2: ip protocol, you can look this up in /etc/protocols 1 is icmp, 6 is tcp, 17 is udp 3: source ip address 4: source port, you can look this up in /etc/services, if it's a wellknown port 5: destination ip address 6: destination port 7: packets count 8: size of data 9: device over which the packet was received/sent 10: associated user in case of a slip/ppp link this will always be "unknown" for ethernet devices and such If the type is an ICMP message, field 4 is the ICMP message type and field 6 ist the ICMP message code. If you enabled HUMAN_READABLE_TIME, field 1 will be a string of the form yy/mm/dd hh:mm:ss If you enabled TCP_USER_INFO, field 10 can be of the form , where uid is the user id of the user that is associated with this tcp connection. This only works for local tcp connections. All of the fields 2 to 10 can be switched off. This will reduce the amount of log entries generated. Please note that for forwarded packets there will be one line for EACH interface the packet passed. So if you are running this on your slip-server you will get all the traffic over the slip interfaces TWICE, once for the sl* devices and once for the eth* device. The same goes for ppp and generally for all forwarded traffic. You can specify with 'notdev' entries, which interfaces you dont want to see in the log. The enclosed perl script will make the output more readable. Please note that this script is merely an example. It will only work if you disable only field 7. I you come up with something better or just something different please let me know, so I can distribute it with the next version in a contrib-directory. Association of traffic with slip/ppp users --------------------------------------- From version 0.4 on there is a mechanism provided to deal with all kinds of ip-number -> user assignment. I'll explain it with an example. Say you are an internet provider, you are giving away slip-access with adresses dynamically assigned from your class-C net 193.97.238.0 You want to associate the generated traffic with the respective slip-user so you can charge them. Your dialin host has the address 193.97.238.3 and your mail/ftp-server has the adress 193.97.238.1. To get the desired information you will have to add these lines to your naccttab: dynamicnet 193.97.238.0 255.255.255.0 This tells nacctd that the addresses on this network should be looked up. You don't want to have your dialin host and your mail-server looked up, so you specify: exclude-name-lookup 193.97.238.1 255.255.255.255 exclude-name-lookup 193.97.238.3 255.255.255.255 You can specify whole networks to be excluded from name-lookup in case you have your network subnetted. In this example we specify two single hosts (netmask 255.255.255.255). Then you have to specify the directory where the files for each address will be put: dynamicip /var/run This tells nacctd that it should expect a file with the name identical to the address. Its contents are the name of the slip/ppp user. So you will have to modify your slip.login and slip.logout scripts. Here are two examples: -------------------- SLIP.LOGIN -------------------- #!/bin/sh - # generic login file for a slip line. sliplogin invokes this with # the parameters: # 1 2 3 4 5 6 7 8-n # slipunit ttyspeed pid loginname local-addr remote-addr mask opt-args # /sbin/ifconfig $1 $5 pointopoint $6 mtu 1500 -trailers up /sbin/route add $6 $1 /sbin/arp -s $6 00:xx:xx:xx:xx:xx pub echo $4 > /var/run/$6 # this is for nacctd exit 0 -------------------- SLIP.LOGIN -------------------- -------------------- SLIP.LOGOUT -------------------- #!/bin/sh - # # slip.logout # /sbin/ifconfig $1 down /sbin/route del $5 /sbin/arp -d $5 rm /var/run/$5 # this is for nacctd exit 0 -------------------- SLIP.LOGOUT -------------------- If you use ppp or another slip package you will have to come up with something similiar. For pppd users: use the "ipparam" option to pass the $LOGNAME parameter to the "ip-up" and "ip-down" scripts. But make sure you use it on the command line, like "/usr/sbin/pppd modem ipparam $LOGNAME etc." and NOT in the /etc/options" file, or it won't work. Thanks for this hint to Eugenio Pierno If you have any further questions about this please ask me. I know this documentation is bad - I'd really apreciate someone writing something better. Mailing lists ------------- There are two mailing lists related to this package. One is for discussion and questions, the other one is an announcement-only list for the announcement of new versions and important bug fixes. Mail majordomo@pythia.lunetix.de for more info. To subscribe to the announcement list send mail to majordomo@pythia.lunetix.de with a body of "subscribe net-acct-announce". You should really consider this if you are using this package. The list is very low volume, so you won't get swamped with mail. To subscribe to the discussion list send mail to majordomo@pythia.lunetix.de with a body of "subscribe net-acct". There has not been much discussion going on in the last time, so don't worry if you don't receive any messages after subscribing. Notes ----- There is a problem with 1.2.13 kernels: when it soft-resets the card the promiscous flag is not saved... According to Donald Becker this is fixed in newer kernels. Bug reports ------------- As this is alpha software it most likely contains some bugs. To do an actually useful bug report please send me the following information - your setup - hardware (ethercard etc.) - software (kernel, libc, etc.) - network layout - what you did and what happened - relevant parts of a debugging output file with debuglevel set to at least 1023. If you can't find the relevant parts, please ask me before mailing huge files. - anything else you think is useful to trace down the bug If you did look at the source and actually found something that looks like a bug, don't bother to send just a short notice. I know this myself, often I fix a small bug in other packages and then I'm just too lazy to make a full-scale bug report. I'm interested in any suggestions on how to improve this software, please mail them to me. If anyone volunteers to write better documentation or to improve this readme (maybe fix all the bad english) I'd be very happy to hear from you. net-acct-0.71-glibc2/CHANGES100644 1750 144 6672 6767070747 14405 0ustar phirateusersFrom 0.1 to 0.1a - removed a silly bug that prevented the lockfiles for dumping not to be erased when the dump was empty. This left a lot of empty lockfiles in /tmp. Arghhhh. From 0.1a to 0.2 - removed a race condition in the signal handling (SIGCHLD). This was introduced when I added the dump process, so it is possible for both children to exit at the same time. This resulted in a zombie dump process on slow or heavy loaded machines. - Added pid file creation (/var/run/nacctd.pid a la crond) and detection. From 0.2 to 0.3 - made output more configurable. Thanks for inspiration from Scott Penrose . From 0.3 to 0.4 - added a new way of handling ip - user assignment. Thanks for the idea and help in debugging from Bart Kindt - added a dontignore option - cleaned up debugging output - made debugging output more configurable - default for ignoremask is now really 255.255.255.255 as mentioned in the documentation, , i.e. don't ignore anything. You might want to add a ignoremask 255.255.255.0 to existing naccttabs, to match the previous default - fixed a few races in child/signal handling From 0.4 to 0.5 - please notice my new email-address uc@coli.uni-sb.de - there is now support for libpcap. I've tested this with libpcap-0.2 and Solaris 2.4. It should work with other Unices with small changes. - enhancements by Bernd Eckenfels (ecki@lina.inka.de) - new notdev-option to disable logging for certain devices - no-detach option (-D) to allow for running from inittab - added count column for a packet count - you can now disable the user column in the output - memory usage reduced for "unknown"-case - support for token-ring and ISDN (thanks to Olaf (root@sel05.bertelsmann.de) for token ring and to Herbert Rosmanith and the various people on the isdn4linux-mailinglist for ISDN) - fixed a bug with the dynamic-net feature. Thanks to Andreas Heilwagen and Sebastian Schaefer for finding this one. I already reported this bug on the mailing-list. - enhancements by Vlad Seriakov - compile-time option to make time column human readable - Get username for local tcp connections. This is a compile-time option from 0.5 to 0.6 (first 'unofficial' release) - new configuration file option: hostlimit Limits packet logging to ONLY the specified IP address(es). Overrides all other limits such as ignorenet etc. Multiple hostlimit tags can be given. Useful for monitoring colocated hosts, dedicated P-to-P links, etc. mutually exclusive with the iflimit tag. - added hash table patches from Tom Brown with configurable hash size in Makefile (default 256) - iflimit tag (based on patches from Nigel Metheringham ) allows you to limit which interfaces we monitor for traffic. similar to the hostlimit tag and mutually exclusive with it. - masquerade support added, also contributed by Nigel Metheringham - SIGHUP now causes nacctd to reread the config file from 0.6 to 0.7: - revised docs and Makefile slightly (added -O2 etc) - increased default hash table size and improved algorithm - added ICMP masquerading and masq bug fixes - fixed bug with multiple notdev definitions in naccttab - added PLIP header entry to naccttab.sample - fixed disable entry in naccttab from field 8 to 7 for 0.5 compatibility - fixed problem with promisc devices not being reinitialized on SIGHUP net-acct-0.71-glibc2/COPYING100644 1750 144 43076 6174231405 14442 0ustar phirateusers GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 675 Mass Ave, Cambridge, MA 02139, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS Appendix: How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. net-acct-0.71-glibc2/src/ 40755 1750 144 0 6767071051 14056 5ustar phirateusersnet-acct-0.71-glibc2/src/ChangeLog100644 1750 144 26130 6767071032 15746 0ustar phirateusersMon Sep 13 15:30:00 1999 Richard Clark * process.c: fixed month-off-by-one bug in Human Readable time. Fri Sep 17 23:20:00 1998 Mark Knox * config.c: patch from Robert Vogelgesang to fix multiple notdev bugs * process.c: fixed masq code typos and added ICMP masquerading - patch submitted by Thorsten Kuehnemann fixed bug in SIGHUP handler where promisc devices were not being reinitialized thanks to Robert Vogelgesang for reporting this one as well. Mon Jun 29 20:39:00 1998 Mark Knox * process.c: increased default hash table size to 4096 improved HASH function * Makefile: added -O2 to compile flags * README: updated mailing list addresses etc Thu May 7 10:24:00 1998 Mark Knox * process.c: added hash table patch from Tom Brown added remap_masq function changed SIGHUP handling to re-read config file * netacct.h: added iflist to struct config added masq support from Nigel Metheringham * capture-linux.c: added code for iflist (based on patches from Nigel Metheringham * netacct.h: added struct mon_host_struct for hostlimit * config.c: added case to parser for hostlimit keyword * capture-xxx.c: added code to packet_loop for hostlist Sun Jul 14 19:29:42 1996 Ulrich Callmeier * netacct.h: Naming fixes * process.c: Changed some of the lck-debug messages to level DBG_ANNOYING Some changes in output format * capture-linux.c: Include ip_icmp.h * naccttab.sample: Updated info about runtime header information configuration * capture-linux.c: Made header information runtime configurable * config.c: Length of name prefix for header information calculated while reading config file * netacct.h: Added length field to headerdat * config.c: Added runtime configuration of header information * process.c: More detailed debugging messages for lck Format for human readable time changed * README: Various updates/fixes to the documentation * naccttab.sample: Added runtime header configuration * netacct.h: Added runtime configuration of header information * netacct.h: Initial integration of patches by Vlad (TCP_USER_INFO, HUMAN_READABLE_TIME) * process.c: Initial integration if patches by Vlad Seriakov (TCP_USER_INFO, HUMAN_READABLE_TIME) * capture-linux.c: Some syntax errors with new offsets fixed Initial integration of patches by Vlad Seriakov * process.c: Integrated Bernd's patches * naccttab.sample: Changes by Bernd, adaptions for his extensions * main.c: Integrated patch of Bernd (-D no detach for inittab) * config.c: Integrated notdev-patch of Bernd * capture-linux.c, netacct.h, README: Integrated patches of Bernd * naccttab.sample: Initial revision * capture-linux.c: Added offsets for tr and isdn devices. Decided to make this configurable at runtime. * capture-linux.c: Corrected bug found by Andreas Heilwagen and Sebastian Schaefer, used dynamicaddr instead of otheraddr incorrectly. Sun Jun 4 19:07:41 1995 Ulrich Callmeier * capture-linux.c: Fixed two bugs with new dynamic ip stuff. Sun May 28 20:18:55 1995 Ulrich Callmeier * netacct.h: Prefixed variables macro DEBUG. Not doing this caused obscure bugs in the debugging output. * README: Various fixes and updates Sun May 28 16:32:28 1995 Ulrich Callmeier * utils.c: Portability fixes * process.c: Removed a few include files that are already included via netacct.h Split up capture.c into process.c and capture-$(ARCH).c Removed variables ignorenet, dynadat Removed functions init_capture, exit_capture, onignorelist, check_user_dev2line, check_user_dynamicip, handle_ip Reworked do_acct to use architecture dependend packet_loop() Added TELL_WAIT* functions to fix races in child/signal handling. See Stevens APUE 8.8 Fixed bug in SIG_CHLD handling - didn't check return value from waitpid before testing errno, so if errno accidentially was set to ECHILD before... go figure... Added debugging output in various places. * main.c: New argument to macro SETSIG to set flags. Not really used until now. Added typecast for pid output * daemon.c: Added debugging output to daemon_stop Changed linux/time.h into sys/time.h for portability * netacct.h: Improved portability by changing some of the includes Changed DEFAULT_IGNOREMASK to 255.255.255.255, so it matches the documentation Some more globals due to the splitting of capture.c into process.c and capture-$(ARCH).c Some #ifdef linux added for linux specific parts * config.c: added option excludenamelookup (keyword "exclude-name-lookup") * capture-linux.c: Split up capture.c in process.c and capture-$(ARCH).c Removed variables running, packets, plist, olist, plistsize, olistsize, lck, writing, dumping, writepid, dumppid, may_write, err_delay, max_err_delay, now, ignorenet, list_compares, list_lookups Removed functions reopen_sockets, do_acct, register_packet, do_write_list, write_list, dump_curr_list, child_finished, alarm_handler, write_log, signal_debug, signal_ignore do_acct is now split up in packet_loop (architecture dependend) and do_acct (in process.c) implemented Bart's suggestions for new style dynamic ip handling (excludenamelookup option and checking other addr if first fails) Tue May 23 19:24:12 1995 Ulrich Callmeier * main.c: Removed global capture_sd * process.c, capture-linux.c: Initial revision Mon May 22 22:28:43 1995 Ulrich Callmeier * netacct.h: Minor fixes * main.c, config.c: Fixed unbuffering of debug output file * capture.c: Added new style dynamic ip handling * capture.c: Cleaned up debugging handling Prepared new style dynamic ip handling Added dontignore handling * config.c: Initialize debugname * config.c: Added parsing of dontignore, dynamicip, debugfile, dynamicnet * netacct.h: Cleaned up debugging handling, addition DBG_*, macro DEBUG Prepared for new style handling of dynamic ip * main.c: Cleaned up debugging handling * daemon.c: Added fclose(dbg_file) for new style debugging output Sun May 21 12:54:44 1995 Ulrich Callmeier * README: Erklaert, wie man zur Discussion-Liste subscribed. minor fixes Wed Apr 12 19:23:34 1995 Ulrich Callmeier * capture.c: Removed unused variable tmp in do_write_list Wed Apr 12 19:13:43 1995 Ulrich Callmeier * capture.c: You can now disable certain fields of output. * config.c: Added parsing of disable statememts * README: Updated for 0.3 * netacct.h: Added disabling of certain fields Wed Mar 1 17:00:56 1995 Ulrich Callmeier * README: For release 0.2 * main.c: Feature added: a pid file (in /var/run) is created on startup and deleted on exit. On startup we check for the existence of such a file. If one exists and contains the pid of a process still running we quit * daemon.c: unlink pid-file on exit * capture.c: Made dumppid and writepid volatile. Added some debugging output. Messages about corrected clock only if difference >5 seconds. * main.c: Using SA_RESTART was a bad idea. Removed it again. Mon Feb 27 16:07:17 1995 Ulrich Callmeier * capture.c: Fixed a bug in SIGCHLD handling. We have to loop until waitpid return 0, not just check once. Removed silly reinstallation of signal handlers. This is 1995... * main.c: We use sigaction instead of signal to set up our signal handlers. Interrupted systemcalls are to be restarted. Tue Feb 21 16:21:49 1995 Ulrich Callmeier * README: Bumped up to version 0.1. Tue Feb 21 16:18:58 1995 Ulrich Callmeier * capture.c: Added three missing unlink(tmpn). This caused a lot of empty lockfiles to be left in /tmp. Arghhhh. * capture.c: Added some if(debug_level > x) to prevent unnecessary syslog output. Mon Feb 20 23:35:57 1995 Ulrich Callmeier * capture.c: Support for delayed write of data: Added dump process Added data timestamping Seperated out do_write_list from write_list. do_write_list is used by write_list and dump_curr_list. Cleaned up alarm signal handler, now in an own routine alarm_handler This maintains an internal clock (in variable now) Removed unneccessary globals flush and fname now that cfg is global * main.c: Cleaned up signal handling: New handler alarm_handler for SIGALRM Added comments Save old dumpfiles on startup (save_dumpfile) Added check if caller is superuser on startup. Exit with appropriate message otherwise. Thanks to Randolf Skerka for the hint. * config.c: Support for dumpname and fdelay. Added check if filename and dumpname are given. * daemon.c: Changed call to write_log to force a complete flush. * netacct.h: Support for holding entries in memory at least a certain time: Added fdelay to struct config. Added default define for fdelay. Added dumpname to struct config. Added field when to struct ipdata (to record last use of entry). Cleaned up alarm handler. Changed prototype of write_log accordingly. Added prototype for new alarm_handler. * daemon.c: Adapted call to write_log to new declaration. Mon Feb 20 16:00:20 1995 Ulrich Callmeier * config.c: Added support for parsing "line" statements. * main.c: Added dev2line global. * netacct.h: Added (preliminary) support to associate slip/ppp packets with users. * capture.c: Added (preliminary) support for associating slip/ppp packets with users. * README: Updated to newest release. * README: Initial revision Sun Feb 19 22:11:47 1995 Ulrich Callmeier * capture.c: Adapted init_capture and exit_capture to new handling of devices to set into promiscous mode. Minor cleanups. * main.c: Moved signal setups to function signal_setup. Removed struct capture. * config.c: Adapted read_config to deal with new linked list of promisc devices. Provided sensible defaults for all of the values. These are imported from netacct.h. * netacct.h: Cleaned up promiscious device handling. Got rid of struct capture. This is now in struct promisc_device. There is now a linked list of devices to put into promiscous mode. This can be empty. Provided sensible defaults for some of the naccttab settings (DEFAULT_* defines) Removed define for version. This is now done with RCS. Configuration information is now a global. * daemon.c: Removed check for capture -> reset. This is now done in exit_capture. Wed Feb 8 15:18:05 1995 Ulrich Callmeier * capture.c: Ifdeffed ignoring of unencapsulated packets. A better system has to be devised. Mon Jan 30 21:10:26 1995 Ulrich Callmeier * netacct.h, utils.c, main.c, daemon.c, config.c, capture.c: Initial revision under RCS net-acct-0.71-glibc2/src/Makefile100644 1750 144 2007 6600776012 15605 0ustar phirateusersifeq ($(ARCH),) ARCH = linux endif VPATH = ../ EXEC = nacctd # Configuration options # Uncomment for debugging output #DEBUG=-g -DDBG=1 # Uncomment for IP masquerade support #MASQ=-DREMAP_MASQUERADE # Size of the packet hash table (default 4096) HASH=-DHASHSIZE=4096 CFLAGS = -Wall -O2 -Wstrict-prototypes $(DEBUG) $(MASQ) $(HASH) OBJECTS = main.o daemon.o process.o utils.o config.o DISTSRC = ChangeLog Makefile capture-linux.c capture-pcap.c config.c daemon.c main.c nacctd naccttab.sample naccttab.sample.pcap netacct.h process.c utils.c LIBS = CC = gcc ifeq ($(ARCH),linux) OBJECTS := $(OBJECTS) capture-linux.o endif ifeq ($(ARCH),pcap-solaris) OBJECTS := $(OBJECTS) capture-pcap.o LIBS := $(LIBS) -lelf -lnsl -ldl -lsocket -lpcap CFLAGS := $(CFLAGS) -L/usr/local/lib endif all: $(EXEC) depend dep: for i in *.c;do $(CPP) -M $$i;done > .tmpdepend mv .tmpdepend .depend $(EXEC): $(OBJECTS) $(CC) -o $(EXEC) $(CFLAGS) $^ $(LIBS) clean: rm -f *.o $(EXEC) ifeq (.depend,$(wildcard .depend)) include .depend endif net-acct-0.71-glibc2/src/capture-linux.c100644 1750 144 34747 6766042010 17146 0ustar phirateusers/* * Network accounting * capture-linux.c - capture raw packets - linux version * (C) 1994, 1995 Ulrich Callmeier * 27/5/1998 - modified to use /etc/protocols instead of constants -mk */ #include #include #include "netacct.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include char *rcs_revision_capture_c = "$Revision: 1.9 $"; void handle_ip(unsigned char buf[], char *devname, char *user); static int capture_sd = -1; /* * New global constants from /etc/protocols replace #defines from protocols.h */ int IP_ICMP = 0; int IP_TCP = 0; int IP_UDP = 0; void init_capture() /* * 1) Open our capture socket * 2) Set all the promisc devices to promiscous mode * 3) Read essential protocol numbers from /etc/protocols - mk */ { struct ifreq ifr; struct promisc_device *p; struct protoent *pr; if ((capture_sd = socket (AF_INET, SOCK_PACKET, htons (ETH_P_ALL))) < 0) { syslog(LOG_ERR, "can't get socket: %m\n"); daemon_stop(0); } p = cfg -> promisc; while(p!=NULL) { strcpy (p -> oldifr.ifr_name, p -> name); if (ioctl (capture_sd, SIOCGIFFLAGS, &(p -> oldifr)) < 0) { syslog(LOG_ERR, "can't get flags: %m\n"); daemon_stop(0); } p -> reset = 1; ifr = p -> oldifr; ifr.ifr_flags |= IFF_PROMISC; if (ioctl (capture_sd, SIOCSIFFLAGS, &ifr) < 0) { syslog(LOG_ERR, "can't set flags: %m\n"); daemon_stop(0); } DEBUG(DBG_MISC, sprintf(dbg, "%s set to promiscous mode\n", p -> name)); p = p -> next; } if((pr=getprotobyname("tcp")) == NULL) { syslog(LOG_ERR, "Can't get TCP protocol entry.\n"); daemon_stop(0); } IP_TCP = pr->p_proto; if((pr=getprotobyname("udp")) == NULL) { syslog(LOG_ERR, "Can't get UDP protocol entry.\n"); daemon_stop(0); } IP_UDP = pr->p_proto; if((pr=getprotobyname("icmp")) == NULL) { syslog(LOG_ERR, "Can't get ICMP protocol entry.\n"); daemon_stop(0); } IP_ICMP = pr->p_proto; } void exit_capture(void) { struct promisc_device *p; /* do we have to check (capture_sd >= 0) ? */ p = cfg -> promisc; while(p != NULL) { if (ioctl (capture_sd, SIOCSIFFLAGS, &(p -> oldifr)) < 0) { syslog(LOG_ERR, "can't reset flags: %m\n"); } p = p -> next; } close (capture_sd); } inline int onnet(unsigned long int addr, struct ipnetwork *net) { return ((addr & net -> netmask) == net -> netnumber); } int onnetlist(unsigned long int addr, struct ipnetwork *netlist) { while(netlist!=NULL) { if(onnet(addr, netlist)) { return 1; } netlist = netlist -> next; } return 0; } struct dynadat *dynadat = NULL; char *check_user_dev2line(char *devname) /* * Find username corresponding to devname */ { struct dev2line *d2l; char *line; struct dynadat *dd; int found; d2l = dev2line; line = NULL; while(d2l!=NULL) { if(strcmp(d2l -> netinterface, devname)==0) { line = d2l -> line; break; } d2l = d2l -> next; } if(line == NULL) return NULL; dd = dynadat; found = 0; while(dd != NULL) { if(strcmp(dd -> netinterface, devname) == 0) { found = 1; break; } dd = dd -> next; } if(!found) { /* We don't have an entry for this device yet. Add one */ dd = malloc(sizeof(struct dynadat)); dd -> netinterface = strdup(devname); dd -> last_stat = 0; /* force reading of utmp */ dd -> mtime = 0; dd -> user = NULL; dd -> next = dynadat; dynadat = dd; } /* dd now points to the right dynadat entry */ /* maybe this is out of date, so we check */ if ((now - dd->last_stat) > FORCE_STAT_TIME ) { struct stat statbuf; /* it could be invalid, lets stat utmp */ if(stat(_PATH_UTMP, &statbuf)==0) { DEBUG(DBG_UTMP, sprintf(dbg, "%d: did a stat of %s\n",(int) now,_PATH_UTMP)); dd -> last_stat = now; if((statbuf.st_mtime - dd->mtime) > 0) { struct utmp *ut_rec; /* utmp record */ /* we have to wade through utmp */ DEBUG(DBG_UTMP, sprintf(dbg, "%d: wading through utmp %s\n",(int) now, _PATH_UTMP)); dd -> mtime = statbuf.st_mtime; while ((ut_rec = getutent())) { if ((ut_rec->ut_type == USER_PROCESS) && (ut_rec->ut_name[0] != '\000') && (strcmp(ut_rec->ut_line,line)==0)) { if(dd -> user) free(dd -> user); dd -> user = malloc(10); strncpy(dd -> user, ut_rec->ut_user, 8); dd->user[8] = 0; DEBUG(DBG_DYNAMIC, sprintf(dbg, "found %s for %s\n",dd->user, line)); break; } } endutent(); } } else { syslog(LOG_ERR,"couldn't stat %s: %m\n",_PATH_UTMP); return NULL; } } return dd -> user; } char *check_user_dynamicip(__u32 addr) /* * Find username corresponding to addr */ { struct dynadat *dd; int found; DEBUG(DBG_ANNOYING, sprintf(dbg, "check_user_dynamicip(%s)\n", intoa(addr))); dd = dynadat; found = 0; while(dd != NULL) { if(dd -> addr == addr) { found = 1; break; } dd = dd -> next; } if(!found) { /* We don't have an entry for this addr yet. Add one */ dd = malloc(sizeof(struct dynadat)); dd -> addr = addr; dd -> last_stat = 0; /* force reading of dir */ dd -> mtime = 0; dd -> user = NULL; dd -> next = dynadat; dynadat = dd; DEBUG(DBG_DYNAMIC, sprintf(dbg, "added entry for %s to dynadat list\n", intoa(addr))); } /* dd now points to the right dynadat entry */ /* maybe this is out of date, so we check */ if ((now - dd->last_stat) > FORCE_STAT_TIME ) { struct stat statbuf; /* it could be invalid, lets stat dir */ if(stat(cfg -> dynamicip, &statbuf)==0) { DEBUG(DBG_DYNAMIC, sprintf(dbg, "%d: did a stat of %s, last_stat was %d, mtime was %d\n",(int) now, cfg->dynamicip, (int) dd->last_stat, (int) dd -> mtime)); dd -> last_stat = now; if((statbuf.st_mtime - dd->mtime) > 0) { FILE *f; char *s; /* we have to read dir */ s = malloc(strlen(cfg->dynamicip) + 1 + 15 + 1 ); strcpy(s, cfg->dynamicip); strcat(s, "/"); strcat(s, intoa(addr)); DEBUG(DBG_DYNAMIC, sprintf(dbg, "%d: reading %s\n",(int) now, s)); if(dd -> user) free(dd -> user); dd -> user = NULL; dd -> mtime = statbuf.st_mtime; f = fopen(s, "r"); if(f == NULL) { /* syslog(LOG_ERR,"couldn't fopen %s: %m\n",s); */ DEBUG(DBG_DYNAMIC, sprintf(dbg, "%d: couldn't fopen %s: %s\n",(int) now, s, strerror(errno))); return NULL; } dd -> user = malloc(BUFSIZ); fgets(dd -> user, BUFSIZ, f); if(dd->user[strlen(dd->user)-1]=='\n') dd->user[strlen(dd->user)-1]='\0'; fclose(f); DEBUG(DBG_DYNAMIC, sprintf(dbg, "found %s for %s\n",dd->user, intoa(addr))); } } else { syslog(LOG_ERR,"couldn't stat %s: %m\n",cfg->dynamicip); return NULL; } } return dd -> user; } void packet_loop() { struct sockaddr saddr; int sizeaddr; unsigned char buff[1600]; unsigned char *buf; int hardheader; int length; static struct iphdr *tmp_iphdr; int type; int dynamicstyle; int do_user; __u32 dynamicaddr, otheraddr; char *user; struct promisc_device *p; struct headerdat *h; int found = 0; struct mon_host_struct *ptr; dynamicstyle = (dev2line != NULL) ? 1 : ((cfg->dynamicip != NULL) ? 2 : 0); buf = &buff[20]; while (running) { sizeaddr = 14; length = recvfrom (capture_sd, buf, 127, 0, &saddr, &sizeaddr); if (length == -1) { if(errno != EINTR) DEBUG(DBG_SYSCALL, sprintf(dbg, "recvfrom: %s\n", strerror(errno))); continue; } do_user = 0; p = cfg -> notdev; while(p!=NULL) { if (!strcmp(p -> name, saddr.sa_data)) { packets->notdev++; break; } p = p -> next; } if (p) continue; found = 0; if(cfg->iflist) { /* we specified at least one iflimit tag */ /* if we don't monitor this interface, bail now - mk */ for(p=cfg->iflist;p && !found;p=p->next) { if(!strcmp(p->name, saddr.sa_data)) found = 1; } if(!found) { packets->ignored++; continue; } } h = cfg -> headers; hardheader = -1; while (h) { if(strncmp(saddr.sa_data,h->name,h->l) == 0) { hardheader = h -> offset; if (h -> type != 0) type = buf[h -> type] * 256 + buf[h -> type + 1]; else type = ETH_P_IP; break; } h = h -> next; } if (hardheader == -1) { /* ASSUMES: interface - line just with ppp and slip etc. */ if(dynamicstyle == 1) do_user = 1; hardheader = 0; type = 0; packets->unenc++; #ifdef IGNORE_UNENC continue; /* ignore ppp/slip */ #endif } else { if(type != ETH_P_IP) { /* ETH_P_ARP, ETH_P_RARP, ETH_P_IPX, etc. */ packets->ignored++; continue; } } tmp_iphdr = (void *) (buf+hardheader); found = 0; if(cfg->hostlist) { /* we specified at least one hostlimit tag */ /* if we don't monitor this IP, bail now - mk */ for(ptr=cfg->hostlist;ptr && !found;ptr=ptr->next) { if(ptr->ipaddr == tmp_iphdr->saddr || ptr->ipaddr == tmp_iphdr->daddr) found = 1; } if(!found) { packets->ignored++; continue; } } if((tmp_iphdr->saddr & cfg->ignoremask) == (tmp_iphdr->daddr & cfg->ignoremask)) { packets->local++; continue; } else { if(onnetlist(tmp_iphdr->saddr,cfg->ignorenet) || onnetlist(tmp_iphdr->daddr, cfg->ignorenet)) { if(!(onnetlist(tmp_iphdr->saddr,cfg->dontignore) || onnetlist(tmp_iphdr->daddr, cfg->dontignore))) { if(debug_level & DBG_IGNORE) { char tmp[18]; strcpy(tmp, intoa(tmp_iphdr->saddr)); DEBUG(DBG_IGNORE, sprintf(dbg, "netignored: %s -> %s\n", tmp,intoa(tmp_iphdr->daddr))); } packets->netignored++; continue; } } packets->ip++; user = NULL; switch(dynamicstyle) { case 1: if(do_user) user = check_user_dev2line(saddr.sa_data); break; case 2: dynamicaddr = otheraddr = 0; if(onnet(tmp_iphdr->saddr, &cfg->dynamicnet)) { dynamicaddr = tmp_iphdr->saddr; if (onnet(tmp_iphdr->daddr, &cfg->dynamicnet)) otheraddr = tmp_iphdr->daddr; DEBUG(DBG_ANNOYING, sprintf(dbg, "source %s is on dynamicnet\n", intoa(dynamicaddr))); } else if (onnet(tmp_iphdr->daddr, &cfg->dynamicnet)) { dynamicaddr = tmp_iphdr->daddr; if(onnet(tmp_iphdr->saddr, &cfg->dynamicnet)) otheraddr = tmp_iphdr->saddr; DEBUG(DBG_ANNOYING, sprintf(dbg, "destination %s is on dynamicnet\n", intoa(dynamicaddr))); } if(dynamicaddr != 0) { if(onnetlist(dynamicaddr, cfg->excludenamelookup)) { DEBUG(DBG_ANNOYING, sprintf(dbg, "BUT: %s is excluded from name lookup\n", intoa(dynamicaddr))); dynamicaddr = otheraddr; otheraddr = 0; if(onnetlist(dynamicaddr, cfg->excludenamelookup)) { DEBUG(DBG_ANNOYING, sprintf(dbg, "prev. bug: %s is excluded from name lookup, too\n", intoa(dynamicaddr))); dynamicaddr = 0; } } if(dynamicaddr != 0) { user = check_user_dynamicip(dynamicaddr); if((user == NULL) && (otheraddr != 0)) { user = check_user_dynamicip(otheraddr); } } } break; } handle_ip(buf+hardheader, saddr.sa_data, user); } } } void handle_ip(unsigned char buf[], char *devname, char *user) { static struct iphdr *tmp_iphdr; static struct tcphdr *tmp_tcphdr; static struct icmphdr *tmp_icmphdr; unsigned short srcport, dstport; tmp_iphdr = (void *) &buf[0]; tmp_tcphdr = (void *) &buf[tmp_iphdr->ihl*4]; /* relevant headers of udphdr and tcphdr are identical */ tmp_icmphdr = (void *) &buf[tmp_iphdr->ihl*4]; if(tmp_iphdr->protocol == IP_UDP) { packets->ip_udp++; srcport = ntohs(tmp_tcphdr->source); dstport = ntohs(tmp_tcphdr->dest); } else if(tmp_iphdr->protocol == IP_TCP) { packets->ip_tcp++; srcport = ntohs(tmp_tcphdr->source); dstport = ntohs(tmp_tcphdr->dest); } else if(tmp_iphdr->protocol == IP_ICMP) { packets->ip_icmp++; srcport = tmp_icmphdr->type; dstport = tmp_icmphdr->code; } else { packets->ip_other++; srcport = dstport = 0; } register_packet(tmp_iphdr->saddr,tmp_iphdr->daddr,tmp_iphdr->protocol, srcport, dstport, ntohs(tmp_iphdr->tot_len), devname, user); } #ifdef TCP_USER_INFO /* Originally by Vlad Seriakov (vlad@torn.ktts.kharkov.ua) */ /* Adapted by Ulrich Callmeier */ int get_tcp_info(struct ipdata *ip, uid_t *uid) { FILE *procinfo; char buffer[1024]; int num, local_port, rem_port, d, state, tmout; long localaddr, remaddr; unsigned long rxq, txq, time_len, retr, inode; int timer_run; if ((procinfo = fopen(PATH_PROCNET_TCP, "r")) == NULL) { syslog(LOG_ERR, "error opening %s: %s", PATH_PROCNET_TCP,strerror(errno)); DEBUG(DBG_ERR, sprintf(dbg,"error opening %s: %s", PATH_PROCNET_TCP,strerror(errno))); return(-1); } fgets(buffer, sizeof(buffer), procinfo); /* skip header line */ while (!feof(procinfo)) { if(fgets(buffer, sizeof(buffer), procinfo)!=NULL) { num = sscanf(buffer, "%d: %lX:%X %lX:%X %X %lX:%lX %X:%lX %lX %d %d %ld\n", &d, &localaddr, &local_port, &remaddr, &rem_port, &state, &txq, &rxq, &timer_run, &time_len, &retr, (int*) uid, &tmout, &inode); if (num < 11) continue; /* 13 ? */ if(localaddr == ip->src && remaddr == ip->dst && local_port == ip->srcport && rem_port == ip->dstport) { fclose(procinfo); return 1; } } } fclose(procinfo); return(0); } #endif net-acct-0.71-glibc2/src/capture-pcap.c100644 1750 144 10702 6524347605 16725 0ustar phirateusers/* * Network accounting * capture-pcap.c - capture raw packets - pcap version * (C) 1996 Ulrich Callmeier */ #include "netacct.h" #include #include #include #include #include void handle_ip(unsigned char buf[], char *devname, char *user); pcap_t *pcap; char errbuff[PCAP_ERRBUF_SIZE]; #define PCAP_SNAPLEN 128 #define PCAP_TMOUT 1000 void handle_frame (unsigned char[], int); void init_capture() { struct promisc_device *p; pcap = NULL; p = cfg -> promisc; if(p!=NULL) { pcap = pcap_open_live(p -> name, PCAP_SNAPLEN, 1, PCAP_TMOUT, errbuff); if(pcap == NULL) { syslog(LOG_ERR, "can't pcap_open_live: %s\n", errbuff); daemon_stop(0); } } DEBUG(DBG_MISC, sprintf(dbg, "%s set to promiscous mode\n", p -> name)); } void exit_capture(void) { if(pcap != NULL) pcap_close (pcap); pcap = NULL; } inline int onnet(unsigned long int addr, struct ipnetwork *net) { return ((addr & net -> netmask) == net -> netnumber); } int onnetlist(unsigned long int addr, struct ipnetwork *netlist) { while(netlist!=NULL) { if(onnet(addr, netlist)) { return 1; } netlist = netlist -> next; } return 0; } void do_packet(u_char *usr, const struct pcap_pkthdr *h, const u_char *p) { handle_frame(p, h->len); } void packet_loop() { int res; while(running) { res = pcap_dispatch(pcap, -1, do_packet, NULL); if(res == -1) { syslog(LOG_ERR, "pcap_dispatch: %s\n", pcap_geterr(pcap)); DEBUG(DBG_ERR, sprintf(dbg,"pcap_dispatch: %s\n", pcap_geterr(pcap))); } } } FILE *acct_file = stderr; void handle_frame (unsigned char buf[], int length) { static struct ip tmp_iphdr; unsigned short srcport, dstport; struct tcphdr tmp_tcphdr; struct udphdr tmp_udphdr; struct icmp tmp_icmphdr; int found = 0; struct mon_host_struct *ptr; if(buf[12] * 256 + buf[13] == ETHERTYPE_IP) { memcpy (&tmp_iphdr, &(buf[14]), sizeof (tmp_iphdr)); found = 0; if(cfg->hostlist) { /* we specified at least one hostlimit tag */ /* if we don't monitor this IP, bail now - mk */ for(ptr=cfg->hostlist;ptr && !found;ptr=ptr->next) { if(ptr->ipaddr == tmp_iphdr->saddr || ptr->ipaddr == tmp_iphdr->daddr) found = 1; } if(!found) { packets->ignored++; continue; } } if((tmp_iphdr.ip_src.s_addr & cfg->ignoremask) == (tmp_iphdr.ip_dst.s_addr & cfg->ignoremask)) { packets->local++; return; } else { if(onnetlist(tmp_iphdr.ip_src.s_addr,cfg->ignorenet) || onnetlist(tmp_iphdr.ip_dst.s_addr, cfg->ignorenet)) { if(!(onnetlist(tmp_iphdr.ip_src.s_addr,cfg->dontignore) || onnetlist(tmp_iphdr.ip_dst.s_addr, cfg->dontignore))) { if(debug_level & DBG_IGNORE) { char tmp[18]; strcpy(tmp, intoa(tmp_iphdr.ip_src.s_addr)); DEBUG(DBG_IGNORE, sprintf(dbg, "netignored: %s -> %s\n", tmp,intoa(tmp_iphdr.ip_dst.s_addr))); } packets->netignored++; return; } } packets->ip++; switch(tmp_iphdr.ip_p) { case IPPROTO_UDP: packets->ip_udp++; memcpy (&tmp_udphdr, &buf[14 + tmp_iphdr.ip_hl * 4], sizeof (tmp_udphdr)); srcport = tmp_udphdr.uh_sport; dstport = tmp_udphdr.uh_dport; break; case IPPROTO_TCP: packets->ip_tcp++; memcpy (&tmp_tcphdr, &buf[14 + tmp_iphdr.ip_hl * 4], sizeof (tmp_tcphdr)); srcport = tmp_tcphdr.th_sport; dstport = tmp_tcphdr.th_dport; break; case IPPROTO_ICMP: packets->ip_icmp++; memcpy (&tmp_icmphdr, &buf[14 + tmp_iphdr.ip_hl * 4], sizeof (tmp_icmphdr)); srcport = tmp_icmphdr.icmp_type; dstport = tmp_icmphdr.icmp_code; break; default: packets->ip_other++; srcport = dstport = 0; break; } register_packet(tmp_iphdr.ip_src.s_addr,tmp_iphdr.ip_dst.s_addr, tmp_iphdr.ip_p, srcport, dstport, ntohs(tmp_iphdr.ip_len), strdup(cfg->promisc->name), NULL); } } else { /* ETH_P_ARP, ETH_P_RARP, ETH_P_IPX, etc. */ packets -> ignored ++; } } net-acct-0.71-glibc2/src/config.c100644 1750 144 25010 6600343772 15600 0ustar phirateusers/* * Network accounting * config.c - configuration module * (C) 1994 Ulrich Callmeier */ #include #include #include #include #include "netacct.h" char *rcs_revision_config_c = "$Revision: 1.14 $"; /* * This routine reads all the configuration from the file fname. * On success it returns a non-NULL pointer to a struct config. * The parser is kind of a hack but it works. */ struct config *read_config(char *fname) { char buff[1024]; FILE *f; int line=0; struct config *cfg = malloc(sizeof(struct config)); if(cfg == NULL) return cfg; cfg -> filename = NULL; cfg -> dumpname = NULL; cfg -> debugname = NULL; cfg -> flush = DEFAULT_FLUSH; cfg -> ignoremask = inet_addr(DEFAULT_IGNOREMASK); cfg -> err_delay = DEFAULT_ERR_DELAY; cfg -> ignorenet = NULL; cfg -> dontignore = NULL; cfg -> promisc = NULL; cfg -> notdev = NULL; cfg -> fdelay = DEFAULT_FDELAY; cfg -> disabled = 0; cfg -> dynamicip = NULL; cfg -> excludenamelookup = NULL; cfg -> headers = NULL; cfg -> hostlist = NULL; cfg -> iflist = NULL; #ifdef REMAP_MASQUERADE cfg -> masqif = 0; #endif debug_level = 0; dev2line = NULL; f=fopen(fname,"r"); if(f == NULL) return NULL; while(fgets(buff,sizeof(buff),f)) { /* remove trailing newline */ char *cmt = strchr(buff,'\n'); if(cmt) *cmt = '\0'; line++; /* remove comments */ cmt = strchr(buff,'#'); if(cmt) *cmt = '\0'; /* remove leading whitespace */ while(isspace(*buff)) { memmove(buff,buff+1,strlen(buff)); } /* remove trailing whitespace */ cmt = strchr(buff,'\0'); cmt --; while(isspace(*cmt)) { *cmt = '\0'; cmt --; } /* process nonempty lines */ if(*buff) { char *kwd = buff; char *value = buff + strcspn(buff," \t"); *value++ = '\0'; while(isspace(*value)) value++; #if DBG printf("key: \"%s\" value: \"%s\" \n",kwd, value); #endif if(strcasecmp(kwd, "flush")==0) { cfg->flush = atoi(value); syslog(LOG_DEBUG,"config: set flushing to %d\n",cfg->flush); } else if(strcasecmp(kwd, "fdelay")==0) { cfg->fdelay = atoi(value); syslog(LOG_DEBUG,"config: set fdelay to %d\n",cfg->fdelay); } else if(strcasecmp(kwd, "file")==0) { cfg->filename = strdup(value); syslog(LOG_DEBUG,"config: set filename to %s\n",cfg->filename); } else if(strcasecmp(kwd, "dumpfile")==0) { cfg->dumpname = strdup(value); syslog(LOG_DEBUG,"config: set dumpfile to %s\n",cfg->dumpname); } else if(strcasecmp(kwd, "debugfile")==0) { cfg->debugname = strdup(value); syslog(LOG_DEBUG,"config: set debugfile to %s\n",cfg->debugname); } else if(strcasecmp(kwd, "dynamicip")==0) { if(value[strlen(value)-1]=='/') value[strlen(value)-1]='\0'; cfg->dynamicip = strdup(value); syslog(LOG_DEBUG,"config: set dynamicip to %s\n",cfg->dynamicip); } else if(strcasecmp(kwd, "ignoremask")==0) { cfg->ignoremask = inet_addr(value); syslog(LOG_DEBUG,"config: set ignoremask to %s\n",intoa(cfg->ignoremask)); } else if(strcasecmp(kwd, "debug")==0) { debug_level = atoi(value); syslog(LOG_DEBUG,"config: set debugging level to %d\n",debug_level); } else if(strcasecmp(kwd, "disable")==0) { int field; field = atoi(value); if((field < MIN_DISABLE) || (field > MAX_DISABLE)) { syslog(LOG_ERR, "config file: invalid disable statement\n"); return NULL; } else { cfg->disabled |= BITMASK(field); syslog(LOG_DEBUG,"config: disabled field %d\n",field); } } else if(strcasecmp(kwd, "ignorenet")==0) { struct ipnetwork *tmp; char *mask; mask = value + strcspn(value," \t"); *mask++ = '\0'; while(isspace(*mask)) mask++; tmp = malloc(sizeof(struct ipnetwork)); if(tmp != NULL) { tmp -> netnumber = inet_addr(value); tmp -> netmask = inet_addr(mask); tmp -> next = cfg -> ignorenet; cfg -> ignorenet = tmp; syslog(LOG_DEBUG, "config: added ignore network (netnumber %s)\n", intoa(cfg -> ignorenet -> netnumber)); syslog(LOG_DEBUG, "config: added ignore network (netmask %s)\n", intoa(cfg -> ignorenet -> netmask)); } } else if(strcasecmp(kwd, "exclude-name-lookup")==0) { struct ipnetwork *tmp; char *mask; mask = value + strcspn(value," \t"); *mask++ = '\0'; while(isspace(*mask)) mask++; tmp = malloc(sizeof(struct ipnetwork)); if(tmp != NULL) { tmp -> netnumber = inet_addr(value); tmp -> netmask = inet_addr(mask); tmp -> next = cfg -> excludenamelookup; cfg -> excludenamelookup = tmp; syslog(LOG_DEBUG, "config: added exclude-name-lookup network (netnumber %s)\n", intoa(cfg -> excludenamelookup -> netnumber)); syslog(LOG_DEBUG, "config: added exclude-name-lookup network (netmask %s)\n", intoa(cfg -> excludenamelookup -> netmask)); } } else if(strcasecmp(kwd, "dynamicnet")==0) { char *mask; mask = value + strcspn(value," \t"); *mask++ = '\0'; while(isspace(*mask)) mask++; cfg -> dynamicnet.netnumber = inet_addr(value); cfg -> dynamicnet.netmask = inet_addr(mask); syslog(LOG_DEBUG, "config: set dynamic network (netnumber %s)\n", intoa(cfg -> dynamicnet.netnumber)); syslog(LOG_DEBUG, "config: set dynamic network (netmask %s)\n", intoa(cfg -> dynamicnet.netmask)); } else if(strcasecmp(kwd, "dontignore")==0) { struct ipnetwork *tmp; char *mask; mask = value + strcspn(value," \t"); *mask++ = '\0'; while(isspace(*mask)) mask++; tmp = malloc(sizeof(struct ipnetwork)); if(tmp != NULL) { tmp -> netnumber = inet_addr(value); tmp -> netmask = inet_addr(mask); tmp -> next = cfg -> dontignore; cfg -> dontignore = tmp; syslog(LOG_DEBUG, "config: added dontignore network (netnumber %s)\n", intoa(cfg -> dontignore -> netnumber)); syslog(LOG_DEBUG, "config: added dontignore network (netmask %s)\n", intoa(cfg -> dontignore -> netmask)); } } else if(strcasecmp(kwd, "headers")==0) { char *offset; char *type; struct headerdat *tmp; offset = value + strcspn(value," \t"); *offset++ = '\0'; while(isspace(*offset)) offset++; type = offset + strcspn(offset," \t"); *type++ = '\0'; while(isspace(*type)) type++; tmp = malloc(sizeof(struct headerdat)); if(tmp != NULL) { tmp -> name = strdup(value); tmp -> l = strlen(value); tmp -> offset = atoi(offset); tmp -> type = atoi(type); tmp -> next = cfg -> headers; cfg -> headers = tmp; syslog(LOG_DEBUG, "config: added headerinfo (%s:%d:%d)\n", tmp -> name, tmp -> offset, tmp -> type); } } else if(strcasecmp(kwd, "device")==0) { struct promisc_device *tmp; tmp = malloc(sizeof(struct promisc_device)); if(tmp != NULL) { tmp -> name = strdup(value); tmp -> reset = 0; tmp -> next = cfg -> promisc; cfg -> promisc = tmp; syslog(LOG_DEBUG,"config: added promiscous device %s\n", cfg->promisc->name); } } else if(strcasecmp(kwd, "notdev")==0) { struct promisc_device *tmp; tmp = malloc(sizeof(struct promisc_device)); if(tmp != NULL) { tmp -> name = strdup(value); tmp -> next = cfg -> notdev; cfg -> notdev = tmp; syslog(LOG_DEBUG,"config: added notdevice %s\n", cfg->notdev->name); } } else if(strcasecmp(kwd, "errdelay")==0) { cfg->err_delay = atoi(value); syslog(LOG_DEBUG,"config: set delay on error to %d\n",cfg->err_delay); } else if(strcasecmp(kwd, "line")==0) { struct dev2line *tmp; char *line; tmp = malloc(sizeof(struct dev2line)); line = value + strcspn(value," \t"); *line++ = '\0'; while(isspace(*line)) line++; tmp -> netinterface = strdup(value); tmp -> line = strdup(line); tmp -> next = dev2line; dev2line = tmp; syslog(LOG_DEBUG,"config: [dev2line:] %s -> %s\n",dev2line->netinterface, dev2line->line); } else if(strcasecmp(kwd, "hostlimit")==0) { unsigned char c1,c2,c3,c4; unsigned long ipaddr; struct mon_host_struct *tmp; c1 = strtol(strtok(value,"."),0,0); c2 = strtol(strtok(NULL,"."),0,0); c3 = strtol(strtok(NULL,"."),0,0); c4 = strtol(strtok(NULL,"."),0,0); ipaddr = htonl((c1 << 24) | (c2 << 16) | (c3 << 8) | c4); tmp = malloc(sizeof(struct mon_host_struct)); if(tmp != NULL) { tmp->ipaddr = ipaddr; tmp->next = cfg->hostlist; cfg->hostlist = tmp; syslog(LOG_DEBUG,"config: added hostlimit %s\n",intoa(cfg->hostlist->ipaddr)); } } else if(strcasecmp(kwd, "iflimit")==0) { struct promisc_device *tmp; tmp = malloc(sizeof(struct promisc_device)); if(tmp != NULL) { tmp -> name = strdup(value); tmp -> next = cfg -> iflist; cfg -> iflist = tmp; syslog(LOG_DEBUG,"config: added iflist %s\n", cfg->iflist->name); } } #ifdef REMAP_MASQUERADE else if(strcasecmp(kwd, "masqif") == 0) { cfg->masqif = inet_addr(value); syslog(LOG_DEBUG, "config: set masqif to %s\n",intoa(cfg->masqif)); } #endif else { syslog(LOG_ERR, "config file: unknown keyword %s in line %d\n",kwd,line); return NULL; } } } if(cfg->filename == NULL) { syslog(LOG_ERR, "config file: no filename given\n"); return NULL; } if(cfg->dumpname == NULL) { syslog(LOG_ERR, "config file: no dumpfile given\n"); return NULL; } #ifdef linux if(cfg->headers == NULL) { syslog(LOG_ERR, "config file: no header information given\n"); return NULL; } #endif if(cfg->debugname == NULL) { syslog(LOG_INFO, "config file: no debugfile given, using /dev/null\n"); cfg->debugname = strdup("/dev/null"); } fclose(f); return cfg; } net-acct-0.71-glibc2/src/daemon.c100644 1750 144 2257 6524340336 15564 0ustar phirateusers/* * Network accounting * daemon.c - Utilities for a daemon process. * (C) 1994 Ulrich Callmeier */ #include #include #include #include #include #include #include #include #include #include #include "netacct.h" char *rcs_revision_daemon_c = "$Revision: 1.8 $"; int daemon_start(void) { int i; pid_t pid; if( (pid = fork()) < 0) return(-1); else if (pid!=0) exit(0); closelog(); for(i=0; i #include #include #include #include #include "netacct.h" char *rcs_revision_main_c = "$Revision: 1.15 $"; /* globals */ char *progname; struct config *cfg; volatile int debug_level; struct dev2line *dev2line; FILE *dbg_file; char *fname = NULL; static int debug = 0; static int daem = 1; void usage(void) { fprintf(stderr, "Usage: %s [-dD] [-c filename]\n\n\t-d\tSwitch on debugging\n", progname); fprintf(stderr, "\t-c\tSpecify alternative configuration file\n"); fprintf(stderr, "\t-D\tDon't detach (for inittab)\n\n"); } void process_options(int argc, char *argv[]) { int c; fname = strdup(DEF_ACCTTAB); while ((c = getopt( argc, argv, "c:dD" )) != EOF) { switch (c) { case 'c': free(fname); fname = strdup(optarg); break; case 'd': debug = 1; break; case 'D': daem = 0; break; case '?': default: usage(); exit(1); } } argc -= optind; argv += optind; if (argc > 1) { usage(); exit(1); } } int do_pid_file(void) /* return 1 if file could be created */ /* return 0 if daemon already running */ /* this is by no means clean of races, if we take it serious we should do it with some well thought out atomic operations */ { FILE *f; if(access(PID_FILE,F_OK)==0) { char buff[80]; int pid; /* file exists */ f = fopen(PID_FILE, "r"); fgets(buff, sizeof(buff), f); fclose(f); pid = atoi(buff); syslog(LOG_INFO, "found pid-file with pid %d\n", pid); if(kill(pid, 0) == -1) { syslog(LOG_INFO, "process %d doesn't exist anymore\n", pid); } else { syslog(LOG_INFO, "process %d is still running.\n", pid); return 0; } } f = fopen(PID_FILE, "w"); fprintf(f, "%d\n", (int) getpid()); fclose(f); return 1; } /* Set a signal handler. */ #define SETSIG(sig, fun, fla) sa.sa_handler = fun; \ sa.sa_flags = fla; \ sigaction(sig, &sa, NULL); void signal_setup(void) { int i; struct sigaction sa; for (i= 1; i < NSIG; ++i) signal(i, signal_ignore); /* these stop the program */ SETSIG(SIGINT, daemon_stop, 0); SETSIG(SIGKILL, daemon_stop, 0); SETSIG(SIGTERM, daemon_stop, 0); /* this one does the scheduling of write processes and handles the internal clock */ SETSIG(SIGALRM, alarm_handler, 0); /* handles notification about child exits */ SETSIG(SIGCHLD, child_finished, 0); /* manipulating the level of debug output */ SETSIG(SIGUSR1, signal_debug, 0); /* increase debugging level */ SETSIG(SIGUSR2, signal_debug, 0); /* turn off debugging */ /* the following signals are used in a nonstandard sense */ /* to see what version is running */ SETSIG(SIGWINCH, signal_debug, 0); /* print version number */ /* in case the program stops receiving packets (due to a kernel bug) */ SETSIG(SIGIOT, signal_debug, 0); /* reopen socket */ /* to cleanly move logfiles */ SETSIG(SIGTSTP, signal_debug, 0); /* stop writing to file */ SETSIG(SIGCONT, signal_debug, 0); /* continue writing to file */ /* ignore, but notify */ SETSIG(SIGHUP, signal_debug, 0); } void save_dumpfile(char *fname) { char *s; if(access(fname,F_OK)==0) { syslog(LOG_DEBUG,"found old dumpfile (%s)\n",fname); s = malloc(strlen(fname)+3); strcpy(s, fname); strcat(s, ".o"); save_dumpfile(s); rename(fname, s); free(s); } else { if(errno != ENOENT) { syslog(LOG_ERR, "error accessing dumpfile: %m\n"); } else { syslog(LOG_DEBUG,"no old dumpfile (%s) exists\n",fname); } } } int main(int argc, char *argv[]) { progname = argv[0]; if(geteuid() != 0) { syslog(LOG_ERR, "must be superuser to run nacctd\n"); exit(1); } /* process user options */ process_options(argc, argv); openlog("nacctd", 0, LOG_DAEMON); syslog(LOG_INFO, "net accounting daemon started"); /* read config file */ cfg = read_config(fname); if(cfg == NULL) { syslog(LOG_ERR, "error reading config file\n"); syslog(LOG_INFO, "net accounting daemon aborting\n"); exit(1); } save_dumpfile(cfg->dumpname); if(!debug && daem) { /* start daemon */ if(daemon_start()!=-1) { openlog("nacctd", 0, LOG_DAEMON); syslog(LOG_INFO, "net accounting daemon forked\n"); } else { syslog(LOG_ERR, "couldn't fork: %m\n"); syslog(LOG_INFO, "net accounting daemon aborting\n"); exit(1); } } dbg_file = fopen(cfg->debugname, "a"); if(dbg_file==NULL) { syslog(LOG_ERR, "error opening debug file: %m\n"); syslog(LOG_INFO, "net accounting daemon aborting\n"); exit(1); } setvbuf(dbg_file, NULL, _IONBF, BUFSIZ); /* check and create /var/run/nacctd.pid */ if(!do_pid_file()) { syslog(LOG_ERR, "daemon already running or stale pid-file\n"); exit(1); } /* signal setup */ signal_setup(); /* init capturing */ init_capture(); /* start being useful */ do_acct(); fclose(dbg_file); return 0; } net-acct-0.71-glibc2/src/naccttab.sample100644 1750 144 11222 6601000052 17127 0ustar phirateusersflush 300 # flush every 5 minutes # this gives the interval in seconds # when the accumulated data is flushed # to the output file fdelay 60 # this defines after how many seconds # of inactivity a certain record of # traffic information may be written out # this helps making the logfiles smaller # since only one output record will be # generated for related traffic file /var/log/net-acct # defines output file # this is the regular output file of # the daemon dumpfile /var/log/net-acct-dump # defines dump file # this is used to dump the not yet # written information so this is not # lost should the machine crash # on startup an eventuelly existing # file of this name will be moved # to *.o notdev eth1 # Dont log entries for this device # Use this on routers that you dont # log forwarded packets twice. device eth0 # device to put into promiscous mode # you can specify as many as you want # and you don't have to specify one # (e.g. if this runs on your router) # iflimit eth0 # on machines with multiple interfaces, # log only packets on this interface # mutually exclusive with hostlimit ignoremask 255.255.255.0 # Ignore traffic on same class C net # This means traffic that is on # your local LAN is not counted. # This is useful for NFS etc. # Not giving this option causes everything # to be counted. # This can degrade performance seriously! ignorenet 127.0.0.0 255.0.0.0 # ignore loopback net # You can define as many ignorenets as # you want. Ignoring a net with # ignorenet is not as efficient as # ignoremask. Thus you should exclude # your local network with ignoremask, # not with ignorenet (although this is # is possible). # masqif 192.168.72.141 # if compiled with -DREMAP_MASQUERADE: # ipnumber you are masquerading as, # this remaps ip/port for incoming # connections (e.g. ftp-data) to ip/port # of the masqueraded destination debug 2 # set debugging level debugfile /tmp/nacctd.debug # where to put debugging info # Device configuration # Defines where the real data starts for each type of interface # First give the name prefix, then the offset in bytes to the start # of the real data, then the offset of the type field in bytes. If # there is no type field, just give a 0. # Don't specify SLIP or PPP devices here, otherwise association of # dynamic ip-addresses with usernames won't work # Put device types with more traffic last. headers tr 40 38 headers lo 14 12 headers isdn 4 0 # headers isdn 14 0 # for hdlc/trans/cisco and hdlc/trans/raw headers eth 14 12 headers plip 14 12 # For dynamic slip/ppp dynamicip /var/run # where files for dynamic ip are stored dynamicnet 202.36.94.0 255.255.255.0 # on which network are all the # dynamically assigned adresses exclude-name-lookup 202.36.94.1 255.255.255.255 exclude-name-lookup 202.36.94.253 255.255.255.255 # hostlimit 12.34.56.78 # log only packets to/from this host # hostlimit 34.56.78.12 # and this one too # this option is mutually exclusive with iflimit # For disabling certain fields # This is commented out by default # Field 7 is disabled by default so we match the old (pre 0.5) output format # disable 2 # disable output of protocol # disable 3 # disable output of source address # disable 4 # disable output of source port # disable 5 # disable output of destination address # disable 6 # disable output of destination port disable 7 # disable output of packets count # disable 8 # disable output of byte count # disable 9 # disable output of device name # disable 10 # disable output of user name # For excluding certain hosts from ignoring # This can be useful for a kludgy way to account for proxy traffic, you'd then # add your proxy server here. # I guess I should consider using some filter language... # This is commented out by default # This does not affect addresses excluded by ignoremask, # as this would impose too much of a performance penalty # dontignore 127.3.4.5 255.255.255.255 # Don't ignore host 127.3.4.5, # although it would be excluded by # above ignorenet statement # line sl0 ttyS0 # One way to # assign traffic to a user is if both # of the following conditions meet: # a) nacctd runs on the ppp/slip server # b) the relation between network interface # (e.g. sl0, ppp1) and serial line (e.g. # ttyS1) is fixed. # You can give as many line statements # as you want # There is a better way now, so this is # commented out net-acct-0.71-glibc2/src/naccttab.sample.pcap100644 1750 144 5244 6524340336 20060 0ustar phirateusersflush 300 # flush every 5 minutes # this gives the interval in seconds # when the accumulated data is flushed # to the output file fdelay 60 # this defines after how many seconds # of inactivity a certain record of # traffic information may be written out # this helps making the logfiles smaller # since only one output record will be # generated for related traffic file /var/log/net-acct # defines output file # this is the regular output file of # the daemon dumpfile /var/log/net-acct-dump # defines dump file # this is used to dump the not yet # written information so this is not # lost should the machine crash # on startup an eventuelly existing # file of this name will be moved # to *.o device le0 # device to get packets from # you must specify exactly one ignoremask 255.255.255.0 # Ignore traffic on same class C net # This means traffic that is on # your local LAN is not counted. # This is useful for NFS etc. # Not giving this option causes everything # to be counted. # This can degrade performance seriously! ignorenet 127.0.0.0 255.0.0.0 # ignore loopback net # You can define as many ignorenets as # you want. Ignoring a net with # ignorenet is not as efficient as # ignoremask. Thus you should exclude # your local network with ignoremask, # not with ignorenet (although this is # is possible). debug 2 # set debugging level debugfile /tmp/nacctd.debug # where to put debugging info # hostlimit 12.34.56.78 # log only packets to/from this host # hostlimit 34.56.78.12 # and this one too # For disabling certain fields # This is commented out by default # disable 2 # disable output of protocol # disable 3 # disable output of source address # disable 4 # disable output of source port # disable 5 # disable output of destination address # disable 6 # disable output of destination port # disable 7 # disable output of packets count # disable 8 # disable output of byte count # disable 9 # disable output of device name # disable 10 # disable output of user name # For excluding certain hosts from ignoring # This can be useful for a kludgy way to account for proxy traffic, you'd then # add your proxy server here. # I guess I should consider using some filter language... # This is commented out by default # This does not affect addresses excluded by ignoremask, # as this would impose too much of a performance penalty # dontignore 127.3.4.5 255.255.255.255 # Don't ignore host 127.3.4.5, # although it would be excluded by # above ignorenet statement net-acct-0.71-glibc2/src/netacct.h100644 1750 144 13061 6766042010 15756 0ustar phirateusers/* * Network accounting * netacct.h - header file * * (C) 1994 Ulrich Callmeier */ #include #include #include #include #include #include #include /* #include */ #include #include /* #include */ /* #include */ #ifdef linux #include /* #include */ #else #define IP_TCP 6 #endif /* certain features you can disable or enable */ #undef HUMAN_READABLE_TIME #undef IGNORE_UNENC #ifdef linux #undef TCP_USER_INFO #endif /* paths */ #ifndef _PATH_UTMP #define _PATH_UTMP "/var/run/utmp" #endif #define DEF_ACCTTAB "/etc/naccttab" #ifdef linux #define PID_FILE "/var/run/nacctd.pid" #else #define PID_FILE "/etc/nacctd.pid" #endif #ifdef TCP_USER_INFO #define PATH_PROCNET_TCP "/proc/net/tcp" #endif /* default settings for naccttab */ #define DEFAULT_IGNOREMASK "255.255.255.255" #define DEFAULT_FLUSH 300 #define DEFAULT_ERR_DELAY 3 #define DEFAULT_FDELAY 60 #define FORCE_STAT_TIME 5 /****************************************/ /* no user configurable stuff from here */ /****************************************/ #define MIN_DISABLE 2 #define MAX_DISABLE 10 #define DIS_PROTO 2 #define DIS_SRC 3 #define DIS_SRCPORT 4 #define DIS_DST 5 #define DIS_DSTPORT 6 #define DIS_COUNT 7 #define DIS_BYTES 8 #define DIS_DEV 9 #define DIS_USER 10 #define BITMASK(bit) (1 << ((bit) % (CHAR_BIT*sizeof(int)))) /* parsing of config file */ #define DBG_CONFIG (1 << 1) #define DBG_STATE (1 << 2) #define DBG_UTMP (1 << 3) #define DBG_DYNAMIC (1 << 4) #define DBG_SYSCALL (1 << 5) #define DBG_IGNORE (1 << 6) #define DBG_MISC (1 << 7) #define DBG_STATISTICS (1 << 8) #define DBG_SIGNAL (1 << 9) #define DBG_ERR (1 << 10) #define DBG_ANNOYING (1 << 30) static char *DBG_TYPE_STRING[31] = {"NONE ", "CONF ", "STATE", "UTMP ", "DYNA ", "SYS ", "IGN ", "MISC ", "STATS", "SIG ", /* 10 */ "ERROR", "", "", "", "", "", "", "", "", "", /* 20 */ "", "", "", "" ,"", "", "", "", "", "", "ANNOY"}; #define DEBUG(level, msg)\ if((level) & debug_level)\ {\ char dbg[255], DBGtmp[255], DBGtype[255]; int DBGi;\ time_t DBGcurtime = time(NULL);\ for(DBGi=1; DBGi<=30; DBGi++) if((1 << DBGi) & level) {strcpy(DBGtype, DBG_TYPE_STRING[DBGi]);break;}\ strftime(DBGtmp, sizeof(DBGtmp), "%d/%m %H:%M:%S ", localtime(&DBGcurtime));\ msg; fprintf(dbg_file, "%s[%s] %s",DBGtmp,DBGtype,dbg);\ } struct ipnetwork { unsigned long netnumber, netmask; struct ipnetwork *next; }; struct promisc_device { char *name; /* name (e.g. eth0) */ int reset; /* do we have to reset it on exit ? */ struct ifreq oldifr; /* old settings */ struct promisc_device *next; }; /* structure for linked list of ip addresses to monitor - mk */ struct mon_host_struct { unsigned long ipaddr; struct mon_host_struct *next; }; struct config { char *filename; char *dumpname; char *debugname; int flush; /* in seconds */ int fdelay; /* in seconds */ unsigned long int ignoremask; int err_delay; /* how many cycles to delay on error ? */ struct ipnetwork *ignorenet; struct ipnetwork *dontignore; struct promisc_device *promisc; struct promisc_device *notdev; struct ipnetwork dynamicnet; struct ipnetwork *excludenamelookup; struct headerdat *headers; struct mon_host_struct *hostlist; struct promisc_device *iflist; #ifdef REMAP_MASQUERADE unsigned long int masqif; #endif char *dynamicip; int disabled; /* disabled output fields */ }; struct dev2line { char *netinterface; char *line; struct dev2line *next; }; struct dynadat { char *netinterface; unsigned long addr; time_t last_stat, mtime; char *user; struct dynadat *next; }; struct headerdat { char *name; int l; int offset; int type; struct headerdat *next; }; struct statistics { unsigned long int unenc; unsigned long int notdev; unsigned long int ignored, netignored, local, ip, dropped; /* sum = total */ unsigned long int ip_udp, ip_tcp, ip_icmp, ip_other; /* sum = ip */ }; struct ipdata { unsigned long int src, dst; unsigned char proto; unsigned short srcport, dstport; #ifdef REMAP_MASQUERADE unsigned long int msqsrc; unsigned short msqport; #endif unsigned long int bytes; unsigned count; char *devname; char *user; time_t when; struct ipdata *next; }; extern char *rcs_revision_config_c; extern char *rcs_revision_daemon_c; extern char *rcs_revision_capture_c; extern char *rcs_revision_main_c; extern char *progname; extern struct config *cfg; extern FILE *dbg_file; extern volatile int debug_level; extern struct dev2line *dev2line; extern volatile int running; extern struct statistics *packets; extern volatile time_t now; /* current time */ extern char *fname; /* capture-xxx.c */ void init_capture(void); void do_acct(void); void exit_capture(void); void packet_loop(void); #ifdef TCP_USER_INFO int get_tcp_info(struct ipdata *ip, uid_t *uid); #endif /* process.c */ void register_packet(unsigned long int src,unsigned long int dst, unsigned char proto, unsigned short srcport, unsigned short dstport, int size, char *devname, char *user); void write_log(int force); void alarm_handler(int sig); void child_finished(int sig); void signal_debug(int sig); void signal_ignore(int sig); /* daemon.c */ int daemon_start(void); void daemon_stop(int sig); /* config.c */ struct config *read_config(char *fname); /* utils.c */ char *ip_proto_name(unsigned char proto); char *intoa(unsigned long addr); char * etheraddr_string(unsigned char *ep); net-acct-0.71-glibc2/src/process.c100644 1750 144 46351 6767070775 16042 0ustar phirateusers/* * Network accounting * process.c - process packets * (C) 1994, 1995 Ulrich Callmeier * * modified April/98 by Tom Brown - tbrown@baremetal.com * added hash table to speed up register_packet */ #include #include #include "netacct.h" #include #include #include #include #include #include #include #include #include #ifdef REMAP_MASQUERADE #include #define PROC_MASQ_FILENAME "/proc/net/ip_masquerade" #endif char *rcs_revision_process_c = "$Revision: 1.8 $"; volatile int running; struct statistics *packets; #ifndef HASH_SIZE #define HASH_SIZE 4096 #endif #define HASH(s,d) ((s &0xfff)^(d &0xfff)) static struct ipdata *plist[HASH_SIZE]; /* data being collected */ static struct ipdata *olist[HASH_SIZE]; /* data being written */ unsigned long int plistsize; unsigned long int olistsize; static volatile sig_atomic_t lck; static volatile sig_atomic_t writing; static volatile sig_atomic_t dumping; volatile pid_t writepid; volatile pid_t dumppid; volatile int may_write; int err_delay, max_err_delay; volatile time_t now; /* statistics */ unsigned int list_compares, list_lookups; #ifdef REMAP_MASQUERADE void remap_masq(struct ipdata *p) { FILE *fd; char buf[257]; char *protocol; char searchtext[20]; int plen; if(p->proto == 6) protocol = "TCP"; else if(p->proto == 17) protocol = "UDP"; else if(p->proto == 1) protocol = "ICMP"; else return; plen = strlen(protocol); sprintf(searchtext, "%08lX:%04X %04X",ntohl(p->dst), p->dstport, p->srcport); if((fd=fopen(PROC_MASQ_FILENAME,"r")) == NULL) return; while(fgets(buf,257,fd)) { if((strncmp(protocol,buf,plen) == 0) && (strncmp(searchtext, buf+plen+15, 18) == 0)) { p->msqsrc = htonl(strtoul(buf+plen+1, NULL, 16)); p->msqport = strtoul(buf+plen+10, NULL, 16); break; } } fclose(fd); return; } #endif void reopen_socket(void) { int save1, save2; /* critical section */ save1 = may_write; may_write = 0; save2 = lck; lck = 1; /* end */ exit_capture(); init_capture(); lck = save2; may_write = save1; } void do_acct() { int i; packets = malloc(sizeof(struct statistics)); if(!packets) { syslog(LOG_ERR,"out of memory"); daemon_stop(0); } packets->ignored = packets->netignored = packets->ip = packets->local = 0; packets->ip_icmp = packets->ip_tcp = packets->ip_udp = packets->ip_other = 0; packets->notdev = packets->unenc = 0; for (i =0; i < HASH_SIZE; i++) { olist[i] = plist[i] = NULL; /* olist = plist = NULL; */ } olistsize = plistsize = 0; lck = writing = dumping = 0; max_err_delay = cfg -> err_delay; err_delay = 0; list_lookups = list_compares = 0; may_write = 1; now = time(NULL); alarm(1); running=1; packet_loop(); } #define DISABLED(n) (cfg->disabled & BITMASK(n)) void register_packet(unsigned long int src,unsigned long int dst, unsigned char proto, unsigned short srcport, unsigned short dstport, int size, char *devname, char *user) { int hash_val = HASH(src,dst); if(lck==0) { struct ipdata *p; DEBUG(DBG_ANNOYING, sprintf(dbg, "lck = 1\n")); lck = 1; p = plist[ hash_val ]; list_lookups++; while(p) { list_compares++; if( (DISABLED(DIS_PROTO) || (p->proto == proto)) && ( DISABLED(DIS_SRC) || (p->src == src)) && (DISABLED(DIS_DST) || (p->dst == dst)) && (DISABLED(DIS_SRCPORT) || (p->srcport == srcport)) && (DISABLED(DIS_DSTPORT) || (p->dstport == dstport)) && (strcmp(p->devname, devname)==0)) { p->bytes +=size; p->when = now; p->count++; lck = 0; DEBUG(DBG_ANNOYING, sprintf(dbg, "lck = 0\n")); return; } p = p->next; } p = malloc(sizeof(struct ipdata)); if(p == NULL) { packets -> dropped++; lck = 0; DEBUG(DBG_ERR, sprintf(dbg, "out of memory\n")); DEBUG(DBG_ANNOYING, sprintf(dbg, "lck = 0\n")); return; } plistsize++; p -> src = src; p -> dst = dst; p -> proto = proto; p -> srcport = srcport; p -> dstport = dstport; #ifdef REMAP_MASQUERADE p -> msqsrc = 0; p -> msqport = 0; if((src == cfg->masqif) && (srcport >= PORT_MASQ_BEGIN) && (srcport <= PORT_MASQ_END)) { remap_masq(p); } #endif p -> bytes = size; p -> count = 1; p -> devname = strdup(devname); if (user) p -> user = strdup(user); else p -> user = NULL; p -> next = plist[ hash_val ]; p -> when = now; #ifdef TCP_USER_INFO /* NEW !!! get user for tcp only */ if((proto == IP_TCP) && (p->user == 0) && (get_tcp_info(p, &uid)==1)) { char tmp[16]; sprintf(tmp, "<%d>", uid); p -> user = strdup(tmp); } #endif plist[ hash_val ] = p; lck = 0; DEBUG(DBG_ANNOYING, sprintf(dbg, "lck = 0\n")); } else { packets->dropped++; } } int do_write_list(FILE *f, struct ipdata *list[]) { struct ipdata *p; int i; #ifdef HUMAN_READABLE_TIME struct tm *tm1; time_t tmm; #endif for( i=0; i < HASH_SIZE; i++) { p = list[i]; while(p) { #ifdef HUMAN_READABLE_TIME /* by Vlad Seriakov */ time(&tmm); tm1 = localtime(&tmm); if(fprintf(f, "%02d/%02d/%02d %02d:%02d:%02d",tm1->tm_year,tm1->tm_mon+1,tm1->tm_mday, tm1->tm_hour,tm1->tm_min,tm1->tm_sec)<0) return 1; #else if(fprintf(f, "%lu",time(0))<0) return 1; #endif if(!DISABLED(DIS_PROTO)) if(fprintf(f, "\t%d",p->proto)<0) return 1; #ifdef REMAP_MASQUERADE if(p->msqport == 0) { #endif if(!DISABLED(DIS_SRC)) if(fprintf(f, "\t%s",intoa(p->src))<0) return 1; if(!DISABLED(DIS_SRCPORT)) if(fprintf(f, "\t%d",p->srcport)<0) return 1; #ifdef REMAP_MASQUERADE } else { if(!DISABLED(DIS_SRC)) if(fprintf(f, "\t%s",intoa(p->msqsrc))<0) return 1; if(!DISABLED(DIS_SRCPORT)) if(fprintf(f, "\t%d",p->msqport)<0) return 1; } #endif if(!DISABLED(DIS_DST)) if(fprintf(f, "\t%s",intoa(p->dst))<0) return 1; if(!DISABLED(DIS_DSTPORT)) if(fprintf(f, "\t%d",p->dstport)<0) return 1; if(!DISABLED(DIS_COUNT)) if(fprintf(f, "\t%u",p->count)<0) return 1; if(!DISABLED(DIS_BYTES)) if(fprintf(f, "\t%lu",p->bytes)<0) return 1; if(!DISABLED(DIS_DEV)) if(fprintf(f, "\t%s",p->devname)<0) return 1; if(!DISABLED(DIS_USER)) if(fprintf(f, "\t%s",p->user?p->user:"unknown")<0) return 1; if(fprintf(f, "\n")<0) return 1; p = p->next; } } if(fclose(f)<0) { return 1; } return 0; } static int pfd1[2], pfd2[2]; void TELL_WAIT_INIT(void) { if(pipe(pfd1) < 0 || pipe(pfd2) < 0) { syslog(LOG_ERR, "pipe error: %s", strerror(errno)); DEBUG(DBG_ERR, sprintf(dbg,"pipe error: %s\n", strerror(errno))); } } void TELL_WAIT_EXIT(void) { if(close(pfd1[0])!=0) { syslog(LOG_ERR, "pipe close error: %s", strerror(errno)); DEBUG(DBG_ERR, sprintf(dbg,"pipe close error: %s\n", strerror(errno))); } if(close(pfd1[1])!=0) { syslog(LOG_ERR, "pipe close error: %s", strerror(errno)); DEBUG(DBG_ERR, sprintf(dbg,"pipe close error: %s\n", strerror(errno))); } if(close(pfd2[0])!=0) { syslog(LOG_ERR, "pipe close error: %s", strerror(errno)); DEBUG(DBG_ERR, sprintf(dbg,"pipe close error: %s\n", strerror(errno))); } if(close(pfd2[1])!=0) { syslog(LOG_ERR, "pipe close error: %s", strerror(errno)); DEBUG(DBG_ERR, sprintf(dbg,"pipe close error: %s\n", strerror(errno))); } } void TELL_PARENT(void) { if(write(pfd2[1], "c", 1) != 1) { syslog(LOG_ERR, "write error: %s", strerror(errno)); DEBUG(DBG_ERR, sprintf(dbg,"write error: %s\n", strerror(errno))); } } void WAIT_PARENT(void) { char c; int n; again: if((n = read(pfd1[0], &c, 1)) != 1) { if((n == -1) && (errno == EINTR)) goto again; syslog(LOG_ERR, "read error: %s", strerror(errno)); DEBUG(DBG_ERR, sprintf(dbg,"read error: %s\n", strerror(errno))); } if(c!='p') { syslog(LOG_ERR, "WAIT_PARENT: incorrect data"); DEBUG(DBG_ERR, sprintf(dbg,"WAIT_PARENT: incorrect data\n")); } } void TELL_CHILD(void) { if(write(pfd1[1], "p", 1) != 1) { syslog(LOG_ERR, "write error: %s", strerror(errno)); DEBUG(DBG_ERR, sprintf(dbg,"write error: %s\n", strerror(errno))); } } void WAIT_CHILD(void) { char c; int n; again: if((n = read(pfd2[0], &c, 1)) != 1) { if((n == -1) && (errno == EINTR)) goto again; syslog(LOG_ERR, "read error: %s", strerror(errno)); DEBUG(DBG_ERR, sprintf(dbg,"read error: %s\n", strerror(errno))); } if(c!='c') { syslog(LOG_ERR, "WAIT_CHILD: incorrect data"); DEBUG(DBG_ERR, sprintf(dbg,"WAIT_CHILD: incorrect data\n")); } } /* write and clear olist */ void write_list(void) { FILE *f; char tmpn[255]; int i; while( (writepid = fork()) < 0) sleep(1); if (writepid!=0) return; /* Here goes the child */ TELL_PARENT(); WAIT_PARENT(); DEBUG(DBG_STATE, sprintf(dbg, "write child: synchronized with parent\n")); sprintf(tmpn, "/tmp/nacctd.write.%d", (int) getpid()); creat(tmpn, S_IRUSR); openlog("nacctd (write)", 0, LOG_DAEMON); DEBUG(DBG_STATE, sprintf(dbg, "* write process %d forked\n", (int) getpid())); f = fopen(cfg->filename, "a"); if(f==NULL) { unlink(tmpn); syslog(LOG_ERR, "error opening file %s: %m\n",cfg->filename); exit(1); } if(do_write_list(f, olist) != 0) { unlink(tmpn); syslog(LOG_ERR, "error writing to file %s: %m\n", cfg->filename); exit(1); } /* memory leak? TAB */ for (i=0; i < HASH_SIZE; i++) olist[i] = NULL; unlink(tmpn); DEBUG(DBG_STATE, sprintf(dbg, "* write finished, count = %ld\n", olistsize)); exit(0); } void dump_curr_list(void) { FILE *f; char tmpn[255]; int i; while( (dumppid = fork()) < 0) sleep(1); if (dumppid!=0) return; TELL_PARENT(); WAIT_PARENT(); DEBUG(DBG_STATE, sprintf(dbg, "dump child: synchronized with parent\n")); /* Here goes the child */ sprintf(tmpn, "/tmp/nacctd.dump.%d", (int) getpid()); creat(tmpn, S_IRUSR); openlog("nacctd (dump)", 0, LOG_DAEMON); DEBUG(DBG_STATE, sprintf(dbg, "* dump process %d forked\n", (int) getpid())); if(plistsize == 0) { unlink(tmpn); unlink(cfg->dumpname); DEBUG(DBG_STATE, sprintf(dbg, "* dump finished, dump empty\n")); exit(0); } f = fopen(cfg->dumpname, "w"); if(f==NULL) { unlink(tmpn); syslog(LOG_ERR, "error opening file %s: %m\n",cfg->dumpname); exit(1); } if(do_write_list(f, plist) != 0) { unlink(tmpn); syslog(LOG_ERR, "error writing to file %s: %m\n", cfg->dumpname); exit(1); } for (i=0; i < HASH_SIZE; i++) plist[i] = NULL; unlink(tmpn); DEBUG(DBG_STATE, sprintf(dbg, "* dump finished, count = %ld\n", plistsize)); exit(0); } void child_finished(int sig) { int status; pid_t pid; DEBUG((DBG_SIGNAL | DBG_STATE), sprintf(dbg, "-> got signal %d, handling\n", sig)); while((pid = waitpid((pid_t) -1, &status, WNOHANG)) != 0) { DEBUG(DBG_SIGNAL, sprintf(dbg, " waitpid returned %d, status = %d, errno = %d\n", pid, status, errno)); if(pid == -1) { if(errno == ECHILD) break; /* no child processes */ DEBUG(DBG_SIGNAL, sprintf(dbg, "waitpid: signaled error: %s\n", strerror(errno))); } if((pid == writepid) || (pid == dumppid)) { if(WIFEXITED(status)) { if(WEXITSTATUS(status)==0) { if(pid == writepid) { writing = 0; DEBUG((DBG_SIGNAL | DBG_STATE), sprintf(dbg, " set writing to 0\n")); } else { dumping = 0; DEBUG((DBG_SIGNAL | DBG_STATE), sprintf(dbg, " set dumping to 0\n")); } } else { syslog(LOG_ERR, "child %d exited with error status %d.\n", pid, WEXITSTATUS(status)); if(pid == writepid) { err_delay = max_err_delay; writing = 0; DEBUG((DBG_SIGNAL | DBG_STATE), sprintf(dbg, " set writing to 0, setting err_delay\n")); } else { dumping = 0; DEBUG((DBG_SIGNAL | DBG_STATE), sprintf(dbg, " set dumping to 0, ignored error condition\n")); } } } else { syslog(LOG_ERR, "Huh? Child %d terminated or stopped by signal (%m)\n", pid); if(pid == writepid) { writing = 0; DEBUG((DBG_SIGNAL | DBG_STATE), sprintf(dbg, " set writing to 0, ignored return code\n")); } else { dumping = 0; DEBUG((DBG_SIGNAL | DBG_STATE), sprintf(dbg, " set dumping to 0, ignored return code\n")); } } } else { syslog(LOG_ERR, "Huh? Child (%d) returned, but not the one we expected (%d, %d)!\n", (int) pid, writepid, dumppid); DEBUG(DBG_STATE, sprintf(dbg, " unexpected child %d signaled return (writepid = %d, dumppid = %d\n",(int) pid, writepid, dumppid)); } DEBUG(DBG_STATE, sprintf(dbg, " child %d signaled return\n",(int) pid)); } DEBUG((DBG_SIGNAL | DBG_STATE), sprintf(dbg, "<- got signal %d, done handling\n", sig)); } void alarm_handler(int sig) { static time_t last_check = 0; static time_t next_write_log = 0; DEBUG( ((sig == SIGALRM) ? DBG_ANNOYING : (DBG_SIGNAL | DBG_STATE)), sprintf(dbg, "got signal %d, handling\n", sig)); now++; if((now - last_check) > 60) { time_t nnow; nnow = time(NULL); if(nnow!=now) { if((abs(nnow - now) > 2)) { DEBUG(DBG_MISC, sprintf(dbg, "internal clock corrected (off by %d seconds)\n",(int) (nnow-now))); } now = nnow; } last_check = now; } if(now >= next_write_log) { write_log(0); next_write_log = now + cfg -> flush; } alarm(1); } void write_log(int force) { struct ipdata *p, *q; static struct ipdata *tlist; /* temp */ int i; DEBUG(DBG_STATE, sprintf(dbg, "write_log called\n")); if(err_delay!=0) { err_delay--; syslog(LOG_INFO,"flushing delayed due to error\n"); DEBUG(DBG_STATE, sprintf(dbg, "flushing delayed due to error\n")); } else if((writing == 0) && (lck == 0) && (may_write == 1)) /* delay if another write cycle is still in progress */ { DEBUG(DBG_STATISTICS, sprintf(dbg, "ignored: %ld netignored: %ld local:%ld ip:%ld unenc:%ld notdev:%ld dropped:%ld\n", packets->ignored, packets->netignored, packets->local, packets->ip, packets->unenc, packets->notdev, packets->dropped)); DEBUG(DBG_STATISTICS, sprintf(dbg, "udp: %ld tcp:%ld icmp:%ld other:%ld\n", packets->ip_udp, packets->ip_tcp, packets->ip_icmp, packets->ip_other)); if(list_lookups != 0) { DEBUG(DBG_STATISTICS, sprintf(dbg, "lookups:%d compares:%d compares/lookup:%f\n", list_lookups, list_compares, ((float) list_compares / (float) list_lookups))); } DEBUG(DBG_STATE, sprintf(dbg, "lck = 1\n")); lck = 1; /* can't update the list now */ DEBUG(DBG_MISC, sprintf(dbg, "Total of %ld entries\n", plistsize)); /* We build two lists: 1) olist, which will be written out 2) tlist, which will be the new plist (just for this hash row) */ olistsize = 0; plistsize = 0; for (i = 0; i < HASH_SIZE; i++) { p = plist[i]; tlist = NULL; olist[i] = NULL; while(p) { q = p->next; if(((now - p->when) > cfg->fdelay) || force) { p->next = olist[i]; olist[i] = p; olistsize++; } else { p->next = tlist; tlist = p; plistsize++; } p = q; } plist[i] = tlist; } if(dumping == 0) { dumping = 1; TELL_WAIT_INIT(); dump_curr_list(); TELL_CHILD(); WAIT_CHILD(); DEBUG(DBG_STATE, sprintf(dbg, "parent: synchronized with dump child\n")); TELL_WAIT_EXIT(); DEBUG(DBG_STATE, sprintf(dbg, "dumppid is %d\n", (int) dumppid)); } writing = 1; /* no further writing 'til this is finished */ lck = 0; DEBUG(DBG_STATE, sprintf(dbg, "lck = 0\n")); DEBUG(DBG_MISC, sprintf(dbg, "Split into %ld [hold] and %ld [write] = %ld [total] entries\n", plistsize, olistsize, plistsize + olistsize)); TELL_WAIT_INIT(); write_list(); /* this forks off a child to do the actual writing */ TELL_CHILD(); WAIT_CHILD(); DEBUG(DBG_STATE, sprintf(dbg, "parent: synchronized with write child\n")); TELL_WAIT_EXIT(); DEBUG(DBG_STATE, sprintf(dbg, "writepid is %d\n", (int) writepid)); for (i=0; i < HASH_SIZE; i++) { p = olist[i]; while(p) { olist[i] = p->next; free(p->devname); if (p->user) free(p->user); free(p); p=olist[i]; } } DEBUG(DBG_STATE, sprintf(dbg, "done freeing\n")); } else { DEBUG(DBG_STATE, sprintf(dbg, "flushing delayed (writing == %d, lck == %d, may_write == %d)\n",writing,lck,may_write)); } } void signal_debug(int sig) { DEBUG(DBG_SIGNAL, sprintf(dbg, "got signal %d, handling\n", sig)); if(sig==SIGUSR1) { debug_level++; } else if(sig==SIGUSR2) { syslog(LOG_DEBUG, "turning off debugging\n"); debug_level = 0; } else if(sig==SIGWINCH) { syslog(LOG_DEBUG,"nacctd, revisions:\n%s\n%s\n%s\n%s\n", rcs_revision_main_c, rcs_revision_process_c, rcs_revision_config_c, rcs_revision_daemon_c); } else if(sig==SIGTSTP) { DEBUG(DBG_STATE, sprintf(dbg, "received SIGTSTP\n")); may_write = 0; } else if(sig==SIGCONT) { DEBUG(DBG_STATE, sprintf(dbg, "received SIGCONT\n")); may_write = 1; } else if(sig==SIGIOT) { DEBUG(DBG_STATE, sprintf(dbg, "reopening socket\n")); reopen_socket(); } else if(sig == SIGHUP) { struct ipnetwork *ip,*ip_next; struct promisc_device *pr,*pr_next; struct headerdat *h,*h_next; struct mon_host_struct *mh,*mh_next; DEBUG(DBG_STATE, sprintf(dbg, "received SIGHUP, rereading config\n")); exit_capture(); if(cfg) { free(cfg->filename); free(cfg->dumpname); free(cfg->debugname); for(ip=cfg->ignorenet;ip;ip=ip_next) { ip_next = ip->next; free(ip); } for(ip=cfg->dontignore;ip;ip=ip_next) { ip_next = ip->next; free(ip); } for(ip=cfg->excludenamelookup;ip;ip=ip_next) { ip_next = ip->next; free(ip); } for(pr=cfg->promisc;pr;pr=pr_next) { pr_next = pr->next; free(pr); } for(pr=cfg->notdev;pr;pr=pr_next) { pr_next = pr->next; free(pr); } for(pr=cfg->iflist;pr;pr=pr_next) { pr_next = pr->next; free(pr); } for(h=cfg->headers;h;h=h_next) { h_next = h->next; free(h); } for(mh=cfg->hostlist;mh;mh=mh_next) { mh_next = mh->next; free(mh); } free(cfg); } cfg = read_config(fname); init_capture(); } else { DEBUG(DBG_SIGNAL, sprintf(dbg, "signal_debug received signal %d, this can't happen\n", sig)); syslog(LOG_INFO,"signal_debug received signal %d, this can't happen\n", sig); } } void signal_ignore(int sig) { DEBUG(DBG_SIGNAL, sprintf(dbg, "got signal %d, ignoring\n", sig)); } net-acct-0.71-glibc2/src/utils.c100644 1750 144 2155 6524340336 15456 0ustar phirateusers/* * Network accounting * utils.c - utility routines * * (C) 1994 Ulrich Callmeier */ #include #include #include "netacct.h" char *intoa(unsigned long addr) { static char buff[18]; char *p; p = (char *) &addr; sprintf(buff, "%d.%d.%d.%d", (p[0] & 255), (p[1] & 255), (p[2] & 255), (p[3] & 255)); return(buff); } static char hex[] = "0123456789abcdef"; char * etheraddr_string(unsigned char *ep) { unsigned int i, j; char *cp, *s; s = cp = (char *)malloc(sizeof("00:00:00:00:00:00")); if ((j = *ep >> 4) != 0) *cp++ = hex[j]; *cp++ = hex[*ep++ & 0xf]; for (i = 5; (int)--i >= 0;) { *cp++ = ':'; if ((j = *ep >> 4) != 0) *cp++ = hex[j]; *cp++ = hex[*ep++ & 0xf]; } *cp = '\0'; return (s); } char *ip_proto_name(unsigned char proto) { switch(proto) { case IPPROTO_ICMP: return "ICMP"; case IPPROTO_TCP: return "TCP"; case IPPROTO_UDP: return "UDP"; } return "?"; } net-acct-0.71-glibc2/tools/ 40755 1750 144 0 6172246407 14426 5ustar phirateusersnet-acct-0.71-glibc2/tools/ctime.pl100644 1750 144 3253 6172247344 16165 0ustar phirateusers;# ctime.pl is a simple Perl emulation for the well known ctime(3C) function. ;# ;# Waldemar Kebsch, Federal Republic of Germany, November 1988 ;# kebsch.pad@nixpbe.UUCP ;# Modified March 1990, Feb 1991 to properly handle timezones ;# $RCSfile: ctime.pl,v $$Revision: 4.1 $$Date: 92/08/07 18:23:47 $ ;# Marion Hakanson (hakanson@cse.ogi.edu) ;# Oregon Graduate Institute of Science and Technology ;# ;# usage: ;# ;# #include # see the -P and -I option in perl.man ;# $Date = &ctime(time); CONFIG: { package ctime; @DoW = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat'); @MoY = ('Jan','Feb','Mar','Apr','May','Jun', 'Jul','Aug','Sep','Oct','Nov','Dec'); } sub ctime { package ctime; local($time) = @_; local($[) = 0; local($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst); # Determine what time zone is in effect. # Use GMT if TZ is defined as null, local time if TZ undefined. # There's no portable way to find the system default timezone. $TZ = defined($ENV{'TZ'}) ? ( $ENV{'TZ'} ? $ENV{'TZ'} : 'GMT' ) : ''; ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = ($TZ eq 'GMT') ? gmtime($time) : localtime($time); # Hack to deal with 'PST8PDT' format of TZ # Note that this can't deal with all the esoteric forms, but it # does recognize the most common: [:]STDoff[DST[off][,rule]] if($TZ=~/^([^:\d+\-,]{3,})([+-]?\d{1,2}(:\d{1,2}){0,2})([^\d+\-,]{3,})?/){ $TZ = $isdst ? $4 : $1; } $TZ .= ' ' unless $TZ eq ''; $year += 1900; sprintf("%s %s %2d %2d:%02d:%02d %s%4d\n", $DoW[$wday], $MoY[$mon], $mday, $hour, $min, $sec, $TZ, $year); } 1; net-acct-0.71-glibc2/tools/german-IP-networks100644 1750 144 12767 6172247344 20135 0ustar phirateusers127 128.176 128.7 129.13 129.143 129.187 129.206 129.217 129.233 129.247 129.26 129.69 129.70 130.133 130.149 130.168 130.183 130.73 130.75 130.83 131.159 131.169 131.173 131.188 131.220 131.234 131.246 131.99 132.176 132.180 132.187 132.195 132.199 132.230 132.231 132.252 134.1 134.100 134.102 134.103 134.104 134.105 134.106 134.107 134.108 134.109 134.110 134.130 134.14 134.147 134.155 134.169 134.171 134.176 134.2 134.245 134.28 134.30 134.34 134.60 134.76 134.91 134.93 134.94 134.95 134.96 134.98 134.99 136.172 136.199 136.243 137.193 137.226 137.248 137.250 138.199 138.244 138.245 138.246 139.1 139.11 139.13 139.14 139.17 139.174 139.18 139.19 139.2 139.20 139.28 139.3 139.30 139.4 139.6 139.75 139.8 139.9 139.92 140.181 141.1 141.10 141.100 141.113 141.12 141.13 141.14 141.16 141.17 141.18 141.19 141.2 141.20 141.200 141.21 141.22 141.23 141.24 141.25 141.26 141.28 141.29 141.30 141.31 141.32 141.33 141.34 141.35 141.37 141.4 141.40 141.41 141.42 141.43 141.44 141.45 141.46 141.47 141.48 141.5 141.51 141.52 141.53 141.54 141.55 141.56 141.57 141.58 141.59 141.6 141.61 141.62 141.63 141.64 141.65 141.67 141.68 141.69 141.7 141.71 141.72 141.73 141.74 141.76 141.78 141.79 141.80 141.82 141.83 141.89 141.99 143.93 144.145 144.41 146.107 146.254 147.172 147.230 148.54 149.201 149.204 149.205 149.217 149.220 149.233 149.236 149.246 149.248 149.249 152.143 153.92 153.93 153.94 153.96 153.97 153.98 158.225 160.44.68 160.45 188.1 192.101.197 192.101.28 192.101.75 192.101.82 192.101.9 192.102.147 192.102.157 192.102.158 192.102.176 192.102.177 192.108.30 192.108.31 192.108.32 192.108.33 192.108.34 192.108.36 192.108.51 192.108.52 192.108.53 192.108.54 192.108.68 192.108.69 192.108.70 192.108.71 192.108.72 192.109.100 192.109.109 192.109.111 192.109.118 192.109.124 192.109.137 192.109.14 192.109.159 192.109.160 192.109.17 192.109.176 192.109.177 192.109.18 192.109.2 192.109.20 192.109.203 192.109.206 192.109.213 192.109.221 192.109.222 192.109.23 192.109.230 192.109.234 192.109.237 192.109.251 192.109.253 192.109.26 192.109.28 192.109.29 192.109.3 192.109.31 192.109.39 192.109.4 192.109.42 192.109.43 192.109.46 192.109.48 192.109.5 192.109.53 192.109.55 192.109.56 192.109.57 192.109.58 192.109.59 192.109.6 192.109.74 192.109.76 192.109.80 192.109.81 192.109.89 192.109.90 192.111.47 192.12.81 192.124.236 192.124.237 192.124.240 192.124.241 192.124.242 192.124.243 192.124.245 192.124.246 192.124.248 192.124.249 192.124.25 192.124.250 192.124.26 192.124.27 192.124.28 192.129.1 192.129.10 192.129.11 192.129.12 192.129.13 192.129.14 192.129.16 192.129.24 192.129.29 192.129.31 192.129.36 192.129.37 192.129.38 192.129.40 192.129.41 192.129.42 192.129.5 192.129.50 192.129.55 192.129.6 192.129.7 192.16.192 192.160.142 192.166.32 192.166.33 192.166.34 192.166.35 192.166.36 192.166.37 192.166.38 192.166.39 192.166.40 192.166.41 192.166.42 192.166.43 192.166.44 192.166.45 192.166.46 192.166.47 192.166.48 192.166.8 192.26.174 192.26.176 192.31.102 192.33.254 192.35.149 192.35.150 192.35.151 192.35.152 192.35.153 192.35.17 192.35.229 192.35.64 192.35.65 192.42.1 192.42.143 192.42.253 192.44.1 192.44.11 192.44.15 192.44.2 192.44.32 192.44.33 192.44.34 192.44.35 192.44.37 192.44.38 192.44.81 192.44.82 192.44.83 192.44.84 192.44.85 192.44.86 192.44.87 192.44.88 192.44.89 192.44.90 192.48.107 192.48.224 192.52.159 192.52.160 192.53.103 192.54.104 192.54.31 192.54.32 192.54.34 192.54.35 192.54.37 192.54.38 192.54.41 192.54.42 192.54.43 192.54.45 192.54.46 192.54.47 192.54.49 192.54.53 192.54.65 192.54.66 192.54.74 192.54.79 192.54.80 192.55.188 192.55.197 192.55.244 192.64.202 192.67.189 192.67.190 192.67.191 192.67.192 192.67.193 192.67.194 192.67.195 192.67.196 192.67.197 192.67.198 192.67.199 192.67.200 192.67.201 192.67.202 192.67.203 192.67.204 192.67.205 192.67.206 192.67.207 192.67.208 192.67.218 192.68.13 192.68.14 192.68.16 192.68.165 192.68.166 192.68.167 192.68.168 192.68.169 192.68.19 192.68.254 192.70.140 192.70.143 192.70.145 192.73.34 192.76.125 192.76.129 192.76.134 192.76.135 192.76.141 192.76.144 192.76.147 192.76.149 192.76.152 192.76.156 192.76.157 192.76.158 192.76.159 192.76.170 192.76.171 192.76.176 192.76.241 192.76.245 192.76.246 192.76.247 192.76.248 192.79.161 192.82.241 192.84.220 192.86.163 192.88.108 192.88.15 192.88.204 192.88.97 192.88.98 192.92.108 193.100.14 193.100.15 193.100.163 193.100.228 193.100.229 193.100.230 193.100.231 193.100.241 193.100.96 193.101.11 193.101.8 193.141.1 193.141.101 193.141.117 193.141.123 193.141.226 193.141.255 193.141.40 193.141.42 193.141.43 193.141.47 193.141.54 193.141.71 193.141.73 193.141.75 193.141.88 193.141.95 193.16.112 193.16.113 193.16.3 193.17.23 193.174.006 193.174.136 193.174.14 193.174.15 193.174.16 193.174.167 193.174.19 193.174.2 193.174.226 193.174.248 193.174.254 193.174.3 193.174.4 193.174.41 193.174.48 193.174.64 193.174.65 193.174.66 193.174.67 193.174.69 193.174.74 193.175.1 193.175.244 193.175.252 193.196.152 193.196.32 193.197.32 193.22.1 193.25.16 193.25.31 193.96.1 193.96.108 193.96.110 193.96.16 193.96.226 193.96.228 193.96.231 193.96.24 193.96.242 193.96.243 193.96.248 193.96.250 193.96.32 193.96.33 193.96.34 193.96.35 193.96.36 193.96.37 193.96.38 193.96.39 193.96.40 193.96.41 193.96.42 193.96.43 193.96.44 193.96.45 193.96.46 193.96.47 193.96.64 193.96.65 193.96.66 193.96.96 193.96.97 193.96.98 193.96.99 193.97.1 193.98.1 193.98.10 193.98.110 193.98.128 193.98.129 193.98.130 193.98.132 193.98.156 193.98.158 193.98.184 193.98.192 193.98.200 193.98.8 193.98.91 193.99.135 193.99.138 193.99.139 193.99.142 193.99.143 193.99.153 193.99.84 255.255.255 53 net-acct-0.71-glibc2/tools/ptime.pl100644 1750 144 12672 6172247344 16227 0ustar phirateusers# File: ptime.pl # Originally was called: pdate.pl # Created by: Jeff Kellem # Created a little while back.. # Last modified: 21 Feb 1991 # Version: 0.8a (first release) # # Minor History: # Started out as a quick hack for date formatting for bry (a friend). # An OS upgrade replaced date with one that didn't support +FORMAT and he # wanted something similar. So, something quick was hacked up. Now, it's # a simple little package for use within other routines. # # routines for producing user-specified date formats # # Possible things you may want to change before calling these routines: # $ptime'default_TZ = timezone to use is if no TZ environment var # ex: $ptime'default_TZ = 'EST5EDT'; # # Routines available in this package (usage): # &'zonetime($time); # &'zonetime; # returns what gmtime($time) and localtime($time) return. # if $time is not specified, use current time from time function. :-) # &'ptime($format, $time); # returns date/time in a user-specified $format. # if $time is not specified, use current time. # n.b.: if $time is null, will be considered the "beginning of time". # if $format is null, use $ptime'default_format (ctime format). # $format interprets the following "escape sequences": # ESCAPE REPLACED BY # %n newline # %t tab # %a abbreviated weekday name (Sun to Sat) # %A full weekday name # %b abbrev. month name (Jan to Dec) # %h abbrev. month name (Jan to Dec) # %B full month name # %d day of month (01 to 31) # %e day of month ( 1 to 31) [single digits preceded by a space] # %m month (01 to 12) # %D mm/dd/yy # %H hour (00 to 23) # %I hour (01 to 12) # %M minutes (00 to 59) # %S seconds (00 to 59) # %p AM or PM # %j day of year (001 to 366) # %w day of week (Sunday == 0) # %r hh:mm:ss [AP]M # %R hh:mm # %T hh:mm:ss # %y year (last 2 digits) # %Y year (4 digits, 19xx, 20xx) # %Z timezone # %% a single `%' # # Example: # &'ptime('',$time); # is just &'ctime($time); # print &'ptime("%D %T %Z\n",time); # prints "02/17/91 14:23:54 GMT\n" # $date = &'ptime('%d %h %Y',time); # $date = "17 Feb 1991"; # $filename = &'ptime('%d_%h_%Y'); # $filename = "17_Feb_1991"; # # Limitations: # Doesn't parse left to right (or at all).. ;-} # Just does straight subst's. # So, $format='%%y' will return '%91' instead of '%y'. # The %% -> % translation is done last. Maybe I should move it to # the top of the subst's. hmm... # Is biased toward American date formatting. May add more hooks for # easy conversion to other languages. # # TODO: # Should get rid of multiple sprintf's when the same occur more than once. # Make it easier to modify for other languages # things like separators, order, etc. # CONFIG: { package ptime; $default_TZ = 'GMT'; $default_format = '%a %h %d %T %Z %Y'; # ctime default format $am = "AM"; $pm = "PM"; @week = ('Sun','Mon','Tue','Wed','Thu','Fri','Sat'); @fullweek = ('Sunday','Monday','Tuesday','Wednesday', 'Thursday','Friday','Saturday'); @month = ('Jan','Feb','Mar','Apr','May','Jun', 'Jul','Aug','Sep','Oct','Nov','Dec'); @fullmonth = ('January','February','March','April','May','June','July', 'August','September','October','November','December'); } sub zonetime { # first arg is time (# of secs) package ptime; $time = $_[0] || ( ! defined $_[0] && time ) || 0; $TZ = $ENV{'TZ'} || $default_TZ; $TZ eq 'GMT' ? gmtime($time) : localtime($time); } sub ptime { package ptime; local($_, $time) = @_; # $_ is format, $time is time (# of secs) ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = &'zonetime($time); $ampm = ($hour % 12); $ampm += ($hour % 12) ? 0 : 12; $p = ($hour < 12) ? $am : $pm; $_ = $default_format unless $_; s/%n/\n/g; # newline s/%t/\t/g; # tab s/%p/$p/g; # AM or PM s/%m/sprintf("%02d",$mon+1)/eg; # month (01 to 12) s/%d/sprintf("%02d",$mday)/eg; # day of month (01 to 31) s/%e/sprintf("%2d",$mday)/eg; # day of month ( 1 to 31) # no special formatting for month & day? need new %-formats #s/%m/$mon+1/eg; # month (1 to 12) #s/%d/$mday/g; # day (1 to 31) s/%y/sprintf("%02d",$year)/eg; # year (last 2 digits) # prints 2069 instead of 1970 for things like EST (oh well.. ;-) s/%Y/$year + (($year < 70) ? 2000 : 1900)/eg; # year (19yy or 20yy) s:%D:sprintf("%02d/%02d/%02d",$mon+1,$mday,$year):eg; # mm/dd/yy s/%H/sprintf("%02d",$hour)/eg; # hour (00 to 23) s/%I/sprintf("%02d",$ampm)/eg; # hour (01 to 12) s/%M/sprintf("%02d",$min)/eg; # minutes (00 to 59) s/%S/sprintf("%02d",$sec)/eg; # seconds (00 to 59) s/%T/sprintf("%02d:%02d:%02d",$hour,$min,$sec)/eg; # HH:MM:SS s/%j/sprintf("%03d",$yday+1)/eg;# day of year (001 to 366) s/%w/$wday/g;# day of week (Sunday == 0) s/%a/$week[$wday]/g; # abbrev. weekday (Sun to Sat) s/%A/$fullweek[$wday]/g; # full weekday name s/%[bh]/$month[$mon]/g; # abbrev. month (Jan to Dec) s/%B/$fullmonth[$mon]/g; # full month name s/%r/sprintf("%02d:%02d:%02d $p", $ampm, $min, $sec)/eg; # hh:mm:ss [AP]M s/%R/sprintf("%02d:%02d", $hour, $min)/eg; # hh:mm # are we in Daylight Savings Time? $TZ =~ s/^(\w{3})-?\d+(\w{3})$/$isdst ? $2 : $1/e; s/%Z/$TZ/g; # timezone as specified by $TZ s/%%/%/g; # single `%' $_; } # in case someone doesn't want to rely on $ptime'default_format or # just wants a &'ctime sub. sub ctime { $time = $_[0]; $format = "%a %h %d %T %Z %Y\n"; &'ptime($format, $time); } 1; net-acct-0.71-glibc2/tools/sl2rdbl100755 1750 144 4551 6172272163 16020 0ustar phirateusers#!/pkg/utils/bin/perl5.002 # (C) 1994 Ulrich Callmeier # Slip To Readable # Converts output of nacctd to a somewhat more readable form require "ctime.pl"; require "ptime.pl"; $AF_INET = 2; open(TABLE, ") { chop; $german_net{$_} = 1; } close(TABLE); setservent(1); while(($na, $al, $po, $pr) = getservent) { if($pr eq "udp") { $udp[$po] = $na; } elsif($pr eq "tcp") { $tcp[$po] = $na; } } endservent; while(<>) { chop; ($x_time, $x_proto, $x_from, $x_fromport, $x_to, $x_toport, $x_size, $dev) = split; $date = &ptime("%a %d.%m.%y %T",$x_time); $h1 = &hbyaddr($x_from); $h2 = &hbyaddr($x_to); $g1 = &is_german($x_from) ? "G" : "I"; $g2 = &is_german($x_to) ? "G" : "I"; if(!(($proto) = getprotobynumber($x_proto))) {$proto = $x_proto;}; if($proto eq 'udp') { if(!(($port1) = $udp[$x_fromport])) {$port1 = $x_fromport;}; if(!(($port2) = $udp[$x_toport])) {$port2 = $x_toport;}; } elsif($proto eq 'tcp') { if(!(($port1) = $tcp[$x_fromport])) {$port1 = $x_fromport;}; if(!(($port2) = $tcp[$x_toport])) {$port2 = $x_toport;}; } else { $port1 = $x_fromport; $port2 = $x_toport; } #print "$date\t$proto\t$h1\t$port1\t$h2\t$port2\t$x_size\t$g1\t$g2\n"; printf ("%21s %-4s %-4s %1s %1s %8d %8s -> %-8s %s -> %s\n",$date, $dev, $proto, $g1, $g2, $x_size, $port1, $port2, $h1, $h2); } sub hbyaddr { local($addr) = @_; local($ipaddr, $host_name); if(! ($host_name = $ip_cache{$addr})) { print "[lookup] " if $debug; $ipaddr=pack("C4",split(/\./,$addr)); if (!(($host_name, $aliases, $addrtype, $length, @addrs) = gethostbyaddr($ipaddr,$AF_INET))) { print "[lookup failed] " if $debug; $host_name = $addr; } $ip_cache{$addr} = $host_name; } print ">>>\"$host_name\"<<< " if $debug; $host_name; } sub is_german { # Algorithmus: # Wir schneiden jeweils das letzte Adress-Byte ab und schauen nach, ob # das Resultat in der Liste der deutschen Netze vorkommt. Es wird # hchstens 3mal abgeschnitten (class-A Netz). local($ipaddr) = @_; $cuts = 1; while($cuts < 4) { $ipaddr =~ s/(.*)\.[0-9]{1,3}$/$1/; $cuts++; if(defined($german_net{$ipaddr})) { return 1; } } return 0; } sub i2s { local($zahl) = @_; local($s) = "$zahl"; while ($s =~ s/(.*\d)(\d\d\d)/$1.$2/) { } $s; } net-acct-0.71-glibc2/contrib/ 40755 1750 144 0 6172246634 14730 5ustar phirateusersnet-acct-0.71-glibc2/contrib/blitz-net-acct-scripts.tar.gz100644 1750 144 3235 5753611540 22460 0ustar phirateusers`/net-acct-scripts.tarWmsFW+62d=!6{&M2N'd!j!)mҟݻ$㶎3j=ֽw839Cc+t{.l-@fuw:0-~MrJ)0—D{,DiȚ~x5&lߵdwMt-s m?#z q(d`S`\b?!)e]5C 늋]}?ht2z1<|̷dn3? \*8M篎~]͛tP=j4z3:(aąxVZs)7 ;1lwn5 ~YBBh`%4( ᤪ|ޙ>/k_~Nmq_wcL0 s1p.k÷A&$ mu0IpM0خ= Na ,NDgdrE`#CXͣ@qx%!S,' ȱ#Vϲ+:qrr8}zJEbjoF&͓ Reply-To: pierno@netway.it To: Ulrich Callmeier Subject: net-acct 0.4 and my script [ ... ] I send you the script I'm using to extract and add ppp traffic. It's very simple but works OK. I didn't write it in perl because I'm a perl beginner and I don't feel yet confortable. If you think this script can be of any usefulness please add it to your contrib directory, it's my vry little contribute to the wonderful Linux Community. [ ... ] ---------------------- CUT HERE ---------------------- #!/bin/sh # # # ppp-acct.sh -- Traffic accounting for dial-up ppp users. # # # # Author: Eugenio Pierno, 1996. # Email: pierno@netway.it # Organization: Netway Internet Provider # Location: Naples, Italy # # # What is it? This script is based on the output of net-acct-0.4 # by Ulrich Callmeier (uc@brian.lunetix.de). # It is intended for a system where you need to know # exactly how much traffic every dial-up ppp user is # generating. # It works on the assumption you have succesfully # configured the "dinamic slip/ppp" options in # /etc/nacctab. # # How does it work? # It clears the default output file "net-acct" and # it does keep an updated value of the traffic of # each dial-up ppp user creating a file "traffico" # in each user home directory. # The file will only contain the total amount of # traffic the user has made since you started logging. # Just make sure you are not accounting local # traffic but only ppp traffic (see the options # in /etc/nacctab). # # How to use it? # Simply put this script in /usr/local/bin and make an entry # in your crontab which looks like: # * */1 * * * exec /usr/local/bin/ppp-acct.sh >& /dev/null # This will execute the script every hour. # # # Directory where the output file "net-acct" is kept. # Adjust this to your site. W3="/usr/var/acct/" # Directory where the users' home directories are kept. # In my system this is /usr/home # Adjust this to your site. W4="/usr/home/" #--------------------------------------------- # Don't need to adjust anything from here down #--------------------------------------------- # Work on a copy of the output file cp ${W3}net-acct ${W3}net-acct.tmp cat /dev/null > ${W3}net-acct # Extract ppp lines from "net-acct" and put them in "ppp-acct" cat ${W3}net-acct.tmp | grep ppp | cut -f7,9 | sort +1 > ${W3}ppp-acct # Delete temporary file rm -f ${W3}net-acct.tmp # Command Block which reads "ppp-acct" and puts ppp traffic in a file # called "traffico" in each user home directory. # If the user had no previous traffic an empty file is created, otherwise # new traffic is added to old traffic. { while read traffic login; do if [ -e ${W4}$login/traffico ]; then OLD_TRAFFIC=`cat ${W4}$login/traffico` declare -i SOMMA=`expr $OLD_TRAFFIC + $traffic` echo $SOMMA > ${W4}$login/traffico else echo $traffic > ${W4}$login/traffico fi done } < ${W3}ppp-acct # Remove ppp-acct rm -f ${W3}ppp-acct -------------------------- CUT HERE --------------------------- ~*-,._.,-*~'`^`'~*-,._.,-*~'`^`'~*-,._.,-*~'`^`'~*-,._.,-*~'`^`'~*-,._.,-*~ Eugenio Pierno Phone: + 81-7624433 Network Administrator Fax: + 81-7623909 Netway Internet Provider Email: pierno@netway.it ITnet Group, Naples, Italy http://www.netway.it/ ~*-,._.,-*~'`^`'~*-,._.,-*~'`^`'~*-,._.,-*~'`^`'~*-,._.,-*~'`^`'~*-,._.,-*~ ITnet is a member of PIPEX International. ITnet is associated to CIX and RIPE.