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;
}
int PfRingDevice::openSingleRxChannel(const char* deviceName, pfring** ring)
{
	if (m_DeviceOpened)
	{
		LOG_ERROR("Device already opened");
		return false;
	}

	uint32_t flags = PF_RING_PROMISC | PF_RING_HW_TIMESTAMP | PF_RING_DNA_SYMMETRIC_RSS;
	*ring = pfring_open(deviceName, DEFAULT_PF_RING_SNAPLEN, flags);

	if (*ring == NULL)
	{
		return 1;
	}
	LOG_DEBUG("pfring_open Succeeded for device [%s]", deviceName);

	if (getIsHwClockEnable())
	{
		setPfRingDeviceClock(*ring);
		LOG_DEBUG("H/W clock set for device [%s]", deviceName);
	}

	if (pfring_enable_rss_rehash(*ring) < 0 || pfring_enable_ring(*ring) < 0)
	{
	    pfring_close(*ring);
	    return 2;
	}

	LOG_DEBUG("pfring enabled for device [%s]", deviceName);

	return 0;
}
示例#3
0
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;
}
示例#4
0
void pfring_bundle_close(pfring_bundle *bundle) {
  int i;

  for(i=0; i<bundle->num_sockets; i++) {
    pfring_close(bundle->sockets[i]);
  }

  memset(bundle, 0, sizeof(pfring_bundle));
}
void sigproc(int sig) {

	pfring_close(handle);
	pfring_breakloop(handle);
	pcap_dump_close(dumper);

	printf("\nSniffer closed. %d files written to disk.\n",filenumber);

 	exit(0);
}
void PfRingDevice::close()
{
	for (int i = 0; i < m_NumOfOpenedRxChannels; i++)
		pfring_close(m_PfRingDescriptors[i]);
	m_DeviceOpened = false;
	clearCoreConfiguration();
	m_NumOfOpenedRxChannels = 0;
	m_IsFilterCurrentlySet = false;
	LOG_DEBUG("Device [%s] closed", m_DeviceName);
}
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);
}
示例#8
0
void sigproc(int sig) {
  static int called = 0;

  fprintf(stderr, "Leaving...\n");
  if(called) return; else called = 1;
  do_shutdown = 1;
  print_stats();
  printf("Sent %llu packets\n", (long long unsigned int)num_pkt_good_sent);
  pfring_close(pd);

  exit(0);
}
示例#9
0
void sigproc(int sig) {
  static int called = 0;
  int i = 0;

  fprintf(stderr, "Leaving...\n");
  if(called) return; else called = 1;
  do_shutdown = 1;
  print_stats();

  for(i=0; i<num_devs; i++)
    pfring_close(pd[i]);

  exit(0);
}
示例#10
0
int frame_pfring(pfring *pd, struct frame_buf *f){
	fbuf = f;
	pfcount = 0;
	packet_direction direction = rx_and_tx_direction;
	int rc;

	pfring_set_direction(pd, direction);

	if((rc = pfring_set_socket_mode(pd, recv_only_mode)) != 0)
		fprintf(stderr, "pfring_set_socket_mode returned [rc=%d]\n", rc);

	pfring_set_application_stats(pd, "statistics not yet computed, please try again...\n");
	
	if(pfring_enable_ring(pd) != 0){
		fprintf(stderr, "unable to enable ring\n");
		pfring_close(pd);
		return -1;
	}

	printf("capture start...\n");
	pfring_loop(pd, pf_dummy_packet, (u_char *)NULL, 1);
	pfring_close(pd);
	return 0;
}
示例#11
0
uint8_t PfRingDevice::getTotalNumOfRxChannels()
{
	if (m_NumOfOpenedRxChannels > 0)
	{
		uint8_t res = pfring_get_num_rx_channels(m_PfRingDescriptors[0]);
		return res;
	}
	else
	{
		uint32_t flags = PF_RING_PROMISC | PF_RING_REENTRANT | PF_RING_HW_TIMESTAMP | PF_RING_DNA_SYMMETRIC_RSS;
		pfring* ring = pfring_open(m_DeviceName, DEFAULT_PF_RING_SNAPLEN, flags);
		uint8_t res = pfring_get_num_rx_channels(ring);
		pfring_close(ring);
		return res;
	}
}
PfRingDeviceList::PfRingDeviceList()
{
	m_PfRingVersion = "";

	FILE *fd = popen("lsmod | grep pf_ring", "r");
	char buf[16];
	if (fread (buf, 1, sizeof (buf), fd) <= 0) // if there is some result the module must be loaded
	{
		LOG_ERROR("PF_RING kernel module isn't loaded. Please run: 'sudo insmod <PF_RING_LOCATION>/kernel/pf_ring.ko'");
		return;
	}

	LOG_DEBUG("PF_RING kernel module is loaded");

	pcap_if_t* interfaceList;
	char errbuf[PCAP_ERRBUF_SIZE];
	LOG_DEBUG("PfRingDeviceList init: searching all interfaces on machine");
	int err = pcap_findalldevs(&interfaceList, errbuf);
	if (err < 0)
	{
		LOG_ERROR("Error searching for PF_RING devices: %s", errbuf);
	}

	pcap_if_t* currInterface = interfaceList;
	while (currInterface != NULL)
	{
		if ((currInterface->flags & 0x1) != PCAP_IF_LOOPBACK)
		{
			uint32_t flags = PF_RING_PROMISC | PF_RING_DNA_SYMMETRIC_RSS;
			pfring* ring = pfring_open(currInterface->name, 128, flags);
			if (ring != NULL)
			{
				if (m_PfRingVersion == "")
					calcPfRingVersion(ring);
				pfring_close(ring);
				PfRingDevice* newDev = new PfRingDevice(currInterface->name);
				m_PfRingDeviceList.push_back(newDev);
				LOG_DEBUG("Found interface: %s", currInterface->name);
			}
		}

		currInterface = currInterface->next;
	}

	LOG_DEBUG("PfRingDeviceList init end");
	pcap_freealldevs(interfaceList);
}
示例#13
0
文件: pfring.c 项目: bigfg/PF_RING
void pfring_close(pfring *ring) {
  if(!ring)
    return;

  if(ring->one_copy_rx_pfring)
    pfring_close(ring->one_copy_rx_pfring);

  pfring_shutdown(ring);

  if(ring->close)
    ring->close(ring);

  if(unlikely(ring->reentrant)) {
    pthread_rwlock_destroy(&ring->rx_lock);
    pthread_rwlock_destroy(&ring->tx_lock);
  }

  free(ring->device_name);
  free(ring);
}
示例#14
0
pfring *pfring_open_consumer(const char *device_name, u_int32_t caplen, u_int32_t flags,
			     u_int8_t consumer_plugin_id,
			     char* consumer_data, u_int consumer_data_len) {
  pfring *ring = pfring_open(device_name, caplen, flags);

  if(ring) {
    if(consumer_plugin_id > 0) {
      int rc;

      ring->kernel_packet_consumer = consumer_plugin_id;
      rc = pfring_set_packet_consumer_mode(ring, consumer_plugin_id,
					   consumer_data, consumer_data_len);
      if(rc < 0) {
	pfring_close(ring);
	return(NULL);
      }
    }
  }

  return ring;
}
示例#15
0
u_int8_t pfring_open_multichannel(const char *device_name, u_int32_t caplen,
				  u_int32_t flags,
				  pfring *ring[MAX_NUM_RX_CHANNELS]) {
  u_int8_t num_channels, i, num = 0;
  char *at;
  char base_device_name[32];

  snprintf(base_device_name, sizeof(base_device_name), "%s", device_name);
  at = strchr(base_device_name, '@');
  if(at != NULL)
    at[0] = '\0';

  /* Count how many RX channel the specified device supports */
  ring[0] = pfring_open(base_device_name, caplen, flags);

  if(ring[0] == NULL)
    return(0);
  else
    num_channels = pfring_get_num_rx_channels(ring[0]);

  pfring_close(ring[0]);

  if(num_channels > MAX_NUM_RX_CHANNELS)
    num_channels = MAX_NUM_RX_CHANNELS;

  /* Now do the real job */
  for(i=0; i<num_channels; i++) {
    char dev[32];

    snprintf(dev, sizeof(dev), "%s@%d", base_device_name, i);
    ring[i] = pfring_open(dev, caplen, flags);

    if(ring[i] == NULL)
      return(num);
    else
      num++;
  }

  return(num);
}
示例#16
0
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;
}
int main(int argc, char* argv[]) {
  pfring  *pd;
  virtual_filtering_device_info info;
  int rc;

  pd = pfring_open("none", 0 /* promisc */, 128 /* snaplen */, 0 /* reentrant */);

  if(pd == NULL) {
    printf("pfring_open error\n");
    return(-1);
  } else {
    u_int32_t version;

    pfring_set_application_name(pd, "vdevice_simulator");
    pfring_version(pd, &version);

    printf("Using PF_RING v.%d.%d.%d\n",
	   (version & 0xFFFF0000) >> 16,
	   (version & 0x0000FF00) >> 8,
	   version & 0x000000FF);
  }

  strcpy(info.device_name, "vdef0");
  info.device_type = silicom_redirector_family;

  if((rc = pfring_set_virtual_device(pd, &info)) < 0) {
    printf("Unable to register virtual device %s [rc=%d]\n", info.device_name, rc);
  } else {
    printf("Succefully registered virtual device %s\n", info.device_name);

  }

  pfring_close(pd);

  return(0);
}
示例#18
0
void game_over()
{
    if (config.inpacket == 0) {
        expire_all_dns_records();
        print_pdns_stats();
        if (config.handle != NULL) pcap_close(config.handle);
        config.handle = NULL;
#ifdef HAVE_PFRING
        if (config.use_pfring && config.pfhandle != NULL) {
            pfring_breakloop(config.pfhandle);
            pfring_close(config.pfhandle);
        }
#endif /* HAVE_PFRING */
        end_all_sessions();
        if (config.logfile_fd != NULL && config.logfile_fd != stdout)
            fclose(config.logfile_fd);
        if (config.logfile_nxd_fd != NULL && config.logfile_nxd_fd != stdout)
            fclose(config.logfile_nxd_fd);
        free_config();
        olog("\n[*] passivedns ended.\n");
        exit(0);
    }
    config.intr_flag |= INTERRUPT_END;
}
示例#19
0
int main(int argc, char* argv[]) {
  pfring  *pd;
  char *device, *buffer;
  u_int buffer_len, num_runs, test_len, i, test_id, j;
  struct timeval startTime, endTime;
  double deltaUsec, call_per_sec, thpt, call_duration_usec;

  device = "eth0";
  pd = pfring_open(device, 128, PF_RING_PROMISC);

  if(pd == NULL) {
    printf("pfring_open error(%s) [%s]\n", device, strerror(errno));
    return(-1);
  } else {
    u_int32_t version;

    pfring_set_application_name(pd, "pfsystest");
    pfring_version(pd, &version);

    printf("Using PF_RING v.%d.%d.%d\n",
	   (version & 0xFFFF0000) >> 16,
	   (version & 0x0000FF00) >> 8,
	   version & 0x000000FF);
  }

  if(0) {
    test_id = 64;
    buffer_len = test_id*1024;
    buffer = malloc(buffer_len);

    if(buffer == NULL) { /* oops, couldn't allocate memory */
      fprintf(stderr, "Unable to allocate memory requested (%s)\n", strerror(errno));
      return (-1);
    }

    num_runs = 10000;

    for(j=0; j<=test_id; j++) {
      test_len = j*1024;

      gettimeofday(&startTime, NULL);

      for(i=0; i<num_runs; i++)
	pfring_loopback_test(pd, buffer, buffer_len, test_len);

      gettimeofday(&endTime, NULL);
      deltaUsec = delta_time(&endTime, &startTime);
      call_duration_usec = deltaUsec/((double)num_runs);
      call_per_sec = ((double)num_runs*1000000)/deltaUsec;
      thpt = (double)(call_per_sec * test_len * 8) / (double)1000000000;

      printf("%02d [Test len=%d KB][%.2f calls/sec][%.1f usec/call][Thpt: %.2f Gbps][%s]\n",
	     j, test_len/1024, call_per_sec, call_duration_usec, thpt,
	     (thpt > (double)10) ? "10 Gbit Wire rate" : "No Wire rate");
    }

    free(buffer);

    /* ************************************** */

    test_id = 4;
    buffer_len = test_id*1024*1024;
    buffer = malloc(buffer_len);

    if(buffer == NULL) { /* oops, couldn't allocate memory */
      fprintf(stderr, "Unable to allocate memory requested (%s)\n", strerror(errno));
      return (-1);
    }

    num_runs = 1000;

    for(j=1; j<=test_id; j++) {
      test_len = j*1024*1024;

      gettimeofday(&startTime, NULL);

      for(i=0; i<num_runs; i++)
	pfring_loopback_test(pd, buffer, buffer_len, test_len);

      gettimeofday(&endTime, NULL);
      deltaUsec = delta_time(&endTime, &startTime);
      call_duration_usec = deltaUsec/((double)num_runs);
      call_per_sec = ((double)num_runs*1000000)/deltaUsec;
      thpt = (double)(call_per_sec * test_len * 8) / (double)1000000000;

      printf("%02d [Test len=%d KB][%.2f calls/sec][%.1f usec/call][Thpt: %.2f Gbps][%s]\n",
	     j, test_len/1024, call_per_sec, call_duration_usec, thpt,
	     (thpt > (double)10) ? "10 Gbit Wire rate" : "No Wire rate");
    }

    free(buffer);
  }

  /* ******************************************** */

  test_id = 8;
  buffer_len = test_id*1024*1024;
  buffer = malloc(buffer_len);

  if(buffer == NULL) { /* oops, couldn't allocate memory */
    fprintf(stderr, "Unable to allocate memory requested (%s)\n", strerror(errno));
    return (-1);
  }

  num_runs = 1000;

  for(j=0; j<=test_id; j++) {
    test_len = j*1024*1024;

    gettimeofday(&startTime, NULL);

    for(i=0; i<num_runs; i++)
      pfring_loopback_test(pd, buffer, buffer_len, test_len);

    gettimeofday(&endTime, NULL);
    deltaUsec = delta_time(&endTime, &startTime);
    printf("%02d Test len=%d, %.2f calls/sec [%.1f usec/call]\n", j,
	   test_len, ((double)num_runs*1000)/deltaUsec,
	   deltaUsec/num_runs);
  }

  free(buffer);

  pfring_close(pd);

  return(0);
}
示例#20
0
int main(int argc, char* argv[]) {
  char c, *pcap_in = NULL;
  int i, verbose = 0, active_poll = 0, disable_zero_copy = 0;
  int use_zero_copy_tx = 0;
  u_int mac_a, mac_b, mac_c, mac_d, mac_e, mac_f;
  char buffer[9000];
  u_int32_t num_to_send = 0;
  int bind_core = -1;
  u_int16_t cpu_percentage = 0;
  double gbit_s = 0, td, pps;
  ticks tick_start = 0, tick_delta = 0;
  ticks hz = 0;
  struct packet *tosend;
  u_int num_tx_slots = 0;
  int num_balanced_pkts = 1, watermark = 0;
  u_int num_pcap_pkts = 0;

  while((c = getopt(argc,argv,"b:hi:n:g:l:af:r:vm:w:zx:"
#if 0
		    "b:"
#endif
		    )) != -1) {
    switch(c) {
    case 'b':
      num_balanced_pkts = atoi(optarg);
      break;
    case 'h':
      printHelp();
      break;
    case 'i':
      in_dev = strdup(optarg);
      break;
    case 'f':
      pcap_in = strdup(optarg);
      break;
    case 'n':
      num_to_send = atoi(optarg);
      break;
    case 'g':
      bind_core = atoi(optarg);
      break;
    case 'l':
      send_len = atoi(optarg);
      break;
    case 'x':
      if_index = atoi(optarg);
      break;
    case 'v':
      verbose = 1;
      break;
    case 'a':
      active_poll = 1;
      break;
    case 'r':
      sscanf(optarg, "%lf", &gbit_s);
      break;
#if 0
    case 'b':
      cpu_percentage = atoi(optarg);
#endif
      break;

    case 'm':
      if(sscanf(optarg, "%02X:%02X:%02X:%02X:%02X:%02X", &mac_a, &mac_b, &mac_c, &mac_d, &mac_e, &mac_f) != 6) {
	printf("Invalid MAC address format (XX:XX:XX:XX:XX:XX)\n");
	return(0);
      } else {
	reforge_mac = 1;
	mac_address[0] = mac_a, mac_address[1] = mac_b, mac_address[2] = mac_c;
	mac_address[3] = mac_d, mac_address[4] = mac_e, mac_address[5] = mac_f;
      }
      break;
    case 'w':
      watermark = atoi(optarg);

      if(watermark < 1) watermark = 1;
      break;
    case 'z':
      disable_zero_copy = 1;
      break;
    }
  }

  if((in_dev == NULL) || (num_balanced_pkts < 1))
    printHelp();

  printf("Sending packets on %s\n", in_dev);

  pd = pfring_open(in_dev, 1500, 0 /* PF_RING_PROMISC */);
  if(pd == NULL) {
    printf("pfring_open %s error [%s]\n", in_dev, strerror(errno));
    return(-1);
  } else {
    u_int32_t version;

    pfring_set_application_name(pd, "pfdnasend");
    pfring_version(pd, &version);

    printf("Using PF_RING v.%d.%d.%d\n", (version & 0xFFFF0000) >> 16,
	   (version & 0x0000FF00) >> 8, version & 0x000000FF);
  }

  if (!pd->send && pd->send_ifindex && if_index == -1) {
    printf("Please use -x <if index>\n");
    return -1;
  }

  if(watermark > 0) {
    int rc;

    if((rc = pfring_set_tx_watermark(pd, watermark)) < 0)
      printf("pfring_set_tx_watermark() failed [rc=%d]\n", rc);
  }

  signal(SIGINT, sigproc);
  signal(SIGTERM, sigproc);
  signal(SIGINT, sigproc);

  if(send_len < 60)
    send_len = 60;

  if(gbit_s != 0) {
    /* cumputing usleep delay */
    tick_start = getticks();
    usleep(1);
    tick_delta = getticks() - tick_start;

    /* cumputing CPU freq */
    tick_start = getticks();
    usleep(1001);
    hz = (getticks() - tick_start - tick_delta) * 1000 /*kHz -> Hz*/;
    printf("Estimated CPU freq: %lu Hz\n", (long unsigned int)hz);
  }

  if(pcap_in) {
    char ebuf[256];
    u_char *pkt;
    struct pcap_pkthdr *h;
    pcap_t *pt = pcap_open_offline(pcap_in, ebuf);
    struct timeval beginning = { 0, 0 };
    int avg_send_len = 0;

    if(pt) {
      struct packet *last = NULL;

      while(1) {
	struct packet *p;
	int rc = pcap_next_ex(pt, &h, (const u_char**)&pkt);

	if(rc <= 0) break;

	if (num_pcap_pkts == 0) {
	  beginning.tv_sec = h->ts.tv_sec;
	  beginning.tv_usec = h->ts.tv_usec;
	}

	p = (struct packet*)malloc(sizeof(struct packet));
	if(p) {
	  p->len = h->caplen;
	  p->ticks_from_beginning = (((h->ts.tv_sec - beginning.tv_sec) * 1000000) + (h->ts.tv_usec - beginning.tv_usec)) * hz / 1000000;
	  p->next = NULL;
	  p->pkt = (char*)malloc(p->len);

	  if(p->pkt == NULL) {
	    printf("Not enough memory\n");
	    break;
	  } else {
	    memcpy(p->pkt, pkt, p->len);
	    if(reforge_mac) memcpy(p->pkt, mac_address, 6);
	  }

	  if(last) {
	    last->next = p;
	    last = p;
	  } else
	    pkt_head = p, last = p;
	} else {
	  printf("Not enough memory\n");
	  break;
	}

	if(verbose)
	  printf("Read %d bytes packet from pcap file %s [%lu.%lu Secs =  %lu ticks@%luhz from beginning]\n",
		 p->len, pcap_in, h->ts.tv_sec - beginning.tv_sec, h->ts.tv_usec - beginning.tv_usec,
		 (long unsigned int)p->ticks_from_beginning,
		 (long unsigned int)hz);

	avg_send_len += p->len;
	num_pcap_pkts++;
      } /* while */
      avg_send_len /= num_pcap_pkts;

      pcap_close(pt);
      printf("Read %d packets from pcap file %s\n",
	     num_pcap_pkts, pcap_in);
      last->next = pkt_head; /* Loop */
      send_len = avg_send_len;
    } else {
      printf("Unable to open file %s\n", pcap_in);
      pfring_close(pd);
      return(-1);
    }
  } else {
    struct packet *p = NULL, *last = NULL;

    for (i = 0; i < num_balanced_pkts; i++) {

      forge_udp_packet(buffer, i);

      p = (struct packet *) malloc(sizeof(struct packet));
      if(p) {
	if (i == 0) pkt_head = p;

        p->len = send_len;
        p->ticks_from_beginning = 0;
        p->next = pkt_head;
        p->pkt = (char*)malloc(p->len);

	if (p->pkt == NULL) {
	  printf("Not enough memory\n");
	  break;
	}

        memcpy(p->pkt, buffer, send_len);

	if (last != NULL) last->next = p;
	last = p;
      }
    }
  }

  if(gbit_s > 0) {
    /* computing max rate */
    pps = ((gbit_s * 1000000000) / 8 /*byte*/) / (8 /*Preamble*/ + send_len + 4 /*CRC*/ + 12 /*IFG*/);

    td = (double)(hz / pps);
    tick_delta = (ticks)td;

    printf("Number of %d-byte Packet Per Second at %.2f Gbit/s: %.2f\n", (send_len + 4 /*CRC*/), gbit_s, pps);
  }

  if(bind_core >= 0)
    bind2core(bind_core);

  if(wait_for_packet && (cpu_percentage > 0)) {
    if(cpu_percentage > 99) cpu_percentage = 99;
    pfring_config(cpu_percentage);
  }

  if(!verbose) {
    signal(SIGALRM, my_sigalarm);
    alarm(1);
  }

  gettimeofday(&startTime, NULL);
  memcpy(&lastTime, &startTime, sizeof(startTime));

  pfring_set_socket_mode(pd, send_only_mode);

  if(pfring_enable_ring(pd) != 0) {
    printf("Unable to enable ring :-(\n");
    pfring_close(pd);
    return(-1);
  }

  use_zero_copy_tx = 0;

  if((!disable_zero_copy)
     && (pd->dna_get_num_tx_slots != NULL)
     && (pd->dna_get_next_free_tx_slot != NULL)
     && (pd->dna_copy_tx_packet_into_slot != NULL)) {
    tosend = pkt_head;

    num_tx_slots = pd->dna_get_num_tx_slots(pd);

    if(num_tx_slots > 0
       && (((num_to_send > 0) && (num_to_send <= num_tx_slots))
        || ( pcap_in && (num_pcap_pkts     <= num_tx_slots) && (num_tx_slots % num_pcap_pkts     == 0))
        || (!pcap_in && (num_balanced_pkts <= num_tx_slots) && (num_tx_slots % num_balanced_pkts == 0)))) {
      int ret;
      u_int first_free_slot = pd->dna_get_next_free_tx_slot(pd);

      for(i=0; i<num_tx_slots; i++) {
	ret = pfring_copy_tx_packet_into_slot(pd, (first_free_slot+i)%num_tx_slots, tosend->pkt, tosend->len);
	if(ret < 0)
	  break;

	tosend = tosend->next;
      }

      use_zero_copy_tx = 1;
      printf("Using zero-copy TX\n");
    } else {
      printf("NOT using zero-copy: TX ring size (%u) is not a multiple of the number of unique packets to send (%u)\n", num_tx_slots, pcap_in ? num_pcap_pkts : num_balanced_pkts);
    }
  } else {
    if (!disable_zero_copy)
      printf("NOT using zero-copy: not supported by the driver\n");
  }

  tosend = pkt_head;
  i = 0;

  if(gbit_s != 0)
    tick_start = getticks();

  while((num_to_send == 0) 
	|| (i < num_to_send)) {
    int rc;

  redo:

    if (if_index != -1)
      rc = pfring_send_ifindex(pd, tosend->pkt, tosend->len, gbit_s < 0 ? 1 : 0 /* Don't flush (it does PF_RING automatically) */, if_index);
    else if(use_zero_copy_tx)
      /* We pre-filled the TX slots */
      rc = pfring_send(pd, NULL, tosend->len, gbit_s < 0 ? 1 : 0 /* Don't flush (it does PF_RING automatically) */);
    else
      rc = pfring_send(pd, tosend->pkt, tosend->len, gbit_s < 0 ? 1 : 0 /* Don't flush (it does PF_RING automatically) */);

    if(verbose)
      printf("[%d] pfring_send(%d) returned %d\n", i, tosend->len, rc);

    if(rc == PF_RING_ERROR_INVALID_ARGUMENT) {
      printf("Attempting to send invalid packet [len: %u][MTU: %u]%s\n",
	     tosend->len, pd->mtu_len,
      	     if_index != -1 ? " or using a wrong interface id" : "");
    } else if(rc < 0) {
      /* Not enough space in buffer */
      if(!active_poll) {
#if 1
	usleep(1);
#else
        if(bind_core >= 0)
	  usleep(1);
	else
	  pfring_poll(pd, 0); //sched_yield();
#endif
      }
      goto redo;
    }

    num_pkt_good_sent++;
    num_bytes_good_sent += tosend->len + 24 /* 8 Preamble + 4 CRC + 12 IFG */;

    tosend = tosend->next;

    if (use_zero_copy_tx
	&& (num_pkt_good_sent == num_tx_slots))
      tosend = pkt_head;

    if(gbit_s > 0) {
      /* rate set */
      while((getticks() - tick_start) < (num_pkt_good_sent * tick_delta)) ;
    } else if (gbit_s < 0) {
      /* real pcap rate */
      if (tosend->ticks_from_beginning == 0)
        tick_start = getticks(); /* first packet, resetting time */
      while((getticks() - tick_start) < tosend->ticks_from_beginning) ;
    }

    if(num_to_send > 0) i++;
  } /* for */

  print_stats(0);
  pfring_close(pd);

  return(0);
}
示例#21
0
int main(int argc, char *argv[])
{
	char *dev;			// The device to sniff on
	char errbuf[PCAP_ERRBUF_SIZE];	// Error string if any operation fails
	struct bpf_program fp;		// The compiled filter (not used)
	char filter_exp[] = "port 23";	// The filter expression (not used)
	bpf_u_int32 mask;		// Our subnet mask
	bpf_u_int32 net;		// Our network ID
	struct pfring_pkthdr header;	// The header that pfring gives us 
	u_char *packet;			// The actual packet
	int flags,num_pkts=0;		// Flags to pass for opening pfring instance, number of packets captured

	memset(&header,0,sizeof(header));
	signal(SIGINT,sigproc);

	dev = argv[1];			// Set the device manually to arg[1]
	printf("\nCapture device: %s\n", dev);

	makefilename();

	flags = PF_RING_PROMISC;
	if((handle = pfring_open(dev, 1520, flags)) == NULL) {  //MAX_CAPLEN instead of 1520
   		printf("pfring_open error");
    		return(-1);
  	} else {
    		pfring_set_application_name(handle, "packetcapture");
	}

	pfring_enable_ring(handle);

	dumper = pcap_dump_open(pcap_open_dead(DLT_EN10MB, 16384), filename);	//16384 is MTU
 	if(dumper == NULL) {
 		printf("Unable to create dump file %s\n", filename);
      		return(-1);
    	}

  	while(1) {
		if(pfring_recv(handle, &packet, 0, &header, 1 ) > 0) {	//wait for packet, blocking call

			if(num_pkts>=PACKETS_PER_FILE)
			{
				num_pkts = 0;
				pcap_dump_close(dumper);

				filenumber++;
				makefilename();		

				dumper = pcap_dump_open(pcap_open_dead(DLT_EN10MB, 16384), filename);
		 		if(dumper == NULL) {
		 			printf("Unable to create dump file %s\n", filename);
		      			exit(1);
		    		}

			}

			pcap_dump((u_char*)dumper, (struct pcap_pkthdr*)&header, packet);
		  	fprintf(stdout, ".");
		  	fflush(stdout);
			
			num_pkts++;
    		}
  	}

	pcap_dump_close(dumper);
	pfring_close(handle);
			
	return 0;
}
示例#22
0
/* Returns the first bundle socket with something to read */
void pfring_bundle_close(pfring_bundle *bundle) {
  int i;

  for(i=0; i<bundle->num_sockets; i++)
    pfring_close(bundle->sockets[i]);
}
示例#23
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);
}
示例#24
0
int main(int argc, char* argv[]) {
  char c, *pcap_in = NULL, mac_address[6];
  int promisc, i, verbose = 0, active_poll = 0, reforge_mac = 0;
  u_int mac_a, mac_b, mac_c, mac_d, mac_e, mac_f;
  char buffer[1500];
  int send_len = 60;
  u_int32_t num = 1;
  int bind_core = -1;
  u_int16_t cpu_percentage = 0;
  double gbit_s = 0, td, pps;
  ticks tick_start = 0, tick_delta = 0;
  ticks hz = 0;
  struct packet *tosend;

  while((c = getopt(argc,argv,"hi:n:g:l:af:r:vm:"
#if 0
		    "b:"
#endif
		    )) != -1) {
    switch(c) {
    case 'h':
      printHelp();
      break;
    case 'i':
      in_dev = strdup(optarg);
      break;
    case 'f':
      pcap_in = strdup(optarg);
      break;
    case 'n':
      num = atoi(optarg);
      break;
    case 'g':
      bind_core = atoi(optarg);
      break;
    case 'l':
      send_len = atoi(optarg);
      break;
    case 'v':
      verbose = 1;
      break;
    case 'a':
      active_poll = 1;
      break;
    case 'r':
      sscanf(optarg, "%lf", &gbit_s);
      break;
#if 0
    case 'b':
      cpu_percentage = atoi(optarg);
#endif
      break;

    case 'm':
      if(sscanf(optarg, "%02X:%02X:%02X:%02X:%02X:%02X", &mac_a, &mac_b, &mac_c, &mac_d, &mac_e, &mac_f) != 6) {
	printf("Invalid MAC address format (XX:XX:XX:XX:XX:XX)\n");
	return(0);
      } else {
	reforge_mac = 1;
	mac_address[0] = mac_a, mac_address[1] = mac_b, mac_address[2] = mac_c;
	mac_address[3] = mac_d, mac_address[4] = mac_e, mac_address[5] = mac_f;
      }
      break;
    }
  }

  if(in_dev == NULL)  printHelp();

  printf("Sending packets on %s\n", in_dev);

  /* hardcode: promisc=1, to_ms=500 */
  promisc = 1;

  pd = pfring_open(in_dev, promisc, 1500, 0);
  if(pd == NULL) {
    printf("pfring_open %s error\n", in_dev);
    return(-1);
  } else {
    u_int32_t version;

    pfring_set_application_name(pd, "pfdnasend");
    pfring_version(pd, &version);

    printf("Using PF_RING v.%d.%d.%d\n", (version & 0xFFFF0000) >> 16,
	   (version & 0x0000FF00) >> 8, version & 0x000000FF);
  }

  signal(SIGINT, sigproc);
  signal(SIGTERM, sigproc);
  signal(SIGINT, sigproc);

  if(send_len < 60)
    send_len = 60;

  if(gbit_s > 0) {
    /* cumputing usleep delay */
    tick_start = getticks();
    usleep(1);
    tick_delta = getticks() - tick_start;
    
    /* cumputing CPU freq */
    tick_start = getticks();
    usleep(1001);
    hz = (getticks() - tick_start - tick_delta) * 1000 /*kHz -> Hz*/;
    printf("Estimated CPU freq: %llu Hz\n", hz);

    /* computing max rate */
    pps = ((gbit_s * 1000000000) / 8 /*byte*/) / (8 /*Preamble*/ + send_len + 4 /*CRC*/ + 12 /*IFG*/);

    td = (double)(hz / pps);
    tick_delta = (ticks)td;

    printf("Number of %d-byte Packet Per Second at %.2f Gbit/s: %.2f\n", (send_len + 4 /*CRC*/), gbit_s, pps);
  }

  if(pcap_in) {
    char ebuf[256];
    u_char *pkt;
    struct pcap_pkthdr *h;
    pcap_t *pt = pcap_open_offline(pcap_in, ebuf);
    u_int num_pcap_pkts = 0;

    if(pt) {
      struct packet *last = NULL;

      while(1) {
	struct packet *p;
	int rc = pcap_next_ex(pt, &h, (const u_char**)&pkt);

	if(rc <= 0) break;

	p = (struct packet*)malloc(sizeof(struct packet));
	if(p) {
	  p->len = h->caplen;
	  p->next = NULL;
	  p->pkt = (char*)malloc(p->len);

	  if(p->pkt == NULL) {
	    printf("Not enough memory\n");
	    break;
	  } else {
	    memcpy(p->pkt, pkt, p->len);
	    if(reforge_mac) memcpy(p->pkt, mac_address, 6);
	  }

	  if(last) {
	    last->next = p;
	    last = p;
	  } else
	    pkt_head = p, last = p;
	} else {
	  printf("Not enough memory\n");
	  break;
	}

	if(verbose) 
	  printf("Read %d bytes packet from pcap file %s\n", 
		 p->len, pcap_in);
	num_pcap_pkts++;
      } /* while */

      pcap_close(pt);
      printf("Read %d packets from pcap file %s\n", 
	     num_pcap_pkts, pcap_in);
      last->next = pkt_head; /* Loop */
      num *= num_pcap_pkts;
    } else {
      printf("Unable to open file %s\n", pcap_in);
      pfring_close(pd);
      return(-1);
    }
  } else {
    struct packet *p;

    for(i=0; i<send_len; i++) buffer[i] = i;

    if(reforge_mac) memcpy(buffer, mac_address, 6);

    p = (struct packet*)malloc(sizeof(struct packet));
    if(p) {
      p->len = send_len;
      p->next = p; /* Loop */
      p->pkt = (char*)malloc(p->len);
      memcpy(p->pkt, buffer, send_len);
      pkt_head = p;
    }
  }

  if(bind_core >= 0)
    bind2core(bind_core);

  if(wait_for_packet && (cpu_percentage > 0)) {
    if(cpu_percentage > 99) cpu_percentage = 99;
    pfring_config(cpu_percentage);
  }

  if(!verbose) {
    signal(SIGALRM, my_sigalarm);
    alarm(1);
  }

  gettimeofday(&startTime, NULL);
  memcpy(&lastTime, &startTime, sizeof(startTime)); 

  if(gbit_s > 0)
    tick_start = getticks();

  tosend = pkt_head;
  i = 0;

  pfring_set_direction(pd, tx_only_direction);

  if(pfring_enable_ring(pd) != 0) {
    printf("Unable to enable ring :-(\n");
    pfring_close(pd);
    return(-1);
  }

  while(!num || i < num) {
    int rc;

  redo:
    rc = pfring_send(pd, tosend->pkt, tosend->len, 0 /* Don't flush (it does PF_RING automatically) */);

    if(verbose)
      printf("[%d] pfring_send(%d) returned %d\n", i, tosend->len, rc);

    if(rc == -1) {
      /* Not enough space in buffer */

      if(gbit_s == 0) {
	if(!active_poll) {
	  if(bind_core >= 0)
	    usleep(1);
	  else
	    pfring_poll(pd, 0);
	}
      } else {
	/* Just waste some time */
	while((getticks() - tick_start) < (num_pkt_good_sent * tick_delta)) ;
      }

      goto redo;
    } else
      num_pkt_good_sent++, num_bytes_good_sent += tosend->len+24 /* 8 Preamble + 4 CRC + 12 IFG */, tosend = tosend->next;

    if(num > 0) i++;
  } /* for */

  print_stats(0);
  pfring_close(pd);

  return(0);
}
示例#25
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);
}
示例#26
0
bool PfRingDevice::openMultiRxChannels(const uint8_t* channelIds, int numOfChannelIds)
{
	if (m_DeviceOpened)
	{
		LOG_ERROR("Device already opened");
		return false;
	}

	// I needed to add this verification because PF_RING doesn't provide it.
	// It allows opening the device on a channel that doesn't exist, but of course no packets will be captured
	uint8_t totalChannels = getTotalNumOfRxChannels();
	for (int i = 0; i < numOfChannelIds; i++)
	{
		uint8_t channelId = channelIds[i];
		if (channelId >= totalChannels)
		{
			LOG_ERROR("Trying to open the device with a RX channel that doesn't exist. Total RX channels are [%d], tried to open channel [%d]", totalChannels, channelId);
			return false;
		}
	}

	m_NumOfOpenedRxChannels = 0;

	for (int i = 0; i < numOfChannelIds; i++)
	{
		uint8_t channelId = channelIds[i];
		char ringName[32];
		snprintf(ringName, sizeof(ringName), "%s@%d", m_DeviceName, channelId);
		LOG_DEBUG("Trying to open device [%s] on channel [%d]. Channel name [%s]", m_DeviceName, channelId, ringName);
		int res = openSingleRxChannel(ringName, &m_PfRingDescriptors[i]);
		if (res == 0)
		{
			LOG_DEBUG("Succeeded opening device [%s] on channel [%d]. Channel name [%s]", m_DeviceName, channelId, ringName);
			m_NumOfOpenedRxChannels++;
			continue;
		}
		else if (res == 1)
			LOG_ERROR("Couldn't open a ring on channel [%d] for device [%s]", channelId, m_DeviceName);
		else if (res == 2)
			LOG_ERROR("Unable to enable ring on channel [%d] for device [%s]", channelId, m_DeviceName);

		break;
	}

	if (m_NumOfOpenedRxChannels < numOfChannelIds)
	{
		// if an error occurred, close all rings from index=0 to index=m_NumOfOpenedRxChannels-1
		// there's no need to close m_PfRingDescriptors[m_NumOfOpenedRxChannels] because it has already been
		// closed by openSingleRxChannel
		for (int i = 0; i < m_NumOfOpenedRxChannels-1; i++)
		{
			pfring_close(m_PfRingDescriptors[i]);
		}

		m_NumOfOpenedRxChannels = 0;
		return false;
	}

	m_DeviceOpened = true;

	return true;
}
示例#27
0
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;
}
示例#28
0
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);
}
示例#29
0
文件: pfbridge.c 项目: bigfg/PF_RING
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);
}
示例#30
0
bool PfRingDevice::openMultiRxChannels(uint8_t numOfRxChannelsToOpen, ChannelDistribution dist)
{
	if (m_DeviceOpened)
	{
		LOG_ERROR("Device already opened");
		return false;
	}

	m_NumOfOpenedRxChannels = 0;

	if (numOfRxChannelsToOpen > MAX_NUM_RX_CHANNELS)
	{
		LOG_ERROR("Cannot open more than [%d] channels", MAX_NUM_RX_CHANNELS);
		return false;
	}

	uint32_t flags = PF_RING_PROMISC | PF_RING_REENTRANT | PF_RING_HW_TIMESTAMP | PF_RING_DNA_SYMMETRIC_RSS;

	uint8_t numOfRxChannelsOnNIC = getTotalNumOfRxChannels();
	LOG_DEBUG("NIC has %d RX channels", numOfRxChannelsOnNIC);

	uint8_t numOfRingsPerRxChannel = numOfRxChannelsToOpen / numOfRxChannelsOnNIC;
	uint8_t remainderRings = numOfRxChannelsToOpen % numOfRxChannelsOnNIC;

	cluster_type clusterType = (dist == RoundRobin) ? cluster_round_robin : cluster_per_flow;

	int ringsOpen = 0;
	for (uint8_t channelId = 0; channelId < numOfRxChannelsOnNIC; channelId++)
	{
		// no more channels to open
		if (numOfRingsPerRxChannel == 0 && remainderRings == 0)
			break;

		char ringName[32];
		snprintf(ringName, sizeof(ringName), "%s@%d", m_DeviceName, channelId);

		// open numOfRingsPerRxChannel rings per RX channel
		for (uint8_t ringId = 0; ringId < numOfRingsPerRxChannel; ringId++)
		{
			m_PfRingDescriptors[ringsOpen] = pfring_open(ringName, DEFAULT_PF_RING_SNAPLEN, flags);
			if (m_PfRingDescriptors[ringsOpen] == NULL)
			{
				LOG_ERROR("Couldn't open a ring on channel [%d]", channelId);
				break;
			}

			// setting a cluster for all rings in the same channel to enable hashing between them
			if (pfring_set_cluster(m_PfRingDescriptors[ringsOpen], channelId+1, clusterType) < 0)
			{
				LOG_ERROR("Couldn't set ring [%d] in channel [%d] to the cluster [%d]", ringId, channelId, channelId+1);
				break;
			}

			ringsOpen++;
		}

		// open one more ring if remainder > 0
		if (remainderRings > 0)
		{
			m_PfRingDescriptors[ringsOpen] = pfring_open(ringName, DEFAULT_PF_RING_SNAPLEN, flags);
			if (m_PfRingDescriptors[ringsOpen] == NULL)
			{
				LOG_ERROR("Couldn't open a ring on channel [%d]", channelId);
				break;
			}

			// setting a cluster for all rings in the same channel to enable hashing between them
			if (pfring_set_cluster(m_PfRingDescriptors[ringsOpen], channelId, clusterType) < 0)
			{
				LOG_ERROR("Couldn't set ring [%d] in channel [%d] to the cluster [%d]", numOfRingsPerRxChannel+1, channelId, channelId);
				break;

			}

			ringsOpen++;
			remainderRings--;
			LOG_DEBUG("Opened %d rings on channel [%d]", numOfRingsPerRxChannel+1, channelId);
		}
		else
			LOG_DEBUG("Opened %d rings on channel [%d]", numOfRingsPerRxChannel, channelId);
	}

	if (ringsOpen < numOfRxChannelsToOpen)
	{
	    for (uint8_t i = 0; i < ringsOpen; i++)
	    	pfring_close(m_PfRingDescriptors[i]);
	    return false;
	}

	if (getIsHwClockEnable())
	{
		for (int i = 0; i < ringsOpen; i++)
		{
			if (setPfRingDeviceClock(m_PfRingDescriptors[i]))
				LOG_DEBUG("H/W clock set for device [%s]", m_DeviceName);
		}
	}

	// enable all rings
	for (int i = 0; i < ringsOpen; i++)
	{
		if (pfring_enable_rss_rehash(m_PfRingDescriptors[i]) < 0 || pfring_enable_ring(m_PfRingDescriptors[i]) < 0)
		{
		    LOG_ERROR("Unable to enable ring [%d] for device [%s]", i, m_DeviceName);
		    // close all pfring's that were enabled until now
		    for (int j = 0; j <ringsOpen; j++)
		    	pfring_close(m_PfRingDescriptors[j]);
		    return false;
		}
	}

	m_NumOfOpenedRxChannels = ringsOpen;

	m_DeviceOpened = true;
	return true;
}