NEW FILE HEADER / COPYRIGHT FORMAT
[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 Sniffer: A simple example application
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 \c Sniffer directory. The
43     code starts out by including the necessary headers
44
45     \skip // Custom includes
46     \until membind
47
48     (The additional includes found in the source but not shown here are part of a short-time fix
49     which will be removed as soon as possible). The example application now contains a helper
50     routine to produce a packet hexdump. We will skip this routine here. The example includes two
51     implementations, one using blocking calls and a while loop, the other using the senf::Scheduler
52     for asynchronous event notification. They are implemented in \c loop_main() and \c
53     scheduler_main(). They will be documented below. For now, we skip these implementations and go
54     straight to the \c main() function
55
56     \skip int main(
57     \until return 1;
58     \until }
59
60     This routine simply interprets the first command line argument and dispatches to the required
61     implementation.
62
63     Now lets go back and study each implementation in detail.
64
65     \dontinclude Sniffer.cc
66
67     \section example_loop A Blocking Implementation
68
69     This implementation is found in the \c loop_main function.
70
71     \skip loop_main
72     \until try
73
74     We catch all exceptions in a \c try block. This is good for a deliverable binary. When debugging
75     the application, it might be better to let the exception \c abort the execution so you can get a
76     backtrace of the exception origin in the debugger.
77
78     We now create a packet socket and bind it to the \c eth0 interface. A packet socket is a linux
79     specific type of socket which returns ethernet packets directly from the network wire. By
80     uncommenting the last line, you may switch the interface into promiscuous mode.
81
82     \until //
83
84     We will now read packets from the socket forever, that is until the user hits Ctrl-C
85
86     \skip while
87     \until read
88
89     The next step is, to parse the data read from the socket as an Ethernet packet
90
91     \until ;
92
93     Lets digest this line step by step: We declare a variable named \c packet as a smart pointer to
94     an \c EthernetPacket instance. \c ptr is a typedef member of all Packet classes for the
95     corresponding smart pointer type. We then initialize this pointer with a call to the static \c
96     create member of the \c Packet class. This member takes the type of Packet to parse as a
97     template argument. We pass \c EthernetPacket here. The function takes an iterator range as an
98     argument, and we pass it the complete packet just read by giving the range \c begin() to \c
99     end() of our just read \c data string.
100
101     The next step is to write out the packet to the standard output
102
103     \until \n\n
104
105     The \c dump call will write out a complete representation of the parsed packet data. The Packet
106     library will \e not try to interpret payload data as long as no exact indication of the payload
107     type is available (example: A UDP Payload is not parsed further unless you explicitly tell the
108     library, how to parse it).  Tools like \c tethereal guess the payload type by checking port
109     numbers and the payload data, however this is not advisable for a general purpose packet
110     library.
111
112     The next line, \c hexdump, will write out the \e last packet component. Packets are managed as a
113     chain of headers. The last header is normally a \c DataPacket holding the payload data.
114
115     That's it. We finish of by catching the exception and giving as much detail as possible if an
116     exception is caught
117
118     \until ;
119     \until }
120     \until }
121
122     The \c prettyName function from the \c Utils library is used, to get a nice, printable
123     representation of the \e dynamic type of the exception instance. It is an interface to the g++
124     demangler. This is necessary since the \c name member of the C++ \c type_info instance is a
125     mangled name in \c g++.
126     
127     That's it for the simple blocking implementation. 
128
129     \section example_scheduler Using the Scheduler
130
131     However, we have another one which uses the Scheduler. We do this as it will be most of the
132     time: We define a class which manages reading the packets and dumping them out.
133
134     \until }
135
136     The class constructor binds the socket defined as a data member to the correct interface.
137
138     \until add
139
140     The public \c run() member is called to run the sniffer.  It first adds the socket to the
141     Scheduler. The \c add() call takes two Arguments, the socket to bind to (which can be a lot of
142     things and must not necessarily be a socket instance) and callback to call, whenever there is an
143     event on that socket. A third argument may be specified to restrict the events, on which the
144     function is called, here we have left out this argument which defaults to
145     senf::Scheduler::EV_ALL.
146
147     The callback is specified as a <a
148     href="http://www.boost.org/doc/html/function.html">Boost.Function</a> object. We use the \c
149     senf::membind helper from the Utils library to build such a function object. This helper takes
150     an arbitrary class member and binds it to a specific instance.
151
152     \until }
153
154     Calling the Schedulers \c process() method will start the event loop. This call does not return
155     (ok, it does return in special cases if \c senf::Scheduler::terminate() is called which does not
156     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 always passes two arguments: The socket and an event id which
162     identifies the type of event which triggered the 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     We now only need to provide the \c scheduler_main() function to run 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(). The
176     code then just creates a \c Sniffer instance and calls it's \c run() member.
177
178     \see \ref senf_components \n
179          \ref senf_build \n
180          <a href="../../../../Socket/doc/html/index.html"><b>libSocket API reference</b></a> \n
181          <a href="../../../../Packets/doc/html/index.html"><b>libPackets API reference</b></a> \n
182          <a href="../../../../Utils/doc/html/index.html"><b>libUtils API reference</b></a>
183  */
184
185 \f
186 // Local Variables:
187 // mode: c++
188 // fill-column: 100
189 // comment-column: 40
190 // c-file-style: "senf"
191 // indent-tabs-mode: nil
192 // ispell-local-dictionary: "american"
193 // compile-command: "scons -u test"
194 // mode: flyspell
195 // mode: auto-fill
196 // End: