Index: source/ariba/AribaModule.cpp
===================================================================
--- source/ariba/AribaModule.cpp	(revision 3071)
+++ source/ariba/AribaModule.cpp	(revision 3374)
@@ -44,4 +44,5 @@
 
 // ariba includes
+#include "ariba/SideportListener.h"
 #include "ariba/utility/misc/Helper.h"
 #include "ariba/utility/misc/StringFormat.h"
@@ -56,12 +57,12 @@
 namespace ariba {
 
-AribaModule::AribaModule() {
+AribaModule::AribaModule()
+	: base_comm(NULL), sideport_sniffer(NULL),
+		ip_addr(NULL), started(false) {
 
 	// init with default values
-	this->base_comm = NULL;
-	this->ip_addr = NULL;
+
 	this->tcp_port = 41402;
 	this->udp_port = 41402;
-	this->started = false;
 }
 
@@ -145,4 +146,8 @@
 }
 
+void AribaModule::registerSideportListener(SideportListener* sideport){
+	sideport_sniffer = sideport;
+}
+
 // @see Module.h
 void AribaModule::initialize() {
Index: source/ariba/AribaModule.h
===================================================================
--- source/ariba/AribaModule.h	(revision 3071)
+++ source/ariba/AribaModule.h	(revision 3374)
@@ -44,5 +44,4 @@
 #include <boost/foreach.hpp>
 
-// usings
 using std::vector;
 using std::string;
@@ -50,5 +49,6 @@
 // forward declaration
 namespace ariba {
-class AribaModule;
+	class AribaModule;
+	class SideportListener;
 }
 
@@ -59,5 +59,4 @@
 namespace ariba {
 
-// forward declarations of old interface
 namespace communication {
 class EndpointDescriptor;
@@ -119,4 +118,16 @@
 	void addBootstrapHints(string bootinfo);
 
+	/**
+	 * Register a sideport for sniffing on communication events
+	 * and get advanced information. The sniffer is attached to
+	 * every node that is created on the module. Only one such
+	 * sniffer can be active system-wide, a new call to this
+	 * register function will only attach the sniffer to nodes
+	 * created after the registration call.
+	 *
+	 * @param sideport The SideportListener to integrate
+	 */
+	void registerSideportListener(SideportListener* sideport);
+
 	// --- module implementation ---
 
@@ -185,4 +196,5 @@
 
 	communication::BaseCommunication* base_comm;
+	SideportListener* sideport_sniffer;
 
 	// TODO: use "abstract" representations here!
Index: source/ariba/CommunicationListener.cpp
===================================================================
--- source/ariba/CommunicationListener.cpp	(revision 3071)
+++ source/ariba/CommunicationListener.cpp	(revision 3374)
@@ -41,4 +41,6 @@
 namespace ariba {
 
+CommunicationListener CommunicationListener::DEFAULT;
+
 CommunicationListener::CommunicationListener() {
 }
@@ -68,4 +70,8 @@
 }
 
+bool CommunicationListener::onEnableSideportListener() {
+	return true;
+}
+
 // --- extended message functionality ---
 //void CommunicationListener::onLinkQoSChanged(const LinkID& l, const NodeID& r,
Index: source/ariba/CommunicationListener.h
===================================================================
--- source/ariba/CommunicationListener.h	(revision 3071)
+++ source/ariba/CommunicationListener.h	(revision 3374)
@@ -56,6 +56,12 @@
  */
 class CommunicationListener {
+
 	friend class ariba::overlay::BaseOverlay;
+	friend class Node;
+
+	static CommunicationListener DEFAULT;
+
 protected:
+
 	CommunicationListener();
 	virtual ~CommunicationListener();
@@ -78,4 +84,7 @@
 			const LinkID& lnk = LinkID::UNSPECIFIED);
 
+	// --- sniffing related method ---
+	virtual bool onEnableSideportListener();
+
 	// --- extended message functionality ---
 	// virtual void onLinkQoSChanged(const LinkID& lnk, const NodeID& remote,
Index: source/ariba/Makefile.am
===================================================================
--- source/ariba/Makefile.am	(revision 3071)
+++ source/ariba/Makefile.am	(revision 3374)
@@ -73,4 +73,5 @@
   Node.cpp \
   NodeListener.cpp \
+  SideportListener.cpp \
   SpoVNetProperties.cpp
 
@@ -87,4 +88,5 @@
   Node.h \
   NodeListener.h \
+  SideportListener.h \
   SpoVNetProperties.h
 
Index: source/ariba/Node.cpp
===================================================================
--- source/ariba/Node.cpp	(revision 3071)
+++ source/ariba/Node.cpp	(revision 3374)
@@ -146,5 +146,14 @@
 
 bool Node::bind(CommunicationListener* listener, const ServiceID& sid) {
-	return base_overlay->bind(listener, sid);
+	// bind the listener
+	bool ret = base_overlay->bind(listener, sid);
+
+	// now that we have a listener, we can ask if sniffing is ok
+	if( ariba_mod.sideport_sniffer != NULL ){
+		bool allow = listener->onEnableSideportListener();
+		base_overlay->registerSidePort(ariba_mod.sideport_sniffer);
+	}
+
+	return ret;
 }
 
Index: source/ariba/Node.h
===================================================================
--- source/ariba/Node.h	(revision 3071)
+++ source/ariba/Node.h	(revision 3374)
@@ -57,4 +57,5 @@
 #include "CommunicationListener.h"
 #include "DataMessage.h"
+#include "SideportListener.h"
 
 using std::vector;
Index: source/ariba/SideportListener.cpp
===================================================================
--- source/ariba/SideportListener.cpp	(revision 3374)
+++ source/ariba/SideportListener.cpp	(revision 3374)
@@ -0,0 +1,89 @@
+// [License]
+// The Ariba-Underlay Copyright
+//
+// Copyright (c) 2008-2009, Institute of Telematics, UniversitÃ€t Karlsruhe (TH)
+//
+// Institute of Telematics
+// UniversitÃ€t Karlsruhe (TH)
+// Zirkel 2, 76128 Karlsruhe
+// Germany
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE INSTITUTE OF TELEMATICS ``AS IS'' AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OF TELEMATICS OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// The views and conclusions contained in the software and documentation
+// are those of the authors and should not be interpreted as representing
+// official policies, either expressed or implied, of the Institute of
+// Telematics.
+// [License]
+
+#include "SideportListener.h"
+
+#include "ariba/overlay/BaseOverlay.h"
+
+namespace ariba {
+
+SideportListener SideportListener::DEFAULT;
+
+SideportListener::SideportListener() : overlay(NULL) {
+}
+
+SideportListener::~SideportListener(){
+}
+
+string SideportListener::getEndpointDescription( const LinkID& link ) const {
+	if( overlay == NULL ) return "";
+	return overlay->getEndpointDescriptor(link).toString();
+}
+
+string SideportListener::getEndpointDescription( const NodeID& node ) const {
+	if( overlay == NULL ) return "";
+	return overlay->getEndpointDescriptor(node).toString();
+}
+
+const NodeID& SideportListener::getNodeID( const LinkID& link ) const {
+	if( overlay == NULL ) return NodeID::UNSPECIFIED;
+	return overlay->getNodeID(link);
+}
+
+vector<LinkID> SideportListener::getLinkIDs( const NodeID& node ) const {
+	if( overlay == NULL ) return vector<LinkID>();
+	return overlay->getLinkIDs( node );
+}
+
+void SideportListener::configure( overlay::BaseOverlay* _overlay ) {
+	overlay = _overlay;
+}
+
+void SideportListener::onLinkUp(const LinkID& lnk, const NodeID& local, const NodeID& remote, const SpoVNetID& spovnet){
+}
+
+void SideportListener::onLinkDown(const LinkID& lnk, const NodeID& local, const NodeID& remote, const SpoVNetID& spovnet){
+}
+
+void SideportListener::onLinkChanged(const LinkID& lnk, const NodeID& local, const NodeID& remote, const SpoVNetID& spovnet){
+}
+
+void SideportListener::onLinkFail(const LinkID& lnk, const NodeID& local, const NodeID& remote, const SpoVNetID& spovnet){
+}
+
+} // namespace ariba
Index: source/ariba/SideportListener.h
===================================================================
--- source/ariba/SideportListener.h	(revision 3374)
+++ source/ariba/SideportListener.h	(revision 3374)
@@ -0,0 +1,216 @@
+// [License]
+// The Ariba-Underlay Copyright
+//
+// Copyright (c) 2008-2009, Institute of Telematics, UniversitÃ€t Karlsruhe (TH)
+//
+// Institute of Telematics
+// UniversitÃ€t Karlsruhe (TH)
+// Zirkel 2, 76128 Karlsruhe
+// Germany
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// 1. Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// 2. Redistributions in binary form must reproduce the above copyright
+// notice, this list of conditions and the following disclaimer in the
+// documentation and/or other materials provided with the distribution.
+//
+// THIS SOFTWARE IS PROVIDED BY THE INSTITUTE OF TELEMATICS ``AS IS'' AND
+// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OF TELEMATICS OR
+// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// The views and conclusions contained in the software and documentation
+// are those of the authors and should not be interpreted as representing
+// official policies, either expressed or implied, of the Institute of
+// Telematics.
+// [License]
+
+#ifndef SIDEPORTLISTENER_H_
+#define SIDEPORTLISTENER_H_
+
+#include <vector>
+#include "Identifiers.h"
+#include "CommunicationListener.h"
+
+using std::vector;
+
+namespace ariba {
+
+// forward declerations
+class Node;
+class AribaModule;
+namespace overlay {
+	class BaseOverlay;
+}
+
+/**
+ * A sideport class to gather advanced information about nodes, links,
+ * their endpoints and get information about all link activity on a node.
+ *
+ * @author Christoph Mayer <mayer@tm.uka.de>
+ */
+class SideportListener {
+
+	friend class Node;
+	friend class AribaModule;
+	friend class overlay::BaseOverlay;
+
+public:
+
+	/**
+	 * A default object of the SideportListener that has empty
+	 * event functions and will return invalid information.
+	 */
+	static SideportListener DEFAULT;
+
+	/**
+	 * Constructor of the SideportListener.
+	 */
+	SideportListener();
+
+	/**
+	 * Virtual Desctructor for the SideportListener.
+	 */
+	virtual ~SideportListener();
+
+	/**
+	 * Get a descriptive string that identifies
+	 * the remote endpoint for the given link.
+	 *
+	 *  @param link The link to query endpoint information for.
+	 *  @return A descriptive endpoint information.
+	 */
+	string getEndpointDescription(
+			const LinkID& link
+			) const;
+
+	/**
+	 * Get a descriprive string that identifiers the remote node.
+	 *
+	 * @param node The node id to query endpoint information.
+	 * @return A descriptive endpoint information.
+	 */
+	string getEndpointDescription(
+			const NodeID& node = NodeID::UNSPECIFIED
+			) const;
+
+	/**
+	 * Get the remote endpoint node id for the given string,
+	 * or the local nodeid for an unspecified link.
+	 *
+	 * @param link The link to get the remote node.
+	 * @return The nodeid of the remote end of the link
+	 * 			or the local nodeid for an unspecified link.
+	 */
+	const NodeID& getNodeID(
+			const LinkID& link = LinkID::UNSPECIFIED
+			) const;
+
+	/**
+	 * Get all links that end at the specified node id.
+	 * Or all links from the local node when the node id
+	 * is set to unspecified.
+	 *
+	 * @param The remote node to query all links or unspecified
+	 * 			for all local starting links
+	 * @return A vector of link ids.
+	 */
+	vector<LinkID> getLinkIDs(
+			const NodeID& node = NodeID::UNSPECIFIED
+			) const;
+
+protected:
+
+	/**
+	 * Notification function when a link has gone up.
+	 *
+	 * @param lnk The corresponding link id.
+	 * @param local The local node id.
+	 * @param remote The remote node id.
+	 * @param spovnet The SpoVNet ID.
+	 */
+	virtual void onLinkUp(
+			const LinkID& lnk,
+			const NodeID& local,
+			const NodeID& remote,
+			const SpoVNetID& spovnet
+			);
+
+	/**
+	 * Notification function when a link has gone down.
+	 *
+	 * @param lnk The corresponding link id.
+	 * @param local The local node id.
+	 * @param remote The remote node id.
+	 * @param spovnet The SpoVNet ID.
+	 */
+	virtual void onLinkDown(
+			const LinkID& lnk,
+			const NodeID& local,
+			const NodeID& remote,
+			const SpoVNetID& spovnet
+			);
+
+	/**
+	 * Notification function when a link has changed
+	 *
+	 * @param lnk The corresponding link id.
+	 * @param local The local node id.
+	 * @param remote The remote node id.
+	 * @param spovnet The SpoVNet ID.
+	 */
+	virtual void onLinkChanged(
+			const LinkID& lnk,
+			const NodeID& local,
+			const NodeID& remote,
+			const SpoVNetID& spovnet
+			);
+
+	/**
+	 * Notification function when a link has failed
+	 *
+	 * @param lnk The corresponding link id.
+	 * @param local The local node id.
+	 * @param remote The remote node id.
+	 * @param spovnet The SpoVNet ID.
+	 */
+	virtual void onLinkFail(
+			const LinkID& lnk,
+			const NodeID& local,
+			const NodeID& remote,
+			const SpoVNetID& spovnet
+			);
+
+private:
+
+	/**
+	 * Configure the sideport with the correct base overlay.
+	 *
+	 * @param _overlay The BaseOverlay where to attach the sideport.
+	 */
+	void configure(
+			overlay::BaseOverlay* _overlay
+			);
+
+	/**
+	 * The configured BaseOverlay where
+	 * the sideport is attached to.
+	 */
+	overlay::BaseOverlay* overlay;
+
+};
+
+} // namespace ariba
+
+#endif // SIDEPORTLISTENER_H_
Index: source/ariba/ariba.h
===================================================================
--- source/ariba/ariba.h	(revision 3071)
+++ source/ariba/ariba.h	(revision 3374)
@@ -54,4 +54,5 @@
 #include "Node.h"
 #include "NodeListener.h"
+#include "SideportListener.h"
 #include "SpoVNetProperties.h"
 
Index: source/ariba/overlay/BaseOverlay.cpp
===================================================================
--- source/ariba/overlay/BaseOverlay.cpp	(revision 3071)
+++ source/ariba/overlay/BaseOverlay.cpp	(revision 3374)
@@ -42,4 +42,5 @@
 #include "ariba/NodeListener.h"
 #include "ariba/CommunicationListener.h"
+#include "ariba/SideportListener.h"
 
 namespace ariba {
@@ -49,7 +50,7 @@
 
 BaseOverlay::BaseOverlay()
-	: bc(NULL), overlayInterface(NULL),
-		nodeId(NodeID::UNSPECIFIED), spovnetId(SpoVNetID::UNSPECIFIED),
-		initiatorLink(LinkID::UNSPECIFIED), state(BaseOverlayStateInvalid){
+	: bc(NULL), overlayInterface(NULL), nodeId(NodeID::UNSPECIFIED),
+		spovnetId(SpoVNetID::UNSPECIFIED), initiatorLink(LinkID::UNSPECIFIED),
+		state(BaseOverlayStateInvalid), sideport(&SideportListener::DEFAULT){
 }
 
@@ -230,4 +231,6 @@
 
 	CommunicationListener* receiver = communicationListeners.get( service );
+	assert( receiver != NULL );
+
 	LinkItem item (link, NodeID::UNSPECIFIED, service, receiver);
 	linkMapping.insert( make_pair(link, item) );
@@ -251,6 +254,6 @@
 	bc->dropLink( link );
 
-	if( item.interface != NULL )
-		item.interface->onLinkDown( link, item.node );
+	item.interface->onLinkDown( link, item.node );
+	sideport->onLinkDown(link, this->nodeId, item.node, this->spovnetId );
 }
 
@@ -352,4 +355,13 @@
 	communicationListeners.registerItem( listener, sid );
 	return true;
+}
+
+bool BaseOverlay::registerSidePort(SideportListener* _sideport){
+	sideport = _sideport;
+	_sideport->configure( this );
+}
+
+bool BaseOverlay::unregisterSidePort(SideportListener* _sideport){
+	sideport = &SideportListener::DEFAULT;
 }
 
@@ -442,5 +454,5 @@
 	if( i == linkMapping.end() ){
 
-		LinkItem item (id, NodeID::UNSPECIFIED, ServiceID::UNSPECIFIED, NULL );
+		LinkItem item (id, NodeID::UNSPECIFIED, ServiceID::UNSPECIFIED, &CommunicationListener::DEFAULT );
 		linkMapping.insert( make_pair(id, item) );
 
@@ -487,6 +499,6 @@
 	}
 
-	if( i->second.interface != NULL )
-		i->second.interface->onLinkDown( id, i->second.node );
+	i->second.interface->onLinkDown( id, i->second.node );
+	sideport->onLinkDown( id, this->nodeId, i->second.node, this->spovnetId );
 
 	linkMapping.erase( i );
@@ -504,8 +516,8 @@
 	if( i == linkMapping.end() ) return;
 
-	if( i->second.interface != NULL ){
-		i->second.interface->onLinkChanged( id, i->second.node );
-		// call onLinkQoSChanged?
-	}
+	i->second.interface->onLinkChanged( id, i->second.node );
+	sideport->onLinkChanged( id, this->nodeId, i->second.node, this->spovnetId );
+
+	// TODO call onLinkQoSChanged?
 
 	i->second.markused();
@@ -523,6 +535,6 @@
 	if( i == linkMapping.end() ) return;
 
-	if( i->second.interface != NULL )
-		i->second.interface->onLinkFail( id, i->second.node );
+	i->second.interface->onLinkFail( id, i->second.node );
+	sideport->onLinkFail( id, this->nodeId, i->second.node, this->spovnetId );
 
 	i->second.markused();
@@ -541,7 +553,5 @@
 
 	// TODO: convert QoSParameterSet to the LinkProperties properties
-	if( i->second.interface != NULL ){
-		// TODO: currently not in the interface: i->second.interface->onLinkQoSChanged( id, i->second.node, LinkProperties::DEFAULT );
-	}
+	// TODO: currently not in the interface: i->second.interface->onLinkQoSChanged( id, i->second.node, LinkProperties::DEFAULT );
 
 	i->second.markused();
@@ -799,5 +809,5 @@
 
 		CommunicationListener* iface = communicationListeners.get( service );
-		if( iface == NULL ){
+		if( iface == NULL || iface == &CommunicationListener::DEFAULT ){
 			logging_warn( "linkup event for service that has been registered with a NULL interface" );
 			return true;
@@ -812,8 +822,12 @@
 
 		if( iface->onLinkRequest(sourcenode) ){
+
+			// call the notification functions
 			iface->onLinkUp( link, sourcenode );
+			sideport->onLinkUp( link, nodeId, sourcenode, this->spovnetId );
+
 		} else {
 			// prevent onLinkDown calls to the service
-			i->second.interface = NULL;
+			i->second.interface = &CommunicationListener::DEFAULT;
 			// drop the link
 			dropLink( link );
@@ -950,4 +964,17 @@
 }
 
+vector<LinkID> BaseOverlay::getLinkIDs( const NodeID& nid ) const {
+
+	vector<LinkID> linkvector;
+
+	BOOST_FOREACH( LinkPair item, linkMapping ){
+		if( item.second.node == nid || nid == NodeID::UNSPECIFIED ){
+			linkvector.push_back( item.second.link );
+		}
+	}
+
+	return linkvector;
+}
+
 void BaseOverlay::incomingRouteMessage(Message* msg){
 	// gets handled as normal data message
Index: source/ariba/overlay/BaseOverlay.h
===================================================================
--- source/ariba/overlay/BaseOverlay.h	(revision 3071)
+++ source/ariba/overlay/BaseOverlay.h	(revision 3374)
@@ -70,4 +70,5 @@
 	class NodeListener;
 	class CommunicationListener;
+	class SideportListener;
 	namespace utility {
 		class OvlVis;
@@ -220,4 +221,14 @@
 
 	/**
+	 * TODO
+	 */
+	bool registerSidePort(SideportListener* _sideport);
+
+	/**
+	 * TODO
+	 */
+	bool unregisterSidePort(SideportListener* _sideport);
+
+	/**
 	 * Returns the own nodeID or the NodeID of the specified link
 	 *
@@ -226,4 +237,13 @@
 	 */
 	const NodeID& getNodeID( const LinkID& lid = LinkID::UNSPECIFIED ) const ;
+
+	/**
+	 * Return all Links for the specified remote nodeid, or all links when
+	 * the node id given is set to unspecified
+	 *
+	 * @param nid The node id to request links for, or unspecified for all links
+	 * @return a vector that contains all the link ids requested
+	 */
+	vector<LinkID> getLinkIDs( const NodeID& nid = NodeID::UNSPECIFIED ) const;
 
 	/**
@@ -342,4 +362,9 @@
 
 	/**
+	 * TODO
+	 */
+	SideportListener* sideport;
+
+	/**
 	 * The abstract overlay interface that implements
 	 * the overlay specific functionality.
@@ -387,8 +412,16 @@
 		static const LinkItem UNSPECIFIED;
 
+		LinkItem()
+			: link(LinkID::UNSPECIFIED), node(NodeID::UNSPECIFIED),
+				service(ServiceID::UNSPECIFIED), interface(&CommunicationListener::DEFAULT),
+				autolink(false), lastuse(0){
+		}
+
 		LinkItem( const LinkID& _link, const NodeID& _node,
 				const ServiceID& _service, CommunicationListener* _interface )
 			: link( _link ), node( _node ), service( _service ), interface( _interface ),
 				autolink( false ), lastuse( time(NULL) ) {
+
+			assert( _interface != NULL );
 		}
 
