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.)master
parent
749726f92c
commit
fa4435e65c
|
@ -19,13 +19,16 @@ pcap-config
|
|||
pcap-filter.manmisc
|
||||
pcap-linktype.manmisc
|
||||
pcap-savefile.manfile
|
||||
pcap-tstamp.manmisc
|
||||
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
|
||||
scanner.c
|
||||
scanner.h
|
||||
selpolltest
|
||||
|
|
15
Makefile.in
15
Makefile.in
|
@ -157,8 +157,10 @@ MAN3PCAP_EXPAND = \
|
|||
pcap_datalink.3pcap.in \
|
||||
pcap_dump_open.3pcap.in \
|
||||
pcap_list_datalinks.3pcap.in \
|
||||
pcap_list_tstamp_types.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 = \
|
||||
pcap_activate.3pcap \
|
||||
|
@ -201,7 +203,9 @@ MAN3PCAP_NOEXPAND = \
|
|||
pcap_snapshot.3pcap \
|
||||
pcap_stats.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=)
|
||||
|
||||
|
@ -210,7 +214,8 @@ MANFILE = \
|
|||
|
||||
MANMISC = \
|
||||
pcap-filter.manmisc.in \
|
||||
pcap-linktype.manmisc.in
|
||||
pcap-linktype.manmisc.in \
|
||||
pcap-tstamp.manmisc.in
|
||||
|
||||
EXTRA_DIST = \
|
||||
$(TESTS_SRC) \
|
||||
|
@ -561,6 +566,9 @@ install: install-shared install-archive pcap-config
|
|||
rm -f $(DESTDIR)$(mandir)/man3/pcap_free_datalinks.3pcap
|
||||
ln $(DESTDIR)$(mandir)/man3/pcap_list_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
|
||||
ln $(DESTDIR)$(mandir)/man3/pcap_loop.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_sendpacket.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_minor_version.3pcap
|
||||
rm -f $(DESTDIR)$(mandir)/man3/pcap_next.3pcap
|
||||
|
|
|
@ -55,6 +55,9 @@
|
|||
/* Define to 1 if you have the <limits.h> header file. */
|
||||
#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 */
|
||||
#undef HAVE_LINUX_TPACKET_AUXDATA_TP_VLAN_TCI
|
||||
|
||||
|
|
|
@ -10787,6 +10787,155 @@ echo "$as_me: no CAN sniffing support implemented for $host_os" >&6;}
|
|||
|
||||
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),
|
||||
# so one script is as good as another. But avoid the broken or
|
||||
# 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_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
|
||||
# This file is a shell script that caches the results of configure
|
||||
|
@ -11430,14 +11579,17 @@ do
|
|||
"Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
|
||||
"pcap-filter.manmisc") CONFIG_FILES="$CONFIG_FILES pcap-filter.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.3pcap") CONFIG_FILES="$CONFIG_FILES pcap.3pcap" ;;
|
||||
"pcap_compile.3pcap") CONFIG_FILES="$CONFIG_FILES pcap_compile.3pcap" ;;
|
||||
"pcap_datalink.3pcap") CONFIG_FILES="$CONFIG_FILES pcap_datalink.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_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_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: error: invalid argument: $ac_config_target" >&2;}
|
||||
|
|
19
configure.in
19
configure.in
|
@ -1447,15 +1447,26 @@ if test "x$enable_can" != "xno" ; then
|
|||
AC_SUBST(CAN_SRC)
|
||||
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_CONFIG_HEADER(config.h)
|
||||
|
||||
AC_OUTPUT(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)
|
||||
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)
|
||||
|
||||
if test -f .devel ; then
|
||||
make depend
|
||||
|
|
|
@ -209,6 +209,7 @@ struct pcap_opt {
|
|||
char *source;
|
||||
int promisc;
|
||||
int rfmon;
|
||||
int tstamp_type;
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -331,6 +332,8 @@ struct pcap {
|
|||
char errbuf[PCAP_ERRBUF_SIZE + 1];
|
||||
int dlt_count;
|
||||
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 */
|
||||
};
|
||||
|
|
125
pcap-linux.c
125
pcap-linux.c
|
@ -138,6 +138,11 @@ static const char rcsid[] _U_ =
|
|||
#include <poll.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#ifdef HAVE_LINUX_NET_TSTAMP_H
|
||||
#include <linux/net_tstamp.h>
|
||||
#include <linux/sockios.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Got Wireless Extensions?
|
||||
*/
|
||||
|
@ -411,6 +416,28 @@ pcap_create(const char *device, char *ebuf)
|
|||
|
||||
handle->activate_op = pcap_activate_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;
|
||||
}
|
||||
|
||||
|
@ -1172,7 +1199,8 @@ pcap_activate_linux(pcap_t *handle)
|
|||
* Success.
|
||||
* Try to use memory-mapped access.
|
||||
*/
|
||||
switch (activate_mmap(handle)) {
|
||||
status = activate_mmap(handle);
|
||||
switch (status) {
|
||||
|
||||
case 1:
|
||||
/* we succeeded; nothing more to do */
|
||||
|
@ -1183,17 +1211,16 @@ pcap_activate_linux(pcap_t *handle)
|
|||
* Kernel doesn't support it - just continue
|
||||
* with non-memory-mapped access.
|
||||
*/
|
||||
status = 0;
|
||||
break;
|
||||
|
||||
case -1:
|
||||
default:
|
||||
/*
|
||||
* We failed to set up to use it, or kernel
|
||||
* supports it, but we failed to enable it;
|
||||
* return an error. handle->errbuf contains
|
||||
* an error message.
|
||||
* the return value is the error status to
|
||||
* return and, if it's PCAP_ERROR, handle->errbuf
|
||||
* contains the error message.
|
||||
*/
|
||||
status = PCAP_ERROR;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
@ -3083,6 +3110,86 @@ create_ring(pcap_t *handle)
|
|||
|
||||
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 *)×ource, 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 */
|
||||
retry:
|
||||
req.tp_block_nr = req.tp_frame_nr / frames_per_block;
|
||||
|
@ -3117,7 +3224,7 @@ retry:
|
|||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"can't create rx ring on packet socket: %s",
|
||||
pcap_strerror(errno));
|
||||
return -1;
|
||||
return PCAP_ERROR;
|
||||
}
|
||||
|
||||
/* memory map the rx ring */
|
||||
|
@ -3130,7 +3237,7 @@ retry:
|
|||
|
||||
/* clear the allocated ring on error*/
|
||||
destroy_ring(handle);
|
||||
return -1;
|
||||
return PCAP_ERROR;
|
||||
}
|
||||
|
||||
/* allocate a ring for each frame header pointer*/
|
||||
|
@ -3142,7 +3249,7 @@ retry:
|
|||
pcap_strerror(errno));
|
||||
|
||||
destroy_ring(handle);
|
||||
return -1;
|
||||
return PCAP_ERROR;
|
||||
}
|
||||
|
||||
/* fill the header ring with proper frame ptr*/
|
||||
|
|
318
pcap.c
318
pcap.c
|
@ -104,6 +104,56 @@ pcap_cant_set_rfmon(pcap_t *p _U_)
|
|||
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
|
||||
* 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 */
|
||||
p->opt.promisc = 0;
|
||||
p->opt.buffer_size = 0;
|
||||
p->opt.tstamp_type = -1; /* default to not setting time stamp type */
|
||||
return (p);
|
||||
}
|
||||
|
||||
|
@ -308,6 +359,41 @@ pcap_set_timeout(pcap_t *p, int timeout_ms)
|
|||
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
|
||||
pcap_set_buffer_size(pcap_t *p, int buffer_size)
|
||||
{
|
||||
|
@ -571,6 +657,91 @@ unsupported:
|
|||
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 {
|
||||
const char *name;
|
||||
const char *description;
|
||||
|
@ -677,91 +848,6 @@ static struct dlt_choice dlt_choices[] = {
|
|||
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
|
||||
pcap_datalink_name_to_val(const char *name)
|
||||
{
|
||||
|
@ -799,6 +885,57 @@ pcap_datalink_val_to_description(int dlt)
|
|||
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
|
||||
pcap_snapshot(pcap_t *p)
|
||||
{
|
||||
|
@ -1006,6 +1143,12 @@ pcap_statustostr(int errnum)
|
|||
|
||||
case PCAP_ERROR_IFACE_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);
|
||||
return(ebuf);
|
||||
|
@ -1213,6 +1356,11 @@ pcap_cleanup_live_common(pcap_t *p)
|
|||
p->dlt_list = NULL;
|
||||
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);
|
||||
#if !defined(WIN32) && !defined(MSDOS)
|
||||
if (p->fd >= 0) {
|
||||
|
|
53
pcap/pcap.h
53
pcap/pcap.h
|
@ -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_PERM_DENIED -8 /* no permission to open the device */
|
||||
#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.
|
||||
|
@ -275,9 +277,60 @@ int pcap_set_promisc(pcap_t *, int);
|
|||
int pcap_can_set_rfmon(pcap_t *);
|
||||
int pcap_set_rfmon(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_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_dead(int, int);
|
||||
pcap_t *pcap_open_offline(const char *, char *);
|
||||
|
|
|
@ -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
|
||||
monitor mode,
|
||||
.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
|
||||
if another error occurred.
|
||||
If
|
||||
|
|
Reference in New Issue