filter fix
[platform/upstream/libpcap.git] / pcap-dag.c
index b5de069..aaa3fae 100644 (file)
  *                Stephen Donnelly <support@endace.com>
  */
 
-#ifndef lint
-static const char rcsid[] _U_ =
-       "@(#) $Header: /tcpdump/master/libpcap/pcap-dag.c,v 1.39 2008-04-14 20:40:58 guy Exp $ (LBL)";
-#endif
-
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
@@ -48,6 +43,15 @@ struct rtentry;              /* declarations in <net/if.h> */
 
 #include "pcap-dag.h"
 
+/*
+ * DAG devices have names beginning with "dag", followed by a number
+ * from 0 to DAG_MAX_BOARDS, then optionally a colon and a stream number
+ * from 0 to DAG_STREAM_MAX.
+ */
+#ifndef DAG_MAX_BOARDS
+#define DAG_MAX_BOARDS 32
+#endif
+
 #define ATM_CELL_SIZE          52
 #define ATM_HDR_SIZE           4
 
@@ -70,6 +74,27 @@ struct sunatm_hdr {
        unsigned short  vci;            /* VCI */
 };
 
+/*
+ * Private data for capturing on DAG devices.
+ */
+struct pcap_dag {
+       struct pcap_stat stat;
+#ifdef HAVE_DAG_STREAMS_API
+       u_char  *dag_mem_bottom;        /* DAG card current memory bottom pointer */
+       u_char  *dag_mem_top;   /* DAG card current memory top pointer */
+#else /* HAVE_DAG_STREAMS_API */
+       void    *dag_mem_base;  /* DAG card memory base address */
+       u_int   dag_mem_bottom; /* DAG card current memory bottom offset */
+       u_int   dag_mem_top;    /* DAG card current memory top offset */
+#endif /* HAVE_DAG_STREAMS_API */
+       int     dag_fcs_bits;   /* Number of checksum bits from link layer */
+       int     dag_offset_flags; /* Flags to pass to dag_offset(). */
+       int     dag_stream;     /* DAG stream number */
+       int     dag_timeout;    /* timeout specified to pcap_open_live.
+                                * Same as in linux above, introduce
+                                * generally? */
+};
+
 typedef struct pcap_dag_node {
        struct pcap_dag_node *next;
        pcap_t *p;
@@ -82,15 +107,6 @@ static const unsigned short endian_test_word = 0x0100;
 
 #define IS_BIGENDIAN() (*((unsigned char *)&endian_test_word))
 
-
-#ifdef DAG_ONLY
-/* This code is required when compiling for a DAG device only. */
-
-/* Replace dag function names with pcap equivalent. */
-#define dag_create pcap_create
-#define dag_platform_finddevs pcap_platform_finddevs
-#endif /* DAG_ONLY */
-
 #define MAX_DAG_PACKET 65536
 
 static unsigned char TempPkt[MAX_DAG_PACKET];
@@ -127,13 +143,15 @@ delete_pcap_dag(pcap_t *p)
 static void
 dag_platform_cleanup(pcap_t *p)
 {
-       
+       struct pcap_dag *pd;
+
        if (p != NULL) {
+               pd = p->priv;
 #ifdef HAVE_DAG_STREAMS_API
-               if(dag_stop_stream(p->fd, p->md.dag_stream) < 0)
+               if(dag_stop_stream(p->fd, pd->dag_stream) < 0)
                        fprintf(stderr,"dag_stop_stream: %s\n", strerror(errno));
                
-               if(dag_detach_stream(p->fd, p->md.dag_stream) < 0)
+               if(dag_detach_stream(p->fd, pd->dag_stream) < 0)
                        fprintf(stderr,"dag_detach_stream: %s\n", strerror(errno));
 #else
                if(dag_stop(p->fd) < 0)
@@ -205,7 +223,7 @@ dag_erf_ext_header_count(uint8_t * erf, size_t len)
        do {
        
                /* sanity check we have enough bytes */
-               if ( len <= (24 + (hdr_num * 8)) )
+               if ( len < (24 + (hdr_num * 8)) )
                        return hdr_num;
 
                /* get the header type */
@@ -225,13 +243,14 @@ dag_erf_ext_header_count(uint8_t * erf, size_t len)
 static int
 dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
 {
+       struct pcap_dag *pd = p->priv;
        unsigned int processed = 0;
-       int flags = p->md.dag_offset_flags;
+       int flags = pd->dag_offset_flags;
        unsigned int nonblocking = flags & DAGF_NONBLOCK;
        unsigned int num_ext_hdr = 0;
 
        /* Get the next bufferful of packets (if necessary). */
-       while (p->md.dag_mem_top - p->md.dag_mem_bottom < dag_record_size) {
+       while (pd->dag_mem_top - pd->dag_mem_bottom < dag_record_size) {
  
                /*
                 * Has "pcap_breakloop()" been called?
@@ -258,23 +277,23 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
                 * If non-block is specified it will return immediately. The user
                 * is then responsible for efficiency.
                 */
-               if ( NULL == (p->md.dag_mem_top = dag_advance_stream(p->fd, p->md.dag_stream, &(p->md.dag_mem_bottom))) ) {
+               if ( NULL == (pd->dag_mem_top = dag_advance_stream(p->fd, pd->dag_stream, &(pd->dag_mem_bottom))) ) {
                     return -1;
                }
 #else
                /* dag_offset does not support timeouts */
-               p->md.dag_mem_top = dag_offset(p->fd, &(p->md.dag_mem_bottom), flags);
+               pd->dag_mem_top = dag_offset(p->fd, &(pd->dag_mem_bottom), flags);
 #endif /* HAVE_DAG_STREAMS_API */
 
-               if (nonblocking && (p->md.dag_mem_top - p->md.dag_mem_bottom < dag_record_size))
+               if (nonblocking && (pd->dag_mem_top - pd->dag_mem_bottom < dag_record_size))
                {
                        /* Pcap is configured to process only available packets, and there aren't any, return immediately. */
                        return 0;
                }
                
                if(!nonblocking &&
-                  p->md.dag_timeout &&
-                  (p->md.dag_mem_top - p->md.dag_mem_bottom < dag_record_size))
+                  pd->dag_timeout &&
+                  (pd->dag_mem_top - pd->dag_mem_bottom < dag_record_size))
                {
                        /* Blocking mode, but timeout set and no data has arrived, return anyway.*/
                        return 0;
@@ -283,16 +302,16 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
        }
        
        /* Process the packets. */
-       while (p->md.dag_mem_top - p->md.dag_mem_bottom >= dag_record_size) {
+       while (pd->dag_mem_top - pd->dag_mem_bottom >= dag_record_size) {
                
                unsigned short packet_len = 0;
                int caplen = 0;
                struct pcap_pkthdr      pcap_header;
                
 #ifdef HAVE_DAG_STREAMS_API
-               dag_record_t *header = (dag_record_t *)(p->md.dag_mem_bottom);
+               dag_record_t *header = (dag_record_t *)(pd->dag_mem_bottom);
 #else
-               dag_record_t *header = (dag_record_t *)(p->md.dag_mem_base + p->md.dag_mem_bottom);
+               dag_record_t *header = (dag_record_t *)(pd->dag_mem_base + pd->dag_mem_bottom);
 #endif /* HAVE_DAG_STREAMS_API */
 
                u_char *dp = ((u_char *)header); /* + dag_record_size; */
@@ -317,7 +336,7 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
                        strncpy(p->errbuf, "dag_read: record too small", PCAP_ERRBUF_SIZE);
                        return -1;
                }
-               p->md.dag_mem_bottom += rlen;
+               pd->dag_mem_bottom += rlen;
 
                /* Count lost packets. */
                switch((header->type & 0x7f)) {
@@ -333,10 +352,10 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
 
                default:
                        if (header->lctr) {
-                               if (p->md.stat.ps_drop > (UINT_MAX - ntohs(header->lctr))) {
-                                       p->md.stat.ps_drop = UINT_MAX;
+                               if (pd->stat.ps_drop > (UINT_MAX - ntohs(header->lctr))) {
+                                       pd->stat.ps_drop = UINT_MAX;
                                } else {
-                                       p->md.stat.ps_drop += ntohs(header->lctr);
+                                       pd->stat.ps_drop += ntohs(header->lctr);
                                }
                        }
                }
@@ -444,7 +463,7 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
                        case TYPE_COLOR_ETH:
                        case TYPE_ETH:
                                packet_len = ntohs(header->wlen);
-                               packet_len -= (p->md.dag_fcs_bits >> 3);
+                               packet_len -= (pd->dag_fcs_bits >> 3);
                                caplen = rlen - dag_record_size - 2;
                                if (caplen > packet_len) {
                                        caplen = packet_len;
@@ -457,7 +476,7 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
                        case TYPE_COLOR_HDLC_POS:
                        case TYPE_HDLC_POS:
                                packet_len = ntohs(header->wlen);
-                               packet_len -= (p->md.dag_fcs_bits >> 3);
+                               packet_len -= (pd->dag_fcs_bits >> 3);
                                caplen = rlen - dag_record_size;
                                if (caplen > packet_len) {
                                        caplen = packet_len;
@@ -467,7 +486,7 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
                        case TYPE_COLOR_MC_HDLC_POS:
                        case TYPE_MC_HDLC:
                                packet_len = ntohs(header->wlen);
-                               packet_len -= (p->md.dag_fcs_bits >> 3);
+                               packet_len -= (pd->dag_fcs_bits >> 3);
                                caplen = rlen - dag_record_size - 4;
                                if (caplen > packet_len) {
                                        caplen = packet_len;
@@ -548,14 +567,14 @@ dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
                        pcap_header.len = packet_len;
        
                        /* Count the packet. */
-                       p->md.stat.ps_recv++;
+                       pd->stat.ps_recv++;
        
                        /* Call the user supplied callback function */
                        callback(user, &pcap_header, dp);
        
                        /* Only count packets that pass the filter, for consistency with standard Linux behaviour. */
                        processed++;
-                       if (processed == cnt && cnt > 0)
+                       if (processed == cnt && !PACKET_COUNT_IS_UNLIMITED(cnt))
                        {
                                /* Reached the user-specified limit. */
                                return cnt;
@@ -587,6 +606,7 @@ dag_inject(pcap_t *p, const void *buf _U_, size_t size _U_)
  */
 static int dag_activate(pcap_t* handle)
 {
+       struct pcap_dag *handlep = handle->priv;
 #if 0
        char conf[30]; /* dag configure string */
 #endif
@@ -616,13 +636,13 @@ static int dag_activate(pcap_t* handle)
        }
        
        /* Parse input name to get dag device and stream number if provided */
-       if (dag_parse_name(device, newDev, strlen(device) + 16, &handle->md.dag_stream) < 0) {
+       if (dag_parse_name(device, newDev, strlen(device) + 16, &handlep->dag_stream) < 0) {
                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_parse_name: %s\n", pcap_strerror(errno));
                goto fail;
        }
        device = newDev;
 
-       if (handle->md.dag_stream%2) {
+       if (handlep->dag_stream%2) {
                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_parse_name: tx (even numbered) streams not supported for capture\n");
                goto fail;
        }
@@ -647,7 +667,7 @@ static int dag_activate(pcap_t* handle)
 
 #ifdef HAVE_DAG_STREAMS_API
        /* Open requested stream. Can fail if already locked or on error */
-       if (dag_attach_stream(handle->fd, handle->md.dag_stream, 0, 0) < 0) {
+       if (dag_attach_stream(handle->fd, handlep->dag_stream, 0, 0) < 0) {
                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_attach_stream: %s\n", pcap_strerror(errno));
                goto failclose;
        }
@@ -655,32 +675,39 @@ static int dag_activate(pcap_t* handle)
        /* Set up default poll parameters for stream
         * Can be overridden by pcap_set_nonblock()
         */
-       if (dag_get_stream_poll(handle->fd, handle->md.dag_stream,
+       if (dag_get_stream_poll(handle->fd, handlep->dag_stream,
                                &mindata, &maxwait, &poll) < 0) {
                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_get_stream_poll: %s\n", pcap_strerror(errno));
                goto faildetach;
        }
        
-       /* 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;
+       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 md.timeout (was to_ms) if supplied. This is a good idea!
+       /* 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->md.timeout/1000;
-       maxwait.tv_usec = (handle->md.timeout%1000) * 1000;
+       maxwait.tv_sec = handle->opt.timeout/1000;
+       maxwait.tv_usec = (handle->opt.timeout%1000) * 1000;
 
-       if (dag_set_stream_poll(handle->fd, handle->md.dag_stream,
+       if (dag_set_stream_poll(handle->fd, handlep->dag_stream,
                                mindata, &maxwait, &poll) < 0) {
                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_set_stream_poll: %s\n", pcap_strerror(errno));
                goto faildetach;
        }
                
 #else
-       if((handle->md.dag_mem_base = dag_mmap(handle->fd)) == MAP_FAILED) {
+       if((handlep->dag_mem_base = dag_mmap(handle->fd)) == MAP_FAILED) {
                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,"dag_mmap %s: %s\n", device, pcap_strerror(errno));
                goto failclose;
        }
@@ -710,7 +737,7 @@ static int dag_activate(pcap_t* handle)
 #endif 
        
 #ifdef HAVE_DAG_STREAMS_API
-       if(dag_start_stream(handle->fd, handle->md.dag_stream) < 0) {
+       if(dag_start_stream(handle->fd, handlep->dag_stream) < 0) {
                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_start_stream %s: %s\n", device, pcap_strerror(errno));
                goto faildetach;
        }
@@ -726,8 +753,8 @@ static int dag_activate(pcap_t* handle)
         * 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;
+       handlep->dag_mem_bottom = 0;
+       handlep->dag_mem_top = 0;
 
        /*
         * Find out how many FCS bits we should strip.
@@ -736,7 +763,7 @@ static int dag_activate(pcap_t* handle)
        daginf = dag_info(handle->fd);
        if ((0x4200 == daginf->device_code) || (0x4230 == daginf->device_code)) {
                /* DAG 4.2S and 4.23S already strip the FCS.  Stripping the final word again truncates the packet. */
-               handle->md.dag_fcs_bits = 0;
+               handlep->dag_fcs_bits = 0;
 
                /* Note that no FCS will be supplied. */
                handle->linktype_ext = LT_FCS_DATALINK_EXT(0);
@@ -744,12 +771,12 @@ static int dag_activate(pcap_t* handle)
                /*
                 * Start out assuming it's 32 bits.
                 */
-               handle->md.dag_fcs_bits = 32;
+               handlep->dag_fcs_bits = 32;
 
                /* Allow an environment variable to override. */
                if ((s = getenv("ERF_FCS_BITS")) != NULL) {
                        if ((n = atoi(s)) == 0 || n == 16 || n == 32) {
-                               handle->md.dag_fcs_bits = n;
+                               handlep->dag_fcs_bits = n;
                        } else {
                                snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
                                        "pcap_activate %s: bad ERF_FCS_BITS value (%d) in environment\n", device, n);
@@ -763,14 +790,14 @@ static int dag_activate(pcap_t* handle)
                if ((s = getenv("ERF_DONT_STRIP_FCS")) != NULL) {
                        /* Yes.  Note the number of bytes that will be
                           supplied. */
-                       handle->linktype_ext = LT_FCS_DATALINK_EXT(handle->md.dag_fcs_bits/16);
+                       handle->linktype_ext = LT_FCS_DATALINK_EXT(handlep->dag_fcs_bits/16);
 
                        /* And don't strip them. */
-                       handle->md.dag_fcs_bits = 0;
+                       handlep->dag_fcs_bits = 0;
                }
        }
 
-       handle->md.dag_timeout  = handle->md.timeout;
+       handlep->dag_timeout    = handle->opt.timeout;
 
        handle->linktype = -1;
        if (dag_get_datalink(handle) < 0)
@@ -801,19 +828,19 @@ static int dag_activate(pcap_t* handle)
        handle->setnonblock_op = dag_setnonblock;
        handle->stats_op = dag_stats;
        handle->cleanup_op = dag_platform_cleanup;
-       handle->md.stat.ps_drop = 0;
-       handle->md.stat.ps_recv = 0;
-       handle->md.stat.ps_ifdrop = 0;
+       handlep->stat.ps_drop = 0;
+       handlep->stat.ps_recv = 0;
+       handlep->stat.ps_ifdrop = 0;
        return 0;
 
 #ifdef HAVE_DAG_STREAMS_API 
 failstop:
-       if (dag_stop_stream(handle->fd, handle->md.dag_stream) < 0) {
+       if (dag_stop_stream(handle->fd, handlep->dag_stream) < 0) {
                fprintf(stderr,"dag_stop_stream: %s\n", strerror(errno));
        }
        
 faildetach:
-       if (dag_detach_stream(handle->fd, handle->md.dag_stream) < 0)
+       if (dag_detach_stream(handle->fd, handlep->dag_stream) < 0)
                fprintf(stderr,"dag_detach_stream: %s\n", strerror(errno));
 #else
 failstop:
@@ -835,11 +862,57 @@ fail:
        return PCAP_ERROR;
 }
 
-pcap_t *dag_create(const char *device, char *ebuf)
+pcap_t *dag_create(const char *device, char *ebuf, int *is_ours)
 {
+       const char *cp;
+       char *cpend;
+       long devnum;
        pcap_t *p;
+#ifdef HAVE_DAG_STREAMS_API
+       long stream = 0;
+#endif
+
+       /* Does this look like a DAG device? */
+       cp = strrchr(device, '/');
+       if (cp == NULL)
+               cp = device;
+       /* Does it begin with "dag"? */
+       if (strncmp(cp, "dag", 3) != 0) {
+               /* Nope, doesn't begin with "dag" */
+               *is_ours = 0;
+               return NULL;
+       }
+       /* Yes - is "dag" followed by a number from 0 to DAG_MAX_BOARDS-1 */
+       cp += 3;
+       devnum = strtol(cp, &cpend, 10);
+#ifdef HAVE_DAG_STREAMS_API
+       if (*cpend == ':') {
+               /* Followed by a stream number. */
+               stream = strtol(++cpend, &cpend, 10);
+       }
+#endif
+       if (cpend == cp || *cpend != '\0') {
+               /* Not followed by a number. */
+               *is_ours = 0;
+               return NULL;
+       }
+       if (devnum < 0 || devnum >= DAG_MAX_BOARDS) {
+               /* Followed by a non-valid number. */
+               *is_ours = 0;
+               return NULL;
+       }
+#ifdef HAVE_DAG_STREAMS_API
+       if (stream <0 || stream >= DAG_STREAM_MAX) {
+               /* Followed by a non-valid stream number. */
+               *is_ours = 0;
+               return NULL;
+       }
+#endif
+
+       /* OK, it's probably ours. */
+       *is_ours = 1;
 
-       p = pcap_create_common(device, ebuf);
+       p = pcap_create_common(device, ebuf, sizeof (struct pcap_dag));
        if (p == NULL)
                return NULL;
 
@@ -849,13 +922,15 @@ pcap_t *dag_create(const char *device, char *ebuf)
 
 static int
 dag_stats(pcap_t *p, struct pcap_stat *ps) {
+       struct pcap_dag *pd = p->priv;
+
        /* This needs to be filled out correctly.  Hopefully a dagapi call will
                 provide all necessary information.
        */
-       /*p->md.stat.ps_recv = 0;*/
-       /*p->md.stat.ps_drop = 0;*/
+       /*pd->stat.ps_recv = 0;*/
+       /*pd->stat.ps_drop = 0;*/
        
-       *ps = p->md.stat;
+       *ps = pd->stat;
  
        return 0;
 }
@@ -870,7 +945,7 @@ dag_stats(pcap_t *p, struct pcap_stat *ps) {
  * open attempts will still be much less than the naive approach.
  */
 int
-dag_platform_finddevs(pcap_if_t **devlistp, char *errbuf)
+dag_findalldevs(pcap_if_t **devlistp, char *errbuf)
 {
        char name[12];  /* XXX - pick a size */
        int ret = 0;
@@ -879,8 +954,8 @@ dag_platform_finddevs(pcap_if_t **devlistp, char *errbuf)
        int dagstream;
        int dagfd;
 
-       /* Try all the DAGs 0-31 */
-       for (c = 0; c < 32; c++) {
+       /* Try all the DAGs 0-DAG_MAX_BOARDS */
+       for (c = 0; c < DAG_MAX_BOARDS; c++) {
                snprintf(name, 12, "dag%d", c);
                if (-1 == dag_parse_name(name, dagname, DAGNAME_BUFSIZE, &dagstream))
                {
@@ -945,8 +1020,6 @@ dag_setfilter(pcap_t *p, struct bpf_program *fp)
        if (install_bpf_program(p, fp) < 0)
                return -1;
 
-       p->md.use_bpf = 0;
-
        return (0);
 }
 
@@ -961,11 +1034,13 @@ dag_set_datalink(pcap_t *p, int dlt)
 static int
 dag_setnonblock(pcap_t *p, int nonblock, char *errbuf)
 {
+       struct pcap_dag *pd = p->priv;
+
        /*
         * Set non-blocking mode on the FD.
         * XXX - is that necessary?  If not, don't bother calling it,
         * and have a "dag_getnonblock()" function that looks at
-        * "p->md.dag_offset_flags".
+        * "pd->dag_offset_flags".
         */
        if (pcap_setnonblock_fd(p, nonblock, errbuf) < 0)
                return (-1);
@@ -975,7 +1050,7 @@ dag_setnonblock(pcap_t *p, int nonblock, char *errbuf)
                struct timeval maxwait;
                struct timeval poll;
                
-               if (dag_get_stream_poll(p->fd, p->md.dag_stream,
+               if (dag_get_stream_poll(p->fd, pd->dag_stream,
                                        &mindata, &maxwait, &poll) < 0) {
                        snprintf(errbuf, PCAP_ERRBUF_SIZE, "dag_get_stream_poll: %s\n", pcap_strerror(errno));
                        return -1;
@@ -990,7 +1065,7 @@ dag_setnonblock(pcap_t *p, int nonblock, char *errbuf)
                else
                        mindata = 65536;
                
-               if (dag_set_stream_poll(p->fd, p->md.dag_stream,
+               if (dag_set_stream_poll(p->fd, pd->dag_stream,
                                        mindata, &maxwait, &poll) < 0) {
                        snprintf(errbuf, PCAP_ERRBUF_SIZE, "dag_set_stream_poll: %s\n", pcap_strerror(errno));
                        return -1;
@@ -998,9 +1073,9 @@ dag_setnonblock(pcap_t *p, int nonblock, char *errbuf)
        }
 #endif /* HAVE_DAG_STREAMS_API */
        if (nonblock) {
-               p->md.dag_offset_flags |= DAGF_NONBLOCK;
+               pd->dag_offset_flags |= DAGF_NONBLOCK;
        } else {
-               p->md.dag_offset_flags &= ~DAGF_NONBLOCK;
+               pd->dag_offset_flags &= ~DAGF_NONBLOCK;
        }
        return (0);
 }
@@ -1008,6 +1083,7 @@ dag_setnonblock(pcap_t *p, int nonblock, char *errbuf)
 static int
 dag_get_datalink(pcap_t *p)
 {
+       struct pcap_dag *pd = p->priv;
        int index=0, dlt_index=0;
        uint8_t types[255];
 
@@ -1022,7 +1098,7 @@ dag_get_datalink(pcap_t *p)
 
 #ifdef HAVE_DAG_GET_STREAM_ERF_TYPES
        /* Get list of possible ERF types for this card */
-       if (dag_get_stream_erf_types(p->fd, p->md.dag_stream, types, 255) < 0) {
+       if (dag_get_stream_erf_types(p->fd, pd->dag_stream, types, 255) < 0) {
                snprintf(p->errbuf, sizeof(p->errbuf), "dag_get_stream_erf_types: %s", pcap_strerror(errno));
                return (-1);            
        }