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; }
/** * \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); }
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; }
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; }