void increment_tcp_counters( rwRec *rwrec, event_metrics_t *metrics) { if (!(rwRecGetFlags(rwrec) & ACK_FLAG)) { metrics->flows_noack++; } if (rwRecGetPkts(rwrec) < SMALL_PKT_CUTOFF) { metrics->flows_small++; } if ((rwRecGetBytes(rwrec) / rwRecGetPkts(rwrec)) > PACKET_PAYLOAD_CUTOFF) { metrics->flows_with_payload++; } if (rwRecGetFlags(rwrec) == RST_FLAG || rwRecGetFlags(rwrec) == (SYN_FLAG | ACK_FLAG) || rwRecGetFlags(rwrec) == (RST_FLAG | ACK_FLAG)) { metrics->flows_backscatter++; } add_count(metrics->tcp_flag_counts, rwRecGetFlags(rwrec), RWSCAN_MAX_FLAGS); }
static skplugin_err_t addRecToBinAgg( const rwRec *rwrec, uint8_t *dest, void *idx, void UNUSED(**extra)) { uint64_t val[2]; switch (*((unsigned int*)(idx))) { case PAYLOAD_BYTES_AGG: memcpy(val, dest, sizeof(uint64_t)); val[0] += getPayload(rwrec); memcpy(dest, val, sizeof(uint64_t)); return SKPLUGIN_OK; case PAYLOAD_RATE_AGG: memcpy(val, dest, RATE_BINARY_SIZE_AGG); val[0] += getPayload(rwrec); val[1] += RWREC_MICRO_DURATION(rwrec); memcpy(dest, val, RATE_BINARY_SIZE_AGG); return SKPLUGIN_OK; case PCKTS_PER_SEC_AGG: memcpy(val, dest, RATE_BINARY_SIZE_AGG); val[0] += rwRecGetPkts(rwrec); val[1] += RWREC_MICRO_DURATION(rwrec); memcpy(dest, val, RATE_BINARY_SIZE_AGG); return SKPLUGIN_OK; case BYTES_PER_SEC_AGG: memcpy(val, dest, RATE_BINARY_SIZE_AGG); val[0] += rwRecGetBytes(rwrec); val[1] += RWREC_MICRO_DURATION(rwrec); memcpy(dest, val, RATE_BINARY_SIZE_AGG); return SKPLUGIN_OK; case BYTES_PER_PACKET_AGG: memcpy(val, dest, RATE_BINARY_SIZE_AGG); val[0] += rwRecGetBytes(rwrec); val[1] += rwRecGetPkts(rwrec); memcpy(dest, val, RATE_BINARY_SIZE_AGG); return SKPLUGIN_OK; } return SKPLUGIN_ERR_FATAL; }
/* * payload = getPayload(rwrec); * * Compute the bytes of payload contained in 'rwrec' by multiplying * the number of packets by the packet overhead and subtracting * that from the byte count. Return 0 if that value would be * negative. * * This function assumes minimal packet headers---that is, there * are no options in the packets. For TCP, assumes there are no * TCP timestamps in the packet. The returned value will be the * maximum possible bytes of payload. */ static uint64_t getPayload( const rwRec *rwrec) { uint64_t overhead; #if SK_ENABLE_IPV6 if (rwRecIsIPv6(rwrec)) { /* IPv6 IP-header header with no options is 40 bytes */ switch (rwRecGetProto(rwrec)) { case IPPROTO_TCP: /* TCP header is 20 (no TCP timestamps) */ overhead = rwRecGetPkts(rwrec) * 60; break; case IPPROTO_UDP: /* UDP header is 8 bytes */ overhead = rwRecGetPkts(rwrec) * 48; break; default: overhead = rwRecGetPkts(rwrec) * 40; break; } } else #endif /* SK_ENABLE_IPV6 */ { /* IPv4 IP-header header with no options is 20 bytes */ switch (rwRecGetProto(rwrec)) { case IPPROTO_TCP: overhead = rwRecGetPkts(rwrec) * 40; break; case IPPROTO_UDP: overhead = rwRecGetPkts(rwrec) * 28; break; default: overhead = rwRecGetPkts(rwrec) * 20; break; } } if (overhead > rwRecGetBytes(rwrec)) { return 0; } return (rwRecGetBytes(rwrec) - overhead); }
/* * Pack the record 'rwrec' into an array of bytes 'ar' */ static int ipv6routingioRecordPack_V3( skstream_t *stream, const rwRec *rwrec, uint8_t *ar) { uint32_t u32; uint64_t u64; rwRecMemGetStartTime(rwrec, &ar[0]); rwRecMemGetElapsed(rwrec, &ar[8]); rwRecMemGetSPort(rwrec, &ar[12]); rwRecMemGetDPort(rwrec, &ar[14]); rwRecMemGetProto(rwrec, &ar[16]); rwRecMemGetFlowType(rwrec, &ar[17]); rwRecMemGetSensor(rwrec, &ar[18]); rwRecMemGetFlags(rwrec, &ar[20]); rwRecMemGetInitFlags(rwrec, &ar[21]); rwRecMemGetRestFlags(rwrec, &ar[22]); rwRecMemGetTcpState(rwrec, &ar[23]); rwRecMemGetApplication(rwrec, &ar[24]); rwRecMemGetMemo(rwrec, &ar[26]); u32 = rwRecGetInput(rwrec); memcpy(&ar[28], &u32, sizeof(u32)); u64 = rwRecGetPkts(rwrec); memcpy(&ar[32], &u64, sizeof(u64)); u64 = rwRecGetBytes(rwrec); memcpy(&ar[40], &u64, sizeof(u64)); u32 = rwRecGetOutput(rwrec); memcpy(&ar[96], &u32, sizeof(u32)); if (rwRecIsIPv6(rwrec)) { /* Record is IPv6 */ #if !SK_ENABLE_IPV6 return SKSTREAM_ERR_UNSUPPORT_IPV6; #else ar[23] |= 0x80; rwRecMemGetSIPv6(rwrec, &ar[48]); rwRecMemGetDIPv6(rwrec, &ar[64]); rwRecMemGetNhIPv6(rwrec, &ar[80]); #endif /* SK_ENABLE_IPV6 */ } else { /* Record is IPv4, but encode as IPv6 */ uint32_t ip; /* sIP */ ip = htonl(rwRecGetSIPv4(rwrec)); memcpy(&ar[48], IP4in6_prefix, sizeof(IP4in6_prefix)); memcpy(&ar[60], &ip, sizeof(ip)); /* dIP */ ip = htonl(rwRecGetDIPv4(rwrec)); memcpy(&ar[64], IP4in6_prefix, sizeof(IP4in6_prefix)); memcpy(&ar[76], &ip, sizeof(ip)); /* nhIP */ ip = htonl(rwRecGetNhIPv4(rwrec)); memcpy(&ar[80], IP4in6_prefix, sizeof(IP4in6_prefix)); memcpy(&ar[92], &ip, sizeof(ip)); } /* swap if required */ if (stream->swapFlag) { ipv6routingioRecordSwap_V3(ar); } return SKSTREAM_OK; }
/* * Process a single input stream (file) of SiLK Flow records: Copy * the header entries from the input stream to the output stream, * read the file, fill a Key and Counter for each flow record, and * add the Key and Counter to the AggBag. */ static int processFile( skstream_t *stream) { sk_aggbag_field_t k_it; sk_aggbag_field_t c_it; sk_aggbag_aggregate_t key; sk_aggbag_aggregate_t counter; skipaddr_t ip; rwRec rwrec; ssize_t rv; ssize_t err; /* copy invocation and notes (annotations) from the SiLK Flow * files to the output stream; these headers will not be written * to the output if --invocation-strip or --notes-strip was * specified. */ rv = skHeaderCopyEntries(skStreamGetSilkHeader(output), skStreamGetSilkHeader(stream), SK_HENTRY_INVOCATION_ID); if (rv) { skStreamPrintLastErr(output, rv, &skAppPrintErr); } rv = skHeaderCopyEntries(skStreamGetSilkHeader(output), skStreamGetSilkHeader(stream), SK_HENTRY_ANNOTATION_ID); if (rv) { skStreamPrintLastErr(output, rv, &skAppPrintErr); } err = SKAGGBAG_OK; while (SKSTREAM_OK == (rv = skStreamReadRecord(stream, &rwrec))) { skAggBagInitializeKey(ab, &key, &k_it); do { switch (skAggBagFieldIterGetType(&k_it)) { case SKAGGBAG_FIELD_SIPv6: case SKAGGBAG_FIELD_SIPv4: rwRecMemGetSIP(&rwrec, &ip); skAggBagAggregateSetIPAddress(&key, &k_it, &ip); break; case SKAGGBAG_FIELD_DIPv6: case SKAGGBAG_FIELD_DIPv4: rwRecMemGetDIP(&rwrec, &ip); skAggBagAggregateSetIPAddress(&key, &k_it, &ip); break; case SKAGGBAG_FIELD_NHIPv6: case SKAGGBAG_FIELD_NHIPv4: rwRecMemGetNhIP(&rwrec, &ip); skAggBagAggregateSetIPAddress(&key, &k_it, &ip); break; case SKAGGBAG_FIELD_SPORT: skAggBagAggregateSetUnsigned( &key, &k_it, rwRecGetSPort(&rwrec)); break; case SKAGGBAG_FIELD_DPORT: skAggBagAggregateSetUnsigned( &key, &k_it, rwRecGetDPort(&rwrec)); break; case SKAGGBAG_FIELD_ICMP_TYPE: skAggBagAggregateSetUnsigned( &key, &k_it, (rwRecIsICMP(&rwrec) ? rwRecGetIcmpType(&rwrec) : 0)); break; case SKAGGBAG_FIELD_ICMP_CODE: skAggBagAggregateSetUnsigned( &key, &k_it, (rwRecIsICMP(&rwrec) ? rwRecGetIcmpCode(&rwrec) : 0)); break; case SKAGGBAG_FIELD_PROTO: skAggBagAggregateSetUnsigned( &key, &k_it, rwRecGetProto(&rwrec)); break; case SKAGGBAG_FIELD_PACKETS: skAggBagAggregateSetUnsigned( &key, &k_it, rwRecGetPkts(&rwrec)); break; case SKAGGBAG_FIELD_BYTES: skAggBagAggregateSetUnsigned( &key, &k_it, rwRecGetBytes(&rwrec)); break; case SKAGGBAG_FIELD_FLAGS: skAggBagAggregateSetUnsigned( &key, &k_it, rwRecGetFlags(&rwrec)); break; case SKAGGBAG_FIELD_SID: skAggBagAggregateSetUnsigned( &key, &k_it, rwRecGetSensor(&rwrec)); break; case SKAGGBAG_FIELD_INPUT: skAggBagAggregateSetUnsigned( &key, &k_it, rwRecGetInput(&rwrec)); break; case SKAGGBAG_FIELD_OUTPUT: skAggBagAggregateSetUnsigned( &key, &k_it, rwRecGetOutput(&rwrec)); break; case SKAGGBAG_FIELD_INIT_FLAGS: skAggBagAggregateSetUnsigned( &key, &k_it, rwRecGetInitFlags(&rwrec)); break; case SKAGGBAG_FIELD_REST_FLAGS: skAggBagAggregateSetUnsigned( &key, &k_it, rwRecGetRestFlags(&rwrec)); break; case SKAGGBAG_FIELD_TCP_STATE: skAggBagAggregateSetUnsigned( &key, &k_it, (rwRecGetTcpState(&rwrec) & SK_TCPSTATE_ATTRIBUTE_MASK)); break; case SKAGGBAG_FIELD_APPLICATION: skAggBagAggregateSetUnsigned( &key, &k_it, rwRecGetApplication(&rwrec)); break; case SKAGGBAG_FIELD_FTYPE_CLASS: skAggBagAggregateSetUnsigned( &key, &k_it, sksiteFlowtypeGetClassID(rwRecGetFlowType(&rwrec))); break; case SKAGGBAG_FIELD_FTYPE_TYPE: skAggBagAggregateSetUnsigned( &key, &k_it, rwRecGetFlowType(&rwrec)); break; case SKAGGBAG_FIELD_STARTTIME: skAggBagAggregateSetUnsigned( &key, &k_it, rwRecGetStartSeconds(&rwrec)); break; case SKAGGBAG_FIELD_ELAPSED: skAggBagAggregateSetUnsigned( &key, &k_it, rwRecGetElapsedSeconds(&rwrec)); break; case SKAGGBAG_FIELD_ENDTIME: skAggBagAggregateSetUnsigned( &key, &k_it, rwRecGetEndSeconds(&rwrec)); break; default: break; } } while (skAggBagFieldIterNext(&k_it) == SK_ITERATOR_OK); skAggBagInitializeCounter(ab, &counter, &c_it); do { switch (skAggBagFieldIterGetType(&c_it)) { case SKAGGBAG_FIELD_RECORDS: skAggBagAggregateSetUnsigned(&counter, &c_it, 1); break; case SKAGGBAG_FIELD_SUM_BYTES: skAggBagAggregateSetUnsigned( &counter, &c_it, rwRecGetBytes(&rwrec)); break; case SKAGGBAG_FIELD_SUM_PACKETS: skAggBagAggregateSetUnsigned( &counter, &c_it, rwRecGetPkts(&rwrec)); break; case SKAGGBAG_FIELD_SUM_ELAPSED: skAggBagAggregateSetUnsigned( &counter, &c_it, rwRecGetElapsedSeconds(&rwrec)); break; default: break; } } while (skAggBagFieldIterNext(&c_it) == SK_ITERATOR_OK); err = skAggBagKeyCounterAdd(ab, &key, &counter, NULL); if (err) { skAppPrintErr("Unable to add to key: %s", skAggBagStrerror(err)); break; } } if (rv != SKSTREAM_ERR_EOF) { skStreamPrintLastErr(stream, rv, &skAppPrintErr); return -1; } return 0; }
static void printRecords( const rwRec rec[]) { char starttime[2][RWCOMPARE_BUFSIZ]; uint32_t elapsed[2]; uint32_t sport[2]; uint32_t dport[2]; uint32_t proto[2]; uint32_t flowtype[2]; uint32_t sensor[2]; uint32_t flags[2]; uint32_t initflags[2]; uint32_t restflags[2]; uint32_t tcpstate[2]; uint32_t application[2]; uint32_t memo[2]; uint32_t input[2]; uint32_t output[2]; uint32_t pkts[2]; uint32_t bytes[2]; char sip[2][RWCOMPARE_BUFSIZ]; char dip[2][RWCOMPARE_BUFSIZ]; char nhip[2][RWCOMPARE_BUFSIZ]; skipaddr_t ip; unsigned i; for (i = 0; i < 2; ++i) { sktimestamp_r( starttime[i], rwRecGetStartTime(&rec[i]), SKTIMESTAMP_EPOCH); elapsed[i] = rwRecGetElapsed(&rec[i]); sport[i] = rwRecGetSPort(&rec[i]); dport[i] = rwRecGetDPort(&rec[i]); proto[i] = rwRecGetProto(&rec[i]); flowtype[i] = rwRecGetFlowType(&rec[i]); sensor[i] = rwRecGetSensor(&rec[i]); flags[i] = rwRecGetFlags(&rec[i]); initflags[i] = rwRecGetInitFlags(&rec[i]); restflags[i] = rwRecGetRestFlags(&rec[i]); tcpstate[i] = rwRecGetTcpState(&rec[i]); application[i] = rwRecGetApplication(&rec[i]); memo[i] = rwRecGetMemo(&rec[i]); input[i] = rwRecGetInput(&rec[i]); output[i] = rwRecGetOutput(&rec[i]); pkts[i] = rwRecGetPkts(&rec[i]); bytes[i] = rwRecGetBytes(&rec[i]); rwRecMemGetSIP(&rec[i], &ip); skipaddrString(sip[i], &ip, SKIPADDR_HEXADECIMAL); rwRecMemGetDIP(&rec[i], &ip); skipaddrString(dip[i], &ip, SKIPADDR_HEXADECIMAL); rwRecMemGetNhIP(&rec[i], &ip); skipaddrString(nhip[i], &ip, SKIPADDR_HEXADECIMAL); } compareStrings("StartTime", starttime); compareNumbers("Elapsed", elapsed); compareNumbers("SPort", sport); compareNumbers("DPort", dport); compareNumbers("Proto", proto); compareNumbers("FlowType", flowtype); compareNumbers("Sensor", sensor); compareNumbers("Flags", flags); compareNumbers("InitFlags", initflags); compareNumbers("RestFlags", restflags); compareNumbers("TcpState", tcpstate); compareNumbers("Application", application); compareNumbers("Memo", memo); compareNumbers("Input", input); compareNumbers("Output", output); compareNumbers("Pkts", pkts); compareNumbers("Bytes", bytes); compareStrings("SIP", sip); compareStrings("DIP", dip); compareStrings("NhIP", nhip); }