uint64_t IpfixCsExporter::retrieveTime(IpfixDataRecord* record, InformationElement::IeId id1, InformationElement::IeId id2, InformationElement::IeId id3, InformationElement::IeEnterpriseNumber pen) { uint64_t rettime; TemplateInfo::FieldInfo* fi = record->templateInfo->getFieldInfo(id1, pen); if (fi != 0) { convertNtp64(*(uint64_t*)(record->data + fi->offset), rettime); } else { fi = record->templateInfo->getFieldInfo(id2, pen); if (fi != 0) { rettime = ntohll(*(uint64_t*)(record->data + fi->offset)); } else { fi = record->templateInfo->getFieldInfo(id3, pen); if (fi != 0) { rettime = ntohl(*(uint32_t*)(record->data + fi->offset)); rettime *= 1000; } else { rettime = 0; } } } return rettime; }
void PythonFlowAnalyzer::onDataRecord(IpfixDataRecord* record) { // only treat non-Options Data Records (although we cannot be sure that there is a Flow inside) if((record->templateInfo->setId != TemplateInfo::NetflowTemplate) && (record->templateInfo->setId != TemplateInfo::IpfixTemplate) && (record->templateInfo->setId != TemplateInfo::IpfixDataTemplate)) { record->removeReference(); return; } Connection conn(record); enum TimeIdentifier { NONE = 1, SEC = 1, mSEC = 2, nSEC = 3 }; TimeIdentifier flowstart = NONE; TimeIdentifier flowend = NONE; TimeIdentifier revflowstart = NONE; TimeIdentifier revflowend = NONE; PyObject* pydict = PyDict_New(); for (uint32_t i = 0; i < record->templateInfo->fieldCount; i++) { TemplateInfo::FieldInfo* fi = &record->templateInfo->fieldInfo[i]; if (fi->type.enterprise==0) { uint64_t time; switch (fi->type.id) { // TODO: call Py_DECREF for each passed value to PyDict_SetItemString case IPFIX_TYPEID_sourceIPv4Address: PyDict_SetItemString(pydict, "sourceIPv4Address", PyLong_FromLong(ntohl(*(uint32_t*)(record->data + fi->offset)))); break; case IPFIX_TYPEID_destinationIPv4Address: PyDict_SetItemString(pydict, "destinationIPv4Address", PyLong_FromLong(ntohl(*(uint32_t*)(record->data + fi->offset)))); break; case IPFIX_TYPEID_sourceTransportPort: PyDict_SetItemString(pydict, "sourceTransportPort", PyLong_FromLong(ntohs(*(uint16_t*)(record->data + fi->offset)))); break; case IPFIX_TYPEID_destinationTransportPort: PyDict_SetItemString(pydict, "destinationTransportPort", PyLong_FromLong(ntohs(*(uint16_t*)(record->data + fi->offset)))); break; case IPFIX_TYPEID_protocolIdentifier: PyDict_SetItemString(pydict, "protocolIdentifier", PyLong_FromLong(*(uint8_t*)(record->data + fi->offset))); break; case IPFIX_TYPEID_flowStartNanoSeconds: flowstart = nSEC; convertNtp64(*(uint64_t*)(record->data + fi->offset), time); PyDict_SetItemString(pydict, "flowStartMilliSeconds", PyLong_FromUnsignedLongLong(time)); break; case IPFIX_TYPEID_flowStartMilliSeconds: if (flowstart>=mSEC) break; flowstart = mSEC; PyDict_SetItemString(pydict, "flowStartMilliSeconds", PyLong_FromUnsignedLongLong(ntohll(*(uint64_t*)(record->data + fi->offset)))); break; case IPFIX_TYPEID_flowStartSeconds: if (flowstart>=SEC) break; flowstart = SEC; PyDict_SetItemString(pydict, "flowStartMilliSeconds", PyLong_FromLong(ntohl(*(uint32_t*)(record->data + fi->offset)))); break; case IPFIX_TYPEID_flowEndNanoSeconds: flowend = nSEC; convertNtp64(*(uint64_t*)(record->data + fi->offset), time); PyDict_SetItemString(pydict, "flowEndMilliSeconds", PyLong_FromUnsignedLongLong(time)); break; case IPFIX_TYPEID_flowEndMilliSeconds: if (flowend>=mSEC) break; flowend = mSEC; PyDict_SetItemString(pydict, "flowEndMilliSeconds", PyLong_FromUnsignedLongLong(ntohll(*(uint64_t*)(record->data + fi->offset)))); break; case IPFIX_TYPEID_flowEndSeconds: if (flowend>=SEC) break; flowend = SEC; PyDict_SetItemString(pydict, "flowEndMilliSeconds", PyLong_FromLong(ntohl(*(uint32_t*)(record->data + fi->offset)))); break; } } else if (fi->type.enterprise==IPFIX_PEN_reverse) { uint64_t time; switch (fi->type.id) { case IPFIX_TYPEID_flowStartNanoSeconds: revflowstart = nSEC; convertNtp64(*(uint64_t*)(record->data + fi->offset), time); PyDict_SetItemString(pydict, "revFlowStartMilliSeconds", PyLong_FromUnsignedLongLong(time)); break; case IPFIX_TYPEID_flowStartMilliSeconds: if (revflowstart>=mSEC) break; revflowstart = mSEC; PyDict_SetItemString(pydict, "revFlowStartMilliSeconds", PyLong_FromUnsignedLongLong(ntohll(*(uint64_t*)(record->data + fi->offset)))); break; case IPFIX_TYPEID_flowStartSeconds: if (revflowstart>=SEC) break; revflowstart = SEC; PyDict_SetItemString(pydict, "revFlowStartMilliSeconds", PyLong_FromLong(ntohl(*(uint32_t*)(record->data + fi->offset)))); break; case IPFIX_TYPEID_flowEndNanoSeconds: revflowend = nSEC; convertNtp64(*(uint64_t*)(record->data + fi->offset), time); PyDict_SetItemString(pydict, "revFlowEndMilliSeconds", PyLong_FromUnsignedLongLong(time)); break; case IPFIX_TYPEID_flowEndMilliSeconds: if (revflowend>=mSEC) break; revflowend = mSEC; PyDict_SetItemString(pydict, "revFlowEndMilliSeconds", PyLong_FromUnsignedLongLong(ntohll(*(uint64_t*)(record->data + fi->offset)))); break; case IPFIX_TYPEID_flowEndSeconds: if (revflowend>=SEC) break; revflowend = SEC; PyDict_SetItemString(pydict, "revFlowEndMilliSeconds", PyLong_FromLong(ntohl(*(uint32_t*)(record->data + fi->offset)))); break; } } } /*char buf[100]; snprintf(buf, ARRAY_SIZE(buf), "FlowRecord(%u, %u, %u, %u)\n", ntohl(conn.srcIP), ntohl(conn.dstIP), ntohs(conn.srcPort), ntohs(conn.dstPort)); PyObject* fr = PyRun_String(buf, Py_eval_input, pyDict, pyDict); if (!fr) { PyErr_Print(); THROWEXCEPTION("PythonFlowAnalyzer: failed to execute given Python code, function 'onDataRecord' not found"); }*/ PyObject* t = PyTuple_New(1); PyTuple_SetItem(t, 0, pydict); PyObject* instance = PyObject_CallObject(pyClass, t); if (!instance) { PyErr_Print(); THROWEXCEPTION("PythonFlowAnalyzer: failed to instantiate class 'FlowRecord'"); } Py_DECREF(t); t = PyTuple_New(1); PyTuple_SetItem(t, 0, instance); PyObject* r = PyObject_CallObject(pyFunc, t); if (!r) { PyErr_Print(); THROWEXCEPTION("PythonFlowAnalyzer: failed to execute function 'onDataRecord'"); } Py_DECREF(t); Py_DECREF(r); record->removeReference(); }
/** * creates new connection element * and initializes values with given IPFIX record * NOTE: all values are *copied*, no reference will be kept to original IPFIX record * @param connTimeout time in seconds when connection element times out */ Connection::Connection(IpfixDataDataRecord* record) : srcOctets(0), dstOctets(0), srcPackets(0), dstPackets(0), srcTcpControlBits(0), dstTcpControlBits(0), srcPayload(0), srcPayloadLen(0), dstPayload(0), dstPayloadLen(0) { // convert IpfixDataDataRecord to Connection IpfixRecord::FieldInfo* fi = record->dataTemplateInfo->getFieldInfo(IPFIX_TYPEID_sourceIPv4Address, 0); if (fi != 0) { srcIP = *(uint32_t*)(record->data + fi->offset); } else { msg(MSG_INFO, "failed to determine source ip for record, assuming 0.0.0.0"); srcIP = 0; } fi = record->dataTemplateInfo->getFieldInfo(IPFIX_TYPEID_destinationIPv4Address, 0); if (fi != 0) { dstIP = *(uint32_t*)(record->data + fi->offset); } else { msg(MSG_INFO, "failed to determine destination ip for record, assuming 0.0.0.0"); dstIP = 0; } fi = record->dataTemplateInfo->getFieldInfo(IPFIX_TYPEID_sourceTransportPort, 0); if (fi != 0) { srcPort = *(uint16_t*)(record->data + fi->offset); } else { msg(MSG_INFO, "failed to determine source port for record, assuming 0"); srcPort = 0; } fi = record->dataTemplateInfo->getFieldInfo(IPFIX_TYPEID_destinationTransportPort, 0); if (fi != 0) { dstPort = *(uint16_t*)(record->data + fi->offset); } else { msg(MSG_INFO, "failed to determine destination port for record, assuming 0"); srcPort = 0; } fi = record->dataTemplateInfo->getFieldInfo(IPFIX_TYPEID_protocolIdentifier, 0); if (fi != 0) { protocol = *(uint8_t*)(record->data + fi->offset); } else { msg(MSG_INFO, "failed to determine protocol for record, using 0"); protocol = 0; } fi = record->dataTemplateInfo->getFieldInfo(IPFIX_TYPEID_flowStartNanoSeconds, 0); if (fi != 0) { convertNtp64(*(uint64_t*)(record->data + fi->offset), srcTimeStart); } else { fi = record->dataTemplateInfo->getFieldInfo(IPFIX_TYPEID_flowStartMilliSeconds, 0); if (fi != 0) { srcTimeStart = ntohll(*(uint64_t*)(record->data + fi->offset)); } else { fi = record->dataTemplateInfo->getFieldInfo(IPFIX_TYPEID_flowStartSeconds, 0); if (fi != 0) { srcTimeStart = ntohl(*(uint32_t*)(record->data + fi->offset)); srcTimeStart *= 1000; } else { srcTimeStart = 0; } } } fi = record->dataTemplateInfo->getFieldInfo(IPFIX_TYPEID_flowEndNanoSeconds, 0); if (fi != 0) { convertNtp64(*(uint64_t*)(record->data + fi->offset), srcTimeEnd); } else { fi = record->dataTemplateInfo->getFieldInfo(IPFIX_TYPEID_flowEndMilliSeconds, 0); if (fi != 0) { srcTimeEnd = ntohll(*(uint64_t*)(record->data + fi->offset)); } else { fi = record->dataTemplateInfo->getFieldInfo(IPFIX_TYPEID_flowEndSeconds, 0); if (fi != 0) { srcTimeEnd = ntohl(*(uint32_t*)(record->data + fi->offset)); srcTimeEnd *= 1000; } else { srcTimeEnd = 0; } } } fi = record->dataTemplateInfo->getFieldInfo(IPFIX_ETYPEID_revFlowStartNanoSeconds, 0); if (fi != 0) { convertNtp64(*(uint64_t*)(record->data + fi->offset), dstTimeStart); } else { fi = record->dataTemplateInfo->getFieldInfo(IPFIX_ETYPEID_revFlowStartMilliSeconds, 0); if (fi != 0) { dstTimeStart = ntohll(*(uint64_t*)(record->data + fi->offset)); } else { fi = record->dataTemplateInfo->getFieldInfo(IPFIX_ETYPEID_revFlowStartSeconds, 0); if (fi != 0) { dstTimeStart = ntohl(*(uint32_t*)(record->data + fi->offset)); dstTimeStart *= 1000; } else { dstTimeStart = 0; } } } fi = record->dataTemplateInfo->getFieldInfo(IPFIX_ETYPEID_revFlowEndNanoSeconds, 0); if (fi != 0) { convertNtp64(*(uint64_t*)(record->data + fi->offset), dstTimeEnd); } else { fi = record->dataTemplateInfo->getFieldInfo(IPFIX_ETYPEID_revFlowEndMilliSeconds, 0); if (fi != 0) { dstTimeEnd = ntohll(*(uint64_t*)(record->data + fi->offset)); } else { fi = record->dataTemplateInfo->getFieldInfo(IPFIX_ETYPEID_revFlowEndSeconds, 0); if (fi != 0) { dstTimeEnd = ntohl(*(uint32_t*)(record->data + fi->offset)); dstTimeEnd *= 1000; } else { dstTimeEnd = 0; } } } fi = record->dataTemplateInfo->getFieldInfo(IPFIX_TYPEID_octetDeltaCount, 0); if (fi != 0) srcOctets = *(uint64_t*)(record->data + fi->offset); fi = record->dataTemplateInfo->getFieldInfo(IPFIX_ETYPEID_revOctetDeltaCount, 0); if (fi != 0) dstOctets = *(uint64_t*)(record->data + fi->offset); fi = record->dataTemplateInfo->getFieldInfo(IPFIX_TYPEID_packetDeltaCount, 0); if (fi != 0) srcPackets = *(uint64_t*)(record->data + fi->offset); fi = record->dataTemplateInfo->getFieldInfo(IPFIX_ETYPEID_revPacketDeltaCount, 0); if (fi != 0) dstPackets = *(uint64_t*)(record->data + fi->offset); fi = record->dataTemplateInfo->getFieldInfo(IPFIX_TYPEID_tcpControlBits, 0); if (fi != 0) srcTcpControlBits = *(uint8_t*)(record->data + fi->offset); fi = record->dataTemplateInfo->getFieldInfo(IPFIX_ETYPEID_revTcpControlBits, 0); 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); if (filen != 0) srcPayloadLen = ntohl(*(uint32_t*)(record->data + filen->offset)); else srcPayloadLen = fi->type.length; srcPayload = new char[srcPayloadLen]; memcpy(srcPayload, record->data + fi->offset, srcPayloadLen); } fi = record->dataTemplateInfo->getFieldInfo(IPFIX_ETYPEID_revFrontPayload, 0); if (fi != 0 && fi->type.length) { IpfixRecord::FieldInfo* filen = record->dataTemplateInfo->getFieldInfo(IPFIX_ETYPEID_revFrontPayloadLen, 0); if (filen != 0) dstPayloadLen = ntohl(*(uint32_t*)(record->data + filen->offset)); else dstPayloadLen = fi->type.length; dstPayload = new char[dstPayloadLen]; memcpy(dstPayload, record->data + fi->offset, dstPayloadLen); } }