Index: FlowSet.cpp
===================================================================
--- FlowSet.cpp	(revision 5f0e41ecee466658d1e94cb2c711f9305b52a975)
+++ FlowSet.cpp	(revision 914f348b84b14a1b3bc5380280b6e824a5b70fde)
@@ -1,6 +1,23 @@
 #include "FlowSet.h"
 
-FlowSet::FlowSet(unsigned short _count, char remoteIPStr[], unsigned char remoteIPBytes[]) {
-	//stuff
+FlowSet::FlowSet(char remoteIPStr[]) {
+	srcIpStr = remoteIPStr;
+	return;	
+}
+
+void FlowSet::AddFlowSetRecord(FlowSetRecord *record)
+{
+	FlowSetRecords.push_back(record);
 	return;
 }
+
+FlowSetRecord* FlowSet::GetRecord(unsigned short index) {
+	if (index < FlowSetRecords.size()) {
+		return FlowSetRecords.at(index);
+	}
+	return nullptr;
+}
+
+unsigned short FlowSet::GetCount() {
+	return FlowSetRecords.size();
+}
Index: FlowSet.h
===================================================================
--- FlowSet.h	(revision 5f0e41ecee466658d1e94cb2c711f9305b52a975)
+++ FlowSet.h	(revision 914f348b84b14a1b3bc5380280b6e824a5b70fde)
@@ -1,3 +1,4 @@
-#include "FlowSetRecord.h"
+ #include "FlowSetRecord.h"
+#include <vector>
 
 #ifndef FLOWSET
@@ -9,14 +10,15 @@
     public:
 
-    FlowSetRecord *FlowSets[];
+		//Constructor (id, length)
+		FlowSet(char remoteIPStr[]);
 
-    //Constructor (id, length)
-    FlowSet(unsigned short _count, char remoteIPStr[], unsigned char remoteIPBytes[]);
+		void AddFlowSetRecord(FlowSetRecord *data);
+		FlowSetRecord* GetRecord(unsigned short index);
+		unsigned short GetCount();
 
     private:
 
-    unsigned short count;
-	char srcIpStr[];
-	unsigned char srcIpBytes[];
+		char *srcIpStr;
+		std::vector<FlowSetRecord*> FlowSetRecords;
 
 };
Index: FlowSetRecord.cpp
===================================================================
--- FlowSetRecord.cpp	(revision 5f0e41ecee466658d1e94cb2c711f9305b52a975)
+++ FlowSetRecord.cpp	(revision 914f348b84b14a1b3bc5380280b6e824a5b70fde)
@@ -3,4 +3,26 @@
 FlowSetRecord::FlowSetRecord(unsigned short _count) {
 	//do stuff
+	count = _count;
+	Field = new Field_t[count];
 	return;
 }
+
+FlowSetRecord::FlowSetRecord() {
+}
+
+void FlowSetRecord::AddRecord(unsigned short code, unsigned short length, unsigned char *data) {
+	Field[currentField].code = code;
+	Field[currentField].length = length;
+	Field[currentField].data = new unsigned char[length];
+	memcpy(Field[currentField].data, data, length);
+	currentField++;
+	return;
+}
+
+FlowSetRecord::Field_t FlowSetRecord::GetRecord(unsigned short index) {
+	return Field[index];
+}
+
+unsigned short FlowSetRecord::GetCount() {
+	return count;
+}
Index: FlowSetRecord.h
===================================================================
--- FlowSetRecord.h	(revision 5f0e41ecee466658d1e94cb2c711f9305b52a975)
+++ FlowSetRecord.h	(revision 914f348b84b14a1b3bc5380280b6e824a5b70fde)
@@ -1,2 +1,4 @@
+#include <cstring>
+
 #ifndef FLOWSETRECORD
 #define FLOWSETRECORD
@@ -7,19 +9,26 @@
 	public:
 
-	struct Field {
-		unsigned short code;
-		unsigned char data[];
-	};
-	typedef struct Field Field_t;
+		struct _Field {
+			unsigned short code;
+			unsigned short length;
+			unsigned char *data;
+		};
+		typedef struct _Field Field_t;
 
-	Field_t *Fields[];
+		//Constructor (id, length)
+		FlowSetRecord(unsigned short _count);
+		FlowSetRecord();
 
-	//Constructor (id, length)
-	FlowSetRecord(unsigned short _count);
+		void AddRecord(unsigned short code, unsigned short length, unsigned char *data);
+		Field_t GetRecord(unsigned short index);
+		unsigned short GetCount();
+
 
 
 	private:
 
-	unsigned short count;
+		Field_t *Field;
+		unsigned short count=0;
+		unsigned short currentField=0;
 
 };
Index: NetFlow9Processor.cpp
===================================================================
--- NetFlow9Processor.cpp	(revision 5f0e41ecee466658d1e94cb2c711f9305b52a975)
+++ NetFlow9Processor.cpp	(revision 914f348b84b14a1b3bc5380280b6e824a5b70fde)
@@ -19,4 +19,5 @@
 		case AF_INET:
 			//set IP
+			inet_ntop(AF_INET, &((sockaddr_in *)remoteAddress)->sin_addr, remoteIPStr, INET_ADDRSTRLEN);
 			break;
 		case AF_INET6:
@@ -27,8 +28,9 @@
 			break;
 	}
-	
-}
-
-int NetFlow9Processor::ProcessPacket(unsigned char buffer[], int bufferLength, FlowSet* processedFlowSet) {
+	name = "undefined";
+	
+}
+
+FlowSet* NetFlow9Processor::ProcessPacket(unsigned char buffer[], int bufferLength) {
 
 	int nextIndex = 0;					// Next byte in the buffer
@@ -41,8 +43,9 @@
 	unsigned int sequenceID = 0;		// Incremented by one for each packet sent
 	unsigned int sourceID = 0;			// Locally significant source ID
+	FlowSet* processedFlowSet = nullptr;
 
 	if ( bufferLength < 24) {
 		//Packet is too short to contain a header
-		return 254;
+		return processedFlowSet;
 	}
 	
@@ -51,5 +54,5 @@
 	if (version != 9) {
 			//Not a NetFlow v9 packet
-			return 253;
+			return processedFlowSet;
 	}
 
@@ -59,5 +62,5 @@
 	if (count < 1) {
 			//Not a NetFlow v9 packet
-			return 252;
+			return processedFlowSet;
 	}
 
@@ -77,10 +80,10 @@
 		if (nextIndex + flowSetLength > bufferLength) {
 			//Invalid/unsupported packet
-			return 251;
+			return processedFlowSet;
 		}
 		if (flowSetID > 255) {
 			//DATA FlowSet
 			printf("  -> Found data flowSetID %d, length %d.\n", flowSetID, flowSetLength);
-			processDataFlowSet(buffer,nextIndex,flowSetID,flowSetLength);
+			processedFlowSet = processDataFlowSet(buffer,nextIndex,flowSetID,flowSetLength, remoteIPStr);
 		}
 		else if (flowSetID == 0) {
@@ -95,5 +98,5 @@
 		else {
 			//Invalid/unsupported packet
-			return 250;
+			return processedFlowSet;
 		}
 		nextIndex += flowSetLength;
@@ -101,34 +104,60 @@
 	while ( nextIndex < bufferLength);
 
-	return sequenceID;
-}
-
-void NetFlow9Processor::processDataFlowSet(unsigned char buffer[], int startIndex, unsigned short flowSetID, unsigned short flowSetLength) {
+	return processedFlowSet;
+}
+
+FlowSet* NetFlow9Processor::processDataFlowSet(unsigned char buffer[], int startIndex, unsigned short flowSetID, unsigned short flowSetLength, char strRemoteIP[]) {
 	int nextIndex = startIndex + 4;             // Next place to look (skip 4 header bytes already parsed)
 	int endIndex = startIndex + flowSetLength ; // End the loop at the end of the template
 	NetFlowDataTemplate *dataTemplate;          // Data Template object
 	NetFlowDataTemplate::Field_t field;
+	FlowSet *Flowset = new FlowSet(strRemoteIP);
+	int recordsExpected = 0;
+	int dataTemplateRecordLength = 0;
+	int lengthOfAllRecords = 0;
 	int count = 0;
 
-	do {
-		
 		dataTemplate = dataTemplateCache->GetDataTemplate(flowSetID);
 		if (!dataTemplate) {
 			printf("  -> Template ID %d doesn't exist in the cache...  skipping\n", flowSetID);
-			return;
-		}
-		printf("  -> Parsing record %d.\n", count);
-		for (std::list<NetFlowDataTemplate::Field_t>::iterator it=dataTemplate->Fields.begin(); it != dataTemplate->Fields.end(); ++it) {
-			field = *it;
-			printf("    -> Code: %d, length: %d\n", field.code, field.length);
-
-			//TODO: Form a standard record and return it
-
-			nextIndex += field.length;
-		}
-		count++;
-	}
-	while ( nextIndex < endIndex );
-}
+			return nullptr;
+		}
+
+		dataTemplateRecordLength = dataTemplate->recordLength();
+		recordsExpected = flowSetLength / dataTemplateRecordLength;
+		lengthOfAllRecords = recordsExpected * dataTemplateRecordLength;
+
+		if (lengthOfAllRecords>flowSetLength) {
+			printf("  -> Length of all record expected in the FlowSet exceeds the length reported\n");
+			return nullptr;
+		}
+
+		printf("  -> FS Length %d, FSR Length: %d, FSRs expected: %d, recalculated length: %d\n", dataTemplateRecordLength, flowSetLength, recordsExpected, lengthOfAllRecords);
+	
+		for (count = 0; count < recordsExpected; count++) {
+		
+			printf("  -> Parsing record %d.\n", count);
+
+			FlowSetRecord *record = new FlowSetRecord(dataTemplate->Fields.size());
+
+			for (std::list<NetFlowDataTemplate::Field_t>::iterator it=dataTemplate->Fields.begin(); it != dataTemplate->Fields.end(); ++it) {
+				field = *it;
+				printf("    -> Code: %d, length: %d\n", field.code, field.length);
+
+				//Form a standard record and return it
+
+				unsigned char recordBuffer[field.length];
+				std::copy(buffer + nextIndex, buffer + nextIndex + field.length, recordBuffer);
+				record->AddRecord(field.code, field.length, recordBuffer);
+
+				nextIndex += field.length;
+			}
+
+			Flowset->AddFlowSetRecord(record);
+		}
+
+	return Flowset;
+}
+
 void NetFlow9Processor::processTemplateFlowSet(unsigned char buffer[], int startIndex, unsigned short flowSetLength) {
 
Index: NetFlow9Processor.h
===================================================================
--- NetFlow9Processor.h	(revision 5f0e41ecee466658d1e94cb2c711f9305b52a975)
+++ NetFlow9Processor.h	(revision 914f348b84b14a1b3bc5380280b6e824a5b70fde)
@@ -16,5 +16,5 @@
 
 		NetFlow9Processor(struct sockaddr *remoteAddress, socklen_t *addressLength);
-		int ProcessPacket(unsigned char buffer[], int bufferLength, FlowSet* processedFlowSet);
+		FlowSet* ProcessPacket(unsigned char buffer[], int bufferLength);
 
 
@@ -22,11 +22,12 @@
 
 		NetFlowDataTemplateCache *dataTemplateCache;
-		char remoteIPStr[];
-		unsigned char remoteIPBytes[];
+		char remoteIPStr[INET6_ADDRSTRLEN];
+		unsigned char remoteIPBytes[16];
+		std::string name;
 //		NetFlowDataTemplate::DataTemplateItem_t *strtest;
 
 		unsigned int ByteTouInt32(unsigned char bytes[], int base);
 		unsigned short ByteTouInt16(unsigned char bytes[], int base);
-		void processDataFlowSet(unsigned char buffer[], int nextIndex, unsigned short flowSetID, unsigned short flowSetLength);
+		FlowSet* processDataFlowSet(unsigned char buffer[], int nextIndex, unsigned short flowSetID, unsigned short flowSetLength, char strRemoteIP[]);
 		void processTemplateFlowSet(unsigned char buffer[], int nextIndex, unsigned short flowSetLength);
 
Index: NetFlowDataTemplate.cpp
===================================================================
--- NetFlowDataTemplate.cpp	(revision 5f0e41ecee466658d1e94cb2c711f9305b52a975)
+++ NetFlowDataTemplate.cpp	(revision 914f348b84b14a1b3bc5380280b6e824a5b70fde)
@@ -5,2 +5,11 @@
 	_count = fieldCount;
 }
+
+int NetFlowDataTemplate::recordLength() {
+	int total = 0;
+	for (std::list<NetFlowDataTemplate::Field_t>::iterator it = Fields.begin(); it != Fields.end(); ++it) {
+		Field_t field = *it;
+		total += field.length;
+	}
+	return total;
+}
Index: NetFlowDataTemplate.h
===================================================================
--- NetFlowDataTemplate.h	(revision 5f0e41ecee466658d1e94cb2c711f9305b52a975)
+++ NetFlowDataTemplate.h	(revision 914f348b84b14a1b3bc5380280b6e824a5b70fde)
@@ -9,21 +9,20 @@
 	public:
 
-	struct Field {
-		unsigned short code;
-		unsigned short length;
-	};
-	typedef struct Field Field_t;
+		struct Field {
+			unsigned short code;
+			unsigned short length;
+		};
+		typedef struct Field Field_t;
 
-	std::list<Field_t> Fields;
+		std::list<Field_t> Fields;
 
-	//Constructor (templateID, fieldCount)
-	NetFlowDataTemplate(unsigned short templateID, unsigned short fieldCount);
-	
-
+		//Constructor (templateID, fieldCount)
+		NetFlowDataTemplate(unsigned short templateID, unsigned short fieldCount);
+		int recordLength();
 
 	private:
 	
-	unsigned short _id;
-	unsigned short _count;
+		unsigned short _id;
+		unsigned short _count;
 
 };
Index: NetSlow.vcxproj
===================================================================
--- NetSlow.vcxproj	(revision 5f0e41ecee466658d1e94cb2c711f9305b52a975)
+++ NetSlow.vcxproj	(revision 914f348b84b14a1b3bc5380280b6e824a5b70fde)
@@ -84,5 +84,4 @@
     <ClInclude Include="NetFlowDataTemplate.h" />
     <ClInclude Include="NetFlowDataTemplateCache.h" />
-    <ClInclude Include="port.h" />
   </ItemGroup>
   <ItemGroup>
Index: netslow.cpp
===================================================================
--- netslow.cpp	(revision 5f0e41ecee466658d1e94cb2c711f9305b52a975)
+++ netslow.cpp	(revision 914f348b84b14a1b3bc5380280b6e824a5b70fde)
@@ -5,5 +5,4 @@
 #include <sys/socket.h>
 #include <arpa/inet.h>
-#include "port.h"
 #include "NetFlow9Processor.h"
 #include "FlowSet.h"
@@ -26,6 +25,9 @@
 	FlowSet *processedFlowSet;						/* Returned flowset after processing */
 	string filename = "/home/ian/projects/NetSlow/netslow.conf";	/* Configuration file - TODO: Add to CLI Arguments */
+	std::string name;
 
 	Config *config = new Config(filename, envp);
+
+	//TODO: Error/syntax checking
 
 	//Create a UDP socket - currently IPv4 only
@@ -51,8 +53,14 @@
 
 	if (config->pBool("single_router")) {
+
 		remoteAddress.sin_family = AF_INET;
 		//TODO: Support IPv6
 		inet_pton(AF_INET, config->group("router1")->pString("ip").c_str(), &(remoteAddress.sin_addr));
 		NetFlow9 = new NetFlow9Processor((struct sockaddr *)&remoteAddress, &addressLength);
+		
+		if (config->group("router1")->pString("name").c_str()) {
+			//TODO: Assign to processor
+			name = config->group("router1")->pString("name");
+		}
 
 		//NetFlow is very simple, so we can simply loop over all packets
@@ -75,7 +83,13 @@
 					//NFv9
 //					printf("Len: %d...  Running NetFlow9Packet Processor\n", bytesReceived);
-					retval = NetFlow9->ProcessPacket(buffer, bytesReceived, processedFlowSet);
-					if (processedFlowSet == 0) {
-						printf("Error in NF9Processor - invalid pointer\n");
+					processedFlowSet = NetFlow9->ProcessPacket(buffer, bytesReceived);
+					if (processedFlowSet == nullptr) {
+						printf("Possible error in NF9Processor - invalid pointer\n");
+					}
+					else {
+						printf("PacketProcessor returned %d flow set records\n", processedFlowSet->GetCount());
+						printf("FSR 0, record 6, code %x, length %d, value: ", processedFlowSet->GetRecord(0)->GetRecord(6).code, processedFlowSet->GetRecord(0)->GetRecord(6).length);
+						for (int i = 0; i < processedFlowSet->GetRecord(0)->GetRecord(6).length; i++) { printf("%02X", processedFlowSet->GetRecord(0)->GetRecord(6).data[i]); }
+						printf("\n");
 					}
 					break;
@@ -84,5 +98,4 @@
 				}
 
-				printf("PacketProcessor returned %d\n", processedFlowSet);
 			}
 		}
Index: rt.h
===================================================================
--- port.h	(revision 5f0e41ecee466658d1e94cb2c711f9305b52a975)
+++ 	(revision )
@@ -1,9 +1,0 @@
-
-/* SERVIVE_PORT defines the default port number for this service 
- * replace the number with a unique number > 1024
- * a reasonable number may be obtained from, say, four
- * digits of your id + 1024
- */
-
-#define SERVICE_PORT	9997	/* hard-coded port number */
-
