int pfring_mod_stack_open(pfring *ring) { int rc; u_int32_t dummy = 0; rc = pfring_mod_open(ring); if (rc != 0) return rc; rc = setsockopt(ring->fd, 0, SO_SET_STACK_INJECTION_MODE, &dummy, sizeof(dummy)); if (rc != 0) { pfring_close(ring); return rc; } pfring_set_direction(ring, tx_only_direction); pfring_set_socket_mode(ring, send_and_recv_mode); /* Only send (inject) and recv (intercept tx) are supported, resetting unused func ptrs */ ring->set_direction = NULL; ring->set_cluster = NULL; ring->remove_from_cluster = NULL; ring->set_master_id = NULL; ring->set_master = NULL; ring->enable_rss_rehash = NULL; ring->set_virtual_device = NULL; ring->add_hw_rule = NULL; ring->remove_hw_rule = NULL; ring->send_last_rx_packet = NULL; return 0; }
pfring *pfring_open(const char *device_name, u_int32_t caplen, u_int32_t flags) { int i = -1; int mod_found = 0; int ret; char *str, *str1; pfring *ring; #ifdef RING_DEBUG printf("[PF_RING] Attempting to pfring_open(%s)\n", device_name); #endif ring = (pfring*)malloc(sizeof(pfring)); if(ring == NULL) return NULL; if(caplen > MAX_CAPLEN) caplen = MAX_CAPLEN; memset(ring, 0, sizeof(pfring)); ring->caplen = caplen; ring->direction = rx_and_tx_direction; ring->mode = send_and_recv_mode; ring->ft_mode = software_only; ring->promisc = !!(flags & PF_RING_PROMISC); ring->reentrant = !!(flags & PF_RING_REENTRANT); ring->long_header = !!(flags & PF_RING_LONG_HEADER); ring->rss_mode = (flags & PF_RING_DNA_SYMMETRIC_RSS) ? PF_RING_DNA_SYMMETRIC_RSS : ( (flags & PF_RING_DNA_FIXED_RSS_Q_0) ? PF_RING_DNA_FIXED_RSS_Q_0 : 0); ring->force_timestamp = !!(flags & PF_RING_TIMESTAMP); ring->strip_hw_timestamp = !!(flags & PF_RING_STRIP_HW_TIMESTAMP); ring->hw_ts.enable_hw_timestamp = !!(flags & PF_RING_HW_TIMESTAMP); ring->tx.enabled_rx_packet_send = !!(flags & PF_RING_RX_PACKET_BOUNCE); ring->disable_parsing = !!(flags & PF_RING_DO_NOT_PARSE); ring->disable_timestamp = !!(flags & PF_RING_DO_NOT_TIMESTAMP); ring->chunk_mode_enabled = !!(flags & PF_RING_CHUNK_MODE); ring->ixia_timestamp_enabled = !!(flags & PF_RING_IXIA_TIMESTAMP); ring->force_userspace_bpf = !!(flags & PF_RING_USERSPACE_BPF); #ifdef RING_DEBUG printf("[PF_RING] pfring_open: device_name=%s\n", device_name); #endif /* modules */ if(device_name) { ret = -1; ring->device_name = NULL; while (pfring_module_list[++i].name) { str = str1 = NULL; #ifdef HAVE_DNA u_int8_t is_dna = 0; if(strcmp(pfring_module_list[i].name, "dna") == 0) { /* DNA module: check proc for renamed interfaces */ FILE *proc_net_pfr; char line[256]; char tmp[32]; char *at; snprintf(tmp, sizeof(tmp), "%s", device_name); at = strchr(tmp, '@'); if (at != NULL) at[0] = '\0'; snprintf(line, sizeof(line), "/proc/net/pf_ring/dev/%s/info", tmp); proc_net_pfr = fopen(line, "r"); if(proc_net_pfr != NULL) { const char *str_mode = "Polling Mode:"; while(fgets(line, sizeof(line), proc_net_pfr) != NULL) { char *p = &line[0]; if (!strncmp(p, str_mode, strlen(str_mode))) { p += strlen(str_mode); is_dna = (strstr(p, "DNA") != NULL); break; } } fclose(proc_net_pfr); } if (!is_dna) continue; } else #endif if(!(str = strstr(device_name, pfring_module_list[i].name))) continue; if(!pfring_module_list[i].open) continue; mod_found = 1; #ifdef RING_DEBUG printf("[PF_RING] pfring_open: found module %s\n", pfring_module_list[i].name); #endif if (str != NULL) { str1 = strchr(str, ':'); if (str1 != NULL) str1++; } ring->device_name = str1 ? strdup(str1) : strdup(device_name); ret = pfring_module_list[i].open(ring); break; } } /* default */ if(!mod_found) { ring->device_name = strdup(device_name ? device_name : "any"); ret = pfring_mod_open(ring); } if(ret < 0) { errno = ENODEV; if(ring->device_name) free(ring->device_name); free(ring); return NULL; } if(unlikely(ring->reentrant)) { pthread_rwlock_init(&ring->rx_lock, PTHREAD_PROCESS_PRIVATE); pthread_rwlock_init(&ring->tx_lock, PTHREAD_PROCESS_PRIVATE); } ring->socket_default_accept_policy = 1; /* Accept (default) */ ring->rdi.device_id = ring->rdi.port_id = -1; /* Default */ ring->mtu_len = pfring_get_mtu_size(ring); if(ring->mtu_len == 0) ring->mtu_len = 9000 /* Jumbo MTU */; ring->mtu_len += sizeof(struct ether_header) + sizeof(struct eth_vlan_hdr); pfring_get_bound_device_ifindex(ring, &ring->device_id); ring->initialized = 1; #ifdef RING_DEBUG printf("[PF_RING] Successfully open pfring_open(%s)\n", device_name); #endif return ring; }
pfring* pfring_open(char *device_name, u_int8_t promisc, u_int32_t caplen, u_int8_t _reentrant) { int i = -1; int mod_found = 0; int ret; char *str; pfring *ring; #ifdef RING_DEBUG printf("[PF_RING] Attempting to pfring_open(%s)\n", device_name); #endif ring = (pfring*)malloc(sizeof(pfring)); if(ring == NULL) return NULL; memset(ring, 0, sizeof(pfring)); ring->promisc = promisc; ring->caplen = caplen; ring->reentrant = _reentrant; ring->direction = rx_and_tx_direction; #ifdef RING_DEBUG printf("pfring_open: device_name=%s\n", device_name); #endif /* modules */ if(device_name) { ret = -1; ring->device_name = NULL; #ifdef HAVE_DNA /* Check if this is a DNA adapter and for some reason the user forgot to add dna:ethX */ if(strcmp(device_name, "any") && strcmp(device_name, "lo") && strncmp(device_name, "dna:", 4)) { ring->device_name = strdup(device_name); ret = pfring_dna_open(ring); } #endif if(ret >= 0) { /* The DNA device exists */ mod_found = 1; } else { if (ring->device_name != NULL) { free(ring->device_name); ring->device_name = NULL; } while (pfring_module_list[++i].name) { if(!(str = strstr(device_name, pfring_module_list[i].name))) continue; if(!(str = strchr(str, ':'))) continue; if(!pfring_module_list[i].open) continue; #ifdef RING_DEBUG printf("pfring_open: found module %s\n", pfring_module_list[i].name); #endif mod_found = 1; ring->device_name = strdup(++str); ret = pfring_module_list[i].open(ring); break; } } } /* default */ if(!mod_found) { ring->device_name = strdup(device_name ? device_name : "any"); ret = pfring_mod_open(ring); } if(ret < 0) { if(ring->device_name) free(ring->device_name); free(ring); return NULL; } if(ring->reentrant) pthread_spin_init(&ring->spinlock, PTHREAD_PROCESS_PRIVATE); ring->initialized = 1; #ifdef RING_DEBUG printf("[PF_RING] Successfully open pfring_open(%s)\n", device_name); #endif return ring; }
pfring* pfring_open(const char *device_name, u_int32_t caplen, u_int32_t flags) { int i = -1; int mod_found = 0; int ret; char *str, *str1; pfring *ring; #ifdef RING_DEBUG printf("[PF_RING] Attempting to pfring_open(%s)\n", device_name); #endif ring = (pfring*)malloc(sizeof(pfring)); if(ring == NULL) return NULL; memset(ring, 0, sizeof(pfring)); ring->promisc = (flags & PF_RING_PROMISC) ? 1 : 0; ring->caplen = caplen; ring->reentrant = (flags & PF_RING_REENTRANT) ? 1 : 0; ring->direction = rx_and_tx_direction; ring->mode = send_and_recv_mode; ring->long_header = (flags & PF_RING_LONG_HEADER) ? 1 : 0; ring->rss_mode = (flags & PF_RING_DNA_SYMMETRIC_RSS) ? PF_RING_DNA_SYMMETRIC_RSS : ( (flags & PF_RING_DNA_FIXED_RSS_Q_0) ? PF_RING_DNA_FIXED_RSS_Q_0 : 0); ring->force_timestamp = (flags & PF_RING_TIMESTAMP) ? 1 : 0; ring->strip_hw_timestamp = (flags & PF_RING_STRIP_HW_TIMESTAMP) ? 1 : 0; ring->hw_ts.enable_hw_timestamp = (flags & PF_RING_HW_TIMESTAMP) ? 1 : 0; ring->tx.enabled_rx_packet_send = (flags & PF_RING_RX_PACKET_BOUNCE) ? 1 : 0; ring->disable_parsing = (flags & PF_RING_DO_NOT_PARSE) ? 1 : 0; ring->disable_timestamp = (flags & PF_RING_DO_NOT_TIMESTAMP) ? 1 : 0; #ifdef RING_DEBUG printf("pfring_open: device_name=%s\n", device_name); #endif /* modules */ if(device_name) { ret = -1; ring->device_name = NULL; while (pfring_module_list[++i].name) { str = str1 = NULL; #ifdef HAVE_DNA u_int8_t is_dna = 0; if(strcmp(pfring_module_list[i].name, "dna") == 0) { /* DNA module: check proc for renamed interfaces */ FILE *proc_net_pfr; char line[256]; snprintf(line, sizeof(line), "/proc/net/pf_ring/dev/%s/info", device_name); proc_net_pfr = fopen(line, "r"); if(proc_net_pfr != NULL) { const char *str_mode = "Polling Mode:"; while(fgets(line, sizeof(line), proc_net_pfr) != NULL) { char *p = &line[0]; if (!strncmp(p, str_mode, strlen(str_mode))) { p += strlen(str_mode); is_dna = (strstr(p, "DNA") != NULL); break; } } } } if (!is_dna) /* if already recognized as dna do not check module prefix */ #endif if(!(str = strstr(device_name, pfring_module_list[i].name))) continue; if(!pfring_module_list[i].open) continue; mod_found = 1; #ifdef RING_DEBUG printf("pfring_open: found module %s\n", pfring_module_list[i].name); #endif if (str != NULL) { str1 = strchr(str, ':'); if (str1 != NULL) str1++; } ring->device_name = str1 ? strdup(str1) : strdup(device_name); ret = pfring_module_list[i].open(ring); break; } } /* default */ if(!mod_found) { ring->device_name = strdup(device_name ? device_name : "any"); ret = pfring_mod_open(ring); } if(ret < 0) { if(ring->device_name) free(ring->device_name); free(ring); return NULL; } if(unlikely(ring->reentrant)) { pthread_rwlock_init(&ring->rx_lock, PTHREAD_PROCESS_PRIVATE); pthread_rwlock_init(&ring->tx_lock, PTHREAD_PROCESS_PRIVATE); } ring->socket_default_accept_policy = 1; /* Accept (default) */ ring->rdi.device_id = ring->rdi.port_id = -1; /* Default */ ring->mtu_len = pfring_get_mtu_size(ring); if(ring->mtu_len == 0) ring->mtu_len = 9000 /* Jumbo MTU */; ring->mtu_len += sizeof(struct ether_header); ring->initialized = 1; #ifdef RING_DEBUG printf("[PF_RING] Successfully open pfring_open(%s)\n", device_name); #endif return ring; }