void RRDVisAnalyzer::analyzeFlow(const Flow* flow) { if (firstFlow) { initDatabases((uint64_t)(((uint64_t)flow->flowStart / 1000) / 60) * 60); firstFlow = false; } static char output[16]; lpm_lookup(tree, flow->srcIP, output); // VERMONT does not use the timestamps properly to determine which direction of the // flow did start the flow. It is therefore possible that the reverse flow direction // actually started the flow. Hence, we need to check this manually. if (flow->flowStart < flow->revFlowStart) { updateEntry(output, flow->flowStart, flow->flowEnd, flow->proto, flow->revBytes, flow->revPackets, flow->bytes, flow->packets); } else { updateEntry(output, flow->revFlowStart, flow->revFlowEnd, flow->proto, flow->bytes, flow->packets, flow->revBytes, flow->revPackets); } lpm_lookup(tree, flow->dstIP, output); if (flow->flowStart < flow->revFlowStart) { updateEntry(output, flow->revFlowStart, flow->revFlowEnd, flow->proto, flow->bytes, flow->packets, flow->revBytes, flow->revPackets); } else { updateEntry(output, flow->flowStart, flow->flowEnd, flow->proto, flow->revBytes, flow->revPackets, flow->bytes, flow->packets); } }
JNIEXPORT jobject JNICALL Java_org_netbsd_liblpm_LPM_lookup__J_3B(JNIEnv *env, jobject obj, jlong lpm_ref, jbyteArray addr_ref) { lpm_t *lpm = (lpm_t *)lpm_ref; jbyte *addr; size_t len; void *ret; len = (*env)->GetArrayLength(env, addr_ref); assert(len == 16 || len == 4); addr = (*env)->GetByteArrayElements(env, addr_ref, NULL); if (addr == NULL) { return NULL; } ret = lpm_lookup(lpm, addr, len); (*env)->ReleaseByteArrayElements(env, addr_ref, addr, JNI_ABORT); return ret; }
JNIEXPORT jobject JNICALL JNICALL Java_org_netbsd_liblpm_LPM_lookup__JLjava_lang_String_2(JNIEnv *env, jobject obj, jlong lpm_ref, jstring addr) { lpm_t *lpm = (lpm_t *)lpm_ref; const char *addr_s; uint32_t addr_buf[4]; size_t len; unsigned pref; addr_s = (*env)->GetStringUTFChars(env, addr, NULL); if (addr_s == NULL) { /* XXX would be better to throw an exception in this case */ return NULL; } if (lpm_strtobin(addr_s, addr_buf, &len, &pref) != 0) { (*env)->ReleaseStringUTFChars(env, addr, addr_s); return NULL; } (*env)->ReleaseStringUTFChars(env, addr, addr_s); return lpm_lookup(lpm, addr_buf, len); }
int main(int argc, char* argv[]) { char* input; int opt; struct lpm_tree* tree; FILE* in; char* ifile = "/dev/stdin"; /* Check inputs; print usage and exit if something is clearly wrong. */ if (argc < 3) { print_usage(argv[0]); exit(EXIT_FAILURE); } /* Parse options */ while ((opt = getopt(argc, argv, "df:")) != -1) { switch (opt) { case 'd': debug = 1; break; case 'f': input = optarg; break; default: /* '?' */ print_usage(argv[0]); exit(EXIT_FAILURE); } } /* Create a fresh tree. */ tree = lpm_init(); /* Read in all prefixes. */ in = fopen(input, "r"); while (1) { char *line = NULL; size_t linecap = 0; ssize_t linelen; char ip_string[INET6_ADDRSTRLEN]; int mask; uint8_t rt; linelen = getline(&line, &linecap, in); if (linelen < 0) { break; } rt = sscanf(line, "%39s %d%*[^\n]", ip_string, &mask); if (rt < 2) { continue; } lpm_insert(tree, ip_string, mask); } fclose(in); lpm_debug_print(tree); /* Begin reading from standard input the lines of text to convert. */ in = fopen(ifile, "r"); while (1) { char *line = NULL; size_t linecap = 0; ssize_t linelen; char address_string[16]; char output[16]; char* pointer; char* strstart; char* strend; int rt; /* Read line. */ linelen = getline(&line, &linecap, in); if (linelen < 0) { break; } line[strlen(line)-1] = '\0'; pointer = line; strstart = pointer; strend = strstr(strstart, " "); while (strend != NULL) { memset(address_string, '\0', 16); memcpy(address_string, strstart, strend - strstart); memset(output, '\0', 16); rt = lpm_lookup(tree, address_string, output); if (rt) { printf("%s ", output); } else { printf("%s ", address_string); } strstart = strend + 1; strend = strstr(strstart, " "); } memset(output, '\0', 16); rt = lpm_lookup(tree, strstart, output); if (rt) { printf("%s\n", output); } else { printf("%s\n", strstart); } free(line); } lpm_destroy(tree); fclose(in); return 1; }
int consume_flow(const char* line, struct lpm_tree* tree) { // create a copy of the line for strtok char tmp_line[LINE_SIZE]; strcpy(tmp_line, line); char delimiter[] = "|"; char* ptr; uint32_t sip; uint32_t dip; uint32_t packets; uint32_t bytes; uint16_t dport; uint16_t sport; uint8_t proto; int ret; // the input line is a | separated list of mulitiple fields (counting field numbers starts at 0) // field1 = first-seen second // field2 = first-seen milliseconds // field3 = last-seen seconds // field4 = last-seen milliseconds // field5 = protocol // field9 = source ip // field10 = source port // field14 = destination ip // field15 = destination port // field20 = flags // field22 = packet // field23 = bytes // We parse a token. If we have a key, we construct the final // key from key_prefix_key (which results in IP_interface_KEY1, IP_interface_KEY2, ...) ptr = strtok(tmp_line, delimiter); uint8_t field_ctr = 0; while (ptr) { switch (field_ctr) { case 1: // first-seen second break; case 2: // first seen milliseconds break; case 3: // last seen seconds break; case 4: // last seen milliseconds break; case 5: // protocol proto = (uint8_t)atoi(ptr); break; case 9: // source ip sip = (uint32_t)atoi(ptr); break; case 10: // source port sport = (uint16_t)atoi(ptr); break; case 14: // destination ip dip = (uint32_t)atoi(ptr); break; case 15: // destination port dport = (uint32_t)atoi(ptr); break; case 20: // flags break; case 22: // packets packets = (uint32_t)atoi(ptr); break; case 23: // bytes bytes = (uint32_t)atoi(ptr); break; default: break; } field_ctr++; ptr = strtok(NULL, delimiter); } uint32_t network_owner_source, network_owner_dest; char network_source[LINE_SIZE]; char network_dest[LINE_SIZE]; lpm_lookup(tree, sip, network_source, &network_owner_source); lpm_lookup(tree, dip, network_dest, &network_owner_dest); network_stats_t *s_net_search = (network_stats_t*)malloc(sizeof(network_stats_t)); if (NULL == s_net_search) { perror("ERROR: Could not allocate s_net_search"); exit(1); } bzero(s_net_search, sizeof(network_stats_t)); network_stats_t *d_net_search = (network_stats_t*)malloc(sizeof(network_stats_t)); if (NULL == d_net_search) { perror("ERROR: Could not allocate d_net_search"); exit(1); } bzero(d_net_search, sizeof(network_stats_t)); s_net_search->id = network_owner_source; d_net_search->id = network_owner_dest; network_stats_t* s_net = *(network_stats_t**)tsearch(s_net_search, &network_tree, compare_networks); if (s_net != s_net_search) { // element is already in tree. delete the search element free(s_net_search); } network_stats_t* d_net = *(network_stats_t**)tsearch(d_net_search, &network_tree, compare_networks); if (d_net != d_net_search) { // element is already in tree. delete the search element free(d_net_search); } s_net->out_pkts += packets; s_net->out_bytes += bytes; d_net->in_pkts += packets; d_net->in_bytes += bytes; switch (proto) { case 1: // ICMP s_net->out_icmp_pkts += packets; s_net->out_icmp_bytes += bytes; d_net->in_icmp_pkts += packets; d_net->in_icmp_bytes += bytes; break; case 6: // TCP s_net->out_tcp_pkts += packets; s_net->out_tcp_bytes += bytes; d_net->in_tcp_pkts += packets; d_net->in_tcp_bytes += bytes; break; case 17: // UDP s_net->out_udp_pkts += packets; s_net->out_udp_bytes += bytes; d_net->in_udp_pkts += packets; d_net->in_udp_bytes += bytes; break; default: s_net->out_other_pkts += packets; s_net->out_other_bytes += bytes; d_net->in_other_pkts += packets; d_net->in_other_bytes += bytes; break; } return 0; }