6 /** \page sniffer Sniffer: A simple example application
8 \dontinclude Sniffer.cc
10 The Sniffer application is a simple command line network sniffer like \c tcpdump or \c
11 tethereal. The application uses a packet socket to read Ethernet packets from the \c eth0
12 interface and dumps the parsed packets out to the standard output.
14 To try out the example application, check out the library, go to the \c Sniffer
20 < Hit Ctrl-C when you've seen enough >
22 < Hit Ctrl-C when you've seen enough >
25 We will now look at the code which is found in \c Sniffer.cc in the \c Sniffer directory. The
26 code starts out by including the necessary headers
28 \skip // Custom includes
31 (The additional includes found in the source but not shown here are part of a short-time fix
32 which will be removed as soon as possible). The example application now contains a helper
33 routine to produce a packet hexdump. We will skip this routine here. The example includes two
34 implementations, one using blocking calls and a while loop, the other using the senf::Scheduler
35 for asynchronous event notification. They are implemented in \c loop_main() and \c
36 scheduler_main(). They will be documented below. For now, we skip these implementations and go
37 straight to the \c main() function
43 This routine simply interprets the first command line argument and dispatches to the required
46 Now lets go back and study each implementation in detail.
48 \dontinclude Sniffer.cc
50 \section example_loop A Blocking Implementation
52 This implementation is found in the \c loop_main function.
57 We catch all exceptions in a \c try block. This is good for a deliverable binary. When debugging
58 the application, it might be better to let the exception \c abort the execution so you can get a
59 backtrace of the exception origin in the debugger.
61 We now create a packet socket and bind it to the \c eth0 interface. A packet socket is a linux
62 specific type of socket which returns ethernet packets directly from the network wire. By
63 uncommenting the last line, you may switch the interface into promiscuous mode.
67 We will now read packets from the socket forever, that is until the user hits Ctrl-C
72 The next step is, to parse the data read from the socket as an Ethernet packet
76 Lets digest this line step by step: We declare a variable named \c packet as a smart pointer to
77 an \c EthernetPacket instance. \c ptr is a typedef member of all Packet classes for the
78 corresponding smart pointer type. We then initialize this pointer with a call to the static \c
79 create member of the \c Packet class. This member takes the type of Packet to parse as a
80 template argument. We pass \c EthernetPacket here. The function takes an iterator range as an
81 argument, and we pass it the complete packet just read by giving the range \c begin() to \c
82 end() of our just read \c data string.
84 The next step is to write out the packet to the standard output
88 The \c dump call will write out a complete representation of the parsed packet data. The Packet
89 library will \e not try to interpret payload data as long as no exact indication of the payload
90 type is available (example: A UDP Payload is not parsed further unless you explicitly tell the
91 library, how to parse it). Tools like \c tethereal guess the payload type by checking port
92 numbers and the payload data, however this is not advisable for a general purpose packet
95 The next line, \c hexdump, will write out the \e last packet component. Packets are managed as a
96 chain of headers. The last header is normally a \c DataPacket holding the payload data.
98 That's it. We finish of by catching the exception and giving as much detail as possible if an
105 The \c prettyName function from the \c Utils library is used, to get a nice, printable
106 representation of the \e dynamic type of the exception instance. It is an interface to the g++
107 demangler. This is necessary since the \c name member of the C++ \c type_info instance is a
108 mangled name in \c g++.
110 That's it for the simple blocking implementation.
112 \section example_scheduler Using the Scheduler
114 However, we have another one which uses the Scheduler. We do this as it will be most of the
115 time: We define a class which manages reading the packets and dumping them out.
119 The class constructor binds the socket defined as a data member to the correct interface.
123 The public \c run() member is called to run the sniffer. It first adds the socket to the
124 Scheduler. The \c add() call takes two Arguments, the socket to bind to (which can be a lot of
125 things and must not necessarily be a socket instance) and callback to call, whenever there is an
126 event on that socket. A third argument may be specified to restrict the events, on which the
127 function is called, here we have left out this argument which defaults to
128 senf::Scheduler::EV_ALL.
130 The callback is specified as a <a
131 href="http://www.boost.org/doc/html/function.html">Boost.Function</a> object. We use the \c
132 senf::membind helper from the Utils library to build such a function object. This helper takes
133 an arbitrary class member and binds it to a specific instance.
137 Calling the Schedulers \c process() method will start the event loop. This call does not return
138 (ok, it does return in special cases if \c senf::Scheduler::terminate() is called which does not
143 The \c dumpPacket() member is called by the scheduler whenever an event on the socket is
144 encountered. The scheduler always passes two arguments: The socket and an event id which
145 identifies the type of event which triggered the call.
149 The body is absolutely identical to the body of the \c while loop of the blocking
150 implementation. However, the scheduler guarantees, that a read on the socket will not block if
151 the socket is triggered to be readable (even if the socket is not set to non-blocking mode).
153 We now only need to provide the \c scheduler_main() function to run this code
158 This function is straight forward. The exception handling is the same as in \c loop_main(). The
159 code then just creates a \c Sniffer instance and calls it's \c run() member.
161 \see \ref components \n
163 <a href="../../../Socket/doc/html/index.html"><b>libSocket API reference</b></a> \n
164 <a href="../../../Packets/doc/html/index.html"><b>libPackets API reference</b></a> \n
165 <a href="../../../Utils/doc/html/index.html"><b>libUtils API reference</b></a>
173 // c-file-style: "senf"
174 // indent-tabs-mode: nil
175 // ispell-local-dictionary: "american"