From: g0dil Date: Thu, 1 Mar 2007 13:22:12 +0000 (+0000) Subject: Documented coding guidelines (file naming, class naming etc) X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=04dd5d565dc0a5888f8d26bbcb12e9d325d6a4e5;p=senf.git Documented coding guidelines (file naming, class naming etc) Extended the Sniffer example to optionally use the Scheduler Some additional small documentation fixes git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@211 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/Example.dox b/Example.dox index fc43ef6..eb5a816 100644 --- a/Example.dox +++ b/Example.dox @@ -2,97 +2,156 @@ \dontinclude Sniffer.cc - The Sniffer application is a simple command line network sniffer - like \c tcpdump or \c tethereal. The application uses a packet - socket to read Ethernet packets from the \c eth0 interface and - dumps the parsed packets out to the standard output. + The Sniffer application is a simple command line network sniffer like \c tcpdump or \c + tethereal. The application uses a packet socket to read Ethernet packets from the \c eth0 + interface and dumps the parsed packets out to the standard output. - We will be looking at \c Sniffer.cc in the \c Sniffer - directory. We start by including the necessary headers + To try out the example application, check out the library, go to the \c Sniffer + directory and execute + +
+    # scons -u
+    # ./sniffer loop
+    < Hit Ctrl-C when you've seen enough >
+    # ./sniffer scheduler
+    < Hit Ctrl-C when you've seen enough >
+    
+ + We will now look at the code which is found in \c Sniffer.cc in the \c Sniffer directory. The + code starts out by including the necessary headers \skip // Custom includes - \until Ethernet + \until membind + + (The additional includes found in the source but not shown here are part of a short-time fix + which will be removed as soon as possible). The example application now contains a helper + routine to produce a packet hexdump. We will skip this routine here. The example includes two + implementations, one using blocking calls and a while loop, the other using the senf::Scheduler + for asynchronous event notification. They are implemented in \c loop_main() and \c + scheduler_main(). They will be documented below. For now, we skip these implementations and go + straight to the \c main() function + + \skip int main( + \until return 1; + \until } - (The additional includes are part of a short-time fix which will - be removed as soon as possible). The example application now - contains a helper routine to produce a packet hexdump. We will - skip this routine here and go directly to the \c main function + This routine simply interprets the first command line argument and dispatches to the required + implementation. - \skip main + Now lets go back and study each implementation in detail. + + \dontinclude Sniffer.cc + + \section example_loop A Blocking Implementation + + This implementation is found in the \c loop_main function. + + \skip loop_main \until try - We catch all exceptions in a \c try block. This is good for a - deliverable binary. When debugging the application, it might be - better to let the exception \c abort the execution so you can get - a backtrace of the exception origin in the debugger. + We catch all exceptions in a \c try block. This is good for a deliverable binary. When debugging + the application, it might be better to let the exception \c abort the execution so you can get a + backtrace of the exception origin in the debugger. - We now create a packet socket and bind it to the \c eth0 - interface. By uncommenting the last line, you may switch the - interface into promiscuous mode. + We now create a packet socket and bind it to the \c eth0 interface. A packet socket is a linux + specific type of socket which returns ethernet packets directly from the network wire. By + uncommenting the last line, you may switch the interface into promiscuous mode. \until // - We will now read packets from the socket forever, that is until - the user hits Ctrl-C + We will now read packets from the socket forever, that is until the user hits Ctrl-C \skip while \until read - The next step is, to parse the data read from the socket as an - Ethernet packet + The next step is, to parse the data read from the socket as an Ethernet packet \until ; - Lets digest this line step by step: We declare a variable named \c - packet as a smart pointer to an \c EthernetPacket instance. \c ptr - is a typedef member of all Packet classes for the corresponding - smart pointer type. We then initialize this pointer with a call to - the static \c create member of the \c Packet class. This member - takes the type of Packet to parse as a template argument. We pass - \c EthernetPacket here. The function takes an iterator range as an - argument, and we pass it the complete packet just read by - giving the range \c begin() to \c end() of our just read \c data - string. + Lets digest this line step by step: We declare a variable named \c packet as a smart pointer to + an \c EthernetPacket instance. \c ptr is a typedef member of all Packet classes for the + corresponding smart pointer type. We then initialize this pointer with a call to the static \c + create member of the \c Packet class. This member takes the type of Packet to parse as a + template argument. We pass \c EthernetPacket here. The function takes an iterator range as an + argument, and we pass it the complete packet just read by giving the range \c begin() to \c + end() of our just read \c data string. - The next step is, to write out the packet to the standard output + The next step is to write out the packet to the standard output \until \n\n - The \c dump call will write out a complete representation of the - parsed packet data. The Packet library will \e not try to - interpret payload data as long as no exact indication of the - payload type is available (example: A UDP Payload is not parsed - further unless you explicitly tell the library, how to parse it). - Tools like \c tethereal guess the payload type by checking port - numbers and the payload data, however this is not advisable for a - general purpose packet library. + The \c dump call will write out a complete representation of the parsed packet data. The Packet + library will \e not try to interpret payload data as long as no exact indication of the payload + type is available (example: A UDP Payload is not parsed further unless you explicitly tell the + library, how to parse it). Tools like \c tethereal guess the payload type by checking port + numbers and the payload data, however this is not advisable for a general purpose packet + library. - The next line, \c hexdump, will write out the \e last packet - component. Packets are managed as a chain of headers. The last - header is normally a \c DataPacket holding the payload data. + The next line, \c hexdump, will write out the \e last packet component. Packets are managed as a + chain of headers. The last header is normally a \c DataPacket holding the payload data. - That's it. We finish of by catching the exception and giving as - much detail as possible if an exception is caught + That's it. We finish of by catching the exception and giving as much detail as possible if an + exception is caught \until ; \until } \until } - The \c prettyName function from the \c Utils library is used, to - get a nice, printable representation of the \e dynamic type of the - exception instance. It is an interface to the g++ demangler. This - is necessary since the \c name member of the C++ \c type_info - instance is a mangled name in C++. + The \c prettyName function from the \c Utils library is used, to get a nice, printable + representation of the \e dynamic type of the exception instance. It is an interface to the g++ + demangler. This is necessary since the \c name member of the C++ \c type_info instance is a + mangled name in \c g++. + + That's it for the simple blocking implementation. - That's it. This is all, that's necessary to read and parse raw - network packets using the SENF library. To try out the example - application, check out the library, go to the \c Sniffer directory - and execute + \section example_scheduler Using the Scheduler -
-    # scons -u
-    # ./Sniffer
-    
+ However, we have another one which uses the Scheduler. We do this as it will be most of the + time: We define a class which manages reading the packets and dumping them out. + + \until } + + The class constructor binds the socket defined as a data member to the correct interface. + + \until add + + The public \c run() member is called to run the sniffer. It first adds the socket to the + Scheduler. The \c add() call takes two Arguments, the socket to bind to (which can be a lot of + things and must not necessarily be a socket instance) and callback to call, whenever there is an + event on that socket. A third argument may be specified to restrict the events, on which the + function is called, here we have left out this argument which defaults to + senf::Scheduler::EV_ALL. + + The callback is specified as a Boost.Function object. We use the \c + senf::membind helper from the Utils library to build such a function object. This helper takes + an arbitrary class member and binds it to a specific instance. + + \until } + + Calling the Schedulers \c process() method will start the event loop. This call does not return + (ok, it does return in special cases if \c senf::Scheduler::terminate() is called which does not + apply here). + + \until { + + The \c dumpPacket() member is called by the scheduler whenever an event on the socket is + encountered. The scheduler always passes two arguments: The socket and an event id which + identifies the type of event which triggered the call. + + \until }; + + The body is absolutely identical to the body of the \c while loop of the blocking + implementation. However, the scheduler guarantees, that a read on the socket will not block if + the socket is triggered to be readable (even if the socket is not set to non-blocking mode). + + We now only need to provide the \c scheduler_main() function to run this code + + \until 0; + \until } + + This function is straight forward. The exception handling is the same as in \c loop_main(). The + code then just creates a \c Sniffer instance and calls it's \c run() member. \see \ref components \n \ref build \n diff --git a/Mainpage.dox b/Mainpage.dox index 9438adb..96779a9 100644 --- a/Mainpage.dox +++ b/Mainpage.dox @@ -1,11 +1,29 @@ +// Copyright (C) 2007 +// Fraunhofer Institut fuer offene Kommunikationssysteme (FOKUS) +// Kompetenzzentrum fuer Satelitenkommunikation (SatCom) +// Stefan Bund +// +// 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., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + /** \mainpage SENF: The Simple and Extensible Network Framework - The SENF Simple and Extensible Network Framework aims to be a - complete set of libraries to facilitate the development of network - applications focusing on network protocols on the layers below the - application layer. However, the framework includes many general - purpose utilities and will be expedient to use well beyond its - primary objective. + The SENF Simple and Extensible Network Framework aims to be a complete set of libraries to + facilitate the development of network applications focusing on network protocols on the layers + below the application layer. However, the framework includes many general purpose utilities and + will be expedient to use well beyond its primary objective. \section Goals @@ -19,14 +37,11 @@ \section start Getting started - To get started using this library, begin by checking out the code - from the BerliOS SVN - repository. You may find help on using the library at '\ref - usage'. If you are interested in SENF, feel free to subscribe - to the SENF - mailing lists. + To get started using this library, begin by checking out the code from the BerliOS SVN repository. You may find + help on using the library at '\ref usage'. If you are interested in SENF, feel free to subscribe + to the SENF mailing lists. If you + want to contribute, read the docs and \e please adhere to the \ref conventions. \see \ref usage\n \ref example @@ -34,15 +49,13 @@ /** \page usage Using the SENF framework - The SENF Framework is a collection of loosely coupled - modules. The libraries are heavily object oriented and template - based. For compatibility reasons, the libraries are therefore - built together with every project making use of the framework. + The SENF Framework is a collection of loosely coupled modules. The libraries are heavily object + oriented and template based. For compatibility reasons, the libraries are therefore built + together with every project making use of the framework. - When starting a new Projekt based on the SENF framework, it is - advisable, to make use of the SENFSCons build environment and use - SVN to manage the code repository. This is the configuration, - described in this documentation. + When starting a new Projekt based on the SENF framework, it is advisable, to make use of the + SENFSCons build environment and use SVN to manage the code repository. This is the + configuration, described in this documentation. \see \ref build \n \ref components \n @@ -51,8 +64,7 @@ \section Preliminaries - Before starting the devlopment, make sure to fulfill the following - requirements: + Before starting the devlopment, make sure to fulfill the following requirements: \li GNU g++, version at least 3.4 \li The Boost libraries (http://www.boost.org) @@ -66,136 +78,117 @@ \li The \c xsltproc XSLT processor (http://xmlsoft.org/XSLT/xsltproc2.html) - The library is only tested with gcc-3.4 and 4.0 on Linux. On other - POSIX platforms with a BSD Socket API, the library should be - usable, possibly with some tweaking (except for the Scheduler, + The library is only tested with gcc-3.4 and 4.0 on Linux. On other POSIX platforms with a BSD + Socket API, the library should be usable, possibly with some tweaking (except for the Scheduler, which relies on \c epoll) */ /** \page build Building the framework - This procedure will test building the complete framework - including the unit tests and the Sniffer test application. This - build is \e not needed to use the framework since every project + This procedure will test building the complete framework including the unit tests and the + Sniffer test application. This build is \e not needed to use the framework since every project will include the full SENF source code itself (via Subversion). - After you have successfully built the library tests, you can - continue to setup your own project using SENF. + After you have successfully built the library tests, you can continue to setup your own project + using SENF. \see \ref components \n \ref svnsetup \section checkout Getting the code - To access the code, check out the code from the BerliOS - repository. Change to your development directory and use the - following subversion command + To access the code, check out the code from the BerliOS repository. Change to your development + directory and use the following subversion command
     $ svn checkout http://svn.berlios.de/svnroot/repos/senf/trunk senf
     
- This will create a new directory \c senf within the current - directory. For further documentation on the use of Subversion, see - the \c svn manpage or the subversion homepage at - http://subversion.tigris.org. A very good introduction and - reference to subversion is available at - http://svnbook.red-bean.com. + This will create a new directory \c senf within the current directory. For further documentation + on the use of Subversion, see the \c svn manpage or the subversion homepage at + http://subversion.tigris.org. A very good introduction and reference to subversion is available + at http://svnbook.red-bean.com. \section compile Building - To build the library, execute all unit tests and build the Sniffer - test application, use + To build the library, execute all unit tests and build the Sniffer test application, use
     $ scons
     $ scons all_tests
     
- in the \c senf directory. This assumes, that you want to build the - library with your default gcc and requires the boost libraries to - be available in the system include paths. If this is not the case, - you can take a look at SConfig.template file. Copy this - file to SConfig and comment out all the variables you - don't want to change (The \e values in the template file are just - arbitrary examples). + in the \c senf directory. This assumes, that you want to build the library with your default gcc + and requires the boost libraries to be available in the system include paths. If this is not the + case, you can take a look at SConfig.template file. Copy this file to SConfig + and comment out all the variables you don't want to change (The \e values in the template file + are just arbitrary examples). */ /** \page components The SENF modules - The framework is made up of several modular components. When using - the library, it is possible to selectively choose to use only a - subset of the implemented modules. + The framework is made up of several modular components. When using the library, it is possible + to selectively choose to use only a subset of the implemented modules. \see \ref build \n \ref svnsetup \section libSocket libSocket: C++ abstraction of the BSD socket API - This library provides a high performance and object oriented - abstraction of the standard socket API. It utilizes a flexible and - extensible policy based design. The library provides predefined - types for the important socket types (UDP and TCP sockets etc) - including raw and packet sockets. \n + This library provides a high performance and object oriented abstraction of the standard socket + API. It utilizes a flexible and extensible policy based design. The library provides predefined + types for the important socket types (UDP and TCP sockets etc) including raw and packet + sockets. \n \see libSocket API reference \section libPackets libPackets: Network packet manipulation - This libarary provides a very flexible infrastructure to - parse, create and otherwise manipulate packetized network - data. Included is a library of several protocol parsers covering - the basic IPv4 and IPv6 network protocols down to the Ethernet - layer. + This libarary provides a very flexible infrastructure to parse, create and otherwise manipulate + packetized network data. Included is a library of several protocol parsers covering the basic + IPv4 and IPv6 network protocols down to the Ethernet layer. \see libPackets API reference \section libScheduler libScheduler: Asynchronous event handling - The scheduler library provides an object oriented interface to the - standard UNIX \c select type event dispatcher. It is based on the - high performance \c epoll system call. It provides support for - read/write events as well as simple timer based events. + The scheduler library provides an object oriented interface to the standard UNIX \c select type + event dispatcher. It is based on the high performance \c epoll system call. It provides support + for read/write events as well as simple timer based events. - \see libScheduler API - reference + \see libScheduler API reference \section libUtils libUtils: Collection of arbitrary utilities - This library is used be most all of the other modules for - miscellaneous tools and utilities. We have + This library is used be most all of the other modules for miscellaneous tools and utilities. We + have \li Simple functions to manage daemon processes \li Standard exception classes - \li senf::intrusive_refcount to simplify the implementation - of classes usable with boost::intrusive_ptr + \li senf::intrusive_refcount to simplify the implementation of classes usable with + boost::intrusive_ptr \li boost::bind extensions \li An interface to the \c g++ demangler integrated with type_info - \li Typedefs and rudimentary methods to simplify handling - high-resolution time values + \li Typedefs and rudimentary methods to simplify handling high-resolution time values - \see libUtils API - reference + \see libUtils API reference \section senfscons SENFSCons, the SENF build environment - SENF relies on SCons (http://www.scons.org) to build. To further - simplify the common tasks, SENF includes a library of custom - routines and builders comprising a very concise build - environment. Included are a number of templates to help - bootstrapping a new project or component. + SENF relies on SCons (http://www.scons.org) to build. To further simplify the common tasks, SENF + includes a library of custom routines and builders comprising a very concise build + environment. Included are a number of templates to help bootstrapping a new project or + component. - \see SENFSCons - reference + \see SENFSCons reference */ /** \page svnsetup Setting up a new project using SENF - The preferred way to use SENF in a new project is to rely on - Subversion and make use of the SENFSCons build environment. The - following sections will describe, how this setup works. + The preferred way to use SENF in a new project is to rely on Subversion and make use of the + SENFSCons build environment. The following sections will describe, how this setup works. \see \ref build \n \ref components \n @@ -203,38 +196,30 @@ \section svnext Setting up the project repository - The most seamless integration is possible if you rely on - Subversion to manage the new project. Subversion does support - 'external repositories'. This allows to import code from a foreign - repository into the checkout without importing it into your - repository. The code will always stay at the remote repository, - updates are automatically available. - - First setup a new empty repository as described for example in the - Subversion book at http://svnbook.red-bean.com or as mandated by - your site policy. We will call the project 'Foo' and assume, that - the project has been checked out into the 'Foo' directory. - - You now have to decide, which modules you want to use. Every - module resides in it's own subdirectory in the SENF - repository. Instead of directly checking out the code, we will use - \c svn:externals. This will instruct \c svn to auutomatically - check out the needed directories from the BerliOS SENF - repository. Change to the 'Foo' directory and type + The most seamless integration is possible if you rely on Subversion to manage the new + project. Subversion does support 'external repositories'. This allows to import code from a + foreign repository into the checkout without importing it into your repository. The code will + always stay at the remote repository, updates are automatically available. + + First setup a new empty repository as described for example in the Subversion book at + http://svnbook.red-bean.com or as mandated by your site policy. We will call the project 'Foo' + and assume, that the project has been checked out into the 'Foo' directory. + + You now have to decide, which modules you want to use. Every module resides in it's own + subdirectory in the SENF repository. Instead of directly checking out the code, we will use \c + svn:externals. This will instruct \c svn to auutomatically check out the needed directories from + the BerliOS SENF repository. Change to the 'Foo' directory and type
     $ svn propedit svn:externals .
     
- The default editor (probably VI) will be started with the current - value of the svn:externals property (which will probably be - empty). Now add all the modules you want plus \c senfscons and - possibly \c doclib (if you want to build the documentation). You - will almost certainly neeed the \c Utils module, since all other - modules depend on it. + The default editor (probably VI) will be started with the current value of the svn:externals + property (which will probably be empty). Now add all the modules you want plus \c senfscons and + possibly \c doclib (if you want to build the documentation). You will almost certainly neeed the + \c Utils module, since all other modules depend on it. - For example, if you want to use the \c Scheduler and \c Socket - module, the file will look like + For example, if you want to use the \c Scheduler and \c Socket module, the file will look like
     senfscons http://svn.berlios.de/svnroot/repos/senf/trunk/senfscons
@@ -249,26 +234,21 @@
     $ svn update
     
- and the code will be checked out into the corresponding - directories. + and the code will be checked out into the corresponding directories. \section new_conf Configuring SENFSCons - To set up the build environment, copy the - senfscons/SConstruct.template to SConstruct in - the project root. The default setup of this file is to build all - subdirectories (using the \c SConscript files of the - subdirectories). You can add additonal global targets and - configuration parameters here. - - If you want to use a non-default compiler or the boost library is - not installed in the system directories, you will have to copy - senfscons/SConfig.template to SConfig in the - project root and edit it there. You should \e never add \c SConfig - to the repository since it should only contain local settings - necessary for building on your local system. You should therefore - add \c SConfig to the list of files ignored by Subversion in the - project root. In the project root execute + To set up the build environment, copy the senfscons/SConstruct.template to + SConstruct in the project root. The default setup of this file is to build all + subdirectories (using the \c SConscript files of the subdirectories). You can add additonal + global targets and configuration parameters here. + + If you want to use a non-default compiler or the boost library is not installed in the system + directories, you will have to copy senfscons/SConfig.template to SConfig in + the project root and edit it there. You should \e never add \c SConfig to the repository since + it should only contain local settings necessary for building on your local system. You should + therefore add \c SConfig to the list of files ignored by Subversion in the project root. In the + project root execute
     $ svn propedit svn:ignore .
@@ -284,16 +264,14 @@
     $ scons
     
- If you have not changed the \c SConstruct file, this will build - all modules you have importet into your project. To build and - execute the unit tests, use + If you have not changed the \c SConstruct file, this will build all modules you have importet + into your project. To build and execute the unit tests, use
     $ scons all_tests
     
- you can also build only a subdirectory by changing to it and - running + you can also build only a subdirectory by changing to it and running
     $ scons -u [target]
@@ -307,63 +285,143 @@
 
 /** \page overview Introduction to the framework
 
-    The SENF framework is relatively complex and makes use of advanced
-    features of the C++ language. To make the most efficient use of
-    the framework, you should have at least a basic understanding of
-    C++ templates and the standard library concepts.
+    The SENF framework is relatively complex and makes use of advanced features of the C++
+    language. To make the most efficient use of the framework, you should have at least a basic
+    understanding of C++ templates and the standard library concepts.
 
-    The library implementation at places makes heavy use of advanced
-    template techniques and relies on some very advanced template
-    libraries from Boost. The aim was however for the \e external
-    interface of the library to be as simple as possible without
-    sacrificing important functionality or adversely impacting the
-    runtime performance.
+    The library implementation at places makes heavy use of advanced template techniques and relies
+    on some very advanced template libraries from Boost. The aim was however for the \e external
+    interface of the library to be as simple as possible without sacrificing important functionality
+    or adversely impacting the runtime performance.
 
-    As already mentioned several times, the library relies on Boost
-    (http://www.boost.org) as a generic library of high quality
-    reusable C++ components. It also makes frequent use of the
-    standard library. It is designed, to integrate well into both
-    libraries and to use the same concepts and ideas.
+    As already mentioned several times, the library relies on Boost (http://www.boost.org) as a
+    generic library of high quality reusable C++ components. It also makes frequent use of the
+    standard library. It is designed, to integrate well into both libraries and to use the same
+    concepts and ideas.
 
     \section startup Getting starting developing with SENF
 
-    To introduce the framework and it's general structure, a simple
-    example application is provided in the SENF repository in the \c
-    Sniffer module. Peruse this example to get a first look at how to
-    make use of SENF.
-
-    When building a network Application with SENF, you will use
-    several modules:
-
-    \li Use the Socket
-        library for network communication needs. This library
-        includes support for raw and packet sockets to allow low level
-        network access.
-    \li Use the Scheduler
-        library to coordinate the asynchronous event
-        processing. This drastically reduces the number of threads
-        needed in your application and will greatly enhance the overall
-        responsiveness.
+    To introduce the framework and it's general structure, a simple example application is provided
+    in the SENF repository in the \c Sniffer module. Peruse this example to get a first look at how
+    to make use of SENF.
+
+    When building a network Application with SENF, you will use several modules:
+
+    \li Use the Socket library for network
+        communication needs. This library includes support for raw and packet sockets to allow low
+        level network access.
+    \li Use the Scheduler library to coordinate
+        the asynchronous event processing. This drastically reduces the number of threads needed in
+        your application and will greatly enhance the overall responsiveness.
     \li To interpret low level network packets, use the Packets
-        library. This library will provide efficient and
-        convenient access to all protocol fields. It supports parsing as
-        well as modifying and creating packets. It has default support
-        for the most important internet protocols and is highly
-        extensible with new protocols.
-    \li Go over the Utils
-        library. It contains small helpers to
-        simplify tasks like daemonization, exception handling,
-        debugging and so on.
-
-    The simplest way to get started is: copy the Sniffer application
-    and start to modify it.
+        href="../../Packets/doc/html/index.html">Packets library. This library will provide
+        efficient and convenient access to all protocol fields. It supports parsing as well as
+        modifying and creating packets. It has default support for the most important internet
+        protocols and is highly extensible with new protocols.
+    \li Go over the Utils library. It contains small
+        helpers to simplify tasks like daemonization, exception handling, debugging and so on.
+
+    The simplest way to get started is: copy the Sniffer application and start to modify it.
 
     \see \ref example \n
          \ref components \n
          \ref svnsetup \n
          \ref build
+
+    \section conventions Coding Conventions
+    
+    Here we have laid down the coding conventions used throughout the SENF framework. Please adhere
+    to these conventions when changing or adding code. If you use emacs, you can use the C++ IDE for
+    emacs from http://g0dil.de which greatly simplifies following these conventions.
+
+    \subsection conventions_file_naming File Naming
+
+    Files should be named according to the main class they define. A single header file should
+    define only one main class. Exceptions to this rule are OK.
+
+    \par Rationale:
+        This simplifies finding the implementation/header for a given class and also reduces the
+        size of each single file.
+    
+    The implementation is divided into a number of different files:
+
+    
+
+    
+
+    
+
+    
+
+    
+
+    
+
+    
+    
+    
+
+    
\c .hC public header
\c .hhC++ public header
\c .ihC++ internal header used only by the implementation. This header will + probably be included indirectly by the public header but is not meant to be perused by the + library user
\c .cC implementation
\c .ccC++ implementation of non-inline non-template functions and + members
\c .ctC++ implementation of non-inline template functions and members
\c .cciC++ implementation of inline non-template functions and + members
\c .ctiC++ implementation of inline template fuanctions and members
\c .mppSpecial include file used for external iteration by the + Boost.Preprocessor library
+ + \par Rationale: + There are two part's to this: First, separating the implementation of inlines and tempaltes + out of the header file makes the header file much easier to read. This is important, since + the header file will be used as a reference by the developers. + \par + Separating inline from non-inline members is used together with the \c prefix_ convention + below to ensure the correct placement of inline vs non-inline members in the source + code. The C++ language requires, that inline members must be included into \e every + compilation unit, non-inline members however must be included \e only in one compilation + unit. Placing the inline members into a separate file allows to automate this: Simply moving + an implementation from one of the inline files into one of the non-inline files will change + the type of implementation accordingly. + + \subsection conventions_type_naming Type Naming + + SENF prefers the use of the CapitalziedLettersToSeparateWords convention for class names. In + this case, class names must start with a capital letter. There are some exceptions to this rule: + Types which define new basic data types to be used like other built-in types may be named using + lowercase letters plus underscores. Also, if a type or class is directly related to some other + library (STL or Boost) which uses the underscore convention, it might be more sensible to follow + this convention. This is open to debate. + + \par Rationale: + Naming types with capital letters nicely gives a visual clue, that a symbol is a type + name. This can also be used by the editor to highlight type names correctly. Additionally, + this convention is compact and does not add additional or repeated overhead. + + \subsection conventions_impl Implementation + + Only in very few places, SENF allows the use of inline implementations (not to be confused with + inline functions). An \e implementation is inline, if it is written directly into the class + definition in the header file. Again there are exceptions to this rule but they are very few: + \li When defining simple exception classes, the 'what()' member may be defined inline if it + returns a string constant. + \li It may be OK to use inline implementations for one-line implementations in internal + headers. + \li The Packet library allows inline implementations for the definition of parsers since doing + so outside the declaration just gets to verbose and parsers definitions are quite length but + very simple and straight forward. + + \par Rationale: + Implementing members inline inside the class declaration makes the declaration much harder + to read. Since the declaration in the header file will be used as a reference by the + developer, the header files should be as readable as possible. + + Every function or method implementation in one of the implementation files must \e always be + prefixed with \c prefix_. This symbol is defined at the beginning of the file and undefined at + the end. The symbol must be defined to be \c inline in the \c .cti and \c .cci files and must be + defined empty in the \c .cc and \c .ct files. + + \par Rationale: + Together with splitting inlines and non-inlines into separate files, this allows to + automatically include the inline definitions at the right places. See above. + */ diff --git a/SConstruct b/SConstruct index f9fb4cc..4f3915c 100644 --- a/SConstruct +++ b/SConstruct @@ -36,7 +36,9 @@ SConscript(glob.glob("*/SConscript")) SENFSCons.StandardTargets(env) SENFSCons.GlobalTargets(env) -SENFSCons.Doxygen(env) +SENFSCons.Doxygen(env, extra_sources = [ + 'Sniffer/Sniffer.cc', +]) SENFSCons.DoxyXRef(env, HTML_HEADER = '#/doclib/doxy-header-overview.html', HTML_FOOTER = '#/doclib/doxy-footer.html') diff --git a/Sniffer/SConscript b/Sniffer/SConscript index de8f21b..8d68b85 100644 --- a/Sniffer/SConscript +++ b/Sniffer/SConscript @@ -4,4 +4,4 @@ import SENFSCons ########################################################################### SENFSCons.Binary(env, 'sniffer', SENFSCons.GlobSources(), - LIBS = [ 'Packets', 'Socket', 'Utils' ]); + LIBS = [ 'Scheduler', 'Packets', 'Socket', 'Utils' ]); diff --git a/Sniffer/Sniffer.cc b/Sniffer/Sniffer.cc index 92239ff..40aec9c 100644 --- a/Sniffer/Sniffer.cc +++ b/Sniffer/Sniffer.cc @@ -30,6 +30,9 @@ #include #include #include "Socket/PacketSocketHandle.hh" +#include "Scheduler/Scheduler.hh" +#include "Utils/membind.hh" + #include "Packets/EthernetPacket.hh" #include "Packets/IpV4Packet.hh" #include "Packets/UDPPacket.hh" @@ -86,7 +89,7 @@ namespace { } } -int main (int argc, char const * argv[]) +int loop_main (int argc, char const * argv[]) { try { senf::PacketSocketHandle sock; @@ -107,6 +110,59 @@ int main (int argc, char const * argv[]) catch (std::exception const & ex) { std::cerr << senf::prettyName(typeid(ex)) << ": " << ex.what() << "\n"; } + return 0; +} + +class Sniffer +{ + senf::PacketSocketHandle sock; + +public: + Sniffer(std::string const & interface) + { sock.bind(senf::LLSocketAddress(interface)); } + + void run() + { + senf::Scheduler::instance().add(sock, senf::membind(&Sniffer::dumpPacket, this)); + senf::Scheduler::instance().process(); + } + +private: + void dumpPacket(senf::FileHandle /* ignored */, senf::Scheduler::EventId event) + { + std::string data (sock.read()); + senf::EthernetPacket::ptr packet ( + senf::Packet::create( + data.begin(), data.end())); + packet->dump(std::cout); + hexdump(packet->last()->begin(), + packet->last()->end()); + std::cout << "\n\n"; + } +}; + +int scheduler_main(int argc, char const * argv[]) +{ + try { + Sniffer sniffer ("eth0"); + sniffer.run(); + } + catch (std::exception const & ex) { + std::cerr << senf::prettyName(typeid(ex)) << ": " << ex.what() << "\n"; + } + return 0; +} + +int main(int argc, char const * argv[]) +{ + if (argc >= 2) + if (std::string(argv[1]) == "loop") + return loop_main(argc,argv); + else if (std::string(argv[1]) == "scheduler") + return scheduler_main(argc,argv); + + std::cerr << "Usage: sniffer { loop | scheduler }" << std::endl; + return 1; } ///////////////////////////////cc.e//////////////////////////////////////// diff --git a/Socket/Mainpage.dox b/Socket/Mainpage.dox index 76334f6..3ca4084 100644 --- a/Socket/Mainpage.dox +++ b/Socket/Mainpage.dox @@ -147,9 +147,12 @@ namespace senf { interface). You will not have \c write or \c readfrom members. \c write will be disabled since the WritePolicy is unknown, \c readfrom will be disabled since a socket with the ConnectedCommunicationPolicy does not have a \c readfrom member. - */ - + \see + \ref policy_group \n + \ref handle_group \n + \ref protocol_group + */ /** \page extend Extending the Library diff --git a/Socket/PacketSocketHandle.hh b/Socket/PacketSocketHandle.hh index aee50f6..ef3d737 100644 --- a/Socket/PacketSocketHandle.hh +++ b/Socket/PacketSocketHandle.hh @@ -61,7 +61,7 @@ namespace senf { \par Socket Handle typedefs: \ref PacketSocketHandle (ProtocolClientSocketHandle) - \par Protocol Interface: + \par Policy Interface: ClientSocketHandle::read(), ClientSocketHandle::readfrom(), ClientSocketHandle::writeto(), ClientSocketHandle::bind(), ClientSocketHandle::local(), ClientSocketHandle::rcvbuf(), ClientSocketHandle::sndbuf() diff --git a/Socket/SocketProtocol.hh b/Socket/SocketProtocol.hh index 1935b6e..e4f9f21 100644 --- a/Socket/SocketProtocol.hh +++ b/Socket/SocketProtocol.hh @@ -103,7 +103,7 @@ namespace senf { class SocketPolicyBase; - /** \brief Socket protocol base class + /** \brief Socket Protocol base class This is the base class of all socket protocol classes. Every protocol class must directly or indirectly inherit from SocketProtocol @@ -211,7 +211,7 @@ namespace senf { }; - /** \brief Concrete socket protocol implementation base class + /** \brief Concrete Socket Protocol implementation base class ConcreteSocketProtocol is the base class of a concrete socket protocol implementation. The final protocol class must inherit from ConcreteSocketProtocol. The template argument \a diff --git a/Socket/TCPSocketHandle.hh b/Socket/TCPSocketHandle.hh index cbb521c..aa60a84 100644 --- a/Socket/TCPSocketHandle.hh +++ b/Socket/TCPSocketHandle.hh @@ -64,7 +64,7 @@ namespace senf { \ref TCPv4ClientSocketHandle (ProtocolClientSocketHandle), \ref TCPv4ServerSocketHandle (ProtocolServerSocketHandle) - \par Protocol Interface: + \par Policy Interface: ClientSocketHandle::read(), ClientSocketHandle::write(), ClientSocketHandle::bind(), ClientSocketHandle::local(), ClientSocketHandle::connect(), ClientSocketHandle::peer(), ClientSocketHandle::rcvbuf(), ClientSocketHandle::sndbuf() @@ -145,7 +145,7 @@ namespace senf { \ref TCPv6ClientSocketHandle (ProtocolClientSocketHandle), \ref TCPv6ServerSocketHandle (ProtocolServerSocketHandle) - \par Protocol Interface: + \par Policy Interface: ClientSocketHandle::read(), ClientSocketHandle::write(), ClientSocketHandle::bind(), ClientSocketHandle::local(), ClientSocketHandle::connect(), ClientSocketHandle::peer(), ClientSocketHandle::rcvbuf(), ClientSocketHandle::sndbuf() diff --git a/doclib/senf.css b/doclib/senf.css index 3b83650..05581a3 100644 --- a/doclib/senf.css +++ b/doclib/senf.css @@ -268,6 +268,7 @@ dl.parameters dd table { table.glossary { border: none; border-spacing: 0; + margin: 10px 0; } table.glossary tr td {