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-8811b9f0742fmaster
parent
3ea294f6ff
commit
c81b3e79e1
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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++) {
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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_*/
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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);
|
||||
};
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
|
|
Loading…
Reference in New Issue