Ejemplo n.º 1
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;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
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;
}
Ejemplo n.º 4
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);
}