Exemplo n.º 1
0
static int file_read(FileImpl* impl)
{
    int n = read(impl->fid, impl->buf, impl->snaplen);

    if ( !n )
    {
        if ( !impl->eof )
        {
            impl->eof = 1;
            return 1;  // <= zero won't make it :(
        }
        return DAQ_READFILE_EOF;
    }

    if ( n < 0 )
    {
        if (errno != EINTR)
        {
            char error_msg[1024] = {0};
            if (strerror_r(errno, error_msg, sizeof(error_msg)) == 0)
                DPE(impl->error, "%s: can't read from file (%s)\n",
                    DAQ_NAME, error_msg);
            else
                DPE(impl->error, "%s: can't read from file: %d\n",
                    DAQ_NAME, errno);
        }
        return DAQ_ERROR;
    }
    return n;
}
Exemplo n.º 2
0
static int bind_interface(AFPacket_Context_t *afpc, AFPacketInstance *instance)
{
    struct sockaddr_ll *sll;
    int err;
    socklen_t errlen = sizeof(err);

    /* Bind to the specified device so we only see packets from it. */
    sll = &instance->sll;
    sll->sll_family = AF_PACKET;
    sll->sll_ifindex = instance->index;
    sll->sll_protocol = htons(ETH_P_ALL);

    if (bind(instance->fd, (struct sockaddr *) sll, sizeof(*sll)) == -1)
    {
        DPE(afpc->errbuf, "%s: bind(%s): %s\n", __FUNCTION__, instance->name, strerror(errno));
        return DAQ_ERROR;
    }

    /* Any pending errors, e.g., network is down? */
    if (getsockopt(instance->fd, SOL_SOCKET, SO_ERROR, &err, &errlen) || err)
    {
        DPE(afpc->errbuf, "%s: getsockopt: %s", __FUNCTION__, strerror(errno));
        return DAQ_ERROR;
    }

    return DAQ_SUCCESS;
}
Exemplo n.º 3
0
static int create_ring(AFPacket_Context_t *afpc, AFPacketInstance *instance, AFPacketRing *ring, int optname)
{
    int rc, order;

    /* Starting with page allocations of order 3, try to allocate an RX ring in the kernel. */
    for (order = DEFAULT_ORDER; order >= 0; order--)
    {
        if (calculate_layout(afpc, &ring->layout, instance->tp_hdrlen, order))
            return DAQ_ERROR;

        /* Ask the kernel to create the ring. */
        rc = setsockopt(instance->fd, SOL_PACKET, optname, (void*) &ring->layout, sizeof(struct tpacket_req));
        if (rc)
        {
            if (errno == ENOMEM)
            {
                if (afpc->debug)
                    printf("%s: Allocation of kernel packet ring failed with order %d, retrying...\n", instance->name, order);
                continue;
            }
            DPE(afpc->errbuf, "%s: Couldn't create kernel ring on packet socket: %s",
                    __FUNCTION__, strerror(errno));
            return DAQ_ERROR;
        }
        /* Store the total ring size for later. */
        ring->size = ring->layout.tp_block_size * ring->layout.tp_block_nr;
        if (afpc->debug)
            printf("Created a ring of type %d with total size of %u\n", optname, ring->size);
        return DAQ_SUCCESS;
    }

    /* If we got here, it means we failed allocation on order 0. */
    DPE(afpc->errbuf, "%s: Couldn't allocate enough memory for the kernel packet ring!", instance->name);
    return DAQ_ERROR;
}
Exemplo n.º 4
0
static int pfring_zc_daq_set_filter(void *handle, const char *filter) {
    Pfring_Context_t *context = (Pfring_Context_t *) handle;

#ifdef ENABLE_BPF
    if (pcap_compile_nopcap(context->snaplen, /* snaplen_arg */
                            DLT_EN10MB,       /* linktype_arg */
                            &context->filter, /* program */
                            filter,           /* const char *buf */
                            0,                /* optimize */
                            0                 /* mask */
                           ) == -1) {
        goto bpf_error;
    }

    if (context->filter.bf_insns == NULL)
        goto bpf_error;

    context->bpf_filter = 1;

    return DAQ_SUCCESS;

bpf_error:
    DPE(context->errbuf, "%s: BPF state machine compilation failed!", __FUNCTION__);
#else
    DPE(context->errbuf, "%s: BPF filters not supported!", __FUNCTION__);
#endif
    return DAQ_ERROR;
}
Exemplo n.º 5
0
static int afpacket_daq_set_filter(void *handle, const char *filter)
{
    AFPacket_Context_t *afpc = (AFPacket_Context_t *) handle;
    struct sfbpf_program fcode;

    if (afpc->filter)
        free(afpc->filter);

    afpc->filter = strdup(filter);
    if (!afpc->filter)
    {
        DPE(afpc->errbuf, "%s: Couldn't allocate memory for the filter string!", __FUNCTION__);
        return DAQ_ERROR;
    }

    if (sfbpf_compile(afpc->snaplen, DLT_EN10MB, &fcode, afpc->filter, 1, 0) < 0)
    {
        DPE(afpc->errbuf, "%s: BPF state machine compilation failed!", __FUNCTION__);
        return DAQ_ERROR;
    }

    sfbpf_freecode(&afpc->fcode);
    afpc->fcode.bf_len = fcode.bf_len;
    afpc->fcode.bf_insns = fcode.bf_insns;

    return DAQ_SUCCESS;
}
Exemplo n.º 6
0
static int create_rx_ring(AFPacket_Context_t *afpc, AFPacketInstance *instance)
{
    int rc, order;

    /* Starting with page allocations of order 3, try to allocate an RX ring in the kernel. */
    for (order = DEFAULT_ORDER; order >= 0; order--)
    {
        if (calculate_layout(afpc, instance, order))
            return DAQ_ERROR;

        /* Ask the kernel to create the ring. */
        rc = setsockopt(instance->fd, SOL_PACKET, PACKET_RX_RING, (void*) &instance->layout, sizeof(struct tpacket_req));
        if (rc)
        {
            if (errno == ENOMEM)
            {
                if (afpc->debug)
                    printf("%s: Allocation of kernel packet RX ring failed with order %d, retrying...\n", instance->name, order);
                continue;
            }
            DPE(afpc->errbuf, "%s: Couldn't create kernel RX ring on packet socket: %s",
                __FUNCTION__, strerror(errno));
            return DAQ_ERROR;
        }
        return DAQ_SUCCESS;
    }

    /* If we got here, it means we failed allocation on order 0. */
    DPE(afpc->errbuf, "%s: Couldn't allocate enough memory for the kernel RX ring!", instance->name);
    return DAQ_ERROR;
}
Exemplo n.º 7
0
static int nfq_daq_acquire (
    void* handle, int c, DAQ_Analysis_Func_t callback, void* user)
{
    NfqImpl *impl = (NfqImpl*)handle;

    int n = 0;
    fd_set fdset;
    struct timeval tv;
    tv.tv_usec = 0;

    // If c is <= 0, don't limit the packets acquired.  However,
    // impl->count = 0 has a special meaning, so interpret accordingly.
    impl->count = (c == 0) ? -1 : c;
    impl->user_data = user;
    impl->user_func = callback;

    while ( (impl->count < 0) || (n < impl->count) )
    {
        FD_ZERO(&fdset);
        FD_SET(impl->sock, &fdset);

        // set this per call
        tv.tv_sec = impl->timeout;
        tv.tv_usec = 0;

        // at least ipq had a timeout!
        if ( select(impl->sock+1, &fdset, NULL, NULL, &tv) < 0 )
        {
            if ( errno == EINTR )
                break;
            DPE(impl->error, "%s: select = %s",
                __FUNCTION__, strerror(errno));
            return DAQ_ERROR;
        }

        if (FD_ISSET(impl->sock, &fdset))
        {
            int len = recv(impl->sock, impl->buf, MSG_BUF_SIZE, 0);

            if ( len > 0)
            {
                int stat = nfq_handle_packet(
                    impl->nf_handle, (char*)impl->buf, len);

                impl->stats.hw_packets_received++;

                if ( stat < 0 )
                {
                    DPE(impl->error, "%s: nfq_handle_packet = %s",
                        __FUNCTION__, strerror(errno));
                    return DAQ_ERROR;
                }
                n++;
            }
        }
    }
    return 0;
}
Exemplo n.º 8
0
static int start_instance(AFPacket_Context_t *afpc, AFPacketInstance *instance)
{
    struct packet_mreq mr;
    int arptype;

    /* Bind the RX ring to this interface. */
    if (bind_instance_interface(afpc, instance) != 0)
        return -1;

    /* Turn on promiscuous mode for the device. */
    memset(&mr, 0, sizeof(mr));
    mr.mr_ifindex = instance->index;
    mr.mr_type = PACKET_MR_PROMISC;
    if (setsockopt(instance->fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr, sizeof(mr)) == -1)
    {
        DPE(afpc->errbuf, "%s: setsockopt: %s", __FUNCTION__, strerror(errno));
        return -1;
    }

    /* Get the link-layer type. */
    arptype = iface_get_arptype(instance);
    if (arptype < 0)
    {
        DPE(afpc->errbuf, "%s: failed to get interface type for device %s: (%d) %s",
                __FUNCTION__, instance->name, errno, strerror(errno));
        return -1;
    }

    if (arptype != ARPHRD_ETHER)
    {
        DPE(afpc->errbuf, "%s: invalid interface type for device %s: %d != %d",
                __FUNCTION__, instance->name, arptype, ARPHRD_ETHER);
        return -1;
    }

    /* Determine which versions of TPACKET the socket supports. */
    if (determine_version(afpc, instance) != DAQ_SUCCESS)
        return -1;

    /* Request the kernel RX ring from af_packet... */
    if (create_ring(afpc, instance, &instance->rx_ring, PACKET_RX_RING) != DAQ_SUCCESS)
        return -1;
    /* ...request the kernel TX ring from af_packet if we're in inline mode... */
    if (instance->peer && create_ring(afpc, instance, &instance->tx_ring, PACKET_TX_RING) != DAQ_SUCCESS)
        return -1;
    /* ...map the memory for the kernel ring(s) into userspace... */
    if (mmap_rings(afpc, instance) != DAQ_SUCCESS)
        return -1;
    /* ...and, finally, set up a userspace ring buffer to represent the kernel RX ring... */
    if (set_up_ring(afpc, instance, &instance->rx_ring) != DAQ_SUCCESS)
        return -1;
    /* ...as well as one for the TX ring if we're in inline mode. */
    if (instance->peer && set_up_ring(afpc, instance, &instance->tx_ring) != DAQ_SUCCESS)
        return -1;

    return 0;
}
Exemplo n.º 9
0
static int pfring_zc_daq_open(Pfring_Context_t *context, int id) {
    uint32_t default_net = 0xFFFFFF00;
    char *device = context->devices[id], *tx_device = context->tx_devices[id];
    pfring_zc_queue *q = NULL;

    if (device == NULL) {
        DPE(context->errbuf, "pfring_zc_open_device(): device #%d name not found", id);
        return -1;
    }

    if (context->mode == DAQ_MODE_INLINE || (context->mode == DAQ_MODE_PASSIVE && context->ids_bridge)) {
        q = pfring_zc_open_device(context->cluster,
                                  tx_device,
                                  tx_only,
                                  (context->promisc_flag ? PF_RING_PROMISC : 0));

        if (q == NULL) {
            DPE(context->errbuf, "pfring_zc_open_device(): unable to open device '%s' (TX)", tx_device);
            return -1;
        }

        context->tx_queues[id] = q;
#ifdef DAQ_PF_RING_BEST_EFFORT_BOOST
        context->mq_queues[id] = q;
#endif
    }

    if (!context->ipc_attach) {

        q = pfring_zc_open_device(context->cluster,
                                  device,
                                  rx_only,
                                  (context->promisc_flag ? PF_RING_PROMISC : 0) | PF_RING_ZC_DEVICE_SW_TIMESTAMP);

        if (q == NULL) {
            DPE(context->errbuf, "pfring_zc_open_device(): unable to open device '%s' (RX)", device);
            return -1;
        }

    } else {

        q = pfring_zc_ipc_attach_queue(context->cluster_id, context->ipc_queues[id], rx_only);

        if (q == NULL) {
            DPE(context->errbuf, "pfring_zc_ipc_attach_queue(): unable to open queue %d from cluster %d (RX)",
                context->ipc_queues[id], context->cluster_id);
            return -1;
        }

    }

    context->rx_queues[id] = q;

    context->netmask = htonl(default_net);

    return 0;
}
Exemplo n.º 10
0
static int start_instance(AFPacket_Context_t *afpc, AFPacketInstance *instance)
{
    struct packet_mreq mr;
    int arptype;

    /* Bind to the specified device so we only see packets from it. */
    if (bind_interface(afpc, instance) != 0)
        return -1;

    /* Turn on promiscuous mode for the device. */
    memset(&mr, 0, sizeof(mr));
    mr.mr_ifindex = instance->index;
    mr.mr_type = PACKET_MR_PROMISC;
    if (setsockopt(instance->fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr, sizeof(mr)) == -1)
    {
        DPE(afpc->errbuf, "%s: setsockopt: %s", __FUNCTION__, strerror(errno));
        return -1;
    }

    /* Get the link-layer type. */
    arptype = iface_get_arptype(instance);
    if (arptype < 0)
    {
        DPE(afpc->errbuf, "%s: failed to get interface type for device %s: (%d) %s",
            __FUNCTION__, instance->name, errno, strerror(errno));
        return -1;
    }

    if (arptype != ARPHRD_ETHER)
    {
        DPE(afpc->errbuf, "%s: invalid interface type for device %s: %d != %d",
            __FUNCTION__, instance->name, arptype, ARPHRD_ETHER);
        return -1;
    }

    /* Determine which versions of TPACKET the socket supports. */
    if (determine_version(afpc, instance) != DAQ_SUCCESS)
        return -1;

    if (afpc->debug)
    {
        printf("Version: %u\n", instance->tp_version);
        printf("Header Length: %u\n", instance->tp_hdrlen);
    }

    if (create_rx_ring(afpc, instance) != DAQ_SUCCESS)
        return -1;

    if (set_up_rx_ring(afpc, instance) != DAQ_SUCCESS)
        return -1;

    return 0;
}
Exemplo n.º 11
0
static AFPacketInstance *create_instance(AFPacket_Context_t *afpc, const char *device)
{
    AFPacketInstance *instance = NULL;

    instance = calloc(1, sizeof(AFPacketInstance));
    if (!instance)
    {
        DPE(afpc->errbuf, "%s: Could not allocate a new instance structure.", __FUNCTION__);
        goto err;
    }

    instance->buffer = MAP_FAILED;

    if ((instance->name = strdup(device)) == NULL)
    {
        DPE(afpc->errbuf, "%s: Could not allocate a copy of the device name.", __FUNCTION__);
        goto err;;
    }

    /* Open the PF_PACKET raw socket to receive all network traffic completely unmodified. */
    instance->fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
    if (instance->fd == -1)
    {
        DPE(afpc->errbuf, "%s: Could not open the PF_PACKET socket: %s", __FUNCTION__, strerror(errno));
        goto err;
    }
    /*
    #ifdef SO_BROADCAST
        tmp = 1;
        if (setsockopt(instance->fd, SOL_SOCKET, SO_BROADCAST, &tmp, sizeof(tmp)) < 0)
        {
            fprintf(stderr, "init_af_packet: failed to set broadcast for device %s", instance->name);
            rval = -8;
            goto bail;
        }
    #endif
    */
    /* Find the device index of the specified interface. */
    instance->index = find_device_index(instance, instance->name);
    if (instance->index == -1)
    {
        DPE(afpc->errbuf, "%s: Could not find index for device %s", __FUNCTION__, instance->name);
        goto err;
    }

    return instance;

err:
    destroy_instance(instance);
    return NULL;
}
Exemplo n.º 12
0
static int set_up_ring(AFPacket_Context_t *afpc, AFPacketInstance *instance, AFPacketRing *ring)
{
    unsigned int idx, block, block_offset, frame, frame_offset;

    /* Allocate a ring to hold packet pointers. */
    ring->entries = calloc(ring->layout.tp_frame_nr, sizeof(AFPacketEntry));
    if (!ring->entries)
    {
        DPE(afpc->errbuf, "%s: Could not allocate ring buffer entries for device %s!", __FUNCTION__, instance->name);
        return DAQ_ERROR_NOMEM;
    }

    /* Set up the buffer entry pointers in the ring. */
    idx = 0;
    for (block = 0; block < ring->layout.tp_block_nr; block++)
    {
        block_offset = block * ring->layout.tp_block_size;
        for (frame = 0; frame < (ring->layout.tp_block_size / ring->layout.tp_frame_size) && idx < ring->layout.tp_frame_nr; frame++)
        {
            frame_offset = frame * ring->layout.tp_frame_size;
            ring->entries[idx].hdr.raw = (uint8_t *) ring->start + block_offset + frame_offset;
            ring->entries[idx].next = &ring->entries[idx + 1];
            idx++;
        }
    }
    /* Make this a circular buffer ... a RING if you will! */
    ring->entries[ring->layout.tp_frame_nr - 1].next = &ring->entries[0];
    /* Initialize our entry point into the ring as the first buffer entry. */
    ring->cursor = &ring->entries[0];

    return DAQ_SUCCESS;
}
Exemplo n.º 13
0
static int file_read(FileImpl* impl)
{
    int n = read(impl->fid, impl->buf, impl->snaplen);

    if ( !n )
    {
        if ( !impl->eof )
        {
            impl->eof = 1;
            return 1;  // <= zero won't make it :(
        }
        return DAQ_READFILE_EOF;
    }

    if ( n < 0 )
    {
        if (errno != EINTR)
        {
            DPE(impl->error, "%s: can't read from file (%s)\n",
                DAQ_NAME, strerror(errno));
        }
        return DAQ_ERROR;
    }
    return n;
}
Exemplo n.º 14
0
static int calculate_layout(AFPacket_Context_t *afpc, AFPacketInstance *instance, int order)
{
    /* Calculate the frame size and minimum block size required. */
    instance->layout.tp_frame_size = TPACKET_ALIGN(afpc->snaplen + TPACKET_ALIGN(TPACKET_ALIGN(instance->tp_hdrlen) + sizeof(struct sockaddr_ll) + ETH_HLEN) - ETH_HLEN);
    instance->layout.tp_block_size = getpagesize() << order;
    while (instance->layout.tp_block_size < instance->layout.tp_frame_size)
        instance->layout.tp_block_size <<= 1;
    instance->frames_per_block = instance->layout.tp_block_size / instance->layout.tp_frame_size;
    if (instance->frames_per_block == 0)
    {
        DPE(afpc->errbuf, "%s: Invalid frames per block (%u/%u) for %s",
            __FUNCTION__, instance->layout.tp_block_size, instance->layout.tp_frame_size, afpc->device);
        return DAQ_ERROR;
    }

    /* Find the total number of frames required to amount to the requested per-interface memory.
        Then find the number of blocks required to hold those packet buffer frames. */
    instance->layout.tp_frame_nr = afpc->size / instance->layout.tp_frame_size;
    instance->layout.tp_block_nr = instance->layout.tp_frame_nr / instance->frames_per_block;
    /* afpc->layout.tp_frame_nr is requested to match frames_per_block*n_blocks */
    instance->layout.tp_frame_nr = instance->layout.tp_block_nr * instance->frames_per_block;
    if (afpc->debug)
    {
        printf("AFPacket Layout:\n");
        printf("  Frame Size: %u\n", instance->layout.tp_frame_size);
        printf("  Frames:     %u\n", instance->layout.tp_frame_nr);
        printf("  Block Size: %u (Order %d)\n", instance->layout.tp_block_size, order);
        printf("  Blocks:     %u\n", instance->layout.tp_block_nr);
    }

    return DAQ_SUCCESS;
}
Exemplo n.º 15
0
static int update_hw_stats(Pfring_Context_t *context) {
  pfring_stat ps;
  int i;

  for (i = 0; i < context->num_devices; i++)
    if (context->ring_handles[i] == NULL)
      /* daq stopped - using last available stats */
      return DAQ_SUCCESS;

  context->stats.hw_packets_received = 0;
  context->stats.hw_packets_dropped = 0;

  for (i = 0; i < context->num_devices; i++) {
    memset(&ps, 0, sizeof(pfring_stat));

    if(pfring_stats(context->ring_handles[i], &ps) < 0) {
      DPE(context->errbuf, "%s: pfring_stats error [ring_idx = %d]", __FUNCTION__, i);
      return DAQ_ERROR;
    }

    context->stats.hw_packets_received += (ps.recv - context->base_recv[i]);
    context->stats.hw_packets_dropped  += (ps.drop - context->base_drop[i]);
  }

  return DAQ_SUCCESS;
}
Exemplo n.º 16
0
static int hext_read(FileImpl* impl)
{
    int n = 0;

    while ( impl->line[0] || fgets(impl->line, sizeof(impl->line), impl->fyle) )
    {
        if ( (n = parse(impl)) )
            break;
    }

    if ( !n )
        n = flush(impl);

    if ( !n )
    {
        if ( (impl->dlt == DLT_USER) && !impl->eof )
        {
            impl->eof = 1;
            return 1;  // <= zero won't make it :(
        }
        return DAQ_READFILE_EOF;
    }

    if ( n < 0 )
    {
        if (errno != EINTR)
        {
            DPE(impl->error, "%s: can't read from file (%s)\n",
                DAQ_NAME, strerror(errno));
        }
        return DAQ_ERROR;
    }
    return n;
}
Exemplo n.º 17
0
static int afpacket_daq_inject(void *handle, const DAQ_PktHdr_t *hdr, const uint8_t *packet_data, uint32_t len, int reverse)
{
    AFPacket_Context_t *afpc = (AFPacket_Context_t *) handle;
    AFPacketInstance *instance;
    AFPacketEntry *entry;

    /* Find the instance that the packet was received on. */
    for (instance = afpc->instances; instance; instance = instance->next)
    {
        if (instance->index == hdr->ingress_index)
            break;
    }

    if (!instance || (!reverse && !(instance = instance->peer)))
        return DAQ_ERROR;

    entry = instance->tx_ring.cursor;
    if (entry->hdr.h2->tp_status == TP_STATUS_AVAILABLE)
    {
        memcpy(entry->hdr.raw + TPACKET_ALIGN(instance->tp_hdrlen), packet_data, len);
        entry->hdr.h2->tp_len = len;
        entry->hdr.h2->tp_status = TP_STATUS_SEND_REQUEST;
        instance->tx_ring.cursor = entry->next;
        if (send(instance->fd, NULL, 0, 0) < 0)
        {
            DPE(afpc->errbuf, "%s: Error sending packet: %s (%d)", __FUNCTION__, strerror(errno), errno);
            return DAQ_ERROR;
        }
        afpc->stats.packets_injected++;
    }

    return DAQ_SUCCESS;
}
Exemplo n.º 18
0
static int pfring_daq_set_filter(void *handle, const char *filter) {
  Pfring_Context_t *context = (Pfring_Context_t *) handle;
  int ret, i;
  struct sfbpf_program fcode;

  if(context->ring_handles[DAQ_PF_RING_PASSIVE_DEV_IDX]) {
    if(sfbpf_compile(context->snaplen, DLT_EN10MB, &fcode,
		     filter, 0 /* 1: optimize */, htonl(context->netmask)) < 0) {
      DPE(context->errbuf, "%s: BPF state machine compilation failed!", __FUNCTION__);
      return DAQ_ERROR;
    }

    ret = DAQ_SUCCESS;
    for (i = 0; i < context->num_devices; i++) {
      if(setsockopt(pfring_get_selectable_fd(context->ring_handles[i]), 0,
		    SO_ATTACH_FILTER, &fcode, sizeof(fcode)) != 0) {
        ret = DAQ_ERROR;
      }
    }

    sfbpf_freecode(&fcode);
  } else {
    /* Just check if the filter is valid */
    if(sfbpf_compile(context->snaplen, DLT_EN10MB, &fcode,
    		     filter, 0 /* 1: optimize */, 0 /* netmask */) < 0) {
      DPE(context->errbuf, "%s: BPF state machine compilation failed!", __FUNCTION__);
      return DAQ_ERROR;
    }

    ret = DAQ_SUCCESS;

    if(context->filter_string)
      free(context->filter_string);

    context->filter_string = strdup(filter);

    if(!context->filter_string) {
      DPE(context->errbuf, "%s: Couldn't allocate memory for the filter string!",
	  __FUNCTION__);
      ret = DAQ_ERROR;
    }

    sfbpf_freecode(&fcode);
  }

  return ret;
}
Exemplo n.º 19
0
static void pfring_zc_daq_set_errbuf(void *handle, const char *string) {
    Pfring_Context_t *context =(Pfring_Context_t *) handle;

    if (!string)
        return;

    DPE(context->errbuf, "%s", string);
}
Exemplo n.º 20
0
static void afpacket_daq_set_errbuf(void *handle, const char *string)
{
    AFPacket_Context_t *afpc = (AFPacket_Context_t *) handle;

    if (!string)
        return;

    DPE(afpc->errbuf, "%s", string);
}
Exemplo n.º 21
0
static int set_up_rx_ring(AFPacket_Context_t *afpc, AFPacketInstance *instance)
{
    unsigned idx, block, frame, ringsize;

    /* Memory map the RX ring. */
    ringsize = instance->layout.tp_block_nr * instance->layout.tp_block_size;
    instance->buffer = mmap(0, ringsize, PROT_READ | PROT_WRITE, MAP_SHARED, instance->fd, 0);
    if (instance->buffer == MAP_FAILED)
    {
        DPE(afpc->errbuf, "%s: Couldn't MMAP the RX ring: %s", __FUNCTION__, strerror(errno));

        /* Destroy the kernel RX ring on error. */
        destroy_rx_ring(instance);
        return DAQ_ERROR;
    }

    /* Allocate a ring to hold packet pointers. */
    instance->ring = calloc(instance->layout.tp_frame_nr, sizeof(AFPacketEntry));
    if (!instance->ring)
    {
        DPE(afpc->errbuf, "%s: Could not allocate entry ring for device %s", __FUNCTION__, instance->name);
        destroy_rx_ring(instance);
        return DAQ_ERROR_NOMEM;
    }

    /* Set up the buffer entry pointers in the ring. */
    idx = 0;
    for (block = 0; block < instance->layout.tp_block_nr; block++)
    {
        for (frame = 0; frame < instance->frames_per_block; frame++)
        {
            instance->ring[idx].begin = (uint8_t *) instance->buffer + (block * instance->layout.tp_block_size) + (frame * instance->layout.tp_frame_size);
            instance->ring[idx].hdr.raw = instance->ring[idx].begin;
            instance->ring[idx].next = &instance->ring[idx + 1];
            idx++;
        }
    }
    /* Make this a circular buffer ... a RING if you will! */
    instance->ring[instance->layout.tp_frame_nr - 1].next = &instance->ring[0];
    /* Initialize our entry point into the ring as the first buffer entry. */
    instance->entry = &instance->ring[0];

    return DAQ_SUCCESS;
}
Exemplo n.º 22
0
static int file_setup(FileImpl* impl)
{
    if ( !strcmp(impl->name, "tty") )
    {
        impl->fid = STDIN_FILENO;
    }
    else if ( (impl->fid = open(impl->name, O_RDONLY|O_NONBLOCK)) < 0 )
    {
        char error_msg[1024] = {0};
        if (strerror_r(errno, error_msg, sizeof(error_msg)) == 0)
            DPE(impl->error, "%s: can't open file (%s)\n", DAQ_NAME, error_msg);
        else
            DPE(impl->error, "%s: can't open file: %d\n", DAQ_NAME, errno);
        return -1;
    }
    impl->start = 1;

    return 0;
}
Exemplo n.º 23
0
/* The function below was heavily influenced by LibPCAP's pcap-linux.c.  Thanks! */
static int determine_version(AFPacket_Context_t *afpc, AFPacketInstance *instance)
{
    socklen_t len;
    int val;

    /* Probe whether kernel supports TPACKET_V2 */
    val = TPACKET_V2;
    len = sizeof(val);
    if (getsockopt(instance->fd, SOL_PACKET, PACKET_HDRLEN, &val, &len) < 0)
    {
        DPE(afpc->errbuf, "Couldn't retrieve TPACKET_V2 header length: %s", strerror(errno));
        return -1;
    }
    instance->tp_hdrlen = val;

    /* Tell the kernel to use TPACKET_V2 */
    val = TPACKET_V2;
    if (setsockopt(instance->fd, SOL_PACKET, PACKET_VERSION, &val, sizeof(val)) < 0)
    {
        DPE(afpc->errbuf, "Couldn't activate TPACKET_V2 on packet socket: %s", strerror(errno));
        return -1;
    }
    instance->tp_version = TPACKET_V2;

    /* Reserve space for VLAN tag reconstruction */
    val = VLAN_TAG_LEN;
    if (setsockopt(instance->fd, SOL_PACKET, PACKET_RESERVE, &val, sizeof(val)) < 0)
    {
        DPE(afpc->errbuf, "Couldn't set up a %d-byte reservation packet socket: %s", val, strerror(errno));
        return -1;
    }

    if (afpc->debug)
    {
        printf("Version: %u\n", instance->tp_version);
        printf("Header Length: %u\n", instance->tp_hdrlen);
    }

    return DAQ_SUCCESS;
}
Exemplo n.º 24
0
static void endace_daq_set_errbuf(void *handle, const char *string)
{
	EndaceDAGCtx_t *ctx = (EndaceDAGCtx_t *) handle;
	if (!ctx)
	{
		return;
	}
	if (!string)
	{
		return;
	}
	DPE(ctx->errbuf, "%s", string);
}
Exemplo n.º 25
0
static int daq_nfq_callback(
    struct nfq_q_handle* qh,
    struct nfgenmsg* nfmsg,
    struct nfq_data* nfad,
    void* data)
{
    NfqImpl *impl = (NfqImpl*)data;
    struct nfqnl_msg_packet_hdr* ph = nfq_get_msg_packet_hdr(nfad);

    DAQ_Verdict verdict;
    DAQ_PktHdr_t hdr;
    uint8_t* pkt;
    int nf_verdict;
    uint32_t data_len;

    if ( impl->state != DAQ_STATE_STARTED )
        return -1;

    if ( !ph || SetPktHdr(impl, nfad, &hdr, &pkt) )
    {
        DPE(impl->error, "%s: can't setup packet header",
            __FUNCTION__);
        return -1;
    }

    if (
        impl->fcode.bf_insns &&
        sfbpf_filter(impl->fcode.bf_insns, pkt, hdr.caplen, hdr.caplen) == 0
    ) {
        verdict = DAQ_VERDICT_PASS;
        impl->stats.packets_filtered++;
    }
    else
    {
        verdict = impl->user_func(impl->user_data, &hdr, pkt);

        if ( verdict >= MAX_DAQ_VERDICT )
            verdict = DAQ_VERDICT_BLOCK;

        impl->stats.verdicts[verdict]++;
        impl->stats.packets_received++;
    }
    nf_verdict = ( impl->passive || s_fwd[verdict] ) ? NF_ACCEPT : NF_DROP;
    data_len = ( verdict == DAQ_VERDICT_REPLACE ) ? hdr.caplen : 0;

    nfq_set_verdict(
        impl->nf_queue, ntohl(ph->packet_id),
        nf_verdict, data_len, pkt);

    return 0;
}
Exemplo n.º 26
0
/* The function below was heavily influenced by LibPCAP's pcap-linux.c.  Thanks! */
static int determine_version(AFPacket_Context_t *afpc, AFPacketInstance *instance)
{
#ifdef HAVE_TPACKET2
    socklen_t len;
    int val;
#endif

    instance->tp_version = TPACKET_V1;
    instance->tp_hdrlen = sizeof(struct tpacket_hdr);

#ifdef HAVE_TPACKET2
    /* Probe whether kernel supports TPACKET_V2 */
    val = TPACKET_V2;
    len = sizeof(val);
    if (getsockopt(instance->fd, SOL_PACKET, PACKET_HDRLEN, &val, &len) < 0)
    {
        /* Version 2 is not supported, stick with V1. */
        if (errno == ENOPROTOOPT)
            return DAQ_SUCCESS;

        DPE(afpc->errbuf, "Couldn't retrieve TPACKET_V2 header length: %s", strerror(errno));
        return -1;
    }
    instance->tp_hdrlen = val;

    val = TPACKET_V2;
    if (setsockopt(instance->fd, SOL_PACKET, PACKET_VERSION, &val, sizeof(val)) < 0)
    {
        DPE(afpc->errbuf, "Couldn't activate TPACKET_V2 on packet socket: %s", strerror(errno));
        return -1;
    }
    instance->tp_version = TPACKET_V2;

#endif /* HAVE_TPACKET2 */
    return DAQ_SUCCESS;
}
Exemplo n.º 27
0
static int file_setup(FileImpl* impl)
{
    if ( !strcmp(impl->name, "tty") )
    {
        impl->fid = STDIN_FILENO;
    }
    else if ( (impl->fid = open(impl->name, O_RDONLY|O_NONBLOCK)) < 0 )
    {
        DPE(impl->error, "%s: can't open file (%s)\n",
            DAQ_NAME, strerror(errno));
        return -1;
    }
    impl->start = 1;

    return 0;
}
Exemplo n.º 28
0
static int pfring_zc_daq_send_packet(Pfring_Context_t *context, pfring_zc_queue *txq, u_int pkt_len) {
    int rc;

    if (txq == NULL)
        return DAQ_ERROR;

    rc = pfring_zc_send_pkt(txq, &context->buffer, 1 /* flush packet */);

    if (rc < 0) {
        DPE(context->errbuf, "%s", "pfring_zc_send_pkt() error");
        return DAQ_ERROR;
    }

    context->stats.packets_injected++;

    return DAQ_SUCCESS;
}
Exemplo n.º 29
0
static int mmap_rings(AFPacket_Context_t *afpc, AFPacketInstance *instance)
{
    unsigned int ringsize;

    /* Map the ring into userspace. */
    ringsize = instance->rx_ring.size + instance->tx_ring.size;
    instance->buffer = mmap(0, ringsize, PROT_READ | PROT_WRITE, MAP_SHARED, instance->fd, 0);
    if (instance->buffer == MAP_FAILED)
    {
        DPE(afpc->errbuf, "%s: Could not MMAP the ring: %s", __FUNCTION__, strerror(errno));
        return DAQ_ERROR;
    }
    instance->rx_ring.start = instance->buffer;
    instance->tx_ring.start = (uint8_t *) instance->buffer + instance->tx_ring.size;

    return DAQ_SUCCESS;
}
Exemplo n.º 30
0
static int pcaprr_daq_inject(void *handle, const DAQ_PktHdr_t *hdr, const uint8_t *packet_data, uint32_t len, int reverse)
{
    Pcaprr_Context_t *context = (Pcaprr_Context_t *) handle;
    int i;
    pcap_t *thandle;

    for (i = 0 ; i < context->handle_count ; i++) {
	    thandle = context->handle[i];
	    if (pcap_inject(thandle, packet_data, len) < 0)
	    {
	        DPE(context->errbuf, "%s", pcap_geterr(thandle));
	        return DAQ_ERROR;
	    }
    }

    context->stats.packets_injected++;
    return DAQ_SUCCESS;
}