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;
}
Exemple #2
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);
}
Exemple #3
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;
}