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