First steps in CCNx packet coding. ccnx_encode* routines rewritten in NS3 style (using NS3::Buffer)

diff --git a/in-progress/ccnx-fib.cpp b/in-progress/ccnx-fib.cpp
new file mode 100644
index 0000000..a8adbd0
--- /dev/null
+++ b/in-progress/ccnx-fib.cpp
@@ -0,0 +1,300 @@
+/* 
+ * File:   ndn_fib.cpp
+ * Author: cawka
+ * 
+ * Created on December 15, 2010, 1:54 PM
+ */
+
+#include "ndn.h"
+#include "ndn_fib.h"
+
+#include <node.h>
+#include <buffer.h>
+#include <network_ip.h>
+#include <partition.h>
+#include <routing_ospfv2.h>
+#include <routing_bgp.h>
+
+//#define NDN_DEBUG_OSPF	0
+//#define NDN_DEBUG_OSPF_NODES 0
+
+//#define NDN_DUMP_FIB		0
+
+
+NdnFib::NdnFib( Ndn &node ) : _node(node) { }
+
+NdnFib::~NdnFib( ) { }
+
+
+//Find corresponding FIB entry for the given content name
+//Longest match is performed
+FibIterator NdnFib::lookup( const string &name )
+{
+	string prefix=name;
+
+	FibIterator entry;
+	do
+	{
+		entry=_fib.find( prefix );
+
+		prefix = GetLongestNamePrefix( prefix );
+	} while( !isValid(entry) && prefix.size()>0 );
+
+	return entry;
+}
+
+bool NdnFibNexthopSorter::operator()( const FibNexthop &first, const FibNexthop &second )
+{
+	// Right now is a very simple logic.
+	// Probably this logic should be changed later
+	if( first. cost==NETWORK_UNREACHABLE && second.cost>=0 ) return false;
+	if( second.cost==NETWORK_UNREACHABLE && first. cost>=0 ) return true;
+	return  first.cost < second.cost;
+}
+
+/**
+ * Update FIB entry
+ * If the entry exists, metric will be updated. Otherwise, new entry will be created
+ * 
+ * @param name				Prefix
+ * @param interfaceIndex	Forwarding interface
+ * @param metric			Routing metric
+ * @param nextHop			Nexthop node address (IPv4)
+ * @return true if a new entry created, false otherwise
+ */
+bool NdnFib::update( const string &name, int interfaceIndex, int metric, NodeAddress nextHop )
+{
+	FibIterator entry = _fib.find( name );
+	if( isValid(entry) )
+	{
+		FibNexthopIterator nh = VALUE(entry).findNexthop( interfaceIndex );
+
+		if( !VALUE(entry).isValid(nh) )
+		{
+			nh = VALUE(entry).forwardingList.insert( VALUE(entry).forwardingList.begin(),
+											 FibNexthop(interfaceIndex,nextHop,metric) );
+		}
+		else
+		{
+			nh->cost = metric;
+			nh->nextHop = nextHop;
+		}
+
+		VALUE(entry).forwardingList.sort( NdnFibNexthopSorter() );
+
+		return false;
+	}
+
+	FibEntry &new_entry = _fib[name];
+	new_entry.forwardingList.push_back( FibNexthop(interfaceIndex,nextHop,metric) );
+
+	for( int interface=0; interface < _node.getNode()->numberInterfaces; interface++ )
+	{
+		NodeAddress src = NetworkIpGetInterfaceAddress( _node.getNode(), interface );
+
+		if( isValidLink(src) && interface!=interfaceIndex )
+		{
+			new_entry.forwardingList.push_back( FibNexthop(interface,0,NETWORK_UNREACHABLE) );
+		}
+	}
+
+	return true;
+}
+
+// helper for update call
+bool NdnFib::update( NodeAddress nodeId, int metric, NodeAddress nextHop )
+{
+	ostringstream os;
+	os << (int)nodeId;
+
+	int interface = NetworkIpGetInterfaceIndexForNextHop( _node.getNode(), nextHop );
+
+	return update( os.str(), interface, metric, nextHop );
+}
+
+// helper for update call
+bool NdnFib::update( NodeAddress nodeId, int interfaceIndex, int metric, NodeAddress nextHop )
+{
+	ostringstream os;
+	os << (int)nodeId;
+
+	int interface = NetworkIpGetInterfaceIndexForNextHop( _node.getNode(), nextHop );
+
+	return update( os.str(), interface, metric, nextHop ); //unknown metric
+}
+
+/**
+ * Invalidate entries in FIB
+ */
+void NdnFib::invalidate( )
+{
+	for( FibRangeIterator fib=_fib.begin(); fib!=_fib.end(); fib++ )
+	{
+		for( FibNexthopIterator nh=VALUE(fib).forwardingList.begin(); nh!=VALUE(fib).forwardingList.end(); nh++ )
+		{
+			nh->cost = NETWORK_UNREACHABLE;
+		}
+	}
+}
+
+//compute and update STO value for Fib Entry (similar to RFC 2988)
+//for now we pick the maximum rto of all forwardings
+void FibEntry::updateSto( )
+{
+    assert( forwardingList.size() > 0 );
+
+    clocktype max = 0;
+
+    for( FibNexthopIterator it = forwardingList.begin();
+		 it != forwardingList.end();
+		 it++ )
+    {
+        clocktype sto = it->srtt + NDN_RTO_K * it->rttvar;
+
+        if( sto > max )
+			max = sto;
+    }
+
+    this->sto = max;
+}
+
+
+/**
+ * Updating FIB using data from OSPF
+ * @param node
+ * @param interface	-2	Invalid OSPF (to purge FIB)
+ *					-1	Normal OSPF
+ *					0-N	SPF was calcylated using only interface `interface'
+ *
+ * @bug	All local networks will always appear in routing table with cost == 1
+ */
+void NdnFib::updateFibFromOSPFv2( int interface )
+{
+    Ospfv2Data* ospf = (Ospfv2Data*)NetworkIpGetRoutingProtocol(_node.getNode(), ROUTING_PROTOCOL_OSPFv2);
+
+	if( interface==-2 ) invalidate( );
+
+#ifdef NDN_DEBUG_OSPF
+	if( interface==-1 ) printf( "Routing/interface costs\n" );
+#endif // NDN_DEBUG_OSPF
+
+#ifdef NDN_DEBUG_OSPF_NODES
+	printf( "-- Node %d (interface %d) --\n", _node.getNode()->nodeId, interface );
+#endif // NDN_DEBUG_OSPF_NODES
+
+    Ospfv2RoutingTableRow* rowPtr = (Ospfv2RoutingTableRow*)
+            BUFFER_GetData(&ospf->routingTable.buffer);
+
+    for (int i = 0; i < ospf->routingTable.numRows; i++)
+    {
+		NodeAddress destNodeId = Ipv4ToNodeId( rowPtr[i].destAddr );
+
+		if( destNodeId!=-1 ) update( destNodeId, rowPtr[i].metric, rowPtr[i].nextHop );
+    }
+
+#ifdef NDN_DUMP_FIB
+	if( interface==-1 ) dump( );
+#endif
+}
+
+void NdnFib::updateFibFromBGP( )
+{
+	BgpData* bgp=(BgpData*)_node.getNode()->appData.exteriorGatewayVar;
+
+	assert( bgp->ip_version == NETWORK_IPV4 );
+
+	invalidate( );
+
+	int i=0;
+	int numEntriesInAdjRibIn=BUFFER_GetCurrentSize( &( bgp->adjRibIn ) )
+			/ sizeof(BgpRoutingInformationBase );
+
+	BgpRoutingInformationBase* adjRibInPtr=(BgpRoutingInformationBase*)
+			BUFFER_GetData( &( bgp->adjRibIn ) );
+
+	for( i=0; i < numEntriesInAdjRibIn; i++ )
+	{
+		assert( adjRibInPtr[i].nextHop.networkType == NETWORK_IPV4 );
+
+		NodeAddress destNodeId = Ipv4ToNodeId( GetIPv4Address(adjRibInPtr[i].destAddress.prefix) );
+
+		if( destNodeId!=-1 && adjRibInPtr[i].isValid != FALSE )
+		{
+			char destNodeStr[NDN_MAX_NAME_LENGTH];
+			memset(destNodeStr, 0, NDN_MAX_NAME_LENGTH);
+			sprintf(destNodeStr, "%d", destNodeId);
+
+			update( destNodeId,
+					adjRibInPtr[i].asPathList->pathSegmentLength / 2,
+					GetIPv4Address(adjRibInPtr[i].nextHop) );
+		}
+	}
+
+#ifdef NDN_DUMP_FIB
+	dump( );
+#endif
+}
+
+void NdnFib::updateFibFromIpRouting( )
+{
+	invalidate( );
+
+	for (int i = 0; i < _node.getNode()->partitionData->numNodes; i ++)
+    {
+		if( !_node.getNode()->networkData.networkVar->ndnEnabled ) continue;
+
+        NodeAddress destNode = _node.getNode()->partitionData->nodeData[i]->nodeId;
+		NodeAddress ipv4subnet = NodeIdToIpv4( destNode );
+
+		int interfaceIndex;
+		NodeAddress nextHopAddr;
+        NetworkGetInterfaceAndNextHopFromForwardingTable(
+			_node.getNode(), ipv4subnet, &interfaceIndex, &nextHopAddr );
+
+        if( interfaceIndex != NETWORK_UNREACHABLE )
+        {
+			update( destNode, interfaceIndex, 1, nextHopAddr );
+        }
+    }
+}
+
+
+
+void NdnFib::dump( )
+{
+	if( _node.getNode()->numberInterfaces==1 ) return;  // do not dump FIB for `virtual' nodes
+
+	printf( "Node %s: FIB\n", _node.getPrefix().c_str() );
+	printf( "  Dest prefix      Interfaces(Costs)                  \n" );
+	printf( "+-------------+--------------------------------------+\n" );
+
+	for( FibRangeIterator fib=_fib.begin(); fib!=_fib.end(); fib++ )
+	{
+		dump( fib );
+	}
+}
+
+void NdnFib::dump( const FibIterator &fib )
+{
+	printf( " %8s ", fib->first.c_str() );
+	for( FibNexthopIterator nh=VALUE(fib).forwardingList.begin(); nh!=VALUE(fib).forwardingList.end(); nh++ )
+	{
+		if( nh!=VALUE(fib).forwardingList.begin() ) printf( "," );
+		printf( "i%d(%d)", nh->interfaceIndex, nh->cost );
+	}
+	printf( "\n" );
+}
+
+void NdnFib::resetProbing()
+{
+    for(FibRangeIterator fib = _fib.begin(); fib != _fib.end(); fib++)
+        VALUE(fib).needsProbing = true;
+}
+
+void NdnFib::updateInterfaceStatus( int interface, int status )
+{
+	for( FibRangeIterator fib = _fib.begin(); fib!=_fib.end(); fib++ )
+	{
+		VALUE(fib).updateStatus( interface, status );
+	}
+}
\ No newline at end of file