mirror of
https://github.com/pavel-odintsov/fastnetmon
synced 2024-05-05 20:16:23 +02:00
Removed old unused code
This commit is contained in:
parent
e3f0860bc6
commit
c2dac3564c
|
@ -1,5 +0,0 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
clang++ fastnetmon_packet_parser.cpp -c -ofastnetmon_packet_parser.o
|
||||
clang++ netmap.cpp -I/usr/local/include -L/usr/local/lib -I/usr/src/fastnetmon/tests/netmap_includes -lboost_thread -lboost_system fastnetmon_packet_parser.o
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
#include <json-c/json.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int main() {
|
||||
for (int i = 0; i < 10000000; i++) {
|
||||
json_object* jobj = json_object_new_object();
|
||||
|
||||
/*Creating a json array*/
|
||||
json_object* jarray = json_object_new_array();
|
||||
|
||||
/*Creating json strings*/
|
||||
json_object* jstring1 = json_object_new_string("c");
|
||||
json_object* jstring2 = json_object_new_string("c++");
|
||||
json_object* jstring3 = json_object_new_string("php");
|
||||
|
||||
/*Adding the above created json strings to the array*/
|
||||
json_object_array_add(jarray, jstring1);
|
||||
json_object_array_add(jarray, jstring2);
|
||||
json_object_array_add(jarray, jstring3);
|
||||
|
||||
json_object_object_add(jobj, "languages", jarray);
|
||||
|
||||
// After _array_add and _object_add operations all ownership moves to obj and will be freed up with jobj
|
||||
|
||||
/*Now printing the json object*/
|
||||
// printf ("The json object created: %sn", json_object_to_json_string(jobj));
|
||||
|
||||
// Free up memory
|
||||
json_object_put(jobj);
|
||||
}
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
{"22.11.22.33" : { 33 : "BB", 4 : "BB", 3 : "BB" },"88.99.11.22" : { 559 : "BB", 572 : "BB", 613 : "BB", 542 : "BB", 565 : "BB", 558 : "BB", 561 : "BB", 543 : "BB", 555 : "BB", 545 : "BB", 568 : "BB", 551 : "BB", 574 : "BB" }, "10.0.1.2" : { 916 : "BB" } }
|
|
@ -1,188 +0,0 @@
|
|||
#include <iostream>
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
#define NETMAP_WITH_LIBS
|
||||
|
||||
#include <boost/thread.hpp>
|
||||
#include <net/netmap_user.h>
|
||||
|
||||
// For pooling operations
|
||||
#include <poll.h>
|
||||
|
||||
#include "fastnetmon_packet_parser.h"
|
||||
|
||||
int number_of_packets = 0;
|
||||
|
||||
/* prototypes */
|
||||
void netmap_thread(struct nm_desc* netmap_descriptor, int netmap_thread);
|
||||
void consume_pkt(u_char* buffer, int len);
|
||||
|
||||
int receive_packets(struct netmap_ring* ring) {
|
||||
u_int cur, rx, n;
|
||||
|
||||
cur = ring->cur;
|
||||
n = nm_ring_space(ring);
|
||||
|
||||
for (rx = 0; rx < n; rx++) {
|
||||
struct netmap_slot* slot = &ring->slot[cur];
|
||||
char* p = NETMAP_BUF(ring, slot->buf_idx);
|
||||
|
||||
// process data
|
||||
consume_pkt((u_char*)p, slot->len);
|
||||
|
||||
cur = nm_ring_next(ring, cur);
|
||||
}
|
||||
|
||||
ring->head = ring->cur = cur;
|
||||
return (rx);
|
||||
}
|
||||
|
||||
void consume_pkt(u_char* buffer, int len) {
|
||||
// static char packet_data[2000];
|
||||
// printf("Got packet with length: %d\n", len);
|
||||
// memcpy(packet_data, buffer, len);
|
||||
struct pfring_pkthdr l2tp_header;
|
||||
memset(&l2tp_header, 0, sizeof(l2tp_header));
|
||||
l2tp_header.len = len;
|
||||
l2tp_header.caplen = len;
|
||||
|
||||
fastnetmon_parse_pkt((u_char*)buffer, &l2tp_header, 4, 1, 0);
|
||||
|
||||
// char print_buffer[512];
|
||||
// fastnetmon_print_parsed_pkt(print_buffer, 512, (u_char*)buffer, &l2tp_header);
|
||||
// printf("%s\n", print_buffer);
|
||||
|
||||
|
||||
__sync_fetch_and_add(&number_of_packets, 1);
|
||||
}
|
||||
|
||||
void receiver(void) {
|
||||
struct nm_desc* netmap_descriptor;
|
||||
|
||||
u_int num_cpus = sysconf(_SC_NPROCESSORS_ONLN);
|
||||
printf("We have %d cpus\n", num_cpus);
|
||||
|
||||
struct nmreq base_nmd;
|
||||
bzero(&base_nmd, sizeof(base_nmd));
|
||||
|
||||
// Magic from pkt-gen.c
|
||||
base_nmd.nr_tx_rings = base_nmd.nr_rx_rings = 0;
|
||||
base_nmd.nr_tx_slots = base_nmd.nr_rx_slots = 0;
|
||||
|
||||
std::string interface = "netmap:eth4";
|
||||
netmap_descriptor = nm_open(interface.c_str(), &base_nmd, 0, NULL);
|
||||
|
||||
if (netmap_descriptor == NULL) {
|
||||
printf("Can't open netmap device %s\n", interface.c_str());
|
||||
exit(1);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("Mapped %dKB memory at %p\n", netmap_descriptor->req.nr_memsize >> 10, netmap_descriptor->mem);
|
||||
printf("We have %d tx and %d rx rings\n", netmap_descriptor->req.nr_tx_rings, netmap_descriptor->req.nr_rx_rings);
|
||||
|
||||
/*
|
||||
protocol stack and may cause a reset of the card,
|
||||
which in turn may take some time for the PHY to
|
||||
reconfigure. We do the open here to have time to reset.
|
||||
*/
|
||||
|
||||
int wait_link = 2;
|
||||
printf("Wait %d seconds for NIC reset\n", wait_link);
|
||||
sleep(wait_link);
|
||||
|
||||
boost::thread* boost_threads_array[num_cpus];
|
||||
for (int i = 0; i < num_cpus; i++) {
|
||||
struct nm_desc nmd = *netmap_descriptor;
|
||||
// This operation is VERY important!
|
||||
nmd.self = &nmd;
|
||||
|
||||
uint64_t nmd_flags = 0;
|
||||
|
||||
if (nmd.req.nr_flags != NR_REG_ALL_NIC) {
|
||||
printf("SHIT SHIT SHIT HAPPINED\n");
|
||||
}
|
||||
|
||||
nmd.req.nr_flags = NR_REG_ONE_NIC;
|
||||
nmd.req.nr_ringid = i;
|
||||
|
||||
/* Only touch one of the rings (rx is already ok) */
|
||||
nmd_flags |= NETMAP_NO_TX_POLL;
|
||||
|
||||
struct nm_desc* new_nmd = nm_open(interface.c_str(), NULL, nmd_flags | NM_OPEN_IFNAME | NM_OPEN_NO_MMAP, &nmd);
|
||||
|
||||
if (new_nmd == NULL) {
|
||||
printf("Can't open netmap descripto for netmap\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("My first ring is %d and last ring id is %d I'm thread %d\n", new_nmd->first_rx_ring, new_nmd->last_rx_ring, i);
|
||||
|
||||
printf("Start new thread %d\n", i);
|
||||
// Start thread and pass netmap descriptor to it
|
||||
boost_threads_array[i] = new boost::thread(netmap_thread, new_nmd, i);
|
||||
}
|
||||
|
||||
printf("Wait for thread finish\n");
|
||||
// Wait all threads for completion
|
||||
for (int i = 0; i < num_cpus; i++) {
|
||||
boost_threads_array[i]->join();
|
||||
}
|
||||
}
|
||||
|
||||
void netmap_thread(struct nm_desc* netmap_descriptor, int thread_number) {
|
||||
struct nm_pkthdr h;
|
||||
u_char* buf;
|
||||
struct pollfd fds;
|
||||
fds.fd = netmap_descriptor->fd; // NETMAP_FD(netmap_descriptor);
|
||||
fds.events = POLLIN;
|
||||
|
||||
struct netmap_ring* rxring = NULL;
|
||||
struct netmap_if* nifp = netmap_descriptor->nifp;
|
||||
|
||||
printf("Reading from fd %d thread id: %d\n", netmap_descriptor->fd, thread_number);
|
||||
|
||||
for (;;) {
|
||||
// We will wait 1000 microseconds for retry, for infinite timeout please use -1
|
||||
int poll_result = poll(&fds, 1, 1000);
|
||||
|
||||
if (poll_result == 0) {
|
||||
// printf("poll return 0 return code\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
if (poll_result == -1) {
|
||||
printf("poll failed with return code -1\n");
|
||||
}
|
||||
|
||||
for (int i = netmap_descriptor->first_rx_ring; i <= netmap_descriptor->last_rx_ring; i++) {
|
||||
// printf("Check ring %d from thread %d\n", i, thread_number);
|
||||
rxring = NETMAP_RXRING(nifp, i);
|
||||
|
||||
if (nm_ring_empty(rxring)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int m = receive_packets(rxring);
|
||||
}
|
||||
|
||||
// while ( (buf = nm_nextpkt(netmap_descriptor, &h)) ) {
|
||||
// consume_pkt(buf, h.len);
|
||||
//}
|
||||
}
|
||||
|
||||
// nm_close(netmap_descriptor);
|
||||
}
|
||||
|
||||
int main() {
|
||||
// receiver();
|
||||
boost::thread netmap_thread(receiver);
|
||||
|
||||
for (;;) {
|
||||
sleep(1);
|
||||
printf("We received %d packets in 1 second\n", number_of_packets);
|
||||
number_of_packets = 0;
|
||||
}
|
||||
|
||||
netmap_thread.join();
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
|
||||
index dfbe8c1..a84d696 100644
|
||||
--- a/src/CMakeLists.txt
|
||||
+++ b/src/CMakeLists.txt
|
||||
@@ -10,6 +10,10 @@ project(FastNetMon)
|
||||
# Enable it and fix all warnigns!
|
||||
# add_definitions ("-Wall")
|
||||
|
||||
+include_directories("/opt/libcuckoo/include/")
|
||||
+# We need C++11 support for libcuckoo
|
||||
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
|
||||
+
|
||||
set (Tutorial_VERSION_MAJOR 1)
|
||||
set (Tutorial_VERSION_MINOR 1)
|
||||
|
||||
@@ -189,5 +193,7 @@ target_link_libraries(fastnetmon pcap_plugin)
|
||||
target_link_libraries(fastnetmon example_plugin)
|
||||
target_link_libraries(fastnetmon netmap_plugin)
|
||||
|
||||
+target_link_libraries(fastnetmon /opt/libcuckoo/lib/libcityhash.so)
|
||||
+
|
||||
install(TARGETS fastnetmon DESTINATION bin)
|
||||
install(TARGETS fastnetmon_client DESTINATION bin)
|
||||
diff --git a/src/fastnetmon.cpp b/src/fastnetmon.cpp
|
||||
index 5308244..cd9e9dc 100644
|
||||
--- a/src/fastnetmon.cpp
|
||||
+++ b/src/fastnetmon.cpp
|
||||
@@ -268,6 +268,8 @@ void process_packet(simple_packet& current_packet);
|
||||
void traffic_draw_program();
|
||||
void interruption_signal_handler(int signal_number);
|
||||
|
||||
+cuckoohash_map<std::string, map_element, CityHasher<std::string> > flow_tracking_table_new_generation;
|
||||
+
|
||||
/* Class for custom comparison fields by different fields */
|
||||
class TrafficComparatorClass {
|
||||
private:
|
||||
@@ -1029,6 +1031,24 @@ void process_packet(simple_packet& current_packet) {
|
||||
}
|
||||
}
|
||||
|
||||
+
|
||||
+ if (packet_direction == OUTGOING or packet_direction == INCOMING) {
|
||||
+ std::string connection_tracking_hash_string = convert_ip_as_uint_to_string(current_packet.dst_ip) + "_" + convert_ip_as_uint_to_string(current_packet.src_ip) + "_" +
|
||||
+ convert_ip_as_uint_to_string(current_packet.source_port) + "_" + convert_ip_as_uint_to_string(current_packet.destination_port) + "_" + convert_ip_as_uint_to_string(current_packet.protocol) + "_";
|
||||
+ get_direction_name(packet_direction);
|
||||
+
|
||||
+ map_element temp_element;
|
||||
+
|
||||
+ if (flow_tracking_table_new_generation.find(connection_tracking_hash_string, temp_element)) {
|
||||
+ // found!
|
||||
+
|
||||
+ } else {
|
||||
+ // not found, create it
|
||||
+ flow_tracking_table_new_generation.insert(connection_tracking_hash_string, temp_element);
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+
|
||||
/* Because we support mirroring, sflow and netflow we should support different cases:
|
||||
- One packet passed for processing (mirror)
|
||||
- Multiple packets ("flows") passed for processing (netflow)
|
||||
diff --git a/src/fastnetmon_types.h b/src/fastnetmon_types.h
|
||||
index 8263645..6e098ca 100644
|
||||
--- a/src/fastnetmon_types.h
|
||||
+++ b/src/fastnetmon_types.h
|
||||
@@ -5,6 +5,9 @@
|
||||
#include <stdint.h> // uint32_t
|
||||
#include <sys/time.h> // struct timeval
|
||||
|
||||
+#include <libcuckoo/cuckoohash_map.hh>
|
||||
+#include <libcuckoo/city_hasher.hh>
|
||||
+
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
|
@ -1,135 +0,0 @@
|
|||
diff --git a/src/fastnetmon.cpp b/src/fastnetmon.cpp
|
||||
index 5308244..2a67506 100644
|
||||
--- a/src/fastnetmon.cpp
|
||||
+++ b/src/fastnetmon.cpp
|
||||
@@ -191,6 +191,12 @@ map_of_vector_counters SubnetVectorMap;
|
||||
// Flow tracking structures
|
||||
map_of_vector_counters_for_flow SubnetVectorMapFlow;
|
||||
|
||||
+typedef std::vector<unsigned long int> lookup_vector_indexes_t;
|
||||
+typedef std::vector<vector_of_counters> lookup_vector_data_t;
|
||||
+
|
||||
+lookup_vector_indexes_t lookup_vector_indexes;
|
||||
+lookup_vector_data_t lookup_vector_data;
|
||||
+
|
||||
/* End of our data structs */
|
||||
|
||||
boost::mutex data_counters_mutex;
|
||||
@@ -969,12 +975,22 @@ bool load_our_networks_list() {
|
||||
|
||||
/* Preallocate data structures */
|
||||
|
||||
- patricia_process (lookup_tree, (void_fn_t)subnet_vectors_allocator);
|
||||
-
|
||||
logger<<log4cpp::Priority::INFO<<"We start total zerofication of counters";
|
||||
zeroify_all_counters();
|
||||
logger<<log4cpp::Priority::INFO<<"We finished zerofication";
|
||||
|
||||
+ // We could try allocate vector from std::map
|
||||
+ patricia_process (lookup_tree, (void_fn_t)subnet_vectors_allocator);
|
||||
+ lookup_vector_indexes.reserve( SubnetVectorMap.size() );
|
||||
+ lookup_vector_data.reserve( SubnetVectorMap.size() );
|
||||
+
|
||||
+ // Copy pointers to the vector
|
||||
+ // We do not need any sort here because vector is already sorted because std::map nature
|
||||
+ for( map_of_vector_counters::iterator ii = SubnetVectorMap.begin(); ii != SubnetVectorMap.end(); ++ii) {
|
||||
+ lookup_vector_indexes.push_back(ii->first);
|
||||
+ lookup_vector_data.push_back(ii->second);
|
||||
+ }
|
||||
+
|
||||
logger<<log4cpp::Priority::INFO<<"We loaded "<<networks_list_as_string.size()<<" subnets to our in-memory list of networks";
|
||||
logger<<log4cpp::Priority::INFO<<"Total number of monitored hosts (total size of all networks): "
|
||||
<<total_number_of_hosts_in_our_networks;
|
||||
@@ -1005,14 +1021,17 @@ void process_packet(simple_packet& current_packet) {
|
||||
}
|
||||
|
||||
// Try to find map key for this subnet
|
||||
- map_of_vector_counters::iterator itr;
|
||||
+ vector_of_counters* itr = NULL;
|
||||
|
||||
if (packet_direction == OUTGOING or packet_direction == INCOMING) {
|
||||
- itr = SubnetVectorMap.find(subnet);
|
||||
+ lookup_vector_indexes_t::iterator fast_iter = std::lower_bound(lookup_vector_indexes.begin(), lookup_vector_indexes.end(), subnet);
|
||||
|
||||
- if (itr == SubnetVectorMap.end()) {
|
||||
+ if (fast_iter != lookup_vector_indexes.end() && *fast_iter == subnet) {
|
||||
+ // Load data from data vector from same index
|
||||
+ itr = &lookup_vector_data[ fast_iter - lookup_vector_indexes.begin() ];
|
||||
+ } else {
|
||||
logger<< log4cpp::Priority::ERROR<<"Can't find vector address in subnet map";
|
||||
- return;
|
||||
+ return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1046,16 +1065,16 @@ void process_packet(simple_packet& current_packet) {
|
||||
if (packet_direction == OUTGOING) {
|
||||
int64_t shift_in_vector = (int64_t)ntohl(current_packet.src_ip) - (int64_t)subnet_in_host_byte_order;
|
||||
|
||||
- if (shift_in_vector < 0 or shift_in_vector >= itr->second.size()) {
|
||||
+ if (shift_in_vector < 0 or shift_in_vector >= itr->size()) {
|
||||
logger<< log4cpp::Priority::ERROR<<"We tried to access to element with index "<<shift_in_vector
|
||||
- <<" which located outside allocated vector with size "<<itr->second.size();
|
||||
+ <<" which located outside allocated vector with size "<<itr->size();
|
||||
|
||||
logger<< log4cpp::Priority::ERROR<<"We expect issues with this packet in OUTGOING direction: "<<print_simple_packet(current_packet);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
- map_element* current_element = &itr->second[shift_in_vector];
|
||||
+ map_element* current_element = &(*itr)[shift_in_vector];
|
||||
|
||||
// Main packet/bytes counter
|
||||
__sync_fetch_and_add(¤t_element->out_packets, sampled_number_of_packets);
|
||||
@@ -1135,16 +1154,16 @@ void process_packet(simple_packet& current_packet) {
|
||||
} else if (packet_direction == INCOMING) {
|
||||
int64_t shift_in_vector = (int64_t)ntohl(current_packet.dst_ip) - (int64_t)subnet_in_host_byte_order;
|
||||
|
||||
- if (shift_in_vector < 0 or shift_in_vector >= itr->second.size()) {
|
||||
+ if (shift_in_vector < 0 or shift_in_vector >= itr->size()) {
|
||||
logger<< log4cpp::Priority::ERROR<<"We tried to access to element with index "<<shift_in_vector
|
||||
- <<" which located outside allocated vector with size "<<itr->second.size();
|
||||
+ <<" which located outside allocated vector with size "<<itr->size();
|
||||
|
||||
logger<< log4cpp::Priority::INFO<<"We expect issues with this packet in INCOMING direction: "<<print_simple_packet(current_packet);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
- map_element* current_element = &itr->second[shift_in_vector];
|
||||
+ map_element* current_element = &(*itr)[shift_in_vector];
|
||||
|
||||
// Main packet/bytes counter
|
||||
__sync_fetch_and_add(¤t_element->in_packets, sampled_number_of_packets);
|
||||
@@ -1307,15 +1326,17 @@ void recalculate_speed() {
|
||||
uint64_t incoming_total_flows = 0;
|
||||
uint64_t outgoing_total_flows = 0;
|
||||
|
||||
- for (map_of_vector_counters::iterator itr = SubnetVectorMap.begin(); itr != SubnetVectorMap.end(); ++itr) {
|
||||
- for (vector_of_counters::iterator vector_itr = itr->second.begin(); vector_itr != itr->second.end(); ++vector_itr) {
|
||||
- int current_index = vector_itr - itr->second.begin();
|
||||
+ for (lookup_vector_indexes_t::iterator itr = lookup_vector_indexes.begin(); itr != lookup_vector_indexes.end(); ++itr) {
|
||||
+ vector_of_counters* vector_pointer = &lookup_vector_data[ itr - lookup_vector_indexes.begin() ];
|
||||
+
|
||||
+ for (vector_of_counters::iterator vector_itr = vector_pointer->begin(); vector_itr != vector_pointer->end(); ++vector_itr) {
|
||||
+ int current_index = vector_itr - vector_pointer->begin();
|
||||
|
||||
// New element
|
||||
map_element new_speed_element;
|
||||
|
||||
// convert to host order for math operations
|
||||
- uint32_t subnet_ip = ntohl(itr->first);
|
||||
+ uint32_t subnet_ip = ntohl(*itr);
|
||||
uint32_t client_ip_in_host_bytes_order = subnet_ip + current_index;
|
||||
|
||||
// covnert to our standard network byte order
|
||||
@@ -1364,7 +1385,7 @@ void recalculate_speed() {
|
||||
new_speed_element.icmp_in_bytes = uint64_t((double)vector_itr->icmp_in_bytes / speed_calc_period);
|
||||
new_speed_element.icmp_out_bytes = uint64_t((double)vector_itr->icmp_out_bytes / speed_calc_period);
|
||||
|
||||
- conntrack_main_struct* flow_counter_ptr = &SubnetVectorMapFlow[itr->first][current_index];
|
||||
+ conntrack_main_struct* flow_counter_ptr = &SubnetVectorMapFlow[*itr][current_index];
|
||||
|
||||
// todo: optimize this operations!
|
||||
uint64_t total_out_flows =
|
|
@ -1,68 +0,0 @@
|
|||
#include <arpa/inet.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
// This code compiles on FreeBSD and Linux but did not work on FreeBSD
|
||||
|
||||
/* Promisc management on FreeBSD is real nighmare, really. Issues with: ifr_flagshigh and IFF_PPROMISC vs IFF_PROMISC */
|
||||
/* Good code examples here: https://github.com/fichtner/netmap/blob/master/extra/libpcap-netmap.diff */
|
||||
|
||||
int main() {
|
||||
// We need really any socket for ioctl
|
||||
|
||||
int fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
||||
|
||||
if (!fd) {
|
||||
printf("Can't create socket\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
struct ifreq ethreq;
|
||||
memset(ðreq, 0, sizeof(ethreq));
|
||||
strncpy(ethreq.ifr_name, "eth6", IFNAMSIZ);
|
||||
|
||||
int ioctl_res = ioctl(fd, SIOCGIFFLAGS, ðreq);
|
||||
|
||||
if (ioctl_res == -1) {
|
||||
printf("Can't get interface flags");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (ethreq.ifr_flags & IFF_PROMISC) {
|
||||
printf("Interface in promisc mode already\n");
|
||||
|
||||
printf("Switch it off\n");
|
||||
|
||||
ethreq.ifr_flags &= ~IFF_PROMISC;
|
||||
|
||||
int ioctl_res_set = ioctl(fd, SIOCSIFFLAGS, ðreq);
|
||||
|
||||
if (ioctl_res_set == -1) {
|
||||
printf("Can't set interface flags");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("promisc mode disabled correctly\n");
|
||||
} else {
|
||||
printf("Interface in non promisc mode now, switch it on\n");
|
||||
|
||||
ethreq.ifr_flags |= IFF_PROMISC;
|
||||
int ioctl_res_set = ioctl(fd, SIOCSIFFLAGS, ðreq);
|
||||
|
||||
if (ioctl_res_set == -1) {
|
||||
printf("Can't set interface flags");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("promisc mode enabled\n");
|
||||
}
|
||||
|
||||
close(fd);
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
import time
|
||||
my_dict = {}
|
||||
|
||||
|
||||
# Intel(R) Core(TM) i7-3635QM CPU @ 2.40GHz: 4.8 MOPS
|
||||
# Intel(R) Core(TM) i7-3820 CPU @ 3.60GHz: python 2.7 7.0 MOPS
|
||||
# Intel(R) Core(TM) i7-3820 CPU @ 3.60GHz: python 2.7/pypy: 8.6 MOPS
|
||||
|
||||
iterations = 10**6*14
|
||||
|
||||
start = time.time()
|
||||
|
||||
# Emulate 14.6 mpps
|
||||
for index in range(0, iterations):
|
||||
my_dict[index] = { "udp": 0 }
|
||||
|
||||
stop = time.time()
|
||||
interval = stop - start
|
||||
|
||||
print iterations / interval / 10**6, "millions of iterations per second"
|
||||
|
|
@ -1,220 +0,0 @@
|
|||
// compile with: gcc -shared -o capturecallback.so -fPIC capturecallback.c
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "../../fastnetmon_packet_parser.h"
|
||||
|
||||
double system_tsc_resolution_hz = 0;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
inline uint64_t rte_rdtsc(void) {
|
||||
union {
|
||||
uint64_t tsc_64;
|
||||
struct {
|
||||
uint32_t lo_32;
|
||||
uint32_t hi_32;
|
||||
};
|
||||
} tsc;
|
||||
|
||||
asm volatile("rdtsc" : "=a"(tsc.lo_32), "=d"(tsc.hi_32));
|
||||
return tsc.tsc_64;
|
||||
}
|
||||
|
||||
void set_tsc_freq_fallback() {
|
||||
uint64_t start = rte_rdtsc();
|
||||
sleep(1);
|
||||
system_tsc_resolution_hz = (double)rte_rdtsc() - start;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
// C++ rewrite of Python code: https://gist.github.com/pavel-odintsov/652904287ca0ca6816f6
|
||||
class token_bucket_t {
|
||||
public:
|
||||
token_bucket_t() {
|
||||
this->tokens = 0;
|
||||
this->rate = 0;
|
||||
this->burst = 0;
|
||||
this->last_timestamp = 0;
|
||||
}
|
||||
|
||||
int64_t get_rate() {
|
||||
return this->rate;
|
||||
}
|
||||
|
||||
int64_t get_burst() {
|
||||
return this->burst;
|
||||
}
|
||||
|
||||
int64_t get_tokens() {
|
||||
return this->tokens;
|
||||
}
|
||||
|
||||
bool set_rate(int64_t rate, int64_t burst) {
|
||||
this->rate = rate;
|
||||
|
||||
this->tokens = burst;
|
||||
this->burst = burst;
|
||||
|
||||
// Start counter!
|
||||
this->last_timestamp = (double)rte_rdtsc() / system_tsc_resolution_hz;
|
||||
}
|
||||
|
||||
int64_t consume(int64_t consumed_tokens) {
|
||||
double current_time = (double)rte_rdtsc() / system_tsc_resolution_hz;
|
||||
double interval = (current_time - this->last_timestamp);
|
||||
|
||||
if (interval < 0) {
|
||||
printf("Your TSC is buggy, we have last %llu and current time: %llu\n", this->last_timestamp, current_time);
|
||||
}
|
||||
|
||||
this->last_timestamp = current_time;
|
||||
|
||||
this->tokens = std::max((double)0, std::min(double(this->tokens + this->rate * interval), double(this->burst))) - 1;
|
||||
|
||||
return this->tokens;
|
||||
}
|
||||
|
||||
private:
|
||||
int64_t rate;
|
||||
int64_t tokens;
|
||||
int64_t burst;
|
||||
double last_timestamp;
|
||||
};
|
||||
|
||||
token_bucket_t global_token_bucket_counter;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Called once before processing packets. */
|
||||
void firehose_start(); /* optional */
|
||||
|
||||
/* Called once after processing packets. */
|
||||
void firehose_stop(); /* optional */
|
||||
|
||||
void firehose_stop() {
|
||||
}
|
||||
|
||||
/*
|
||||
* Process a packet received from a NIC.
|
||||
*
|
||||
* pciaddr: name of PCI device packet is received from
|
||||
* data: packet payload (ethernet frame)
|
||||
* length: payload length in bytes
|
||||
*/
|
||||
inline void firehose_packet(const char* pciaddr, char* data, int length);
|
||||
|
||||
/* Intel 82599 "Legacy" receive descriptor format.
|
||||
* See Intel 82599 data sheet section 7.1.5.
|
||||
* http://www.intel.com/content/dam/www/public/us/en/documents/datasheets/82599-10-gbe-controller-datasheet.pdf
|
||||
*/
|
||||
struct firehose_rdesc {
|
||||
uint64_t address;
|
||||
uint16_t length;
|
||||
uint16_t cksum;
|
||||
uint8_t status;
|
||||
uint8_t errors;
|
||||
uint16_t vlan;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Traverse the hardware receive descriptor ring.
|
||||
* Process each packet that is ready.
|
||||
* Return the updated ring index.
|
||||
*/
|
||||
int firehose_callback_v1(const char* pciaddr, char** packets, struct firehose_rdesc* rxring, int ring_size, int index) {
|
||||
while (rxring[index].status & 1) {
|
||||
int next_index = (index + 1) & (ring_size - 1);
|
||||
__builtin_prefetch(packets[next_index]);
|
||||
firehose_packet(pciaddr, packets[index], rxring[index].length);
|
||||
rxring[index].status = 0; /* reset descriptor for reuse */
|
||||
index = next_index;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
|
||||
uint64_t received_packets = 0;
|
||||
|
||||
void* speed_printer(void* ptr) {
|
||||
while (1) {
|
||||
uint64_t packets_before = received_packets;
|
||||
|
||||
sleep(1);
|
||||
|
||||
uint64_t packets_after = received_packets;
|
||||
uint64_t pps = packets_after - packets_before;
|
||||
|
||||
printf("We process: %llu pps tokens %lld rate %lld burst %lld \n", (long long)pps,
|
||||
global_token_bucket_counter.get_tokens(), global_token_bucket_counter.get_rate(),
|
||||
global_token_bucket_counter.get_burst());
|
||||
}
|
||||
}
|
||||
|
||||
void sigproc(int sig) {
|
||||
firehose_stop();
|
||||
|
||||
printf("We caught SINGINT and will finish application\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
// We will start speed printer
|
||||
void firehose_start() {
|
||||
signal(SIGINT, sigproc);
|
||||
|
||||
set_tsc_freq_fallback();
|
||||
global_token_bucket_counter.set_rate(10000000, 15000000);
|
||||
|
||||
// printf("tsq hz is: %f\n", system_tsc_resolution_hz);
|
||||
|
||||
pthread_t thread;
|
||||
pthread_create(&thread, NULL, speed_printer, NULL);
|
||||
|
||||
pthread_detach(thread);
|
||||
}
|
||||
|
||||
void firehose_packet(const char* pciaddr, char* data, int length) {
|
||||
// Put packet to the cache
|
||||
|
||||
/*
|
||||
struct pfring_pkthdr packet_header;
|
||||
memset(&packet_header, 0, sizeof(packet_header));
|
||||
packet_header.len = length;
|
||||
packet_header.caplen = length;
|
||||
|
||||
fastnetmon_parse_pkt((u_char*)data, &packet_header, 3, 0, 0);
|
||||
*/
|
||||
|
||||
/*
|
||||
char print_buffer[512];
|
||||
fastnetmon_print_parsed_pkt(print_buffer, 512, (u_char*)data, &packet_header);
|
||||
printf("packet: %s\n", print_buffer);
|
||||
*/
|
||||
|
||||
int64_t consume_result = global_token_bucket_counter.consume(1);
|
||||
|
||||
if (consume_result < 0) {
|
||||
printf("Overflow!\n");
|
||||
}
|
||||
|
||||
__sync_fetch_and_add(&received_packets, 1);
|
||||
// printf("Got packet with %d bytes.\n", length);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -1,16 +0,0 @@
|
|||
#include <iostream>
|
||||
#include <tins/tins.h>
|
||||
|
||||
// g++ tins_parser.cpp -ltins
|
||||
using namespace Tins;
|
||||
|
||||
bool callback(const PDU& pdu) {
|
||||
const IP& ip = pdu.rfind_pdu<IP>(); // Find the IP layer
|
||||
const TCP& tcp = pdu.rfind_pdu<TCP>(); // Find the TCP layer
|
||||
std::cout << ip.src_addr() << ':' << tcp.sport() << " -> " << ip.dst_addr() << ':' << tcp.dport() << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
int main() {
|
||||
Sniffer("eth0").sniff_loop(callback);
|
||||
}
|
Loading…
Reference in New Issue