2004-03-31 09:07:39 +00:00
|
|
|
/*
|
2017-02-12 07:04:44 +00:00
|
|
|
* pcap-dag.c: Packet capture interface for Emulex EndaceDAG cards.
|
2004-03-31 09:07:39 +00:00
|
|
|
*
|
|
|
|
* The functionality of this code attempts to mimic that of pcap-linux as much
|
|
|
|
* as possible. This code is compiled in several different ways depending on
|
|
|
|
* whether DAG_ONLY and HAVE_DAG_API are defined. If HAVE_DAG_API is not
|
|
|
|
* defined it should not get compiled in, otherwise if DAG_ONLY is defined then
|
|
|
|
* the 'dag_' function calls are renamed to 'pcap_' equivalents. If DAG_ONLY
|
|
|
|
* is not defined then nothing is altered - the dag_ functions will be
|
|
|
|
* called as required from their pcap-linux/bpf equivalents.
|
|
|
|
*
|
2005-05-29 17:46:52 +00:00
|
|
|
* Authors: Richard Littin, Sean Irvine ({richard,sean}@reeltwo.com)
|
2017-02-12 07:04:44 +00:00
|
|
|
* Modifications: Jesper Peterson
|
|
|
|
* Koryn Grant
|
|
|
|
* Stephen Donnelly <stephen.donnelly@emulex.com>
|
2004-03-31 09:07:39 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
2018-05-18 12:21:19 +00:00
|
|
|
#include <config.h>
|
2004-03-31 09:07:39 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <sys/param.h> /* optionally get BSD define */
|
|
|
|
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <errno.h>
|
|
|
|
|
|
|
|
#include "pcap-int.h"
|
|
|
|
|
|
|
|
#include <ctype.h>
|
|
|
|
#include <netinet/in.h>
|
|
|
|
#include <sys/mman.h>
|
|
|
|
#include <sys/socket.h>
|
|
|
|
#include <sys/types.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
|
|
|
|
struct mbuf; /* Squelch compiler warnings on some platforms for */
|
|
|
|
struct rtentry; /* declarations in <net/if.h> */
|
|
|
|
#include <net/if.h>
|
|
|
|
|
2005-05-29 17:46:52 +00:00
|
|
|
#include "dagnew.h"
|
|
|
|
#include "dagapi.h"
|
2017-02-12 07:04:44 +00:00
|
|
|
#include "dagpci.h"
|
2018-05-18 12:21:19 +00:00
|
|
|
#include "dag_config_api.h"
|
2004-03-31 09:07:39 +00:00
|
|
|
|
2009-03-21 20:43:56 +00:00
|
|
|
#include "pcap-dag.h"
|
|
|
|
|
2013-05-30 06:41:26 +00:00
|
|
|
/*
|
|
|
|
* DAG devices have names beginning with "dag", followed by a number
|
2015-01-06 18:58:31 +00:00
|
|
|
* from 0 to DAG_MAX_BOARDS, then optionally a colon and a stream number
|
|
|
|
* from 0 to DAG_STREAM_MAX.
|
2013-05-30 06:41:26 +00:00
|
|
|
*/
|
2015-01-06 18:58:31 +00:00
|
|
|
#ifndef DAG_MAX_BOARDS
|
|
|
|
#define DAG_MAX_BOARDS 32
|
|
|
|
#endif
|
2013-05-30 06:41:26 +00:00
|
|
|
|
2017-02-12 07:04:44 +00:00
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
#ifndef ERF_TYPE_AAL5
|
|
|
|
#define ERF_TYPE_AAL5 4
|
2017-02-12 07:04:44 +00:00
|
|
|
#endif
|
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
#ifndef ERF_TYPE_MC_HDLC
|
|
|
|
#define ERF_TYPE_MC_HDLC 5
|
2017-02-12 07:04:44 +00:00
|
|
|
#endif
|
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
#ifndef ERF_TYPE_MC_RAW
|
|
|
|
#define ERF_TYPE_MC_RAW 6
|
2017-02-12 07:04:44 +00:00
|
|
|
#endif
|
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
#ifndef ERF_TYPE_MC_ATM
|
|
|
|
#define ERF_TYPE_MC_ATM 7
|
2017-02-12 07:04:44 +00:00
|
|
|
#endif
|
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
#ifndef ERF_TYPE_MC_RAW_CHANNEL
|
|
|
|
#define ERF_TYPE_MC_RAW_CHANNEL 8
|
2017-02-12 07:04:44 +00:00
|
|
|
#endif
|
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
#ifndef ERF_TYPE_MC_AAL5
|
|
|
|
#define ERF_TYPE_MC_AAL5 9
|
2017-02-12 07:04:44 +00:00
|
|
|
#endif
|
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
#ifndef ERF_TYPE_COLOR_HDLC_POS
|
|
|
|
#define ERF_TYPE_COLOR_HDLC_POS 10
|
2017-02-12 07:04:44 +00:00
|
|
|
#endif
|
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
#ifndef ERF_TYPE_COLOR_ETH
|
|
|
|
#define ERF_TYPE_COLOR_ETH 11
|
2017-02-12 07:04:44 +00:00
|
|
|
#endif
|
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
#ifndef ERF_TYPE_MC_AAL2
|
|
|
|
#define ERF_TYPE_MC_AAL2 12
|
2017-02-12 07:04:44 +00:00
|
|
|
#endif
|
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
#ifndef ERF_TYPE_IP_COUNTER
|
|
|
|
#define ERF_TYPE_IP_COUNTER 13
|
2017-02-12 07:04:44 +00:00
|
|
|
#endif
|
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
#ifndef ERF_TYPE_TCP_FLOW_COUNTER
|
|
|
|
#define ERF_TYPE_TCP_FLOW_COUNTER 14
|
2017-02-12 07:04:44 +00:00
|
|
|
#endif
|
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
#ifndef ERF_TYPE_DSM_COLOR_HDLC_POS
|
|
|
|
#define ERF_TYPE_DSM_COLOR_HDLC_POS 15
|
2017-02-12 07:04:44 +00:00
|
|
|
#endif
|
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
#ifndef ERF_TYPE_DSM_COLOR_ETH
|
|
|
|
#define ERF_TYPE_DSM_COLOR_ETH 16
|
2017-02-12 07:04:44 +00:00
|
|
|
#endif
|
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
#ifndef ERF_TYPE_COLOR_MC_HDLC_POS
|
|
|
|
#define ERF_TYPE_COLOR_MC_HDLC_POS 17
|
2017-02-12 07:04:44 +00:00
|
|
|
#endif
|
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
#ifndef ERF_TYPE_AAL2
|
|
|
|
#define ERF_TYPE_AAL2 18
|
2017-02-12 07:04:44 +00:00
|
|
|
#endif
|
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
#ifndef ERF_TYPE_COLOR_HASH_POS
|
|
|
|
#define ERF_TYPE_COLOR_HASH_POS 19
|
2017-02-12 07:04:44 +00:00
|
|
|
#endif
|
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
#ifndef ERF_TYPE_COLOR_HASH_ETH
|
|
|
|
#define ERF_TYPE_COLOR_HASH_ETH 20
|
2017-02-12 07:04:44 +00:00
|
|
|
#endif
|
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
#ifndef ERF_TYPE_INFINIBAND
|
|
|
|
#define ERF_TYPE_INFINIBAND 21
|
2017-02-12 07:04:44 +00:00
|
|
|
#endif
|
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
#ifndef ERF_TYPE_IPV4
|
|
|
|
#define ERF_TYPE_IPV4 22
|
2017-02-12 07:04:44 +00:00
|
|
|
#endif
|
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
#ifndef ERF_TYPE_IPV6
|
|
|
|
#define ERF_TYPE_IPV6 23
|
2017-02-12 07:04:44 +00:00
|
|
|
#endif
|
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
#ifndef ERF_TYPE_RAW_LINK
|
|
|
|
#define ERF_TYPE_RAW_LINK 24
|
2017-02-12 07:04:44 +00:00
|
|
|
#endif
|
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
#ifndef ERF_TYPE_INFINIBAND_LINK
|
|
|
|
#define ERF_TYPE_INFINIBAND_LINK 25
|
2017-02-12 07:04:44 +00:00
|
|
|
#endif
|
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
#ifndef ERF_TYPE_META
|
|
|
|
#define ERF_TYPE_META 27
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifndef ERF_TYPE_PAD
|
|
|
|
#define ERF_TYPE_PAD 48
|
2017-02-12 07:04:44 +00:00
|
|
|
#endif
|
|
|
|
|
2005-05-29 17:46:52 +00:00
|
|
|
#define ATM_CELL_SIZE 52
|
|
|
|
#define ATM_HDR_SIZE 4
|
|
|
|
|
2007-10-16 02:02:02 +00:00
|
|
|
/*
|
|
|
|
* A header containing additional MTP information.
|
|
|
|
*/
|
|
|
|
#define MTP2_SENT_OFFSET 0 /* 1 byte */
|
|
|
|
#define MTP2_ANNEX_A_USED_OFFSET 1 /* 1 byte */
|
|
|
|
#define MTP2_LINK_NUMBER_OFFSET 2 /* 2 bytes */
|
|
|
|
#define MTP2_HDR_LEN 4 /* length of the header */
|
|
|
|
|
|
|
|
#define MTP2_ANNEX_A_NOT_USED 0
|
|
|
|
#define MTP2_ANNEX_A_USED 1
|
|
|
|
#define MTP2_ANNEX_A_USED_UNKNOWN 2
|
|
|
|
|
2005-05-29 17:46:52 +00:00
|
|
|
/* SunATM pseudo header */
|
|
|
|
struct sunatm_hdr {
|
|
|
|
unsigned char flags; /* destination and traffic type */
|
|
|
|
unsigned char vpi; /* VPI */
|
|
|
|
unsigned short vci; /* VCI */
|
|
|
|
};
|
2004-03-31 09:07:39 +00:00
|
|
|
|
2015-01-06 18:58:31 +00:00
|
|
|
/*
|
|
|
|
* Private data for capturing on DAG devices.
|
|
|
|
*/
|
|
|
|
struct pcap_dag {
|
|
|
|
struct pcap_stat stat;
|
|
|
|
u_char *dag_mem_bottom; /* DAG card current memory bottom pointer */
|
|
|
|
u_char *dag_mem_top; /* DAG card current memory top pointer */
|
|
|
|
int dag_fcs_bits; /* Number of checksum bits from link layer */
|
2018-05-18 12:21:19 +00:00
|
|
|
int dag_flags; /* Flags */
|
2015-01-06 18:58:31 +00:00
|
|
|
int dag_stream; /* DAG stream number */
|
|
|
|
int dag_timeout; /* timeout specified to pcap_open_live.
|
|
|
|
* Same as in linux above, introduce
|
|
|
|
* generally? */
|
2018-05-18 12:21:19 +00:00
|
|
|
dag_card_ref_t dag_ref; /* DAG Configuration/Status API card reference */
|
|
|
|
dag_component_t dag_root; /* DAG CSAPI Root component */
|
|
|
|
attr_uuid_t drop_attr; /* DAG Stream Drop Attribute handle, if available */
|
|
|
|
struct timeval required_select_timeout;
|
|
|
|
/* Timeout caller must use in event loops */
|
2015-01-06 18:58:31 +00:00
|
|
|
};
|
|
|
|
|
2004-03-31 09:07:39 +00:00
|
|
|
typedef struct pcap_dag_node {
|
2005-05-29 17:46:52 +00:00
|
|
|
struct pcap_dag_node *next;
|
|
|
|
pcap_t *p;
|
|
|
|
pid_t pid;
|
2004-03-31 09:07:39 +00:00
|
|
|
} pcap_dag_node_t;
|
|
|
|
|
|
|
|
static pcap_dag_node_t *pcap_dags = NULL;
|
|
|
|
static int atexit_handler_installed = 0;
|
|
|
|
static const unsigned short endian_test_word = 0x0100;
|
|
|
|
|
|
|
|
#define IS_BIGENDIAN() (*((unsigned char *)&endian_test_word))
|
|
|
|
|
2007-10-16 02:02:02 +00:00
|
|
|
#define MAX_DAG_PACKET 65536
|
|
|
|
|
|
|
|
static unsigned char TempPkt[MAX_DAG_PACKET];
|
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
#ifndef HAVE_DAG_LARGE_STREAMS_API
|
|
|
|
#define dag_attach_stream64(a, b, c, d) dag_attach_stream(a, b, c, d)
|
|
|
|
#define dag_get_stream_poll64(a, b, c, d, e) dag_get_stream_poll(a, b, c, d, e)
|
|
|
|
#define dag_set_stream_poll64(a, b, c, d, e) dag_set_stream_poll(a, b, c, d, e)
|
|
|
|
#define dag_size_t uint32_t
|
|
|
|
#endif
|
|
|
|
|
2004-03-31 09:07:39 +00:00
|
|
|
static int dag_setfilter(pcap_t *p, struct bpf_program *fp);
|
|
|
|
static int dag_stats(pcap_t *p, struct pcap_stat *ps);
|
|
|
|
static int dag_set_datalink(pcap_t *p, int dlt);
|
|
|
|
static int dag_get_datalink(pcap_t *p);
|
2018-05-18 12:21:19 +00:00
|
|
|
static int dag_setnonblock(pcap_t *p, int nonblock);
|
2004-03-31 09:07:39 +00:00
|
|
|
|
2005-05-29 17:46:52 +00:00
|
|
|
static void
|
|
|
|
delete_pcap_dag(pcap_t *p)
|
|
|
|
{
|
|
|
|
pcap_dag_node_t *curr = NULL, *prev = NULL;
|
|
|
|
|
|
|
|
for (prev = NULL, curr = pcap_dags; curr != NULL && curr->p != p; prev = curr, curr = curr->next) {
|
|
|
|
/* empty */
|
|
|
|
}
|
|
|
|
|
|
|
|
if (curr != NULL && curr->p == p) {
|
|
|
|
if (prev != NULL) {
|
|
|
|
prev->next = curr->next;
|
|
|
|
} else {
|
|
|
|
pcap_dags = curr->next;
|
|
|
|
}
|
|
|
|
}
|
2004-03-31 09:07:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Performs a graceful shutdown of the DAG card, frees dynamic memory held
|
|
|
|
* in the pcap_t structure, and closes the file descriptor for the DAG card.
|
|
|
|
*/
|
|
|
|
|
2005-05-29 17:46:52 +00:00
|
|
|
static void
|
2009-03-21 20:43:56 +00:00
|
|
|
dag_platform_cleanup(pcap_t *p)
|
2005-05-29 17:46:52 +00:00
|
|
|
{
|
2018-05-18 12:21:19 +00:00
|
|
|
struct pcap_dag *pd = p->priv;
|
2015-01-06 18:58:31 +00:00
|
|
|
|
2017-02-12 07:04:44 +00:00
|
|
|
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, pd->dag_stream) < 0)
|
|
|
|
fprintf(stderr,"dag_detach_stream: %s\n", strerror(errno));
|
2018-05-18 12:21:19 +00:00
|
|
|
|
|
|
|
if(pd->dag_ref != NULL) {
|
|
|
|
dag_config_dispose(pd->dag_ref);
|
2017-02-12 07:04:44 +00:00
|
|
|
p->fd = -1;
|
2018-05-18 12:21:19 +00:00
|
|
|
pd->dag_ref = NULL;
|
2006-09-04 19:43:23 +00:00
|
|
|
}
|
2017-02-12 07:04:44 +00:00
|
|
|
delete_pcap_dag(p);
|
|
|
|
pcap_cleanup_live_common(p);
|
2018-05-18 12:21:19 +00:00
|
|
|
/* Note: don't need to call close(p->fd) or dag_close(p->fd) as dag_config_dispose(pd->dag_ref) does this. */
|
2004-03-31 09:07:39 +00:00
|
|
|
}
|
|
|
|
|
2005-05-29 17:46:52 +00:00
|
|
|
static void
|
|
|
|
atexit_handler(void)
|
|
|
|
{
|
|
|
|
while (pcap_dags != NULL) {
|
|
|
|
if (pcap_dags->pid == getpid()) {
|
2017-02-12 07:04:44 +00:00
|
|
|
if (pcap_dags->p != NULL)
|
|
|
|
dag_platform_cleanup(pcap_dags->p);
|
2005-05-29 17:46:52 +00:00
|
|
|
} else {
|
|
|
|
delete_pcap_dag(pcap_dags->p);
|
|
|
|
}
|
|
|
|
}
|
2004-03-31 09:07:39 +00:00
|
|
|
}
|
|
|
|
|
2005-05-29 17:46:52 +00:00
|
|
|
static int
|
|
|
|
new_pcap_dag(pcap_t *p)
|
|
|
|
{
|
|
|
|
pcap_dag_node_t *node = NULL;
|
2004-03-31 09:07:39 +00:00
|
|
|
|
2005-05-29 17:46:52 +00:00
|
|
|
if ((node = malloc(sizeof(pcap_dag_node_t))) == NULL) {
|
|
|
|
return -1;
|
|
|
|
}
|
2004-03-31 09:07:39 +00:00
|
|
|
|
2005-05-29 17:46:52 +00:00
|
|
|
if (!atexit_handler_installed) {
|
|
|
|
atexit(atexit_handler);
|
|
|
|
atexit_handler_installed = 1;
|
|
|
|
}
|
2004-03-31 09:07:39 +00:00
|
|
|
|
2005-05-29 17:46:52 +00:00
|
|
|
node->next = pcap_dags;
|
|
|
|
node->p = p;
|
|
|
|
node->pid = getpid();
|
2004-03-31 09:07:39 +00:00
|
|
|
|
2005-05-29 17:46:52 +00:00
|
|
|
pcap_dags = node;
|
2004-03-31 09:07:39 +00:00
|
|
|
|
2005-05-29 17:46:52 +00:00
|
|
|
return 0;
|
2004-03-31 09:07:39 +00:00
|
|
|
}
|
|
|
|
|
2009-03-21 20:43:56 +00:00
|
|
|
static unsigned int
|
|
|
|
dag_erf_ext_header_count(uint8_t * erf, size_t len)
|
|
|
|
{
|
|
|
|
uint32_t hdr_num = 0;
|
|
|
|
uint8_t hdr_type;
|
|
|
|
|
|
|
|
/* basic sanity checks */
|
|
|
|
if ( erf == NULL )
|
|
|
|
return 0;
|
|
|
|
if ( len < 16 )
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* check if we have any extension headers */
|
|
|
|
if ( (erf[8] & 0x80) == 0x00 )
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* loop over the extension headers */
|
|
|
|
do {
|
2017-02-12 07:04:44 +00:00
|
|
|
|
2009-03-21 20:43:56 +00:00
|
|
|
/* sanity check we have enough bytes */
|
2015-01-06 18:58:31 +00:00
|
|
|
if ( len < (24 + (hdr_num * 8)) )
|
2009-03-21 20:43:56 +00:00
|
|
|
return hdr_num;
|
|
|
|
|
|
|
|
/* get the header type */
|
|
|
|
hdr_type = erf[(16 + (hdr_num * 8))];
|
|
|
|
hdr_num++;
|
|
|
|
|
|
|
|
} while ( hdr_type & 0x80 );
|
|
|
|
|
|
|
|
return hdr_num;
|
|
|
|
}
|
|
|
|
|
2004-03-31 09:07:39 +00:00
|
|
|
/*
|
|
|
|
* Read at most max_packets from the capture stream and call the callback
|
|
|
|
* for each of them. Returns the number of packets handled, -1 if an
|
|
|
|
* error occured, or -2 if we were told to break out of the loop.
|
|
|
|
*/
|
2005-05-29 17:46:52 +00:00
|
|
|
static int
|
|
|
|
dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
|
|
|
|
{
|
2015-01-06 18:58:31 +00:00
|
|
|
struct pcap_dag *pd = p->priv;
|
2004-03-31 09:07:39 +00:00
|
|
|
unsigned int processed = 0;
|
2018-05-18 12:21:19 +00:00
|
|
|
unsigned int nonblocking = pd->dag_flags & DAGF_NONBLOCK;
|
2009-03-21 20:43:56 +00:00
|
|
|
unsigned int num_ext_hdr = 0;
|
2017-02-12 07:04:44 +00:00
|
|
|
unsigned int ticks_per_second;
|
2004-03-31 09:07:39 +00:00
|
|
|
|
2006-09-04 19:43:23 +00:00
|
|
|
/* Get the next bufferful of packets (if necessary). */
|
2015-01-06 18:58:31 +00:00
|
|
|
while (pd->dag_mem_top - pd->dag_mem_bottom < dag_record_size) {
|
2017-02-12 07:04:44 +00:00
|
|
|
|
2006-09-04 19:43:23 +00:00
|
|
|
/*
|
|
|
|
* Has "pcap_breakloop()" been called?
|
|
|
|
*/
|
|
|
|
if (p->break_loop) {
|
2004-03-31 09:07:39 +00:00
|
|
|
/*
|
2006-09-04 19:43:23 +00:00
|
|
|
* Yes - clear the flag that indicates that
|
|
|
|
* it has, and return -2 to indicate that
|
|
|
|
* we were told to break out of the loop.
|
2004-03-31 09:07:39 +00:00
|
|
|
*/
|
2006-09-04 19:43:23 +00:00
|
|
|
p->break_loop = 0;
|
|
|
|
return -2;
|
|
|
|
}
|
2004-03-31 09:07:39 +00:00
|
|
|
|
2006-09-04 19:43:23 +00:00
|
|
|
/* dag_advance_stream() will block (unless nonblock is called)
|
|
|
|
* until 64kB of data has accumulated.
|
|
|
|
* If to_ms is set, it will timeout before 64kB has accumulated.
|
|
|
|
* We wait for 64kB because processing a few packets at a time
|
|
|
|
* can cause problems at high packet rates (>200kpps) due
|
|
|
|
* to inefficiencies.
|
|
|
|
* This does mean if to_ms is not specified the capture may 'hang'
|
|
|
|
* for long periods if the data rate is extremely slow (<64kB/sec)
|
|
|
|
* If non-block is specified it will return immediately. The user
|
|
|
|
* is then responsible for efficiency.
|
|
|
|
*/
|
2015-01-06 18:58:31 +00:00
|
|
|
if ( NULL == (pd->dag_mem_top = dag_advance_stream(p->fd, pd->dag_stream, &(pd->dag_mem_bottom))) ) {
|
2009-03-21 20:43:56 +00:00
|
|
|
return -1;
|
|
|
|
}
|
2006-09-04 19:43:23 +00:00
|
|
|
|
2015-01-06 18:58:31 +00:00
|
|
|
if (nonblocking && (pd->dag_mem_top - pd->dag_mem_bottom < dag_record_size))
|
2006-09-04 19:43:23 +00:00
|
|
|
{
|
|
|
|
/* Pcap is configured to process only available packets, and there aren't any, return immediately. */
|
|
|
|
return 0;
|
|
|
|
}
|
2017-02-12 07:04:44 +00:00
|
|
|
|
2006-09-04 19:43:23 +00:00
|
|
|
if(!nonblocking &&
|
2015-01-06 18:58:31 +00:00
|
|
|
pd->dag_timeout &&
|
|
|
|
(pd->dag_mem_top - pd->dag_mem_bottom < dag_record_size))
|
2006-09-04 19:43:23 +00:00
|
|
|
{
|
|
|
|
/* Blocking mode, but timeout set and no data has arrived, return anyway.*/
|
|
|
|
return 0;
|
2004-03-31 09:07:39 +00:00
|
|
|
}
|
2006-09-04 19:43:23 +00:00
|
|
|
|
|
|
|
}
|
2017-02-12 07:04:44 +00:00
|
|
|
|
2006-09-04 19:43:23 +00:00
|
|
|
/* Process the packets. */
|
2015-01-06 18:58:31 +00:00
|
|
|
while (pd->dag_mem_top - pd->dag_mem_bottom >= dag_record_size) {
|
2017-02-12 07:04:44 +00:00
|
|
|
|
2006-09-04 19:43:23 +00:00
|
|
|
unsigned short packet_len = 0;
|
|
|
|
int caplen = 0;
|
|
|
|
struct pcap_pkthdr pcap_header;
|
2017-02-12 07:04:44 +00:00
|
|
|
|
2015-01-06 18:58:31 +00:00
|
|
|
dag_record_t *header = (dag_record_t *)(pd->dag_mem_bottom);
|
2004-03-31 09:07:39 +00:00
|
|
|
|
2009-03-21 20:43:56 +00:00
|
|
|
u_char *dp = ((u_char *)header); /* + dag_record_size; */
|
2006-09-04 19:43:23 +00:00
|
|
|
unsigned short rlen;
|
2017-02-12 07:04:44 +00:00
|
|
|
|
2006-09-04 19:43:23 +00:00
|
|
|
/*
|
|
|
|
* Has "pcap_breakloop()" been called?
|
|
|
|
*/
|
|
|
|
if (p->break_loop) {
|
2004-03-31 09:07:39 +00:00
|
|
|
/*
|
2006-09-04 19:43:23 +00:00
|
|
|
* Yes - clear the flag that indicates that
|
|
|
|
* it has, and return -2 to indicate that
|
|
|
|
* we were told to break out of the loop.
|
2004-03-31 09:07:39 +00:00
|
|
|
*/
|
2006-09-04 19:43:23 +00:00
|
|
|
p->break_loop = 0;
|
|
|
|
return -2;
|
|
|
|
}
|
2017-02-12 07:04:44 +00:00
|
|
|
|
2006-09-04 19:43:23 +00:00
|
|
|
rlen = ntohs(header->rlen);
|
|
|
|
if (rlen < dag_record_size)
|
|
|
|
{
|
|
|
|
strncpy(p->errbuf, "dag_read: record too small", PCAP_ERRBUF_SIZE);
|
|
|
|
return -1;
|
|
|
|
}
|
2015-01-06 18:58:31 +00:00
|
|
|
pd->dag_mem_bottom += rlen;
|
2006-09-04 19:43:23 +00:00
|
|
|
|
|
|
|
/* Count lost packets. */
|
2009-03-21 20:43:56 +00:00
|
|
|
switch((header->type & 0x7f)) {
|
|
|
|
/* in these types the color value overwrites the lctr */
|
2018-05-18 12:21:19 +00:00
|
|
|
case ERF_TYPE_COLOR_HDLC_POS:
|
|
|
|
case ERF_TYPE_COLOR_ETH:
|
|
|
|
case ERF_TYPE_DSM_COLOR_HDLC_POS:
|
|
|
|
case ERF_TYPE_DSM_COLOR_ETH:
|
|
|
|
case ERF_TYPE_COLOR_MC_HDLC_POS:
|
|
|
|
case ERF_TYPE_COLOR_HASH_ETH:
|
|
|
|
case ERF_TYPE_COLOR_HASH_POS:
|
2007-10-16 02:02:02 +00:00
|
|
|
break;
|
|
|
|
|
2006-09-04 19:43:23 +00:00
|
|
|
default:
|
2018-05-18 12:21:19 +00:00
|
|
|
if ( (pd->drop_attr == kNullAttributeUuid) && (header->lctr) ) {
|
|
|
|
pd->stat.ps_drop += ntohs(header->lctr);
|
2004-03-31 09:07:39 +00:00
|
|
|
}
|
2006-09-04 19:43:23 +00:00
|
|
|
}
|
2017-02-12 07:04:44 +00:00
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
if ((header->type & 0x7f) == ERF_TYPE_PAD) {
|
2009-03-21 20:43:56 +00:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
num_ext_hdr = dag_erf_ext_header_count(dp, rlen);
|
|
|
|
|
|
|
|
/* ERF encapsulation */
|
2017-02-12 07:04:44 +00:00
|
|
|
/* The Extensible Record Format is not dropped for this kind of encapsulation,
|
2009-03-21 20:43:56 +00:00
|
|
|
* and will be handled as a pseudo header by the decoding application.
|
|
|
|
* The information carried in the ERF header and in the optional subheader (if present)
|
|
|
|
* could be merged with the libpcap information, to offer a better decoding.
|
|
|
|
* The packet length is
|
|
|
|
* o the length of the packet on the link (header->wlen),
|
2017-02-12 07:04:44 +00:00
|
|
|
* o plus the length of the ERF header (dag_record_size), as the length of the
|
2009-03-21 20:43:56 +00:00
|
|
|
* pseudo header will be adjusted during the decoding,
|
|
|
|
* o plus the length of the optional subheader (if present).
|
|
|
|
*
|
|
|
|
* The capture length is header.rlen and the byte stuffing for alignment will be dropped
|
|
|
|
* if the capture length is greater than the packet length.
|
|
|
|
*/
|
|
|
|
if (p->linktype == DLT_ERF) {
|
|
|
|
packet_len = ntohs(header->wlen) + dag_record_size;
|
|
|
|
caplen = rlen;
|
|
|
|
switch ((header->type & 0x7f)) {
|
2018-05-18 12:21:19 +00:00
|
|
|
case ERF_TYPE_MC_AAL5:
|
|
|
|
case ERF_TYPE_MC_ATM:
|
|
|
|
case ERF_TYPE_MC_HDLC:
|
|
|
|
case ERF_TYPE_MC_RAW_CHANNEL:
|
|
|
|
case ERF_TYPE_MC_RAW:
|
|
|
|
case ERF_TYPE_MC_AAL2:
|
|
|
|
case ERF_TYPE_COLOR_MC_HDLC_POS:
|
2009-03-21 20:43:56 +00:00
|
|
|
packet_len += 4; /* MC header */
|
|
|
|
break;
|
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
case ERF_TYPE_COLOR_HASH_ETH:
|
|
|
|
case ERF_TYPE_DSM_COLOR_ETH:
|
|
|
|
case ERF_TYPE_COLOR_ETH:
|
|
|
|
case ERF_TYPE_ETH:
|
2009-03-21 20:43:56 +00:00
|
|
|
packet_len += 2; /* ETH header */
|
|
|
|
break;
|
|
|
|
} /* switch type */
|
|
|
|
|
|
|
|
/* Include ERF extension headers */
|
|
|
|
packet_len += (8 * num_ext_hdr);
|
|
|
|
|
|
|
|
if (caplen > packet_len) {
|
|
|
|
caplen = packet_len;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
/* Other kind of encapsulation according to the header Type */
|
|
|
|
|
|
|
|
/* Skip over generic ERF header */
|
|
|
|
dp += dag_record_size;
|
|
|
|
/* Skip over extension headers */
|
|
|
|
dp += 8 * num_ext_hdr;
|
2017-02-12 07:04:44 +00:00
|
|
|
|
2009-03-21 20:43:56 +00:00
|
|
|
switch((header->type & 0x7f)) {
|
2018-05-18 12:21:19 +00:00
|
|
|
case ERF_TYPE_ATM:
|
|
|
|
case ERF_TYPE_AAL5:
|
|
|
|
if ((header->type & 0x7f) == ERF_TYPE_AAL5) {
|
2009-03-21 20:43:56 +00:00
|
|
|
packet_len = ntohs(header->wlen);
|
|
|
|
caplen = rlen - dag_record_size;
|
|
|
|
}
|
2018-05-18 12:21:19 +00:00
|
|
|
case ERF_TYPE_MC_ATM:
|
|
|
|
if ((header->type & 0x7f) == ERF_TYPE_MC_ATM) {
|
2009-03-21 20:43:56 +00:00
|
|
|
caplen = packet_len = ATM_CELL_SIZE;
|
|
|
|
dp+=4;
|
|
|
|
}
|
2018-05-18 12:21:19 +00:00
|
|
|
case ERF_TYPE_MC_AAL5:
|
|
|
|
if ((header->type & 0x7f) == ERF_TYPE_MC_AAL5) {
|
2009-03-21 20:43:56 +00:00
|
|
|
packet_len = ntohs(header->wlen);
|
|
|
|
caplen = rlen - dag_record_size - 4;
|
|
|
|
dp+=4;
|
|
|
|
}
|
2017-02-12 07:04:44 +00:00
|
|
|
/* Skip over extension headers */
|
|
|
|
caplen -= (8 * num_ext_hdr);
|
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
if ((header->type & 0x7f) == ERF_TYPE_ATM) {
|
2009-03-21 20:43:56 +00:00
|
|
|
caplen = packet_len = ATM_CELL_SIZE;
|
|
|
|
}
|
|
|
|
if (p->linktype == DLT_SUNATM) {
|
|
|
|
struct sunatm_hdr *sunatm = (struct sunatm_hdr *)dp;
|
|
|
|
unsigned long rawatm;
|
2017-02-12 07:04:44 +00:00
|
|
|
|
2009-03-21 20:43:56 +00:00
|
|
|
rawatm = ntohl(*((unsigned long *)dp));
|
|
|
|
sunatm->vci = htons((rawatm >> 4) & 0xffff);
|
|
|
|
sunatm->vpi = (rawatm >> 20) & 0x00ff;
|
2017-02-12 07:04:44 +00:00
|
|
|
sunatm->flags = ((header->flags.iface & 1) ? 0x80 : 0x00) |
|
2009-03-21 20:43:56 +00:00
|
|
|
((sunatm->vpi == 0 && sunatm->vci == htons(5)) ? 6 :
|
2017-02-12 07:04:44 +00:00
|
|
|
((sunatm->vpi == 0 && sunatm->vci == htons(16)) ? 5 :
|
2009-03-21 20:43:56 +00:00
|
|
|
((dp[ATM_HDR_SIZE] == 0xaa &&
|
|
|
|
dp[ATM_HDR_SIZE+1] == 0xaa &&
|
|
|
|
dp[ATM_HDR_SIZE+2] == 0x03) ? 2 : 1)));
|
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
} else if (p->linktype == DLT_ATM_RFC1483) {
|
2009-03-21 20:43:56 +00:00
|
|
|
packet_len -= ATM_HDR_SIZE;
|
|
|
|
caplen -= ATM_HDR_SIZE;
|
|
|
|
dp += ATM_HDR_SIZE;
|
2018-05-18 12:21:19 +00:00
|
|
|
} else
|
|
|
|
continue;
|
2009-03-21 20:43:56 +00:00
|
|
|
break;
|
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
case ERF_TYPE_COLOR_HASH_ETH:
|
|
|
|
case ERF_TYPE_DSM_COLOR_ETH:
|
|
|
|
case ERF_TYPE_COLOR_ETH:
|
|
|
|
case ERF_TYPE_ETH:
|
|
|
|
if ((p->linktype != DLT_EN10MB) &&
|
|
|
|
(p->linktype != DLT_DOCSIS))
|
|
|
|
continue;
|
2009-03-21 20:43:56 +00:00
|
|
|
packet_len = ntohs(header->wlen);
|
2015-01-06 18:58:31 +00:00
|
|
|
packet_len -= (pd->dag_fcs_bits >> 3);
|
2009-03-21 20:43:56 +00:00
|
|
|
caplen = rlen - dag_record_size - 2;
|
2017-02-12 07:04:44 +00:00
|
|
|
/* Skip over extension headers */
|
|
|
|
caplen -= (8 * num_ext_hdr);
|
2009-03-21 20:43:56 +00:00
|
|
|
if (caplen > packet_len) {
|
|
|
|
caplen = packet_len;
|
|
|
|
}
|
|
|
|
dp += 2;
|
|
|
|
break;
|
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
case ERF_TYPE_COLOR_HASH_POS:
|
|
|
|
case ERF_TYPE_DSM_COLOR_HDLC_POS:
|
|
|
|
case ERF_TYPE_COLOR_HDLC_POS:
|
|
|
|
case ERF_TYPE_HDLC_POS:
|
|
|
|
if ((p->linktype != DLT_CHDLC) &&
|
|
|
|
(p->linktype != DLT_PPP_SERIAL) &&
|
|
|
|
(p->linktype != DLT_FRELAY))
|
|
|
|
continue;
|
2009-03-21 20:43:56 +00:00
|
|
|
packet_len = ntohs(header->wlen);
|
2015-01-06 18:58:31 +00:00
|
|
|
packet_len -= (pd->dag_fcs_bits >> 3);
|
2009-03-21 20:43:56 +00:00
|
|
|
caplen = rlen - dag_record_size;
|
2017-02-12 07:04:44 +00:00
|
|
|
/* Skip over extension headers */
|
|
|
|
caplen -= (8 * num_ext_hdr);
|
2009-03-21 20:43:56 +00:00
|
|
|
if (caplen > packet_len) {
|
|
|
|
caplen = packet_len;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
case ERF_TYPE_COLOR_MC_HDLC_POS:
|
|
|
|
case ERF_TYPE_MC_HDLC:
|
|
|
|
if ((p->linktype != DLT_CHDLC) &&
|
|
|
|
(p->linktype != DLT_PPP_SERIAL) &&
|
|
|
|
(p->linktype != DLT_FRELAY) &&
|
|
|
|
(p->linktype != DLT_MTP2) &&
|
|
|
|
(p->linktype != DLT_MTP2_WITH_PHDR) &&
|
|
|
|
(p->linktype != DLT_LAPD))
|
|
|
|
continue;
|
2009-03-21 20:43:56 +00:00
|
|
|
packet_len = ntohs(header->wlen);
|
2015-01-06 18:58:31 +00:00
|
|
|
packet_len -= (pd->dag_fcs_bits >> 3);
|
2009-03-21 20:43:56 +00:00
|
|
|
caplen = rlen - dag_record_size - 4;
|
2017-02-12 07:04:44 +00:00
|
|
|
/* Skip over extension headers */
|
|
|
|
caplen -= (8 * num_ext_hdr);
|
2009-03-21 20:43:56 +00:00
|
|
|
if (caplen > packet_len) {
|
|
|
|
caplen = packet_len;
|
|
|
|
}
|
|
|
|
/* jump the MC_HDLC_HEADER */
|
|
|
|
dp += 4;
|
|
|
|
#ifdef DLT_MTP2_WITH_PHDR
|
|
|
|
if (p->linktype == DLT_MTP2_WITH_PHDR) {
|
|
|
|
/* Add the MTP2 Pseudo Header */
|
|
|
|
caplen += MTP2_HDR_LEN;
|
|
|
|
packet_len += MTP2_HDR_LEN;
|
2017-02-12 07:04:44 +00:00
|
|
|
|
2009-03-21 20:43:56 +00:00
|
|
|
TempPkt[MTP2_SENT_OFFSET] = 0;
|
|
|
|
TempPkt[MTP2_ANNEX_A_USED_OFFSET] = MTP2_ANNEX_A_USED_UNKNOWN;
|
|
|
|
*(TempPkt+MTP2_LINK_NUMBER_OFFSET) = ((header->rec.mc_hdlc.mc_header>>16)&0x01);
|
|
|
|
*(TempPkt+MTP2_LINK_NUMBER_OFFSET+1) = ((header->rec.mc_hdlc.mc_header>>24)&0xff);
|
|
|
|
memcpy(TempPkt+MTP2_HDR_LEN, dp, caplen);
|
|
|
|
dp = TempPkt;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
break;
|
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
case ERF_TYPE_IPV4:
|
|
|
|
if ((p->linktype != DLT_RAW) &&
|
|
|
|
(p->linktype != DLT_IPV4))
|
|
|
|
continue;
|
|
|
|
packet_len = ntohs(header->wlen);
|
|
|
|
caplen = rlen - dag_record_size;
|
|
|
|
/* Skip over extension headers */
|
|
|
|
caplen -= (8 * num_ext_hdr);
|
|
|
|
if (caplen > packet_len) {
|
|
|
|
caplen = packet_len;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ERF_TYPE_IPV6:
|
|
|
|
if ((p->linktype != DLT_RAW) &&
|
|
|
|
(p->linktype != DLT_IPV6))
|
|
|
|
continue;
|
2009-03-21 20:43:56 +00:00
|
|
|
packet_len = ntohs(header->wlen);
|
|
|
|
caplen = rlen - dag_record_size;
|
2017-02-12 07:04:44 +00:00
|
|
|
/* Skip over extension headers */
|
|
|
|
caplen -= (8 * num_ext_hdr);
|
2009-03-21 20:43:56 +00:00
|
|
|
if (caplen > packet_len) {
|
|
|
|
caplen = packet_len;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
Update libpcap to 1.1.1.
Changes:
Thu. April 1, 2010. guy@alum.mit.edu.
Summary for 1.1.1 libpcap release
Update CHANGES to reflect more of the changes in 1.1.0.
Fix build on RHEL5.
Fix shared library build on AIX.
Thu. March 11, 2010. ken@netfunctional.ca/guy@alum.mit.edu.
Summary for 1.1.0 libpcap release
Add SocketCAN capture support
Add Myricom SNF API support
Update Endace DAG and ERF support
Add support for shared libraries on Solaris, HP-UX, and AIX
Build, install, and un-install shared libraries by default;
don't build/install shared libraries on platforms we don't support
Fix building from a directory other than the source directory
Fix compiler warnings and builds on some platforms
Update config.guess and config.sub
Support monitor mode on mac80211 devices on Linux
Fix USB memory-mapped capturing on Linux; it requires a new DLT_
value
On Linux, scan /sys/class/net for devices if we have it; scan
it, or /proc/net/dev if we don't have /sys/class/net, even if
we have getifaddrs(), as it'll find interfaces with no
addresses
Add limited support for reading pcap-ng files
Fix BPF driver-loading error handling on AIX
Support getting the full-length interface description on FreeBSD
In the lexical analyzer, free up any addrinfo structure we got back
from getaddrinfo().
Add support for BPF and libdlpi in OpenSolaris (and SXCE)
Hyphenate "link-layer" everywhere
Add /sys/kernel/debug/usb/usbmon to the list of usbmon locations
In pcap_read_linux_mmap(), if there are no frames available, call
poll() even if we're in non-blocking mode, so we pick up
errors, and check for the errors in question.
Note that poll() works on BPF devices is Snow Leopard
If an ENXIO or ENETDOWN is received, it may mean the device has
gone away. Deal with it.
For BPF, raise the default capture buffer size to from 32k to 512k
Support ps_ifdrop on Linux
Added a bunch of #ifdef directives to make wpcap.dll (WinPcap) compile
under cygwin.
Changes to Linux mmapped captures.
Fix bug where create_ring would fail for particular snaplen and
buffer size combinations
Update pcap-config so that it handles libpcap requiring
additional libraries
Add workaround for threadsafeness on Windows
Add missing mapping for DLT_ENC <-> LINKTYPE_ENC
DLT: Add DLT_CAN_SOCKETCAN
DLT: Add Solaris ipnet
Don't check for DLT_IPNET if it's not defined
Add link-layer types for Fibre Channel FC-2
Add link-layer types for Wireless HART
Add link-layer types for AOS
Add link-layer types for DECT
Autoconf fixes (AIX, HP-UX, OSF/1, Tru64 cleanups)
Install headers unconditionally, and include vlan.h/bluetooth.h if
enabled
Autoconf fixes+cleanup
Support enabling/disabling bluetooth (--{en,dis}able-bluetooth)
Support disabling SITA support (--without-sita)
Return -1 on failure to create packet ring (if supported but
creation failed)
Fix handling of 'any' device, so that it can be opened, and no longer
attempt to open it in Monitor mode
Add support for snapshot length for USB Memory-Mapped Interface
Fix configure and build on recent Linux kernels
Fix memory-mapped Linux capture to support pcap_next() and
pcap_next_ex()
Fixes for Linux USB capture
DLT: Add DLT_LINUX_EVDEV
DLT: Add DLT_GSMTAP_UM
DLT: Add DLT_GSMTAP_ABIS
2010-10-28 16:22:13 +00:00
|
|
|
/* These types have no matching 'native' DLT, but can be used with DLT_ERF above */
|
2018-05-18 12:21:19 +00:00
|
|
|
case ERF_TYPE_MC_RAW:
|
|
|
|
case ERF_TYPE_MC_RAW_CHANNEL:
|
|
|
|
case ERF_TYPE_IP_COUNTER:
|
|
|
|
case ERF_TYPE_TCP_FLOW_COUNTER:
|
|
|
|
case ERF_TYPE_INFINIBAND:
|
|
|
|
case ERF_TYPE_RAW_LINK:
|
|
|
|
case ERF_TYPE_INFINIBAND_LINK:
|
2009-03-21 20:43:56 +00:00
|
|
|
default:
|
|
|
|
/* Unhandled ERF type.
|
|
|
|
* Ignore rather than generating error
|
|
|
|
*/
|
|
|
|
continue;
|
|
|
|
} /* switch type */
|
|
|
|
|
|
|
|
} /* ERF encapsulation */
|
2017-02-12 07:04:44 +00:00
|
|
|
|
2009-03-21 20:43:56 +00:00
|
|
|
if (caplen > p->snapshot)
|
|
|
|
caplen = p->snapshot;
|
2004-03-31 09:07:39 +00:00
|
|
|
|
2006-09-04 19:43:23 +00:00
|
|
|
/* Run the packet filter if there is one. */
|
|
|
|
if ((p->fcode.bf_insns == NULL) || bpf_filter(p->fcode.bf_insns, dp, packet_len, caplen)) {
|
2017-02-12 07:04:44 +00:00
|
|
|
|
2006-09-04 19:43:23 +00:00
|
|
|
/* convert between timestamp formats */
|
|
|
|
register unsigned long long ts;
|
2017-02-12 07:04:44 +00:00
|
|
|
|
2006-09-04 19:43:23 +00:00
|
|
|
if (IS_BIGENDIAN()) {
|
2007-10-16 02:02:02 +00:00
|
|
|
ts = SWAPLL(header->ts);
|
2006-09-04 19:43:23 +00:00
|
|
|
} else {
|
|
|
|
ts = header->ts;
|
|
|
|
}
|
2004-03-31 09:07:39 +00:00
|
|
|
|
2017-02-12 07:04:44 +00:00
|
|
|
switch (p->opt.tstamp_precision) {
|
|
|
|
case PCAP_TSTAMP_PRECISION_NANO:
|
|
|
|
ticks_per_second = 1000000000;
|
|
|
|
break;
|
|
|
|
case PCAP_TSTAMP_PRECISION_MICRO:
|
|
|
|
default:
|
|
|
|
ticks_per_second = 1000000;
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
2006-09-04 19:43:23 +00:00
|
|
|
pcap_header.ts.tv_sec = ts >> 32;
|
2017-02-12 07:04:44 +00:00
|
|
|
ts = (ts & 0xffffffffULL) * ticks_per_second;
|
2006-09-04 19:43:23 +00:00
|
|
|
ts += 0x80000000; /* rounding */
|
2017-02-12 07:04:44 +00:00
|
|
|
pcap_header.ts.tv_usec = ts >> 32;
|
|
|
|
if (pcap_header.ts.tv_usec >= ticks_per_second) {
|
|
|
|
pcap_header.ts.tv_usec -= ticks_per_second;
|
2006-09-04 19:43:23 +00:00
|
|
|
pcap_header.ts.tv_sec++;
|
|
|
|
}
|
2004-03-31 09:07:39 +00:00
|
|
|
|
2006-09-04 19:43:23 +00:00
|
|
|
/* Fill in our own header data */
|
|
|
|
pcap_header.caplen = caplen;
|
|
|
|
pcap_header.len = packet_len;
|
2017-02-12 07:04:44 +00:00
|
|
|
|
2006-09-04 19:43:23 +00:00
|
|
|
/* Count the packet. */
|
2015-01-06 18:58:31 +00:00
|
|
|
pd->stat.ps_recv++;
|
2017-02-12 07:04:44 +00:00
|
|
|
|
2006-09-04 19:43:23 +00:00
|
|
|
/* Call the user supplied callback function */
|
|
|
|
callback(user, &pcap_header, dp);
|
2017-02-12 07:04:44 +00:00
|
|
|
|
2006-09-04 19:43:23 +00:00
|
|
|
/* Only count packets that pass the filter, for consistency with standard Linux behaviour. */
|
|
|
|
processed++;
|
2015-01-06 18:58:31 +00:00
|
|
|
if (processed == cnt && !PACKET_COUNT_IS_UNLIMITED(cnt))
|
2006-09-04 19:43:23 +00:00
|
|
|
{
|
|
|
|
/* Reached the user-specified limit. */
|
|
|
|
return cnt;
|
2004-03-31 09:07:39 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2006-09-04 19:43:23 +00:00
|
|
|
|
2004-03-31 09:07:39 +00:00
|
|
|
return processed;
|
|
|
|
}
|
|
|
|
|
2005-05-29 17:46:52 +00:00
|
|
|
static int
|
|
|
|
dag_inject(pcap_t *p, const void *buf _U_, size_t size _U_)
|
|
|
|
{
|
|
|
|
strlcpy(p->errbuf, "Sending packets isn't supported on DAG cards",
|
|
|
|
PCAP_ERRBUF_SIZE);
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
|
2004-03-31 09:07:39 +00:00
|
|
|
/*
|
|
|
|
* Get a handle for a live capture from the given DAG device. Passing a NULL
|
|
|
|
* device will result in a failure. The promisc flag is ignored because DAG
|
2009-03-21 20:43:56 +00:00
|
|
|
* cards are always promiscuous. The to_ms parameter is used in setting the
|
|
|
|
* API polling parameters.
|
2017-02-12 07:04:44 +00:00
|
|
|
*
|
2007-10-16 02:02:02 +00:00
|
|
|
* snaplen is now also ignored, until we get per-stream slen support. Set
|
2009-03-21 20:43:56 +00:00
|
|
|
* slen with approprite DAG tool BEFORE pcap_activate().
|
2007-10-16 02:02:02 +00:00
|
|
|
*
|
2004-03-31 09:07:39 +00:00
|
|
|
* See also pcap(3).
|
|
|
|
*/
|
2018-05-18 12:21:19 +00:00
|
|
|
static int dag_activate(pcap_t* p)
|
2005-05-29 17:46:52 +00:00
|
|
|
{
|
2018-05-18 12:21:19 +00:00
|
|
|
struct pcap_dag *pd = p->priv;
|
2005-05-29 17:46:52 +00:00
|
|
|
char *s;
|
|
|
|
int n;
|
|
|
|
daginf_t* daginf;
|
2007-10-16 02:02:02 +00:00
|
|
|
char * newDev = NULL;
|
2018-05-18 12:21:19 +00:00
|
|
|
char * device = p->opt.device;
|
|
|
|
dag_size_t mindata;
|
2006-09-04 19:43:23 +00:00
|
|
|
struct timeval maxwait;
|
|
|
|
struct timeval poll;
|
|
|
|
|
2005-05-29 17:46:52 +00:00
|
|
|
if (device == NULL) {
|
2018-05-18 12:21:19 +00:00
|
|
|
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "device is NULL");
|
2009-03-21 20:43:56 +00:00
|
|
|
return -1;
|
2005-05-29 17:46:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Initialize some components of the pcap structure. */
|
2007-10-16 02:02:02 +00:00
|
|
|
newDev = (char *)malloc(strlen(device) + 16);
|
|
|
|
if (newDev == NULL) {
|
2018-05-18 12:21:19 +00:00
|
|
|
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
|
|
|
errno, "Can't allocate string for device name");
|
2007-10-16 02:02:02 +00:00
|
|
|
goto fail;
|
|
|
|
}
|
2017-02-12 07:04:44 +00:00
|
|
|
|
2006-09-04 19:43:23 +00:00
|
|
|
/* Parse input name to get dag device and stream number if provided */
|
2018-05-18 12:21:19 +00:00
|
|
|
if (dag_parse_name(device, newDev, strlen(device) + 16, &pd->dag_stream) < 0) {
|
|
|
|
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
|
|
|
errno, "dag_parse_name");
|
2006-09-04 19:43:23 +00:00
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
device = newDev;
|
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
if (pd->dag_stream%2) {
|
|
|
|
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "dag_parse_name: tx (even numbered) streams not supported for capture");
|
2006-09-04 19:43:23 +00:00
|
|
|
goto fail;
|
|
|
|
}
|
2005-05-29 17:46:52 +00:00
|
|
|
|
|
|
|
/* setup device parameters */
|
2018-05-18 12:21:19 +00:00
|
|
|
if((pd->dag_ref = dag_config_init((char *)device)) == NULL) {
|
|
|
|
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
|
|
|
errno, "dag_config_init %s", device);
|
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
|
|
|
if((p->fd = dag_config_get_card_fd(pd->dag_ref)) < 0) {
|
|
|
|
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
|
|
|
errno, "dag_config_get_card_fd %s", device);
|
2005-05-29 17:46:52 +00:00
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
2006-09-04 19:43:23 +00:00
|
|
|
/* Open requested stream. Can fail if already locked or on error */
|
2018-05-18 12:21:19 +00:00
|
|
|
if (dag_attach_stream64(p->fd, pd->dag_stream, 0, 0) < 0) {
|
|
|
|
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
|
|
|
errno, "dag_attach_stream");
|
2007-10-16 02:02:02 +00:00
|
|
|
goto failclose;
|
2006-09-04 19:43:23 +00:00
|
|
|
}
|
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
/* Try to find Stream Drop attribute */
|
|
|
|
pd->drop_attr = kNullAttributeUuid;
|
|
|
|
pd->dag_root = dag_config_get_root_component(pd->dag_ref);
|
|
|
|
if ( dag_component_get_subcomponent(pd->dag_root, kComponentStreamFeatures, 0) )
|
|
|
|
{
|
|
|
|
pd->drop_attr = dag_config_get_indexed_attribute_uuid(pd->dag_ref, kUint32AttributeStreamDropCount, pd->dag_stream/2);
|
|
|
|
}
|
|
|
|
|
2006-09-04 19:43:23 +00:00
|
|
|
/* Set up default poll parameters for stream
|
|
|
|
* Can be overridden by pcap_set_nonblock()
|
|
|
|
*/
|
2018-05-18 12:21:19 +00:00
|
|
|
if (dag_get_stream_poll64(p->fd, pd->dag_stream,
|
2006-09-04 19:43:23 +00:00
|
|
|
&mindata, &maxwait, &poll) < 0) {
|
2018-05-18 12:21:19 +00:00
|
|
|
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
|
|
|
errno, "dag_get_stream_poll");
|
2007-10-16 02:02:02 +00:00
|
|
|
goto faildetach;
|
2006-09-04 19:43:23 +00:00
|
|
|
}
|
2017-02-12 07:04:44 +00:00
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
/* Use the poll time as the required select timeout for callers
|
|
|
|
* who are using select()/etc. in an event loop waiting for
|
|
|
|
* packets to arrive.
|
|
|
|
*/
|
|
|
|
pd->required_select_timeout = poll;
|
|
|
|
p->required_select_timeout = &pd->required_select_timeout;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Turn a negative snapshot value (invalid), a snapshot value of
|
|
|
|
* 0 (unspecified), or a value bigger than the normal maximum
|
|
|
|
* value, into the maximum allowed value.
|
|
|
|
*
|
|
|
|
* If some application really *needs* a bigger snapshot
|
|
|
|
* length, we should just increase MAXIMUM_SNAPLEN.
|
|
|
|
*/
|
|
|
|
if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN)
|
|
|
|
p->snapshot = MAXIMUM_SNAPLEN;
|
|
|
|
|
|
|
|
if (p->opt.immediate) {
|
2015-01-06 18:58:31 +00:00
|
|
|
/* Call callback immediately.
|
2018-05-18 12:21:19 +00:00
|
|
|
* XXX - is this the right way to p this?
|
2015-01-06 18:58:31 +00:00
|
|
|
*/
|
|
|
|
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;
|
|
|
|
}
|
2006-09-04 19:43:23 +00:00
|
|
|
|
2015-01-06 18:58:31 +00:00
|
|
|
/* Obey opt.timeout (was to_ms) if supplied. This is a good idea!
|
2006-09-04 19:43:23 +00:00
|
|
|
* Recommend 10-100ms. Calls will time out even if no data arrived.
|
|
|
|
*/
|
2018-05-18 12:21:19 +00:00
|
|
|
maxwait.tv_sec = p->opt.timeout/1000;
|
|
|
|
maxwait.tv_usec = (p->opt.timeout%1000) * 1000;
|
2006-09-04 19:43:23 +00:00
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
if (dag_set_stream_poll64(p->fd, pd->dag_stream,
|
2006-09-04 19:43:23 +00:00
|
|
|
mindata, &maxwait, &poll) < 0) {
|
2018-05-18 12:21:19 +00:00
|
|
|
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
|
|
|
errno, "dag_set_stream_poll");
|
2007-10-16 02:02:02 +00:00
|
|
|
goto faildetach;
|
2006-09-04 19:43:23 +00:00
|
|
|
}
|
2017-02-12 07:04:44 +00:00
|
|
|
|
2007-10-16 02:02:02 +00:00
|
|
|
/* XXX Not calling dag_configure() to set slen; this is unsafe in
|
|
|
|
* multi-stream environments as the gpp config is global.
|
|
|
|
* Once the firmware provides 'per-stream slen' this can be supported
|
|
|
|
* again via the Config API without side-effects */
|
|
|
|
#if 0
|
2005-05-29 17:46:52 +00:00
|
|
|
/* set the card snap length to the specified snaplen parameter */
|
2007-10-16 02:02:02 +00:00
|
|
|
/* This is a really bad idea, as different cards have different
|
|
|
|
* valid slen ranges. Should fix in Config API. */
|
2018-05-18 12:21:19 +00:00
|
|
|
if (p->snapshot == 0 || p->snapshot > MAX_DAG_SNAPLEN) {
|
|
|
|
p->snapshot = MAX_DAG_SNAPLEN;
|
2005-05-29 17:46:52 +00:00
|
|
|
} else if (snaplen < MIN_DAG_SNAPLEN) {
|
2018-05-18 12:21:19 +00:00
|
|
|
p->snapshot = MIN_DAG_SNAPLEN;
|
2005-05-29 17:46:52 +00:00
|
|
|
}
|
|
|
|
/* snap len has to be a multiple of 4 */
|
2017-02-12 07:04:44 +00:00
|
|
|
#endif
|
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
if(dag_start_stream(p->fd, pd->dag_stream) < 0) {
|
|
|
|
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
|
|
|
errno, "dag_start_stream %s", device);
|
2007-10-16 02:02:02 +00:00
|
|
|
goto faildetach;
|
2005-05-29 17:46:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* 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!
|
|
|
|
*/
|
2018-05-18 12:21:19 +00:00
|
|
|
pd->dag_mem_bottom = 0;
|
|
|
|
pd->dag_mem_top = 0;
|
2005-05-29 17:46:52 +00:00
|
|
|
|
2009-03-21 20:43:56 +00:00
|
|
|
/*
|
|
|
|
* Find out how many FCS bits we should strip.
|
|
|
|
* First, query the card to see if it strips the FCS.
|
|
|
|
*/
|
2018-05-18 12:21:19 +00:00
|
|
|
daginf = dag_info(p->fd);
|
2009-03-21 20:43:56 +00:00
|
|
|
if ((0x4200 == daginf->device_code) || (0x4230 == daginf->device_code)) {
|
2005-05-29 17:46:52 +00:00
|
|
|
/* DAG 4.2S and 4.23S already strip the FCS. Stripping the final word again truncates the packet. */
|
2018-05-18 12:21:19 +00:00
|
|
|
pd->dag_fcs_bits = 0;
|
2005-05-29 17:46:52 +00:00
|
|
|
|
2009-03-21 20:43:56 +00:00
|
|
|
/* Note that no FCS will be supplied. */
|
2018-05-18 12:21:19 +00:00
|
|
|
p->linktype_ext = LT_FCS_DATALINK_EXT(0);
|
2009-03-21 20:43:56 +00:00
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* Start out assuming it's 32 bits.
|
|
|
|
*/
|
2018-05-18 12:21:19 +00:00
|
|
|
pd->dag_fcs_bits = 32;
|
2009-03-21 20:43:56 +00:00
|
|
|
|
|
|
|
/* Allow an environment variable to override. */
|
|
|
|
if ((s = getenv("ERF_FCS_BITS")) != NULL) {
|
|
|
|
if ((n = atoi(s)) == 0 || n == 16 || n == 32) {
|
2018-05-18 12:21:19 +00:00
|
|
|
pd->dag_fcs_bits = n;
|
2009-03-21 20:43:56 +00:00
|
|
|
} else {
|
2018-05-18 12:21:19 +00:00
|
|
|
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
|
2017-02-12 07:04:44 +00:00
|
|
|
"pcap_activate %s: bad ERF_FCS_BITS value (%d) in environment", device, n);
|
2009-03-21 20:43:56 +00:00
|
|
|
goto failstop;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Did the user request that they not be stripped?
|
|
|
|
*/
|
|
|
|
if ((s = getenv("ERF_DONT_STRIP_FCS")) != NULL) {
|
|
|
|
/* Yes. Note the number of bytes that will be
|
|
|
|
supplied. */
|
2018-05-18 12:21:19 +00:00
|
|
|
p->linktype_ext = LT_FCS_DATALINK_EXT(pd->dag_fcs_bits/16);
|
2009-03-21 20:43:56 +00:00
|
|
|
|
|
|
|
/* And don't strip them. */
|
2018-05-18 12:21:19 +00:00
|
|
|
pd->dag_fcs_bits = 0;
|
2005-05-29 17:46:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
pd->dag_timeout = p->opt.timeout;
|
2005-05-29 17:46:52 +00:00
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
p->linktype = -1;
|
|
|
|
if (dag_get_datalink(p) < 0)
|
2007-10-16 02:02:02 +00:00
|
|
|
goto failstop;
|
2017-02-12 07:04:44 +00:00
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
p->bufsize = 0;
|
2005-05-29 17:46:52 +00:00
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
if (new_pcap_dag(p) < 0) {
|
|
|
|
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
|
|
|
errno, "new_pcap_dag %s", device);
|
2007-10-16 02:02:02 +00:00
|
|
|
goto failstop;
|
2005-05-29 17:46:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2006-09-04 19:43:23 +00:00
|
|
|
* "select()" and "poll()" don't work on DAG device descriptors.
|
2005-05-29 17:46:52 +00:00
|
|
|
*/
|
2018-05-18 12:21:19 +00:00
|
|
|
p->selectable_fd = -1;
|
2004-03-31 09:07:39 +00:00
|
|
|
|
2007-10-16 02:02:02 +00:00
|
|
|
if (newDev != NULL) {
|
|
|
|
free((char *)newDev);
|
|
|
|
}
|
2004-03-31 09:07:39 +00:00
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
p->read_op = dag_read;
|
|
|
|
p->inject_op = dag_inject;
|
|
|
|
p->setfilter_op = dag_setfilter;
|
|
|
|
p->setdirection_op = NULL; /* Not implemented.*/
|
|
|
|
p->set_datalink_op = dag_set_datalink;
|
|
|
|
p->getnonblock_op = pcap_getnonblock_fd;
|
|
|
|
p->setnonblock_op = dag_setnonblock;
|
|
|
|
p->stats_op = dag_stats;
|
|
|
|
p->cleanup_op = dag_platform_cleanup;
|
|
|
|
pd->stat.ps_drop = 0;
|
|
|
|
pd->stat.ps_recv = 0;
|
|
|
|
pd->stat.ps_ifdrop = 0;
|
2009-03-21 20:43:56 +00:00
|
|
|
return 0;
|
2004-03-31 09:07:39 +00:00
|
|
|
|
2007-10-16 02:02:02 +00:00
|
|
|
failstop:
|
2018-05-18 12:21:19 +00:00
|
|
|
if (dag_stop_stream(p->fd, pd->dag_stream) < 0) {
|
2009-03-21 20:43:56 +00:00
|
|
|
fprintf(stderr,"dag_stop_stream: %s\n", strerror(errno));
|
2007-10-16 02:02:02 +00:00
|
|
|
}
|
2017-02-12 07:04:44 +00:00
|
|
|
|
2007-10-16 02:02:02 +00:00
|
|
|
faildetach:
|
2018-05-18 12:21:19 +00:00
|
|
|
if (dag_detach_stream(p->fd, pd->dag_stream) < 0)
|
2009-03-21 20:43:56 +00:00
|
|
|
fprintf(stderr,"dag_detach_stream: %s\n", strerror(errno));
|
2017-02-12 07:04:44 +00:00
|
|
|
|
2007-10-16 02:02:02 +00:00
|
|
|
failclose:
|
2018-05-18 12:21:19 +00:00
|
|
|
dag_config_dispose(pd->dag_ref);
|
|
|
|
delete_pcap_dag(p);
|
2009-03-21 20:43:56 +00:00
|
|
|
|
2004-03-31 09:07:39 +00:00
|
|
|
fail:
|
2018-05-18 12:21:19 +00:00
|
|
|
pcap_cleanup_live_common(p);
|
2006-09-04 19:43:23 +00:00
|
|
|
if (newDev != NULL) {
|
|
|
|
free((char *)newDev);
|
2005-05-29 17:46:52 +00:00
|
|
|
}
|
2004-03-31 09:07:39 +00:00
|
|
|
|
2009-03-21 20:43:56 +00:00
|
|
|
return PCAP_ERROR;
|
|
|
|
}
|
|
|
|
|
2013-05-30 06:41:26 +00:00
|
|
|
pcap_t *dag_create(const char *device, char *ebuf, int *is_ours)
|
2009-03-21 20:43:56 +00:00
|
|
|
{
|
2013-05-30 06:41:26 +00:00
|
|
|
const char *cp;
|
|
|
|
char *cpend;
|
|
|
|
long devnum;
|
2009-03-21 20:43:56 +00:00
|
|
|
pcap_t *p;
|
2015-01-06 18:58:31 +00:00
|
|
|
long stream = 0;
|
2009-03-21 20:43:56 +00:00
|
|
|
|
2013-05-30 06:41:26 +00:00
|
|
|
/* 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;
|
|
|
|
}
|
2015-01-06 18:58:31 +00:00
|
|
|
/* Yes - is "dag" followed by a number from 0 to DAG_MAX_BOARDS-1 */
|
2013-05-30 06:41:26 +00:00
|
|
|
cp += 3;
|
|
|
|
devnum = strtol(cp, &cpend, 10);
|
2015-01-06 18:58:31 +00:00
|
|
|
if (*cpend == ':') {
|
|
|
|
/* Followed by a stream number. */
|
|
|
|
stream = strtol(++cpend, &cpend, 10);
|
|
|
|
}
|
2018-05-18 12:21:19 +00:00
|
|
|
|
2013-05-30 06:41:26 +00:00
|
|
|
if (cpend == cp || *cpend != '\0') {
|
|
|
|
/* Not followed by a number. */
|
|
|
|
*is_ours = 0;
|
|
|
|
return NULL;
|
|
|
|
}
|
2018-05-18 12:21:19 +00:00
|
|
|
|
2015-01-06 18:58:31 +00:00
|
|
|
if (devnum < 0 || devnum >= DAG_MAX_BOARDS) {
|
2013-05-30 06:41:26 +00:00
|
|
|
/* Followed by a non-valid number. */
|
|
|
|
*is_ours = 0;
|
|
|
|
return NULL;
|
|
|
|
}
|
2018-05-18 12:21:19 +00:00
|
|
|
|
2015-01-06 18:58:31 +00:00
|
|
|
if (stream <0 || stream >= DAG_STREAM_MAX) {
|
|
|
|
/* Followed by a non-valid stream number. */
|
|
|
|
*is_ours = 0;
|
|
|
|
return NULL;
|
|
|
|
}
|
2013-05-30 06:41:26 +00:00
|
|
|
|
|
|
|
/* OK, it's probably ours. */
|
|
|
|
*is_ours = 1;
|
|
|
|
|
2017-02-12 07:04:44 +00:00
|
|
|
p = pcap_create_common(ebuf, sizeof (struct pcap_dag));
|
2009-03-21 20:43:56 +00:00
|
|
|
if (p == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
p->activate_op = dag_activate;
|
2017-02-12 07:04:44 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* We claim that we support microsecond and nanosecond time
|
|
|
|
* stamps.
|
|
|
|
*
|
|
|
|
* XXX Our native precision is 2^-32s, but libpcap doesn't support
|
|
|
|
* power of two precisions yet. We can convert to either MICRO or NANO.
|
|
|
|
*/
|
|
|
|
p->tstamp_precision_count = 2;
|
|
|
|
p->tstamp_precision_list = malloc(2 * sizeof(u_int));
|
|
|
|
if (p->tstamp_precision_list == NULL) {
|
2018-05-18 12:21:19 +00:00
|
|
|
pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
|
|
|
|
errno, "malloc");
|
2017-02-12 07:04:44 +00:00
|
|
|
pcap_close(p);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
p->tstamp_precision_list[0] = PCAP_TSTAMP_PRECISION_MICRO;
|
|
|
|
p->tstamp_precision_list[1] = PCAP_TSTAMP_PRECISION_NANO;
|
2009-03-21 20:43:56 +00:00
|
|
|
return p;
|
2004-03-31 09:07:39 +00:00
|
|
|
}
|
|
|
|
|
2005-05-29 17:46:52 +00:00
|
|
|
static int
|
|
|
|
dag_stats(pcap_t *p, struct pcap_stat *ps) {
|
2015-01-06 18:58:31 +00:00
|
|
|
struct pcap_dag *pd = p->priv;
|
2018-05-18 12:21:19 +00:00
|
|
|
uint32_t stream_drop;
|
|
|
|
dag_err_t dag_error;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Packet records received (ps_recv) are counted in dag_read().
|
|
|
|
* Packet records dropped (ps_drop) are read from Stream Drop attribute if present,
|
|
|
|
* otherwise integrate the ERF Header lctr counts (if available) in dag_read().
|
|
|
|
* We are reporting that no records are dropped by the card/driver (ps_ifdrop).
|
|
|
|
*/
|
2015-01-06 18:58:31 +00:00
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
if(pd->drop_attr != kNullAttributeUuid) {
|
|
|
|
/* Note this counter is cleared at start of capture and will wrap at UINT_MAX.
|
|
|
|
* The application is responsible for polling ps_drop frequently enough
|
|
|
|
* to detect each wrap and integrate total drop with a wider counter */
|
|
|
|
if ((dag_error = dag_config_get_uint32_attribute_ex(pd->dag_ref, pd->drop_attr, &stream_drop) == kDagErrNone)) {
|
|
|
|
pd->stat.ps_drop = stream_drop;
|
|
|
|
} else {
|
|
|
|
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "reading stream drop attribute: %s",
|
|
|
|
dag_config_strerror(dag_error));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
2017-02-12 07:04:44 +00:00
|
|
|
|
2015-01-06 18:58:31 +00:00
|
|
|
*ps = pd->stat;
|
2017-02-12 07:04:44 +00:00
|
|
|
|
2005-05-29 17:46:52 +00:00
|
|
|
return 0;
|
2004-03-31 09:07:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2018-05-18 12:21:19 +00:00
|
|
|
* Add all DAG devices.
|
2004-03-31 09:07:39 +00:00
|
|
|
*/
|
|
|
|
int
|
2018-05-18 12:21:19 +00:00
|
|
|
dag_findalldevs(pcap_if_list_t *devlistp, char *errbuf)
|
2004-03-31 09:07:39 +00:00
|
|
|
{
|
2006-09-04 19:43:23 +00:00
|
|
|
char name[12]; /* XXX - pick a size */
|
|
|
|
int c;
|
2009-03-21 20:43:56 +00:00
|
|
|
char dagname[DAGNAME_BUFSIZE];
|
|
|
|
int dagstream;
|
|
|
|
int dagfd;
|
2017-02-12 07:04:44 +00:00
|
|
|
dag_card_inf_t *inf;
|
|
|
|
char *description;
|
2018-05-18 12:21:19 +00:00
|
|
|
int stream, rxstreams;
|
2005-05-29 17:46:52 +00:00
|
|
|
|
2015-01-06 18:58:31 +00:00
|
|
|
/* Try all the DAGs 0-DAG_MAX_BOARDS */
|
|
|
|
for (c = 0; c < DAG_MAX_BOARDS; c++) {
|
2017-02-12 07:04:44 +00:00
|
|
|
pcap_snprintf(name, 12, "dag%d", c);
|
2009-03-21 20:43:56 +00:00
|
|
|
if (-1 == dag_parse_name(name, dagname, DAGNAME_BUFSIZE, &dagstream))
|
2006-09-04 19:43:23 +00:00
|
|
|
{
|
2018-05-18 12:21:19 +00:00
|
|
|
(void) pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
|
|
|
"dag: device name %s can't be parsed", name);
|
|
|
|
return (-1);
|
2005-05-29 17:46:52 +00:00
|
|
|
}
|
2009-03-21 20:43:56 +00:00
|
|
|
if ( (dagfd = dag_open(dagname)) >= 0 ) {
|
2018-05-18 12:21:19 +00:00
|
|
|
description = NULL;
|
2017-02-12 07:04:44 +00:00
|
|
|
if ((inf = dag_pciinfo(dagfd)))
|
|
|
|
description = dag_device_name(inf->device_code, 1);
|
2018-05-18 12:21:19 +00:00
|
|
|
/*
|
|
|
|
* XXX - is there a way to determine whether
|
|
|
|
* the card is plugged into a network or not?
|
|
|
|
* If so, we should check that and set
|
|
|
|
* PCAP_IF_CONNECTION_STATUS_CONNECTED or
|
|
|
|
* PCAP_IF_CONNECTION_STATUS_DISCONNECTED.
|
|
|
|
*
|
|
|
|
* Also, are there notions of "up" and "running"?
|
|
|
|
*/
|
|
|
|
if (add_dev(devlistp, name, 0, description, errbuf) == NULL) {
|
2009-03-21 20:43:56 +00:00
|
|
|
/*
|
|
|
|
* Failure.
|
|
|
|
*/
|
2018-05-18 12:21:19 +00:00
|
|
|
return (-1);
|
2009-03-21 20:43:56 +00:00
|
|
|
}
|
2018-05-18 12:21:19 +00:00
|
|
|
rxstreams = dag_rx_get_stream_count(dagfd);
|
|
|
|
for(stream=0;stream<DAG_STREAM_MAX;stream+=2) {
|
|
|
|
if (0 == dag_attach_stream(dagfd, stream, 0, 0)) {
|
|
|
|
dag_detach_stream(dagfd, stream);
|
|
|
|
|
|
|
|
pcap_snprintf(name, 10, "dag%d:%d", c, stream);
|
|
|
|
if (add_dev(devlistp, name, 0, description, errbuf) == NULL) {
|
|
|
|
/*
|
|
|
|
* Failure.
|
|
|
|
*/
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
rxstreams--;
|
|
|
|
if(rxstreams <= 0) {
|
|
|
|
break;
|
2009-03-21 20:43:56 +00:00
|
|
|
}
|
2017-02-12 07:04:44 +00:00
|
|
|
}
|
2009-03-21 20:43:56 +00:00
|
|
|
}
|
|
|
|
dag_close(dagfd);
|
|
|
|
}
|
|
|
|
|
2005-05-29 17:46:52 +00:00
|
|
|
}
|
2018-05-18 12:21:19 +00:00
|
|
|
return (0);
|
2004-03-31 09:07:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Installs the given bpf filter program in the given pcap structure. There is
|
|
|
|
* no attempt to store the filter in kernel memory as that is not supported
|
|
|
|
* with DAG cards.
|
|
|
|
*/
|
2005-05-29 17:46:52 +00:00
|
|
|
static int
|
|
|
|
dag_setfilter(pcap_t *p, struct bpf_program *fp)
|
|
|
|
{
|
|
|
|
if (!p)
|
|
|
|
return -1;
|
|
|
|
if (!fp) {
|
|
|
|
strncpy(p->errbuf, "setfilter: No filter specified",
|
|
|
|
sizeof(p->errbuf));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Make our private copy of the filter */
|
|
|
|
|
|
|
|
if (install_bpf_program(p, fp) < 0)
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
return (0);
|
2004-03-31 09:07:39 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
dag_set_datalink(pcap_t *p, int dlt)
|
|
|
|
{
|
2005-05-29 17:46:52 +00:00
|
|
|
p->linktype = dlt;
|
|
|
|
|
2004-03-31 09:07:39 +00:00
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
2018-05-18 12:21:19 +00:00
|
|
|
dag_setnonblock(pcap_t *p, int nonblock)
|
2004-03-31 09:07:39 +00:00
|
|
|
{
|
2015-01-06 18:58:31 +00:00
|
|
|
struct pcap_dag *pd = p->priv;
|
2018-05-18 12:21:19 +00:00
|
|
|
dag_size_t mindata;
|
|
|
|
struct timeval maxwait;
|
|
|
|
struct timeval poll;
|
2015-01-06 18:58:31 +00:00
|
|
|
|
2004-03-31 09:07:39 +00:00
|
|
|
/*
|
|
|
|
* 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
|
2018-05-18 12:21:19 +00:00
|
|
|
* "pd->dag_flags".
|
2004-03-31 09:07:39 +00:00
|
|
|
*/
|
2018-05-18 12:21:19 +00:00
|
|
|
if (pcap_setnonblock_fd(p, nonblock) < 0)
|
2004-03-31 09:07:39 +00:00
|
|
|
return (-1);
|
2017-02-12 07:04:44 +00:00
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
if (dag_get_stream_poll64(p->fd, pd->dag_stream,
|
|
|
|
&mindata, &maxwait, &poll) < 0) {
|
|
|
|
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
|
|
|
errno, "dag_get_stream_poll");
|
|
|
|
return -1;
|
|
|
|
}
|
2017-02-12 07:04:44 +00:00
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
/* 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!
|
|
|
|
*/
|
|
|
|
if(nonblock)
|
|
|
|
mindata = 0;
|
|
|
|
else
|
|
|
|
mindata = 65536;
|
|
|
|
|
|
|
|
if (dag_set_stream_poll64(p->fd, pd->dag_stream,
|
|
|
|
mindata, &maxwait, &poll) < 0) {
|
|
|
|
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
|
|
|
|
errno, "dag_set_stream_poll");
|
|
|
|
return -1;
|
2006-09-04 19:43:23 +00:00
|
|
|
}
|
2018-05-18 12:21:19 +00:00
|
|
|
|
2004-03-31 09:07:39 +00:00
|
|
|
if (nonblock) {
|
2018-05-18 12:21:19 +00:00
|
|
|
pd->dag_flags |= DAGF_NONBLOCK;
|
2004-03-31 09:07:39 +00:00
|
|
|
} else {
|
2018-05-18 12:21:19 +00:00
|
|
|
pd->dag_flags &= ~DAGF_NONBLOCK;
|
2004-03-31 09:07:39 +00:00
|
|
|
}
|
|
|
|
return (0);
|
|
|
|
}
|
2017-02-12 07:04:44 +00:00
|
|
|
|
2004-03-31 09:07:39 +00:00
|
|
|
static int
|
|
|
|
dag_get_datalink(pcap_t *p)
|
|
|
|
{
|
2015-01-06 18:58:31 +00:00
|
|
|
struct pcap_dag *pd = p->priv;
|
2009-03-21 20:43:56 +00:00
|
|
|
int index=0, dlt_index=0;
|
2007-10-16 02:02:02 +00:00
|
|
|
uint8_t types[255];
|
2005-05-29 17:46:52 +00:00
|
|
|
|
2007-10-16 02:02:02 +00:00
|
|
|
memset(types, 0, 255);
|
|
|
|
|
|
|
|
if (p->dlt_list == NULL && (p->dlt_list = malloc(255*sizeof(*(p->dlt_list)))) == NULL) {
|
2018-05-18 12:21:19 +00:00
|
|
|
pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf),
|
|
|
|
errno, "malloc");
|
2005-05-29 17:46:52 +00:00
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
|
2007-10-16 02:02:02 +00:00
|
|
|
p->linktype = 0;
|
|
|
|
|
2009-03-21 20:43:56 +00:00
|
|
|
#ifdef HAVE_DAG_GET_STREAM_ERF_TYPES
|
|
|
|
/* Get list of possible ERF types for this card */
|
2015-01-06 18:58:31 +00:00
|
|
|
if (dag_get_stream_erf_types(p->fd, pd->dag_stream, types, 255) < 0) {
|
2018-05-18 12:21:19 +00:00
|
|
|
pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf),
|
|
|
|
errno, "dag_get_stream_erf_types");
|
2017-02-12 07:04:44 +00:00
|
|
|
return (-1);
|
2009-03-21 20:43:56 +00:00
|
|
|
}
|
2017-02-12 07:04:44 +00:00
|
|
|
|
2009-03-21 20:43:56 +00:00
|
|
|
while (types[index]) {
|
|
|
|
|
|
|
|
#elif defined HAVE_DAG_GET_ERF_TYPES
|
2007-10-16 02:02:02 +00:00
|
|
|
/* Get list of possible ERF types for this card */
|
|
|
|
if (dag_get_erf_types(p->fd, types, 255) < 0) {
|
2018-05-18 12:21:19 +00:00
|
|
|
pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf),
|
|
|
|
errno, "dag_get_erf_types");
|
2017-02-12 07:04:44 +00:00
|
|
|
return (-1);
|
2007-10-16 02:02:02 +00:00
|
|
|
}
|
2017-02-12 07:04:44 +00:00
|
|
|
|
2007-10-16 02:02:02 +00:00
|
|
|
while (types[index]) {
|
|
|
|
#else
|
2005-05-29 17:46:52 +00:00
|
|
|
/* Check the type through a dagapi call. */
|
2007-10-16 02:02:02 +00:00
|
|
|
types[index] = dag_linktype(p->fd);
|
2005-05-29 17:46:52 +00:00
|
|
|
|
2007-10-16 02:02:02 +00:00
|
|
|
{
|
|
|
|
#endif
|
2009-03-21 20:43:56 +00:00
|
|
|
switch((types[index] & 0x7f)) {
|
2005-05-29 17:46:52 +00:00
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
case ERF_TYPE_HDLC_POS:
|
|
|
|
case ERF_TYPE_COLOR_HDLC_POS:
|
|
|
|
case ERF_TYPE_DSM_COLOR_HDLC_POS:
|
|
|
|
case ERF_TYPE_COLOR_HASH_POS:
|
2009-03-21 20:43:56 +00:00
|
|
|
|
2007-10-16 02:02:02 +00:00
|
|
|
if (p->dlt_list != NULL) {
|
2009-03-21 20:43:56 +00:00
|
|
|
p->dlt_list[dlt_index++] = DLT_CHDLC;
|
|
|
|
p->dlt_list[dlt_index++] = DLT_PPP_SERIAL;
|
|
|
|
p->dlt_list[dlt_index++] = DLT_FRELAY;
|
2007-10-16 02:02:02 +00:00
|
|
|
}
|
|
|
|
if(!p->linktype)
|
|
|
|
p->linktype = DLT_CHDLC;
|
|
|
|
break;
|
2005-05-29 17:46:52 +00:00
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
case ERF_TYPE_ETH:
|
|
|
|
case ERF_TYPE_COLOR_ETH:
|
|
|
|
case ERF_TYPE_DSM_COLOR_ETH:
|
|
|
|
case ERF_TYPE_COLOR_HASH_ETH:
|
2007-10-16 02:02:02 +00:00
|
|
|
/*
|
|
|
|
* This is (presumably) a real Ethernet capture; give it a
|
|
|
|
* link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so
|
|
|
|
* that an application can let you choose it, in case you're
|
|
|
|
* capturing DOCSIS traffic that a Cisco Cable Modem
|
|
|
|
* Termination System is putting out onto an Ethernet (it
|
|
|
|
* doesn't put an Ethernet header onto the wire, it puts raw
|
|
|
|
* DOCSIS frames out on the wire inside the low-level
|
|
|
|
* Ethernet framing).
|
|
|
|
*/
|
|
|
|
if (p->dlt_list != NULL) {
|
2009-03-21 20:43:56 +00:00
|
|
|
p->dlt_list[dlt_index++] = DLT_EN10MB;
|
|
|
|
p->dlt_list[dlt_index++] = DLT_DOCSIS;
|
2007-10-16 02:02:02 +00:00
|
|
|
}
|
|
|
|
if(!p->linktype)
|
|
|
|
p->linktype = DLT_EN10MB;
|
|
|
|
break;
|
2005-05-29 17:46:52 +00:00
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
case ERF_TYPE_ATM:
|
|
|
|
case ERF_TYPE_AAL5:
|
|
|
|
case ERF_TYPE_MC_ATM:
|
|
|
|
case ERF_TYPE_MC_AAL5:
|
2007-10-16 02:02:02 +00:00
|
|
|
if (p->dlt_list != NULL) {
|
2009-03-21 20:43:56 +00:00
|
|
|
p->dlt_list[dlt_index++] = DLT_ATM_RFC1483;
|
|
|
|
p->dlt_list[dlt_index++] = DLT_SUNATM;
|
2007-10-16 02:02:02 +00:00
|
|
|
}
|
|
|
|
if(!p->linktype)
|
|
|
|
p->linktype = DLT_ATM_RFC1483;
|
|
|
|
break;
|
2005-05-29 17:46:52 +00:00
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
case ERF_TYPE_COLOR_MC_HDLC_POS:
|
|
|
|
case ERF_TYPE_MC_HDLC:
|
2007-10-16 02:02:02 +00:00
|
|
|
if (p->dlt_list != NULL) {
|
2009-03-21 20:43:56 +00:00
|
|
|
p->dlt_list[dlt_index++] = DLT_CHDLC;
|
|
|
|
p->dlt_list[dlt_index++] = DLT_PPP_SERIAL;
|
|
|
|
p->dlt_list[dlt_index++] = DLT_FRELAY;
|
|
|
|
p->dlt_list[dlt_index++] = DLT_MTP2;
|
|
|
|
p->dlt_list[dlt_index++] = DLT_MTP2_WITH_PHDR;
|
|
|
|
p->dlt_list[dlt_index++] = DLT_LAPD;
|
2007-10-16 02:02:02 +00:00
|
|
|
}
|
|
|
|
if(!p->linktype)
|
|
|
|
p->linktype = DLT_CHDLC;
|
|
|
|
break;
|
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
case ERF_TYPE_IPV4:
|
|
|
|
if (p->dlt_list != NULL) {
|
|
|
|
p->dlt_list[dlt_index++] = DLT_RAW;
|
|
|
|
p->dlt_list[dlt_index++] = DLT_IPV4;
|
|
|
|
}
|
2007-10-16 02:02:02 +00:00
|
|
|
if(!p->linktype)
|
2009-03-21 20:43:56 +00:00
|
|
|
p->linktype = DLT_RAW;
|
2007-10-16 02:02:02 +00:00
|
|
|
break;
|
|
|
|
|
2018-05-18 12:21:19 +00:00
|
|
|
case ERF_TYPE_IPV6:
|
|
|
|
if (p->dlt_list != NULL) {
|
|
|
|
p->dlt_list[dlt_index++] = DLT_RAW;
|
|
|
|
p->dlt_list[dlt_index++] = DLT_IPV6;
|
|
|
|
}
|
|
|
|
if(!p->linktype)
|
|
|
|
p->linktype = DLT_RAW;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case ERF_TYPE_LEGACY:
|
|
|
|
case ERF_TYPE_MC_RAW:
|
|
|
|
case ERF_TYPE_MC_RAW_CHANNEL:
|
|
|
|
case ERF_TYPE_IP_COUNTER:
|
|
|
|
case ERF_TYPE_TCP_FLOW_COUNTER:
|
|
|
|
case ERF_TYPE_INFINIBAND:
|
|
|
|
case ERF_TYPE_RAW_LINK:
|
|
|
|
case ERF_TYPE_INFINIBAND_LINK:
|
|
|
|
case ERF_TYPE_META:
|
2007-10-16 02:02:02 +00:00
|
|
|
default:
|
2009-03-21 20:43:56 +00:00
|
|
|
/* Libpcap cannot deal with these types yet */
|
Update libpcap to 1.1.1.
Changes:
Thu. April 1, 2010. guy@alum.mit.edu.
Summary for 1.1.1 libpcap release
Update CHANGES to reflect more of the changes in 1.1.0.
Fix build on RHEL5.
Fix shared library build on AIX.
Thu. March 11, 2010. ken@netfunctional.ca/guy@alum.mit.edu.
Summary for 1.1.0 libpcap release
Add SocketCAN capture support
Add Myricom SNF API support
Update Endace DAG and ERF support
Add support for shared libraries on Solaris, HP-UX, and AIX
Build, install, and un-install shared libraries by default;
don't build/install shared libraries on platforms we don't support
Fix building from a directory other than the source directory
Fix compiler warnings and builds on some platforms
Update config.guess and config.sub
Support monitor mode on mac80211 devices on Linux
Fix USB memory-mapped capturing on Linux; it requires a new DLT_
value
On Linux, scan /sys/class/net for devices if we have it; scan
it, or /proc/net/dev if we don't have /sys/class/net, even if
we have getifaddrs(), as it'll find interfaces with no
addresses
Add limited support for reading pcap-ng files
Fix BPF driver-loading error handling on AIX
Support getting the full-length interface description on FreeBSD
In the lexical analyzer, free up any addrinfo structure we got back
from getaddrinfo().
Add support for BPF and libdlpi in OpenSolaris (and SXCE)
Hyphenate "link-layer" everywhere
Add /sys/kernel/debug/usb/usbmon to the list of usbmon locations
In pcap_read_linux_mmap(), if there are no frames available, call
poll() even if we're in non-blocking mode, so we pick up
errors, and check for the errors in question.
Note that poll() works on BPF devices is Snow Leopard
If an ENXIO or ENETDOWN is received, it may mean the device has
gone away. Deal with it.
For BPF, raise the default capture buffer size to from 32k to 512k
Support ps_ifdrop on Linux
Added a bunch of #ifdef directives to make wpcap.dll (WinPcap) compile
under cygwin.
Changes to Linux mmapped captures.
Fix bug where create_ring would fail for particular snaplen and
buffer size combinations
Update pcap-config so that it handles libpcap requiring
additional libraries
Add workaround for threadsafeness on Windows
Add missing mapping for DLT_ENC <-> LINKTYPE_ENC
DLT: Add DLT_CAN_SOCKETCAN
DLT: Add Solaris ipnet
Don't check for DLT_IPNET if it's not defined
Add link-layer types for Fibre Channel FC-2
Add link-layer types for Wireless HART
Add link-layer types for AOS
Add link-layer types for DECT
Autoconf fixes (AIX, HP-UX, OSF/1, Tru64 cleanups)
Install headers unconditionally, and include vlan.h/bluetooth.h if
enabled
Autoconf fixes+cleanup
Support enabling/disabling bluetooth (--{en,dis}able-bluetooth)
Support disabling SITA support (--without-sita)
Return -1 on failure to create packet ring (if supported but
creation failed)
Fix handling of 'any' device, so that it can be opened, and no longer
attempt to open it in Monitor mode
Add support for snapshot length for USB Memory-Mapped Interface
Fix configure and build on recent Linux kernels
Fix memory-mapped Linux capture to support pcap_next() and
pcap_next_ex()
Fixes for Linux USB capture
DLT: Add DLT_LINUX_EVDEV
DLT: Add DLT_GSMTAP_UM
DLT: Add DLT_GSMTAP_ABIS
2010-10-28 16:22:13 +00:00
|
|
|
/* Add no 'native' DLTs, but still covered by DLT_ERF */
|
2009-03-21 20:43:56 +00:00
|
|
|
break;
|
2005-05-29 17:46:52 +00:00
|
|
|
|
2007-10-16 02:02:02 +00:00
|
|
|
} /* switch */
|
2009-03-21 20:43:56 +00:00
|
|
|
index++;
|
2005-05-29 17:46:52 +00:00
|
|
|
}
|
|
|
|
|
2009-03-21 20:43:56 +00:00
|
|
|
p->dlt_list[dlt_index++] = DLT_ERF;
|
|
|
|
|
|
|
|
p->dlt_count = dlt_index;
|
|
|
|
|
|
|
|
if(!p->linktype)
|
|
|
|
p->linktype = DLT_ERF;
|
2007-10-16 02:02:02 +00:00
|
|
|
|
2005-05-29 17:46:52 +00:00
|
|
|
return p->linktype;
|
2004-03-31 09:07:39 +00:00
|
|
|
}
|
2017-02-12 07:04:44 +00:00
|
|
|
|
|
|
|
#ifdef DAG_ONLY
|
|
|
|
/*
|
|
|
|
* This libpcap build supports only DAG cards, not regular network
|
|
|
|
* interfaces.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* There are no regular interfaces, just DAG interfaces.
|
|
|
|
*/
|
|
|
|
int
|
2018-05-18 12:21:19 +00:00
|
|
|
pcap_platform_finddevs(pcap_if_list_t *devlistp _U_, char *errbuf)
|
2017-02-12 07:04:44 +00:00
|
|
|
{
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Attempts to open a regular interface fail.
|
|
|
|
*/
|
|
|
|
pcap_t *
|
|
|
|
pcap_create_interface(const char *device, char *errbuf)
|
|
|
|
{
|
|
|
|
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
|
|
|
|
"This version of libpcap only supports DAG cards");
|
|
|
|
return NULL;
|
|
|
|
}
|
2018-05-18 12:21:19 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Libpcap version string.
|
|
|
|
*/
|
|
|
|
const char *
|
|
|
|
pcap_lib_version(void)
|
|
|
|
{
|
|
|
|
return (PCAP_VERSION_STRING " (DAG-only)");
|
|
|
|
}
|
2017-02-12 07:04:44 +00:00
|
|
|
#endif
|