int setup_steering(pfring* thering, const char* addr, int queue) { int rc; static int rule_id = 0; // @HACK! hw_filtering_rule rule; intel_82599_perfect_filter_hw_rule *perfect_rule; if (thering == 0 || addr == 0) { errno = EINVAL; return -1; } printf("### Perfect Rule Example ###\n"); rc = pfring_set_filtering_mode(thering, hardware_only); printf("pfring_set_filtering_mode: hardware_only %s(%d)\n", (rc == 0) ? "SUCCEEDED" : "FAILED", rc ); /* NOTE: - valid protocols: UDP or TCP */ perfect_rule = &rule.rule_family.perfect_rule; memset(&rule, 0, sizeof(rule)); rule.rule_family_type = intel_82599_perfect_filter_rule; rule.rule_id = rule_id++; perfect_rule->queue_id = queue; perfect_rule->proto = IPPROTO_UDP; perfect_rule->d_addr = ntohl(inet_addr(addr)); rc = pfring_add_hw_rule(thering, &rule); if(rc != 0) printf("pfring_add_hw_rule(%d) failed [rc=%d]: " "did you enable the FlowDirector " "(ethtool -K ethX ntuple on)\n", rule.rule_id, rc); else printf("pfring_add_hw_rule(%d) succeeded: " "steering UDP traffic %s:* -> *\n", rule.rule_id, addr); return rc; }
static int pfring_daq_open(Pfring_Context_t *context, int id) { uint32_t default_net = 0xFFFFFF00; char *device = context->devices[id]; int pfring_rc; pfring *ring_handle; char buf[32]; if(!device) { DPE(context->errbuf, "%s", "PF_RING a device must be specified"); return -1; } if(device) { if(strncmp(device, "dna", 3) == 0) { DPE(context->errbuf, "DNA is not supported by daq_pfring. Please get daq_pfring_dna from http://shop.ntop.org"); return(-1); } context->pkt_buffer = NULL; ring_handle = pfring_open(device, context->snaplen, PF_RING_LONG_HEADER | (context->promisc_flag ? PF_RING_PROMISC : 0)); if(!ring_handle) { DPE(context->errbuf, "pfring_open(): unable to open device '%s'. Please use -i <device>", device); return -1; } } pfring_get_bound_device_ifindex(ring_handle, &context->ifindexes[id]); /* TODO this is because rules purging is not yet available with hw rules */ pfring_set_filtering_mode(ring_handle, software_only); if (context->mode == DAQ_MODE_INLINE) { /* Default mode: recv_and_send_mode */ pfring_set_direction(ring_handle, rx_only_direction); } else if (context->mode == DAQ_MODE_PASSIVE) { /* Default direction: rx_and_tx_direction */ if(context->num_reflector_devices > id) { /* lowlevelbridge ON */ filtering_rule rule; memset(&rule, 0, sizeof(rule)); rule.rule_id = 1; rule.rule_action = reflect_packet_and_continue_rule_evaluation; snprintf(rule.reflector_device_name, REFLECTOR_NAME_LEN, "%s", context->reflector_devices[id]); if(pfring_add_filtering_rule(ring_handle, &rule) < 0) { DPE(context->errbuf, "unable to set the low level packet reflector %s -> %s", device, rule.reflector_device_name); pfring_close(ring_handle); return -1; } else printf("%s -> %s\n", context->devices[id], context->reflector_devices[id]); pfring_set_direction(ring_handle, rx_only_direction); } pfring_set_socket_mode(ring_handle, recv_only_mode); } if(context->clusterids[id] > 0) { pfring_rc = pfring_set_cluster(ring_handle, context->clusterids[id], context->cluster_mode); if(pfring_rc != 0) { DPE(context->errbuf, "pfring_set_cluster returned %d", pfring_rc); pfring_close(ring_handle); return -1; } snprintf(buf, sizeof(buf), "snort-cluster-%d-socket-%d", context->clusterids[id], id); pfring_set_application_name(ring_handle, buf); } else { snprintf(buf, sizeof(buf), "snort-socket-%d", id); pfring_set_application_name(ring_handle, buf); } pfring_set_poll_watermark(ring_handle, context->watermark); context->netmask = htonl(default_net); context->ring_handles[id] = ring_handle; return(0); }
int pfring_dna_open(pfring *ring) { int channel_id = 0; int rc; int i; char *at; ring->direction = rx_only_direction; ring->close = pfring_dna_close; ring->set_sampling_rate = pfring_dna_set_sampling_rate; ring->stats = pfring_dna_stats; ring->recv = pfring_dna_recv; ring->enable_ring = pfring_dna_enable_ring; ring->set_direction = pfring_dna_set_direction; ring->poll = pfring_dna_poll; ring->set_poll_watermark = pfring_mod_set_poll_watermark; ring->set_poll_duration = pfring_mod_set_poll_duration; ring->set_channel_id = pfring_mod_set_channel_id; ring->set_application_name = pfring_mod_set_application_name; ring->set_application_stats = pfring_mod_set_application_stats; ring->get_appl_stats_file_name = pfring_mod_get_appl_stats_file_name; ring->bind = pfring_mod_bind; ring->get_num_rx_channels = pfring_mod_get_num_rx_channels; ring->get_selectable_fd = pfring_mod_get_selectable_fd; ring->set_socket_mode = pfring_mod_set_socket_mode; ring->get_ring_id = pfring_mod_get_ring_id; ring->version = pfring_mod_version; ring->get_bound_device_address = pfring_mod_get_bound_device_address; ring->get_bound_device_ifindex = pfring_mod_get_bound_device_ifindex; ring->get_device_ifindex = pfring_mod_get_device_ifindex; ring->get_slot_header_len = pfring_mod_get_slot_header_len; ring->set_virtual_device = pfring_mod_set_virtual_device; ring->add_hw_rule = pfring_hw_ft_add_hw_rule; ring->remove_hw_rule = pfring_hw_ft_remove_hw_rule; ring->loopback_test = pfring_mod_loopback_test; ring->disable_ring = pfring_mod_disable_ring; ring->handle_hash_filtering_rule = pfring_mod_handle_hash_filtering_rule; ring->add_filtering_rule = pfring_mod_add_filtering_rule; ring->remove_filtering_rule = pfring_mod_remove_filtering_rule; ring->toggle_filtering_policy = pfring_mod_toggle_filtering_policy; ring->shutdown = pfring_mod_shutdown; /* These functions are set by the dna library: (when supported by the device) * ring->send * ring->send_get_time * ring->next_pkt_time * ring->next_pkt_raw_timestamp * ring->set_device_clock * ring->get_device_clock */ ring->poll_duration = DEFAULT_POLL_DURATION; ring->dna.last_dna_operation = remove_device_mapping; ring->fd = socket(PF_RING, SOCK_RAW, htons(ETH_P_ALL)); #ifdef DEBUG printf("Open RING [fd=%d]\n", ring->fd); #endif if(ring->fd < 0) return -1; at = strchr(ring->device_name, '@'); if(at != NULL) { at[0] = '\0'; /* Syntax ethX@1 channel 1 */ channel_id = atoi(&at[1]); } ring->dna.dna_dev.channel_id = channel_id; rc = pfring_map_dna_device(ring, add_device_mapping, ring->device_name); if(rc < 0) { #if 0 printf("pfring_map_dna_device() failed [rc=%d]: device already in use, channel not existing or non-DNA driver?\n", rc); printf("Make sure that you load the DNA-driver *after* you loaded the PF_RING kernel module\n"); #endif return -1; } rc = pfring_get_mapped_dna_device(ring, &ring->dna.dna_dev); if(rc < 0) { printf("pfring_get_mapped_dna_device() failed [rc=%d]\n", rc); pfring_map_dna_device(ring, remove_device_mapping, ring->device_name); close(ring->fd); return -1; } #ifdef DEBUG printf("[num_slots=%d][slot_len=%d][tot_mem_len=%d]\n", ring->dna.dna_dev.packet_memory_num_slots, ring->dna.dna_dev.packet_memory_slot_len, ring->dna.dna_dev.packet_memory_tot_len); printf("[memory_num_slots=%d][memory_slot_len=%d]" "[memory_tot_len=%d]\n", ring->dna.dna_dev.descr_packet_memory_num_slots, ring->dna.dna_dev.descr_packet_memory_slot_len, ring->dna.dna_dev.descr_packet_memory_tot_len); #endif ring->dna.dna_mapped_device = 1; /* ***************************************** */ for(i=0; i<ring->dna.dna_dev.mem_info.rx.packet_memory_num_chunks; i++) { ring->dna.dna_dev.rx_packet_memory[i] = (unsigned long)mmap(NULL, ring->dna.dna_dev.mem_info.rx.packet_memory_chunk_len, PROT_READ|PROT_WRITE, MAP_SHARED, ring->fd, (100+i)*getpagesize()); if(ring->dna.dna_dev.rx_packet_memory[i] == (unsigned long)MAP_FAILED) { printf("mmap(100/%d) failed", i); close(ring->fd); return -1; } } /* ***************************************** */ for(i=0; i<ring->dna.dna_dev.mem_info.tx.packet_memory_num_chunks; i++) { ring->dna.dna_dev.tx_packet_memory[i] = (unsigned long)mmap(NULL, ring->dna.dna_dev.mem_info.tx.packet_memory_chunk_len, PROT_READ|PROT_WRITE, MAP_SHARED, ring->fd, (100+ring->dna.dna_dev.mem_info.rx.packet_memory_num_chunks+i)*getpagesize()); if(ring->dna.dna_dev.tx_packet_memory[i] == (unsigned long)MAP_FAILED) { printf("mmap(100/%d) failed", i); close(ring->fd); return -1; } } /* ***************************************** */ if(ring->dna.dna_dev.mem_info.rx.descr_packet_memory_tot_len > 0) { ring->dna.dna_dev.rx_descr_packet_memory = (void*)mmap(NULL, ring->dna.dna_dev.mem_info.rx.descr_packet_memory_tot_len, PROT_READ|PROT_WRITE, MAP_SHARED, ring->fd, 1*getpagesize()); if(ring->dna.dna_dev.rx_descr_packet_memory == MAP_FAILED) { printf("mmap(1) failed"); close(ring->fd); return -1; } } /* ***************************************** */ if(ring->dna.dna_dev.mem_info.tx.descr_packet_memory_tot_len > 0) { ring->dna.dna_dev.tx_descr_packet_memory = (void*)mmap(NULL, ring->dna.dna_dev.mem_info.tx.descr_packet_memory_tot_len, PROT_READ|PROT_WRITE, MAP_SHARED, ring->fd, 3*getpagesize()); if(ring->dna.dna_dev.tx_descr_packet_memory == MAP_FAILED) { printf("mmap(3) failed"); close(ring->fd); return -1; } } /* ***************************************** */ if(ring->dna.dna_dev.mem_info.phys_card_memory_len > 0) { /* some DNA drivers do not use this memory */ ring->dna.dna_dev.phys_card_memory = (void*)mmap(NULL, ring->dna.dna_dev.mem_info.phys_card_memory_len, PROT_READ|PROT_WRITE, MAP_SHARED, ring->fd, 2*getpagesize()); if(ring->dna.dna_dev.phys_card_memory == MAP_FAILED) { printf("mmap(2) failed"); close(ring->fd); return -1; } } /* ***************************************** */ if(ring->promisc) { if(pfring_set_if_promisc(ring->device_name, 1) == 0) ring->clear_promisc = 1; } /* ***************************************** */ pfring_set_filtering_mode(ring, hardware_only); /* ***************************************** */ rc = dna_init(ring, sizeof(pfring)); if(rc < 0) { printf("dna_init() failed\n"); close(ring->fd); return rc; } pfring_enable_hw_timestamp(ring, ring->device_name, ring->hw_ts.enable_hw_timestamp ? 1 : 0, 0 /* TX timestamp disabled by default */); #ifdef DEBUG pfring_dump_dna_stats(ring); #endif pfring_hw_ft_init(ring); return 0; }