dect
/
libpcap
Archived
13
0
Fork 0

Add support for setting the time stamp type for a capture.

Based on a patch from Scott Mcmillan <scott.a.mcmillan@intel.com>.

(Second part of the commit.)
This commit is contained in:
Guy Harris 2010-08-22 17:36:27 -07:00
parent 749726f92c
commit fa4435e65c
10 changed files with 596 additions and 103 deletions

3
.gitignore vendored
View File

@ -19,13 +19,16 @@ pcap-config
pcap-filter.manmisc pcap-filter.manmisc
pcap-linktype.manmisc pcap-linktype.manmisc
pcap-savefile.manfile pcap-savefile.manfile
pcap-tstamp.manmisc
pcap.3pcap pcap.3pcap
pcap_compile.3pcap pcap_compile.3pcap
pcap_datalink.3pcap pcap_datalink.3pcap
pcap_dump_open.3pcap pcap_dump_open.3pcap
pcap_list_datalinks.3pcap pcap_list_datalinks.3pcap
pcap_list_tstamp_types.3pcap
pcap_open_dead.3pcap pcap_open_dead.3pcap
pcap_open_offline.3pcap pcap_open_offline.3pcap
pcap_set_tstamp_type.3pcap
scanner.c scanner.c
scanner.h scanner.h
selpolltest selpolltest

View File

@ -157,8 +157,10 @@ MAN3PCAP_EXPAND = \
pcap_datalink.3pcap.in \ pcap_datalink.3pcap.in \
pcap_dump_open.3pcap.in \ pcap_dump_open.3pcap.in \
pcap_list_datalinks.3pcap.in \ pcap_list_datalinks.3pcap.in \
pcap_list_tstamp_types.3pcap.in \
pcap_open_dead.3pcap.in \ pcap_open_dead.3pcap.in \
pcap_open_offline.3pcap.in pcap_open_offline.3pcap.in \
pcap_set_tstamp_type.3pcap.in
MAN3PCAP_NOEXPAND = \ MAN3PCAP_NOEXPAND = \
pcap_activate.3pcap \ pcap_activate.3pcap \
@ -201,7 +203,9 @@ MAN3PCAP_NOEXPAND = \
pcap_snapshot.3pcap \ pcap_snapshot.3pcap \
pcap_stats.3pcap \ pcap_stats.3pcap \
pcap_statustostr.3pcap \ pcap_statustostr.3pcap \
pcap_strerror.3pcap pcap_strerror.3pcap \
pcap_tstamp_type_name_to_val.3pcap \
pcap_tstamp_type_val_to_name.3pcap
MAN3PCAP = $(MAN3PCAP_NOEXPAND) $(MAN3PCAP_EXPAND:.in=) MAN3PCAP = $(MAN3PCAP_NOEXPAND) $(MAN3PCAP_EXPAND:.in=)
@ -210,7 +214,8 @@ MANFILE = \
MANMISC = \ MANMISC = \
pcap-filter.manmisc.in \ pcap-filter.manmisc.in \
pcap-linktype.manmisc.in pcap-linktype.manmisc.in \
pcap-tstamp.manmisc.in
EXTRA_DIST = \ EXTRA_DIST = \
$(TESTS_SRC) \ $(TESTS_SRC) \
@ -561,6 +566,9 @@ install: install-shared install-archive pcap-config
rm -f $(DESTDIR)$(mandir)/man3/pcap_free_datalinks.3pcap rm -f $(DESTDIR)$(mandir)/man3/pcap_free_datalinks.3pcap
ln $(DESTDIR)$(mandir)/man3/pcap_list_datalinks.3pcap \ ln $(DESTDIR)$(mandir)/man3/pcap_list_datalinks.3pcap \
$(DESTDIR)$(mandir)/man3/pcap_free_datalinks.3pcap $(DESTDIR)$(mandir)/man3/pcap_free_datalinks.3pcap
rm -f $(DESTDIR)$(mandir)/man3/pcap_free_tstamp_types.3pcap
ln $(DESTDIR)$(mandir)/man3/pcap_list_tstamp_types.3pcap \
$(DESTDIR)$(mandir)/man3/pcap_free_tstamp_types.3pcap
rm -f $(DESTDIR)$(mandir)/man3/pcap_dispatch.3pcap rm -f $(DESTDIR)$(mandir)/man3/pcap_dispatch.3pcap
ln $(DESTDIR)$(mandir)/man3/pcap_loop.3pcap \ ln $(DESTDIR)$(mandir)/man3/pcap_loop.3pcap \
$(DESTDIR)$(mandir)/man3/pcap_dispatch.3pcap $(DESTDIR)$(mandir)/man3/pcap_dispatch.3pcap
@ -648,6 +656,7 @@ uninstall: uninstall-shared
rm -f $(DESTDIR)$(mandir)/man3/pcap_perror.3pcap rm -f $(DESTDIR)$(mandir)/man3/pcap_perror.3pcap
rm -f $(DESTDIR)$(mandir)/man3/pcap_sendpacket.3pcap rm -f $(DESTDIR)$(mandir)/man3/pcap_sendpacket.3pcap
rm -f $(DESTDIR)$(mandir)/man3/pcap_free_datalinks.3pcap rm -f $(DESTDIR)$(mandir)/man3/pcap_free_datalinks.3pcap
rm -f $(DESTDIR)$(mandir)/man3/pcap_free_tstamp_types.3pcap
rm -f $(DESTDIR)$(mandir)/man3/pcap_dispatch.3pcap rm -f $(DESTDIR)$(mandir)/man3/pcap_dispatch.3pcap
rm -f $(DESTDIR)$(mandir)/man3/pcap_minor_version.3pcap rm -f $(DESTDIR)$(mandir)/man3/pcap_minor_version.3pcap
rm -f $(DESTDIR)$(mandir)/man3/pcap_next.3pcap rm -f $(DESTDIR)$(mandir)/man3/pcap_next.3pcap

View File

@ -55,6 +55,9 @@
/* Define to 1 if you have the <limits.h> header file. */ /* Define to 1 if you have the <limits.h> header file. */
#undef HAVE_LIMITS_H #undef HAVE_LIMITS_H
/* Define to 1 if you have the <linux/net_tstamp.h> header file. */
#undef HAVE_LINUX_NET_TSTAMP_H
/* if tp_vlan_tci exists */ /* if tp_vlan_tci exists */
#undef HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI #undef HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI

154
configure vendored
View File

@ -10787,6 +10787,155 @@ echo "$as_me: no CAN sniffing support implemented for $host_os" >&6;}
fi fi
case "$host_os" in
linux*)
for ac_header in linux/net_tstamp.h
do
as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
{ echo "$as_me:$LINENO: checking for $ac_header" >&5
echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
echo $ECHO_N "(cached) $ECHO_C" >&6
fi
ac_res=`eval echo '${'$as_ac_Header'}'`
{ echo "$as_me:$LINENO: result: $ac_res" >&5
echo "${ECHO_T}$ac_res" >&6; }
else
# Is the header compilable?
{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
$ac_includes_default
#include <$ac_header>
_ACEOF
rm -f conftest.$ac_objext
if { (ac_try="$ac_compile"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_compile") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } && {
test -z "$ac_c_werror_flag" ||
test ! -s conftest.err
} && test -s conftest.$ac_objext; then
ac_header_compiler=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_header_compiler=no
fi
rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
echo "${ECHO_T}$ac_header_compiler" >&6; }
# Is the header present?
{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h. */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <$ac_header>
_ACEOF
if { (ac_try="$ac_cpp conftest.$ac_ext"
case "(($ac_try" in
*\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
*) ac_try_echo=$ac_try;;
esac
eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
(eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
ac_status=$?
grep -v '^ *+' conftest.er1 >conftest.err
rm -f conftest.er1
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } >/dev/null && {
test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
test ! -s conftest.err
}; then
ac_header_preproc=yes
else
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
ac_header_preproc=no
fi
rm -f conftest.err conftest.$ac_ext
{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
echo "${ECHO_T}$ac_header_preproc" >&6; }
# So? What about this header?
case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
yes:no: )
{ echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
ac_header_preproc=yes
;;
no:yes:* )
{ echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
{ echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
;;
esac
{ echo "$as_me:$LINENO: checking for $ac_header" >&5
echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
echo $ECHO_N "(cached) $ECHO_C" >&6
else
eval "$as_ac_Header=\$ac_header_preproc"
fi
ac_res=`eval echo '${'$as_ac_Header'}'`
{ echo "$as_me:$LINENO: result: $ac_res" >&5
echo "${ECHO_T}$ac_res" >&6; }
fi
if test `eval echo '${'$as_ac_Header'}'` = yes; then
cat >>confdefs.h <<_ACEOF
#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
_ACEOF
fi
done
;;
*)
{ echo "$as_me:$LINENO: no hardware timestamp support implemented for $host_os" >&5
echo "$as_me: no hardware timestamp support implemented for $host_os" >&6;}
;;
esac
# Find a good install program. We prefer a C program (faster), # Find a good install program. We prefer a C program (faster),
# so one script is as good as another. But avoid the broken or # so one script is as good as another. But avoid the broken or
# incompatible versions: # incompatible versions:
@ -10871,7 +11020,7 @@ test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
ac_config_headers="$ac_config_headers config.h" ac_config_headers="$ac_config_headers config.h"
ac_config_files="$ac_config_files Makefile pcap-filter.manmisc pcap-linktype.manmisc pcap-savefile.manfile pcap.3pcap pcap_compile.3pcap pcap_datalink.3pcap pcap_dump_open.3pcap pcap_list_datalinks.3pcap pcap_open_dead.3pcap pcap_open_offline.3pcap" ac_config_files="$ac_config_files Makefile pcap-filter.manmisc pcap-linktype.manmisc pcap-tstamp.manmisc pcap-savefile.manfile pcap.3pcap pcap_compile.3pcap pcap_datalink.3pcap pcap_dump_open.3pcap pcap_list_datalinks.3pcap pcap_list_tstamp_types.3pcap pcap_open_dead.3pcap pcap_open_offline.3pcap pcap_set_tstamp_type.3pcap"
cat >confcache <<\_ACEOF cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure # This file is a shell script that caches the results of configure
@ -11430,14 +11579,17 @@ do
"Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
"pcap-filter.manmisc") CONFIG_FILES="$CONFIG_FILES pcap-filter.manmisc" ;; "pcap-filter.manmisc") CONFIG_FILES="$CONFIG_FILES pcap-filter.manmisc" ;;
"pcap-linktype.manmisc") CONFIG_FILES="$CONFIG_FILES pcap-linktype.manmisc" ;; "pcap-linktype.manmisc") CONFIG_FILES="$CONFIG_FILES pcap-linktype.manmisc" ;;
"pcap-tstamp.manmisc") CONFIG_FILES="$CONFIG_FILES pcap-tstamp.manmisc" ;;
"pcap-savefile.manfile") CONFIG_FILES="$CONFIG_FILES pcap-savefile.manfile" ;; "pcap-savefile.manfile") CONFIG_FILES="$CONFIG_FILES pcap-savefile.manfile" ;;
"pcap.3pcap") CONFIG_FILES="$CONFIG_FILES pcap.3pcap" ;; "pcap.3pcap") CONFIG_FILES="$CONFIG_FILES pcap.3pcap" ;;
"pcap_compile.3pcap") CONFIG_FILES="$CONFIG_FILES pcap_compile.3pcap" ;; "pcap_compile.3pcap") CONFIG_FILES="$CONFIG_FILES pcap_compile.3pcap" ;;
"pcap_datalink.3pcap") CONFIG_FILES="$CONFIG_FILES pcap_datalink.3pcap" ;; "pcap_datalink.3pcap") CONFIG_FILES="$CONFIG_FILES pcap_datalink.3pcap" ;;
"pcap_dump_open.3pcap") CONFIG_FILES="$CONFIG_FILES pcap_dump_open.3pcap" ;; "pcap_dump_open.3pcap") CONFIG_FILES="$CONFIG_FILES pcap_dump_open.3pcap" ;;
"pcap_list_datalinks.3pcap") CONFIG_FILES="$CONFIG_FILES pcap_list_datalinks.3pcap" ;; "pcap_list_datalinks.3pcap") CONFIG_FILES="$CONFIG_FILES pcap_list_datalinks.3pcap" ;;
"pcap_list_tstamp_types.3pcap") CONFIG_FILES="$CONFIG_FILES pcap_list_tstamp_types.3pcap" ;;
"pcap_open_dead.3pcap") CONFIG_FILES="$CONFIG_FILES pcap_open_dead.3pcap" ;; "pcap_open_dead.3pcap") CONFIG_FILES="$CONFIG_FILES pcap_open_dead.3pcap" ;;
"pcap_open_offline.3pcap") CONFIG_FILES="$CONFIG_FILES pcap_open_offline.3pcap" ;; "pcap_open_offline.3pcap") CONFIG_FILES="$CONFIG_FILES pcap_open_offline.3pcap" ;;
"pcap_set_tstamp_type.3pcap") CONFIG_FILES="$CONFIG_FILES pcap_set_tstamp_type.3pcap" ;;
*) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
echo "$as_me: error: invalid argument: $ac_config_target" >&2;} echo "$as_me: error: invalid argument: $ac_config_target" >&2;}

View File

@ -1447,15 +1447,26 @@ if test "x$enable_can" != "xno" ; then
AC_SUBST(CAN_SRC) AC_SUBST(CAN_SRC)
fi fi
dnl check for hardware timestamp support
case "$host_os" in
linux*)
AC_CHECK_HEADERS([linux/net_tstamp.h])
;;
*)
AC_MSG_NOTICE(no hardware timestamp support implemented for $host_os)
;;
esac
AC_PROG_INSTALL AC_PROG_INSTALL
AC_CONFIG_HEADER(config.h) AC_CONFIG_HEADER(config.h)
AC_OUTPUT(Makefile pcap-filter.manmisc pcap-linktype.manmisc AC_OUTPUT(Makefile pcap-filter.manmisc pcap-linktype.manmisc
pcap-savefile.manfile pcap.3pcap pcap_compile.3pcap pcap-tstamp.manmisc pcap-savefile.manfile pcap.3pcap
pcap_datalink.3pcap pcap_dump_open.3pcap pcap_compile.3pcap pcap_datalink.3pcap pcap_dump_open.3pcap
pcap_list_datalinks.3pcap pcap_open_dead.3pcap pcap_list_datalinks.3pcap pcap_list_tstamp_types.3pcap
pcap_open_offline.3pcap) pcap_open_dead.3pcap pcap_open_offline.3pcap
pcap_set_tstamp_type.3pcap)
if test -f .devel ; then if test -f .devel ; then
make depend make depend

View File

@ -209,6 +209,7 @@ struct pcap_opt {
char *source; char *source;
int promisc; int promisc;
int rfmon; int rfmon;
int tstamp_type;
}; };
/* /*
@ -331,6 +332,8 @@ struct pcap {
char errbuf[PCAP_ERRBUF_SIZE + 1]; char errbuf[PCAP_ERRBUF_SIZE + 1];
int dlt_count; int dlt_count;
u_int *dlt_list; u_int *dlt_list;
int tstamp_type_count;
u_int *tstamp_type_list;
struct pcap_pkthdr pcap_header; /* This is needed for the pcap_next_ex() to work */ struct pcap_pkthdr pcap_header; /* This is needed for the pcap_next_ex() to work */
}; };

View File

@ -138,6 +138,11 @@ static const char rcsid[] _U_ =
#include <poll.h> #include <poll.h>
#include <dirent.h> #include <dirent.h>
#ifdef HAVE_LINUX_NET_TSTAMP_H
#include <linux/net_tstamp.h>
#include <linux/sockios.h>
#endif
/* /*
* Got Wireless Extensions? * Got Wireless Extensions?
*/ */
@ -411,6 +416,28 @@ pcap_create(const char *device, char *ebuf)
handle->activate_op = pcap_activate_linux; handle->activate_op = pcap_activate_linux;
handle->can_set_rfmon_op = pcap_can_set_rfmon_linux; handle->can_set_rfmon_op = pcap_can_set_rfmon_linux;
#if defined(HAVE_LINUX_NET_TSTAMP_H) && defined(PACKET_TIMESTAMP)
/*
* We claim that we support:
*
* software time stamps, with no details about their precision;
* hardware time stamps, synced to the host time;
* hardware time stamps, not synced to the host time.
*
* XXX - we can't ask a device whether it supports
* hardware time stamps, so we just claim all devices do.
*/
handle->tstamp_type_count = 3;
handle->tstamp_type_list = malloc(3 * sizeof(u_int));
if (handle->tstamp_type_list == NULL) {
free(handle);
return NULL;
}
handle->tstamp_type_list[0] = PCAP_TSTAMP_HOST;
handle->tstamp_type_list[1] = PCAP_TSTAMP_ADAPTER;
handle->tstamp_type_list[2] = PCAP_TSTAMP_ADAPTER_UNSYNC;
#endif
return handle; return handle;
} }
@ -1172,7 +1199,8 @@ pcap_activate_linux(pcap_t *handle)
* Success. * Success.
* Try to use memory-mapped access. * Try to use memory-mapped access.
*/ */
switch (activate_mmap(handle)) { status = activate_mmap(handle);
switch (status) {
case 1: case 1:
/* we succeeded; nothing more to do */ /* we succeeded; nothing more to do */
@ -1183,17 +1211,16 @@ pcap_activate_linux(pcap_t *handle)
* Kernel doesn't support it - just continue * Kernel doesn't support it - just continue
* with non-memory-mapped access. * with non-memory-mapped access.
*/ */
status = 0;
break; break;
case -1: default:
/* /*
* We failed to set up to use it, or kernel * We failed to set up to use it, or kernel
* supports it, but we failed to enable it; * supports it, but we failed to enable it;
* return an error. handle->errbuf contains * the return value is the error status to
* an error message. * return and, if it's PCAP_ERROR, handle->errbuf
* contains the error message.
*/ */
status = PCAP_ERROR;
goto fail; goto fail;
} }
} }
@ -3083,6 +3110,86 @@ create_ring(pcap_t *handle)
frames_per_block = req.tp_block_size/req.tp_frame_size; frames_per_block = req.tp_block_size/req.tp_frame_size;
/*
* PACKET_TIMESTAMP was added after linux/net_tstamp.h was,
* so we check for PACKET_TIMESTAMP. We check for
* linux/net_tstamp.h just in case a system somehow has
* PACKET_TIMESTAMP but not linux/net_tstamp.h; that might
* be unnecessary.
*
* SIOCSHWTSTAMP was introduced in the patch that introduced
* linux/net_tstamp.h, so we don't bother checking whether
* SIOCSHWTSTAMP is defined (if your Linux system has
* linux/net_tstamp.h but doesn't define SIOCSHWTSTAMP, your
* Linux system is badly broken).
*/
#if defined(HAVE_LINUX_NET_TSTAMP_H) && defined(PACKET_TIMESTAMP)
/*
* If we were told to do so, ask the kernel and the driver
* to use hardware timestamps.
*
* Hardware timestamps are only supported with mmapped
* captures.
*/
if (handle->opt.tstamp_type == PCAP_TSTAMP_ADAPTER ||
handle->opt.tstamp_type == PCAP_TSTAMP_ADAPTER_UNSYNCED) {
struct hwtstamp_config hwconfig;
struct ifreq ifr;
int timesource;
/*
* Ask for hardware time stamps on all packets,
* including transmitted packets.
*/
memset(&hwconfig, 0, sizeof(hwconfig));
hwconfig.tx_type = HWTSTAMP_TX_ON;
hwconfig.rx_filter = HWTSTAMP_FILTER_ALL;
memset(&ifr, 0, sizeof(ifr));
strcpy(ifr.ifr_name, handle->opt.source);
ifr.ifr_data = (void *)&hwconfig;
if (ioctl(handle->fd, SIOCSHWTSTAMP, &ifr) < 0) {
switch (errno) {
case EPERM:
return PCAP_ERROR_PERM_DENIED;
case EOPNOTSUPP:
return PCAP_ERROR_TSTAMP_TYPE_NOTSUP:
default:
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"SIOCSHWTSTAMP failed: %s",
pcap_strerror(errno));
return PCAP_ERROR;
}
}
if (handle->opt.tstamp_type == PCAP_TSTAMP_ADAPTER) {
/*
* Hardware timestamp, synchronized
* with the system clock.
*/
timesource = SOF_TIMESTAMPING_SYS_HARDWARE;
} else {
/*
* PCAP_TSTAMP_ADAPTER_UNSYNCED - hardware
* timestamp, not synchronized with the
* system clock.
*/
timesource = SOF_TIMESTAMPING_RAW_HARDWARE;
}
if (setsockopt(handle->fd, SOL_PACKET, PACKET_TIMESTAMP,
(void *)&timesource, sizeof(timesource))) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"can't set PACKET_TIMESTAMP: %s",
pcap_strerror(errno));
return PCAP_ERROR;
}
}
#endif /* HAVE_LINUX_NET_TSTAMP_H && PACKET_TIMESTAMP */
/* ask the kernel to create the ring */ /* ask the kernel to create the ring */
retry: retry:
req.tp_block_nr = req.tp_frame_nr / frames_per_block; req.tp_block_nr = req.tp_frame_nr / frames_per_block;
@ -3117,7 +3224,7 @@ retry:
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE, snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"can't create rx ring on packet socket: %s", "can't create rx ring on packet socket: %s",
pcap_strerror(errno)); pcap_strerror(errno));
return -1; return PCAP_ERROR;
} }
/* memory map the rx ring */ /* memory map the rx ring */
@ -3130,7 +3237,7 @@ retry:
/* clear the allocated ring on error*/ /* clear the allocated ring on error*/
destroy_ring(handle); destroy_ring(handle);
return -1; return PCAP_ERROR;
} }
/* allocate a ring for each frame header pointer*/ /* allocate a ring for each frame header pointer*/
@ -3142,7 +3249,7 @@ retry:
pcap_strerror(errno)); pcap_strerror(errno));
destroy_ring(handle); destroy_ring(handle);
return -1; return PCAP_ERROR;
} }
/* fill the header ring with proper frame ptr*/ /* fill the header ring with proper frame ptr*/

318
pcap.c
View File

@ -104,6 +104,56 @@ pcap_cant_set_rfmon(pcap_t *p _U_)
return (0); return (0);
} }
/*
* Sets *tstamp_typesp to point to an array 1 or more supported time stamp
* types; the return value is the number of supported time stamp types.
* The list should be freed by a call to pcap_free_tstamp_types() when
* you're done with it.
*
* A return value of 0 means "you don't get a choice of time stamp type",
* in which case *tstamp_typesp is set to null.
*
* PCAP_ERROR is returned on error.
*/
int
pcap_list_tstamp_types(pcap_t *p, int **tstamp_typesp)
{
if (p->tstamp_type_count == 0) {
/*
* We don't support multiple time stamp types.
*/
*tstamp_typesp = NULL;
} else {
*tstamp_typesp = (int*)calloc(sizeof(**tstamp_typesp),
p->tstamp_type_count);
if (*tstamp_typesp == NULL) {
(void)snprintf(p->errbuf, sizeof(p->errbuf),
"malloc: %s", pcap_strerror(errno));
return (PCAP_ERROR);
}
(void)memcpy(*tstamp_typesp, p->tstamp_type_list,
sizeof(**tstamp_typesp) * p->tstamp_type_count);
}
return (p->tstamp_type_count);
}
/*
* In Windows, you might have a library built with one version of the
* C runtime library and an application built with another version of
* the C runtime library, which means that the library might use one
* version of malloc() and free() and the application might use another
* version of malloc() and free(). If so, that means something
* allocated by the library cannot be freed by the application, so we
* need to have a pcap_free_tstamp_types() routine to free up the list
* allocated by pcap_list_tstamp_types(), even though it's just a wrapper
* around free().
*/
void
pcap_free_tstamp_types(int *tstamp_type_list)
{
free(tstamp_type_list);
}
/* /*
* Default one-shot callback; overridden for capture types where the * Default one-shot callback; overridden for capture types where the
* packet data cannot be guaranteed to be available after the callback * packet data cannot be guaranteed to be available after the callback
@ -258,6 +308,7 @@ pcap_create_common(const char *source, char *ebuf)
pcap_set_snaplen(p, 65535); /* max packet size */ pcap_set_snaplen(p, 65535); /* max packet size */
p->opt.promisc = 0; p->opt.promisc = 0;
p->opt.buffer_size = 0; p->opt.buffer_size = 0;
p->opt.tstamp_type = -1; /* default to not setting time stamp type */
return (p); return (p);
} }
@ -308,6 +359,41 @@ pcap_set_timeout(pcap_t *p, int timeout_ms)
return 0; return 0;
} }
int
pcap_set_tstamp_type(pcap_t *p, int tstamp_type)
{
int i;
if (pcap_check_activated(p))
return PCAP_ERROR_ACTIVATED;
/*
* If p->tstamp_type_count is 0, we don't support setting
* the time stamp type at all.
*/
if (p->tstamp_type_count == 0)
return PCAP_ERROR_CANTSET_TSTAMP_TYPE;
/*
* Check whether we claim to support this type of time stamp.
*/
for (i = 0; i < p->tstamp_type_count; i++) {
if (p->tstamp_type_list[i] == tstamp_type) {
/*
* Yes.
*/
p->opt.tstamp_type = tstamp_type;
return 0;
}
}
/*
* No. We support setting the time stamp type, but not to this
* particular value.
*/
return PCAP_ERROR_TSTAMP_TYPE_NOTSUP;
}
int int
pcap_set_buffer_size(pcap_t *p, int buffer_size) pcap_set_buffer_size(pcap_t *p, int buffer_size)
{ {
@ -571,6 +657,91 @@ unsupported:
return (-1); return (-1);
} }
/*
* This array is designed for mapping upper and lower case letter
* together for a case independent comparison. The mappings are
* based upon ascii character sequences.
*/
static const u_char charmap[] = {
(u_char)'\000', (u_char)'\001', (u_char)'\002', (u_char)'\003',
(u_char)'\004', (u_char)'\005', (u_char)'\006', (u_char)'\007',
(u_char)'\010', (u_char)'\011', (u_char)'\012', (u_char)'\013',
(u_char)'\014', (u_char)'\015', (u_char)'\016', (u_char)'\017',
(u_char)'\020', (u_char)'\021', (u_char)'\022', (u_char)'\023',
(u_char)'\024', (u_char)'\025', (u_char)'\026', (u_char)'\027',
(u_char)'\030', (u_char)'\031', (u_char)'\032', (u_char)'\033',
(u_char)'\034', (u_char)'\035', (u_char)'\036', (u_char)'\037',
(u_char)'\040', (u_char)'\041', (u_char)'\042', (u_char)'\043',
(u_char)'\044', (u_char)'\045', (u_char)'\046', (u_char)'\047',
(u_char)'\050', (u_char)'\051', (u_char)'\052', (u_char)'\053',
(u_char)'\054', (u_char)'\055', (u_char)'\056', (u_char)'\057',
(u_char)'\060', (u_char)'\061', (u_char)'\062', (u_char)'\063',
(u_char)'\064', (u_char)'\065', (u_char)'\066', (u_char)'\067',
(u_char)'\070', (u_char)'\071', (u_char)'\072', (u_char)'\073',
(u_char)'\074', (u_char)'\075', (u_char)'\076', (u_char)'\077',
(u_char)'\100', (u_char)'\141', (u_char)'\142', (u_char)'\143',
(u_char)'\144', (u_char)'\145', (u_char)'\146', (u_char)'\147',
(u_char)'\150', (u_char)'\151', (u_char)'\152', (u_char)'\153',
(u_char)'\154', (u_char)'\155', (u_char)'\156', (u_char)'\157',
(u_char)'\160', (u_char)'\161', (u_char)'\162', (u_char)'\163',
(u_char)'\164', (u_char)'\165', (u_char)'\166', (u_char)'\167',
(u_char)'\170', (u_char)'\171', (u_char)'\172', (u_char)'\133',
(u_char)'\134', (u_char)'\135', (u_char)'\136', (u_char)'\137',
(u_char)'\140', (u_char)'\141', (u_char)'\142', (u_char)'\143',
(u_char)'\144', (u_char)'\145', (u_char)'\146', (u_char)'\147',
(u_char)'\150', (u_char)'\151', (u_char)'\152', (u_char)'\153',
(u_char)'\154', (u_char)'\155', (u_char)'\156', (u_char)'\157',
(u_char)'\160', (u_char)'\161', (u_char)'\162', (u_char)'\163',
(u_char)'\164', (u_char)'\165', (u_char)'\166', (u_char)'\167',
(u_char)'\170', (u_char)'\171', (u_char)'\172', (u_char)'\173',
(u_char)'\174', (u_char)'\175', (u_char)'\176', (u_char)'\177',
(u_char)'\200', (u_char)'\201', (u_char)'\202', (u_char)'\203',
(u_char)'\204', (u_char)'\205', (u_char)'\206', (u_char)'\207',
(u_char)'\210', (u_char)'\211', (u_char)'\212', (u_char)'\213',
(u_char)'\214', (u_char)'\215', (u_char)'\216', (u_char)'\217',
(u_char)'\220', (u_char)'\221', (u_char)'\222', (u_char)'\223',
(u_char)'\224', (u_char)'\225', (u_char)'\226', (u_char)'\227',
(u_char)'\230', (u_char)'\231', (u_char)'\232', (u_char)'\233',
(u_char)'\234', (u_char)'\235', (u_char)'\236', (u_char)'\237',
(u_char)'\240', (u_char)'\241', (u_char)'\242', (u_char)'\243',
(u_char)'\244', (u_char)'\245', (u_char)'\246', (u_char)'\247',
(u_char)'\250', (u_char)'\251', (u_char)'\252', (u_char)'\253',
(u_char)'\254', (u_char)'\255', (u_char)'\256', (u_char)'\257',
(u_char)'\260', (u_char)'\261', (u_char)'\262', (u_char)'\263',
(u_char)'\264', (u_char)'\265', (u_char)'\266', (u_char)'\267',
(u_char)'\270', (u_char)'\271', (u_char)'\272', (u_char)'\273',
(u_char)'\274', (u_char)'\275', (u_char)'\276', (u_char)'\277',
(u_char)'\300', (u_char)'\341', (u_char)'\342', (u_char)'\343',
(u_char)'\344', (u_char)'\345', (u_char)'\346', (u_char)'\347',
(u_char)'\350', (u_char)'\351', (u_char)'\352', (u_char)'\353',
(u_char)'\354', (u_char)'\355', (u_char)'\356', (u_char)'\357',
(u_char)'\360', (u_char)'\361', (u_char)'\362', (u_char)'\363',
(u_char)'\364', (u_char)'\365', (u_char)'\366', (u_char)'\367',
(u_char)'\370', (u_char)'\371', (u_char)'\372', (u_char)'\333',
(u_char)'\334', (u_char)'\335', (u_char)'\336', (u_char)'\337',
(u_char)'\340', (u_char)'\341', (u_char)'\342', (u_char)'\343',
(u_char)'\344', (u_char)'\345', (u_char)'\346', (u_char)'\347',
(u_char)'\350', (u_char)'\351', (u_char)'\352', (u_char)'\353',
(u_char)'\354', (u_char)'\355', (u_char)'\356', (u_char)'\357',
(u_char)'\360', (u_char)'\361', (u_char)'\362', (u_char)'\363',
(u_char)'\364', (u_char)'\365', (u_char)'\366', (u_char)'\367',
(u_char)'\370', (u_char)'\371', (u_char)'\372', (u_char)'\373',
(u_char)'\374', (u_char)'\375', (u_char)'\376', (u_char)'\377',
};
int
pcap_strcasecmp(const char *s1, const char *s2)
{
register const u_char *cm = charmap,
*us1 = (const u_char *)s1,
*us2 = (const u_char *)s2;
while (cm[*us1] == cm[*us2++])
if (*us1++ == '\0')
return(0);
return (cm[*us1] - cm[*--us2]);
}
struct dlt_choice { struct dlt_choice {
const char *name; const char *name;
const char *description; const char *description;
@ -677,91 +848,6 @@ static struct dlt_choice dlt_choices[] = {
DLT_CHOICE_SENTINEL DLT_CHOICE_SENTINEL
}; };
/*
* This array is designed for mapping upper and lower case letter
* together for a case independent comparison. The mappings are
* based upon ascii character sequences.
*/
static const u_char charmap[] = {
(u_char)'\000', (u_char)'\001', (u_char)'\002', (u_char)'\003',
(u_char)'\004', (u_char)'\005', (u_char)'\006', (u_char)'\007',
(u_char)'\010', (u_char)'\011', (u_char)'\012', (u_char)'\013',
(u_char)'\014', (u_char)'\015', (u_char)'\016', (u_char)'\017',
(u_char)'\020', (u_char)'\021', (u_char)'\022', (u_char)'\023',
(u_char)'\024', (u_char)'\025', (u_char)'\026', (u_char)'\027',
(u_char)'\030', (u_char)'\031', (u_char)'\032', (u_char)'\033',
(u_char)'\034', (u_char)'\035', (u_char)'\036', (u_char)'\037',
(u_char)'\040', (u_char)'\041', (u_char)'\042', (u_char)'\043',
(u_char)'\044', (u_char)'\045', (u_char)'\046', (u_char)'\047',
(u_char)'\050', (u_char)'\051', (u_char)'\052', (u_char)'\053',
(u_char)'\054', (u_char)'\055', (u_char)'\056', (u_char)'\057',
(u_char)'\060', (u_char)'\061', (u_char)'\062', (u_char)'\063',
(u_char)'\064', (u_char)'\065', (u_char)'\066', (u_char)'\067',
(u_char)'\070', (u_char)'\071', (u_char)'\072', (u_char)'\073',
(u_char)'\074', (u_char)'\075', (u_char)'\076', (u_char)'\077',
(u_char)'\100', (u_char)'\141', (u_char)'\142', (u_char)'\143',
(u_char)'\144', (u_char)'\145', (u_char)'\146', (u_char)'\147',
(u_char)'\150', (u_char)'\151', (u_char)'\152', (u_char)'\153',
(u_char)'\154', (u_char)'\155', (u_char)'\156', (u_char)'\157',
(u_char)'\160', (u_char)'\161', (u_char)'\162', (u_char)'\163',
(u_char)'\164', (u_char)'\165', (u_char)'\166', (u_char)'\167',
(u_char)'\170', (u_char)'\171', (u_char)'\172', (u_char)'\133',
(u_char)'\134', (u_char)'\135', (u_char)'\136', (u_char)'\137',
(u_char)'\140', (u_char)'\141', (u_char)'\142', (u_char)'\143',
(u_char)'\144', (u_char)'\145', (u_char)'\146', (u_char)'\147',
(u_char)'\150', (u_char)'\151', (u_char)'\152', (u_char)'\153',
(u_char)'\154', (u_char)'\155', (u_char)'\156', (u_char)'\157',
(u_char)'\160', (u_char)'\161', (u_char)'\162', (u_char)'\163',
(u_char)'\164', (u_char)'\165', (u_char)'\166', (u_char)'\167',
(u_char)'\170', (u_char)'\171', (u_char)'\172', (u_char)'\173',
(u_char)'\174', (u_char)'\175', (u_char)'\176', (u_char)'\177',
(u_char)'\200', (u_char)'\201', (u_char)'\202', (u_char)'\203',
(u_char)'\204', (u_char)'\205', (u_char)'\206', (u_char)'\207',
(u_char)'\210', (u_char)'\211', (u_char)'\212', (u_char)'\213',
(u_char)'\214', (u_char)'\215', (u_char)'\216', (u_char)'\217',
(u_char)'\220', (u_char)'\221', (u_char)'\222', (u_char)'\223',
(u_char)'\224', (u_char)'\225', (u_char)'\226', (u_char)'\227',
(u_char)'\230', (u_char)'\231', (u_char)'\232', (u_char)'\233',
(u_char)'\234', (u_char)'\235', (u_char)'\236', (u_char)'\237',
(u_char)'\240', (u_char)'\241', (u_char)'\242', (u_char)'\243',
(u_char)'\244', (u_char)'\245', (u_char)'\246', (u_char)'\247',
(u_char)'\250', (u_char)'\251', (u_char)'\252', (u_char)'\253',
(u_char)'\254', (u_char)'\255', (u_char)'\256', (u_char)'\257',
(u_char)'\260', (u_char)'\261', (u_char)'\262', (u_char)'\263',
(u_char)'\264', (u_char)'\265', (u_char)'\266', (u_char)'\267',
(u_char)'\270', (u_char)'\271', (u_char)'\272', (u_char)'\273',
(u_char)'\274', (u_char)'\275', (u_char)'\276', (u_char)'\277',
(u_char)'\300', (u_char)'\341', (u_char)'\342', (u_char)'\343',
(u_char)'\344', (u_char)'\345', (u_char)'\346', (u_char)'\347',
(u_char)'\350', (u_char)'\351', (u_char)'\352', (u_char)'\353',
(u_char)'\354', (u_char)'\355', (u_char)'\356', (u_char)'\357',
(u_char)'\360', (u_char)'\361', (u_char)'\362', (u_char)'\363',
(u_char)'\364', (u_char)'\365', (u_char)'\366', (u_char)'\367',
(u_char)'\370', (u_char)'\371', (u_char)'\372', (u_char)'\333',
(u_char)'\334', (u_char)'\335', (u_char)'\336', (u_char)'\337',
(u_char)'\340', (u_char)'\341', (u_char)'\342', (u_char)'\343',
(u_char)'\344', (u_char)'\345', (u_char)'\346', (u_char)'\347',
(u_char)'\350', (u_char)'\351', (u_char)'\352', (u_char)'\353',
(u_char)'\354', (u_char)'\355', (u_char)'\356', (u_char)'\357',
(u_char)'\360', (u_char)'\361', (u_char)'\362', (u_char)'\363',
(u_char)'\364', (u_char)'\365', (u_char)'\366', (u_char)'\367',
(u_char)'\370', (u_char)'\371', (u_char)'\372', (u_char)'\373',
(u_char)'\374', (u_char)'\375', (u_char)'\376', (u_char)'\377',
};
int
pcap_strcasecmp(const char *s1, const char *s2)
{
register const u_char *cm = charmap,
*us1 = (const u_char *)s1,
*us2 = (const u_char *)s2;
while (cm[*us1] == cm[*us2++])
if (*us1++ == '\0')
return(0);
return (cm[*us1] - cm[*--us2]);
}
int int
pcap_datalink_name_to_val(const char *name) pcap_datalink_name_to_val(const char *name)
{ {
@ -799,6 +885,57 @@ pcap_datalink_val_to_description(int dlt)
return (NULL); return (NULL);
} }
struct tstamp_type_choice {
const char *name;
const char *description;
int type;
};
static struct tstamp_type_choice tstamp_type_choices[] = {
{ "host", "Host", PCAP_TSTAMP_HOST },
{ "host_lowprec", "Host, low precision", PCAP_TSTAMP_HOST_LOWPREC },
{ "host_hiprec", "Host, high precision", PCAP_TSTAMP_HOST_HIPREC },
{ "adapter", "Adapter", PCAP_TSTAMP_ADAPTER },
{ "adapter_unsynced", "Adapter, not synced with system time", PCAP_TSTAMP_ADAPTER_UNSYNCED },
{ NULL, NULL, 0 }
};
int
pcap_tstamp_type_name_to_val(const char *name)
{
int i;
for (i = 0; tstamp_type_choices[i].name != NULL; i++) {
if (pcap_strcasecmp(tstamp_type_choices[i].name, name) == 0)
return (tstamp_type_choices[i].type);
}
return (PCAP_ERROR);
}
const char *
pcap_tstamp_type_val_to_name(int tstamp_type)
{
int i;
for (i = 0; tstamp_type_choices[i].name != NULL; i++) {
if (tstamp_type_choices[i].type == tstamp_type)
return (tstamp_type_choices[i].name);
}
return (NULL);
}
const char *
pcap_tstamp_type_val_to_description(int tstamp_type)
{
int i;
for (i = 0; tstamp_type_choices[i].name != NULL; i++) {
if (tstamp_type_choices[i].type == tstamp_type)
return (tstamp_type_choices[i].description);
}
return (NULL);
}
int int
pcap_snapshot(pcap_t *p) pcap_snapshot(pcap_t *p)
{ {
@ -1006,6 +1143,12 @@ pcap_statustostr(int errnum)
case PCAP_ERROR_IFACE_NOT_UP: case PCAP_ERROR_IFACE_NOT_UP:
return ("That device is not up"); return ("That device is not up");
case PCAP_ERROR_CANTSET_TSTAMP_TYPE:
return ("That device doesn't support setting the time stamp type");
case PCAP_ERROR_TSTAMP_TYPE_NOTSUP:
return ("That type of time stamp is not supported by that device");
} }
(void)snprintf(ebuf, sizeof ebuf, "Unknown error: %d", errnum); (void)snprintf(ebuf, sizeof ebuf, "Unknown error: %d", errnum);
return(ebuf); return(ebuf);
@ -1213,6 +1356,11 @@ pcap_cleanup_live_common(pcap_t *p)
p->dlt_list = NULL; p->dlt_list = NULL;
p->dlt_count = 0; p->dlt_count = 0;
} }
if (p->tstamp_type_list != NULL) {
free(p->tstamp_type_list);
p->tstamp_type_list = NULL;
p->tstamp_type_count = 0;
}
pcap_freecode(&p->fcode); pcap_freecode(&p->fcode);
#if !defined(WIN32) && !defined(MSDOS) #if !defined(WIN32) && !defined(MSDOS)
if (p->fd >= 0) { if (p->fd >= 0) {

View File

@ -251,6 +251,8 @@ typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,
#define PCAP_ERROR_NOT_RFMON -7 /* operation supported only in monitor mode */ #define PCAP_ERROR_NOT_RFMON -7 /* operation supported only in monitor mode */
#define PCAP_ERROR_PERM_DENIED -8 /* no permission to open the device */ #define PCAP_ERROR_PERM_DENIED -8 /* no permission to open the device */
#define PCAP_ERROR_IFACE_NOT_UP -9 /* interface isn't up */ #define PCAP_ERROR_IFACE_NOT_UP -9 /* interface isn't up */
#define PCAP_ERROR_CANTSET_TSTAMP_TYPE -10 /* this device doesn't support setting the time stamp type */
#define PCAP_ERROR_TSTAMP_TYPE_NOTSUP -11 /* the requested time stamp type is not supported */
/* /*
* Warning codes for the pcap API. * Warning codes for the pcap API.
@ -275,9 +277,60 @@ int pcap_set_promisc(pcap_t *, int);
int pcap_can_set_rfmon(pcap_t *); int pcap_can_set_rfmon(pcap_t *);
int pcap_set_rfmon(pcap_t *, int); int pcap_set_rfmon(pcap_t *, int);
int pcap_set_timeout(pcap_t *, int); int pcap_set_timeout(pcap_t *, int);
int pcap_set_tstamp_type(pcap_t *, int);
int pcap_set_buffer_size(pcap_t *, int); int pcap_set_buffer_size(pcap_t *, int);
int pcap_activate(pcap_t *); int pcap_activate(pcap_t *);
int pcap_list_tstamp_types(pcap_t *, int **);
void pcap_free_tstamp_types(int *);
int pcap_tstamp_type_name_to_val(const char *);
const char *pcap_tstamp_type_val_to_name(int);
const char *pcap_tstamp_type_val_to_description(int);
/*
* Time stamp types.
* Not all systems and interfaces will necessarily support all of these.
*
* A system that supports PCAP_TSTAMP_HOST is offering time stamps
* provided by the host machine, rather than by the capture device,
* but not committing to any characteristics of the time stamp;
* it will not offer any of the PCAP_TSTAMP_HOST_ subtypes.
*
* PCAP_TSTAMP_HOST_LOWPREC is a time stamp, provided by the host machine,
* that's low-precision but relatively cheap to fetch; it's normally done
* using the system clock, so it's normally synchronized with times you'd
* fetch from system calls.
*
* PCAP_TSTAMP_HOST_HIPREC is a time stamp, provided by the host machine,
* that's high-precision; it might be more expensive to fetch. It might
* or might not be synchronized with the system clock, and might have
* problems with time stamps for packets received on different CPUs,
* depending on the platform.
*
* PCAP_TSTAMP_ADAPTER is a high-precision time stamp supplied by the
* capture device; it's synchronized with the system clock.
*
* PCAP_TSTAMP_ADAPTER_UNSYNC is a high-precision time stamp supplied by
* the capture device; it's not synchronized with the system clock.
*
* Note that time stamps synchronized with the system clock can go
* backwards, as the system clock can go backwards. If a clock is
* not in sync with the system clock, that could be because the
* system clock isn't keeping accurate time, because the other
* clock isn't keeping accurate time, or both.
*
* Note that host-provided time stamps generally correspond to the
* time when the time-stamping code sees the packet; this could
* be some unknown amount of time after the first or last bit of
* the packet is received by the network adapter, due to batching
* of interrupts for packet arrival, queueing delays, etc..
*/
#define PCAP_TSTAMP_HOST 0 /* host-provided, unknown characteristics */
#define PCAP_TSTAMP_HOST_LOWPREC 1 /* host-provided, low precision */
#define PCAP_TSTAMP_HOST_HIPREC 2 /* host-provided, high precision */
#define PCAP_TSTAMP_ADAPTER 3 /* device-provided, synced with the system clock */
#define PCAP_TSTAMP_ADAPTER_UNSYNCED 4 /* device-provided, not synced with the system clock */
pcap_t *pcap_open_live(const char *, int, int, int, char *); pcap_t *pcap_open_live(const char *, int, int, int, char *);
pcap_t *pcap_open_dead(int, int); pcap_t *pcap_open_dead(int, int);
pcap_t *pcap_open_offline(const char *, char *); pcap_t *pcap_open_offline(const char *, char *);

View File

@ -56,7 +56,11 @@ if the process doesn't have permission to open the capture source,
if monitor mode was specified but the capture source doesn't support if monitor mode was specified but the capture source doesn't support
monitor mode, monitor mode,
.B PCAP_ERROR_IFACE_NOT_UP .B PCAP_ERROR_IFACE_NOT_UP
if the capture source is not up, and if the capture source is not up,
.B PCAP_ERROR_TSTAMP_TYPE_NOTSUP
if the time stamp specified in a previous
.B pcap_set_tstamp_type()
call isn't supported by the capture source, and
.B PCAP_ERROR .B PCAP_ERROR
if another error occurred. if another error occurred.
If If