-pcap_t *dag_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebuf) {
- char conf[30]; /* dag configure string */
- pcap_t *handle;
- char *s;
- int n;
-
- if (device == NULL) {
- snprintf(ebuf, PCAP_ERRBUF_SIZE, "device is NULL: %s", pcap_strerror(errno));
- return NULL;
- }
- /* Allocate a handle for this session. */
-
- handle = malloc(sizeof(*handle));
- if (handle == NULL) {
- snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc %s: %s", device, pcap_strerror(errno));
- return NULL;
- }
-
- /* Initialize some components of the pcap structure. */
-
- memset(handle, 0, sizeof(*handle));
-
- if (strstr(device, "/dev") == NULL) {
- char * newDev = (char *)malloc(strlen(device) + 6);
- newDev[0] = '\0';
- strcat(newDev, "/dev/");
- strcat(newDev,device);
- device = newDev;
- } else {
- device = strdup(device);
- }
-
- if (device == NULL) {
- snprintf(ebuf, PCAP_ERRBUF_SIZE, "str_dup: %s\n", pcap_strerror(errno));
- goto fail;
- }
-
- /* setup device parameters */
- if((handle->fd = dag_open((char *)device)) < 0) {
- snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_open %s: %s", device, pcap_strerror(errno));
- goto fail;
- }
-
- /* set the card snap length to the specified snaplen parameter */
- if (snaplen == 0 || snaplen > MAX_DAG_SNAPLEN) {
- snaplen = MAX_DAG_SNAPLEN;
- } else if (snaplen < MIN_DAG_SNAPLEN) {
- snaplen = MIN_DAG_SNAPLEN;
- }
- /* snap len has to be a multiple of 4 */
- snprintf(conf, 30, "varlen slen=%d", (snaplen + 3) & ~3);
-
- fprintf(stderr, "Configuring DAG with '%s'.\n", conf);
- if(dag_configure(handle->fd, conf) < 0) {
- snprintf(ebuf, PCAP_ERRBUF_SIZE,"dag_configure %s: %s\n", device, pcap_strerror(errno));
- goto fail;
- }
-
- if((handle->md.dag_mem_base = dag_mmap(handle->fd)) == MAP_FAILED) {
- snprintf(ebuf, PCAP_ERRBUF_SIZE,"dag_mmap %s: %s\n", device, pcap_strerror(errno));
- goto fail;
- }
-
- if(dag_start(handle->fd) < 0) {
- snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_start %s: %s\n", device, pcap_strerror(errno));
- goto fail;
- }
-
- /*
- * Important! You have to ensure bottom is properly
- * initialized to zero on startup, it won't give you
- * a compiler warning if you make this mistake!
- */
- handle->md.dag_mem_bottom = 0;
- handle->md.dag_mem_top = 0;
-
- /* TODO: query the card */
- handle->md.dag_fcs_bits = 32;
- if ((s = getenv("ERF_FCS_BITS")) != NULL) {
- if ((n = atoi(s)) == 0 || n == 16|| n == 32) {
- handle->md.dag_fcs_bits = n;
- } else {
- snprintf(ebuf, PCAP_ERRBUF_SIZE,
- "pcap_open_live %s: bad ERF_FCS_BITS value (%d) in environment\n", device, n);
- goto fail;
- }
- }
-
- handle->snapshot = snaplen;
- /*handle->md.timeout = to_ms; */
-
- if ((handle->linktype = dag_get_datalink(handle)) < 0) {
- snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_get_linktype %s: unknown linktype\n", device);
- goto fail;
- }
-
- handle->bufsize = 0;
-
- if (new_pcap_dag(handle) < 0) {
- snprintf(ebuf, PCAP_ERRBUF_SIZE, "new_pcap_dag %s: %s\n", device, pcap_strerror(errno));
- goto fail;
- }
-
- /*
- * "select()" and "poll()" don't (yet) work on DAG device descriptors.
- */
- handle->selectable_fd = -1;
-
-#ifdef linux
- handle->md.device = (char *)device;
+static int dag_activate(pcap_t* handle)
+{
+ struct pcap_dag *handlep = handle->priv;
+#if 0
+ char conf[30]; /* dag configure string */
+#endif
+ char *s;
+ int n;
+ daginf_t* daginf;
+ char * newDev = NULL;
+ char * device = handle->opt.device;
+#ifdef HAVE_DAG_STREAMS_API
+ uint32_t mindata;
+ struct timeval maxwait;
+ struct timeval poll;
+#endif
+
+ if (device == NULL) {
+ pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "device is NULL: %s", pcap_strerror(errno));
+ return -1;
+ }
+
+ /* Initialize some components of the pcap structure. */
+
+#ifdef HAVE_DAG_STREAMS_API
+ newDev = (char *)malloc(strlen(device) + 16);
+ if (newDev == NULL) {
+ pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't allocate string for device name: %s", pcap_strerror(errno));
+ goto fail;
+ }
+
+ /* Parse input name to get dag device and stream number if provided */
+ if (dag_parse_name(device, newDev, strlen(device) + 16, &handlep->dag_stream) < 0) {
+ pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_parse_name: %s", pcap_strerror(errno));
+ goto fail;
+ }
+ device = newDev;
+
+ if (handlep->dag_stream%2) {
+ pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_parse_name: tx (even numbered) streams not supported for capture");
+ goto fail;
+ }
+#else
+ if (strncmp(device, "/dev/", 5) != 0) {
+ newDev = (char *)malloc(strlen(device) + 5);
+ if (newDev == NULL) {
+ pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't allocate string for device name: %s", pcap_strerror(errno));
+ goto fail;
+ }
+ strcpy(newDev, "/dev/");
+ strcat(newDev, device);
+ device = newDev;
+ }
+#endif /* HAVE_DAG_STREAMS_API */
+
+ /* setup device parameters */
+ if((handle->fd = dag_open((char *)device)) < 0) {
+ pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_open %s: %s", device, pcap_strerror(errno));
+ goto fail;
+ }
+
+#ifdef HAVE_DAG_STREAMS_API
+ /* Open requested stream. Can fail if already locked or on error */
+ if (dag_attach_stream(handle->fd, handlep->dag_stream, 0, 0) < 0) {
+ pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_attach_stream: %s", pcap_strerror(errno));
+ goto failclose;
+ }
+
+ /* Set up default poll parameters for stream
+ * Can be overridden by pcap_set_nonblock()
+ */
+ if (dag_get_stream_poll(handle->fd, handlep->dag_stream,
+ &mindata, &maxwait, &poll) < 0) {
+ pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_get_stream_poll: %s", pcap_strerror(errno));
+ goto faildetach;
+ }
+
+ if (handle->opt.immediate) {
+ /* Call callback immediately.
+ * XXX - is this the right way to handle this?
+ */
+ mindata = 0;
+ } else {
+ /* Amount of data to collect in Bytes before calling callbacks.
+ * Important for efficiency, but can introduce latency
+ * at low packet rates if to_ms not set!
+ */
+ mindata = 65536;
+ }
+
+ /* Obey opt.timeout (was to_ms) if supplied. This is a good idea!
+ * Recommend 10-100ms. Calls will time out even if no data arrived.
+ */
+ maxwait.tv_sec = handle->opt.timeout/1000;
+ maxwait.tv_usec = (handle->opt.timeout%1000) * 1000;
+
+ if (dag_set_stream_poll(handle->fd, handlep->dag_stream,
+ mindata, &maxwait, &poll) < 0) {
+ pcap_snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_set_stream_poll: %s", pcap_strerror(errno));
+ goto faildetach;
+ }
+