Got rid of different Template types, compiled and roughly tested

git-svn-id: file:///Users/braun/svn/vermont/branches/vermont/new-template@2200 aef3b71b-58ee-0310-9ba9-8811b9f0742f
master
muenz 2009-12-02 14:26:57 +00:00
parent 3ea294f6ff
commit c81b3e79e1
33 changed files with 766 additions and 1015 deletions

View File

@ -23,7 +23,7 @@
<ieName>destinationIPv4Address</ieName>
</flowKey>
<flowKey>
<ieName>icmpTypeCode</ieName>
<ieName>icmpTypeCodeIPv4</ieName>
</flowKey>
<flowKey>
<ieName>protocolIdentifier</ieName>
@ -125,6 +125,7 @@
<collector>
<ipAddress>127.0.0.1</ipAddress>
<transportProtocol>132</transportProtocol>
<port>1500</port>
</collector>
</ipfixExporter>
</ipfixConfig>

View File

@ -39,6 +39,8 @@ extern "C" {
#define IPFIX_protocolIdentifier_SCTP 132
#define IPFIX_protocolIdentifier_RAW 255
#define NetflowV9_SetId_Template 0
#define NetflowV9_SetId_OptionsTemplate 1
#define IPFIX_SetId_Template 2
#define IPFIX_SetId_OptionsTemplate 3
#define IPFIX_SetId_DataTemplate 4

View File

@ -42,7 +42,7 @@ Connection::Connection(IpfixDataDataRecord* record)
dstPayload(0), dstPayloadLen(0)
{
// convert IpfixDataDataRecord to Connection
IpfixRecord::FieldInfo* fi = record->dataTemplateInfo->getFieldInfo(IPFIX_TYPEID_sourceIPv4Address, 0);
TemplateInfo::FieldInfo* fi = record->dataTemplateInfo->getFieldInfo(IPFIX_TYPEID_sourceIPv4Address, 0);
if (fi != 0) {
srcIP = *(uint32_t*)(record->data + fi->offset);
} else {
@ -160,7 +160,7 @@ Connection::Connection(IpfixDataDataRecord* record)
if (fi != 0) dstTcpControlBits = *(uint8_t*)(record->data + fi->offset);
fi = record->dataTemplateInfo->getFieldInfo(IPFIX_ETYPEID_frontPayload, 0);
if (fi != 0 && fi->type.length) {
IpfixRecord::FieldInfo* filen = record->dataTemplateInfo->getFieldInfo(IPFIX_ETYPEID_frontPayloadLen, 0);
TemplateInfo::FieldInfo* filen = record->dataTemplateInfo->getFieldInfo(IPFIX_ETYPEID_frontPayloadLen, 0);
if (filen != 0)
srcPayloadLen = ntohl(*(uint32_t*)(record->data + filen->offset));
else
@ -170,7 +170,7 @@ Connection::Connection(IpfixDataDataRecord* record)
}
fi = record->dataTemplateInfo->getFieldInfo(IPFIX_ETYPEID_revFrontPayload, 0);
if (fi != 0 && fi->type.length) {
IpfixRecord::FieldInfo* filen = record->dataTemplateInfo->getFieldInfo(IPFIX_ETYPEID_revFrontPayloadLen, 0);
TemplateInfo::FieldInfo* filen = record->dataTemplateInfo->getFieldInfo(IPFIX_ETYPEID_revFrontPayloadLen, 0);
if (filen != 0)
dstPayloadLen = ntohl(*(uint32_t*)(record->data + filen->offset));
else

View File

@ -36,7 +36,7 @@ InstanceManager<IpfixTemplateDestructionRecord> IpfixDbReader::templateDestructi
/***** Internal Functions ****************************************************/
void copyUintNetByteOrder(IpfixRecord::Data* dest, char* src, IpfixRecord::FieldInfo::Type type);
void copyUintNetByteOrder(IpfixRecord::Data* dest, char* src, TemplateInfo::FieldInfo::Type type);
/**
* First send a a new template, then send the dataTemplates for all stored
@ -50,7 +50,8 @@ void* IpfixDbReader::readFromDB(void* ipfixDbReader_)
msg(MSG_DIALOG, "IpfixDbReader: Start sending tables");
for(vector<string>::iterator i = ipfixDbReader->tables.begin(); i != ipfixDbReader->tables.end() && !ipfixDbReader->exitFlag; i++) {
boost::shared_ptr<IpfixRecord::TemplateInfo> templateInfo(new IpfixRecord::TemplateInfo);
boost::shared_ptr<TemplateInfo> templateInfo(new TemplateInfo);
templateInfo->setId = TemplateInfo::IpfixTemplate;
if(ipfixDbReader->dbReaderSendNewTemplate(templateInfo, *i) != 0)
{
msg(MSG_ERROR, "IpfixDbReader: Template error, skip table");
@ -70,16 +71,11 @@ void* IpfixDbReader::readFromDB(void* ipfixDbReader_)
* Constructs a template from the table data and sends it to all connected
* modules.
*/
int IpfixDbReader::dbReaderSendNewTemplate(boost::shared_ptr<IpfixRecord::TemplateInfo> templateInfo, const string& tableName)
int IpfixDbReader::dbReaderSendNewTemplate(boost::shared_ptr<TemplateInfo> templateInfo, const string& tableName)
{
// reset record length
recordLength = 0;
templateInfo->templateId =0;
templateInfo->fieldCount = 0;
templateInfo->fieldInfo = NULL;
templateInfo->userData = NULL;
/**get columnsname of the table*/
if(getColumns(tableName) != 0) {
msg(MSG_ERROR,"IpfixDbReader: Could not get columns for template");
@ -88,12 +84,12 @@ int IpfixDbReader::dbReaderSendNewTemplate(boost::shared_ptr<IpfixRecord::Templa
for(vector<columnDB>::iterator i = columns.begin(); i != columns.end(); i++) {
templateInfo->fieldCount++;
templateInfo->fieldInfo = (IpfixRecord::FieldInfo*)realloc(templateInfo->fieldInfo,
sizeof(IpfixRecord::FieldInfo)*templateInfo->fieldCount);
IpfixRecord::FieldInfo* fi = &templateInfo->fieldInfo[templateInfo->fieldCount - 1];
templateInfo->fieldInfo = (TemplateInfo::FieldInfo*)realloc(templateInfo->fieldInfo,
sizeof(TemplateInfo::FieldInfo)*templateInfo->fieldCount);
TemplateInfo::FieldInfo* fi = &templateInfo->fieldInfo[templateInfo->fieldCount - 1];
fi->type.id = i->ipfixId;
fi->type.length = i->length;
fi->type.eid = 0;
fi->type.enterprise = 0;
fi->offset = recordLength;
recordLength = recordLength + fi->type.length;
}
@ -108,7 +104,7 @@ int IpfixDbReader::dbReaderSendNewTemplate(boost::shared_ptr<IpfixRecord::Templa
}
void copyUintNetByteOrder(IpfixRecord::Data* dest, char* src, IpfixRecord::FieldInfo::Type type) {
void copyUintNetByteOrder(IpfixRecord::Data* dest, char* src, TemplateInfo::FieldInfo::Type type) {
switch (type.length) {
case 1:
*(uint8_t*)dest = *(uint8_t*)src;
@ -135,7 +131,7 @@ void copyUintNetByteOrder(IpfixRecord::Data* dest, char* src, IpfixRecord::Field
* strings, therefore they must change into IPFIX format
*/
int IpfixDbReader::dbReaderSendTable(boost::shared_ptr<IpfixRecord::TemplateInfo> templateInfo, const string& tableName)
int IpfixDbReader::dbReaderSendTable(boost::shared_ptr<TemplateInfo> templateInfo, const string& tableName)
{
MYSQL_RES* dbResult = NULL;
MYSQL_ROW dbRow = NULL;
@ -271,7 +267,7 @@ int IpfixDbReader::dbReaderSendTable(boost::shared_ptr<IpfixRecord::TemplateInfo
}
int IpfixDbReader::dbReaderDestroyTemplate(boost::shared_ptr<IpfixRecord::TemplateInfo> templateInfo)
int IpfixDbReader::dbReaderDestroyTemplate(boost::shared_ptr<TemplateInfo> templateInfo)
{
IpfixTemplateDestructionRecord* ipfixRecord = templateDestructionRecordIM.getNewInstance();
ipfixRecord->sourceID = srcId;

View File

@ -78,9 +78,9 @@ class IpfixDbReader : public Module, public Source<IpfixRecord*>, public Destina
int getTables();
int getColumns(const string& tableName);
static void* readFromDB(void* ipfixDbReader_);
int dbReaderSendNewTemplate(boost::shared_ptr<IpfixRecord::TemplateInfo> templateInfo, const string& tableName);
int dbReaderSendTable(boost::shared_ptr<IpfixRecord::TemplateInfo> templateInfo, const string& tableName);
int dbReaderDestroyTemplate(boost::shared_ptr<IpfixRecord::TemplateInfo> templateInfo);
int dbReaderSendNewTemplate(boost::shared_ptr<TemplateInfo> templateInfo, const string& tableName);
int dbReaderSendTable(boost::shared_ptr<TemplateInfo> templateInfo, const string& tableName);
int dbReaderDestroyTemplate(boost::shared_ptr<TemplateInfo> templateInfo);
int connectToDb( const string& hostName, const string& dbName, const string& userName, const string& password, unsigned int port);
};

View File

@ -36,28 +36,29 @@
* Attention: order of entries is important!
*/
IpfixDbWriter::Column identify [] = {
{CN_dstIP, "INTEGER(10) UNSIGNED", 0, IPFIX_TYPEID_destinationIPv4Address},
{CN_srcIP, "INTEGER(10) UNSIGNED", 0, IPFIX_TYPEID_sourceIPv4Address},
{CN_srcPort, "SMALLINT(5) UNSIGNED", 0, IPFIX_TYPEID_sourceTransportPort},
{CN_dstPort, "SMALLINT(5) UNSIGNED", 0, IPFIX_TYPEID_destinationTransportPort},
{CN_proto, "TINYINT(3) UNSIGNED", 0, IPFIX_TYPEID_protocolIdentifier },
{CN_dstTos, "TINYINT(3) UNSIGNED", 0, IPFIX_TYPEID_classOfServiceIPv4},
{CN_bytes, "BIGINT(20) UNSIGNED", 0, IPFIX_TYPEID_octetDeltaCount},
{CN_pkts, "BIGINT(20) UNSIGNED", 0, IPFIX_TYPEID_packetDeltaCount},
{CN_firstSwitched, "INTEGER(10) UNSIGNED", 0, IPFIX_TYPEID_flowStartSeconds}, // default value is invalid/not used for this ent
{CN_lastSwitched, "INTEGER(10) UNSIGNED", 0, IPFIX_TYPEID_flowEndSeconds}, // default value is invalid/not used for this entry
{CN_firstSwitchedMillis, "SMALLINT(5) UNSIGNED", 0, IPFIX_TYPEID_flowStartMilliSeconds},
{CN_lastSwitchedMillis, "SMALLINT(5) UNSIGNED", 0, IPFIX_TYPEID_flowEndMilliSeconds},
{CN_tcpControlBits, "SMALLINT(5) UNSIGNED", 0, IPFIX_TYPEID_tcpControlBits},
{CN_revbytes, "BIGINT(20) UNSIGNED", 0, IPFIX_ETYPEID_revOctetDeltaCount},
{CN_revpkts, "BIGINT(20) UNSIGNED", 0, IPFIX_ETYPEID_revPacketDeltaCount},
{CN_revFirstSwitched, "INTEGER(10) UNSIGNED", 0, IPFIX_ETYPEID_revFlowStartSeconds}, // default value is invalid/not used for this entry
{CN_revLastSwitched, "INTEGER(10) UNSIGNED", 0, IPFIX_ETYPEID_revFlowEndSeconds}, // default value is invalid/not used for this entry
{CN_revFirstSwitchedMillis, "SMALLINT(5) UNSIGNED", 0, IPFIX_ETYPEID_revFlowStartMilliSeconds},
{CN_revLastSwitchedMillis, "SMALLINT(5) UNSIGNED", 0, IPFIX_ETYPEID_revFlowEndMilliSeconds},
{CN_revTcpControlBits, "SMALLINT(5) UNSIGNED", 0, IPFIX_ETYPEID_revTcpControlBits},
{CN_maxPacketGap, "BIGINT(20) UNSIGNED", 0, IPFIX_ETYPEID_maxPacketGap},
{CN_exporterID, "SMALLINT(5) UNSIGNED", 0, EXPORTERID},
{CN_dstIP, "INTEGER(10) UNSIGNED", 0, IPFIX_TYPEID_destinationIPv4Address, 0},
{CN_srcIP, "INTEGER(10) UNSIGNED", 0, IPFIX_TYPEID_sourceIPv4Address, 0},
{CN_srcPort, "SMALLINT(5) UNSIGNED", 0, IPFIX_TYPEID_sourceTransportPort, 0},
{CN_dstPort, "SMALLINT(5) UNSIGNED", 0, IPFIX_TYPEID_destinationTransportPort, 0},
{CN_proto, "TINYINT(3) UNSIGNED", 0, IPFIX_TYPEID_protocolIdentifier, 0 },
{CN_dstTos, "TINYINT(3) UNSIGNED", 0, IPFIX_TYPEID_classOfServiceIPv4, 0},
{CN_bytes, "BIGINT(20) UNSIGNED", 0, IPFIX_TYPEID_octetDeltaCount, 0},
{CN_pkts, "BIGINT(20) UNSIGNED", 0, IPFIX_TYPEID_packetDeltaCount, 0},
{CN_firstSwitched, "INTEGER(10) UNSIGNED", 0, IPFIX_TYPEID_flowStartSeconds, 0}, // default value is invalid/not used for this ent
{CN_lastSwitched, "INTEGER(10) UNSIGNED", 0, IPFIX_TYPEID_flowEndSeconds, 0}, // default value is invalid/not used for this entry
{CN_firstSwitchedMillis, "SMALLINT(5) UNSIGNED", 0, IPFIX_TYPEID_flowStartMilliSeconds, 0},
{CN_lastSwitchedMillis, "SMALLINT(5) UNSIGNED", 0, IPFIX_TYPEID_flowEndMilliSeconds, 0},
{CN_tcpControlBits, "SMALLINT(5) UNSIGNED", 0, IPFIX_TYPEID_tcpControlBits, 0},
//TODO: use enterprise number for the following extended types (Gerhard, 12/2009)
{CN_revbytes, "BIGINT(20) UNSIGNED", 0, IPFIX_ETYPEID_revOctetDeltaCount, 0},
{CN_revpkts, "BIGINT(20) UNSIGNED", 0, IPFIX_ETYPEID_revPacketDeltaCount, 0},
{CN_revFirstSwitched, "INTEGER(10) UNSIGNED", 0, IPFIX_ETYPEID_revFlowStartSeconds, 0}, // default value is invalid/not used for this entry
{CN_revLastSwitched, "INTEGER(10) UNSIGNED", 0, IPFIX_ETYPEID_revFlowEndSeconds, 0}, // default value is invalid/not used for this entry
{CN_revFirstSwitchedMillis, "SMALLINT(5) UNSIGNED", 0, IPFIX_ETYPEID_revFlowStartMilliSeconds, 0},
{CN_revLastSwitchedMillis, "SMALLINT(5) UNSIGNED", 0, IPFIX_ETYPEID_revFlowEndMilliSeconds, 0},
{CN_revTcpControlBits, "SMALLINT(5) UNSIGNED", 0, IPFIX_ETYPEID_revTcpControlBits, 0},
{CN_maxPacketGap, "BIGINT(20) UNSIGNED", 0, IPFIX_ETYPEID_maxPacketGap, 0},
{CN_exporterID, "SMALLINT(5) UNSIGNED", 0, EXPORTERID, 0},
{0} // last entry must be 0
};
@ -146,7 +147,7 @@ int IpfixDbWriter::connectToDB()
* save record to database
*/
void IpfixDbWriter::processDataDataRecord(const IpfixRecord::SourceID& sourceID,
IpfixRecord::DataTemplateInfo& dataTemplateInfo, uint16_t length,
TemplateInfo& dataTemplateInfo, uint16_t length,
IpfixRecord::Data* data)
{
string rowString;
@ -207,7 +208,7 @@ void IpfixDbWriter::processDataDataRecord(const IpfixRecord::SourceID& sourceID,
* The result is written into row, the firstSwitched time is returned in flowstartsec
*/
string& IpfixDbWriter::getInsertString(string& row, time_t& flowstartsec, const IpfixRecord::SourceID& sourceID,
IpfixRecord::DataTemplateInfo& dataTemplateInfo,uint16_t length, IpfixRecord::Data* data)
TemplateInfo& dataTemplateInfo,uint16_t length, IpfixRecord::Data* data)
{
uint64_t intdata = 0;
uint64_t intdata2 = 0;
@ -237,7 +238,7 @@ string& IpfixDbWriter::getInsertString(string& row, time_t& flowstartsec, const
if(dataTemplateInfo.fieldCount > 0) {
// look inside the ipfix record
for(k=0; k < dataTemplateInfo.fieldCount; k++) {
if(dataTemplateInfo.fieldInfo[k].type.id == col->ipfixId) {
if(dataTemplateInfo.fieldInfo[k].type.enterprise == col->enterprise && dataTemplateInfo.fieldInfo[k].type.id == col->ipfixId) {
notfound = false;
intdata = getData(dataTemplateInfo.fieldInfo[k].type,(data+dataTemplateInfo.fieldInfo[k].offset));
DPRINTF("IpfixDbWriter::getData: really saw ipfix id %d in packet with intdata %llX, type %d, length %d and offset %X", col->ipfixId, intdata, dataTemplateInfo.fieldInfo[k].type.id, dataTemplateInfo.fieldInfo[k].type.length, dataTemplateInfo.fieldInfo[k].offset);
@ -248,7 +249,7 @@ string& IpfixDbWriter::getInsertString(string& row, time_t& flowstartsec, const
if( dataTemplateInfo.dataCount > 0 && notfound) {
// look in static data fields of template for data
for(k=0; k < dataTemplateInfo.dataCount; k++) {
if(dataTemplateInfo.dataInfo[k].type.id == col->ipfixId) {
if(dataTemplateInfo.fieldInfo[k].type.enterprise == col->enterprise && dataTemplateInfo.dataInfo[k].type.id == col->ipfixId) {
notfound = false;
intdata = getData(dataTemplateInfo.dataInfo[k].type,(dataTemplateInfo.data+dataTemplateInfo.dataInfo[k].offset));
break;
@ -258,75 +259,79 @@ string& IpfixDbWriter::getInsertString(string& row, time_t& flowstartsec, const
if(notfound) {
notfound2 = true;
// for some Ids, we have an alternative
switch (col->ipfixId) {
case IPFIX_TYPEID_flowStartSeconds:
if(dataTemplateInfo.fieldCount > 0) {
for(k=0; k < dataTemplateInfo.fieldCount; k++) {
// look for alternative (flowStartMilliSeconds/1000)
if(dataTemplateInfo.fieldInfo[k].type.id == IPFIX_TYPEID_flowStartMilliSeconds) {
intdata = getData(dataTemplateInfo.fieldInfo[k].type,(data+dataTemplateInfo.fieldInfo[k].offset)) / 1000;
if(col->enterprise == 0) {
switch (col->ipfixId) {
case IPFIX_TYPEID_flowStartSeconds:
if(dataTemplateInfo.fieldCount > 0) {
for(k=0; k < dataTemplateInfo.fieldCount; k++) {
// look for alternative (flowStartMilliSeconds/1000)
if(dataTemplateInfo.fieldInfo[k].type.id == IPFIX_TYPEID_flowStartMilliSeconds) {
intdata = getData(dataTemplateInfo.fieldInfo[k].type,(data+dataTemplateInfo.fieldInfo[k].offset)) / 1000;
notfound = false;
break;
}
// if no flow start time is available, maybe this is is from a netflow from Cisco
// then - as a last alternative - use flowStartSysUpTime as flow start time
if(dataTemplateInfo.fieldInfo[k].type.id == IPFIX_TYPEID_flowStartSysUpTime) {
intdata2 = getData(dataTemplateInfo.fieldInfo[k].type,(data+dataTemplateInfo.fieldInfo[k].offset));
notfound2 = false;
}
}
if(notfound && !notfound2) {
intdata = intdata2;
notfound = false;
break;
}
// if no flow start time is available, maybe this is is from a netflow from Cisco
// then - as a last alternative - use flowStartSysUpTime as flow start time
if(dataTemplateInfo.fieldInfo[k].type.id == IPFIX_TYPEID_flowStartSysUpTime) {
intdata2 = getData(dataTemplateInfo.fieldInfo[k].type,(data+dataTemplateInfo.fieldInfo[k].offset));
notfound2 = false;
}
}
if(notfound && !notfound2) {
intdata = intdata2;
notfound = false;
break;
//TODO: replace by enterprise number (Gerhard 12/2009)
case IPFIX_ETYPEID_revFlowStartSeconds:
// look for alternative (revFlowStartMilliSeconds/1000)
if(dataTemplateInfo.fieldCount > 0) {
for(k=0; k < dataTemplateInfo.fieldCount; k++) {
if(dataTemplateInfo.fieldInfo[k].type.id == IPFIX_ETYPEID_revFlowStartMilliSeconds) {
intdata = getData(dataTemplateInfo.fieldInfo[k].type,(data+dataTemplateInfo.fieldInfo[k].offset)) / 1000;
notfound = false;
break;
}
}
}
}
break;
case IPFIX_ETYPEID_revFlowStartSeconds:
// look for alternative (revFlowStartMilliSeconds/1000)
if(dataTemplateInfo.fieldCount > 0) {
for(k=0; k < dataTemplateInfo.fieldCount; k++) {
if(dataTemplateInfo.fieldInfo[k].type.id == IPFIX_ETYPEID_revFlowStartMilliSeconds) {
intdata = getData(dataTemplateInfo.fieldInfo[k].type,(data+dataTemplateInfo.fieldInfo[k].offset)) / 1000;
break;
case IPFIX_TYPEID_flowEndSeconds:
if(dataTemplateInfo.fieldCount > 0) {
for(k=0; k < dataTemplateInfo.fieldCount; k++) {
// look for alternative (flowEndMilliSeconds/1000)
if(dataTemplateInfo.fieldInfo[k].type.id == IPFIX_TYPEID_flowEndMilliSeconds) {
intdata = getData(dataTemplateInfo.fieldInfo[k].type,(data+dataTemplateInfo.fieldInfo[k].offset)) / 1000;
notfound = false;
break;
}
// if no flow end time is available, maybe this is is from a netflow from Cisco
// then use flowEndSysUpTime as flow start time
if(dataTemplateInfo.fieldInfo[k].type.id == IPFIX_TYPEID_flowEndSysUpTime) {
intdata2 = getData(dataTemplateInfo.fieldInfo[k].type,(data+dataTemplateInfo.fieldInfo[k].offset));
notfound2 = false;
}
}
if(notfound && !notfound2) {
intdata = intdata2;
notfound = false;
break;
}
}
}
break;
case IPFIX_TYPEID_flowEndSeconds:
if(dataTemplateInfo.fieldCount > 0) {
for(k=0; k < dataTemplateInfo.fieldCount; k++) {
// look for alternative (flowEndMilliSeconds/1000)
if(dataTemplateInfo.fieldInfo[k].type.id == IPFIX_TYPEID_flowEndMilliSeconds) {
intdata = getData(dataTemplateInfo.fieldInfo[k].type,(data+dataTemplateInfo.fieldInfo[k].offset)) / 1000;
notfound = false;
break;
}
// if no flow end time is available, maybe this is is from a netflow from Cisco
// then use flowEndSysUpTime as flow start time
if(dataTemplateInfo.fieldInfo[k].type.id == IPFIX_TYPEID_flowEndSysUpTime) {
intdata2 = getData(dataTemplateInfo.fieldInfo[k].type,(data+dataTemplateInfo.fieldInfo[k].offset));
notfound2 = false;
break;
//TODO: replace by enterprise number (Gerhard 12/2009)
case IPFIX_ETYPEID_revFlowEndSeconds:
// look for alternative (revFlowEndMilliSeconds/1000)
if(dataTemplateInfo.fieldCount > 0) {
for(k=0; k < dataTemplateInfo.fieldCount; k++) {
if(dataTemplateInfo.fieldInfo[k].type.id == IPFIX_ETYPEID_revFlowEndMilliSeconds) {
intdata = getData(dataTemplateInfo.fieldInfo[k].type,(data+dataTemplateInfo.fieldInfo[k].offset)) / 1000;
notfound = false;
break;
}
}
}
if(notfound && !notfound2) {
intdata = intdata2;
notfound = false;
}
}
break;
case IPFIX_ETYPEID_revFlowEndSeconds:
// look for alternative (revFlowEndMilliSeconds/1000)
if(dataTemplateInfo.fieldCount > 0) {
for(k=0; k < dataTemplateInfo.fieldCount; k++) {
if(dataTemplateInfo.fieldInfo[k].type.id == IPFIX_ETYPEID_revFlowEndMilliSeconds) {
intdata = getData(dataTemplateInfo.fieldInfo[k].type,(data+dataTemplateInfo.fieldInfo[k].offset)) / 1000;
notfound = false;
break;
}
}
}
break;
break;
}
}
// if still not found, get default value
if(notfound)
@ -334,28 +339,31 @@ string& IpfixDbWriter::getInsertString(string& row, time_t& flowstartsec, const
}
// we need extra treatment for timing related fields
switch (col->ipfixId) {
case IPFIX_TYPEID_flowStartSeconds:
// save time for table access
if (flowstartsec==0) flowstartsec = intdata;
break;
case IPFIX_TYPEID_flowEndSeconds:
break;
if(col->enterprise == 0 ) {
switch (col->ipfixId) {
case IPFIX_TYPEID_flowStartSeconds:
// save time for table access
if (flowstartsec==0) flowstartsec = intdata;
break;
case IPFIX_TYPEID_flowEndSeconds:
break;
case IPFIX_TYPEID_flowStartMilliSeconds:
// if flowStartSeconds is not stored in one of the columns, but flowStartMilliSeconds is,
// then we use flowStartMilliSeconds for table access
// This is realized by storing this value only if flowStartSeconds has not yet been seen.
// A later appearing flowStartSeconds will override this value.
if (flowstartsec==0)
flowstartsec = intdata/1000;
case IPFIX_TYPEID_flowEndMilliSeconds:
case IPFIX_ETYPEID_revFlowStartMilliSeconds:
case IPFIX_ETYPEID_revFlowEndMilliSeconds:
// in the database the millisecond entry is counted from last second
intdata %= 1000;
break;
case IPFIX_TYPEID_flowStartMilliSeconds:
// if flowStartSeconds is not stored in one of the columns, but flowStartMilliSeconds is,
// then we use flowStartMilliSeconds for table access
// This is realized by storing this value only if flowStartSeconds has not yet been seen.
// A later appearing flowStartSeconds will override this value.
if (flowstartsec==0)
flowstartsec = intdata/1000;
case IPFIX_TYPEID_flowEndMilliSeconds:
//TODO: replace by enterprise number (Gerhard 12/2009)
case IPFIX_ETYPEID_revFlowStartMilliSeconds:
case IPFIX_ETYPEID_revFlowEndMilliSeconds:
// in the database the millisecond entry is counted from last second
intdata %= 1000;
break;
}
}
}
@ -517,7 +525,7 @@ int IpfixDbWriter::getExporterID(const IpfixRecord::SourceID& sourceID)
/**
* Get data of the record is given by the IPFIX_TYPEID
*/
uint64_t IpfixDbWriter::getData(IpfixRecord::FieldInfo::Type type, IpfixRecord::Data* data)
uint64_t IpfixDbWriter::getData(InformationElement::IeInfo type, IpfixRecord::Data* data)
{
switch (type.length) {
case 1:
@ -545,20 +553,9 @@ uint64_t IpfixDbWriter::getData(IpfixRecord::FieldInfo::Type type, IpfixRecord::
*/
void IpfixDbWriter::onDataRecord(IpfixDataRecord* record)
{
// convert templateInfo to dataTemplateInfo
IpfixRecord::DataTemplateInfo dataTemplateInfo;
dataTemplateInfo.templateId = 0;
dataTemplateInfo.preceding = 0;
dataTemplateInfo.freePointers = false; // don't free the given pointers, as they are taken from a different structure
dataTemplateInfo.fieldCount = record->templateInfo->fieldCount; /**< number of regular fields */
dataTemplateInfo.fieldInfo = record->templateInfo->fieldInfo; /**< array of FieldInfos describing each of these fields */
dataTemplateInfo.dataCount = 0; /**< number of fixed-value fields */
dataTemplateInfo.dataInfo = NULL; /**< array of FieldInfos describing each of these fields */
dataTemplateInfo.data = NULL; /**< data start pointer for fixed-value fields */
dataTemplateInfo.userData = record->templateInfo->userData; /**< pointer to a field that can be used by higher-level modules */
processDataDataRecord(*record->sourceID.get(), *record->templateInfo.get(),
record->dataLength, record->data);
processDataDataRecord(*record->sourceID.get(), dataTemplateInfo, record->dataLength, record->data);
record->removeReference();
}

View File

@ -61,8 +61,9 @@ class IpfixDbWriter
struct Column {
const char* columnName; /** column name */
const char* columnType; /** column data type in database */
uint64_t defaultValue; /** default value */
uint16_t ipfixId; /** IPFIX_TYPEID */
uint64_t defaultValue; /** default value */
InformationElement::IeId ipfixId; /** IPFIX_TYPEID */
InformationElement::IeEnterpriseNumber enterprise; /** enterprise number */
};
private:

View File

@ -276,7 +276,7 @@ void IpfixDbWriterPg::onDataDataRecord(IpfixDataDataRecord* record)
* save given elements of record to database
*/
void IpfixDbWriterPg::processDataDataRecord(IpfixRecord::SourceID* sourceID,
IpfixRecord::DataTemplateInfo* dataTemplateInfo, uint16_t length,
TemplateInfo* dataTemplateInfo, uint16_t length,
IpfixRecord::Data* data)
{
DPRINTF("Processing data record");
@ -318,7 +318,7 @@ void IpfixDbWriterPg::processDataDataRecord(IpfixRecord::SourceID* sourceID,
void IpfixDbWriterPg::onDataRecord(IpfixDataRecord* record)
{
// convert templateInfo to dataTemplateInfo
IpfixRecord::DataTemplateInfo dataTemplateInfo;
TemplateInfo dataTemplateInfo;
dataTemplateInfo.templateId = 0;
dataTemplateInfo.preceding = 0;
dataTemplateInfo.freePointers = false; // don't free the given pointers, as they are taken from a different structure
@ -400,11 +400,11 @@ void IpfixDbWriterPg::extractNtp64(uint64_t& intdata, uint32_t& micros)
/**
* loop over the IpfixRecord::DataTemplateInfo (fieldinfo,datainfo) to get the IPFIX values to store in database
* loop over the TemplateInfo (fieldinfo,datainfo) to get the IPFIX values to store in database
* results are stored in insertBuffer.sql
*/
void IpfixDbWriterPg::fillInsertRow(IpfixRecord::SourceID* sourceID,
IpfixRecord::DataTemplateInfo* dataTemplateInfo, uint16_t length, IpfixRecord::Data* data)
TemplateInfo* dataTemplateInfo, uint16_t length, IpfixRecord::Data* data)
{
uint32_t j, k;
uint64_t intdata = 0;
@ -718,7 +718,7 @@ int IpfixDbWriterPg::getExporterID(IpfixRecord::SourceID* sourceID)
/**
* Get data of the record is given by the IPFIX_TYPEID
*/
uint64_t IpfixDbWriterPg::getdata(IpfixRecord::FieldInfo::Type type, IpfixRecord::Data* data)
uint64_t IpfixDbWriterPg::getdata(InformationElement::IeInfo type, IpfixRecord::Data* data)
{
if(type.id == IPFIX_TYPEID_sourceIPv4Address || type.id == IPFIX_TYPEID_destinationIPv4Address)
return getipv4address(type, data);
@ -728,7 +728,7 @@ uint64_t IpfixDbWriterPg::getdata(IpfixRecord::FieldInfo::Type type, IpfixRecord
/**
* determine the ipv4address of the data record
*/
uint32_t IpfixDbWriterPg::getipv4address( IpfixRecord::FieldInfo::Type type, IpfixRecord::Data* data)
uint32_t IpfixDbWriterPg::getipv4address( InformationElement::IeInfo type, IpfixRecord::Data* data)
{
if (type.length > 5) {
@ -751,7 +751,7 @@ uint32_t IpfixDbWriterPg::getipv4address( IpfixRecord::FieldInfo::Type type, Ipf
/**
* get the IPFIX value
*/
uint64_t IpfixDbWriterPg::getIPFIXValue(IpfixRecord::FieldInfo::Type type, IpfixRecord::Data* data)
uint64_t IpfixDbWriterPg::getIPFIXValue(InformationElement::IeInfo type, IpfixRecord::Data* data)
{
switch (type.length) {
case 1:

View File

@ -114,7 +114,7 @@ class IpfixDbWriterPg
void addColumnEntry(const char* insert, bool quoted, bool lastcolumn);
void addColumnEntry(const uint64_t insert, bool quoted, bool lastcolumn);
void fillInsertRow(IpfixRecord::SourceID* sourceID,
IpfixRecord::DataTemplateInfo* dataTemplateInfo, uint16_t length, IpfixRecord::Data* data);
TemplateInfo* dataTemplateInfo, uint16_t length, IpfixRecord::Data* data);
bool writeToDb();
int getExporterID(IpfixRecord::SourceID* sourceID);
bool checkCurrentTable(uint64_t flowStart);
@ -124,18 +124,18 @@ class IpfixDbWriterPg
private:
void connectToDB();
void processDataDataRecord(IpfixRecord::SourceID* sourceID,
IpfixRecord::DataTemplateInfo* dataTemplateInfo, uint16_t length,
TemplateInfo* dataTemplateInfo, uint16_t length,
IpfixRecord::Data* data);
/***** Internal Functions ****************************************************/
char* getTableNamDependTime(char* tablename,uint64_t flowstartsec);
uint64_t getdata(IpfixRecord::FieldInfo::Type type, IpfixRecord::Data* data);
uint64_t getIPFIXValue(IpfixRecord::FieldInfo::Type type, IpfixRecord::Data* data);
uint64_t getdata(InformationElement::IeInfo type, IpfixRecord::Data* data);
uint64_t getIPFIXValue(InformationElement::IeInfo type, IpfixRecord::Data* data);
uint32_t getdefaultIPFIXdata(int ipfixtype);
uint32_t getipv4address(IpfixRecord::FieldInfo::Type type, IpfixRecord::Data* data);
uint32_t getipv4address(InformationElement::IeInfo type, IpfixRecord::Data* data);
void extractNtp64(uint64_t& intdata, uint32_t& micros);

View File

@ -50,21 +50,18 @@ using namespace std;
//static variables
InstanceManager<IpfixTemplateRecord> IpfixParser::templateRecordIM("IpfixTemplateRecord", 0);
InstanceManager<IpfixOptionsTemplateRecord> IpfixParser::optionsTemplateRecordIM("IpfixOptionsTemplateRecord", 0);
InstanceManager<IpfixDataTemplateRecord> IpfixParser::dataTemplateRecordIM("IpfixDataTemplateRecord", 0);
InstanceManager<IpfixDataRecord> IpfixParser::dataRecordIM("IpfixDataRecord", 0);
InstanceManager<IpfixOptionsRecord> IpfixParser::optionsRecordIM("IpfixOptionsRecord", 0);
InstanceManager<IpfixDataDataRecord> IpfixParser::dataDataRecordIM("IpfixDataDataRecord", 0);
InstanceManager<IpfixTemplateDestructionRecord> IpfixParser::templateDestructionRecordIM("IpfixTemplateDestructionRecord", 0);
InstanceManager<IpfixOptionsTemplateDestructionRecord> IpfixParser::optionsTemplateDestructionRecordIM("IpfixOptionsTemplateDestructionRecord", 0);
InstanceManager<IpfixDataTemplateDestructionRecord> IpfixParser::dataTemplateDestructionRecordIM("IpfixDataTemplateDestructionRecord", 0);
/**
* Processes an IPFIX template set.
* Called by processMessage
* setId needs to be TemplateInfo::IpfixTemplate or TemplateInfo::NetflowTemplate
*/
void IpfixParser::processTemplateSet(boost::shared_ptr<IpfixRecord::SourceID> sourceId, boost::shared_array<uint8_t> message, IpfixSetHeader* set, uint8_t* endOfMessage) {
void IpfixParser::processTemplateSet(boost::shared_ptr<IpfixRecord::SourceID> sourceId, TemplateInfo::SetId setId, boost::shared_array<uint8_t> message, IpfixSetHeader* set, uint8_t* endOfMessage) {
uint8_t* endOfSet = (uint8_t*)set + ntohs(set->length);
uint8_t* record = (uint8_t*)&set->data;
@ -84,7 +81,7 @@ void IpfixParser::processTemplateSet(boost::shared_ptr<IpfixRecord::SourceID> so
continue;
}
TemplateBuffer::BufferedTemplate* bt = new TemplateBuffer::BufferedTemplate;
boost::shared_ptr<IpfixRecord::TemplateInfo> ti(new IpfixRecord::TemplateInfo);
boost::shared_ptr<TemplateInfo> ti(new TemplateInfo);
bt->sourceID = sourceId;
bt->templateID = ntohs(th->templateId);
bt->recordLength = 0;
@ -92,8 +89,9 @@ void IpfixParser::processTemplateSet(boost::shared_ptr<IpfixRecord::SourceID> so
bt->templateInfo = ti;
ti->userData = 0;
ti->templateId = ntohs(th->templateId);
ti->setId = setId;
ti->fieldCount = ntohs(th->fieldCount);
ti->fieldInfo = (IpfixRecord::FieldInfo*)malloc(ti->fieldCount * sizeof(IpfixRecord::FieldInfo));
ti->fieldInfo = (TemplateInfo::FieldInfo*)malloc(ti->fieldCount * sizeof(TemplateInfo::FieldInfo));
int isLengthVarying = 0;
uint16_t fieldNo;
for (fieldNo = 0; fieldNo < ti->fieldCount; fieldNo++) {
@ -148,8 +146,9 @@ void IpfixParser::processTemplateSet(boost::shared_ptr<IpfixRecord::SourceID> so
/**
* Processes an IPFIX Options Template Set.
* Called by processMessage
* setId needs to be TemplateInfo::IpfixOptionsTemplate or TemplateInfo::NetflowOptionsTemplate
*/
void IpfixParser::processOptionsTemplateSet(boost::shared_ptr<IpfixRecord::SourceID> sourceId, boost::shared_array<uint8_t> message, IpfixSetHeader* set, uint8_t* endOfMessage) {
void IpfixParser::processOptionsTemplateSet(boost::shared_ptr<IpfixRecord::SourceID> sourceId, TemplateInfo::SetId setId, boost::shared_array<uint8_t> message, IpfixSetHeader* set, uint8_t* endOfMessage) {
uint8_t* endOfSet = (uint8_t*)set + ntohs(set->length);
uint8_t* record = (uint8_t*)&set->data;
@ -180,18 +179,19 @@ void IpfixParser::processOptionsTemplateSet(boost::shared_ptr<IpfixRecord::Sourc
}
TemplateBuffer::BufferedTemplate* bt = new TemplateBuffer::BufferedTemplate;
boost::shared_ptr<IpfixRecord::OptionsTemplateInfo> ti(new IpfixRecord::OptionsTemplateInfo);
boost::shared_ptr<TemplateInfo> ti(new TemplateInfo);
bt->sourceID = sourceId;
bt->templateID = ntohs(oth->templateId);
bt->recordLength = 0;
bt->setID = ntohs(set->id);
bt->optionsTemplateInfo = ti;
bt->templateInfo = ti;
ti->userData = 0;
ti->templateId = ntohs(oth->templateId);
ti->setId = setId;
ti->scopeCount = ntohs(oth->scopeCount);
ti->scopeInfo = (IpfixRecord::FieldInfo*)malloc(ti->scopeCount * sizeof(IpfixRecord::FieldInfo));
ti->scopeInfo = (TemplateInfo::FieldInfo*)malloc(ti->scopeCount * sizeof(TemplateInfo::FieldInfo));
ti->fieldCount = ntohs(oth->fieldCount)-ntohs(oth->scopeCount);
ti->fieldInfo = (IpfixRecord::FieldInfo*)malloc(ti->fieldCount * sizeof(IpfixRecord::FieldInfo));
ti->fieldInfo = (TemplateInfo::FieldInfo*)malloc(ti->fieldCount * sizeof(TemplateInfo::FieldInfo));
int isLengthVarying = 0;
uint16_t scopeNo;
for (scopeNo = 0; scopeNo < ti->scopeCount; scopeNo++) {
@ -268,9 +268,9 @@ void IpfixParser::processOptionsTemplateSet(boost::shared_ptr<IpfixRecord::Sourc
else
bt->expires = 0;
IpfixOptionsTemplateRecord* ipfixRecord = optionsTemplateRecordIM.getNewInstance();
IpfixTemplateRecord* ipfixRecord = templateRecordIM.getNewInstance();
ipfixRecord->sourceID = sourceId;
ipfixRecord->optionsTemplateInfo = ti;
ipfixRecord->templateInfo = ti;
statTotalDataRecords++;
push(ipfixRecord);
}
@ -310,18 +310,19 @@ void IpfixParser::processDataTemplateSet(boost::shared_ptr<IpfixRecord::SourceID
}
TemplateBuffer::BufferedTemplate* bt = new TemplateBuffer::BufferedTemplate;
boost::shared_ptr<IpfixRecord::DataTemplateInfo> ti(new IpfixRecord::DataTemplateInfo);
boost::shared_ptr<TemplateInfo> ti(new TemplateInfo);
bt->sourceID = sourceId;
bt->templateID = ntohs(dth->templateId);
bt->recordLength = 0;
bt->setID = ntohs(set->id);
bt->dataTemplateInfo = ti;
bt->templateInfo = ti;
ti->userData = 0;
ti->templateId = ntohs(dth->templateId);
ti->setId = TemplateInfo::IpfixDataTemplate;
ti->preceding = ntohs(dth->precedingRule);
ti->fieldCount = ntohs(dth->fieldCount);
ti->dataCount = ntohs(dth->dataCount);
ti->fieldInfo = (IpfixRecord::FieldInfo*)malloc(ti->fieldCount * sizeof(IpfixRecord::FieldInfo));
ti->fieldInfo = (TemplateInfo::FieldInfo*)malloc(ti->fieldCount * sizeof(TemplateInfo::FieldInfo));
int isLengthVarying = 0;
uint16_t fieldNo;
for (fieldNo = 0; fieldNo < ti->fieldCount; fieldNo++) {
@ -360,7 +361,7 @@ void IpfixParser::processDataTemplateSet(boost::shared_ptr<IpfixRecord::SourceID
}
}
ti->dataInfo = (IpfixRecord::FieldInfo*)malloc(ti->dataCount * sizeof(IpfixRecord::FieldInfo));
ti->dataInfo = (TemplateInfo::FieldInfo*)malloc(ti->dataCount * sizeof(TemplateInfo::FieldInfo));
for (fieldNo = 0; fieldNo < ti->dataCount; fieldNo++) {
/* check if there are at least 4 bytes for this field */
if (record+4 > endOfSet) {
@ -434,9 +435,9 @@ void IpfixParser::processDataTemplateSet(boost::shared_ptr<IpfixRecord::SourceID
else
bt->expires = 0;
IpfixDataTemplateRecord* ipfixRecord = dataTemplateRecordIM.getNewInstance();
IpfixTemplateRecord* ipfixRecord = templateRecordIM.getNewInstance();
ipfixRecord->sourceID = sourceId;
ipfixRecord->dataTemplateInfo = ti;
ipfixRecord->templateInfo = ti;
push(ipfixRecord);
}
}
@ -476,7 +477,7 @@ uint32_t IpfixParser::processDataSet(boost::shared_ptr<IpfixRecord::SourceID> so
if (bt->setID == IPFIX_SetId_Template) {
#endif
boost::shared_ptr<IpfixRecord::TemplateInfo> ti = bt->templateInfo;
boost::shared_ptr<TemplateInfo> ti = bt->templateInfo;
if (bt->recordLength < 65535) {
if (record + bt->recordLength > endOfSet) {
@ -507,7 +508,7 @@ uint32_t IpfixParser::processDataSet(boost::shared_ptr<IpfixRecord::SourceID> so
int fieldLength;
int i;
bool incomplete = false;
ti = boost::shared_ptr<IpfixRecord::TemplateInfo>(new IpfixRecord::TemplateInfo(*bt->templateInfo.get()));
ti = boost::shared_ptr<TemplateInfo>(new TemplateInfo(*bt->templateInfo.get()));
for (i = 0; i < ti->fieldCount; i++) {
if (!ti->fieldInfo[i].isVariableLength) {
fieldLength = ti->fieldInfo[i].type.length;
@ -554,7 +555,7 @@ uint32_t IpfixParser::processDataSet(boost::shared_ptr<IpfixRecord::SourceID> so
}
} else if (bt->setID == IPFIX_SetId_OptionsTemplate) {
boost::shared_ptr<IpfixRecord::OptionsTemplateInfo> ti = bt->optionsTemplateInfo;
boost::shared_ptr<TemplateInfo> ti = bt->templateInfo;
if (bt->recordLength < 65535) {
if (record + bt->recordLength > endOfSet) {
@ -584,7 +585,7 @@ uint32_t IpfixParser::processDataSet(boost::shared_ptr<IpfixRecord::SourceID> so
int fieldLength;
int i;
bool incomplete = false;
ti = boost::shared_ptr<IpfixRecord::OptionsTemplateInfo>(new IpfixRecord::OptionsTemplateInfo(*bt->optionsTemplateInfo.get()));
ti = boost::shared_ptr<TemplateInfo>(new TemplateInfo(*bt->templateInfo.get()));
for (i = 0; i < ti->scopeCount; i++) {
if (!ti->scopeInfo[i].isVariableLength) {
fieldLength = ti->scopeInfo[i].type.length;
@ -663,7 +664,7 @@ uint32_t IpfixParser::processDataSet(boost::shared_ptr<IpfixRecord::SourceID> so
}
} else if (bt->setID == IPFIX_SetId_DataTemplate) {
boost::shared_ptr<IpfixRecord::DataTemplateInfo> ti = bt->dataTemplateInfo;
boost::shared_ptr<TemplateInfo> ti = bt->templateInfo;
if (bt->recordLength < 65535) {
if (record + bt->recordLength > endOfSet) {
@ -693,7 +694,7 @@ uint32_t IpfixParser::processDataSet(boost::shared_ptr<IpfixRecord::SourceID> so
int fieldLength;
int i;
bool incomplete = false;
ti = boost::shared_ptr<IpfixRecord::DataTemplateInfo>(new IpfixRecord::DataTemplateInfo(*bt->dataTemplateInfo.get()));
ti = boost::shared_ptr<TemplateInfo>(new TemplateInfo(*bt->templateInfo.get()));
for (i = 0; i < ti->fieldCount; i++) {
if (!ti->fieldInfo[i].isVariableLength) {
fieldLength = ti->fieldInfo[i].type.length;
@ -757,6 +758,7 @@ int IpfixParser::processNetflowV9Packet(boost::shared_array<uint8_t> message, ui
}
NetflowV9Header* header = (NetflowV9Header*)message.get();
sourceId->observationDomainId = ntohl(header->observationDomainId);
/* pointer to first set */
IpfixSetHeader* set = (IpfixSetHeader*)&header->data;
@ -765,8 +767,8 @@ int IpfixParser::processNetflowV9Packet(boost::shared_array<uint8_t> message, ui
uint8_t* endOfMessage = (uint8_t*)((uint8_t*)message.get() + length);
int i;
sourceId->observationDomainId = ntohl(header->observationDomainId);
uint16_t tmpid;
uint32_t numberOfDataRecords = 0;
for (i = 0; i < ntohs(header->setCount); i++) {
/* check if there is space for a set header */
@ -780,16 +782,28 @@ int IpfixParser::processNetflowV9Packet(boost::shared_array<uint8_t> message, ui
return -1;
}
if (ntohs(set->id) == NetflowV9_SetId_Template) {
processTemplateSet(sourceId, message, set, endOfMessage);
} else
if (ntohs(set->id) >= IPFIX_SetId_Data_Start) {
processDataSet(sourceId, message, set, endOfMessage);
} else {
msg(MSG_ERROR, "Unsupported Set ID - expected 0/256+, got %d", ntohs(set->id));
}
tmpid=ntohs(set->id);
switch(tmpid) {
case NetflowV9_SetId_Template:
processTemplateSet(sourceId, TemplateInfo::NetflowTemplate, message, set, endOfMessage);
break;
case NetflowV9_SetId_OptionsTemplate:
processOptionsTemplateSet(sourceId, TemplateInfo::IpfixOptionsTemplate, message, set, endOfMessage);
break;
default:
if(tmpid >= IPFIX_SetId_Data_Start) {
statTotalDRPackets++;
numberOfDataRecords += processDataSet(sourceId, message, set, endOfMessage);
} else {
msg(MSG_ERROR, "processNetflowV9Packet: Unsupported Set ID - expected 0/1/256+, got %d", tmpid);
}
}
set = (IpfixSetHeader*)((uint8_t*)set + ntohs(set->length));
}
//FIXME: check for out-of-order messages and lost records
msg(MSG_VDEBUG, "Message contained %u bytes, sequence number was %u", numberOfDataRecords, ntohl(header->sequenceNo));
return 0;
}
@ -831,22 +845,22 @@ int IpfixParser::processIpfixPacket(boost::shared_array<uint8_t> message, uint16
tmpid=ntohs(set->id);
switch(tmpid) {
case IPFIX_SetId_DataTemplate:
processDataTemplateSet(sourceId, message, set, endOfMessage);
break;
case IPFIX_SetId_Template:
processTemplateSet(sourceId, message, set, endOfMessage);
break;
case IPFIX_SetId_OptionsTemplate:
processOptionsTemplateSet(sourceId, message, set, endOfMessage);
break;
default:
if(tmpid >= IPFIX_SetId_Data_Start) {
statTotalDRPackets++;
numberOfDataRecords += processDataSet(sourceId, message, set, endOfMessage);
} else {
msg(MSG_ERROR, "processIpfixPacket: Unsupported Set ID - expected 2/3/4/256+, got %d", tmpid);
}
case IPFIX_SetId_DataTemplate:
processDataTemplateSet(sourceId, message, set, endOfMessage);
break;
case IPFIX_SetId_Template:
processTemplateSet(sourceId, TemplateInfo::IpfixTemplate, message, set, endOfMessage);
break;
case IPFIX_SetId_OptionsTemplate:
processOptionsTemplateSet(sourceId, TemplateInfo::IpfixOptionsTemplate, message, set, endOfMessage);
break;
default:
if(tmpid >= IPFIX_SetId_Data_Start) {
statTotalDRPackets++;
numberOfDataRecords += processDataSet(sourceId, message, set, endOfMessage);
} else {
msg(MSG_ERROR, "processIpfixPacket: Unsupported Set ID - expected 2/3/4/256+, got %d", tmpid);
}
}
set = (IpfixSetHeader*)((uint8_t*)set + ntohs(set->length));
}

View File

@ -21,8 +21,6 @@
#ifndef INCLUDED_IpfixParser_hpp
#define INCLUDED_IpfixParser_hpp
#define NetflowV9_SetId_Template 0
#include "IpfixReceiver.hpp"
#include "IpfixRecordSender.h"
@ -43,7 +41,7 @@ class TemplateBuffer;
* (see the @c setTemplateCallback() and @c setDataRecordCallback() function groups).
*
* The Collector module supports higher-level modules by providing field types and offsets along
* with the raw data block of individual messages passed via the callback functions (see @c IpfixRecord::TemplateInfo)
* with the raw data block of individual messages passed via the callback functions (see @c TemplateInfo)
*/
class IpfixParser : public IpfixPacketProcessor, public Sensor
{
@ -140,9 +138,9 @@ class IpfixParser : public IpfixPacketProcessor, public Sensor
pthread_mutex_t mutex; /**< Used to give only one IpfixReceiver access to the IpfixPacketProcessor */
uint32_t processDataSet(boost::shared_ptr<IpfixRecord::SourceID> sourceID, boost::shared_array<uint8_t> message, IpfixSetHeader* set, uint8_t* endOfMessage);
void processTemplateSet(boost::shared_ptr<IpfixRecord::SourceID> sourceID, boost::shared_array<uint8_t> message, IpfixSetHeader* set, uint8_t* endOfMessage);
void processTemplateSet(boost::shared_ptr<IpfixRecord::SourceID> sourceID, TemplateInfo::SetId setId, boost::shared_array<uint8_t> message, IpfixSetHeader* set, uint8_t* endOfMessage);
void processDataTemplateSet(boost::shared_ptr<IpfixRecord::SourceID> sourceID, boost::shared_array<uint8_t> message, IpfixSetHeader* set, uint8_t* endOfMessage);
void processOptionsTemplateSet(boost::shared_ptr<IpfixRecord::SourceID> sourceId, boost::shared_array<uint8_t> message, IpfixSetHeader* set, uint8_t* endOfMessage);
void processOptionsTemplateSet(boost::shared_ptr<IpfixRecord::SourceID> sourceId, TemplateInfo::SetId setId, boost::shared_array<uint8_t> message, IpfixSetHeader* set, uint8_t* endOfMessage);
int processNetflowV9Packet(boost::shared_array<uint8_t> message, uint16_t length, boost::shared_ptr<IpfixRecord::SourceID> sourceId);
int processIpfixPacket(boost::shared_array<uint8_t> message, uint16_t length, boost::shared_ptr<IpfixRecord::SourceID> sourceId);
@ -155,14 +153,10 @@ class IpfixParser : public IpfixPacketProcessor, public Sensor
IpfixRecordSender* ipfixRecordSender;
static InstanceManager<IpfixTemplateRecord> templateRecordIM;
static InstanceManager<IpfixOptionsTemplateRecord> optionsTemplateRecordIM;
static InstanceManager<IpfixDataTemplateRecord> dataTemplateRecordIM;
static InstanceManager<IpfixDataRecord> dataRecordIM;
static InstanceManager<IpfixOptionsRecord> optionsRecordIM;
static InstanceManager<IpfixDataDataRecord> dataDataRecordIM;
static InstanceManager<IpfixTemplateDestructionRecord> templateDestructionRecordIM;
static InstanceManager<IpfixOptionsTemplateDestructionRecord> optionsTemplateDestructionRecordIM;
static InstanceManager<IpfixDataTemplateDestructionRecord> dataTemplateDestructionRecordIM;
void resendBufferedTemplates();
void setTemplateDestroyed(bool destroyed);

View File

@ -143,54 +143,56 @@ void printFieldData(InformationElement::IeInfo type, IpfixRecord::Data* pattern)
timeval t;
uint64_t hbnum;
switch (type.id) {
case IPFIX_TYPEID_protocolIdentifier:
printf("protocolIdentifier: ");
printProtocol(type, pattern);
break;
case IPFIX_TYPEID_sourceIPv4Address:
printf("sourceIPv4Address: ");
printIPv4(type, pattern);
break;
case IPFIX_TYPEID_destinationIPv4Address:
printf("destinationIPv4Address: ");
printIPv4(type, pattern);
break;
case IPFIX_TYPEID_sourceTransportPort:
printf("sourceTransportPort: ");
printPort(type, pattern);
break;
case IPFIX_TYPEID_destinationTransportPort:
printf("destinationTransportPort: ");
printPort(type, pattern);
break;
case IPFIX_TYPEID_flowStartNanoSeconds:
case IPFIX_TYPEID_flowEndNanoSeconds:
case IPFIX_ETYPEID_revFlowStartNanoSeconds:
case IPFIX_ETYPEID_revFlowEndNanoSeconds:
printf("%s: ", typeid2string(type.id));
hbnum = ntohll(*(uint64_t*)pattern);
if (hbnum>0) {
t = timentp64(*((ntp64*)(&hbnum)));
printf("%d.%06d seconds", (int32_t)t.tv_sec, (int32_t)t.tv_usec);
} else {
printf("no value (only zeroes in field)");
if(type.enterprise == 0) {
switch (type.id) {
case IPFIX_TYPEID_protocolIdentifier:
printf("protocolIdentifier: ");
printProtocol(type, pattern);
return;
case IPFIX_TYPEID_sourceIPv4Address:
printf("sourceIPv4Address: ");
printIPv4(type, pattern);
return;
case IPFIX_TYPEID_destinationIPv4Address:
printf("destinationIPv4Address: ");
printIPv4(type, pattern);
return;
case IPFIX_TYPEID_sourceTransportPort:
printf("sourceTransportPort: ");
printPort(type, pattern);
return;
case IPFIX_TYPEID_destinationTransportPort:
printf("destinationTransportPort: ");
printPort(type, pattern);
return;
case IPFIX_TYPEID_flowStartNanoSeconds:
case IPFIX_TYPEID_flowEndNanoSeconds:
// TODO: replace by enterprise number (Gerhard, 12/2009)
case IPFIX_ETYPEID_revFlowStartNanoSeconds:
case IPFIX_ETYPEID_revFlowEndNanoSeconds:
printf("%s: ", typeid2string(type.id));
hbnum = ntohll(*(uint64_t*)pattern);
if (hbnum>0) {
t = timentp64(*((ntp64*)(&hbnum)));
printf("%d.%06d seconds", (int32_t)t.tv_sec, (int32_t)t.tv_usec);
} else {
printf("no value (only zeroes in field)");
}
return;
case IPFIX_ETYPEID_frontPayload:
case IPFIX_ETYPEID_revFrontPayload:
printf("%s: ", typeid2string(type.id));
printFrontPayload(type, pattern);
return;
}
break;
case IPFIX_ETYPEID_frontPayload:
case IPFIX_ETYPEID_revFrontPayload:
printf("%s: ", typeid2string(type.id));
printFrontPayload(type, pattern);
break;
default:
s = typeid2string(type.id);
if (s != NULL) {
printf("%s: ", s);
printUint(type, pattern);
} else {
DPRINTF("Field with ID %d unparseable\n", type.id);
}
break;
}
// default treatment
s = typeid2string(type.id);
if (s != NULL) {
printf("%s: ", s);
printUint(type, pattern);
} else {
DPRINTF("Field with ID %d unparseable\n", type.id);
}
}
@ -261,15 +263,47 @@ void IpfixPrinter::onTemplate(IpfixTemplateRecord* record)
{
/* we need a FieldInfo for printIPv4 */
InformationElement::IeInfo tmpInfo = {0, 4, 0}; // length=4 for IPv4 address
printf("\n-+--- Template (id=%u) from ", record->templateInfo->templateId);
if(record->sourceID->exporterAddress.len == 4)
printIPv4(tmpInfo, &record->sourceID->exporterAddress.ip[0]);
else
printf("non-IPv4 address");
printf(":%d (", record->sourceID->exporterPort);
tmpInfo.length = 1; // length=1 for protocol identifier
printProtocol(tmpInfo, &record->sourceID->protocol);
printf(")\n");
switch(record->templateInfo->setId) {
case TemplateInfo::NetflowTemplate:
printf("\n-+--- Netflow Template (id=%u) from ", record->templateInfo->templateId);
break;
case TemplateInfo::NetflowOptionsTemplate:
printf("\n-+--- Netflow Options Template (id=%u) from ", record->templateInfo->templateId);
break;
case TemplateInfo::IpfixTemplate:
printf("\n-+--- Ipfix Template (id=%u) from ", record->templateInfo->templateId);
break;
case TemplateInfo::IpfixOptionsTemplate:
printf("\n-+--- Ipfix Options Template (id=%u) from ", record->templateInfo->templateId);
break;
case TemplateInfo::IpfixDataTemplate:
printf("\n-+--- Ipfix Data Template (id=%u) from ", record->templateInfo->templateId);
break;
}
if (record->sourceID) {
if (record->sourceID->exporterAddress.len == 4)
printIPv4(tmpInfo, &record->sourceID->exporterAddress.ip[0]);
else
printf("non-IPv4 address");
printf(":%d (", record->sourceID->exporterPort);
tmpInfo.length = 1; // length=1 for protocol identifier
printProtocol(tmpInfo, &record->sourceID->protocol);
printf(")\n");
} else {
printf("no sourceID given in template");
}
// print fixed data in the case of a data template
if(record->templateInfo->setId == TemplateInfo::IpfixDataTemplate) {
printf(" `- fixed data\n");
for (int i = 0; i < record->templateInfo->dataCount; i++) {
printf(" ' `- ");
printFieldData(record->templateInfo->dataInfo[i].type,
(record->templateInfo->data + record->templateInfo->dataInfo[i].offset));
printf("\n");
}
}
printf(" `---\n\n");
record->removeReference();
}
@ -283,15 +317,36 @@ void IpfixPrinter::onTemplateDestruction(IpfixTemplateDestructionRecord* record)
{
/* we need a FieldInfo for printIPv4 */
InformationElement::IeInfo tmpInfo = {0, 4, 0}; // length=4 for IPv4 address
printf("Destroyed a Template (id=%u) from ", record->templateInfo->templateId);
if(record->sourceID->exporterAddress.len == 4)
printIPv4(tmpInfo, &record->sourceID->exporterAddress.ip[0]);
else
printf("non-IPv4 address");
printf(":%d (", record->sourceID->exporterPort);
tmpInfo.length = 1; // length=1 for protocol identifier
printProtocol(tmpInfo, &record->sourceID->protocol);
printf(")\n");
switch(record->templateInfo->setId) {
case TemplateInfo::NetflowTemplate:
printf("\n-+--- Destroyed Netflow Template (id=%u) from ", record->templateInfo->templateId);
break;
case TemplateInfo::NetflowOptionsTemplate:
printf("\n-+--- Destroyed Netflow Options Template (id=%u) from ", record->templateInfo->templateId);
break;
case TemplateInfo::IpfixTemplate:
printf("\n-+--- Destroyed Ipfix Template (id=%u) from ", record->templateInfo->templateId);
break;
case TemplateInfo::IpfixOptionsTemplate:
printf("\n-+--- Destroyed Ipfix Options Template (id=%u) from ", record->templateInfo->templateId);
break;
case TemplateInfo::IpfixDataTemplate:
printf("\n-+--- Destroyed Ipfix Data Template (id=%u) from ", record->templateInfo->templateId);
break;
}
if (record->sourceID) {
if (record->sourceID->exporterAddress.len == 4)
printIPv4(tmpInfo, &record->sourceID->exporterAddress.ip[0]);
else
printf("non-IPv4 address");
printf(":%d (", record->sourceID->exporterPort);
tmpInfo.length = 1; // length=1 for protocol identifier
printProtocol(tmpInfo, &record->sourceID->protocol);
printf(")\n");
} else {
printf("no sourceID given in template");
}
record->removeReference();
}
@ -322,7 +377,7 @@ void IpfixPrinter::printUint(char* buf, InformationElement::IeInfo type, IpfixRe
*/
void IpfixPrinter::printOneLineRecord(IpfixDataRecord* record)
{
boost::shared_ptr<IpfixRecord::TemplateInfo> dataTemplateInfo = record->templateInfo;
boost::shared_ptr<TemplateInfo> dataTemplateInfo = record->templateInfo;
char buf[100], buf2[100];
if (linesPrinted==0 || linesPrinted>50) {
@ -340,7 +395,7 @@ void IpfixPrinter::printOneLineRecord(IpfixDataRecord* record)
uint32_t timetype = 0;
uint32_t starttime = 0;
IpfixRecord::FieldInfo* fi = dataTemplateInfo->getFieldInfo(IPFIX_TYPEID_flowStartSeconds, 0);
TemplateInfo::FieldInfo* fi = dataTemplateInfo->getFieldInfo(IPFIX_TYPEID_flowStartSeconds, 0);
if (fi != NULL) {
timetype = IPFIX_TYPEID_flowStartSeconds;
time_t t = ntohl(*reinterpret_cast<time_t*>(record->data+fi->offset));
@ -494,7 +549,7 @@ void IpfixPrinter::onDataRecord(IpfixDataRecord* record)
printf(":%d (", record->sourceID->exporterPort);
tmpInfo.length = 1; // length=1 for protocol identifier
printProtocol(tmpInfo, &record->sourceID->protocol);
printf(") )\n");
printf("))\n");
printf(" `- variable data\n");
for (i = 0; i < record->templateInfo->fieldCount; i++) {
@ -515,49 +570,6 @@ void IpfixPrinter::onDataRecord(IpfixDataRecord* record)
record->removeReference();
}
/**
* Prints a OptionsTemplate
* @param sourceID SourceID of the exporting process
* @param dataTemplateInfo Pointer to a structure defining the DataTemplate used
*/
void IpfixPrinter::onOptionsTemplate(IpfixOptionsTemplateRecord* record)
{
/* we need a FieldInfo for printIPv4 */
InformationElement::IeInfo tmpInfo = {0, 4, 0}; // length=4 for IPv4 address
printf("\n-+--- OptionsTemplate (id=%u) from ", record->optionsTemplateInfo->templateId);
if(record->sourceID->exporterAddress.len == 4)
printIPv4(tmpInfo, &record->sourceID->exporterAddress.ip[0]);
else
printf("non-IPv4 address");
printf(":%d (", record->sourceID->exporterPort);
tmpInfo.length = 1; // length=1 for protocol identifier
printProtocol(tmpInfo, &record->sourceID->protocol);
printf(")\n");
printf(" `---\n\n");
record->removeReference();
}
/**
* Prints a DataTemplate that was announced to be destroyed
* @param sourceID SourceID of the exporting process
* @param dataTemplateInfo Pointer to a structure defining the DataTemplate used
*/
void IpfixPrinter::onOptionsTemplateDestruction(IpfixOptionsTemplateDestructionRecord* record)
{
/* we need a FieldInfo for printIPv4 */
InformationElement::IeInfo tmpInfo = {0, 4, 0}; // length=4 for IPv4 address
printf("Destroyed an OptionsTemplate (id=%u) from ", record->optionsTemplateInfo->templateId);
if(record->sourceID->exporterAddress.len == 4)
printIPv4(tmpInfo, &record->sourceID->exporterAddress.ip[0]);
else
printf("non-IPv4 address");
printf(":%d (", record->sourceID->exporterPort);
tmpInfo.length = 1; // length=1 for protocol identifier
printProtocol(tmpInfo, &record->sourceID->protocol);
printf(")\n");
record->removeReference();
}
/**
* Prints an OptionsRecord
* @param sourceID SourceID of the exporting process
@ -577,69 +589,12 @@ void IpfixPrinter::onOptionsRecord(IpfixOptionsRecord* record)
printf(":%d (", record->sourceID->exporterPort);
tmpInfo.length = 1; // length=1 for protocol identifier
printProtocol(tmpInfo, &record->sourceID->protocol);
printf(") )\n");
printf("))\n");
printf(" `---\n\n");
record->removeReference();
}
/**
* Prints a DataTemplate
* @param sourceID SourceID of the exporting process
* @param dataTemplateInfo Pointer to a structure defining the DataTemplate used
*/
void IpfixPrinter::onDataTemplate(IpfixDataTemplateRecord* record)
{
int i;
/* we need a FieldInfo for printIPv4 */
InformationElement::IeInfo tmpInfo = {0, 4, 0}; // length=4 for IPv4 address
printf("\n-+--- DataTemplate (id=%u) from ", record->dataTemplateInfo->templateId);
if (record->sourceID) {
if (record->sourceID->exporterAddress.len == 4)
printIPv4(tmpInfo, &record->sourceID->exporterAddress.ip[0]);
else
printf("non-IPv4 address");
printf(":%d (", record->sourceID->exporterPort);
tmpInfo.length = 1; // length=1 for protocol identifier
printProtocol(tmpInfo, &record->sourceID->protocol);
printf(")\n");
} else {
printf("no sourceID given in template");
}
printf(" `- fixed data\n");
for (i = 0; i < record->dataTemplateInfo->dataCount; i++) {
printf(" ' `- ");
printFieldData(record->dataTemplateInfo->dataInfo[i].type,
(record->dataTemplateInfo->data + record->dataTemplateInfo->dataInfo[i].offset));
printf("\n");
}
printf(" `---\n\n");
record->removeReference();
}
/**
* Prints a DataTemplate that was announced to be destroyed
* @param sourceID SourceID of the exporting process
* @param dataTemplateInfo Pointer to a structure defining the DataTemplate used
*/
void IpfixPrinter::onDataTemplateDestruction(IpfixDataTemplateDestructionRecord* record)
{
/* we need a FieldInfo for printIPv4 */
InformationElement::IeInfo tmpInfo = {0, 4, 0}; // length=4 for IPv4 address
printf("Destroyed a DataTemplate (id=%u) from ", record->dataTemplateInfo->templateId);
if(record->sourceID->exporterAddress.len == 4)
printIPv4(tmpInfo, &record->sourceID->exporterAddress.ip[0]);
else
printf("non-IPv4 address");
printf(":%d (", record->sourceID->exporterPort);
tmpInfo.length = 1; // length=1 for protocol identifier
printProtocol(tmpInfo, &record->sourceID->protocol);
printf(")\n");
record->removeReference();
}
/**
* Prints a DataDataRecord
* @param sourceID SourceID of the exporting process
@ -652,7 +607,7 @@ void IpfixPrinter::onDataDataRecord(IpfixDataDataRecord* record)
int i;
/* we need a FieldInfo for printIPv4 */
InformationElement::IeInfo tmpInfo = {0, 4, 0}; // length=4 for IPv4 address
boost::shared_ptr<IpfixRecord::DataTemplateInfo> dataTemplateInfo;
boost::shared_ptr<TemplateInfo> dataTemplateInfo;
switch (outputType) {
case LINE:
@ -670,7 +625,7 @@ void IpfixPrinter::onDataDataRecord(IpfixDataDataRecord* record)
printf(":%d (", record->sourceID->exporterPort);
tmpInfo.length = 1; // length=1 for protocol identifier
printProtocol(tmpInfo, &record->sourceID->protocol);
printf(") )\n");
printf("))\n");
printf(" `- fixed data\n");
for (i = 0; i < dataTemplateInfo->dataCount; i++) {

View File

@ -40,14 +40,10 @@ class IpfixPrinter : public Module, public IpfixRecordDestination, public Source
IpfixPrinter(OutputType outputtype = TREE, string filename = "");
~IpfixPrinter();
virtual void onDataTemplate(IpfixDataTemplateRecord* record);
virtual void onDataDataRecord(IpfixDataDataRecord* record);
virtual void onDataTemplateDestruction(IpfixDataTemplateDestructionRecord* record);
virtual void onOptionsTemplate(IpfixOptionsTemplateRecord* record);
virtual void onOptionsRecord(IpfixOptionsRecord* record);
virtual void onOptionsTemplateDestruction(IpfixOptionsTemplateDestructionRecord* record);
virtual void onTemplate(IpfixTemplateRecord* record);
virtual void onDataRecord(IpfixDataRecord* record);
virtual void onOptionsRecord(IpfixOptionsRecord* record);
virtual void onDataDataRecord(IpfixDataDataRecord* record);
virtual void onTemplate(IpfixTemplateRecord* record);
virtual void onTemplateDestruction(IpfixTemplateDestructionRecord* record);
protected:

View File

@ -153,6 +153,132 @@ namespace InformationElement {
}
/* Methods of TemplateInfo class */
TemplateInfo::TemplateInfo() : templateId(0), setId(UnknownSetId), fieldCount(0), fieldInfo(NULL),
userData(NULL), destroyed(false), freePointers(true),
scopeCount(0), scopeInfo(NULL), dataCount(0), dataInfo(NULL), preceding(0), dataLength(0), data(NULL),
anonymized(false)
{}
TemplateInfo::TemplateInfo(const TemplateInfo& t)
{
templateId = t.templateId;
setId = t.setId;
// copy fields
fieldCount = t.fieldCount; /**< number of regular fields */
fieldInfo = (FieldInfo*)malloc(fieldCount*sizeof(FieldInfo));
memcpy(fieldInfo, t.fieldInfo, fieldCount*sizeof(FieldInfo));
userData = t.userData;
destroyed = t.destroyed;
freePointers = t.freePointers;
// copy Options Template scope fields
scopeCount = t.scopeCount;
scopeInfo = (FieldInfo*)malloc(scopeCount*sizeof(FieldInfo));
memcpy(scopeInfo, t.scopeInfo, scopeCount*sizeof(FieldInfo));
// copy Data Template data fields and further attributes
dataCount = t.dataCount;
dataInfo = (FieldInfo*)malloc(dataCount*sizeof(FieldInfo));
memcpy(dataInfo, t.dataInfo, dataCount*sizeof(FieldInfo));
preceding = t.preceding;
dataLength = t.dataLength;
data = (IpfixRecord::Data*)malloc(dataLength*sizeof(IpfixRecord::Data));
memcpy(data, t.data, dataLength*sizeof(IpfixRecord::Data));
anonymized = t.anonymized;
}
TemplateInfo::~TemplateInfo() {
if (freePointers)
{
free(fieldInfo);
free(scopeInfo);
free(dataInfo);
free(data);
freePointers = false;
}
}
/**
* Gets a Template's FieldInfo by Information Element id. Length is ignored.
* @param type Information Element to look for. Length is ignored.
* @return NULL if not found
*/
TemplateInfo::FieldInfo* TemplateInfo::getFieldInfo(const InformationElement::IeInfo& type) {
return getFieldInfo(type.id, type.enterprise);
}
// IpfixRecord::Data* TemplateInfo::getFieldPointer(InformationElement::IeInfo* type, IpfixRecord::Data* pdata) {
// return getFieldPointer(type->id, &pdata);
// }
//
/**
* Gets a Template's FieldInfo by IE Id and enterprise number.
* @param fieldTypeId Information element Id to look for
* @param fieldTypeEid Enterprise number to look for
* @return NULL if not found
*/
TemplateInfo::FieldInfo* TemplateInfo::getFieldInfo(InformationElement::IeId fieldTypeId, InformationElement::IeEnterpriseNumber fieldTypeEid) {
int i;
for (i = 0; i < fieldCount; i++) {
if ((fieldInfo[i].type.id == fieldTypeId) && (fieldInfo[i].type.enterprise == fieldTypeEid)) {
return &fieldInfo[i];
}
}
return NULL;
}
/**
* Gets position of a field in the Template.
* @param fieldTypeId Information element Id to look for
* @param fieldTypeEid Enterprise number to look for
* @return NULL if not found
*/
int TemplateInfo::getFieldIndex(InformationElement::IeId fieldTypeId, InformationElement::IeEnterpriseNumber fieldTypeEid) {
int i;
for (i = 0; i < fieldCount; i++) {
if ((fieldInfo[i].type.id == fieldTypeId) && (fieldInfo[i].type.enterprise == fieldTypeEid)) {
return i;
}
}
return -1;
}
/**
* Gets data of Data Templates for a given Information Element.
* @param type Information Element to get data for
* @return NULL if not found
*/
TemplateInfo::FieldInfo* TemplateInfo::getDataInfo(const InformationElement::IeInfo& type) {
return getDataInfo(type.id, type.enterprise);
}
/**
* Gets data of Data Templates for a given Information Element Id and enterprise number.
* @param fieldTypeId Information Element id to look for
* @param fieldTypeEid enterprise number to look for
* @return NULL if not found
*/
TemplateInfo::FieldInfo* TemplateInfo::getDataInfo(InformationElement::IeId fieldTypeId, InformationElement::IeEnterpriseNumber fieldTypeEid) {
int i;
for (i = 0; i < dataCount; i++) {
if ((dataInfo[i].type.id == fieldTypeId) && (dataInfo[i].type.enterprise == fieldTypeEid)) {
return &dataInfo[i];
}
}
return NULL;
}
IpfixRecord::IpfixRecord()
{
@ -161,21 +287,11 @@ IpfixRecord::IpfixRecord()
IpfixRecord::~IpfixRecord() {
}
IpfixOptionsTemplateRecord::IpfixOptionsTemplateRecord(InstanceManager<IpfixOptionsTemplateRecord>* im)
: ManagedInstance<IpfixOptionsTemplateRecord>(im)
{
}
IpfixTemplateRecord::IpfixTemplateRecord(InstanceManager<IpfixTemplateRecord>* im)
: ManagedInstance<IpfixTemplateRecord>(im)
{
}
IpfixDataTemplateRecord::IpfixDataTemplateRecord(InstanceManager<IpfixDataTemplateRecord>* im)
: ManagedInstance<IpfixDataTemplateRecord>(im)
{
}
IpfixDataRecord::IpfixDataRecord(InstanceManager<IpfixDataRecord>* im)
: ManagedInstance<IpfixDataRecord>(im)
{
@ -196,13 +312,3 @@ IpfixTemplateDestructionRecord::IpfixTemplateDestructionRecord(InstanceManager<I
{
}
IpfixOptionsTemplateDestructionRecord::IpfixOptionsTemplateDestructionRecord(InstanceManager<IpfixOptionsTemplateDestructionRecord>* im)
: ManagedInstance<IpfixOptionsTemplateDestructionRecord>(im)
{
}
IpfixDataTemplateDestructionRecord::IpfixDataTemplateDestructionRecord(InstanceManager<IpfixDataTemplateDestructionRecord>* im)
: ManagedInstance<IpfixDataTemplateDestructionRecord>(im)
{
}

View File

@ -49,7 +49,6 @@ namespace InformationElement {
const Packet::IPProtocolType getValidProtocols(const IeInfo& type);
}
typedef uint16_t TemplateID;
/**
* represents one one of several IPFIX Records, e.g. a Data Record, an Options Template Record, ...
@ -59,204 +58,6 @@ class IpfixRecord
public:
typedef uint8_t Data;
/**
* Information describing a single field in the fields passed via various callback functions.
*/
struct FieldInfo {
InformationElement::IeInfo type;
int32_t offset; /**< offset in bytes from a data start pointer. For internal purposes 0xFFFFFFFF is defined as yet unknown */
int32_t privDataOffset; /**< offset in bytes from data start pointer for internal private data which is not exported via IPFIX */
bool isVariableLength; /**< true if this field's length might change from record to record, false otherwise */
};
/**
* Template description passed to the callback function when a new Template arrives.
*/
struct TemplateInfo {
TemplateInfo() : fieldInfo(NULL), destroyed(false), freePointers(true) { }
TemplateInfo(const TemplateInfo& t)
{
templateId = t.templateId;
fieldCount = t.fieldCount; /**< number of regular fields */
fieldInfo = (IpfixRecord::FieldInfo*)malloc(fieldCount*sizeof(FieldInfo));
memcpy(fieldInfo, t.fieldInfo, fieldCount*sizeof(FieldInfo));
userData = t.userData;
destroyed = t.destroyed;
freePointers = t.freePointers;
}
~TemplateInfo() {
if (freePointers) free(fieldInfo);
}
/**
* Gets a Template's FieldInfo by field id. Length is ignored.
* @param type Field id and enterprise to look for. Length is ignored.
* @return NULL if not found
*/
IpfixRecord::FieldInfo* getFieldInfo(InformationElement::IeInfo* type) {
return getFieldInfo(type->id, type->enterprise);
}
// IpfixRecord::Data* getFieldPointer(InformationElement::IeInfo* type, IpfixRecord::Data* pdata) {
// return getFieldPointer(type->id, &pdata);
// }
/**
* Gets a Template's FieldInfo by field id. Length is ignored.
* @param fieldTypeId FieldInfo::Type id to look for
* @param fieldTypeEid FieldInfo::Type enterprise to look for
* @return NULL if not found
*/
IpfixRecord::FieldInfo* getFieldInfo(InformationElement::IeId fieldTypeId, InformationElement::IeEnterpriseNumber fieldTypeEid) {
int i;
for (i = 0; i < fieldCount; i++) {
if ((fieldInfo[i].type.id == fieldTypeId) && (fieldInfo[i].type.enterprise == fieldTypeEid)) {
return &fieldInfo[i];
}
}
return NULL;
}
int getFieldIndex(InformationElement::IeId fieldTypeId, InformationElement::IeEnterpriseNumber fieldTypeEid) {
int i;
for (i = 0; i < fieldCount; i++) {
if ((fieldInfo[i].type.id == fieldTypeId) && (fieldInfo[i].type.enterprise == fieldTypeEid)) {
return i;
}
}
return -1;
}
uint16_t templateId; /**< the template id assigned to this template or 0 if we don't know or don't care */
uint16_t fieldCount; /**< number of regular fields */
IpfixRecord::FieldInfo* fieldInfo; /**< array of FieldInfos describing each of these fields */
void* userData; /**< pointer to a field that can be used by higher-level modules */
/**
* if this template is to be destroyed because of module reconfiguration, this flag is set to true
* it should be checked in every module which caches this structure and be destroyed in method
* Module::preRegistration2()
**/
bool destroyed;
bool freePointers; /** small helper variable to indicate if pointers should be freed on destruction */
};
/**
* OptionsTemplate description passed to the callback function when a new OptionsTemplate arrives.
* Note that - other than in [PROTO] - fieldCount specifies only the number of regular fields
*/
struct OptionsTemplateInfo {
OptionsTemplateInfo() : scopeInfo(NULL), fieldInfo(NULL) {
}
OptionsTemplateInfo(const OptionsTemplateInfo& t)
{
templateId = t.templateId;
scopeCount = t.scopeCount;
scopeInfo = (FieldInfo*)malloc(scopeCount*sizeof(FieldInfo));
memcpy(scopeInfo, t.scopeInfo, scopeCount*sizeof(FieldInfo));
fieldCount = t.fieldCount; /**< number of regular fields */
fieldInfo = (FieldInfo*)malloc(fieldCount*sizeof(FieldInfo));
memcpy(fieldInfo, t.fieldInfo, fieldCount*sizeof(FieldInfo));
userData = t.userData;
}
~OptionsTemplateInfo() {
free(fieldInfo);
free(scopeInfo);
}
uint16_t templateId; /**< the template id assigned to this template or 0 if we don't know or don't care */
uint16_t scopeCount; /**< number of scope fields */
IpfixRecord::FieldInfo* scopeInfo; /**< array of FieldInfos describing each of these fields */
uint16_t fieldCount; /**< number of regular fields. This is NOT the number of all fields */
IpfixRecord::FieldInfo* fieldInfo; /**< array of FieldInfos describing each of these fields */
void* userData; /**< pointer to a field that can be used by higher-level modules */
};
/**
* DataTemplate description passed to the callback function when a new DataTemplate arrives.
*/
struct DataTemplateInfo : public TemplateInfo
{
DataTemplateInfo() : TemplateInfo(), preceding(0), dataCount(0), dataInfo(NULL), dataLength(0), data(NULL), anonymized (false) {
}
DataTemplateInfo(const DataTemplateInfo& t)
{
templateId = t.templateId;
preceding = t.preceding;
fieldCount = t.fieldCount;
fieldInfo = (FieldInfo*)malloc(fieldCount*sizeof(FieldInfo));
memcpy(fieldInfo, t.fieldInfo, fieldCount*sizeof(FieldInfo));
dataCount = t.dataCount;
dataInfo = (FieldInfo*)malloc(dataCount*sizeof(FieldInfo));
memcpy(dataInfo, t.dataInfo, dataCount*sizeof(FieldInfo));
dataLength = t.dataLength;
data = (Data*)malloc(dataLength*sizeof(Data));
memcpy(data, t.data, dataLength*sizeof(Data));
anonymized = t.anonymized;
userData = t.userData;
destroyed = t.destroyed;
freePointers = t.freePointers;
}
~DataTemplateInfo() {
if (freePointers) {
free(fieldInfo);
free(dataInfo);
free(data);
freePointers = false;
}
}
IpfixRecord::FieldInfo* getDataInfo(InformationElement::IeInfo* type) {
return getDataInfo(type->id, type->enterprise);
}
/**
* Gets a DataTemplate's Data-FieldInfo by field id.
* @param fieldTypeId Field id to look for
* @param fieldTypeEid Field enterprise to look for
* @return NULL if not found
*/
IpfixRecord::FieldInfo* getDataInfo(InformationElement::IeId fieldTypeId, InformationElement::IeEnterpriseNumber fieldTypeEid) {
int i;
for (i = 0; i < dataCount; i++) {
if ((dataInfo[i].type.id == fieldTypeId) && (dataInfo[i].type.enterprise == fieldTypeEid)) {
return &dataInfo[i];
}
}
return NULL;
}
uint16_t preceding; /**< the preceding rule field as defined in the draft */
uint16_t dataCount; /**< number of fixed-value fields */
IpfixRecord::FieldInfo* dataInfo; /**< array of FieldInfos describing each of these fields */
uint16_t dataLength;
IpfixRecord::Data* data; /**< data start pointer for fixed-value fields */
bool anonymized; /** flag that indicates if fixed-value fields have been anonymized */
void* userData; /**< pointer to a field that can be used by higher-level modules */
};
/* This struct is called SourceID for historic reasons.
* A better name would be something like TemplateScope (TransportSession + ObservationDomainId)
@ -319,40 +120,87 @@ class IpfixRecord
virtual void addReference(int count = 1) = 0;
};
/**
* Template description passed to the callback function when a new Template arrives.
*/
class TemplateInfo {
public:
typedef uint16_t TemplateId;
enum SetId {
UnknownSetId = -1,
NetflowTemplate = 0,
NetflowOptionsTemplate = 1,
IpfixTemplate = 2,
IpfixOptionsTemplate = 3,
IpfixDataTemplate = 4
};
/**
* Information describing a single field in the Template
*/
struct FieldInfo {
InformationElement::IeInfo type;
int32_t offset; /**< offset in bytes from a data start pointer. For internal purposes 0xFFFFFFFF is defined as yet unknown */
int32_t privDataOffset; /**< offset in bytes from data start pointer for internal private data which is not exported via IPFIX */
bool isVariableLength; /**< true if this field's length might change from record to record, false otherwise */
};
TemplateInfo();
TemplateInfo(const TemplateInfo& t);
~TemplateInfo();
FieldInfo* getFieldInfo(const InformationElement::IeInfo& type);
FieldInfo* getFieldInfo(InformationElement::IeId fieldTypeId, InformationElement::IeEnterpriseNumber fieldTypeEid);
int getFieldIndex(InformationElement::IeId fieldTypeId, InformationElement::IeEnterpriseNumber fieldTypeEid);
FieldInfo* getDataInfo(const InformationElement::IeInfo& type);
FieldInfo* getDataInfo(InformationElement::IeId fieldTypeId, InformationElement::IeEnterpriseNumber fieldTypeEid);
TemplateId templateId; /**< the template id assigned to this template */
SetId setId; /**< set Id */
uint16_t fieldCount; /**< number of regular fields */
FieldInfo* fieldInfo; /**< array of FieldInfos describing each of these fields */
void* userData; /**< pointer to a field that can be used by higher-level modules */
/**
* if this template is to be destroyed because of module reconfiguration, this flag is set to true
* it should be checked in every module which caches this structure and be destroyed in method
* Module::preRegistration2()
**/
bool destroyed;
bool freePointers; /** small helper variable to indicate if pointers should be freed on destruction */
// only used by Options Templates:
uint16_t scopeCount; /**< number of scope fields */
FieldInfo* scopeInfo; /**< array of FieldInfos describing each of these fields */
// only used by Data Templates:
uint16_t dataCount; /**< number of fixed-value fields */
FieldInfo* dataInfo; /**< array of FieldInfos describing each of these fields */
uint16_t preceding; /**< the preceding rule field as defined in the draft */
uint16_t dataLength;
IpfixRecord::Data* data; /**< data start pointer for fixed-value fields */
bool anonymized; /** flag that indicates if fixed-value fields have been anonymized */
};
class IpfixTemplateRecord : public IpfixRecord, public ManagedInstance<IpfixTemplateRecord> {
public:
IpfixTemplateRecord(InstanceManager<IpfixTemplateRecord>* im);
boost::shared_ptr<IpfixRecord::TemplateInfo> templateInfo;
boost::shared_ptr<TemplateInfo> templateInfo;
// redirector to reference remover of ManagedInstance
virtual void removeReference() { ManagedInstance<IpfixTemplateRecord>::removeReference(); }
virtual void addReference(int count = 1) { ManagedInstance<IpfixTemplateRecord>::addReference(count); }
};
class IpfixOptionsTemplateRecord : public IpfixRecord, public ManagedInstance<IpfixOptionsTemplateRecord> {
public:
IpfixOptionsTemplateRecord(InstanceManager<IpfixOptionsTemplateRecord>* im);
boost::shared_ptr<IpfixRecord::OptionsTemplateInfo> optionsTemplateInfo;
// redirector to reference remover of ManagedInstance
virtual void removeReference() { ManagedInstance<IpfixOptionsTemplateRecord>::removeReference(); }
virtual void addReference(int count = 1) { ManagedInstance<IpfixOptionsTemplateRecord>::addReference(count); }
};
class IpfixDataTemplateRecord : public IpfixRecord, public ManagedInstance<IpfixDataTemplateRecord> {
public:
IpfixDataTemplateRecord(InstanceManager<IpfixDataTemplateRecord>* im);
boost::shared_ptr<IpfixRecord::DataTemplateInfo> dataTemplateInfo;
// redirector to reference remover of ManagedInstance
virtual void removeReference() { ManagedInstance<IpfixDataTemplateRecord>::removeReference(); }
virtual void addReference(int count = 1) { ManagedInstance<IpfixDataTemplateRecord>::addReference(count); }
};
class IpfixDataRecord : public IpfixRecord, public ManagedInstance<IpfixDataRecord> {
public:
IpfixDataRecord(InstanceManager<IpfixDataRecord>* im);
boost::shared_ptr<IpfixRecord::TemplateInfo> templateInfo;
boost::shared_ptr<TemplateInfo> templateInfo;
int dataLength;
boost::shared_array<IpfixRecord::Data> message; /**< data block that contains @c data */
IpfixRecord::Data* data; /**< pointer to start of field data in @c message. Undefined after @c message goes out of scope. */
@ -365,7 +213,7 @@ class IpfixDataRecord : public IpfixRecord, public ManagedInstance<IpfixDataReco
class IpfixOptionsRecord : public IpfixRecord, public ManagedInstance<IpfixOptionsRecord> {
public:
IpfixOptionsRecord(InstanceManager<IpfixOptionsRecord>* im);
boost::shared_ptr<IpfixRecord::OptionsTemplateInfo> optionsTemplateInfo;
boost::shared_ptr<TemplateInfo> optionsTemplateInfo;
int dataLength;
boost::shared_array<IpfixRecord::Data> message; /**< data block that contains @c data */
IpfixRecord::Data* data; /**< pointer to start of field data in @c message. Undefined after @c message goes out of scope. */
@ -379,7 +227,7 @@ class IpfixDataDataRecord : public IpfixRecord, public ManagedInstance<IpfixData
{
public:
IpfixDataDataRecord(InstanceManager<IpfixDataDataRecord>* im);
boost::shared_ptr<IpfixRecord::DataTemplateInfo> dataTemplateInfo;
boost::shared_ptr<TemplateInfo> dataTemplateInfo;
int dataLength;
boost::shared_array<IpfixRecord::Data> message; /**< data block that contains @c data */
IpfixRecord::Data* data; /**< pointer to start of field data in @c message. Undefined after @c message goes out of scope. */
@ -392,32 +240,13 @@ class IpfixDataDataRecord : public IpfixRecord, public ManagedInstance<IpfixData
class IpfixTemplateDestructionRecord : public IpfixRecord, public ManagedInstance<IpfixTemplateDestructionRecord> {
public:
IpfixTemplateDestructionRecord(InstanceManager<IpfixTemplateDestructionRecord>* im);
boost::shared_ptr<IpfixRecord::TemplateInfo> templateInfo;
boost::shared_ptr<TemplateInfo> templateInfo;
// redirector to reference remover of ManagedInstance
virtual void removeReference() { ManagedInstance<IpfixTemplateDestructionRecord>::removeReference(); }
virtual void addReference(int count = 1) { ManagedInstance<IpfixTemplateDestructionRecord>::addReference(count); }
};
class IpfixOptionsTemplateDestructionRecord : public IpfixRecord, public ManagedInstance<IpfixOptionsTemplateDestructionRecord> {
public:
IpfixOptionsTemplateDestructionRecord(InstanceManager<IpfixOptionsTemplateDestructionRecord>* im);
boost::shared_ptr<IpfixRecord::OptionsTemplateInfo> optionsTemplateInfo;
// redirector to reference remover of ManagedInstance
virtual void removeReference() { ManagedInstance<IpfixOptionsTemplateDestructionRecord>::removeReference(); }
virtual void addReference(int count = 1) { ManagedInstance<IpfixOptionsTemplateDestructionRecord>::addReference(count); }
};
class IpfixDataTemplateDestructionRecord : public IpfixRecord, public ManagedInstance<IpfixDataTemplateDestructionRecord> {
public:
IpfixDataTemplateDestructionRecord(InstanceManager<IpfixDataTemplateDestructionRecord>* im);
boost::shared_ptr<IpfixRecord::DataTemplateInfo> dataTemplateInfo;
// redirector to reference remover of ManagedInstance
virtual void removeReference() { ManagedInstance<IpfixDataTemplateDestructionRecord>::removeReference(); }
virtual void addReference(int count = 1) { ManagedInstance<IpfixDataTemplateDestructionRecord>::addReference(count); }
};
#endif

View File

@ -10,17 +10,7 @@ void IpfixRecordAnonymizer::setCopyMode(bool mode)
void IpfixRecordAnonymizer::onTemplate(IpfixTemplateRecord* record)
{
send(record);
}
void IpfixRecordAnonymizer::onOptionsTemplate(IpfixOptionsTemplateRecord* record)
{
send(record);
}
void IpfixRecordAnonymizer::onDataTemplate(IpfixDataTemplateRecord* record)
{
//FIXME: anonymize Data Templates
send(record);
}
@ -42,7 +32,7 @@ void IpfixRecordAnonymizer::onDataRecord(IpfixDataRecord* record)
myRecord = record;
for (int i = 0; i != myRecord->templateInfo->fieldCount; ++i) {
IpfixRecord::FieldInfo* field = myRecord->templateInfo->fieldInfo + i;
TemplateInfo::FieldInfo* field = myRecord->templateInfo->fieldInfo + i;
anonField(field->type.id, myRecord->data + field->offset, field->type.length);
}
send(myRecord);
@ -62,7 +52,7 @@ void IpfixRecordAnonymizer::onDataDataRecord(IpfixDataDataRecord* record)
myRecord = dataDataRecordIM.getNewInstance();
myRecord->sourceID = record->sourceID;
// we also need to copy the Data Template Info
myRecord->dataTemplateInfo = boost::shared_ptr<IpfixRecord::DataTemplateInfo>(new IpfixRecord::DataTemplateInfo(*record->dataTemplateInfo.get()));
myRecord->dataTemplateInfo = boost::shared_ptr<TemplateInfo>(new TemplateInfo(*record->dataTemplateInfo.get()));
//myRecord->dataTemplateInfo = record->dataTemplateInfo;
myRecord->dataLength = record->dataLength; // = recordLength
myRecord->message = boost::shared_array<IpfixRecord::Data>(new IpfixRecord::Data[record->dataLength]);
@ -76,14 +66,14 @@ void IpfixRecordAnonymizer::onDataDataRecord(IpfixDataDataRecord* record)
// anonymize data template fixed value fields if necessary
if(!myRecord->dataTemplateInfo->anonymized) {
for (int i = 0; i != myRecord->dataTemplateInfo->dataCount; ++i) {
IpfixRecord::FieldInfo* field = myRecord->dataTemplateInfo->dataInfo + i;
TemplateInfo::FieldInfo* field = myRecord->dataTemplateInfo->dataInfo + i;
anonField(field->type.id, myRecord->dataTemplateInfo->data + field->offset, field->type.length);
}
myRecord->dataTemplateInfo->anonymized = true;
}
// anonymize variable value fields
for (int i = 0; i != myRecord->dataTemplateInfo->fieldCount; ++i) {
IpfixRecord::FieldInfo* field = myRecord->dataTemplateInfo->fieldInfo + i;
TemplateInfo::FieldInfo* field = myRecord->dataTemplateInfo->fieldInfo + i;
anonField(field->type.id, myRecord->data + field->offset, field->type.length);
}
send(myRecord);
@ -94,15 +84,4 @@ void IpfixRecordAnonymizer::onTemplateDestruction(IpfixTemplateDestructionRecord
send(record);
}
void IpfixRecordAnonymizer::onOptionsTemplateDestruction(IpfixOptionsTemplateDestructionRecord* record)
{
send(record);
}
void IpfixRecordAnonymizer::onDataTemplateDestruction(IpfixDataTemplateDestructionRecord* record)
{
send(record);
}

View File

@ -19,14 +19,10 @@ protected:
static InstanceManager<IpfixDataDataRecord> dataDataRecordIM;
virtual void onTemplate(IpfixTemplateRecord* record);
virtual void onOptionsTemplate(IpfixOptionsTemplateRecord* record);
virtual void onDataTemplate(IpfixDataTemplateRecord* record);
virtual void onDataRecord(IpfixDataRecord* record);
virtual void onOptionsRecord(IpfixOptionsRecord* record);
virtual void onDataDataRecord(IpfixDataDataRecord* record);
virtual void onTemplateDestruction(IpfixTemplateDestructionRecord* record);
virtual void onOptionsTemplateDestruction(IpfixOptionsTemplateDestructionRecord* record);
virtual void onDataTemplateDestruction(IpfixDataTemplateDestructionRecord* record);
};
#endif

View File

@ -51,26 +51,10 @@ void IpfixRecordDestination::receive(IpfixRecord* ipfixRecord)
IpfixTemplateRecord* rec = dynamic_cast<IpfixTemplateRecord*>(ipfixRecord);
if (rec) onTemplate(rec);
}
{
IpfixDataTemplateRecord* rec = dynamic_cast<IpfixDataTemplateRecord*>(ipfixRecord);
if (rec) onDataTemplate(rec);
}
{
IpfixOptionsTemplateRecord* rec = dynamic_cast<IpfixOptionsTemplateRecord*>(ipfixRecord);
if (rec) onOptionsTemplate(rec);
}
{
IpfixTemplateDestructionRecord* rec = dynamic_cast<IpfixTemplateDestructionRecord*>(ipfixRecord);
if (rec) onTemplateDestruction(rec);
}
{
IpfixDataTemplateDestructionRecord* rec = dynamic_cast<IpfixDataTemplateDestructionRecord*>(ipfixRecord);
if (rec) onDataTemplateDestruction(rec);
}
{
IpfixOptionsTemplateDestructionRecord* rec = dynamic_cast<IpfixOptionsTemplateDestructionRecord*>(ipfixRecord);
if (rec) onOptionsTemplateDestruction(rec);
}
}
/**
@ -83,26 +67,6 @@ void IpfixRecordDestination::onTemplate(IpfixTemplateRecord* record)
record->removeReference();
}
/**
* Callback function invoked when a new DataTemplate arrives.
* @param sourceID SourceID of the exporter that sent this DataTemplate
* @param optionsTemplateInfo Pointer to a structure defining this Template
*/
void IpfixRecordDestination::onOptionsTemplate(IpfixOptionsTemplateRecord* record)
{
record->removeReference();
}
/**
* Callback function invoked when a new DataTemplate arrives.
* @param sourceID SourceID of the exporter that sent this DataTemplate
* @param dataTemplateInfo Pointer to a structure defining this Template
*/
void IpfixRecordDestination::onDataTemplate(IpfixDataTemplateRecord* record)
{
record->removeReference();
}
/**
* Callback function invoked when a new Data Record arrives.
* @param sourceID SourceID of the exporter that sent this Record
@ -152,26 +116,3 @@ void IpfixRecordDestination::onTemplateDestruction(IpfixTemplateDestructionRecor
record->removeReference();
}
/**
* Callback function invoked when a OptionsTemplate is being destroyed.
* Particularly useful for cleaning up userData associated with this Template
* @param sourceID SourceID of the exporter that sent this OptionsTemplate
* @param optionsTemplateInfo Pointer to a structure defining this OptionsTemplate
*/
void IpfixRecordDestination::onOptionsTemplateDestruction(IpfixOptionsTemplateDestructionRecord* record)
{
record->removeReference();
}
/**
* Callback function invoked when a DataTemplate is being destroyed.
* Particularly useful for cleaning up userData associated with this Template
* @param sourceID SourceID of the exporter that sent this DataTemplate
* @param dataTemplateInfo Pointer to a structure defining this DataTemplate
*/
void IpfixRecordDestination::onDataTemplateDestruction(IpfixDataTemplateDestructionRecord* record)
{
record->removeReference();
}

View File

@ -42,14 +42,10 @@ public:
protected:
// virtual handler functions for child classes
virtual void onTemplate(IpfixTemplateRecord* record);
virtual void onOptionsTemplate(IpfixOptionsTemplateRecord* record);
virtual void onDataTemplate(IpfixDataTemplateRecord* record);
virtual void onDataRecord(IpfixDataRecord* record);
virtual void onOptionsRecord(IpfixOptionsRecord* record);
virtual void onDataDataRecord(IpfixDataDataRecord* record);
virtual void onTemplateDestruction(IpfixTemplateDestructionRecord* record);
virtual void onOptionsTemplateDestruction(IpfixOptionsTemplateDestructionRecord* record);
virtual void onDataTemplateDestruction(IpfixDataTemplateDestructionRecord* record);
};
#endif /*IPFIXRECORDDESTINATION_H_*/

View File

@ -83,6 +83,7 @@ out:
THROWEXCEPTION("IpfixSender creation failed");
return;
}
IpfixSender::IpfixSender(uint32_t observationDomainId)
: statSentPackets(0),
noCachedRecords(0),
@ -171,9 +172,9 @@ void IpfixSender::addCollector(const char *ip, uint16_t port, ipfix_transport_pr
* looks in cached templates if given template is already registered there
* @returns true if it was found
*/
bool IpfixSender::isTemplateRegistered(IpfixRecord::TemplateInfo* ti)
bool IpfixSender::isTemplateRegistered(TemplateInfo* ti)
{
list<boost::shared_ptr<IpfixRecord::TemplateInfo> >::iterator iter = registeredTemplates.begin();
list<boost::shared_ptr<TemplateInfo> >::iterator iter = registeredTemplates.begin();
while (iter != registeredTemplates.end()) {
if (iter->get()->templateId == ti->templateId) return true;
iter++;
@ -184,9 +185,9 @@ bool IpfixSender::isTemplateRegistered(IpfixRecord::TemplateInfo* ti)
/**
* removes given template from cached templates
*/
void IpfixSender::removeRegisteredTemplate(IpfixRecord::TemplateInfo* ti)
void IpfixSender::removeRegisteredTemplate(TemplateInfo* ti)
{
list<boost::shared_ptr<IpfixRecord::TemplateInfo> >::iterator iter = registeredTemplates.begin();
list<boost::shared_ptr<TemplateInfo> >::iterator iter = registeredTemplates.begin();
while (iter != registeredTemplates.end()) {
if (iter->get()->templateId == ti->templateId) {
registeredTemplates.erase(iter);
@ -200,20 +201,19 @@ void IpfixSender::removeRegisteredTemplate(IpfixRecord::TemplateInfo* ti)
/**
* adds given template to the list of cached templates
*/
void IpfixSender::addRegisteredTemplate(boost::shared_ptr<IpfixRecord::TemplateInfo> ti)
void IpfixSender::addRegisteredTemplate(boost::shared_ptr<TemplateInfo> ti)
{
registeredTemplates.push_back(ti);
}
/**
* Announces a new Template
* @param sourceID ignored
* @param dataTemplateInfo Pointer to a structure defining the DataTemplate used
* @param record Pointer to a structure defining the Template used
*/
void IpfixSender::onDataTemplate(IpfixDataTemplateRecord* record)
void IpfixSender::onTemplate(IpfixTemplateRecord* record)
{
boost::shared_ptr<IpfixRecord::DataTemplateInfo> dataTemplateInfo = record->dataTemplateInfo;
uint16_t my_template_id;
boost::shared_ptr<TemplateInfo> dataTemplateInfo = record->templateInfo;
TemplateInfo::TemplateId my_template_id;
uint16_t my_preceding;
ipfix_exporter* exporter = (ipfix_exporter*)ipfixExporter;
@ -248,7 +248,7 @@ void IpfixSender::onDataTemplate(IpfixDataTemplateRecord* record)
/* Count number of IPv4 fields with length 5 */
int splitFields = 0;
for (i = 0; i < dataTemplateInfo->fieldCount; i++) {
IpfixRecord::FieldInfo* fi = &dataTemplateInfo->fieldInfo[i];
TemplateInfo::FieldInfo* fi = &dataTemplateInfo->fieldInfo[i];
if ((fi->type.id == IPFIX_TYPEID_sourceIPv4Address) && (fi->type.length == 5)) {
splitFields++;
}
@ -260,7 +260,7 @@ void IpfixSender::onDataTemplate(IpfixDataTemplateRecord* record)
/* Count number of IPv4 fields with length 5 */
int splitFixedfields = 0;
for (i = 0; i < dataTemplateInfo->dataCount; i++) {
IpfixRecord::FieldInfo* fi = &dataTemplateInfo->dataInfo[i];
TemplateInfo::FieldInfo* fi = &dataTemplateInfo->dataInfo[i];
if ((fi->type.id == IPFIX_TYPEID_sourceIPv4Address) && (fi->type.length == 5)) {
splitFixedfields++;
}
@ -274,7 +274,7 @@ void IpfixSender::onDataTemplate(IpfixDataTemplateRecord* record)
}
for (i = 0; i < dataTemplateInfo->fieldCount; i++) {
IpfixRecord::FieldInfo* fi = &dataTemplateInfo->fieldInfo[i];
TemplateInfo::FieldInfo* fi = &dataTemplateInfo->fieldInfo[i];
/* Split IPv4 fields with length 5, i.e. fields with network mask attached */
if ((fi->type.id == IPFIX_TYPEID_sourceIPv4Address) && (fi->type.length == 5)) {
@ -294,7 +294,7 @@ void IpfixSender::onDataTemplate(IpfixDataTemplateRecord* record)
int dataLength = 0;
for (i = 0; i < dataTemplateInfo->dataCount; i++) {
IpfixRecord::FieldInfo* fi = &dataTemplateInfo->dataInfo[i];
TemplateInfo::FieldInfo* fi = &dataTemplateInfo->dataInfo[i];
dataLength += fi->type.length;
@ -318,7 +318,7 @@ void IpfixSender::onDataTemplate(IpfixDataTemplateRecord* record)
memcpy(data, dataTemplateInfo->data, dataLength);
for (i = 0; i < dataTemplateInfo->dataCount; i++) {
IpfixRecord::FieldInfo* fi = &dataTemplateInfo->dataInfo[i];
TemplateInfo::FieldInfo* fi = &dataTemplateInfo->dataInfo[i];
/* Invert imask of IPv4 fields with length 5, i.e. fields with network mask attached */
if ((fi->type.id == IPFIX_TYPEID_sourceIPv4Address) && (fi->type.length == 5)) {
@ -351,10 +351,9 @@ void IpfixSender::onDataTemplate(IpfixDataTemplateRecord* record)
/**
* Invalidates a template; Does NOT free dataTemplateInfo
* @param sourceID ignored
* @param dataTemplateInfo Pointer to a structure defining the DataTemplate used
* @param record Pointer to a structure defining the Template used
*/
void IpfixSender::onDataTemplateDestruction(IpfixDataTemplateDestructionRecord* record)
void IpfixSender::onTemplateDestruction(IpfixTemplateDestructionRecord* record)
{
ipfix_exporter* exporter = (ipfix_exporter*)ipfixExporter;
@ -362,9 +361,9 @@ void IpfixSender::onDataTemplateDestruction(IpfixDataTemplateDestructionRecord*
THROWEXCEPTION("exporter not set");
}
removeRegisteredTemplate(record->dataTemplateInfo.get());
removeRegisteredTemplate(record->templateInfo.get());
uint16_t my_template_id = record->dataTemplateInfo->templateId;
TemplateInfo::TemplateId my_template_id = record->templateInfo->templateId;
/* Remove template from ipfixlolib */
@ -376,7 +375,7 @@ void IpfixSender::onDataTemplateDestruction(IpfixDataTemplateDestructionRecord*
msg(MSG_INFO, "sndIpfix removed template with ID %u", my_template_id);
}
free(record->dataTemplateInfo->userData);
free(record->templateInfo->userData);
sendRecords();
}
@ -388,7 +387,7 @@ void IpfixSender::onDataTemplateDestruction(IpfixDataTemplateDestructionRecord*
* @param templateId of the new Data Set
* @return returns -1 on error, 0 otherwise
*/
void IpfixSender::startDataSet(uint16_t templateId)
void IpfixSender::startDataSet(TemplateInfo::TemplateId templateId)
{
ipfix_exporter* exporter = (ipfix_exporter*)ipfixExporter;
uint16_t my_n_template_id = htons(templateId);
@ -467,7 +466,7 @@ void IpfixSender::removeRecordReferences()
*/
void IpfixSender::onDataDataRecord(IpfixDataDataRecord* record)
{
boost::shared_ptr<IpfixRecord::DataTemplateInfo> dataTemplateInfo = record->dataTemplateInfo;
boost::shared_ptr<TemplateInfo> dataTemplateInfo = record->dataTemplateInfo;
IpfixRecord::Data* data = record->data;
ipfix_exporter* exporter = (ipfix_exporter*)ipfixExporter;
@ -479,7 +478,7 @@ void IpfixSender::onDataDataRecord(IpfixDataDataRecord* record)
int i;
for (i = 0; i < dataTemplateInfo->fieldCount; i++) {
IpfixRecord::FieldInfo* fi = &dataTemplateInfo->fieldInfo[i];
TemplateInfo::FieldInfo* fi = &dataTemplateInfo->fieldInfo[i];
/* Split IPv4 fields with length 5, i.e. fields with network mask attached */
if ((fi->type.id == IPFIX_TYPEID_sourceIPv4Address) && (fi->type.length == 5)) {
@ -527,10 +526,10 @@ void IpfixSender::onReconfiguration2()
THROWEXCEPTION("exporter not set");
}
list<boost::shared_ptr<IpfixRecord::TemplateInfo> >::iterator iter = registeredTemplates.begin();
list<boost::shared_ptr<TemplateInfo> >::iterator iter = registeredTemplates.begin();
while (iter != registeredTemplates.end()) {
if (iter->get()->destroyed) {
uint16_t id = iter->get()->templateId;
TemplateInfo::TemplateId id = iter->get()->templateId;
// Remove template from ipfixlolib
if (0 != ipfix_remove_template_set(exporter, id)) {

View File

@ -47,17 +47,13 @@ public:
void flushPacket();
// inherited from IpfixRecordDestination
virtual void onTemplate(IpfixTemplateRecord* record) {
// FIXME: not sure how to deal with this
msg(MSG_DEBUG, "%s:%u Ignoring Template", __FILE__, __LINE__);
};
virtual void onDataRecord(IpfixDataRecord* record) {
// FIXME: not sure how to deal with this
msg(MSG_DEBUG, "%s:%u Ignoring Template", __FILE__, __LINE__);
}
virtual void onDataTemplate(IpfixDataTemplateRecord* record);
virtual void onDataTemplateDestruction(IpfixDataTemplateDestructionRecord* record);
virtual void onTemplate(IpfixTemplateRecord* record);
virtual void onTemplateDestruction(IpfixTemplateDestructionRecord* record);
virtual void onDataDataRecord(IpfixDataDataRecord* record);
virtual void onReconfiguration1();
@ -89,9 +85,9 @@ protected:
void endAndSendDataSet();
void startDataSet(uint16_t templateId);
bool isTemplateRegistered(IpfixRecord::TemplateInfo* ti);
void removeRegisteredTemplate(IpfixRecord::TemplateInfo* ti);
void addRegisteredTemplate(boost::shared_ptr<IpfixRecord::TemplateInfo> ti);
bool isTemplateRegistered(TemplateInfo* ti);
void removeRegisteredTemplate(TemplateInfo* ti);
void addRegisteredTemplate(boost::shared_ptr<TemplateInfo> ti);
void sendRecords(bool forcesend = false);
void registerTimeout();
@ -102,7 +98,7 @@ private:
uint8_t conversionRingbuffer[65536]; /**< Ringbuffer used to store converted imasks between @c ipfix_put_data_field() and @c ipfix_send() */
uint16_t currentTemplateId; /**< Template ID of the unfinished data set */
uint16_t noCachedRecords; /**< number of records already passed to ipfixlob, should be equal to recordsToRelease.size() */
list<boost::shared_ptr<IpfixRecord::TemplateInfo> > registeredTemplates; /**< contains all templates which were already registered in ipfixlolib */
list<boost::shared_ptr<TemplateInfo> > registeredTemplates; /**< contains all templates which were already registered in ipfixlolib */
uint16_t recordCacheTimeout; /**< how long may records be cached until sent, milliseconds */
bool timeoutRegistered; /**< true if next timeout was already registered in timer */

View File

@ -27,9 +27,9 @@
#include "common/msg.h"
/**
* Returns a IpfixRecord::TemplateInfo, IpfixRecord::OptionsTemplateInfo, IpfixRecord::DataTemplateInfo or NULL
* Returns a TemplateInfo or NULL
*/
TemplateBuffer::BufferedTemplate* TemplateBuffer::getBufferedTemplate(boost::shared_ptr<IpfixRecord::SourceID> sourceId, TemplateID templateId) {
TemplateBuffer::BufferedTemplate* TemplateBuffer::getBufferedTemplate(boost::shared_ptr<IpfixRecord::SourceID> sourceId, TemplateInfo::TemplateId templateId) {
time_t now = time(0);
TemplateBuffer::BufferedTemplate* bt = head;
@ -61,7 +61,7 @@ TemplateBuffer::BufferedTemplate* TemplateBuffer::getBufferedTemplate(boost::sha
}
/**
* Saves a IpfixRecord::TemplateInfo, IpfixRecord::OptionsTemplateInfo, IpfixRecord::DataTemplateInfo overwriting existing Templates
* Saves a TemplateInfo, IpfixRecord::OptionsTemplateInfo, IpfixRecord::DataTemplateInfo overwriting existing Templates
*/
void TemplateBuffer::bufferTemplate(TemplateBuffer::BufferedTemplate* bt) {
destroyBufferedTemplate(bt->sourceID, bt->templateID);
@ -73,7 +73,7 @@ void TemplateBuffer::bufferTemplate(TemplateBuffer::BufferedTemplate* bt) {
/**
* Frees memory, marks Template unused.
*/
void TemplateBuffer::destroyBufferedTemplate(boost::shared_ptr<IpfixRecord::SourceID> sourceId, TemplateID templateId, bool all)
void TemplateBuffer::destroyBufferedTemplate(boost::shared_ptr<IpfixRecord::SourceID> sourceId, TemplateInfo::TemplateId templateId, bool all)
{
TemplateBuffer::BufferedTemplate* predecessor = 0;
TemplateBuffer::BufferedTemplate* bt = head;
@ -89,38 +89,11 @@ void TemplateBuffer::destroyBufferedTemplate(boost::shared_ptr<IpfixRecord::Sour
} else {
head = (TemplateBuffer::BufferedTemplate*)bt->next;
}
if (bt->setID == IPFIX_SetId_Template) {
/* Invoke all registered callback functions */
IpfixTemplateDestructionRecord* ipfixRecord = ipfixParser->templateDestructionRecordIM.getNewInstance();
ipfixRecord->sourceID = bt->sourceID;
ipfixRecord->templateInfo = bt->templateInfo;
ipfixParser->ipfixRecordSender->send(ipfixRecord);
} else
#ifdef SUPPORT_NETFLOWV9
if (bt->setID == NetflowV9_SetId_Template) {
/* Invoke all registered callback functions */
IpfixTemplateDestructionRecord* ipfixRecord = ipfixParser->templateDestructionRecordIM.getNewInstance();
ipfixRecord->sourceID = bt->sourceID;
ipfixRecord->templateInfo = bt->templateInfo;
ipfixParser->ipfixRecordSender->send(ipfixRecord);
} else
#endif
if (bt->setID == IPFIX_SetId_OptionsTemplate) {
/* Invoke all registered callback functions */
IpfixOptionsTemplateDestructionRecord* ipfixRecord = ipfixParser->optionsTemplateDestructionRecordIM.getNewInstance();
ipfixRecord->sourceID = bt->sourceID;
ipfixRecord->optionsTemplateInfo = bt->optionsTemplateInfo;
ipfixParser->ipfixRecordSender->send(ipfixRecord);
} else if (bt->setID == IPFIX_SetId_DataTemplate) {
/* Invoke all registered callback functions */
IpfixDataTemplateDestructionRecord* ipfixRecord = ipfixParser->dataTemplateDestructionRecordIM.getNewInstance();
ipfixRecord->sourceID = bt->sourceID;
ipfixRecord->dataTemplateInfo = bt->dataTemplateInfo;
ipfixParser->ipfixRecordSender->send(ipfixRecord);
} else {
msg(MSG_FATAL, "Unknown template type requested to be freed: %d", bt->setID);
}
/* Invoke all registered callback functions */
IpfixTemplateDestructionRecord* ipfixRecord = ipfixParser->templateDestructionRecordIM.getNewInstance();
ipfixRecord->sourceID = bt->sourceID;
ipfixRecord->templateInfo = bt->templateInfo;
ipfixParser->ipfixRecordSender->send(ipfixRecord);
TemplateBuffer::BufferedTemplate* toBeFreed = bt;
bt = (TemplateBuffer::BufferedTemplate*)bt->next;
delete toBeFreed;

View File

@ -41,21 +41,19 @@ class TemplateBuffer {
*/
struct BufferedTemplate {
boost::shared_ptr<IpfixRecord::SourceID> sourceID; /**< source identifier of exporter that sent this template */
TemplateID templateID; /**< template# this template defines */
TemplateInfo::TemplateId templateID; /**< template# this template defines */
uint16_t recordLength; /**< length of one Data Record that will be transferred in Data Sets. Variable-length carry -1 */
TemplateID setID; /**< should be 2,3,4 and determines the type of pointer used in the unions */
TemplateInfo::TemplateId setID; /**< should be 2,3,4 and determines the type of pointer used in the unions */
time_t expires; /**< Timestamp when this Template will expire or 0 if it will never expire */
boost::shared_ptr<IpfixRecord::TemplateInfo> templateInfo;
boost::shared_ptr<IpfixRecord::OptionsTemplateInfo> optionsTemplateInfo;
boost::shared_ptr<IpfixRecord::DataTemplateInfo> dataTemplateInfo;
boost::shared_ptr<TemplateInfo> templateInfo;
TemplateBuffer::BufferedTemplate* next; /**< Pointer to next buffered Template */
};
TemplateBuffer(IpfixParser* parentIpfixParser);
~TemplateBuffer();
TemplateBuffer::BufferedTemplate* getBufferedTemplate(boost::shared_ptr<IpfixRecord::SourceID> sourceId, TemplateID templateId);
void destroyBufferedTemplate(boost::shared_ptr<IpfixRecord::SourceID> sourceId, TemplateID templateId, bool all = false);
TemplateBuffer::BufferedTemplate* getBufferedTemplate(boost::shared_ptr<IpfixRecord::SourceID> sourceId, TemplateInfo::TemplateId templateId);
void destroyBufferedTemplate(boost::shared_ptr<IpfixRecord::SourceID> sourceId, TemplateInfo::TemplateId templateId, bool all = false);
// templateId=2,3,4 means that all Templates, Option Templates, or Data Templates of given sourceID are destroyed
// all=true overrides templateId parameter, so all Templates of given sourceID will be deleted
void bufferTemplate(TemplateBuffer::BufferedTemplate* bt);

View File

@ -51,17 +51,19 @@ BaseHashtable::BaseHashtable(Source<IpfixRecord*>* recordsource, Rule* rule,
*/
uint32_t BaseHashtable::getPrivateDataLength(const InformationElement::IeInfo& type)
{
switch (type.id) {
case IPFIX_ETYPEID_frontPayload: // four bytes TCP sequence ID, four bytes for byte-counter for aggregated data
case IPFIX_ETYPEID_revFrontPayload: // "
case IPFIX_ETYPEID_maxPacketGap: // old flow end time (to calculate packet gap)
case IPFIX_ETYPEID_revMaxPacketGap: // old flow end time (to calculate packet gap)
return 8;
//TODO: if(type.enterprise=29305)... (Gerhard, 12/2009)
if(type.enterprise == 0) {
switch (type.id) {
case IPFIX_ETYPEID_frontPayload: // four bytes TCP sequence ID, four bytes for byte-counter for aggregated data
case IPFIX_ETYPEID_revFrontPayload: // "
case IPFIX_ETYPEID_maxPacketGap: // old flow end time (to calculate packet gap)
case IPFIX_ETYPEID_revMaxPacketGap: // old flow end time (to calculate packet gap)
return 8;
default:
return 0;
default:
return 0;
}
}
return 0;
}
@ -69,8 +71,9 @@ void BaseHashtable::createDataTemplate(Rule* rule)
{
int dataLength = 0; /**< length in bytes of the @c data field */
dataTemplate.reset(new IpfixRecord::DataTemplateInfo);
dataTemplate.reset(new TemplateInfo);
dataTemplate->templateId = rule->id;
dataTemplate->setId = TemplateInfo::IpfixDataTemplate;
dataTemplate->preceding = rule->preceding;
dataTemplate->fieldCount = 0;
dataTemplate->fieldInfo = NULL;
@ -90,9 +93,9 @@ void BaseHashtable::createDataTemplate(Rule* rule)
if (rf->pattern != NULL) {
/* create new fixed-data field containing pattern */
dataTemplate->dataCount++;
dataTemplate->dataInfo = (IpfixRecord::FieldInfo*) realloc(dataTemplate->dataInfo,
sizeof(IpfixRecord::FieldInfo) * dataTemplate->dataCount);
IpfixRecord::FieldInfo* fi = &dataTemplate->dataInfo[dataTemplate->dataCount - 1];
dataTemplate->dataInfo = (TemplateInfo::FieldInfo*) realloc(dataTemplate->dataInfo,
sizeof(TemplateInfo::FieldInfo) * dataTemplate->dataCount);
TemplateInfo::FieldInfo* fi = &dataTemplate->dataInfo[dataTemplate->dataCount - 1];
fi->type = rf->type;
fi->offset = dataLength;
fi->privDataOffset = 0;
@ -113,9 +116,9 @@ void BaseHashtable::createDataTemplate(Rule* rule)
else if (rf->modifier != Rule::Field::DISCARD) {
/* define new data field with Rule::Field's type */
dataTemplate->fieldCount++;
dataTemplate->fieldInfo = (IpfixRecord::FieldInfo*) realloc(dataTemplate->fieldInfo,
sizeof(IpfixRecord::FieldInfo) * dataTemplate->fieldCount);
IpfixRecord::FieldInfo* fi = &dataTemplate->fieldInfo[dataTemplate->fieldCount - 1];
dataTemplate->fieldInfo = (TemplateInfo::FieldInfo*) realloc(dataTemplate->fieldInfo,
sizeof(TemplateInfo::FieldInfo) * dataTemplate->fieldCount);
TemplateInfo::FieldInfo* fi = &dataTemplate->fieldInfo[dataTemplate->fieldCount - 1];
fi->type = rf->type;
fi->offset = fieldLength;
fi->privDataOffset = 0;
@ -129,7 +132,7 @@ void BaseHashtable::createDataTemplate(Rule* rule)
uint32_t revfpLengthOffset = 0;
privDataLength = 0;
for (uint32_t i = 0; i < dataTemplate->fieldCount; i++) {
IpfixRecord::FieldInfo* fi = &dataTemplate->fieldInfo[i];
TemplateInfo::FieldInfo* fi = &dataTemplate->fieldInfo[i];
uint32_t len = getPrivateDataLength(fi->type);
if (len > 0) {
fi->privDataOffset = fieldLength + privDataLength;
@ -144,7 +147,7 @@ void BaseHashtable::createDataTemplate(Rule* rule)
// update private data offsets for fields which access private data from other fields
// example: front payload length accesses data from front payload
for (uint32_t i = 0; i < dataTemplate->fieldCount; i++) {
IpfixRecord::FieldInfo* fi = &dataTemplate->fieldInfo[i];
TemplateInfo::FieldInfo* fi = &dataTemplate->fieldInfo[i];
if (fi->type.id == IPFIX_ETYPEID_frontPayloadLen) {
if (!fpLengthOffset) {
THROWEXCEPTION("no front payload field specified in template, so front payload length is not available either");
@ -312,58 +315,62 @@ void BaseHashtable::expireFlows(bool all)
*/
int BaseHashtable::isToBeAggregated(const InformationElement::IeInfo& type)
{
switch (type.id) {
case IPFIX_TYPEID_flowStartSysUpTime:
case IPFIX_TYPEID_flowStartSeconds:
case IPFIX_TYPEID_flowStartMilliSeconds:
case IPFIX_TYPEID_flowStartMicroSeconds:
case IPFIX_TYPEID_flowStartNanoSeconds:
case IPFIX_TYPEID_flowEndSysUpTime:
case IPFIX_TYPEID_flowEndSeconds:
case IPFIX_TYPEID_flowEndMilliSeconds:
case IPFIX_TYPEID_flowEndMicroSeconds:
case IPFIX_TYPEID_flowEndNanoSeconds:
case IPFIX_TYPEID_octetDeltaCount:
case IPFIX_TYPEID_postOctetDeltaCount:
case IPFIX_TYPEID_packetDeltaCount:
case IPFIX_TYPEID_postPacketDeltaCount:
case IPFIX_TYPEID_droppedOctetDeltaCount:
case IPFIX_TYPEID_droppedPacketDeltaCount:
case IPFIX_TYPEID_tcpControlBits:
case IPFIX_ETYPEID_frontPayload:
case IPFIX_ETYPEID_frontPayloadLen:
case IPFIX_ETYPEID_frontPayloadPktCount:
case IPFIX_ETYPEID_revFrontPayload:
case IPFIX_ETYPEID_revFrontPayloadLen:
case IPFIX_ETYPEID_revFlowStartSeconds:
case IPFIX_ETYPEID_revFlowStartMilliSeconds:
case IPFIX_ETYPEID_revFlowStartNanoSeconds:
case IPFIX_ETYPEID_revFlowEndSeconds:
case IPFIX_ETYPEID_revFlowEndMilliSeconds:
case IPFIX_ETYPEID_revFlowEndNanoSeconds:
case IPFIX_ETYPEID_revOctetDeltaCount:
case IPFIX_ETYPEID_revPacketDeltaCount:
case IPFIX_ETYPEID_revTcpControlBits:
case IPFIX_ETYPEID_maxPacketGap:
case IPFIX_ETYPEID_revMaxPacketGap:
return 1;
if(type.enterprise == 0) {
switch (type.id) {
case IPFIX_TYPEID_flowStartSysUpTime:
case IPFIX_TYPEID_flowStartSeconds:
case IPFIX_TYPEID_flowStartMilliSeconds:
case IPFIX_TYPEID_flowStartMicroSeconds:
case IPFIX_TYPEID_flowStartNanoSeconds:
case IPFIX_TYPEID_flowEndSysUpTime:
case IPFIX_TYPEID_flowEndSeconds:
case IPFIX_TYPEID_flowEndMilliSeconds:
case IPFIX_TYPEID_flowEndMicroSeconds:
case IPFIX_TYPEID_flowEndNanoSeconds:
case IPFIX_TYPEID_octetDeltaCount:
case IPFIX_TYPEID_postOctetDeltaCount:
case IPFIX_TYPEID_packetDeltaCount:
case IPFIX_TYPEID_postPacketDeltaCount:
case IPFIX_TYPEID_droppedOctetDeltaCount:
case IPFIX_TYPEID_droppedPacketDeltaCount:
case IPFIX_TYPEID_tcpControlBits:
//TODO: replace by enterprise number (Gerhard, 12/2009)
case IPFIX_ETYPEID_frontPayload:
case IPFIX_ETYPEID_frontPayloadLen:
case IPFIX_ETYPEID_frontPayloadPktCount:
case IPFIX_ETYPEID_revFrontPayload:
case IPFIX_ETYPEID_revFrontPayloadLen:
case IPFIX_ETYPEID_revFlowStartSeconds:
case IPFIX_ETYPEID_revFlowStartMilliSeconds:
case IPFIX_ETYPEID_revFlowStartNanoSeconds:
case IPFIX_ETYPEID_revFlowEndSeconds:
case IPFIX_ETYPEID_revFlowEndMilliSeconds:
case IPFIX_ETYPEID_revFlowEndNanoSeconds:
case IPFIX_ETYPEID_revOctetDeltaCount:
case IPFIX_ETYPEID_revPacketDeltaCount:
case IPFIX_ETYPEID_revTcpControlBits:
case IPFIX_ETYPEID_maxPacketGap:
case IPFIX_ETYPEID_revMaxPacketGap:
return 1;
case IPFIX_TYPEID_octetTotalCount:
case IPFIX_TYPEID_packetTotalCount:
case IPFIX_TYPEID_droppedOctetTotalCount:
case IPFIX_TYPEID_droppedPacketTotalCount:
case IPFIX_TYPEID_postMCastPacketDeltaCount:
case IPFIX_TYPEID_postMCastOctetDeltaCount:
case IPFIX_TYPEID_observedFlowTotalCount:
case IPFIX_TYPEID_exportedOctetTotalCount:
case IPFIX_TYPEID_exportedMessageTotalCount:
case IPFIX_TYPEID_exportedFlowTotalCount:
DPRINTF("isToBeAggregated: Will not aggregate %s field", typeid2string(type.id));
return 0;
case IPFIX_TYPEID_octetTotalCount:
case IPFIX_TYPEID_packetTotalCount:
case IPFIX_TYPEID_droppedOctetTotalCount:
case IPFIX_TYPEID_droppedPacketTotalCount:
case IPFIX_TYPEID_postMCastPacketDeltaCount:
case IPFIX_TYPEID_postMCastOctetDeltaCount:
case IPFIX_TYPEID_observedFlowTotalCount:
case IPFIX_TYPEID_exportedOctetTotalCount:
case IPFIX_TYPEID_exportedMessageTotalCount:
case IPFIX_TYPEID_exportedFlowTotalCount:
DPRINTF("isToBeAggregated: Will not aggregate %s field", typeid2string(type.id));
return 0;
default:
return 0;
default:
return 0;
}
}
return 0;
}
/**
@ -371,9 +378,9 @@ int BaseHashtable::isToBeAggregated(const InformationElement::IeInfo& type)
*/
void BaseHashtable::sendDataTemplate()
{
IpfixDataTemplateRecord* ipfixRecord = dataTemplateRecordIM.getNewInstance();
IpfixTemplateRecord* ipfixRecord = dataTemplateRecordIM.getNewInstance();
ipfixRecord->sourceID.reset();
ipfixRecord->dataTemplateInfo = dataTemplate;
ipfixRecord->templateInfo = dataTemplate;
recordSource->send(ipfixRecord);
}

View File

@ -71,7 +71,7 @@ public:
void postReconfiguration();
protected:
boost::shared_ptr<IpfixRecord::DataTemplateInfo> dataTemplate; /**< structure describing both variable and fixed fields and containing fixed data */
boost::shared_ptr<TemplateInfo> dataTemplate; /**< structure describing both variable and fixed fields and containing fixed data */
HashtableBucket** buckets; /**< array of pointers to hash buckets at start of spill chain. Members are NULL where no entry present */
uint32_t htableBits;
@ -97,7 +97,7 @@ protected:
HashtableBucketList exportList;
InstanceManager<IpfixDataDataRecord> dataDataRecordIM;
InstanceManager<IpfixDataTemplateRecord> dataTemplateRecordIM;
InstanceManager<IpfixTemplateRecord> dataTemplateRecordIM;
InstanceManager<BucketListElement> hbucketIM;
alock_t aggInProgress; /** indicates if currently an element is aggregated in the hashtable, used for atomic lock for preReconfiguration */

View File

@ -55,7 +55,7 @@ void FlowHashtable::genBiflowStructs()
DPRINTF("fieldCount=%d", dataTemplate->fieldCount);
for (int32_t i=0; i<dataTemplate->fieldCount; i++) {
DPRINTF("fieldCount=%d", i);
IpfixRecord::FieldInfo* fi = &dataTemplate->fieldInfo[i];
TemplateInfo::FieldInfo* fi = &dataTemplate->fieldInfo[i];
if (fi->type.length>maxFieldSize) maxFieldSize = fi->type.length;
switch (fi->type.id) {
case IPFIX_TYPEID_protocolIdentifier:
@ -102,7 +102,7 @@ void FlowHashtable::genBiflowStructs()
}
for (int i=0; i<dataTemplate->fieldCount; i++) {
IpfixRecord::FieldInfo* fi = &dataTemplate->fieldInfo[i];
TemplateInfo::FieldInfo* fi = &dataTemplate->fieldInfo[i];
switch (fi->type.id) {
case IPFIX_TYPEID_sourceIPv4Address:
revDataTemplateMapper[i] = dstIPIdx;
@ -129,7 +129,7 @@ void FlowHashtable::genBiflowStructs()
/**
* Adds (or otherwise aggregates) @c deltaData to @c baseData
*/
int FlowHashtable::aggregateField(IpfixRecord::FieldInfo* basefi, IpfixRecord::FieldInfo* deltafi, IpfixRecord::Data* base,
int FlowHashtable::aggregateField(TemplateInfo::FieldInfo* basefi, TemplateInfo::FieldInfo* deltafi, IpfixRecord::Data* base,
IpfixRecord::Data* delta) {
IpfixRecord::Data* baseData = base+basefi->offset;
IpfixRecord::Data* deltaData = delta+deltafi->offset;
@ -284,7 +284,7 @@ int FlowHashtable::aggregateField(IpfixRecord::FieldInfo* basefi, IpfixRecord::F
* @returns 1 if second is bigger than first argument
* @returns -1 if first is bigger than second argument
*/
int FlowHashtable::compare4ByteField(IpfixRecord::Data* baseFlow, IpfixRecord::FieldInfo* baseFi, IpfixRecord::Data* flow, IpfixRecord::FieldInfo* deltaFi)
int FlowHashtable::compare4ByteField(IpfixRecord::Data* baseFlow, TemplateInfo::FieldInfo* baseFi, IpfixRecord::Data* flow, TemplateInfo::FieldInfo* deltaFi)
{
IpfixRecord::Data* baseData = baseFlow+baseFi->offset;
IpfixRecord::Data* deltaData = flow+deltaFi->offset;
@ -302,7 +302,7 @@ int FlowHashtable::compare4ByteField(IpfixRecord::Data* baseFlow, IpfixRecord::F
* @returns 1 if second is bigger than first argument
* @returns -1 if first is bigger than second argument
*/
int FlowHashtable::compare8ByteField(IpfixRecord::Data* baseFlow, IpfixRecord::FieldInfo* baseFi, IpfixRecord::Data* flow, IpfixRecord::FieldInfo* deltaFi)
int FlowHashtable::compare8ByteField(IpfixRecord::Data* baseFlow, TemplateInfo::FieldInfo* baseFi, IpfixRecord::Data* flow, TemplateInfo::FieldInfo* deltaFi)
{
IpfixRecord::Data* baseData = baseFlow+baseFi->offset;
IpfixRecord::Data* deltaData = flow+deltaFi->offset;
@ -326,7 +326,7 @@ int FlowHashtable::aggregateFlow(IpfixRecord::Data* baseFlow, IpfixRecord::Data*
int result = 0;
for (i = 0; i < dataTemplate->fieldCount; i++) {
IpfixRecord::FieldInfo* fi = &dataTemplate->fieldInfo[i];
TemplateInfo::FieldInfo* fi = &dataTemplate->fieldInfo[i];
if(!isToBeAggregated(fi->type)) {
continue;
@ -416,14 +416,14 @@ int FlowHashtable::equalFlow(IpfixRecord::Data* flow1, IpfixRecord::Data* flow2,
if(flow1 == flow2) return 1;
for(i = 0; i < dataTemplate->fieldCount; i++) {
IpfixRecord::FieldInfo* fi = &dataTemplate->fieldInfo[i];
TemplateInfo::FieldInfo* fi = &dataTemplate->fieldInfo[i];
if(isToBeAggregated(fi->type)) {
continue;
}
if (reverse) {
IpfixRecord::FieldInfo* rfi = &dataTemplate->fieldInfo[revDataTemplateMapper[i]];
TemplateInfo::FieldInfo* rfi = &dataTemplate->fieldInfo[revDataTemplateMapper[i]];
if(!equalRaw(&fi->type, flow1 + fi->offset,
&fi->type /* both types *must* be equal, although they may not */,
flow2 + rfi->offset)) {
@ -466,8 +466,8 @@ HashtableBucket* FlowHashtable::lookupBucket(uint32_t hash, IpfixRecord::Data* d
void FlowHashtable::reverseFlowBucket(HashtableBucket* bucket)
{
for (uint32_t i = 0; i < dataTemplate->fieldCount; i++) {
IpfixRecord::FieldInfo* fi = &dataTemplate->fieldInfo[i];
IpfixRecord::FieldInfo* fi2 = &dataTemplate->fieldInfo[flowReverseMapper[i]];
TemplateInfo::FieldInfo* fi = &dataTemplate->fieldInfo[i];
TemplateInfo::FieldInfo* fi2 = &dataTemplate->fieldInfo[flowReverseMapper[i]];
if (fi != fi2) {
//msg(MSG_ERROR, "mapping idx %d to idx %d", i, flowReverseMapper[i]);
@ -559,7 +559,7 @@ void FlowHashtable::bufferDataBlock(boost::shared_array<IpfixRecord::Data> data)
* Copies \c srcData to \c dstData applying \c modifier.
* Takes care to pad \c srcData with zero-bytes in case it is shorter than \c dstData.
*/
void FlowHashtable::copyData(IpfixRecord::FieldInfo* dstFI, IpfixRecord::Data* dst, IpfixRecord::FieldInfo* srcFI, IpfixRecord::Data* src, Rule::Field::Modifier modifier)
void FlowHashtable::copyData(TemplateInfo::FieldInfo* dstFI, IpfixRecord::Data* dst, TemplateInfo::FieldInfo* srcFI, IpfixRecord::Data* src, Rule::Field::Modifier modifier)
{
InformationElement::IeInfo* dstType = &dstFI->type;
InformationElement::IeInfo* srcType = &srcFI->type;
@ -667,7 +667,7 @@ void FlowHashtable::copyData(IpfixRecord::FieldInfo* dstFI, IpfixRecord::Data* d
/**
* Buffer passed flow in Hashtable @c ht
*/
void FlowHashtable::aggregateTemplateData(IpfixRecord::TemplateInfo* ti, IpfixRecord::Data* data)
void FlowHashtable::aggregateTemplateData(TemplateInfo* ti, IpfixRecord::Data* data)
{
// the following lock should almost never fail (only during reconfiguration)
while (atomic_lock(&aggInProgress)) {
@ -685,8 +685,8 @@ void FlowHashtable::aggregateTemplateData(IpfixRecord::TemplateInfo* ti, IpfixRe
memset(htdata.get()+fieldLength, 0, privDataLength);
for (i = 0; i < dataTemplate->fieldCount; i++) {
IpfixRecord::FieldInfo* hfi = &dataTemplate->fieldInfo[i];
IpfixRecord::FieldInfo* tfi = ti->getFieldInfo(&hfi->type);
TemplateInfo::FieldInfo* hfi = &dataTemplate->fieldInfo[i];
TemplateInfo::FieldInfo* tfi = ti->getFieldInfo(hfi->type);
if (!tfi) {
DPRINTF("Flow to be buffered did not contain %s field\n", typeid2string(hfi->type.id));
@ -749,7 +749,7 @@ void FlowHashtable::aggregateTemplateData(IpfixRecord::TemplateInfo* ti, IpfixRe
/**
* Buffer passed flow (containing fixed-value fields) in Hashtable @c ht
*/
void FlowHashtable::aggregateDataTemplateData(IpfixRecord::DataTemplateInfo* ti, IpfixRecord::Data* data)
void FlowHashtable::aggregateDataTemplateData(TemplateInfo* ti, IpfixRecord::Data* data)
{
DPRINTF("called");
@ -770,12 +770,12 @@ void FlowHashtable::aggregateDataTemplateData(IpfixRecord::DataTemplateInfo* ti,
memset(htdata.get()+fieldLength, 0, privDataLength);
for (i = 0; i < dataTemplate->fieldCount; i++) {
IpfixRecord::FieldInfo* hfi = &dataTemplate->fieldInfo[i];
TemplateInfo::FieldInfo* hfi = &dataTemplate->fieldInfo[i];
bool fieldFilled = false;
/* Copy from matching variable field, should it exist */
IpfixRecord::FieldInfo* tfi = ti->getFieldInfo(&hfi->type);
TemplateInfo::FieldInfo* tfi = ti->getFieldInfo(hfi->type);
if (tfi) {
// this path is normal for normal flow data records!
fieldFilled = true;
@ -822,7 +822,7 @@ void FlowHashtable::aggregateDataTemplateData(IpfixRecord::DataTemplateInfo* ti,
}
/* No matching variable field. Copy from matching fixed field, should it exist */
tfi = ti->getDataInfo(&hfi->type);
tfi = ti->getDataInfo(hfi->type);
if (tfi) {
fieldFilled = true;
copyData(hfi, htdata.get(), tfi, ti->data, fieldModifier[i]);

View File

@ -14,8 +14,8 @@ public:
uint16_t minBufferTime, uint16_t maxBufferTime, uint8_t hashbits);
virtual ~FlowHashtable();
void aggregateTemplateData(IpfixRecord::TemplateInfo* ti, IpfixRecord::Data* data);
void aggregateDataTemplateData(IpfixRecord::DataTemplateInfo* ti, IpfixRecord::Data* data);
void aggregateTemplateData(TemplateInfo* ti, IpfixRecord::Data* data);
void aggregateDataTemplateData(TemplateInfo* ti, IpfixRecord::Data* data);
private:
@ -30,7 +30,7 @@ private:
vector<uint32_t> flowReverseMapper;
char* switchArray; /**< used by function reverseFlowBucket as temporary storage */
int aggregateField(IpfixRecord::FieldInfo* basefi, IpfixRecord::FieldInfo* deltafi, IpfixRecord::Data* base,
int aggregateField(TemplateInfo::FieldInfo* basefi, TemplateInfo::FieldInfo* deltafi, IpfixRecord::Data* base,
IpfixRecord::Data* delta);
int aggregateFlow(IpfixRecord::Data* baseFlow, IpfixRecord::Data* flow, bool reverse);
uint32_t getHash(IpfixRecord::Data* data, bool reverse);
@ -39,13 +39,13 @@ private:
void bufferDataBlock(boost::shared_array<IpfixRecord::Data> data);
int equalRaw(InformationElement::IeInfo* data1Type, IpfixRecord::Data* data1,
InformationElement::IeInfo* data2Type, IpfixRecord::Data* data2);
void copyData(IpfixRecord::FieldInfo* dstFI, IpfixRecord::Data* dst,
IpfixRecord::FieldInfo* srcFI, IpfixRecord::Data* src, Rule::Field::Modifier modifier);
void copyData(TemplateInfo::FieldInfo* dstFI, IpfixRecord::Data* dst,
TemplateInfo::FieldInfo* srcFI, IpfixRecord::Data* src, Rule::Field::Modifier modifier);
void genBiflowStructs();
int compare4ByteField(IpfixRecord::Data* baseFlow, IpfixRecord::FieldInfo* baseFi,
IpfixRecord::Data* flow, IpfixRecord::FieldInfo* deltaFi);
int compare8ByteField(IpfixRecord::Data* baseFlow, IpfixRecord::FieldInfo* baseFi,
IpfixRecord::Data* flow, IpfixRecord::FieldInfo* deltaFi);
int compare4ByteField(IpfixRecord::Data* baseFlow, TemplateInfo::FieldInfo* baseFi,
IpfixRecord::Data* flow, TemplateInfo::FieldInfo* deltaFi);
int compare8ByteField(IpfixRecord::Data* baseFlow, TemplateInfo::FieldInfo* baseFi,
IpfixRecord::Data* flow, TemplateInfo::FieldInfo* deltaFi);
void mapReverseElement(uint32_t tid);
void reverseFlowBucket(HashtableBucket* bucket);
};

View File

@ -64,7 +64,7 @@ void IpfixAggregator::onDataRecord(IpfixDataRecord* record)
}
#endif
IpfixRecord::TemplateInfo* ti = record->templateInfo.get();
TemplateInfo* ti = record->templateInfo.get();
for (size_t i = 0; i < rules->count; i++) {
@ -96,12 +96,13 @@ void IpfixAggregator::onDataDataRecord(IpfixDataDataRecord* record)
}
#endif
TemplateInfo* ti = record->dataTemplateInfo.get();
mutex.lock();
for (size_t i = 0; i < rules->count; i++) {
if (rules->rule[i]->dataTemplateDataMatches(record->dataTemplateInfo.get(), record->data)) {
if (rules->rule[i]->dataTemplateDataMatches(ti, record->data)) {
DPRINTF("rule %d matches\n", i);
static_cast<FlowHashtable*>(rules->rule[i]->hashtable)->aggregateDataTemplateData(
record->dataTemplateInfo.get(), record->data);
static_cast<FlowHashtable*>(rules->rule[i]->hashtable)->aggregateDataTemplateData(ti, record->data);
}
}
mutex.unlock();

View File

@ -474,7 +474,7 @@ bool PacketHashtable::isRawPacketPtrVariable(const InformationElement::IeInfo& t
/**
* helper function for buildExpHelperTable
*/
void PacketHashtable::fillExpFieldData(ExpFieldData* efd, IpfixRecord::FieldInfo* hfi, Rule::Field::Modifier fieldModifier, uint16_t index)
void PacketHashtable::fillExpFieldData(ExpFieldData* efd, TemplateInfo::FieldInfo* hfi, Rule::Field::Modifier fieldModifier, uint16_t index)
{
efd->typeId = hfi->type.id;
efd->dstIndex = hfi->offset;
@ -519,7 +519,7 @@ void PacketHashtable::fillExpFieldData(ExpFieldData* efd, IpfixRecord::FieldInfo
if (efd->typeId==IPFIX_ETYPEID_frontPayload) {
*reinterpret_cast<uint32_t*>(efd->data) = 0xFFFFFFFF;
for (int i=0; i<dataTemplate->fieldCount; i++) {
IpfixRecord::FieldInfo* hfi = &dataTemplate->fieldInfo[i];
TemplateInfo::FieldInfo* hfi = &dataTemplate->fieldInfo[i];
if (hfi->type.id==IPFIX_ETYPEID_frontPayloadPktCount) {
*reinterpret_cast<uint32_t*>(efd->data) = hfi->offset;
}
@ -576,7 +576,7 @@ void PacketHashtable::buildExpHelperTable()
// at first, fill data structure with aggregatable fields
uint16_t efdIdx = 0;
for (int i=0; i<dataTemplate->fieldCount; i++) {
IpfixRecord::FieldInfo* hfi = &dataTemplate->fieldInfo[i];
TemplateInfo::FieldInfo* hfi = &dataTemplate->fieldInfo[i];
if (!typeAvailable(hfi->type)) {
THROWEXCEPTION("Type '%s' is not contained in raw packet. Please remove it from PacketAggregator rule.", typeid2string(hfi->type.id));
}
@ -588,7 +588,7 @@ void PacketHashtable::buildExpHelperTable()
// now the remaining fields
for (int i=0; i<dataTemplate->fieldCount; i++) {
IpfixRecord::FieldInfo* hfi = &dataTemplate->fieldInfo[i];
TemplateInfo::FieldInfo* hfi = &dataTemplate->fieldInfo[i];
if (isToBeAggregated(hfi->type)) continue;
ExpFieldData* efd = &expHelperTable.expFieldData[efdIdx++];
fillExpFieldData(efd, hfi, fieldModifier[i], efdIdx-1);

View File

@ -101,7 +101,7 @@ private:
static void copyDataDummy(IpfixRecord::Data* bucket, const IpfixRecord::Data* src, ExpFieldData* efd);
static void aggregateFrontPayload(IpfixRecord::Data* bucket, const Packet* src, const ExpFieldData* efd, bool firstpacket = false);
void (*getCopyDataFunction(const ExpFieldData* efd))(IpfixRecord::Data*, const IpfixRecord::Data*, ExpFieldData*);
void fillExpFieldData(ExpFieldData* efd, IpfixRecord::FieldInfo* hfi, Rule::Field::Modifier fieldModifier, uint16_t index);
void fillExpFieldData(ExpFieldData* efd, TemplateInfo::FieldInfo* hfi, Rule::Field::Modifier fieldModifier, uint16_t index);
uint32_t expCalculateHash(const IpfixRecord::Data* data);
boost::shared_array<IpfixRecord::Data> buildBucketData(const Packet* p);
void expAggregateField(const ExpFieldData* efd, IpfixRecord::Data* baseData, const IpfixRecord::Data* deltaData);

View File

@ -69,7 +69,8 @@ void Rule::initialize()
bool protocolid = false;
for (int i=0; i<fieldCount; i++) {
Rule::Field* f = field[i];
if (f->type.id==IPFIX_TYPEID_protocolIdentifier) protocolid = true;
if (f->type.enterprise == 0 && f->type.id == IPFIX_TYPEID_protocolIdentifier)
protocolid = true;
validProtocols = Packet::IPProtocolType(validProtocols & InformationElement::getValidProtocols(f->type));
}
// small exception: if protocol id is inside the template, we assume that all types of protocols are valid
@ -280,17 +281,17 @@ int matchesPattern(const InformationElement::IeInfo* dataType, const IpfixRecord
* we will also have to check if the flow's mask is no broader than the ruleField's
* @return 0 if the field had an associated mask that did not match
*/
int checkAssociatedMask(IpfixRecord::TemplateInfo* info, IpfixRecord::Data* data, Rule::Field* ruleField) {
if ((ruleField->type.id == IPFIX_TYPEID_sourceIPv4Address) && (ruleField->pattern) && (ruleField->type.length == 5)) {
IpfixRecord::FieldInfo* maskInfo = info->getFieldInfo(IPFIX_TYPEID_sourceIPv4Mask, 0);
int checkAssociatedMask(TemplateInfo* info, IpfixRecord::Data* data, Rule::Field* ruleField) {
if ((ruleField->type.enterprise == 0) && (ruleField->type.id == IPFIX_TYPEID_sourceIPv4Address) && (ruleField->pattern) && (ruleField->type.length == 5)) {
TemplateInfo::FieldInfo* maskInfo = info->getFieldInfo(IPFIX_TYPEID_sourceIPv4Mask, 0);
if (!maskInfo) return 1;
uint8_t pmask = 32 - getIPv4IMask(&ruleField->type, ruleField->pattern);
uint8_t dmask = *(data + maskInfo->offset);
return (dmask >= pmask);
}
if ((ruleField->type.id == IPFIX_TYPEID_destinationIPv4Address) && (ruleField->pattern) && (ruleField->type.length == 5)) {
IpfixRecord::FieldInfo* maskInfo = info->getFieldInfo(IPFIX_TYPEID_destinationIPv4Mask, 0);
if ((ruleField->type.enterprise == 0) && (ruleField->type.id == IPFIX_TYPEID_destinationIPv4Address) && (ruleField->pattern) && (ruleField->type.length == 5)) {
TemplateInfo::FieldInfo* maskInfo = info->getFieldInfo(IPFIX_TYPEID_destinationIPv4Mask, 0);
if (!maskInfo) return 1;
uint8_t pmask = 32 - getIPv4IMask(&ruleField->type, ruleField->pattern);
@ -300,31 +301,6 @@ int checkAssociatedMask(IpfixRecord::TemplateInfo* info, IpfixRecord::Data* data
return 1;
}
/**
* templateDataMatchesRule helper.
* If a flow's IP matched a ruleField's IP address + mask,
* we will also have to check if the flow's mask is no broader than the ruleField's
* @return 0 if the field had an associated mask that did not match
*/
int checkAssociatedMask2(IpfixRecord::DataTemplateInfo* info, IpfixRecord::Data* data, Rule::Field* ruleField) {
if ((ruleField->type.id == IPFIX_TYPEID_sourceIPv4Address) && (ruleField->pattern) && (ruleField->type.length == 5)) {
IpfixRecord::FieldInfo* maskInfo = info->getFieldInfo(IPFIX_TYPEID_sourceIPv4Mask, 0);
if (!maskInfo) return 1;
uint8_t pmask = 32 - getIPv4IMask(&ruleField->type, ruleField->pattern);
uint8_t dmask = *(data + maskInfo->offset);
return (dmask >= pmask);
}
if ((ruleField->type.id == IPFIX_TYPEID_destinationIPv4Address) && (ruleField->pattern) && (ruleField->type.length == 5)) {
IpfixRecord::FieldInfo* maskInfo = info->getFieldInfo(IPFIX_TYPEID_destinationIPv4Mask, 0);
if (!maskInfo) return 1;
uint8_t pmask = 32 - getIPv4IMask(&ruleField->type, ruleField->pattern);
uint8_t dmask = *(data + maskInfo->offset);
return (dmask >= pmask);
}
return 1;
}
/**
* templateDataMatchesRule helper.
@ -332,17 +308,17 @@ int checkAssociatedMask2(IpfixRecord::DataTemplateInfo* info, IpfixRecord::Data*
* we will also have to check if the flow's mask is no broader than the ruleField's
* @return 0 if the field had an associated mask that did not match
*/
int checkAssociatedMask3(IpfixRecord::DataTemplateInfo* info, IpfixRecord::Data* data, Rule::Field* ruleField) {
if ((ruleField->type.id == IPFIX_TYPEID_sourceIPv4Address) && (ruleField->pattern) && (ruleField->type.length == 5)) {
IpfixRecord::FieldInfo* maskInfo = info->getDataInfo(IPFIX_TYPEID_sourceIPv4Mask, 0);
int checkAssociatedMask3(TemplateInfo* info, IpfixRecord::Data* data, Rule::Field* ruleField) {
if ((ruleField->type.enterprise == 0) && (ruleField->type.id == IPFIX_TYPEID_sourceIPv4Address) && (ruleField->pattern) && (ruleField->type.length == 5)) {
TemplateInfo::FieldInfo* maskInfo = info->getDataInfo(IPFIX_TYPEID_sourceIPv4Mask, 0);
if (!maskInfo) return 1;
uint8_t pmask = 32 - getIPv4IMask(&ruleField->type, ruleField->pattern);
uint8_t dmask = *(data + maskInfo->offset);
return (dmask >= pmask);
}
if ((ruleField->type.id == IPFIX_TYPEID_destinationIPv4Address) && (ruleField->pattern) && (ruleField->type.length == 5)) {
IpfixRecord::FieldInfo* maskInfo = info->getDataInfo(IPFIX_TYPEID_destinationIPv4Mask, 0);
if ((ruleField->type.enterprise == 0) && (ruleField->type.id == IPFIX_TYPEID_destinationIPv4Address) && (ruleField->pattern) && (ruleField->type.length == 5)) {
TemplateInfo::FieldInfo* maskInfo = info->getDataInfo(IPFIX_TYPEID_destinationIPv4Mask, 0);
if (!maskInfo) return 1;
uint8_t pmask = 32 - getIPv4IMask(&ruleField->type, ruleField->pattern);
@ -356,16 +332,16 @@ int checkAssociatedMask3(IpfixRecord::DataTemplateInfo* info, IpfixRecord::Data*
* Checks if a given flow matches a rule
* @return 1 if rule is matched, 0 otherwise
*/
int Rule::templateDataMatches(IpfixRecord::TemplateInfo* info, IpfixRecord::Data* data) {
int Rule::templateDataMatches(TemplateInfo* info, IpfixRecord::Data* data) {
int i;
IpfixRecord::FieldInfo* fieldInfo;
TemplateInfo::FieldInfo* fieldInfo;
for (i = 0; i < fieldCount; i++) {
Rule::Field* ruleField = field[i];
/* for all patterns of this rule, check if they are matched */
if (field[i]->pattern) {
fieldInfo = info->getFieldInfo(&ruleField->type);
fieldInfo = info->getFieldInfo(ruleField->type);
if (fieldInfo) {
/* corresponding data field found, check if it matches. If it doesn't the whole rule cannot be matched */
if (!matchesPattern(&fieldInfo->type, (data + fieldInfo->offset), &ruleField->type, ruleField->pattern)) return 0;
@ -381,7 +357,7 @@ int Rule::templateDataMatches(IpfixRecord::TemplateInfo* info, IpfixRecord::Data
}
/* if a non-discarding rule field specifies no pattern, check at least if the data field exists */
else if (field[i]->modifier != Rule::Field::DISCARD) {
fieldInfo = info->getFieldInfo(&ruleField->type);
fieldInfo = info->getFieldInfo(ruleField->type);
if (fieldInfo) continue;
if (biflowAggregation && InformationElement::isBiflowField(ruleField->type)) return 1;
@ -417,7 +393,7 @@ bool Rule::ExptemplateDataMatches(const Packet* p)
switch (ruleField->type.id) {
case IPFIX_TYPEID_sourceIPv4Address:
{
IpfixRecord::FieldInfo fi;
TemplateInfo::FieldInfo fi;
fi.type.id = IPFIX_TYPEID_sourceIPv4Address;
fi.type.length = 4;
fi.offset = 12;
@ -436,7 +412,7 @@ bool Rule::ExptemplateDataMatches(const Packet* p)
}
case IPFIX_TYPEID_destinationIPv4Address:
{
IpfixRecord::FieldInfo fi;
TemplateInfo::FieldInfo fi;
fi.type.id = IPFIX_TYPEID_destinationIPv4Address;
fi.type.length = 4;
fi.offset = 16;
@ -456,7 +432,7 @@ bool Rule::ExptemplateDataMatches(const Packet* p)
}
case IPFIX_TYPEID_sourceTransportPort:
{
IpfixRecord::FieldInfo fi;
TemplateInfo::FieldInfo fi;
fi.type.id = IPFIX_TYPEID_sourceTransportPort;
fi.type.length = 2;
fi.offset = 0;
@ -466,7 +442,7 @@ bool Rule::ExptemplateDataMatches(const Packet* p)
}
case IPFIX_TYPEID_destinationTransportPort:
{
IpfixRecord::FieldInfo fi;
TemplateInfo::FieldInfo fi;
fi.type.id = IPFIX_TYPEID_destinationTransportPort;
fi.type.length = 2;
fi.offset = 2;
@ -491,9 +467,9 @@ bool Rule::ExptemplateDataMatches(const Packet* p)
* Checks if a given flow matches a rule
* @return 1 if rule is matched, 0 otherwise
*/
int Rule::dataTemplateDataMatches(IpfixRecord::DataTemplateInfo* info, IpfixRecord::Data* data) {
int Rule::dataTemplateDataMatches(TemplateInfo* info, IpfixRecord::Data* data) {
int i;
IpfixRecord::FieldInfo* fieldInfo;
TemplateInfo::FieldInfo* fieldInfo;
/* for all patterns of this rule, check if they are matched */
for(i = 0; i < fieldCount; i++) {
@ -501,11 +477,11 @@ int Rule::dataTemplateDataMatches(IpfixRecord::DataTemplateInfo* info, IpfixReco
if(field[i]->pattern) {
Rule::Field* ruleField = field[i];
fieldInfo = info->getFieldInfo(&ruleField->type);
fieldInfo = info->getFieldInfo(ruleField->type);
if (fieldInfo) {
/* corresponding data field found, check if it matches. If it doesn't the whole rule cannot be matched */
if (!matchesPattern(&fieldInfo->type, (data + fieldInfo->offset), &ruleField->type, ruleField->pattern)) return 0;
if (!checkAssociatedMask2(info, data, ruleField)) return 0;
if (!checkAssociatedMask(info, data, ruleField)) return 0;
continue;
}
@ -514,7 +490,7 @@ int Rule::dataTemplateDataMatches(IpfixRecord::DataTemplateInfo* info, IpfixReco
see if we find a corresponding fixed data field
*/
fieldInfo = info->getDataInfo(&ruleField->type);
fieldInfo = info->getDataInfo(ruleField->type);
if (fieldInfo) {
/* corresponding fixed data field found, check if it matches. If it doesn't the whole rule cannot be matched */
if (!matchesPattern(&fieldInfo->type, (info->data + fieldInfo->offset), &ruleField->type, ruleField->pattern)) return 0;

View File

@ -69,9 +69,9 @@ class Rule {
~Rule();
void initialize();
void print();
int templateDataMatches(IpfixRecord::TemplateInfo* info, IpfixRecord::Data* data);
int templateDataMatches(TemplateInfo* info, IpfixRecord::Data* data);
bool ExptemplateDataMatches(const Packet* p);
int dataTemplateDataMatches(IpfixRecord::DataTemplateInfo* info, IpfixRecord::Data* data);
int dataTemplateDataMatches(TemplateInfo* info, IpfixRecord::Data* data);
uint16_t id;
uint16_t preceding;

View File

@ -27,10 +27,6 @@ class TestSink : public IpfixRecordDestination {
{
}
virtual void onDataTemplate(IpfixDataTemplateRecord* record)
{
}
virtual void onDataRecord(IpfixDataRecord* record) {
uint8_t inSourceID = record->sourceID->exporterAddress.ip[0];
uint8_t inTemplateId = record->templateInfo->templateId - 256;
@ -88,11 +84,12 @@ boost::shared_array<uint8_t> createTestData(uint8_t magic_number) {
return testData;
}
boost::shared_ptr<IpfixRecord::TemplateInfo> createTestTemplate(uint8_t magic_number) {
boost::shared_ptr<IpfixRecord::TemplateInfo> testTemplate(new IpfixRecord::TemplateInfo);
boost::shared_ptr<TemplateInfo> createTestTemplate(uint8_t magic_number) {
boost::shared_ptr<TemplateInfo> testTemplate(new TemplateInfo);
testTemplate->templateId = magic_number + 256;
testTemplate->setId = TemplateInfo::IpfixTemplate;
testTemplate->fieldCount = 1;
testTemplate->fieldInfo = (IpfixRecord::FieldInfo*)malloc(testTemplate->fieldCount * sizeof(IpfixRecord::FieldInfo));
testTemplate->fieldInfo = (TemplateInfo::FieldInfo*)malloc(testTemplate->fieldCount * sizeof(TemplateInfo::FieldInfo));
testTemplate->fieldInfo[0].type.id = magic_number;
testTemplate->fieldInfo[0].type.length = 1;
testTemplate->fieldInfo[0].type.enterprise = 0;
@ -102,14 +99,15 @@ boost::shared_ptr<IpfixRecord::TemplateInfo> createTestTemplate(uint8_t magic_nu
return testTemplate;
}
boost::shared_ptr<IpfixRecord::DataTemplateInfo> createTestDataTemplate(uint8_t magic_number) {
boost::shared_ptr<IpfixRecord::DataTemplateInfo> testTemplate(new IpfixRecord::DataTemplateInfo);
boost::shared_ptr<TemplateInfo> createTestDataTemplate(uint8_t magic_number) {
boost::shared_ptr<TemplateInfo> testTemplate(new TemplateInfo);
testTemplate->templateId = magic_number + 256;
testTemplate->setId = TemplateInfo::IpfixDataTemplate;
testTemplate->preceding = 0;
testTemplate->fieldCount = 1;
testTemplate->fieldInfo = (IpfixRecord::FieldInfo*)malloc(testTemplate->fieldCount * sizeof(IpfixRecord::FieldInfo));
testTemplate->fieldInfo = (TemplateInfo::FieldInfo*)malloc(testTemplate->fieldCount * sizeof(TemplateInfo::FieldInfo));
testTemplate->dataCount = 1;
testTemplate->dataInfo = (IpfixRecord::FieldInfo*)malloc(testTemplate->fieldCount * sizeof(IpfixRecord::FieldInfo));
testTemplate->dataInfo = (TemplateInfo::FieldInfo*)malloc(testTemplate->fieldCount * sizeof(TemplateInfo::FieldInfo));
testTemplate->data = (uint8_t*)malloc(1); testTemplate->data[0] = magic_number;
testTemplate->fieldInfo[0].type.id = magic_number;
testTemplate->fieldInfo[0].type.length = 1;
@ -137,7 +135,7 @@ boost::shared_ptr<IpfixRecord::SourceID> createTestSourceId(uint8_t magic_number
}
IpfixDataRecord* createTestDataRecord(uint8_t magic_number, boost::shared_ptr<IpfixRecord::SourceID> sourceId, boost::shared_ptr<IpfixRecord::TemplateInfo> templateInfo) {
IpfixDataRecord* createTestDataRecord(uint8_t magic_number, boost::shared_ptr<IpfixRecord::SourceID> sourceId, boost::shared_ptr<TemplateInfo> templateInfo) {
static InstanceManager<IpfixDataRecord> im("IpfixDataRecord");
IpfixDataRecord* testRecord = im.getNewInstance();
testRecord->sourceID = sourceId;
@ -149,7 +147,7 @@ IpfixDataRecord* createTestDataRecord(uint8_t magic_number, boost::shared_ptr<Ip
return testRecord;
}
IpfixTemplateDestructionRecord* createTestTemplateDestructionRecord(uint8_t magic_number, boost::shared_ptr<IpfixRecord::TemplateInfo> templateInfo) {
IpfixTemplateDestructionRecord* createTestTemplateDestructionRecord(uint8_t magic_number, boost::shared_ptr<TemplateInfo> templateInfo) {
static InstanceManager<IpfixTemplateDestructionRecord> im("IpfixTemplateDestructionRecord");
IpfixTemplateDestructionRecord* testRecord = im.getNewInstance();
testRecord->templateInfo = templateInfo;
@ -157,7 +155,7 @@ IpfixTemplateDestructionRecord* createTestTemplateDestructionRecord(uint8_t magi
return testRecord;
}
IpfixDataDataRecord* createTestDataDataRecord(uint8_t magic_number, boost::shared_ptr<IpfixRecord::SourceID> sourceId, boost::shared_ptr<IpfixRecord::DataTemplateInfo> dataTemplateInfo) {
IpfixDataDataRecord* createTestDataDataRecord(uint8_t magic_number, boost::shared_ptr<IpfixRecord::SourceID> sourceId, boost::shared_ptr<TemplateInfo> dataTemplateInfo) {
static InstanceManager<IpfixDataDataRecord> im("IpfixDataDataRecord");
IpfixDataDataRecord* testRecord = im.getNewInstance();
testRecord->sourceID = sourceId;
@ -169,7 +167,7 @@ IpfixDataDataRecord* createTestDataDataRecord(uint8_t magic_number, boost::share
return testRecord;
}
IpfixTemplateRecord* createTestTemplateRecord(uint8_t magic_number, boost::shared_ptr<IpfixRecord::TemplateInfo> templateInfo) {
IpfixTemplateRecord* createTestTemplateRecord(uint8_t magic_number, boost::shared_ptr<TemplateInfo> templateInfo) {
static InstanceManager<IpfixTemplateRecord> im("IpfixTemplateRecord");
IpfixTemplateRecord* testRecord = im.getNewInstance();
testRecord->templateInfo = templateInfo;
@ -177,18 +175,18 @@ IpfixTemplateRecord* createTestTemplateRecord(uint8_t magic_number, boost::share
return testRecord;
}
IpfixDataTemplateRecord* createTestDataTemplateRecord(uint8_t magic_number, boost::shared_ptr<IpfixRecord::DataTemplateInfo> dataTemplateInfo) {
static InstanceManager<IpfixDataTemplateRecord> im("IpfixDataTemplateRecord");
IpfixDataTemplateRecord* testRecord = im.getNewInstance();
testRecord->dataTemplateInfo = dataTemplateInfo;
IpfixTemplateRecord* createTestDataTemplateRecord(uint8_t magic_number, boost::shared_ptr<TemplateInfo> dataTemplateInfo) {
static InstanceManager<IpfixTemplateRecord> im("IpfixDataTemplateRecord");
IpfixTemplateRecord* testRecord = im.getNewInstance();
testRecord->templateInfo = dataTemplateInfo;
return testRecord;
}
IpfixDataTemplateDestructionRecord* createTestDataTemplateDestructionRecord(uint8_t magic_number, boost::shared_ptr<IpfixRecord::DataTemplateInfo> dataTemplateInfo) {
static InstanceManager<IpfixDataTemplateDestructionRecord> im("IpfixDataTemplateDestructionRecord");
IpfixDataTemplateDestructionRecord* testRecord = im.getNewInstance();
testRecord->dataTemplateInfo = dataTemplateInfo;
IpfixTemplateDestructionRecord* createTestDataTemplateDestructionRecord(uint8_t magic_number, boost::shared_ptr<TemplateInfo> dataTemplateInfo) {
static InstanceManager<IpfixTemplateDestructionRecord> im("IpfixDataTemplateDestructionRecord");
IpfixTemplateDestructionRecord* testRecord = im.getNewInstance();
testRecord->templateInfo = dataTemplateInfo;
return testRecord;
}
@ -206,7 +204,7 @@ void test_module_coupling() {
std::vector<IpfixDataRecord*> testRecords;
for (uint8_t magic_number = 0; magic_number < 255; magic_number++) {
boost::shared_ptr<IpfixRecord::SourceID> testSourceId = createTestSourceId(magic_number);
boost::shared_ptr<IpfixRecord::TemplateInfo> templateInfo = createTestTemplate(magic_number);
boost::shared_ptr<TemplateInfo> templateInfo = createTestTemplate(magic_number);
IpfixTemplateRecord* dtr = createTestTemplateRecord(magic_number, templateInfo);
testSink.receive(dtr);
testRecords.push_back(createTestDataRecord(magic_number, testSourceId, templateInfo));
@ -265,8 +263,8 @@ void test_ipfixlolib_rawdir() {
std::vector<IpfixDataDataRecord*> testDataRecords;
for (uint8_t magic_number = 0; magic_number < 16; magic_number++) {
boost::shared_ptr<IpfixRecord::SourceID> testSourceId = createTestSourceId(magic_number);
boost::shared_ptr<IpfixRecord::DataTemplateInfo> dataTemplateInfo = createTestDataTemplate(magic_number);
IpfixDataTemplateRecord* dtr = createTestDataTemplateRecord(magic_number, dataTemplateInfo);
boost::shared_ptr<TemplateInfo> dataTemplateInfo = createTestDataTemplate(magic_number);
IpfixTemplateRecord* dtr = createTestDataTemplateRecord(magic_number, dataTemplateInfo);
ipfixRawdirWriter.receive(dtr);
testDataRecords.push_back(createTestDataDataRecord(magic_number, testSourceId, dataTemplateInfo));