Example #1
0
static int endace_daq_initialize(const DAQ_Config_t * config, void **ctxt_ptr, char *errbuf, size_t len)
{
	// Passive mode is all that is currently supported
	if (config->mode != DAQ_MODE_PASSIVE)
	{
		snprintf(errbuf, len, "%s: Unsupported mode", __FUNCTION__);
		return DAQ_ERROR;
	}

	// Setup the context
	EndaceDAGCtx_t *ctx = calloc(1, sizeof(EndaceDAGCtx_t));
	if (!ctx)
	{
		snprintf(errbuf, len, "%s: failed to allocate memory for the new Endace DAG context!", __FUNCTION__);
		return DAQ_ERROR_NOMEM;
	}

	// Parse device information out for processing
	if ( dag_parse_name(config->name, ctx->name, DAGNAME_BUFSIZE, &ctx->stream) < 0 )
	{
		snprintf(errbuf, len, "%s: invalid device specification!", __FUNCTION__);
		return DAQ_ERROR;
	}

	ctx->state = DAQ_STATE_INITIALIZED;
	ctx->snaplen = config->snaplen;

	*ctxt_ptr = ctx;
	return DAQ_SUCCESS;
}
Example #2
0
/**
 * \brief   Initialize the ERF receiver thread, generate a single
 *          ErfDagThreadVar structure for each thread, this will
 *          contain a DAG file descriptor which is read when the
 *          thread executes.
 *
 * \param tv        Thread variable to ThreadVars
 * \param initdata  Initial data to the interface passed from the user,
 *                  this is processed by the user.
 *
 *                  We assume that we have only a single name for the DAG
 *                  interface.
 *
 * \param data      data pointer gets populated with
 *
 */
TmEcode
ReceiveErfDagThreadInit(ThreadVars *tv, void *initdata, void **data)
{
    SCEnter();
    int stream_count = 0;

    if (initdata == NULL) {
        SCLogError(SC_ERR_INVALID_ARGUMENT, "Error: No DAG interface provided.");
        SCReturnInt(TM_ECODE_FAILED);
    }

    ErfDagThreadVars *ewtn = SCMalloc(sizeof(ErfDagThreadVars));
    if (unlikely(ewtn == NULL)) {
        SCLogError(SC_ERR_MEM_ALLOC, "Failed to allocate memory for ERF DAG thread vars.");
        exit(EXIT_FAILURE);
    }

    memset(ewtn, 0, sizeof(*ewtn));

    /* dag_parse_name will return a DAG device name and stream number
     * to open for this thread.
     */
    if (dag_parse_name(initdata, ewtn->dagname, DAGNAME_BUFSIZE,
                       &ewtn->dagstream) < 0)
    {
        SCLogError(SC_ERR_INVALID_ARGUMENT,
                   "Failed to parse DAG interface: %s",
                   (char*)initdata);
        SCFree(ewtn);
        exit(EXIT_FAILURE);
    }

    SCLogInfo("Opening DAG: %s on stream: %d for processing",
              ewtn->dagname, ewtn->dagstream);

    if ((ewtn->dagfd = dag_open(ewtn->dagname)) < 0)
    {
        SCLogError(SC_ERR_ERF_DAG_OPEN_FAILED, "Failed to open DAG: %s",
                   ewtn->dagname);
        SCFree(ewtn);
        SCReturnInt(TM_ECODE_FAILED);
    }

    /* Check to make sure the card has enough available streams to
     * support reading from the one specified.
     */
    if ((stream_count = dag_rx_get_stream_count(ewtn->dagfd)) < 0)
    {
        SCLogError(SC_ERR_ERF_DAG_OPEN_FAILED,
                   "Failed to open stream: %d, DAG: %s, could not query stream count",
                   ewtn->dagstream, ewtn->dagname);
        SCFree(ewtn);
        SCReturnInt(TM_ECODE_FAILED);
    }

    /* Check to make sure we have enough rx streams to open the stream
     * the user is asking for.
     */
    if (ewtn->dagstream > stream_count*2)
    {
        SCLogError(SC_ERR_ERF_DAG_OPEN_FAILED,
                   "Failed to open stream: %d, DAG: %s, insufficient streams: %d",
                   ewtn->dagstream, ewtn->dagname, stream_count);
        SCFree(ewtn);
        SCReturnInt(TM_ECODE_FAILED);
    }

    /* If we are transmitting into a soft DAG card then set the stream
     * to act in reverse mode.
     */
    if (0 != (ewtn->dagstream & 0x01))
    {
        /* Setting reverse mode for using with soft dag from daemon side */
        if(dag_set_mode(ewtn->dagfd, ewtn->dagstream, DAG_REVERSE_MODE)) {
            SCLogError(SC_ERR_ERF_DAG_STREAM_OPEN_FAILED,
                       "Failed to set mode to DAG_REVERSE_MODE on stream: %d, DAG: %s",
                       ewtn->dagstream, ewtn->dagname);
            SCFree(ewtn);
            SCReturnInt(TM_ECODE_FAILED);
        }
    }

    if (dag_attach_stream(ewtn->dagfd, ewtn->dagstream, 0, 0) < 0)
    {
        SCLogError(SC_ERR_ERF_DAG_STREAM_OPEN_FAILED,
                   "Failed to open DAG stream: %d, DAG: %s",
                   ewtn->dagstream, ewtn->dagname);
        SCFree(ewtn);
        SCReturnInt(TM_ECODE_FAILED);
    }

    if (dag_start_stream(ewtn->dagfd, ewtn->dagstream) < 0)
    {
        SCLogError(SC_ERR_ERF_DAG_STREAM_START_FAILED,
                   "Failed to start DAG stream: %d, DAG: %s",
                   ewtn->dagstream, ewtn->dagname);
        SCFree(ewtn);
        SCReturnInt(TM_ECODE_FAILED);
    }

    SCLogInfo("Attached and started stream: %d on DAG: %s",
              ewtn->dagstream, ewtn->dagname);

    /*
     * Initialise DAG Polling parameters.
     */
    timerclear(&ewtn->maxwait);
    ewtn->maxwait.tv_usec = 20 * 1000; /* 20ms timeout */
    timerclear(&ewtn->poll);
    ewtn->poll.tv_usec = 1 * 1000; /* 1ms poll interval */

    /* 32kB minimum data to return -- we still restrict the number of
     * pkts that are processed to a maximum of dag_max_read_packets.
     */
    if (dag_set_stream_poll(ewtn->dagfd, ewtn->dagstream, 32*1024, &(ewtn->maxwait), &(ewtn->poll)) < 0)
    {
        SCLogError(SC_ERR_ERF_DAG_STREAM_SET_FAILED,
                   "Failed to set poll parameters for stream: %d, DAG: %s",
                   ewtn->dagstream, ewtn->dagname);
        SCFree(ewtn);
        SCReturnInt(TM_ECODE_FAILED);
    }

    ewtn->packets = SCPerfTVRegisterCounter("capture.dag_packets",
                                            tv, SC_PERF_TYPE_UINT64, "NULL");
    ewtn->drops = SCPerfTVRegisterCounter("capture.dag_drops",
                                          tv, SC_PERF_TYPE_UINT64, "NULL");

    ewtn->tv = tv;
    *data = (void *)ewtn;

    SCLogInfo("Starting processing packets from stream: %d on DAG: %s",
              ewtn->dagstream, ewtn->dagname);

    SCReturnInt(TM_ECODE_OK);
}
Example #3
0
int pfring_dag_open(pfring *ring) {
  int i = 0;
  pfring_dag *d = NULL;
  uint32_t mindata;
  struct timeval maxwait;
  struct timeval poll;
  daginf_t* info;
  uint8_t stream_erf_types[MAX_CARD_ERF_TYPES];
  uint8_t supported = 0;

  ring->close = pfring_dag_close;
  ring->stats = pfring_dag_stats;
  ring->recv  = pfring_dag_recv;
  ring->set_poll_watermark = pfring_dag_set_poll_watermark;
  ring->set_poll_duration  = pfring_dag_set_poll_duration;
  ring->set_direction      = pfring_dag_set_direction;
  ring->enable_ring        = pfring_dag_enable_ring;

  ring->priv_data = malloc(sizeof(pfring_dag)); 

  if(ring->priv_data == NULL)
    goto ret_error; 
  
  memset(ring->priv_data, 0, sizeof(pfring_dag));
  d = ring->priv_data;

  if(ring->caplen > MAX_CAPLEN) 
    ring->caplen = MAX_CAPLEN;

  d->device_name = (char *) malloc(DAGNAME_BUFSIZE);

  if (d->device_name == NULL) {
    goto free_private;
  }

  if (dag_parse_name(ring->device_name, d->device_name, DAGNAME_BUFSIZE, &d->stream_num) < 0) {
    fprintf(stderr,"Error: device name not recognized\n");
    goto free_device_name;
  }

  if (d->stream_num % 2) {
    fprintf(stderr,"Error: odd-numbered streams are TX streams\n");
    goto free_device_name;
  }

  if((d->fd = dag_open((char *) d->device_name)) < 0) {
    fprintf(stderr, "Error opening %s\n", d->device_name);
    goto free_device_name;
  }

  if (dag_attach_stream(d->fd, d->stream_num, 0, 0) < 0) {
    fprintf(stderr, "Error attaching to stream %d: is it already attached to another application?\n", d->stream_num);
    goto dag_close;
  }

  if (dag_get_stream_poll(d->fd, d->stream_num, &mindata, &maxwait, &poll) < 0) {
    fprintf(stderr, "Error getting poll info\n");
    goto dag_detach;
  }
	
  ring->poll_duration = DEFAULT_POLL_DURATION;

  mindata = DEFAULT_MIN_PKT_QUEUED * AVG_PACKET_SIZE; //min_pkt=128, avg=512 -> min_bytes=65536

  maxwait.tv_sec  =  ring->poll_duration / 1000;
  maxwait.tv_usec = (ring->poll_duration % 1000) * 1000;

  if (dag_set_stream_poll(d->fd, d->stream_num, mindata, &maxwait, &poll) < 0) {
    fprintf(stderr, "Error setting poll info\n");
    goto dag_detach;
  }

  if(dag_start_stream(d->fd, d->stream_num) < 0) {
    fprintf(stderr, "Error starting stream\n");
    goto dag_detach;
  }

  d->bottom = NULL;
  d->top    = NULL;

  d->strip_crc = 1;

  info = dag_info(d->fd);
  if (info->device_code == 0x4200 || info->device_code == 0x4230) //these cards already strip the CRC
    d->strip_crc = 0;

  memset(stream_erf_types, 0, MAX_CARD_ERF_TYPES);

  if (dag_get_stream_erf_types(d->fd, d->stream_num, stream_erf_types, MAX_CARD_ERF_TYPES) < 0) {
    fprintf(stderr, "Error getting stream type\n");
    goto dag_stop;
  }

  while (stream_erf_types[i] && i<MAX_CARD_ERF_TYPES)
  switch(stream_erf_types[i++] & 0x7f) {
    case TYPE_ETH:
    case TYPE_COLOR_ETH:
    case TYPE_DSM_COLOR_ETH:
    case TYPE_COLOR_HASH_ETH:
      supported = 1;
      break;
    default:
      break;
  }
  
  if (!supported){
      fprintf(stderr, "Error: stream type not supported\n");
      goto dag_stop;
  }

  return 0;

dag_stop:
  dag_stop_stream(d->fd, d->stream_num);
	
dag_detach:
  dag_detach_stream(d->fd, d->stream_num);

dag_close:
  dag_close(ring->fd);

free_device_name:
  free(d->device_name);

free_private:
  free(ring->priv_data);

ret_error:
  return -1;
}
Example #4
0
int open_device(char *dagname_buf)
{
    struct timeval  maxwait;
    struct timeval  poll;
    //daginf_t        *daginfo;

    //dagutil_set_progname("DAG_CAPD");

    /* Set up default DAG device. */
#if 0
    if (-1 == dag_parse_name(dagname_buf, dagname, DAGNAME_BUFSIZE, &dag_devnum)) {
        log_print(LOGN_CRI, "%s: FAIL[dag_parse_name] [%s]", __FUNCTION__, strerror(errno));
        exit(errno);
    }

    if((dag_fd = dag_open(dagname)) < 0) {
        log_print(LOGN_CRI, "%s: FAIL[dag_open] [%s]", __FUNCTION__, strerror(errno));
        exit(errno);
    }

    /* No option configured now.*/
    buffer[0] = 0;
    if(dag_configure(dag_fd, buffer) < 0) {
        log_print(LOGN_CRI, "%s: FAIL[dag_configure] [%s]", __FUNCTION__, strerror(errno));
        exit(errno);
    }

    if(dag_attach_stream(dag_fd, dag_devnum, 0, 0) < 0) {
        log_print(LOGN_CRI, "%s: FAIL[dag_attach_stream] [%s]", __FUNCTION__, strerror(errno));
        exit(errno);
    }

    if(dag_start_stream(dag_fd, dag_devnum) < 0) {
        log_print(LOGN_CRI, "%s: FAIL[dag_start_stream] [%s]", __FUNCTION__, strerror(errno));
        exit(errno);
    }

    /* Query the card first for special cases. */
    daginfo = dag_info(dag_fd);
    if ((0x4200 == daginfo->device_code) || (0x4230 == daginfo->device_code)) {
        /* DAG 4.2S and 4.23S already strip the FCS. */
        /* Stripping the final word again truncates the packet. */
        /* (pcap-dag.c of libpcap) */
        fcs_bits = 0;
    }
    log_print(LOGN_INFO, "DEVICE[%04x]: %s [FCS: %d]",
              daginfo->device_code, dag_device_name(daginfo->device_code, 1), fcs_bits);
#endif
    /*
     * Initialise DAG Polling parameters.
     */
#if 0
    timerclear(&maxwait);
    maxwait.tv_usec = 100 * 1000; /* 100ms timeout */
    timerclear(&poll);
    poll.tv_usec = 10 * 1000; /* 10ms poll interval */

    /* 32kB minimum data to return */
    dag_set_stream_poll(dag_fd, dag_devnum, 32*ONE_KIBI, &maxwait, &poll);
#endif

#if 1
    uint32_t mindata;

    timerclear(&maxwait);
    //maxwait.tv_usec = 100 * 1000; /* 100ms timeout */
    timerclear(&poll);
    //poll.tv_usec = 10 * 1000; /* 10ms poll interval */

    //mindata = 32*1024;
    mindata = 0;

    /* 32kB minimum data to return */
    //dag_set_stream_poll(dag_fd, dag_devnum, mindata, &maxwait, &poll);
#endif

    log_print( LOGN_DEBUG, "dag_devnum:%d", dag_devnum );

    return 0;
}