# -*- python -*-
-import sys, os, os.path
-try: sys.path.append(((_ for _ in (os.path.join(os.path.sep.join(('..' for _ in range(_))),d,
- 'site_scons') for d in ('','senf','Senf') for _ in range(len(os.getcwd().split('/'))))
- if os.path.exists(_))).next())
-except: sys.path.append('/usr/lib/senf/site_scons')
-import senfutil
+import senfutil, os
-env = Environment()
+env = Environment(ENV = os.environ)
senfutil.SetupForSENF(env)
senfutil.DefaultOptions(env)
--- /dev/null
+import sys, os
+
+def findsenf(sysdirs = ('/usr/local/lib/senf','/usr/lib/senf'),
+ subdirs = ('', 'senf', 'Senf', 'SENF')):
+ from os.path import join, sep, exists, normpath
+ from itertools import starmap, product, chain
+
+ def joinpaths(*p): return starmap(join, product(*p))
+ def existing(l): return (e for e in l if exists(e))
+ def ancestors(d): p = d.split(sep); return (join(p[0]+sep,*p[1:i]) for i in range(len(p),0,-1))
+ def butfirst(l):
+ i = iter(l); i.next()
+ for e in i : yield e
+
+ try: return normpath(existing(butfirst(joinpaths(
+ chain(ancestors(os.getcwd()),sysdirs),
+ subdirs,('site_scons/senfutil.py',)))).next())
+ except StopIteration: raise ImportError, 'senfutil not found'
+
+__file__ = findsenf(); del findsenf
+sys.path.append(os.path.dirname(__file__))
+execfile(__file__, locals(), globals())
\dontinclude udpServer.cc
- This Application is a command line based client/server application, which sends some strings from
- client to server, where they are printed on the command line.
+ This Application is a command line based client/server application, which sends some strings
+ from client to server, where they are printed on the command line.
After installing the Library, the udpServer and the udpClient can be found in the
senf/Example/udpServer directory and compiled with
<pre>
- # scons -u
- <Then you can start the client/server with>
+ # scons -u
+ </pre>
- # ./udpServer
- # ./udpClient
+ Now you can start the application with
+ <pre>
+ # ./udpServer
+ # ./udpClient
</pre>
- When we take a look to the code, we start with the Server:
- First we include the necessary headers:
+ \section UDPserverApplication UDP server application
+
+ We take a look to the code starting with the Server: The file starts out including the necessary
+ header files:
\skip // Custom includes
\until membind
integrated Scheduler. The scheduler library provides a simple yet flexible abstraction of
the standard asynchronous UNIX mainloop utilizing \c select or \c poll.
- \section UDP_serverApplication UDP server application
-
First we define a class which is responsible for opening a socket and print out the incoming
data on stdout. We create a \c ::UDPv4ClientSocketHandle, which is an unconnected and
- uninitialized UDP (Ipv4) socket.
+ uninitialized UDP (IPv4) socket.
\until serverSock;
- The constructor initialize the Server Object with a given address and port. In our case the
- server listens static on the loopback device with port 4243.
+ The name \e client socket handle is a bit misleading: The handle is a \e client and not a \e
+ server socket handle since it implements the ordinary (client) socket API and not the connection
+ oriented (e.g. TCP accept) server socket API. Since UDP is not connection oriented, there exists
+ no \c UDPv4ServerSocketHandle.
\until {}
- The public \c run() member is called to run the sniffer. It first adds the socket to the
- Scheduler. The <tt> \link senf::Scheduler::add add() \endlink </tt> 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 function to call, whenever there is an event on that socket.The callback
- is specified as a <a href="http://www.boost.org/doc/libs/release/doc/html/function.html">
- Boost.Function</a> object. A third argument may be specified to restrict the events, on which
- the function is called, here we used the EV_READ Argument, because we just want the program to
- read from the socket. The default argument is set to \c senf::Scheduler::EV_ALL, which allows
- all actions on the socket.
+ The constructor initialize the Server Object with a given address and port. In our case the
+ server configuration is static: The server listens on the loopback device on port 4243. We
+ instantiate and configure a senf::scheduler::FdEvent instance to call Server::readFromClient
+ whenever data is available on the handle.
\until }
- Calling the Schedulers <tt> \link senf::Scheduler::process process()\endlink </tt> 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). The Callback Function is
- the \c readFromClient() Function, which is declared as private here and will be called whenever
- an event on the socket is encountered. The scheduler passes the event ID to the function.
+ The public \c run() member is called to run the sniffer. It enables the event callback and
+ enters the scheduler main-loop.
\until event)
- In the function the data from the socket is put into a standard string and dumped out on stdout.
+ This member function is called by the %scheduler whenever new data is available. The scheduler
+ passes in an event-mask of the event(s) triggering the call.
\until };
- In the main function we need to create an Object of our Server with the loopback address and the port.
+ In the function the data from the socket is put into a standard string and dumped out on stdout.
\until return 0;
+ \until }
+
+ In the main function we need to create an Object of our Server with the loopback address and the
+ port.
That's it. We finish of by catching the exception and giving as much %detail as possible if an
- exception is caught. The \c prettyName function from the \c Utils library is used, to get a nice,
- printable representation of the dynamic type of the exception instance. It is an interface to
- the g++ demangler. This is necessary since the name member of the C++ \c type_info instance is
- a mangled name in g++.
+ exception is caught. The \c prettyName function from the \c Utils library is used, to get a
+ nice, printable representation of the dynamic type of the exception instance. It is an interface
+ to the g++ de-mangler. This is necessary since the name member of the C++ \c type_info instance
+ is a mangled name in g++.
- \section UDP_clientApplication UDP client application
+ \section UDPclientApplication UDP client application
\dontinclude udpClient.cc
- The client application uses the same mechanisms, but implements them in a small main function.
+ The client application uses the same mechanisms but implements them in a small main function.
It sends numbers as strings to the server.
\skip argv[])
\until return 0;
+ \until }
- First a \c ::UDPv4ClientSocketHandle is created. With the function
- \c writeto(senf::INet4SocketAddress, string) the string s will be written to the specified
- address and port, which is constructed here from a static string read from the console with the format \c IP:PORT. In this
- example Integers from zero to ten are send to the Server socket.
-
- The exception handling is again the same as with the server application.
+ First a \c senf::::UDPv4ClientSocketHandle is created. With
+ <tt>writeto(senf::INet4SocketAddress, string)</tt> the string \c s will be written to the
+ specified address and port, which is constructed here from a static string read from the command
+ line with the syntax \c IP:PORT. In this example Integers from zero to ten are send to the
+ Server socket.
*/
\f
PROJECT_NAME = Overview
PROJECT_NUMBER = "$(REVISION)"
GENERATE_XML = NO
+EXAMPLE_PATH = "$(TOPDIR)/Examples/Sniffer/site_scons"
\ No newline at end of file
To get started using this library, begin by checking out the code from the <a
href="http://developer.berlios.de/svn/?group_id=7489">BerliOS SVN repository</a>. You may find
- help on using the library at '\ref senf_usage'. If you are interested in SENF, feel free to subscribe
- to the <a href="http://developer.berlios.de/mail/?group_id=7489">SENF mailing lists</a>. If you
- want to contribute, read the docs and \e please adhere to the \ref senf_conventions.
+ help on using the library at '\ref senf_usage'. If you are interested in SENF, feel free to
+ subscribe to the <a href="http://developer.berlios.de/mail/?group_id=7489">SENF mailing
+ lists</a>. If you want to contribute, read the docs and \e please adhere to the \ref
+ senf_conventions.
\see \ref senf_usage\n
<a href="../../Examples/doc/html/index.html">Examples</a>
\autotoc
+ \c senfutil helps setting up projects which utilize SENF. It will configure all necessary
+ compiler and linker options and additionally sets up some useful defaults and utilities.
+
+ \c senfutil really serves three roles
+
+ \li detect SENF and configure the build accordingly
+ \li make some SCons extensions used within SENF available to other projects
+ \li set default compilation options in the same way, they are set when compiling SENF proper.
+
+ The last two points are of course optional.
+
+ \section senfutil_tutorial Tutorial
+
+ To utilize \c senfutil you need to do two things:
+ \li Update your \c SConstruct file
+ \li add a bootstrap \c senfutil.py to \c site_scons
+
+ Lets start with the \c SConstruct file
+ \code
+ import senfutil
+
+ env = Environment()
+ senfutil.SetupForSENF(env)
+ senfutil.DefaultOptions(env)
+
+ env.SetDefault(
+ PROJECTNAME = 'Example project',
+ PROJECTEMAIL = 'developer@domain.com',
+ DOCLINKS = [ ('Homepage', 'http://www.domain.com') ]
+ )
+
+ sources, tests = senfutil.Glob(env, exclude=['main.cc'])
+
+ objects = env.Object(sources)
+ example = env.Program('example', objects + ['main.cc'])
+ test = env.BoostUnitTest('test', objects + tests)
+
+ env.Default(example)
+
+ senfutil.Doxygen(env)
+
+ senfutil.CleanGlob('all', [ '*~', '#*#' ])
+ \endcode
+
+ This simple sample already enables a lot of functionality:
+ \li support for different \e SENF flavors (debug/normal/final)
+ \li support for different \e build flavors (debug/normal/final)
+ \li sensible default compile options for the different flavors
+ \li support for extended command-line variables
+ \li building documentation with an auto-generated Doxyfile
+ \li running unit-tests
+ \li cleaning backup and temporary files
+
+ Here a very quick rundown of the important scons commands:
+ \li Build default target:
+ <pre>
+ $ scons
+ </pre>
+ \li Build documentation and unit-tests:
+ <pre>
+ $ scons doc test
+ </pre>
+ \li clean up everything
+ <pre>
+ $ scons -c all
+ </pre>
+ \li Pass custom options on the command-line
+ <pre>
+ $ scons CXXFLAGS+=-Wextra
+ </pre>
+
+ Since \c senfutil.py is not on the standard \c python or \c SCons path, some extra steps are
+ needed to find it.
+ \li Either add the possible directories to <tt>sys.path</tt> before importing \c senfutil:
+ \code
+ import sys
+ sys.path.extend(('/usr/local/lib/senf/site_scons', '/usr/lib/senf/site_scons'))
+ import senfutil
+ \endcode
+ \li Alternatively, install the following utility script as <tt>site_scons/senfutil.py</tt> into
+ your project. This script will search for <tt>site_scons/senfutil.py</tt> in a list of
+ directories and then load the real \c senfutil.py on top of itself. The directories searched
+ include: the current directory and all parents, subdirectories named <tt>senf/</tt>,
+ <tt>Senf/</tt> or <tt>SENF/</tt> thereof, and <tt>/usr/local/lib/senf/</tt> and
+ <tt>/usr/lib/senf/</tt>
+ \include senfutil.py
+
+ \section senfutil_features
+
The \c senfutil utility for SCons helps setting up a project to compile against SENF:
\li \c senfutil adds all necessary libraries to link against
mac
MACAddress
MACAddressParser
+mainloop
mainpage
malformed
manualparse
RawINetProtocol
RawV
rdynamic
+readFromClient
ReadInfo
receiveModule
ReceiverDecorator
SENFSCons
ServerLog
serverlog
+serverSock
ServerSocketHandle
setBegin
setEnd
ssi
std
stderr
+stdout
stefan
STL
strerror
typeField
UDLR
udp
+udpClient
+UDPclientApplication
UDPPacket
udpReader
+udpServer
+UDPserverApplication
UDPv
udpWriter
UInt