bool PfRingDevice::setFilter(std::string filterAsString) { if (!m_DeviceOpened) { LOG_ERROR("Device not opened"); return false; } for (int i = 0; i < m_NumOfOpenedRxChannels; i++) { int res = pfring_set_bpf_filter(m_PfRingDescriptors[i], (char*)filterAsString.c_str()); if(res < 0) { if (res == PF_RING_ERROR_NOT_SUPPORTED) LOG_ERROR("BPF filtering isn't supported on current PF_RING version. Please re-compile PF_RING with the --enable-bpf flag"); else LOG_ERROR("Couldn't set filter '%s'", filterAsString.c_str()); return false; } } m_IsFilterCurrentlySet = true; LOG_DEBUG("Successfully set filter '%s'", filterAsString.c_str()); return true; }
void reader_pfring_init(char *UNUSED(name)) { int flags = PF_RING_PROMISC | PF_RING_TIMESTAMP; int clusterId = moloch_config_int(NULL, "pfringClusterId", 0, 0, 255); int i; for (i = 0; i < MAX_INTERFACES && config.interface[i]; i++) { rings[i] = pfring_open(config.interface[i], MOLOCH_SNAPLEN, flags); if (config.bpf) { int err = pfring_set_bpf_filter(rings[i], config.bpf); if (err < 0) { LOG("pfring set filter error %d for %s", err, config.bpf); exit (1); } } if (!rings[i]) { LOG("pfring open failed! - %s", config.interface[i]); exit(1); } pfring_set_cluster(rings[i], clusterId, cluster_per_flow_5_tuple); pfring_set_application_name(rings[i], "moloch-capture"); pfring_set_poll_watermark(rings[i], 64); pfring_enable_rss_rehash(rings[i]); } moloch_reader_start = reader_pfring_start; moloch_reader_stop = reader_pfring_stop; moloch_reader_stats = reader_pfring_stats; }
long stream_pfring_open(struct stream** stptr, const struct ether_addr* addr, const char* iface, size_t buffer_size){ int ret = 0; assert(stptr); /* validate arguments */ if ( !(addr && iface) ){ return EINVAL; } /* get MTU for interface */ const int if_mtu = iface_mtu(iface); if ( if_mtu < 0 ){ return errno; } pfring_config(99); /* open pfring */ char* derp = strdup(iface); pfring* pd = pfring_open(derp, 1, 9000, 0); if ( !pd ){ return errno; } pfring_set_application_name(pd, "libcap_utils"); uint32_t version; pfring_version(pd, &version); fprintf(stderr, "Using PF_RING v.%d.%d.%d\n", (version & 0xFFFF0000) >> 16, (version & 0x0000FF00) >> 8, version & 0x000000FF); if((ret = pfring_set_direction(pd, rx_and_tx_direction)) != 0) fprintf(stderr, "pfring_set_direction returned %d (perhaps you use a direction other than rx only with DNA ?)\n", ret); if((ret = pfring_set_socket_mode(pd, recv_only_mode)) != 0) fprintf(stderr, "pfring_set_socket_mode returned [rc=%d]\n", ret); char bpfFilter[] = "ether proto 0x810"; ret = pfring_set_bpf_filter(pd, bpfFilter); if ( ret != 0 ) { fprintf(stderr, "pfring_set_bpf_filter(%s) returned %d\n", bpfFilter, ret); } else { fprintf(stderr, "Successfully set BPF filter '%s'\n", bpfFilter); } /* default buffer_size of 25*MTU */ if ( buffer_size == 0 ){ buffer_size = 250 * if_mtu; } /* ensure buffer is a multiple of MTU and can hold at least one frame */ if ( buffer_size < if_mtu ){ return ERROR_BUFFER_LENGTH; } else if ( buffer_size % if_mtu != 0 ){ return ERROR_BUFFER_MULTIPLE; } /* additional memory for the frame pointers */ size_t frames = buffer_size / if_mtu; size_t frame_offset = sizeof(char*) * frames; buffer_size += frame_offset; /* Initialize the structure */ if ( (ret = stream_alloc(stptr, PROTOCOL_ETHERNET_MULTICAST, sizeof(struct stream_pfring), buffer_size) != 0) ){ return ret; } struct stream_pfring* st = (struct stream_pfring*)*stptr; st->pd = pd; st->num_address = 0; st->if_mtu = if_mtu; memset(st->seqnum, 0, sizeof(long unsigned int) * MAX_ADDRESS); if (pfring_enable_ring(pd) != 0) { fprintf(stderr, "Unable to enable ring :-(\n"); pfring_close(pd); return(-1); } /* setup buffer pointers (see brief overview at struct declaration) */ st->num_frames = frames; st->num_packets = 0; st->read_ptr = NULL; st->base.readPos = 0; st->base.writePos = 0; for ( unsigned int i = 0; i < frames; i++ ){ st->frame[i] = st->base.buffer + frame_offset + i * if_mtu; } /* add membership to group */ if ( (ret=stream_pfring_add(&st->base, addr)) != 0 ){ return ret; } /* if ( (ret=stream_pfring_init(stptr, addr, iface, ETH_P_ALL, buffer_size)) != 0 ){ return ret; } */ st->base.type = PROTOCOL_ETHERNET_MULTICAST; st->base.FH.comment_size = 0; st->base.comment = NULL; /* callbacks */ st->base.fill_buffer = NULL; st->base.destroy = (destroy_callback)destroy; st->base.write = NULL; st->base.read = (read_callback)stream_pfring_read; return 0; }