Commit cbf580cf authored by Håvard Moås's avatar Håvard Moås
Browse files

Update IPFIXLIB to add basic precise stddev/expval calculation of packet...

Update IPFIXLIB to add basic precise stddev/expval calculation of packet distance and packet lengths, havard.mork@gmail.com

git-svn-id: file:///home/svn/mapi/branches/haavardm-mapi@56 8d5bb341-7cf1-0310-8cf6-ba355fef3186
parent a5eef39b
......@@ -616,11 +616,16 @@ void addPktToHash(np_ctxt_t *npctxt,
if((bkt->proto == proto)
&& ((cmpIpAddress(bkt->src, src) && cmpIpAddress(bkt->dst, dst) && (bkt->sport == sport) && (bkt->dport == dport))
|| (cmpIpAddress(bkt->src, dst) && cmpIpAddress(bkt->dst, src) && (bkt->sport == dport) && (bkt->dport == sport)))) {
unsigned long ts_sec, ts_usec; // Distance from lasat packet
if(npctxt->histPktDistEnabled) {
/*
* Calculate time since last package. This is used both for
* calculating the packet-distance histogram, and calculating
* std.deviation for packet distance.
*/
if(npctxt->histPktDistEnabled || npctxt->pktDistLengthStddevs>0) {
unsigned long long ts;
unsigned long ts_sec, ts_usec;
unsigned int nslot;
if(bkt->lastSeenSent > bkt->lastSeenRcvd) {
ts = bkt->lastSeenSent;
......@@ -634,26 +639,27 @@ void addPktToHash(np_ctxt_t *npctxt,
// we only want to deal with the usec part.
ts = stamp-ts;
ts_sec = (ts>>32)&0xFFFFFFFFl;
ts_usec= (ts&0xFFFFFFFFl)/4295l;
nslot = PKTDIST_HISTOGRAM_SLOTS-1;
if(ts_sec==0l) { // ignore everything from 1sec and up
ts_usec= (ts&0xFFFFFFFFl)/4295l;
if(npctxt->histPktDistEnabled) {
unsigned int nslot = PKTDIST_HISTOGRAM_SLOTS-1;
int i;
nslot = PKTDIST_HISTOGRAM_SLOTS-1;
for(i=0; i<PKTDIST_HISTOGRAM_SLOTS; i++) {
if(ts_usec <= npctxt->histPktDistBucket[i]) {
nslot = i;
break;
}
}
//nslot = ts_usec/PKTDIST_HISTOGRAM_DISTR;
if(ts_sec==0l) { // ignore everything from 1sec and up
nslot = PKTDIST_HISTOGRAM_SLOTS-1;
for(i=0; i<PKTDIST_HISTOGRAM_SLOTS; i++) {
if(ts_usec <= npctxt->histPktDistBucket[i]) {
nslot = i;
break;
}
}
}
if(bkt->src.ipType.ipv4 == src.ipType.ipv4)
bkt->src2dstPktDistHistogram[nslot]++;
else
bkt->dst2srcPktDistHistogram[nslot]++;
}
//if(nslot >= PKTDIST_HISTOGRAM_SLOTS)
// nslot = PKTDIST_HISTOGRAM_SLOTS-1;
if(bkt->src.ipType.ipv4 == src.ipType.ipv4)
bkt->src2dstPktDistHistogram[nslot]++;
else
bkt->dst2srcPktDistHistogram[nslot]++;
}
......@@ -680,6 +686,14 @@ void addPktToHash(np_ctxt_t *npctxt,
else
bkt->optionsIPV6src2dst |= 0; // N/I
if(npctxt->pktDistLengthStddevs>0) {
bkt->src2dst_expval_pktdist_x = bkt->src2dst_expval_pktdist_x + ts_usec;
bkt->src2dst_expval_pktdist_x2 = bkt->src2dst_expval_pktdist_x2 + ts_usec*ts_usec;
bkt->src2dst_expval_pktlength_x = bkt->src2dst_expval_pktlength_x + len;
bkt->src2dst_expval_pktlength_x2= bkt->src2dst_expval_pktlength_x2+ len*len;
}
} else {
bkt->bytesRcvd += len, bkt->pktRcvd += numPkts;
if(bkt->firstSeenRcvd == 0)
......@@ -712,6 +726,14 @@ void addPktToHash(np_ctxt_t *npctxt,
else
bkt->dst2srcPktlenIpv6 = payloadLen;
}
if(npctxt->pktDistLengthStddevs>0) {
bkt->dst2src_expval_pktdist_x = bkt->dst2src_expval_pktdist_x + ts_usec;
bkt->dst2src_expval_pktdist_x2 = bkt->dst2src_expval_pktdist_x2 + ts_usec*ts_usec;
bkt->dst2src_expval_pktlength_x = bkt->dst2src_expval_pktlength_x + len;
bkt->dst2src_expval_pktlength_x2= bkt->dst2src_expval_pktlength_x2+ len*len;
}
}
pthread_mutex_unlock(&hashMutex[mutexIdx]);
......@@ -834,6 +856,17 @@ void addPktToHash(np_ctxt_t *npctxt,
//src2dstOctetTotalCount = len;
//dst2srcOctetTotalCount = 0;
if(npctxt->pktDistLengthStddevs>0) {
bkt->src2dst_expval_pktdist_x = 0;
bkt->src2dst_expval_pktdist_x2 = 0;
bkt->src2dst_expval_pktlength_x = 0;
bkt->src2dst_expval_pktlength_x2= 0;
bkt->dst2src_expval_pktdist_x = 0;
bkt->dst2src_expval_pktdist_x2 = 0;
bkt->dst2src_expval_pktlength_x = 0;
bkt->dst2src_expval_pktlength_x2= 0;
}
/* Calculate src2dst payload length (payload length for ipv6). Only first packet. */
bkt->src2dstPktlenIpv4 = 0;
......
......@@ -301,6 +301,8 @@ typedef struct {
u_int16_t histPktSizeBucket[PKTSZ_HISTOGRAM_SLOTS];
u_int16_t histPktDistBucket[PKTDIST_HISTOGRAM_SLOTS];
u_int8_t bitrateCalcEnabled; // Bitset, see BITRATECALC_* flags for options
uint8_t pktDistLengthStddevs;
// Exporter's addresses
uint32_t exporterIpv4Address; // in_addr
......
......@@ -1132,7 +1132,8 @@ npInitContext(void)
npctxt->histPktDistBucket[8] = 1000;
npctxt->histPktDistBucket[9] =0xFFFF;
npctxt->bitrateCalcEnabled = BITRATECALC_NONE;
npctxt->bitrateCalcEnabled = BITRATECALC_NONE;
npctxt->pktDistLengthStddevs = 0;
npctxt->numObservedFlows = 0;
......
......@@ -164,6 +164,17 @@ typedef struct hashBucket {
u_int64_t dst2srcOctetDeltaCount;
//u_int64_t src2dstOctetTotalCount;
//u_int64_t dst2srcOctetTotalCount;
u_int64_t src2dst_expval_pktdist_x;
u_int64_t src2dst_expval_pktdist_x2;
u_int64_t src2dst_expval_pktlength_x;
u_int64_t src2dst_expval_pktlength_x2;
u_int64_t dst2src_expval_pktdist_x;
u_int64_t dst2src_expval_pktdist_x2;
u_int64_t dst2src_expval_pktlength_x;
u_int64_t dst2src_expval_pktlength_x2;
} HashBucket;
......@@ -39,13 +39,18 @@
#define FID_HISTOGRAM_PKT_LNGTH 32769
#define FID_HISTOGRAM_PKT_DIST 32770
#define FID_PAYLOAD 32776
#define FID_RATE_1SEC_MAX 32780
#define FID_RATE_1SEC_MIN 32781
#define FID_RATE_100MS_MAX 32782
#define FID_RATE_100MS_MIN 32783
#define FID_RATE_10MS_MAX 32784
#define FID_RATE_10MS_MIN 32785
#define FID_PAYLOAD 32776
#define FID_STDDEV_PKT_DIST 32790
#define FID_EXPVAL_PKT_DIST 32791
#define FID_STDDEV_PKT_LENGTH 32792
#define FID_EXPVAL_PKT_LENGTH 32793
#ifndef __KERNEL__
......@@ -764,13 +769,19 @@ static V9TemplateId ver9_templates[] = {
// Note that 32768 is reserved (ent.mark = 1, ent.id = 0)
{ FID_HISTOGRAM_PKT_LNGTH, PKTSZ_HISTOGRAM_SLOTS*sizeof(u_int8_t), "HISTOGRAM_PKT_LNGTH" },
{ FID_HISTOGRAM_PKT_DIST, PKTDIST_HISTOGRAM_SLOTS*sizeof(u_int8_t), "HISTOGRAM_PKT_DIST" },
{ FID_PAYLOAD, PAYLOAD_EXCERPT_MAX, "PAYLOAD" },
{ FID_RATE_1SEC_MAX, 4, "MAXRATE_1SEC" },
{ FID_RATE_1SEC_MIN, 4, "MINRATE_1SEC" },
{ FID_RATE_100MS_MAX, 4, "MAXRATE_100MS" },
{ FID_RATE_100MS_MIN, 4, "MINRATE_100MS" },
{ FID_RATE_10MS_MAX, 4, "MAXRATE_10MS" },
{ FID_RATE_10MS_MIN, 4, "MINRATE_10MS" },
{ FID_PAYLOAD, PAYLOAD_EXCERPT_MAX, "PAYLOAD" },
{ FID_STDDEV_PKT_DIST, 4, "STDDEV_PKT_DIST" }, // returns float-32
{ FID_EXPVAL_PKT_DIST, 4, "EXPVAL_PKT_DIST" }, // returns float-32
{ FID_STDDEV_PKT_LENGTH,4, "STDDEV_PKT_LENGTH" }, // returns float-32
{ FID_EXPVAL_PKT_LENGTH,4, "EXPVAL_PKT_LENGTH" }, // returns float-32
{ 0, 0, NULL }
};
......@@ -815,6 +826,16 @@ static void copyInt64(u_int64_t _t64, char *outBuffer, u_int *outBufferBegin, u_
}
}
static void copyFloat(float _f, char *outBuffer, u_int *outBufferBegin, u_int *outBufferMax) {
void *_t32 = &_f;
u_int32_t t32 = htonl(*(u_int32_t *)_t32);
if((*outBufferBegin)+sizeof(t32) < (*outBufferMax)) {
memcpy(&outBuffer[(*outBufferBegin)], &t32, sizeof(t32));
(*outBufferBegin) += sizeof(t32);
}
}
/* static void copyInt32Array(u_int32_t *_t32a, char *outBuffer, u_int *outBufferBegin, u_int *outBufferMax, u_int nelements) {
u_int i;
......@@ -1367,6 +1388,49 @@ static void handleTemplate(np_ctxt_t *npctxt, V9TemplateId *theTemplate,
case FID_PAYLOAD:
exportPayload(npctxt, theFlow, direction, theTemplate,
outBuffer, outBufferBegin, outBufferMax);
case FID_STDDEV_PKT_DIST:
{
float f;
if(direction==0)
f = (float)(theFlow->src2dst_expval_pktdist_x2/(u_int64_t)theFlow->pktSent -
theFlow->src2dst_expval_pktdist_x/(u_int64_t)theFlow->pktSent);
else
f = (float)(theFlow->dst2src_expval_pktdist_x2/(u_int64_t)theFlow->pktRcvd -
theFlow->dst2src_expval_pktdist_x/(u_int64_t)theFlow->pktRcvd);
copyFloat(f, outBuffer,outBufferBegin, outBufferMax);
}
break;
case FID_EXPVAL_PKT_DIST:
{
float f;
if(direction==0)
f = (float)(theFlow->src2dst_expval_pktdist_x/(u_int64_t)theFlow->pktSent);
else
f = (float)(theFlow->dst2src_expval_pktdist_x/(u_int64_t)theFlow->pktRcvd);
copyFloat(f, outBuffer,outBufferBegin,outBufferMax);
}
break;
case FID_STDDEV_PKT_LENGTH:
{
float f;
if(direction==0)
f = (float)(theFlow->src2dst_expval_pktlength_x2/(u_int64_t)theFlow->pktSent -
theFlow->src2dst_expval_pktlength_x/(u_int64_t)theFlow->pktSent);
else
f = (float)(theFlow->dst2src_expval_pktlength_x2/(u_int64_t)theFlow->pktRcvd -
theFlow->dst2src_expval_pktlength_x/(u_int64_t)theFlow->pktRcvd);
copyFloat(f, outBuffer,outBufferBegin,outBufferMax);
}
break;
case FID_EXPVAL_PKT_LENGTH:
{
float f;
if(direction==0)
f = (float)(theFlow->src2dst_expval_pktlength_x/(u_int64_t)theFlow->pktSent);
else
f = (float)(theFlow->dst2src_expval_pktlength_x/(u_int64_t)theFlow->pktRcvd);
copyFloat(f, outBuffer,outBufferBegin,outBufferMax);
}
break;
}
}
......@@ -1423,6 +1487,13 @@ turnOnSpecialProcessing(np_ctxt_t *npctxt, u_int element) {
case FID_RATE_10MS_MIN:
npctxt->bitrateCalcEnabled |= BITRATECALC_10MS;
break;
case FID_STDDEV_PKT_DIST:
case FID_EXPVAL_PKT_DIST:
case FID_STDDEV_PKT_LENGTH:
case FID_EXPVAL_PKT_LENGTH:
npctxt->pktDistLengthStddevs = 1;
break;
}
return;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment