NetworkHandler::NetworkHandler(std::string deviceName) { deviceName_ = deviceName; myMac_ = EthernetUtils::GetMacOfInterface(deviceName); myIP_ = EthernetUtils::GetIPOfInterface(GetDeviceName()); u_int32_t flags = 0; flags |= PF_RING_LONG_HEADER; flags |= PF_RING_PROMISC; flags |= PF_RING_DNA_SYMMETRIC_RSS; /* Note that symmetric RSS is ignored by non-DNA drivers */ const int snaplen = 128; pfring** rings = new pfring*[MAX_NUM_RX_CHANNELS]; numberOfQueues_ = pfring_open_multichannel((char*) deviceName.data(), snaplen, flags, rings); queueRings_ = new ntop::PFring *[numberOfQueues_]; for (uint_fast8_t i = 0; i < numberOfQueues_; i++) { std::string queDeviceName = deviceName; queDeviceName = deviceName + "@" + std::to_string((int) i); /* * http://www.ntop.org/pfring_api/pfring_8h.html#a397061c37a91876b6b68584e2cb99da5 */ pfring_set_poll_watermark(rings[i], 128); queueRings_[i] = new ntop::PFring(rings[i], (char*) queDeviceName.data(), snaplen, flags); if (queueRings_[i]->enable_ring() >= 0) { LOG_INFO<< "Successfully opened device " << queueRings_[i]->get_device_name(); } else { LOG_ERROR << "Unable to open device " << queDeviceName << "! Is pf_ring not loaded or do you use quick mode and have already a socket bound to this device?!"; exit(1); } } asyncSendData_.set_capacity(1000); }
int open_rss_rings(char *rss_device, pfring **rss_rings) { long i; int rc, num_channels; num_channels = pfring_open_multichannel(rss_device, 1500 /* snaplen */, PF_RING_PROMISC | PF_RING_DNA_FIXED_RSS_Q_0, rss_rings); if(num_channels < num_threads) { fprintf(stderr, "Error: interface %s has %u channels available, you need at least %u as the number of slave threads\n", rss_device, num_channels, num_threads); return -1; } for(i=0; i<num_channels; i++) { char buf[32]; snprintf(buf, sizeof(buf), "pfdnacluster-%s-channel-%ld", rss_device, i); pfring_set_application_name(rss_rings[i], buf); if((rc = pfring_set_socket_mode(rss_rings[i], send_only_mode)) != 0) fprintf(stderr, "pfring_set_socket_mode returned [rc=%d]\n", rc); } return 0; }
int main(int argc, char* argv[]) { char *device = NULL, c, *bind_mask = NULL; int snaplen = DEFAULT_SNAPLEN, rc, watermark = 0, rehash_rss = 0; packet_direction direction = rx_only_direction; long i; u_int16_t cpu_percentage = 0, poll_duration = 0; u_int32_t version; u_int32_t flags = 0; startTime.tv_sec = 0; thiszone = gmt2local(0); numCPU = sysconf( _SC_NPROCESSORS_ONLN ); memset(thread_core_affinity, -1, sizeof(thread_core_affinity)); while((c = getopt(argc,argv,"hi:l:mvae:w:b:rp:g:")) != -1) { switch(c) { case 'h': printHelp(); return(0); break; case 'a': wait_for_packet = 0; break; case 'e': switch(atoi(optarg)) { case rx_and_tx_direction: case rx_only_direction: case tx_only_direction: direction = atoi(optarg); break; } break; case 'l': snaplen = atoi(optarg); break; case 'i': device = strdup(optarg); break; case 'm': use_extended_pkt_header = 1; break; case 'v': verbose = 1; break; case 'w': watermark = atoi(optarg); break; case 'b': cpu_percentage = atoi(optarg); break; case 'r': rehash_rss = 1; break; case 'p': poll_duration = atoi(optarg); break; case 'g': bind_mask = strdup(optarg); break; } } if(verbose) watermark = 1; if(device == NULL) device = DEFAULT_DEVICE; printf("Capturing from %s\n", device); flags |= PF_RING_PROMISC; /* hardcode: promisc=1 */ #if 0 flags |= PF_RING_DNA_FIXED_RSS_Q_0; #else flags |= PF_RING_DNA_SYMMETRIC_RSS; /* Note that symmetric RSS is ignored by non-DNA drivers */ #endif if(use_extended_pkt_header) flags |= PF_RING_LONG_HEADER; num_channels = pfring_open_multichannel(device, snaplen, flags, ring); if(num_channels <= 0) { fprintf(stderr, "pfring_open_multichannel() returned %d [%s]\n", num_channels, strerror(errno)); return(-1); } if (num_channels > MAX_NUM_THREADS) { printf("WARNING: Too many channels (%d), using %d channels\n", num_channels, MAX_NUM_THREADS); num_channels = MAX_NUM_THREADS; } else if (num_channels > numCPU) { printf("WARNING: More channels (%d) than available cores (%d), using %d channels\n", num_channels, numCPU, numCPU); num_channels = numCPU; } else { printf("Found %d channels\n", num_channels); } if(bind_mask != NULL) { char *id = strtok(bind_mask, ":"); int idx = 0; while(id != NULL) { thread_core_affinity[idx++] = atoi(id) % numCPU; if(idx >= num_channels) break; id = strtok(NULL, ":"); } } pfring_version(ring[0], &version); printf("Using PF_RING v.%d.%d.%d\n", (version & 0xFFFF0000) >> 16, (version & 0x0000FF00) >> 8, version & 0x000000FF); for(i=0; i<num_channels; i++) { char buf[32]; snprintf(buf, sizeof(buf), "pfcount_multichannel-thread %ld", i); pfring_set_application_name(ring[i], buf); if((rc = pfring_set_direction(ring[i], direction)) != 0) fprintf(stderr, "pfring_set_direction returned %d [direction=%d] (you can't capture TX with DNA)\n", rc, direction); if((rc = pfring_set_socket_mode(ring[i], recv_only_mode)) != 0) fprintf(stderr, "pfring_set_socket_mode returned [rc=%d]\n", rc); if(watermark > 0) { if((rc = pfring_set_poll_watermark(ring[i], watermark)) != 0) fprintf(stderr, "pfring_set_poll_watermark returned [rc=%d][watermark=%d]\n", rc, watermark); } #if 0 setup_steering(ring[0], "192.168.30.207", -1); /* UTDF */ setup_steering(ring[0], "224.0.1.92", 1); setup_steering(ring[0], "224.0.1.94", 1); setup_steering(ring[0], "224.0.1.96", 1); /* BATS */ setup_steering(ring[0], "224.0.62.2", 2); /* default: should go to channel 0 */ #endif if(rehash_rss) pfring_enable_rss_rehash(ring[i]); if(poll_duration > 0) pfring_set_poll_duration(ring[i], poll_duration); pfring_enable_ring(ring[i]); pthread_create(&pd_thread[i], NULL, packet_consumer_thread, (void*)i); usleep(500); } if(cpu_percentage > 0) { if(cpu_percentage > 99) cpu_percentage = 99; pfring_config(cpu_percentage); } signal(SIGINT, sigproc); signal(SIGTERM, sigproc); signal(SIGINT, sigproc); if(!verbose) { signal(SIGALRM, my_sigalarm); alarm(ALARM_SLEEP); } for(i=0; i<num_channels; i++) { pthread_join(pd_thread[i], NULL); pfring_close(ring[i]); } return(0); }