2004-03-31 09:07:39 +00:00
|
|
|
/*
|
|
|
|
* pcap-dag.c: Packet capture interface for Endace DAG card.
|
|
|
|
*
|
|
|
|
* 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)
|
2006-09-04 19:43:23 +00:00
|
|
|
* Modifications: Jesper Peterson <support@endace.com>
|
|
|
|
* Koryn Grant <support@endace.com>
|
|
|
|
* Stephen Donnelly <support@endace.com>
|
2004-03-31 09:07:39 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef lint
|
|
|
|
static const char rcsid[] _U_ =
|
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
|
|
|
"@(#) $Header: /tcpdump/master/libpcap/pcap-dag.c,v 1.39 2008-04-14 20:40:58 guy Exp $ (LBL)";
|
2004-03-31 09:07:39 +00:00
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "config.h"
|
|
|
|
#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"
|
2004-03-31 09:07:39 +00:00
|
|
|
|
2009-03-21 20:43:56 +00:00
|
|
|
#include "pcap-dag.h"
|
|
|
|
|
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
|
|
|
|
|
|
|
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))
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef DAG_ONLY
|
|
|
|
/* This code is required when compiling for a DAG device only. */
|
|
|
|
|
|
|
|
/* Replace dag function names with pcap equivalent. */
|
2009-03-21 20:43:56 +00:00
|
|
|
#define dag_create pcap_create
|
2004-03-31 09:07:39 +00:00
|
|
|
#define dag_platform_finddevs pcap_platform_finddevs
|
|
|
|
#endif /* DAG_ONLY */
|
|
|
|
|
2007-10-16 02:02:02 +00:00
|
|
|
#define MAX_DAG_PACKET 65536
|
|
|
|
|
|
|
|
static unsigned char TempPkt[MAX_DAG_PACKET];
|
|
|
|
|
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);
|
|
|
|
static int dag_setnonblock(pcap_t *p, int nonblock, char *errbuf);
|
|
|
|
|
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
|
|
|
{
|
2006-09-04 19:43:23 +00:00
|
|
|
|
|
|
|
if (p != NULL) {
|
|
|
|
#ifdef HAVE_DAG_STREAMS_API
|
|
|
|
if(dag_stop_stream(p->fd, p->md.dag_stream) < 0)
|
|
|
|
fprintf(stderr,"dag_stop_stream: %s\n", strerror(errno));
|
2005-05-29 17:46:52 +00:00
|
|
|
|
2006-09-04 19:43:23 +00:00
|
|
|
if(dag_detach_stream(p->fd, p->md.dag_stream) < 0)
|
|
|
|
fprintf(stderr,"dag_detach_stream: %s\n", strerror(errno));
|
2004-03-31 09:07:39 +00:00
|
|
|
#else
|
2005-05-29 17:46:52 +00:00
|
|
|
if(dag_stop(p->fd) < 0)
|
|
|
|
fprintf(stderr,"dag_stop: %s\n", strerror(errno));
|
2006-09-04 19:43:23 +00:00
|
|
|
#endif /* HAVE_DAG_STREAMS_API */
|
2009-03-21 20:43:56 +00:00
|
|
|
if(p->fd != -1) {
|
|
|
|
if(dag_close(p->fd) < 0)
|
|
|
|
fprintf(stderr,"dag_close: %s\n", strerror(errno));
|
|
|
|
p->fd = -1;
|
|
|
|
}
|
|
|
|
delete_pcap_dag(p);
|
|
|
|
pcap_cleanup_live_common(p);
|
2006-09-04 19:43:23 +00:00
|
|
|
}
|
2005-05-29 17:46:52 +00:00
|
|
|
/* Note: don't need to call close(p->fd) here as dag_close(p->fd) 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()) {
|
2009-03-21 20:43:56 +00:00
|
|
|
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 {
|
|
|
|
|
|
|
|
/* sanity check we have enough bytes */
|
|
|
|
if ( len <= (24 + (hdr_num * 8)) )
|
|
|
|
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)
|
|
|
|
{
|
2004-03-31 09:07:39 +00:00
|
|
|
unsigned int processed = 0;
|
|
|
|
int flags = p->md.dag_offset_flags;
|
|
|
|
unsigned int nonblocking = flags & DAGF_NONBLOCK;
|
2009-03-21 20:43:56 +00:00
|
|
|
unsigned int num_ext_hdr = 0;
|
2004-03-31 09:07:39 +00:00
|
|
|
|
2006-09-04 19:43:23 +00:00
|
|
|
/* Get the next bufferful of packets (if necessary). */
|
|
|
|
while (p->md.dag_mem_top - p->md.dag_mem_bottom < dag_record_size) {
|
2004-03-31 09:07:39 +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
|
|
|
#ifdef HAVE_DAG_STREAMS_API
|
|
|
|
/* 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.
|
|
|
|
*/
|
2009-03-21 20:43:56 +00:00
|
|
|
if ( NULL == (p->md.dag_mem_top = dag_advance_stream(p->fd, p->md.dag_stream, &(p->md.dag_mem_bottom))) ) {
|
|
|
|
return -1;
|
|
|
|
}
|
2006-09-04 19:43:23 +00:00
|
|
|
#else
|
|
|
|
/* dag_offset does not support timeouts */
|
|
|
|
p->md.dag_mem_top = dag_offset(p->fd, &(p->md.dag_mem_bottom), flags);
|
|
|
|
#endif /* HAVE_DAG_STREAMS_API */
|
|
|
|
|
|
|
|
if (nonblocking && (p->md.dag_mem_top - p->md.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))
|
|
|
|
{
|
|
|
|
/* 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
|
|
|
|
|
|
|
}
|
2005-05-29 17:46:52 +00:00
|
|
|
|
2006-09-04 19:43:23 +00:00
|
|
|
/* Process the packets. */
|
|
|
|
while (p->md.dag_mem_top - p->md.dag_mem_bottom >= dag_record_size) {
|
2009-03-21 20:43:56 +00:00
|
|
|
|
2006-09-04 19:43:23 +00:00
|
|
|
unsigned short packet_len = 0;
|
|
|
|
int caplen = 0;
|
|
|
|
struct pcap_pkthdr pcap_header;
|
2009-03-21 20:43:56 +00:00
|
|
|
|
2006-09-04 19:43:23 +00:00
|
|
|
#ifdef HAVE_DAG_STREAMS_API
|
|
|
|
dag_record_t *header = (dag_record_t *)(p->md.dag_mem_bottom);
|
|
|
|
#else
|
|
|
|
dag_record_t *header = (dag_record_t *)(p->md.dag_mem_base + p->md.dag_mem_bottom);
|
|
|
|
#endif /* HAVE_DAG_STREAMS_API */
|
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;
|
2004-03-31 09:07:39 +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
|
|
|
rlen = ntohs(header->rlen);
|
|
|
|
if (rlen < dag_record_size)
|
|
|
|
{
|
|
|
|
strncpy(p->errbuf, "dag_read: record too small", PCAP_ERRBUF_SIZE);
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
p->md.dag_mem_bottom += rlen;
|
|
|
|
|
|
|
|
/* Count lost packets. */
|
2009-03-21 20:43:56 +00:00
|
|
|
switch((header->type & 0x7f)) {
|
|
|
|
/* in these types the color value overwrites the lctr */
|
2006-09-04 19:43:23 +00:00
|
|
|
case TYPE_COLOR_HDLC_POS:
|
|
|
|
case TYPE_COLOR_ETH:
|
2007-10-16 02:02:02 +00:00
|
|
|
case TYPE_DSM_COLOR_HDLC_POS:
|
|
|
|
case TYPE_DSM_COLOR_ETH:
|
|
|
|
case TYPE_COLOR_MC_HDLC_POS:
|
2009-03-21 20:43:56 +00:00
|
|
|
case TYPE_COLOR_HASH_ETH:
|
|
|
|
case TYPE_COLOR_HASH_POS:
|
2007-10-16 02:02:02 +00:00
|
|
|
break;
|
|
|
|
|
2006-09-04 19:43:23 +00:00
|
|
|
default:
|
2004-03-31 09:07:39 +00:00
|
|
|
if (header->lctr) {
|
2005-05-29 17:46:52 +00:00
|
|
|
if (p->md.stat.ps_drop > (UINT_MAX - ntohs(header->lctr))) {
|
2004-03-31 09:07:39 +00:00
|
|
|
p->md.stat.ps_drop = UINT_MAX;
|
|
|
|
} else {
|
2005-05-29 17:46:52 +00:00
|
|
|
p->md.stat.ps_drop += ntohs(header->lctr);
|
2004-03-31 09:07:39 +00:00
|
|
|
}
|
|
|
|
}
|
2006-09-04 19:43:23 +00:00
|
|
|
}
|
2009-03-21 20:43:56 +00:00
|
|
|
|
|
|
|
if ((header->type & 0x7f) == TYPE_PAD) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
num_ext_hdr = dag_erf_ext_header_count(dp, rlen);
|
|
|
|
|
|
|
|
/* ERF encapsulation */
|
|
|
|
/* The Extensible Record Format is not dropped for this kind of encapsulation,
|
|
|
|
* 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),
|
|
|
|
* o plus the length of the ERF header (dag_record_size), as the length of the
|
|
|
|
* 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)) {
|
|
|
|
case TYPE_MC_AAL5:
|
|
|
|
case TYPE_MC_ATM:
|
|
|
|
case TYPE_MC_HDLC:
|
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
|
|
|
case TYPE_MC_RAW_CHANNEL:
|
|
|
|
case TYPE_MC_RAW:
|
|
|
|
case TYPE_MC_AAL2:
|
|
|
|
case TYPE_COLOR_MC_HDLC_POS:
|
2009-03-21 20:43:56 +00:00
|
|
|
packet_len += 4; /* MC header */
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TYPE_COLOR_HASH_ETH:
|
|
|
|
case TYPE_DSM_COLOR_ETH:
|
|
|
|
case TYPE_COLOR_ETH:
|
|
|
|
case TYPE_ETH:
|
|
|
|
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;
|
|
|
|
|
|
|
|
switch((header->type & 0x7f)) {
|
|
|
|
case TYPE_ATM:
|
|
|
|
case TYPE_AAL5:
|
|
|
|
if (header->type == TYPE_AAL5) {
|
|
|
|
packet_len = ntohs(header->wlen);
|
|
|
|
caplen = rlen - dag_record_size;
|
|
|
|
}
|
|
|
|
case TYPE_MC_ATM:
|
|
|
|
if (header->type == TYPE_MC_ATM) {
|
|
|
|
caplen = packet_len = ATM_CELL_SIZE;
|
|
|
|
dp+=4;
|
|
|
|
}
|
|
|
|
case TYPE_MC_AAL5:
|
|
|
|
if (header->type == TYPE_MC_AAL5) {
|
|
|
|
packet_len = ntohs(header->wlen);
|
|
|
|
caplen = rlen - dag_record_size - 4;
|
|
|
|
dp+=4;
|
|
|
|
}
|
|
|
|
if (header->type == TYPE_ATM) {
|
|
|
|
caplen = packet_len = ATM_CELL_SIZE;
|
|
|
|
}
|
|
|
|
if (p->linktype == DLT_SUNATM) {
|
|
|
|
struct sunatm_hdr *sunatm = (struct sunatm_hdr *)dp;
|
|
|
|
unsigned long rawatm;
|
|
|
|
|
|
|
|
rawatm = ntohl(*((unsigned long *)dp));
|
|
|
|
sunatm->vci = htons((rawatm >> 4) & 0xffff);
|
|
|
|
sunatm->vpi = (rawatm >> 20) & 0x00ff;
|
|
|
|
sunatm->flags = ((header->flags.iface & 1) ? 0x80 : 0x00) |
|
|
|
|
((sunatm->vpi == 0 && sunatm->vci == htons(5)) ? 6 :
|
|
|
|
((sunatm->vpi == 0 && sunatm->vci == htons(16)) ? 5 :
|
|
|
|
((dp[ATM_HDR_SIZE] == 0xaa &&
|
|
|
|
dp[ATM_HDR_SIZE+1] == 0xaa &&
|
|
|
|
dp[ATM_HDR_SIZE+2] == 0x03) ? 2 : 1)));
|
|
|
|
|
|
|
|
} else {
|
|
|
|
packet_len -= ATM_HDR_SIZE;
|
|
|
|
caplen -= ATM_HDR_SIZE;
|
|
|
|
dp += ATM_HDR_SIZE;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TYPE_COLOR_HASH_ETH:
|
|
|
|
case TYPE_DSM_COLOR_ETH:
|
|
|
|
case TYPE_COLOR_ETH:
|
|
|
|
case TYPE_ETH:
|
|
|
|
packet_len = ntohs(header->wlen);
|
|
|
|
packet_len -= (p->md.dag_fcs_bits >> 3);
|
|
|
|
caplen = rlen - dag_record_size - 2;
|
|
|
|
if (caplen > packet_len) {
|
|
|
|
caplen = packet_len;
|
|
|
|
}
|
|
|
|
dp += 2;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TYPE_COLOR_HASH_POS:
|
|
|
|
case TYPE_DSM_COLOR_HDLC_POS:
|
|
|
|
case TYPE_COLOR_HDLC_POS:
|
|
|
|
case TYPE_HDLC_POS:
|
|
|
|
packet_len = ntohs(header->wlen);
|
|
|
|
packet_len -= (p->md.dag_fcs_bits >> 3);
|
|
|
|
caplen = rlen - dag_record_size;
|
|
|
|
if (caplen > packet_len) {
|
|
|
|
caplen = packet_len;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TYPE_COLOR_MC_HDLC_POS:
|
|
|
|
case TYPE_MC_HDLC:
|
|
|
|
packet_len = ntohs(header->wlen);
|
|
|
|
packet_len -= (p->md.dag_fcs_bits >> 3);
|
|
|
|
caplen = rlen - dag_record_size - 4;
|
|
|
|
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;
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
|
|
|
case TYPE_IPV4:
|
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
|
|
|
case TYPE_IPV6:
|
2009-03-21 20:43:56 +00:00
|
|
|
packet_len = ntohs(header->wlen);
|
|
|
|
caplen = rlen - dag_record_size;
|
|
|
|
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 */
|
|
|
|
case TYPE_MC_RAW:
|
|
|
|
case TYPE_MC_RAW_CHANNEL:
|
|
|
|
case TYPE_IP_COUNTER:
|
|
|
|
case TYPE_TCP_FLOW_COUNTER:
|
|
|
|
case TYPE_INFINIBAND:
|
|
|
|
case TYPE_RAW_LINK:
|
|
|
|
case TYPE_INFINIBAND_LINK:
|
2009-03-21 20:43:56 +00:00
|
|
|
default:
|
|
|
|
/* Unhandled ERF type.
|
|
|
|
* Ignore rather than generating error
|
|
|
|
*/
|
|
|
|
continue;
|
|
|
|
} /* switch type */
|
|
|
|
|
|
|
|
/* Skip over extension headers */
|
|
|
|
caplen -= (8 * num_ext_hdr);
|
|
|
|
|
|
|
|
} /* ERF encapsulation */
|
|
|
|
|
|
|
|
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)) {
|
2009-03-21 20:43:56 +00:00
|
|
|
|
2006-09-04 19:43:23 +00:00
|
|
|
/* convert between timestamp formats */
|
|
|
|
register unsigned long long ts;
|
2004-03-31 09:07:39 +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
|
|
|
|
2006-09-04 19:43:23 +00:00
|
|
|
pcap_header.ts.tv_sec = ts >> 32;
|
|
|
|
ts = (ts & 0xffffffffULL) * 1000000;
|
|
|
|
ts += 0x80000000; /* rounding */
|
|
|
|
pcap_header.ts.tv_usec = ts >> 32;
|
|
|
|
if (pcap_header.ts.tv_usec >= 1000000) {
|
|
|
|
pcap_header.ts.tv_usec -= 1000000;
|
|
|
|
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;
|
2005-05-29 17:46:52 +00:00
|
|
|
|
2006-09-04 19:43:23 +00:00
|
|
|
/* Count the packet. */
|
|
|
|
p->md.stat.ps_recv++;
|
2005-05-29 17:46:52 +00:00
|
|
|
|
2006-09-04 19:43:23 +00:00
|
|
|
/* Call the user supplied callback function */
|
|
|
|
callback(user, &pcap_header, dp);
|
2005-05-29 17:46:52 +00:00
|
|
|
|
2006-09-04 19:43:23 +00:00
|
|
|
/* Only count packets that pass the filter, for consistency with standard Linux behaviour. */
|
|
|
|
processed++;
|
2009-03-21 20:43:56 +00:00
|
|
|
if (processed == cnt && cnt > 0)
|
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.
|
2004-03-31 09:07:39 +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).
|
|
|
|
*/
|
2009-03-21 20:43:56 +00:00
|
|
|
static int dag_activate(pcap_t* handle)
|
2005-05-29 17:46:52 +00:00
|
|
|
{
|
2009-03-21 20:43:56 +00:00
|
|
|
#if 0
|
2005-05-29 17:46:52 +00:00
|
|
|
char conf[30]; /* dag configure string */
|
2009-03-21 20:43:56 +00:00
|
|
|
#endif
|
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;
|
2009-03-21 20:43:56 +00:00
|
|
|
char * device = handle->opt.source;
|
2006-09-04 19:43:23 +00:00
|
|
|
#ifdef HAVE_DAG_STREAMS_API
|
|
|
|
uint32_t mindata;
|
|
|
|
struct timeval maxwait;
|
|
|
|
struct timeval poll;
|
|
|
|
#endif
|
|
|
|
|
2005-05-29 17:46:52 +00:00
|
|
|
if (device == NULL) {
|
2009-03-21 20:43:56 +00:00
|
|
|
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "device is NULL: %s", pcap_strerror(errno));
|
|
|
|
return -1;
|
2005-05-29 17:46:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Initialize some components of the pcap structure. */
|
|
|
|
|
2006-09-04 19:43:23 +00:00
|
|
|
#ifdef HAVE_DAG_STREAMS_API
|
2007-10-16 02:02:02 +00:00
|
|
|
newDev = (char *)malloc(strlen(device) + 16);
|
|
|
|
if (newDev == NULL) {
|
2009-03-21 20:43:56 +00:00
|
|
|
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't allocate string for device name: %s\n", pcap_strerror(errno));
|
2007-10-16 02:02:02 +00:00
|
|
|
goto fail;
|
|
|
|
}
|
2006-09-04 19:43:23 +00:00
|
|
|
|
|
|
|
/* 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) {
|
2009-03-21 20:43:56 +00:00
|
|
|
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_parse_name: %s\n", pcap_strerror(errno));
|
2006-09-04 19:43:23 +00:00
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
device = newDev;
|
|
|
|
|
|
|
|
if (handle->md.dag_stream%2) {
|
2009-03-21 20:43:56 +00:00
|
|
|
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_parse_name: tx (even numbered) streams not supported for capture\n");
|
2006-09-04 19:43:23 +00:00
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
#else
|
2007-10-16 02:02:02 +00:00
|
|
|
if (strncmp(device, "/dev/", 5) != 0) {
|
|
|
|
newDev = (char *)malloc(strlen(device) + 5);
|
|
|
|
if (newDev == NULL) {
|
2009-03-21 20:43:56 +00:00
|
|
|
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "Can't allocate string for device name: %s\n", pcap_strerror(errno));
|
2007-10-16 02:02:02 +00:00
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
strcpy(newDev, "/dev/");
|
|
|
|
strcat(newDev, device);
|
2005-05-29 17:46:52 +00:00
|
|
|
device = newDev;
|
|
|
|
}
|
2006-09-04 19:43:23 +00:00
|
|
|
#endif /* HAVE_DAG_STREAMS_API */
|
2005-05-29 17:46:52 +00:00
|
|
|
|
|
|
|
/* setup device parameters */
|
|
|
|
if((handle->fd = dag_open((char *)device)) < 0) {
|
2009-03-21 20:43:56 +00:00
|
|
|
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_open %s: %s", device, pcap_strerror(errno));
|
2005-05-29 17:46:52 +00:00
|
|
|
goto fail;
|
|
|
|
}
|
|
|
|
|
2006-09-04 19:43:23 +00:00
|
|
|
#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) {
|
2009-03-21 20:43:56 +00:00
|
|
|
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_attach_stream: %s\n", pcap_strerror(errno));
|
2007-10-16 02:02:02 +00:00
|
|
|
goto failclose;
|
2006-09-04 19:43:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* 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,
|
|
|
|
&mindata, &maxwait, &poll) < 0) {
|
2009-03-21 20:43:56 +00:00
|
|
|
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_get_stream_poll: %s\n", pcap_strerror(errno));
|
2007-10-16 02:02:02 +00:00
|
|
|
goto faildetach;
|
2006-09-04 19:43:23 +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!
|
|
|
|
*/
|
|
|
|
mindata = 65536;
|
|
|
|
|
2009-03-21 20:43:56 +00:00
|
|
|
/* Obey md.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.
|
|
|
|
*/
|
2009-03-21 20:43:56 +00:00
|
|
|
maxwait.tv_sec = handle->md.timeout/1000;
|
|
|
|
maxwait.tv_usec = (handle->md.timeout%1000) * 1000;
|
2006-09-04 19:43:23 +00:00
|
|
|
|
|
|
|
if (dag_set_stream_poll(handle->fd, handle->md.dag_stream,
|
|
|
|
mindata, &maxwait, &poll) < 0) {
|
2009-03-21 20:43:56 +00:00
|
|
|
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_set_stream_poll: %s\n", pcap_strerror(errno));
|
2007-10-16 02:02:02 +00:00
|
|
|
goto faildetach;
|
2006-09-04 19:43:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#else
|
|
|
|
if((handle->md.dag_mem_base = dag_mmap(handle->fd)) == MAP_FAILED) {
|
2009-03-21 20:43:56 +00:00
|
|
|
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,"dag_mmap %s: %s\n", device, pcap_strerror(errno));
|
2007-10-16 02:02:02 +00:00
|
|
|
goto failclose;
|
2006-09-04 19:43:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* HAVE_DAG_STREAMS_API */
|
|
|
|
|
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. */
|
2009-03-21 20:43:56 +00:00
|
|
|
if (handle->snapshot == 0 || handle->snapshot > MAX_DAG_SNAPLEN) {
|
|
|
|
handle->snapshot = MAX_DAG_SNAPLEN;
|
2005-05-29 17:46:52 +00:00
|
|
|
} else if (snaplen < MIN_DAG_SNAPLEN) {
|
2009-03-21 20:43:56 +00:00
|
|
|
handle->snapshot = MIN_DAG_SNAPLEN;
|
2005-05-29 17:46:52 +00:00
|
|
|
}
|
|
|
|
/* snap len has to be a multiple of 4 */
|
|
|
|
snprintf(conf, 30, "varlen slen=%d", (snaplen + 3) & ~3);
|
|
|
|
|
|
|
|
if(dag_configure(handle->fd, conf) < 0) {
|
2009-03-21 20:43:56 +00:00
|
|
|
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,"dag_configure %s: %s\n", device, pcap_strerror(errno));
|
2007-10-16 02:02:02 +00:00
|
|
|
goto faildetach;
|
2005-05-29 17:46:52 +00:00
|
|
|
}
|
2007-10-16 02:02:02 +00:00
|
|
|
#endif
|
|
|
|
|
2006-09-04 19:43:23 +00:00
|
|
|
#ifdef HAVE_DAG_STREAMS_API
|
|
|
|
if(dag_start_stream(handle->fd, handle->md.dag_stream) < 0) {
|
2009-03-21 20:43:56 +00:00
|
|
|
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_start_stream %s: %s\n", device, pcap_strerror(errno));
|
2007-10-16 02:02:02 +00:00
|
|
|
goto faildetach;
|
2005-05-29 17:46:52 +00:00
|
|
|
}
|
2006-09-04 19:43:23 +00:00
|
|
|
#else
|
2005-05-29 17:46:52 +00:00
|
|
|
if(dag_start(handle->fd) < 0) {
|
2009-03-21 20:43:56 +00:00
|
|
|
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "dag_start %s: %s\n", device, pcap_strerror(errno));
|
2007-10-16 02:02:02 +00:00
|
|
|
goto failclose;
|
2005-05-29 17:46:52 +00:00
|
|
|
}
|
2006-09-04 19:43:23 +00:00
|
|
|
#endif /* HAVE_DAG_STREAMS_API */
|
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!
|
|
|
|
*/
|
|
|
|
handle->md.dag_mem_bottom = 0;
|
|
|
|
handle->md.dag_mem_top = 0;
|
|
|
|
|
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.
|
|
|
|
*/
|
2005-05-29 17:46:52 +00:00
|
|
|
daginf = dag_info(handle->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. */
|
|
|
|
handle->md.dag_fcs_bits = 0;
|
|
|
|
|
2009-03-21 20:43:56 +00:00
|
|
|
/* Note that no FCS will be supplied. */
|
|
|
|
handle->linktype_ext = LT_FCS_DATALINK_EXT(0);
|
|
|
|
} else {
|
|
|
|
/*
|
|
|
|
* Start out assuming it's 32 bits.
|
|
|
|
*/
|
|
|
|
handle->md.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;
|
|
|
|
} else {
|
|
|
|
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
|
|
|
"pcap_activate %s: bad ERF_FCS_BITS value (%d) in environment\n", device, n);
|
|
|
|
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. */
|
|
|
|
handle->linktype_ext = LT_FCS_DATALINK_EXT(handle->md.dag_fcs_bits/16);
|
|
|
|
|
|
|
|
/* And don't strip them. */
|
|
|
|
handle->md.dag_fcs_bits = 0;
|
2005-05-29 17:46:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-03-21 20:43:56 +00:00
|
|
|
handle->md.dag_timeout = handle->md.timeout;
|
2005-05-29 17:46:52 +00:00
|
|
|
|
|
|
|
handle->linktype = -1;
|
2009-03-21 20:43:56 +00:00
|
|
|
if (dag_get_datalink(handle) < 0)
|
2007-10-16 02:02:02 +00:00
|
|
|
goto failstop;
|
2005-05-29 17:46:52 +00:00
|
|
|
|
|
|
|
handle->bufsize = 0;
|
|
|
|
|
|
|
|
if (new_pcap_dag(handle) < 0) {
|
2009-03-21 20:43:56 +00:00
|
|
|
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, "new_pcap_dag %s: %s\n", device, pcap_strerror(errno));
|
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
|
|
|
*/
|
|
|
|
handle->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
|
|
|
|
2005-05-29 17:46:52 +00:00
|
|
|
handle->read_op = dag_read;
|
|
|
|
handle->inject_op = dag_inject;
|
|
|
|
handle->setfilter_op = dag_setfilter;
|
2005-07-11 03:24:53 +00:00
|
|
|
handle->setdirection_op = NULL; /* Not implemented.*/
|
2005-05-29 17:46:52 +00:00
|
|
|
handle->set_datalink_op = dag_set_datalink;
|
|
|
|
handle->getnonblock_op = pcap_getnonblock_fd;
|
|
|
|
handle->setnonblock_op = dag_setnonblock;
|
|
|
|
handle->stats_op = dag_stats;
|
2009-03-21 20:43:56 +00:00
|
|
|
handle->cleanup_op = dag_platform_cleanup;
|
2007-10-16 02:02:02 +00:00
|
|
|
handle->md.stat.ps_drop = 0;
|
|
|
|
handle->md.stat.ps_recv = 0;
|
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
|
|
|
handle->md.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
|
|
|
#ifdef HAVE_DAG_STREAMS_API
|
|
|
|
failstop:
|
2009-03-21 20:43:56 +00:00
|
|
|
if (dag_stop_stream(handle->fd, handle->md.dag_stream) < 0) {
|
|
|
|
fprintf(stderr,"dag_stop_stream: %s\n", strerror(errno));
|
2007-10-16 02:02:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
faildetach:
|
2009-03-21 20:43:56 +00:00
|
|
|
if (dag_detach_stream(handle->fd, handle->md.dag_stream) < 0)
|
|
|
|
fprintf(stderr,"dag_detach_stream: %s\n", strerror(errno));
|
|
|
|
#else
|
2007-10-16 02:02:02 +00:00
|
|
|
failstop:
|
2009-03-21 20:43:56 +00:00
|
|
|
if (dag_stop(handle->fd) < 0)
|
|
|
|
fprintf(stderr,"dag_stop: %s\n", strerror(errno));
|
2007-10-16 02:02:02 +00:00
|
|
|
#endif /* HAVE_DAG_STREAMS_API */
|
|
|
|
|
|
|
|
failclose:
|
2009-03-21 20:43:56 +00:00
|
|
|
if (dag_close(handle->fd) < 0)
|
|
|
|
fprintf(stderr,"dag_close: %s\n", strerror(errno));
|
|
|
|
delete_pcap_dag(handle);
|
|
|
|
|
2004-03-31 09:07:39 +00:00
|
|
|
fail:
|
2009-03-21 20:43:56 +00:00
|
|
|
pcap_cleanup_live_common(handle);
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
pcap_t *dag_create(const char *device, char *ebuf)
|
|
|
|
{
|
|
|
|
pcap_t *p;
|
|
|
|
|
|
|
|
p = pcap_create_common(device, ebuf);
|
|
|
|
if (p == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
p->activate_op = dag_activate;
|
|
|
|
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) {
|
|
|
|
/* 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;*/
|
|
|
|
|
|
|
|
*ps = p->md.stat;
|
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
|
|
|
* Previously we just generated a list of all possible names and let
|
|
|
|
* pcap_add_if() attempt to open each one, but with streams this adds up
|
|
|
|
* to 81 possibilities which is inefficient.
|
|
|
|
*
|
|
|
|
* Since we know more about the devices we can prune the tree here.
|
|
|
|
* pcap_add_if() will still retest each device but the total number of
|
|
|
|
* open attempts will still be much less than the naive approach.
|
2004-03-31 09:07:39 +00:00
|
|
|
*/
|
|
|
|
int
|
|
|
|
dag_platform_finddevs(pcap_if_t **devlistp, char *errbuf)
|
|
|
|
{
|
2006-09-04 19:43:23 +00:00
|
|
|
char name[12]; /* XXX - pick a size */
|
2005-05-29 17:46:52 +00:00
|
|
|
int ret = 0;
|
2006-09-04 19:43:23 +00:00
|
|
|
int c;
|
2009-03-21 20:43:56 +00:00
|
|
|
char dagname[DAGNAME_BUFSIZE];
|
|
|
|
int dagstream;
|
|
|
|
int dagfd;
|
2005-05-29 17:46:52 +00:00
|
|
|
|
2006-09-04 19:43:23 +00:00
|
|
|
/* Try all the DAGs 0-9 */
|
|
|
|
for (c = 0; c < 9; c++) {
|
|
|
|
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
|
|
|
{
|
2009-03-21 20:43:56 +00:00
|
|
|
return -1;
|
2005-05-29 17:46:52 +00:00
|
|
|
}
|
2009-03-21 20:43:56 +00:00
|
|
|
if ( (dagfd = dag_open(dagname)) >= 0 ) {
|
|
|
|
if (pcap_add_if(devlistp, name, 0, NULL, errbuf) == -1) {
|
|
|
|
/*
|
|
|
|
* Failure.
|
|
|
|
*/
|
|
|
|
ret = -1;
|
|
|
|
}
|
|
|
|
#ifdef HAVE_DAG_STREAMS_API
|
|
|
|
{
|
|
|
|
int stream, rxstreams;
|
|
|
|
rxstreams = dag_rx_get_stream_count(dagfd);
|
|
|
|
for(stream=0;stream<16;stream+=2) {
|
|
|
|
if (0 == dag_attach_stream(dagfd, stream, 0, 0)) {
|
|
|
|
dag_detach_stream(dagfd, stream);
|
|
|
|
|
|
|
|
snprintf(name, 10, "dag%d:%d", c, stream);
|
|
|
|
if (pcap_add_if(devlistp, name, 0, NULL, errbuf) == -1) {
|
|
|
|
/*
|
|
|
|
* Failure.
|
|
|
|
*/
|
|
|
|
ret = -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2006-09-04 19:43:23 +00:00
|
|
|
#endif /* HAVE_DAG_STREAMS_API */
|
2009-03-21 20:43:56 +00:00
|
|
|
dag_close(dagfd);
|
|
|
|
}
|
|
|
|
|
2005-05-29 17:46:52 +00:00
|
|
|
}
|
|
|
|
return (ret);
|
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;
|
|
|
|
|
|
|
|
p->md.use_bpf = 0;
|
|
|
|
|
|
|
|
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
|
|
|
|
dag_setnonblock(pcap_t *p, int nonblock, char *errbuf)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* 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".
|
|
|
|
*/
|
|
|
|
if (pcap_setnonblock_fd(p, nonblock, errbuf) < 0)
|
|
|
|
return (-1);
|
2006-09-04 19:43:23 +00:00
|
|
|
#ifdef HAVE_DAG_STREAMS_API
|
|
|
|
{
|
|
|
|
uint32_t mindata;
|
|
|
|
struct timeval maxwait;
|
|
|
|
struct timeval poll;
|
|
|
|
|
|
|
|
if (dag_get_stream_poll(p->fd, p->md.dag_stream,
|
|
|
|
&mindata, &maxwait, &poll) < 0) {
|
|
|
|
snprintf(errbuf, PCAP_ERRBUF_SIZE, "dag_get_stream_poll: %s\n", pcap_strerror(errno));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* 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_poll(p->fd, p->md.dag_stream,
|
|
|
|
mindata, &maxwait, &poll) < 0) {
|
|
|
|
snprintf(errbuf, PCAP_ERRBUF_SIZE, "dag_set_stream_poll: %s\n", pcap_strerror(errno));
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif /* HAVE_DAG_STREAMS_API */
|
2004-03-31 09:07:39 +00:00
|
|
|
if (nonblock) {
|
|
|
|
p->md.dag_offset_flags |= DAGF_NONBLOCK;
|
|
|
|
} else {
|
|
|
|
p->md.dag_offset_flags &= ~DAGF_NONBLOCK;
|
|
|
|
}
|
|
|
|
return (0);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int
|
|
|
|
dag_get_datalink(pcap_t *p)
|
|
|
|
{
|
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) {
|
2005-05-29 17:46:52 +00:00
|
|
|
(void)snprintf(p->errbuf, sizeof(p->errbuf), "malloc: %s", pcap_strerror(errno));
|
|
|
|
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 */
|
|
|
|
if (dag_get_stream_erf_types(p->fd, p->md.dag_stream, types, 255) < 0) {
|
|
|
|
snprintf(p->errbuf, sizeof(p->errbuf), "dag_get_stream_erf_types: %s", pcap_strerror(errno));
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
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) {
|
|
|
|
snprintf(p->errbuf, sizeof(p->errbuf), "dag_get_erf_types: %s", pcap_strerror(errno));
|
|
|
|
return (-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
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
|
|
|
|
2007-10-16 02:02:02 +00:00
|
|
|
case TYPE_HDLC_POS:
|
|
|
|
case TYPE_COLOR_HDLC_POS:
|
|
|
|
case TYPE_DSM_COLOR_HDLC_POS:
|
2009-03-21 20:43:56 +00:00
|
|
|
case TYPE_COLOR_HASH_POS:
|
|
|
|
|
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
|
|
|
|
2007-10-16 02:02:02 +00:00
|
|
|
case TYPE_ETH:
|
|
|
|
case TYPE_COLOR_ETH:
|
|
|
|
case TYPE_DSM_COLOR_ETH:
|
2009-03-21 20:43:56 +00:00
|
|
|
case 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
|
|
|
|
2007-10-16 02:02:02 +00:00
|
|
|
case TYPE_ATM:
|
|
|
|
case TYPE_AAL5:
|
|
|
|
case TYPE_MC_ATM:
|
|
|
|
case TYPE_MC_AAL5:
|
|
|
|
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
|
|
|
|
2007-10-16 02:02:02 +00:00
|
|
|
case TYPE_COLOR_MC_HDLC_POS:
|
|
|
|
case TYPE_MC_HDLC:
|
|
|
|
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;
|
|
|
|
|
2009-03-21 20:43:56 +00:00
|
|
|
case TYPE_IPV4:
|
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
|
|
|
case TYPE_IPV6:
|
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;
|
|
|
|
|
2009-03-21 20:43:56 +00:00
|
|
|
case TYPE_LEGACY:
|
|
|
|
case TYPE_MC_RAW:
|
|
|
|
case TYPE_MC_RAW_CHANNEL:
|
|
|
|
case TYPE_IP_COUNTER:
|
|
|
|
case TYPE_TCP_FLOW_COUNTER:
|
|
|
|
case TYPE_INFINIBAND:
|
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
|
|
|
case TYPE_RAW_LINK:
|
|
|
|
case TYPE_INFINIBAND_LINK:
|
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
|
|
|
}
|