static int max_packet_len(Pfring_Context_t *context, char *device, int id, int *card_buffers) { int max_len = 1536, num_slots = 32768 /* max */; pfring *ring; ring = pfring_open(device, 1536, PF_RING_PROMISC); if (ring == NULL) goto error; pfring_get_bound_device_ifindex(ring, &context->ifindexes[id]); if (ring->zc_device) { pfring_card_settings settings; pfring_get_card_settings(ring, &settings); max_len = settings.max_packet_size; num_slots = settings.rx_ring_slots; } else { max_len = pfring_get_mtu_size(ring); if (max_len == 0) max_len = 9000; max_len += 14 + 4; num_slots = 0; } pfring_close(ring); error: *card_buffers = num_slots; return max_len; }
void PfRingDevice::setPfRingDeviceAttributes() { if (m_InterfaceIndex > -1) return; pfring* ring = NULL; bool closeRing = false; if (m_NumOfOpenedRxChannels > 0) ring = m_PfRingDescriptors[0]; else { uint32_t flags = PF_RING_PROMISC | PF_RING_DNA_SYMMETRIC_RSS; ring = pfring_open(m_DeviceName, DEFAULT_PF_RING_SNAPLEN, flags); closeRing = true; } if (ring == NULL) { LOG_ERROR("Could not open a pfring for setting device attributes: MAC address, interface index and HW clock"); return; } // set device MAC address uint8_t macAddress[6]; if (pfring_get_bound_device_address(ring, macAddress) < 0) LOG_ERROR("Unable to read the device MAC address for interface '%s'", m_DeviceName); else m_MacAddress = MacAddress(macAddress); // set interface ID if (pfring_get_bound_device_ifindex(ring, &m_InterfaceIndex) < 0) LOG_ERROR("Unable to read interface index of device"); // try to set hardware device clock m_HwClockEnabled = setPfRingDeviceClock(ring); // set interface MTU int mtu = pfring_get_mtu_size(ring); if (mtu < 0) LOG_ERROR("Could not get MTU. pfring_get_mtu_size returned an error: %d", mtu); else m_DeviceMTU = mtu + sizeof(ether_header) + sizeof(vlan_header); if (LoggerPP::getInstance().isDebugEnabled(PcapLogModulePfRingDevice)) { std::string hwEnabled = (m_HwClockEnabled ? "enabled" : "disabled"); LOG_DEBUG("Capturing from %s [%s][ifIndex: %d][MTU: %d], HW clock %s", m_DeviceName, m_MacAddress.toString().c_str(), m_InterfaceIndex, m_DeviceMTU, hwEnabled.c_str()); } if (closeRing) pfring_close(ring); }
static int max_packet_len(Pfring_Context_t *context, char *device, int id) { int max_len; pfring *ring; ring = pfring_open(device, 1536, PF_RING_PROMISC); if (ring == NULL) return 1536; pfring_get_bound_device_ifindex(ring, &context->ifindexes[id]); if (ring->dna.dna_mapped_device) { max_len = ring->dna.dna_dev.mem_info.rx.packet_memory_slot_len; } else { max_len = pfring_get_mtu_size(ring); if (max_len == 0) max_len = 9000; max_len += 14 + 4; } pfring_close(ring); return max_len; }
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; }
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 main(int argc, char* argv[]) { pfring *a_ring, *b_ring; char *a_dev = NULL, *b_dev = NULL, c; u_int8_t verbose = 0, use_pfring_send = 0; int a_ifindex, b_ifindex; int bind_core = -1; u_int16_t watermark = 1; while((c = getopt(argc,argv, "ha:b:c:fvpg:w:")) != -1) { switch(c) { case 'h': printHelp(); return 0; break; case 'a': a_dev = strdup(optarg); break; case 'b': b_dev = strdup(optarg); break; case 'p': use_pfring_send = 1; break; case 'v': verbose = 1; break; case 'g': bind_core = atoi(optarg); break; case 'w': watermark = atoi(optarg); break; } } if ((!a_dev) || (!b_dev)) { printf("You must specify two devices!\n"); return -1; } if(strcmp(a_dev, b_dev) == 0) { printf("Bridge devices must be different!\n"); return -1; } /* Device A */ if((a_ring = pfring_open(a_dev, MAX_PKT_LEN, PF_RING_PROMISC | PF_RING_LONG_HEADER | (use_pfring_send ? 0 : PF_RING_RX_PACKET_BOUNCE)) ) == NULL) { printf("pfring_open error for %s [%s]\n", a_dev, strerror(errno)); return(-1); } pfring_set_application_name(a_ring, "pfbridge-a"); pfring_set_direction(a_ring, rx_only_direction); pfring_set_socket_mode(a_ring, recv_only_mode); pfring_set_poll_watermark(a_ring, watermark); pfring_get_bound_device_ifindex(a_ring, &a_ifindex); /* Device B */ if((b_ring = pfring_open(b_dev, MAX_PKT_LEN, PF_RING_PROMISC|PF_RING_LONG_HEADER)) == NULL) { printf("pfring_open error for %s [%s]\n", b_dev, strerror(errno)); pfring_close(a_ring); return(-1); } pfring_set_application_name(b_ring, "pfbridge-b"); pfring_set_socket_mode(b_ring, send_only_mode); pfring_get_bound_device_ifindex(b_ring, &b_ifindex); /* Enable Sockets */ if (pfring_enable_ring(a_ring) != 0) { printf("Unable enabling ring 'a' :-(\n"); pfring_close(a_ring); pfring_close(b_ring); return(-1); } if(use_pfring_send) { if (pfring_enable_ring(b_ring)) { printf("Unable enabling ring 'b' :-(\n"); pfring_close(a_ring); pfring_close(b_ring); return(-1); } } else { pfring_close(b_ring); } signal(SIGALRM, my_sigalarm); alarm(1); if(bind_core >= 0) bind2core(bind_core); while(1) { u_char *buffer; struct pfring_pkthdr hdr; if(pfring_recv(a_ring, &buffer, 0, &hdr, 1) > 0) { int rc; if(use_pfring_send) { rc = pfring_send(b_ring, (char *) buffer, hdr.caplen, 1); if(rc < 0) printf("pfring_send(caplen=%u <= mtu=%u?) error %d\n", hdr.caplen, b_ring->mtu_len, rc); else if(verbose) printf("Forwarded %d bytes packet\n", hdr.len); } else { rc = pfring_send_last_rx_packet(a_ring, b_ifindex); if(rc < 0) printf("pfring_send_last_rx_packet() error %d\n", rc); else if(verbose) printf("Forwarded %d bytes packet\n", hdr.len); } if(rc >= 0) num_sent++; } } pfring_close(a_ring); if(use_pfring_send) pfring_close(b_ring); return(0); }
int main(int argc, char* argv[]) { pfring *a_ring, *b_ring; char *a_dev = NULL, *b_dev = NULL, c; u_int8_t verbose = 0, use_pfring_send = 0; int a_ifindex, b_ifindex; while((c = getopt(argc,argv, "ha:b:c:fvp")) != -1) { switch(c) { case 'h': printHelp(); return 0; break; case 'a': a_dev = strdup(optarg); break; case 'b': b_dev = strdup(optarg); break; case 'p': use_pfring_send = 1; break; case 'v': verbose = 1; break; } } if ((!a_dev) || (!b_dev)) { printf("You must specify two devices!\n"); return -1; } if(strcmp(a_dev, b_dev) == 0) { printf("Bridge devices must be different!\n"); return -1; } /* open devices */ if((a_ring = pfring_open(a_dev, 1500, PF_RING_PROMISC|PF_RING_LONG_HEADER)) == NULL) { printf("pfring_open error for %s [%s]\n", a_dev, strerror(errno)); return(-1); } else { pfring_set_application_name(a_ring, "pfbridge-a"); pfring_set_direction(a_ring, rx_and_tx_direction); pfring_get_bound_device_ifindex(a_ring, &a_ifindex); } if((b_ring = pfring_open(b_dev, 1500, PF_RING_PROMISC|PF_RING_LONG_HEADER)) == NULL) { printf("pfring_open error for %s [%s]\n", b_dev, strerror(errno)); pfring_close(a_ring); return(-1); } else { pfring_set_application_name(b_ring, "pfbridge-b"); pfring_set_direction(b_ring, rx_and_tx_direction); pfring_get_bound_device_ifindex(b_ring, &b_ifindex); } /* Enable rings */ pfring_enable_ring(a_ring); if(use_pfring_send) pfring_enable_ring(b_ring); else pfring_close(b_ring); signal(SIGALRM, my_sigalarm); alarm(1); while(1) { u_char *buffer; struct pfring_pkthdr hdr; if(pfring_recv(a_ring, &buffer, 0, &hdr, 1) > 0) { int rc; if(use_pfring_send) { rc = pfring_send(b_ring, (char*)buffer, hdr.caplen, 1); if(rc < 0) printf("pfring_send_last_rx_packet() error %d\n", rc); else if(verbose) printf("Forwarded %d bytes packet\n", hdr.len); } else { rc = pfring_send_last_rx_packet(a_ring, b_ifindex); if(rc < 0) printf("pfring_send_last_rx_packet() error %d\n", rc); else if(verbose) printf("Forwarded %d bytes packet\n", hdr.len); } if(rc >= 0) num_sent++; } } pfring_close(a_ring); if(use_pfring_send) pfring_close(b_ring); return(0); }