diff options
author | Graydon, Tracy <tracy.graydon@intel.com> | 2013-02-01 15:06:25 -0800 |
---|---|---|
committer | Graydon, Tracy <tracy.graydon@intel.com> | 2013-02-01 15:06:25 -0800 |
commit | d3d3d30bc7ae0ddcce814d510136f3c43467ddc2 (patch) | |
tree | b7c7b74337b993ff79ed69b9c9d071a0a370b5d0 | |
download | dropwatch-d3d3d30bc7ae0ddcce814d510136f3c43467ddc2.tar.gz dropwatch-d3d3d30bc7ae0ddcce814d510136f3c43467ddc2.tar.bz2 dropwatch-d3d3d30bc7ae0ddcce814d510136f3c43467ddc2.zip |
Initial commit for Tizen ExtrasHEADsubmit/2.0alpha/20130201.230646accepted/2.0alpha/20130201.2258362.0alpha
-rw-r--r-- | COPYING | 340 | ||||
-rw-r--r-- | Makefile | 47 | ||||
-rw-r--r-- | README | 37 | ||||
-rw-r--r-- | doc/dropwatch.1 | 36 | ||||
-rw-r--r-- | packaging/dropwatch.spec | 46 | ||||
-rw-r--r-- | spec/dropwatch.spec | 43 | ||||
-rw-r--r-- | src/Makefile | 16 | ||||
-rw-r--r-- | src/lookup.c | 102 | ||||
-rw-r--r-- | src/lookup.h | 64 | ||||
-rw-r--r-- | src/lookup_bfd.c | 75 | ||||
-rw-r--r-- | src/lookup_kas.c | 163 | ||||
-rw-r--r-- | src/main.c | 613 | ||||
-rw-r--r-- | src/net_dropmon.h | 56 |
13 files changed, 1638 insertions, 0 deletions
@@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..56d04ae --- /dev/null +++ b/Makefile @@ -0,0 +1,47 @@ +REL_VERSION:=1.4 +ROOT_DIR=$(shell pwd) + +all: release srpm rpm + +rel-upload: release + scp $(ROOT_DIR)/dropwatch-$(REL_VERSION).tbz2 fedorahosted.org:dropwatch + +release: tarball + +tarball: + mkdir -p stage + ln -s $(ROOT_DIR) stage/dropwatch-$(REL_VERSION) + tar jchf $(ROOT_DIR)/stage/dropwatch-$(REL_VERSION).tbz2 --exclude \.git --exclude stage -C stage dropwatch-$(REL_VERSION)/ + mv $(ROOT_DIR)/stage/*.tbz2 $(ROOT_DIR) + rm -rf stage + +srpm: tarball + $(shell sed -e"s/MAKEFILE_VERSION/$(REL_VERSION)/" ./spec/dropwatch.spec > ./dropwatch.spec) + rpmbuild --define "_sourcedir $(ROOT_DIR)" --define "_srcrpmdir $(ROOT_DIR)" -bs $(ROOT_DIR)/dropwatch.spec + +rpm: srpm + mkdir -p BUILD + mkdir -p RPMS + rpmbuild --define "_sourcedir $(ROOT_DIR)" --define "_builddir $(ROOT_DIR)/BUILD" --define "_rpmdir $(ROOT_DIR)/RPMS" -bb $(ROOT_DIR)/dropwatch.spec + rm -rf BUILD + +clean: + rm -f $(ROOT_DIR)/dropwatch*.tbz2 $(ROOT_DIR)/*.rpm $(ROOT_DIR)/*.spec + rm -rf BUILD + rm -rf RPMS + rm -rf stage + make -C src clean + +build: + make -C src all + +build_clean: + make -c src clean + +tag: + git tag -s -u $(GIT_AUTHOR_EMAIL) -m"Tag V$(REL_VERSION)" V$(REL_VERSION) + +git-upload: + git push --all ssh://git.fedorahosted.org/git/dropwatch.git + git push --tags ssh://git.fedorahosted.org/git/dropwatch.git + @@ -0,0 +1,37 @@ +Thanks for Downloading dropwatch! + +What is Dropwatch? +Dropwatch is a project I started in an effort to improve the ability for +developers and system administrator to diagnose problems in the Linux Networking +stack, specifically in our ability to diagnose where packets are getting +dropped. From my probing, I've come to the conclusion that there are four main +shortcommings in our current environment: + +1) Consolidation, or lack thereof. Currently, if you would like to check on the +status of dropped packets in the kernel, you need to check at least 3 places, +and possibly more: The /proc/net/snmp file, the netstat utility, the tc utility, +and ethool. This project aims to consolidate several of those checks into one +tool, making it easier for a sysadmin or developer to detect lost packets + +2) Clarity of information. Dropped packets are not obvious. a sysadmin needs +to be intimately familiar with each of the above tools to understand which +events or statistics correlate to a dropped packet and which do not. While that +is often self evident, it is also often not. Dropwatch aims to improve that +clarity + +3) Ambiguity. Even when a dropped packet is detected, the causes for those +dropped packets are not always clear. Does a UDPInError mean the application +receive buffer was full, or does it mean its checksum was bad? Dropwatch +attempts to disambiguate the causes for dropped packets. + +4) Performance. Utilties can be written to aggregate the data in the various +other utilities to solve some of these problems, but such solutions require +periodic polling of several interfaces, which is far from optimal, especially +when lost packets are rare. This solution improves on the performance aspect by +implementing a kernel feature which allows asyncronous notification of dropped +packets when they happen. + +Questions +Feel free to email me directly at nhorman@redhat.com with question, or if you +find a bug, open a trac ticket at https://fedorahosted.org/dropwatch/ + diff --git a/doc/dropwatch.1 b/doc/dropwatch.1 new file mode 100644 index 0000000..d9e754e --- /dev/null +++ b/doc/dropwatch.1 @@ -0,0 +1,36 @@ +.PU +.TH dropwatch "1" "Mar 2009" "Neil Horman" +.SH NAME +dropwatch - kernel dropped packet monitoring utility +.SH SYNOPSIS +.B dropwatch [-l <method> | list] +.SH DESCRIPTION +.I dropwatch +dropwatch is an interactive utility for monitoring and recording packets that +are dropped by the kernel +.SH OPTIONS +.TP +.B -l <method> | list +Select the translation method to use when a drop alert arrives. By default the +raw instruction pointer of a drop location is output, but by the use of the -l +option, we can assign a translation method so that the instruction pointer can +be translated into function names. Currently supported lookup methods are: +.PP +.B kas - use /proc/kallsyms to lookup instruction pointers to function mappings +.SH INTERACTIVE COMMANDS +.TP +.B start +Tells the kernel to start reporting dropped packets +.TP +.B stop +Tells the kernel to discontinue reporting dropped packets +.TP +.B exit +Exits the dropmonitor program +.TP +.B help +Displays summary of all commands +.TP +.B set alertlimit <value> +Sets a triggerpoint to stop monitoring for dropped packets after <value> alerts +have been received diff --git a/packaging/dropwatch.spec b/packaging/dropwatch.spec new file mode 100644 index 0000000..7ac0f51 --- /dev/null +++ b/packaging/dropwatch.spec @@ -0,0 +1,46 @@ +Summary: Kernel dropped packet monitor +Name: dropwatch +Version: 1.4 +Release: 1 +Source0: https://fedorahosted.org/releases/d/r/dropwatch/dropwatch-%{version}.tbz2 +URL: http://fedorahosted.org/dropwatch +License: GPLv2+ +Group: Applications/System +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root +BuildRequires: kernel-adaptation-intel-automotive-devel +BuildRequires: libnl2-devel +BuildRequires: readline-devel +BuildRequires: binutils-devel +BuildRequires: ncurses-devel +Requires: libnl2 +Requires: readline + +%description +dropwatch is an utility to interface to the kernel to monitor for dropped +network packets. + +%prep +%setup -q + +%build +cd src +export CFLAGS=$RPM_OPT_FLAGS +make + +%install +rm -rf $RPM_BUILD_ROOT +mkdir -p $RPM_BUILD_ROOT%{_bindir} +mkdir -p $RPM_BUILD_ROOT%{_mandir}/man1 +install -m0755 src/dropwatch $RPM_BUILD_ROOT%{_bindir} +install -m0644 doc/dropwatch.1 $RPM_BUILD_ROOT%{_mandir}/man1 + +%clean +rm -rf $RPM_BUILD_ROOT + + +%files +%defattr(-,root,root,-) +%{_bindir}/* +%{_mandir}/man1/* +%doc README +%doc COPYING diff --git a/spec/dropwatch.spec b/spec/dropwatch.spec new file mode 100644 index 0000000..02d48aa --- /dev/null +++ b/spec/dropwatch.spec @@ -0,0 +1,43 @@ +%define uversion MAKEFILE_VERSION +Summary: Kernel dropped packet monitor +Name: dropwatch +Version: %{uversion} +Release: 0%{?dist} +Source0: https://fedorahosted.org/releases/d/r/dropwatch/dropwatch-%{uversion}.tbz2 +URL: http://fedorahosted.org/dropwatch +License: GPLv2+ +Group: Applications/System +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root +BuildRequires: kernel-devel, libnl-devel, readline-devel +BuildRequires: binutils-devel, binutils-static pkgconfig +Requires: libnl, readline + +%description +dropwatch is an utility to interface to the kernel to monitor for dropped +network packets. + +%prep +%setup -q + +%build +cd src +export CFLAGS=$RPM_OPT_FLAGS +make + +%install +rm -rf $RPM_BUILD_ROOT +mkdir -p $RPM_BUILD_ROOT%{_bindir} +mkdir -p $RPM_BUILD_ROOT%{_mandir}/man1 +install -m0755 src/dropwatch $RPM_BUILD_ROOT%{_bindir} +install -m0644 doc/dropwatch.1 $RPM_BUILD_ROOT%{_mandir}/man1 + +%clean +rm -rf $RPM_BUILD_ROOT + + +%files +%defattr(-,root,root,-) +%{_bindir}/* +%{_mandir}/man1/* +%doc README +%doc COPYING diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..d131f90 --- /dev/null +++ b/src/Makefile @@ -0,0 +1,16 @@ +all: dropwatch +CFLAGS += -c -g -D_GNU_SOURCE -Wall -Werror +CFLAGS += `pkg-config --cflags libnl-2.0` +LDFLAGS += -lbfd -lreadline -ltermcap +LDFLAGS += `pkg-config --libs libnl-2.0` +OBJFILES := main.o lookup.o\ + lookup_bfd.o lookup_kas.o + +dropwatch: $(OBJFILES) + gcc -g -o dropwatch $(OBJFILES) $(LDFLAGS) + +%.o: %.c + gcc $(CFLAGS) $< +clean: + rm -f dropwatch *.o + diff --git a/src/lookup.c b/src/lookup.c new file mode 100644 index 0000000..ba54991 --- /dev/null +++ b/src/lookup.c @@ -0,0 +1,102 @@ +/* + * Copyright (C) 2009, Neil Horman <nhorman@redhat.com> + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +/* + * This is a translator. given an input address, this will convert it into a + * function and offset. Unless overridden, it will automatically determine + * tranlations using the following methods, in order of priority: + * 1) /usr/lib/debug/<kernel version> using libbfd + * 2) /proc/kallsyms + */ +#include <stdlib.h> +#include <stdio.h> +#include <sys/utsname.h> +#include <bfd.h> +#include <string.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> + +#include "lookup.h" + +extern struct lookup_methods bfd_methods; +extern struct lookup_methods kallsym_methods; + +static int lookup_null_init(void) +{ + printf("Initalizing null lookup method\n"); + return 0; +} + +static int lookup_null_sym(void *pc, struct loc_result *location) +{ + /* + * In the null method, every lookup fails + */ + return 1; +} + +static struct lookup_methods null_methods = { + lookup_null_init, + lookup_null_sym, +}; + +static struct lookup_methods *methods = NULL; + +int init_lookup(lookup_init_method_t method) +{ + int rc; + switch (method) { + case METHOD_NULL: + /* + * Don't actuall do any lookups, + * just pretend everything is + * not found + */ + methods = &null_methods; + break; + case METHOD_AUTO: + methods = &bfd_methods; + if (methods->lookup_init() == 0) + return 0; + methods = &kallsym_methods; + if (methods->lookup_init() == 0) + return 0; + methods = NULL; + return -1; + case METHOD_DEBUGINFO: + methods = &bfd_methods; + break; + case METHOD_KALLSYMS: + methods = &kallsym_methods; + break; + } + + rc = methods->lookup_init(); + if (rc < 0) + methods = NULL; + return rc; +} + +int lookup_symbol(void *pc, struct loc_result *loc) +{ + if (loc == NULL) + return 1; + return methods->get_symbol(pc, loc); +} diff --git a/src/lookup.h b/src/lookup.h new file mode 100644 index 0000000..e6568d8 --- /dev/null +++ b/src/lookup.h @@ -0,0 +1,64 @@ +/* + * Copyright (C) 2009, Neil Horman <nhorman@redhat.com> + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +/* + * This is a translator. given an input address, this will convert it into a + * function and offset. Unless overridden, it will automatically determine + * tranlations using the following methods, in order of priority: + * 1) /usr/lib/debug/<kernel version> using libbfd + * 2) /proc/kallsyms + */ + +#include <stdlib.h> +#include <asm/types.h> + + +/* + * Initalization routine + * INPUTS: + * method - enum describing how to do translation + * * METHOD_NULL : Just print pc values, not symbols + * * METHOD_AUTO : automatic search for best method + * * METHOD_DEBUGINFO : use debuginfo package + * * METHOD_KALLSYMS : use /proc/kallsyms + * returns: + * * 0 : initalization succeded + * * < 0 : initalization failed + */ +typedef enum { + METHOD_NULL = 0, + METHOD_AUTO, + METHOD_DEBUGINFO, + METHOD_KALLSYMS +} lookup_init_method_t; + +struct loc_result { + const char *symbol; + __u64 offset; +}; + +int init_lookup(lookup_init_method_t method); +int lookup_symbol(void *pc, struct loc_result *location); + +struct lookup_methods { + int (*lookup_init)(void); + int(*get_symbol)(void *pc, struct loc_result *location); +}; + + diff --git a/src/lookup_bfd.c b/src/lookup_bfd.c new file mode 100644 index 0000000..cc7010b --- /dev/null +++ b/src/lookup_bfd.c @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2009, Neil Horman <nhorman@redhat.com> + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +/* + * This is a translator. given an input address, this will convert it into a + * symbollic name using the bfd library + */ + +#include <stdlib.h> +#include <stdio.h> +#include <sys/utsname.h> +#include <bfd.h> +#include <string.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> + +#include "lookup.h" + + +static int lookup_bfd_init(void) +{ + struct utsname uts; + struct stat sb; + char *dbibuf; + + /* + *Start by determining if we have the required debuginfo package + *here + */ + if(uname(&uts)<0) + return-1; + + dbibuf = malloc(strlen("/usr/lib/debug/lib/modules") + strlen(uts.release) + 1); + sprintf(dbibuf,"/usr/lib/debug/lib/modules/%s", uts.release); + if (stat(dbibuf,&sb) < 0) { + free(dbibuf); + goto out_fail; + } + + free(dbibuf); + + + bfd_init(); + return 0; + +out_fail: + return-1; +} + +static int lookup_bfd_sym(void *pc, struct loc_result *location) +{ + return 1; +} + +struct lookup_methods bfd_methods = { + lookup_bfd_init, + lookup_bfd_sym, +}; diff --git a/src/lookup_kas.c b/src/lookup_kas.c new file mode 100644 index 0000000..09fad98 --- /dev/null +++ b/src/lookup_kas.c @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2009, Neil Horman <nhorman@redhat.com> + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +/* + * This is a translator. given an input address, this will convert it into a + * symbolic name using /proc/kallsyms + */ + +#include <stdlib.h> +#include <stdio.h> +#include <sys/utsname.h> +#include <bfd.h> +#include <string.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/queue.h> + +#include "lookup.h" + +struct symbol_entry { + char *sym_name; + __u64 start; + __u64 end; + LIST_ENTRY(symbol_entry) list; +}; + +LIST_HEAD(sym_list, symbol_entry); + +/* + * This is our cache of symbols that we've previously looked up + */ +static struct sym_list sym_list_head = {NULL}; + + +static int lookup_kas_cache( __u64 pc, struct loc_result *location) +{ + struct symbol_entry *sym; + + LIST_FOREACH(sym, &sym_list_head, list) { + if ((pc >= sym->start) && + (pc <= sym->end)) { + location->symbol = sym->sym_name; + location->offset = (pc - sym->start); + return 0; + } + } + + return 1; +} + +static void kas_add_cache(__u64 start, __u64 end, char *name) +{ + struct symbol_entry *sym = NULL; + + sym = malloc(sizeof(struct symbol_entry)); + if (!sym) + return; + + sym->start = start; + sym->end = end; + sym->sym_name = name; + + LIST_INSERT_HEAD(&sym_list_head, sym, list); + return; +} + +static int lookup_kas_proc(__u64 pc, struct loc_result *location) +{ + FILE *pf; + __u64 ppc; + __u64 uppc, ulpc, uipc; + char *name, *last_name; + + pf = fopen("/proc/kallsyms", "r"); + + if (!pf) + return 1; + + last_name = NULL; + uipc = pc; + ulpc = 0; + while (!feof(pf)) { + /* + * Each line of /proc/kallsyms is formatteded as: + * - "%pK %c %s\n" (for kernel internal symbols), or + * - "%pK %c %s\t[%s]\n" (for module-provided symbols) + */ + if (fscanf(pf, "%llx %*s %as [ %*[^]] ]", &ppc, &name) < 0) { + perror("Error Scanning File: "); + break; + } + + uppc = (__u64)ppc; + if ((uipc >= ulpc) && + (uipc < uppc)) { + /* + * The last symbol we looked at + * was a hit, record and return it + * Note that we don't free last_name + * here, because the cache is using it + */ + kas_add_cache(ulpc, uppc-1, last_name); + fclose(pf); + free(name); + return lookup_kas_cache(pc, location); + } + + /* + * Advance all our state holders + */ + free(last_name); + last_name = name; + ulpc = uppc; + } + + fclose(pf); + return 1; +} + +static int lookup_kas_init(void) +{ + printf("Initalizing kallsyms db\n"); + + return 0; +} + + +static int lookup_kas_sym(void *pc, struct loc_result *location) +{ + __u64 pcv; + + memset(&pcv, 0, sizeof(__u64)); + + memcpy(&pcv, &pc, sizeof(void *)); + + if (!lookup_kas_cache(pcv, location)) + return 0; + + return lookup_kas_proc(pcv, location); +} + +struct lookup_methods kallsym_methods = { + lookup_kas_init, + lookup_kas_sym, +}; + diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..caccaf1 --- /dev/null +++ b/src/main.c @@ -0,0 +1,613 @@ +/* + * Copyright (C) 2009, Neil Horman <nhorman@redhat.com> + * + * This program file 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; version 2 of the License. + * + * 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 in a file named COPYING; if not, write to the + * Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA + */ + +/* + * Opens our netlink socket. Returns the socket descriptor or < 0 on error + */ + +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <signal.h> +#include <stdint.h> +#include <getopt.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/socket.h> +#include <sys/queue.h> +#include <readline/readline.h> +#include <readline/history.h> +#include <asm/types.h> +#include <netlink/netlink.h> +#include <netlink/genl/genl.h> +#include <netlink/genl/ctrl.h> + +#include "net_dropmon.h" +#include "lookup.h" + +/* + * This is just in place until the kernel changes get comitted + */ +#ifndef NETLINK_DRPMON +#define NETLINK_DRPMON 20 +#endif + +struct netlink_message { + void *msg; + struct nl_msg *nlbuf; + int refcnt; + LIST_ENTRY(netlink_message) ack_list_element; + int seq; + void (*ack_cb)(struct netlink_message *amsg, struct netlink_message *msg, int err); +}; + +LIST_HEAD(ack_list, netlink_message); + +struct ack_list ack_list_head = {NULL}; + +unsigned long alimit = 0; +unsigned long acount = 0; + +void handle_dm_alert_msg(struct netlink_message *msg, int err); +void handle_dm_config_msg(struct netlink_message *msg, int err); +void handle_dm_start_msg(struct netlink_message *amsg, struct netlink_message *msg, int err); +void handle_dm_stop_msg(struct netlink_message *amsg, struct netlink_message *msg, int err); +int disable_drop_monitor(); + + +static void(*type_cb[_NET_DM_CMD_MAX])(struct netlink_message *, int err) = { + NULL, + handle_dm_alert_msg, + handle_dm_config_msg, + NULL, + NULL +}; + +static struct nl_sock *nsd; +static int nsf; + +enum { + STATE_IDLE = 0, + STATE_ACTIVATING, + STATE_RECEIVING, + STATE_RQST_DEACTIVATE, + STATE_RQST_ACTIVATE, + STATE_DEACTIVATING, + STATE_FAILED, + STATE_EXIT, +}; + +static int state = STATE_IDLE; + +void sigint_handler(int signum) +{ + if ((state == STATE_RECEIVING) || + (state == STATE_RQST_DEACTIVATE)) { + disable_drop_monitor(); + state = STATE_DEACTIVATING; + } + else + printf("Got a sigint while not receiving\n"); + return; +} + +struct nl_sock *setup_netlink_socket() +{ + struct nl_sock *sd; + int family; + + + sd = nl_socket_alloc(); + + genl_connect(sd); + + family = genl_ctrl_resolve(sd, "NET_DM"); + + if (family < 0) { + printf("Unable to find NET_DM family, dropwatch can't work\n"); + goto out_close; + } + + nsf = family; + + nl_close(sd); + nl_socket_free(sd); + + sd = nl_socket_alloc(); + nl_join_groups(sd, NET_DM_GRP_ALERT); + + nl_connect(sd, NETLINK_GENERIC); + + return sd; + +out_close: + nl_close(sd); + nl_socket_free(sd); + return NULL; + +} + +struct netlink_message *alloc_netlink_msg(uint32_t type, uint16_t flags, size_t size) +{ + struct netlink_message *msg; + static uint32_t seq = 0; + + msg = (struct netlink_message *)malloc(sizeof(struct netlink_message)); + + if (!msg) + return NULL; + + msg->refcnt = 1; + msg->nlbuf = nlmsg_alloc(); + msg->msg = genlmsg_put(msg->nlbuf, 0, seq, nsf, size, flags, type, 1); + + msg->ack_cb = NULL; + msg->seq = seq++; + + return msg; +} + +void set_ack_cb(struct netlink_message *msg, + void (*cb)(struct netlink_message *, struct netlink_message *, int)) +{ + + if (msg->ack_cb) + return; + + msg->ack_cb = cb; + msg->refcnt++; + LIST_INSERT_HEAD(&ack_list_head, msg, ack_list_element); +} + + +struct netlink_message *wrap_netlink_msg(struct nlmsghdr *buf) +{ + struct netlink_message *msg; + + msg = (struct netlink_message *)malloc(sizeof(struct netlink_message)); + if (msg) { + msg->refcnt = 1; + msg->msg = buf; + msg->nlbuf = NULL; + } + + return msg; +} + +int free_netlink_msg(struct netlink_message *msg) +{ + int refcnt; + + msg->refcnt--; + + refcnt = msg->refcnt; + + if (!refcnt) { + if (msg->nlbuf) + nlmsg_free(msg->nlbuf); + else + free(msg->msg); + free(msg); + } + + return refcnt; +} + +int send_netlink_message(struct netlink_message *msg) +{ + return nl_send(nsd, msg->nlbuf); +} + +struct netlink_message *recv_netlink_message(int *err) +{ + static unsigned char *buf; + struct netlink_message *msg; + struct genlmsghdr *glm; + struct sockaddr_nl nla; + int type; + int rc; + + *err = 0; + + do { + rc = nl_recv(nsd, &nla, &buf, NULL); + if (rc < 0) { + switch (errno) { + case EINTR: + /* + * Take a pass throught the state loop + */ + return NULL; + break; + default: + perror("Receive operation failed:"); + return NULL; + break; + } + } + } while (rc == 0); + + msg = wrap_netlink_msg((struct nlmsghdr *)buf); + + type = ((struct nlmsghdr *)msg->msg)->nlmsg_type; + + /* + * Note the NLMSG_ERROR is overloaded + * Its also used to deliver ACKs + */ + if (type == NLMSG_ERROR) { + struct netlink_message *am; + struct nlmsgerr *errm = nlmsg_data(msg->msg); + LIST_FOREACH(am, &ack_list_head, ack_list_element) { + if (am->seq == errm->msg.nlmsg_seq) + break; + } + + if (am) { + LIST_REMOVE(am, ack_list_element); + am->ack_cb(msg, am, errm->error); + free_netlink_msg(am); + } else { + printf("Got an unexpected ack for sequence %d\n", errm->msg.nlmsg_seq); + } + + free_netlink_msg(msg); + return NULL; + } + + glm = nlmsg_data(msg->msg); + type = glm->cmd; + + if ((type > NET_DM_CMD_MAX) || + (type <= NET_DM_CMD_UNSPEC)) { + printf("Received message of unknown type %d\n", + type); + free_netlink_msg(msg); + return NULL; + } + + return msg; +} + +void process_rx_message(void) +{ + struct netlink_message *msg; + int err; + int type; + sigset_t bs; + + sigemptyset(&bs); + sigaddset(&bs, SIGINT); + sigprocmask(SIG_UNBLOCK, &bs, NULL); + msg = recv_netlink_message(&err); + sigprocmask(SIG_BLOCK, &bs, NULL); + + if (msg) { + struct nlmsghdr *nlh = msg->msg; + struct genlmsghdr *glh = nlmsg_data(nlh); + type = glh->cmd; + type_cb[type](msg, err); + } + return; +} + + + +/* + * These are the received message handlers + */ +void handle_dm_alert_msg(struct netlink_message *msg, int err) +{ + int i; + struct nlmsghdr *nlh = msg->msg; + struct genlmsghdr *glh = nlmsg_data(nlh); + struct loc_result res; + struct net_dm_alert_msg *alert = nla_data(genlmsg_data(glh)); + + if (state != STATE_RECEIVING) + goto out_free; + + + + for (i=0; i < alert->entries; i++) { + void *location; + memcpy(&location, alert->points[i].pc, sizeof(void *)); + if (lookup_symbol(location, &res)) + printf ("%d drops at location %p\n", alert->points[i].count, location); + else + printf ("%d drops at %s+%llx (%p)\n", + alert->points[i].count, res.symbol, res.offset, location); + acount++; + if (alimit && (acount == alimit)) { + printf("Alert limit reached, deactivating!\n"); + state = STATE_RQST_DEACTIVATE; + } + } + +out_free: + free_netlink_msg(msg); +} + +void handle_dm_config_msg(struct netlink_message *msg, int err) +{ + printf("Got a config message\n"); +} + +void handle_dm_start_msg(struct netlink_message *amsg, struct netlink_message *msg, int err) +{ + if (err != 0) { + char *erm = strerror(err*-1); + printf("Failed activation request, error: %s\n", erm); + state = STATE_FAILED; + goto out; + } + + if (state == STATE_ACTIVATING) { + struct sigaction act; + memset(&act, 0, sizeof(struct sigaction)); + act.sa_handler = sigint_handler; + act.sa_flags = SA_RESETHAND; + + printf("Kernel monitoring activated.\n"); + printf("Issue Ctrl-C to stop monitoring\n"); + sigaction(SIGINT, &act, NULL); + + state = STATE_RECEIVING; + } else { + printf("Odd, the kernel told us that it activated and we didn't ask\n"); + state = STATE_FAILED; + } +out: + return; +} + +void handle_dm_stop_msg(struct netlink_message *amsg, struct netlink_message *msg, int err) +{ + char *erm; + + if ((err == 0) || (err == -EAGAIN)) { + printf("Got a stop message\n"); + state = STATE_IDLE; + } else { + erm = strerror(err*-1); + printf("Stop request failed, error: %s\n", erm); + } + +} + +int enable_drop_monitor() +{ + struct netlink_message *msg; + + msg = alloc_netlink_msg(NET_DM_CMD_START, NLM_F_REQUEST|NLM_F_ACK, 0); + + set_ack_cb(msg, handle_dm_start_msg); + + return send_netlink_message(msg); +} + +int disable_drop_monitor() +{ + struct netlink_message *msg; + + msg = alloc_netlink_msg(NET_DM_CMD_STOP, NLM_F_REQUEST|NLM_F_ACK, 0); + + set_ack_cb(msg, handle_dm_stop_msg); + + return send_netlink_message(msg); +} + +void display_help() +{ + printf("Command Syntax:\n"); + printf("exit\t\t\t\t - Quit dropwatch\n"); + printf("help\t\t\t\t - Display this message\n"); + printf("set:\n"); + printf("\talertlimit <number>\t - caputre only this many alert packets\n"); + printf("start\t\t\t\t - start capture\n"); + printf("stop\t\t\t\t - stop capture\n"); +} + +void enter_command_line_mode() +{ + char *input; + + do { + input = readline("dropwatch> "); + + if (input == NULL) { + /* Someone closed stdin on us */ + printf("Terminating dropwatch...\n"); + state = STATE_EXIT; + break; + } + + if (!strcmp(input,"start")) { + state = STATE_RQST_ACTIVATE; + break; + } + + if (!strcmp(input, "stop")) { + state = STATE_RQST_DEACTIVATE; + break; + } + + if (!strcmp(input, "exit")) { + state = STATE_EXIT; + break; + } + + if (!strcmp (input, "help")) { + display_help(); + goto next_input; + } + + if (!strncmp(input, "set", 3)) { + char *ninput = input+4; + if (!strncmp(ninput, "alertlimit", 10)) { + alimit = strtoul(ninput+10, NULL, 10); + printf("setting alert capture limit to %lu\n", + alimit); + goto next_input; + } + } +next_input: + free(input); + } while(1); + + free(input); +} + +void enter_state_loop(void) +{ + + int should_rx = 0; + + while (1) { + switch(state) { + + case STATE_IDLE: + should_rx = 0; + enter_command_line_mode(); + break; + case STATE_RQST_ACTIVATE: + printf("Enabling monitoring...\n"); + if (enable_drop_monitor() < 0) { + perror("Unable to send activation msg:"); + state = STATE_FAILED; + } else { + state = STATE_ACTIVATING; + should_rx = 1; + } + + break; + + case STATE_ACTIVATING: + printf("Waiting for activation ack....\n"); + break; + case STATE_RECEIVING: + break; + case STATE_RQST_DEACTIVATE: + printf("Deactivation requested, turning off monitoring\n"); + if (disable_drop_monitor() < 0) { + perror("Unable to send deactivation msg:"); + state = STATE_FAILED; + } else + state = STATE_DEACTIVATING; + should_rx = 1; + break; + case STATE_DEACTIVATING: + printf("Waiting for deactivation ack...\n"); + break; + + case STATE_EXIT: + case STATE_FAILED: + should_rx = 0; + return; + default: + printf("Unknown state received! exiting!\n"); + state = STATE_FAILED; + should_rx = 0; + break; + } + + /* + * After we process our state loop, look to see if we have messages + */ + if (should_rx) + process_rx_message(); + } +} + +struct option options[] = { + {"lmethod", 1, 0, 'l'}, + {0, 0, 0, 0} +}; + +void usage() +{ + printf("dropwatch [-l|--lmethod <method | list>]\n"); +} + +int main (int argc, char **argv) +{ + int c, optind; + lookup_init_method_t meth = METHOD_NULL; + /* + * parse the options + */ + for(;;) { + c = getopt_long(argc, argv, "l:", options, &optind); + + /* are we done parsing ? */ + if (c == -1) + break; + + switch(c) { + + case '?': + usage(); + exit(1); + /* NOTREACHED */ + case 'l': + /* select the lookup method we want to use */ + if (!strncmp(optarg, "list", 4)) { + printf("Available lookup methods:\n"); + printf("kas - use /proc/kallsyms\n"); + exit(0); + } else if (!strncmp(optarg, "kas", 3)) { + meth = METHOD_KALLSYMS; + } else { + printf("Unknown lookup method %s\n", optarg); + exit(1); + } + break; + default: + printf("Unknown option\n"); + usage(); + exit(1); + /* NOTREACHED */ + } + } + + /* + * open up the netlink socket that we need to talk to our dropwatch socket + */ + nsd = setup_netlink_socket(); + + if (nsd == NULL) { + printf("Cleaning up on socket creation error\n"); + goto out; + } + + + /* + * Initalize our lookup library + */ + init_lookup(meth); + + enter_state_loop(); + printf("Shutting down ...\n"); + + nl_close(nsd); + exit(0); +out: + exit(1); +} diff --git a/src/net_dropmon.h b/src/net_dropmon.h new file mode 100644 index 0000000..0217fb8 --- /dev/null +++ b/src/net_dropmon.h @@ -0,0 +1,56 @@ +#ifndef __NET_DROPMON_H +#define __NET_DROPMON_H + +#include <linux/netlink.h> + +struct net_dm_drop_point { + __u8 pc[8]; + __u32 count; +}; + +#define NET_DM_CFG_VERSION 0 +#define NET_DM_CFG_ALERT_COUNT 1 +#define NET_DM_CFG_ALERT_DELAY 2 +#define NET_DM_CFG_MAX 3 + +struct net_dm_config_entry { + __u32 type; + __u64 data __attribute__((aligned(8))); +}; + +struct net_dm_config_msg { + __u32 entries; + struct net_dm_config_entry options[0]; +}; + +struct net_dm_alert_msg { + __u32 entries; + struct net_dm_drop_point points[0]; +}; + +struct net_dm_user_msg { + union { + struct net_dm_config_msg user; + struct net_dm_alert_msg alert; + } u; +}; + + +/* These are the netlink message types for this protocol */ + +enum { + NET_DM_CMD_UNSPEC = 0, + NET_DM_CMD_ALERT, + NET_DM_CMD_CONFIG, + NET_DM_CMD_START, + NET_DM_CMD_STOP, + _NET_DM_CMD_MAX, +}; + +#define NET_DM_CMD_MAX (_NET_DM_CMD_MAX - 1) + +/* + * Our group identifiers + */ +#define NET_DM_GRP_ALERT 1 +#endif |