summaryrefslogtreecommitdiff
path: root/pcap-dag.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2013-05-06 14:16:14 -0700
committerGuy Harris <guy@alum.mit.edu>2013-05-06 14:16:14 -0700
commite9e96bbc3efd45ba6d1dbb097bc09845ba54c5d6 (patch)
tree88c0719044762ff35a1adedafcea69ab4dc005b5 /pcap-dag.c
parent5c18aa3e68e7d54712102e359efe4567fa81eca8 (diff)
downloadlibpcap-e9e96bbc3efd45ba6d1dbb097bc09845ba54c5d6.tar.gz
Move platform-dependent pcap_t data out of the pcap_t structure.
Put the private data right after the pcap_t structure, with a pointer to it in the pcap_t. The initial goal is to allow new pcap modules to be added without having to hack pcap-int.h. In the longer term, we may want to freeze the pcap_t structure, except possibly for adding new method pointers at the end, and provide an ABI for adding modules. We also put the stuff used by the read path at the beginning of the pcap_t structure, to try to keep it on the same set of cache lines.
Diffstat (limited to 'pcap-dag.c')
-rw-r--r--pcap-dag.c140
1 files changed, 84 insertions, 56 deletions
diff --git a/pcap-dag.c b/pcap-dag.c
index 847a556f..d006aa61 100644
--- a/pcap-dag.c
+++ b/pcap-dag.c
@@ -76,6 +76,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;
@@ -124,13 +145,15 @@ delete_pcap_dag(pcap_t *p)
static void
dag_platform_cleanup(pcap_t *p)
{
-
+ struct pcap_dag *pd;
+
if (p != NULL) {
+ pd = p->private;
#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)
@@ -222,13 +245,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->private;
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?
@@ -255,23 +279,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;
@@ -280,16 +304,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; */
@@ -314,7 +338,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)) {
@@ -330,10 +354,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);
}
}
}
@@ -441,7 +465,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;
@@ -454,7 +478,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;
@@ -464,7 +488,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;
@@ -545,7 +569,7 @@ 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);
@@ -584,6 +608,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->private;
#if 0
char conf[30]; /* dag configure string */
#endif
@@ -613,13 +638,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;
}
@@ -644,7 +669,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;
}
@@ -652,7 +677,7 @@ 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;
@@ -664,20 +689,20 @@ static int dag_activate(pcap_t* handle)
*/
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;
}
@@ -707,7 +732,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;
}
@@ -723,8 +748,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.
@@ -733,7 +758,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);
@@ -741,12 +766,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);
@@ -760,14 +785,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)
@@ -798,19 +823,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:
@@ -866,7 +891,7 @@ pcap_t *dag_create(const char *device, char *ebuf, int *is_ours)
/* 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;
@@ -876,13 +901,15 @@ pcap_t *dag_create(const char *device, char *ebuf, int *is_ours)
static int
dag_stats(pcap_t *p, struct pcap_stat *ps) {
+ struct pcap_dag *pd = p->private;
+
/* 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;
}
@@ -972,8 +999,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);
}
@@ -988,11 +1013,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->private;
+
/*
* 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);
@@ -1002,7 +1029,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;
@@ -1017,7 +1044,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;
@@ -1025,9 +1052,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);
}
@@ -1035,6 +1062,7 @@ dag_setnonblock(pcap_t *p, int nonblock, char *errbuf)
static int
dag_get_datalink(pcap_t *p)
{
+ struct pcap_dag *pd = p->private;
int index=0, dlt_index=0;
uint8_t types[255];
@@ -1049,7 +1077,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);
}