e7526bbf631f51a3f5da4be9951f394cc35ae39c
[senf.git] / Examples / Sniffer / Mainpage.dox
1 // $Id$
2 //
3 // Copyright (C) 2007
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Stefan Bund <g0dil@berlios.de>
7 //
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 // GNU General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22
23 /** \mainpage Simple packet sniffer reading and dumping raw network packets
24
25     \dontinclude Sniffer.cc
26
27     The Sniffer application is a simple command line network sniffer like \c tcpdump or \c
28     tethereal. The application uses a packet socket to read Ethernet packets from the \c eth0
29     interface and dumps the parsed packets out to the standard output.
30
31     To try out the example application, check out the library, go to the \c %Sniffer
32     directory and execute
33
34     <pre>
35     # scons -u
36     # ./sniffer loop
37     < Hit Ctrl-C when you've seen enough >
38     # ./sniffer scheduler
39     < Hit Ctrl-C when you've seen enough >
40     </pre>
41
42     We will now look at the code which is found in \c Sniffer.cc in the <tt>Examples/%Sniffer</tt>
43     directory. The code starts out by including the necessary headers
44
45     \skip // Custom includes
46     \until #include <senf/Scheduler/Scheduler.hh>
47
48     The example includes two implementations, one using blocking calls and a while loop, the other
49     using the senf::Scheduler for asynchronous event notification. They are implemented in
50     \c loop_main() and \c scheduler_main(). They will be documented below. For now, we skip these
51     implementations and go straight to the \c main() function
52
53     \skip int main(
54     \until return 1;
55     \until }
56
57     This routine simply interprets the first command line argument and dispatches to the required
58     implementation.
59
60     Now lets go back and study each implementation in detail.
61
62     \dontinclude Sniffer.cc
63
64     \section example_loop A Blocking Implementation
65
66     This implementation is found in the \c loop_main function.
67
68     \skip loop_main
69     \until try
70
71     We catch all exceptions in a \c try block. This is good for a deliverable binary. When debugging
72     the application, it might be better to let the exception \c abort the execution so you can get a
73     backtrace of the exception origin in the debugger.
74
75     We create a packet socket and bind it to the interface given as second command line argument.  A
76     packet socket is a linux specific type of socket which returns ethernet packets directly from
77     the network wire. By uncommenting the last line, you may switch the interface into promiscuous
78     mode.
79
80     \until //
81
82     We will now read packets from the socket forever, that is until the user hits Ctrl-C
83
84     \skip while
85     \until while
86
87     The next step is, to parse the data read from the socket as an Ethernet packet
88
89     \until sock.read
90
91     There are several ways to read and parse a packet with different tradeoffs between efficiency
92     and simplicity. The Version we use here is already quite efficient.
93
94     We begin by pre-declaring an uninitialized senf::EthernetPacket instance. By uninitialized we
95     mean, that the instance is not parseable and has a length of 0 bytes. This differs from a
96     default-constructed packet instance which may have initial content and \e is parseable.
97
98     We then tell the socket to read as much data as is available into the packet. The second arg to
99     read specifies the maximum number of bytes to read or 0 to read as much as possible. We pass
100     <tt>packet.data()</tt> to <tt>socket.read</tt> which is an STL compatible container holding the
101     data bytes of our previously created senf::EthernetPacket instance (which is currently empty).
102
103     The next step is to write out the packet to the standard output
104
105     \until \n\n
106
107     The \c dump call will write out a complete representation of the parsed packet data. The Packet
108     library will \e not try to interpret payload data as long as no exact indication of the payload
109     type is available (example: A UDP Payload is not parsed further unless you explicitly tell the
110     library, how to parse it).  Tools like \c tethereal guess the payload type by checking port
111     numbers and the payload data, however this is not advisable for a general purpose packet
112     library.
113
114     The next line, \c hexdump, will write out the \e last packet component. Packets are managed as a
115     chain of headers. The last header is normally a \c DataPacket holding the payload data.
116
117     That's it. We finish of by catching the exception and giving as much detail as possible if an
118     exception is caught
119
120     \until ;
121     \until }
122     \until }
123
124     The \c prettyName function from the \c Utils library is used, to get a nice, printable
125     representation of the \e dynamic type of the exception instance. It is an interface to the g++
126     de-mangler. This is necessary since the \c name member of the C++ \c type_info instance is a
127     mangled name in \c g++.
128
129     That's it for the simple blocking implementation.
130
131     \section example_scheduler Using the Scheduler
132
133     However, we have another one which uses the Scheduler.
134
135     \until }
136
137     The class constructor binds the socket defined as a data member to the correct interface. To
138     tell the scheduler to call us back whenever data is available on the socket, we add a
139     senf::scheduler::FdEvent instance to out class.
140
141     The senf::scheduler::FdEvent constructor takes several arguments:
142     \li a string describing the event.
143     \li the callback to call whenever the event occurs.  The callback is specified as a <a
144         href="http://www.boost.org/doc/libs/release/doc/html/function.html">Boost.Function</a>
145         object. We use the \c senf::membind helper from the Utils library to build such a
146         function object. This helper takes an arbitrary class member and binds it to a specific
147         instance.
148     \li the handle or file descriptor to monitor.
149     \li and the events to watch for.
150
151     \until }
152
153     The public \c run() member is called to run the sniffer.  Here we just forward the call to the
154     scheduler. Calling the Schedulers \c process() method will start the event loop. This call does
155     not return (ok, that's a lie. It does return when \c senf::scheduler::terminate() is called
156     which does not apply here).
157
158     \until {
159
160     The \c dumpPacket() member is called by the scheduler whenever an event on the socket is
161     encountered. The scheduler calls this function with a mask of the events which triggered the
162     call.
163
164     \until };
165
166     The body is absolutely identical to the body of the \c while loop of the blocking
167     implementation. However, the scheduler guarantees, that a read on the socket will not block if
168     the socket is triggered to be readable (even if the socket is not set to non-blocking mode).
169
170     What's left is the \c scheduler_main() function to utilize this code
171
172     \until 0;
173     \until }
174
175     This function is straight forward. The exception handling is the same as in \c loop_main().
176
177     \see \ref senf_components \n
178          \ref senf_build \n
179          <a href="../../../../senf/Socket/doc/html/index.html"><b>libSocket API reference</b></a> \n
180          <a href="../../../../senf/Packets/doc/html/index.html"><b>libPackets API reference</b></a> \n
181          <a href="../../../../senf/Utils/doc/html/index.html"><b>libUtils API reference</b></a>
182  */
183
184 \f
185 // Local Variables:
186 // mode: c++
187 // fill-column: 100
188 // comment-column: 40
189 // c-file-style: "senf"
190 // indent-tabs-mode: nil
191 // ispell-local-dictionary: "american"
192 // compile-command: "scons -u doc"
193 // mode: auto-fill
194 // End: