mirror of
https://github.com/nmap/nmap.git
synced 2025-12-23 07:59:03 +00:00
Restore a few necessary parts of libpcap. Final commit for libpcap 1.9.0 upgrade
This commit is contained in:
@@ -0,0 +1,64 @@
|
||||
diff --git a/libpcap/configure.ac b/libpcap/configure.ac
|
||||
index 0127f0a..4b35daa 100644
|
||||
--- a/libpcap/configure.ac
|
||||
+++ b/libpcap/configure.ac
|
||||
@@ -743,10 +743,10 @@ linux)
|
||||
# Do we have libnl?
|
||||
#
|
||||
AC_ARG_WITH(libnl,
|
||||
- AC_HELP_STRING([--without-libnl],[disable libnl support @<:@default=yes, on Linux, if present@:>@]),
|
||||
+ AC_HELP_STRING([--without-libnl],[disable libnl support @<:@default=disabled@:>@]),
|
||||
with_libnl=$withval,with_libnl=if_available)
|
||||
|
||||
- if test x$with_libnl != xno ; then
|
||||
+ if test x$with_libnl = xyes ; then
|
||||
have_any_nl="no"
|
||||
|
||||
incdir=-I/usr/include/libnl3
|
||||
@@ -1814,8 +1814,8 @@ solaris*)
|
||||
esac
|
||||
|
||||
AC_ARG_ENABLE(shared,
|
||||
-AC_HELP_STRING([--enable-shared],[build shared libraries @<:@default=yes, if support available@:>@]))
|
||||
-test "x$enable_shared" = "xno" && DYEXT="none"
|
||||
+AC_HELP_STRING([--enable-shared],[build shared libraries @<:@default=no@:>@]))
|
||||
+test "x$enable_shared" != "xyes" && DYEXT="none"
|
||||
|
||||
AC_PROG_RANLIB
|
||||
AC_CHECK_TOOL([AR], [ar])
|
||||
@@ -1887,9 +1887,9 @@ AC_SUBST(RPCAPD_LIBS)
|
||||
AC_SUBST(EXTRA_NETWORK_LIBS)
|
||||
|
||||
AC_ARG_ENABLE([usb],
|
||||
-[AC_HELP_STRING([--enable-usb],[enable USB capture support @<:@default=yes, if support available@:>@])],
|
||||
+[AC_HELP_STRING([--enable-usb],[enable USB capture support @<:@default=no@:>@])],
|
||||
[],
|
||||
- [enable_usb=yes])
|
||||
+ [enable_usb=no])
|
||||
|
||||
if test "xxx_only" = yes; then
|
||||
# User requested something-else-only pcap, so they don't
|
||||
@@ -2035,9 +2035,9 @@ fi
|
||||
|
||||
|
||||
AC_ARG_ENABLE([bluetooth],
|
||||
-[AC_HELP_STRING([--enable-bluetooth],[enable Bluetooth support @<:@default=yes, if support available@:>@])],
|
||||
+[AC_HELP_STRING([--enable-bluetooth],[enable Bluetooth support @<:@default=no@:>@])],
|
||||
[],
|
||||
- [enable_bluetooth=ifsupportavailable])
|
||||
+ [enable_bluetooth=no])
|
||||
|
||||
if test "xxx_only" = yes; then
|
||||
# User requested something-else-only pcap, so they don't
|
||||
@@ -2120,9 +2120,9 @@ if test "x$enable_bluetooth" != "xno" ; then
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE([dbus],
|
||||
-[AC_HELP_STRING([--enable-dbus],[enable D-Bus capture support @<:@default=yes, if support available@:>@])],
|
||||
+[AC_HELP_STRING([--enable-dbus],[enable D-Bus capture support @<:@default=no@:>@])],
|
||||
[],
|
||||
- [enable_dbus=ifavailable])
|
||||
+ [enable_dbus=no])
|
||||
|
||||
if test "xxx_only" = yes; then
|
||||
# User requested something-else-only pcap, so they don't
|
||||
25
libpcap/NMAP_MODIFICATIONS/HOWTO-UPGRADE
Normal file
25
libpcap/NMAP_MODIFICATIONS/HOWTO-UPGRADE
Normal file
@@ -0,0 +1,25 @@
|
||||
Download libpcap-X.Y.tar.gz from http://www.tcpdump.org/#latest-release
|
||||
and verify the signature.
|
||||
|
||||
cd
|
||||
# Make a copy of this directory.
|
||||
cp -r ~/nmap/libpcap/NMAP_MODIFICATIONS .
|
||||
tar xzvf libpcap-X.Y.tar.gz
|
||||
cd nmap
|
||||
rsync -rv --delete ~/libpcap-X.Y/ ~/nmap/libpcap/
|
||||
git add -A libpcap
|
||||
cd libpcap
|
||||
./configure
|
||||
make grammar.c scanner.c scanner.h
|
||||
git add grammar.c scanner.c scanner.h
|
||||
cd ..
|
||||
# Apply patches.
|
||||
git apply ~/NMAP_MODIFICATIONS/000*
|
||||
# Make changes as necessary and update the patch files
|
||||
cd libpcap
|
||||
autoconf
|
||||
cd ..
|
||||
git add -u libpcap
|
||||
mv ~/NMAP_MODIFICATIONS libpcap/
|
||||
git add libpcap/NMAP_MODIFICATIONS
|
||||
git commit -m "Upgrade libpcap to X.Y."
|
||||
323
libpcap/grammar.h
Normal file
323
libpcap/grammar.h
Normal file
@@ -0,0 +1,323 @@
|
||||
/* A Bison parser, made by GNU Bison 3.0.4. */
|
||||
|
||||
/* Bison interface for Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* As a special exception, you may create a larger work that contains
|
||||
part or all of the Bison parser skeleton and distribute that work
|
||||
under terms of your choice, so long as that work isn't itself a
|
||||
parser generator using the skeleton or a modified version thereof
|
||||
as a parser skeleton. Alternatively, if you modify or redistribute
|
||||
the parser skeleton itself, you may (at your option) remove this
|
||||
special exception, which will cause the skeleton and the resulting
|
||||
Bison output files to be licensed under the GNU General Public
|
||||
License without this special exception.
|
||||
|
||||
This special exception was added by the Free Software Foundation in
|
||||
version 2.2 of Bison. */
|
||||
|
||||
#ifndef YY_PCAP_GRAMMAR_H_INCLUDED
|
||||
# define YY_PCAP_GRAMMAR_H_INCLUDED
|
||||
/* Debug traces. */
|
||||
#ifndef YYDEBUG
|
||||
# define YYDEBUG 0
|
||||
#endif
|
||||
#if YYDEBUG
|
||||
extern int pcap_debug;
|
||||
#endif
|
||||
|
||||
/* Token type. */
|
||||
#ifndef YYTOKENTYPE
|
||||
# define YYTOKENTYPE
|
||||
enum yytokentype
|
||||
{
|
||||
DST = 258,
|
||||
SRC = 259,
|
||||
HOST = 260,
|
||||
GATEWAY = 261,
|
||||
NET = 262,
|
||||
NETMASK = 263,
|
||||
PORT = 264,
|
||||
PORTRANGE = 265,
|
||||
LESS = 266,
|
||||
GREATER = 267,
|
||||
PROTO = 268,
|
||||
PROTOCHAIN = 269,
|
||||
CBYTE = 270,
|
||||
ARP = 271,
|
||||
RARP = 272,
|
||||
IP = 273,
|
||||
SCTP = 274,
|
||||
TCP = 275,
|
||||
UDP = 276,
|
||||
ICMP = 277,
|
||||
IGMP = 278,
|
||||
IGRP = 279,
|
||||
PIM = 280,
|
||||
VRRP = 281,
|
||||
CARP = 282,
|
||||
ATALK = 283,
|
||||
AARP = 284,
|
||||
DECNET = 285,
|
||||
LAT = 286,
|
||||
SCA = 287,
|
||||
MOPRC = 288,
|
||||
MOPDL = 289,
|
||||
TK_BROADCAST = 290,
|
||||
TK_MULTICAST = 291,
|
||||
NUM = 292,
|
||||
INBOUND = 293,
|
||||
OUTBOUND = 294,
|
||||
PF_IFNAME = 295,
|
||||
PF_RSET = 296,
|
||||
PF_RNR = 297,
|
||||
PF_SRNR = 298,
|
||||
PF_REASON = 299,
|
||||
PF_ACTION = 300,
|
||||
TYPE = 301,
|
||||
SUBTYPE = 302,
|
||||
DIR = 303,
|
||||
ADDR1 = 304,
|
||||
ADDR2 = 305,
|
||||
ADDR3 = 306,
|
||||
ADDR4 = 307,
|
||||
RA = 308,
|
||||
TA = 309,
|
||||
LINK = 310,
|
||||
GEQ = 311,
|
||||
LEQ = 312,
|
||||
NEQ = 313,
|
||||
ID = 314,
|
||||
EID = 315,
|
||||
HID = 316,
|
||||
HID6 = 317,
|
||||
AID = 318,
|
||||
LSH = 319,
|
||||
RSH = 320,
|
||||
LEN = 321,
|
||||
IPV6 = 322,
|
||||
ICMPV6 = 323,
|
||||
AH = 324,
|
||||
ESP = 325,
|
||||
VLAN = 326,
|
||||
MPLS = 327,
|
||||
PPPOED = 328,
|
||||
PPPOES = 329,
|
||||
GENEVE = 330,
|
||||
ISO = 331,
|
||||
ESIS = 332,
|
||||
CLNP = 333,
|
||||
ISIS = 334,
|
||||
L1 = 335,
|
||||
L2 = 336,
|
||||
IIH = 337,
|
||||
LSP = 338,
|
||||
SNP = 339,
|
||||
CSNP = 340,
|
||||
PSNP = 341,
|
||||
STP = 342,
|
||||
IPX = 343,
|
||||
NETBEUI = 344,
|
||||
LANE = 345,
|
||||
LLC = 346,
|
||||
METAC = 347,
|
||||
BCC = 348,
|
||||
SC = 349,
|
||||
ILMIC = 350,
|
||||
OAMF4EC = 351,
|
||||
OAMF4SC = 352,
|
||||
OAM = 353,
|
||||
OAMF4 = 354,
|
||||
CONNECTMSG = 355,
|
||||
METACONNECT = 356,
|
||||
VPI = 357,
|
||||
VCI = 358,
|
||||
RADIO = 359,
|
||||
FISU = 360,
|
||||
LSSU = 361,
|
||||
MSU = 362,
|
||||
HFISU = 363,
|
||||
HLSSU = 364,
|
||||
HMSU = 365,
|
||||
SIO = 366,
|
||||
OPC = 367,
|
||||
DPC = 368,
|
||||
SLS = 369,
|
||||
HSIO = 370,
|
||||
HOPC = 371,
|
||||
HDPC = 372,
|
||||
HSLS = 373,
|
||||
OR = 374,
|
||||
AND = 375,
|
||||
UMINUS = 376
|
||||
};
|
||||
#endif
|
||||
/* Tokens. */
|
||||
#define DST 258
|
||||
#define SRC 259
|
||||
#define HOST 260
|
||||
#define GATEWAY 261
|
||||
#define NET 262
|
||||
#define NETMASK 263
|
||||
#define PORT 264
|
||||
#define PORTRANGE 265
|
||||
#define LESS 266
|
||||
#define GREATER 267
|
||||
#define PROTO 268
|
||||
#define PROTOCHAIN 269
|
||||
#define CBYTE 270
|
||||
#define ARP 271
|
||||
#define RARP 272
|
||||
#define IP 273
|
||||
#define SCTP 274
|
||||
#define TCP 275
|
||||
#define UDP 276
|
||||
#define ICMP 277
|
||||
#define IGMP 278
|
||||
#define IGRP 279
|
||||
#define PIM 280
|
||||
#define VRRP 281
|
||||
#define CARP 282
|
||||
#define ATALK 283
|
||||
#define AARP 284
|
||||
#define DECNET 285
|
||||
#define LAT 286
|
||||
#define SCA 287
|
||||
#define MOPRC 288
|
||||
#define MOPDL 289
|
||||
#define TK_BROADCAST 290
|
||||
#define TK_MULTICAST 291
|
||||
#define NUM 292
|
||||
#define INBOUND 293
|
||||
#define OUTBOUND 294
|
||||
#define PF_IFNAME 295
|
||||
#define PF_RSET 296
|
||||
#define PF_RNR 297
|
||||
#define PF_SRNR 298
|
||||
#define PF_REASON 299
|
||||
#define PF_ACTION 300
|
||||
#define TYPE 301
|
||||
#define SUBTYPE 302
|
||||
#define DIR 303
|
||||
#define ADDR1 304
|
||||
#define ADDR2 305
|
||||
#define ADDR3 306
|
||||
#define ADDR4 307
|
||||
#define RA 308
|
||||
#define TA 309
|
||||
#define LINK 310
|
||||
#define GEQ 311
|
||||
#define LEQ 312
|
||||
#define NEQ 313
|
||||
#define ID 314
|
||||
#define EID 315
|
||||
#define HID 316
|
||||
#define HID6 317
|
||||
#define AID 318
|
||||
#define LSH 319
|
||||
#define RSH 320
|
||||
#define LEN 321
|
||||
#define IPV6 322
|
||||
#define ICMPV6 323
|
||||
#define AH 324
|
||||
#define ESP 325
|
||||
#define VLAN 326
|
||||
#define MPLS 327
|
||||
#define PPPOED 328
|
||||
#define PPPOES 329
|
||||
#define GENEVE 330
|
||||
#define ISO 331
|
||||
#define ESIS 332
|
||||
#define CLNP 333
|
||||
#define ISIS 334
|
||||
#define L1 335
|
||||
#define L2 336
|
||||
#define IIH 337
|
||||
#define LSP 338
|
||||
#define SNP 339
|
||||
#define CSNP 340
|
||||
#define PSNP 341
|
||||
#define STP 342
|
||||
#define IPX 343
|
||||
#define NETBEUI 344
|
||||
#define LANE 345
|
||||
#define LLC 346
|
||||
#define METAC 347
|
||||
#define BCC 348
|
||||
#define SC 349
|
||||
#define ILMIC 350
|
||||
#define OAMF4EC 351
|
||||
#define OAMF4SC 352
|
||||
#define OAM 353
|
||||
#define OAMF4 354
|
||||
#define CONNECTMSG 355
|
||||
#define METACONNECT 356
|
||||
#define VPI 357
|
||||
#define VCI 358
|
||||
#define RADIO 359
|
||||
#define FISU 360
|
||||
#define LSSU 361
|
||||
#define MSU 362
|
||||
#define HFISU 363
|
||||
#define HLSSU 364
|
||||
#define HMSU 365
|
||||
#define SIO 366
|
||||
#define OPC 367
|
||||
#define DPC 368
|
||||
#define SLS 369
|
||||
#define HSIO 370
|
||||
#define HOPC 371
|
||||
#define HDPC 372
|
||||
#define HSLS 373
|
||||
#define OR 374
|
||||
#define AND 375
|
||||
#define UMINUS 376
|
||||
|
||||
/* Value type. */
|
||||
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||
|
||||
union YYSTYPE
|
||||
{
|
||||
#line 286 "grammar.y" /* yacc.c:1909 */
|
||||
|
||||
int i;
|
||||
bpf_u_int32 h;
|
||||
u_char *e;
|
||||
char *s;
|
||||
struct stmt *stmt;
|
||||
struct arth *a;
|
||||
struct {
|
||||
struct qual q;
|
||||
int atmfieldtype;
|
||||
int mtp3fieldtype;
|
||||
struct block *b;
|
||||
} blk;
|
||||
struct block *rblk;
|
||||
|
||||
#line 312 "grammar.h" /* yacc.c:1909 */
|
||||
};
|
||||
|
||||
typedef union YYSTYPE YYSTYPE;
|
||||
# define YYSTYPE_IS_TRIVIAL 1
|
||||
# define YYSTYPE_IS_DECLARED 1
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
int pcap_parse (void *yyscanner, compiler_state_t *cstate);
|
||||
|
||||
#endif /* !YY_PCAP_GRAMMAR_H_INCLUDED */
|
||||
40
libpcap/testprogs/CMakeLists.txt
Normal file
40
libpcap/testprogs/CMakeLists.txt
Normal file
@@ -0,0 +1,40 @@
|
||||
if(MSVC)
|
||||
file(GLOB PROJECT_SOURCE_LIST_WIN32_C ${pcap_SOURCE_DIR}/missing/getopt.c)
|
||||
include_directories(${pcap_SOURCE_DIR}/missing)
|
||||
endif(MSVC)
|
||||
|
||||
add_custom_target(testprogs)
|
||||
|
||||
macro(add_test_executable _executable)
|
||||
add_executable(${_executable} EXCLUDE_FROM_ALL
|
||||
${_executable}.c ${PROJECT_SOURCE_LIST_WIN32_C})
|
||||
if(NOT C_ADDITIONAL_FLAGS STREQUAL "")
|
||||
set_target_properties(${_executable} PROPERTIES
|
||||
COMPILE_FLAGS ${C_ADDITIONAL_FLAGS})
|
||||
endif()
|
||||
if(WIN32)
|
||||
target_link_libraries(${_executable}
|
||||
${ARGN} ${LIBRARY_NAME} ${PCAP_LINK_LIBRARIES})
|
||||
else(WIN32)
|
||||
target_link_libraries(${_executable}
|
||||
${ARGN} ${LIBRARY_NAME}_static ${PCAP_LINK_LIBRARIES})
|
||||
endif(WIN32)
|
||||
add_dependencies(testprogs ${_executable})
|
||||
endmacro()
|
||||
|
||||
add_test_executable(can_set_rfmon_test)
|
||||
add_test_executable(capturetest)
|
||||
add_test_executable(filtertest)
|
||||
add_test_executable(findalldevstest)
|
||||
add_test_executable(opentest)
|
||||
add_test_executable(reactivatetest)
|
||||
|
||||
if(NOT WIN32)
|
||||
add_test_executable(selpolltest)
|
||||
endif()
|
||||
|
||||
add_test_executable(threadsignaltest ${CMAKE_THREAD_LIBS_INIT})
|
||||
|
||||
if(NOT WIN32)
|
||||
add_test_executable(valgrindtest)
|
||||
endif()
|
||||
144
libpcap/testprogs/Makefile.in
Normal file
144
libpcap/testprogs/Makefile.in
Normal file
@@ -0,0 +1,144 @@
|
||||
# Copyright (c) 1993, 1994, 1995, 1996
|
||||
# The Regents of the University of California. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that: (1) source code distributions
|
||||
# retain the above copyright notice and this paragraph in its entirety, (2)
|
||||
# distributions including binary code include the above copyright notice and
|
||||
# this paragraph in its entirety in the documentation or other materials
|
||||
# provided with the distribution, and (3) all advertising materials mentioning
|
||||
# features or use of this software display the following acknowledgement:
|
||||
# ``This product includes software developed by the University of California,
|
||||
# Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
|
||||
# the University nor the names of its contributors may be used to endorse
|
||||
# or promote products derived from this software without specific prior
|
||||
# written permission.
|
||||
# THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
|
||||
# WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
#
|
||||
# Various configurable paths (remember to edit Makefile.in, not Makefile)
|
||||
#
|
||||
|
||||
# Top level hierarchy
|
||||
prefix = @prefix@
|
||||
exec_prefix = @exec_prefix@
|
||||
datarootdir = @datarootdir@
|
||||
# Pathname of directory to install the configure program
|
||||
bindir = @bindir@
|
||||
# Pathname of directory to install the rpcapd daemon
|
||||
sbindir = @sbindir@
|
||||
# Pathname of directory to install the include files
|
||||
includedir = @includedir@
|
||||
# Pathname of directory to install the library
|
||||
libdir = @libdir@
|
||||
# Pathname of directory to install the man pages
|
||||
mandir = @mandir@
|
||||
|
||||
# VPATH
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
#
|
||||
# You shouldn't need to edit anything below.
|
||||
#
|
||||
|
||||
LD = /usr/bin/ld
|
||||
CC = @CC@
|
||||
AR = @AR@
|
||||
LN_S = @LN_S@
|
||||
MKDEP = @MKDEP@
|
||||
CCOPT = @V_CCOPT@
|
||||
INCLS = -I. -I.. -I@srcdir@ -I@srcdir@/.. @V_INCLS@
|
||||
DEFS = @DEFS@ @V_DEFS@
|
||||
ADDLOBJS = @ADDLOBJS@
|
||||
ADDLARCHIVEOBJS = @ADDLARCHIVEOBJS@
|
||||
LIBS = @LIBS@
|
||||
PTHREAD_LIBS = @PTHREAD_LIBS@
|
||||
CROSSFLAGS=
|
||||
CFLAGS = @CFLAGS@ ${CROSSFLAGS}
|
||||
LDFLAGS = @LDFLAGS@ ${CROSSFLAGS}
|
||||
DYEXT = @DYEXT@
|
||||
V_RPATH_OPT = @V_RPATH_OPT@
|
||||
DEPENDENCY_CFLAG = @DEPENDENCY_CFLAG@
|
||||
EXTRA_NETWORK_LIBS=@EXTRA_NETWORK_LIBS@
|
||||
|
||||
# Standard CFLAGS for building test programs
|
||||
FULL_CFLAGS = $(CCOPT) $(INCLS) $(DEFS) $(CFLAGS)
|
||||
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
|
||||
# Explicitly define compilation rule since SunOS 4's make doesn't like gcc.
|
||||
# Also, gcc does not remove the .o before forking 'as', which can be a
|
||||
# problem if you don't own the file but can write to the directory.
|
||||
.c.o:
|
||||
@rm -f $@
|
||||
$(CC) $(FULL_CFLAGS) -c $(srcdir)/$*.c
|
||||
|
||||
SRC = @VALGRINDTEST_SRC@ \
|
||||
capturetest.c \
|
||||
can_set_rfmon_test.c \
|
||||
filtertest.c \
|
||||
findalldevstest.c \
|
||||
opentest.c \
|
||||
reactivatetest.c \
|
||||
selpolltest.c \
|
||||
threadsignaltest.c
|
||||
|
||||
TESTS = $(SRC:.c=)
|
||||
|
||||
TAGFILES = \
|
||||
$(SRC) $(HDR)
|
||||
|
||||
CLEANFILES = $(OBJ) $(TESTS)
|
||||
|
||||
all: $(TESTS)
|
||||
|
||||
capturetest: $(srcdir)/capturetest.c ../libpcap.a
|
||||
$(CC) $(FULL_CFLAGS) -I. -L. -o capturetest $(srcdir)/capturetest.c ../libpcap.a $(LIBS)
|
||||
|
||||
can_set_rfmon_test: $(srcdir)/can_set_rfmon_test.c ../libpcap.a
|
||||
$(CC) $(FULL_CFLAGS) -I. -L. -o can_set_rfmon_test $(srcdir)/can_set_rfmon_test.c ../libpcap.a $(LIBS)
|
||||
|
||||
filtertest: $(srcdir)/filtertest.c ../libpcap.a
|
||||
$(CC) $(FULL_CFLAGS) -I. -L. -o filtertest $(srcdir)/filtertest.c ../libpcap.a $(EXTRA_NETWORK_LIBS) $(LIBS)
|
||||
|
||||
findalldevstest: $(srcdir)/findalldevstest.c ../libpcap.a
|
||||
$(CC) $(FULL_CFLAGS) -I. -L. -o findalldevstest $(srcdir)/findalldevstest.c ../libpcap.a $(EXTRA_NETWORK_LIBS) $(LIBS)
|
||||
|
||||
opentest: $(srcdir)/opentest.c ../libpcap.a
|
||||
$(CC) $(FULL_CFLAGS) -I. -L. -o opentest $(srcdir)/opentest.c ../libpcap.a $(LIBS)
|
||||
|
||||
reactivatetest: $(srcdir)/reactivatetest.c ../libpcap.a
|
||||
$(CC) $(FULL_CFLAGS) -I. -L. -o reactivatetest $(srcdir)/reactivatetest.c ../libpcap.a $(LIBS)
|
||||
|
||||
selpolltest: $(srcdir)/selpolltest.c ../libpcap.a
|
||||
$(CC) $(FULL_CFLAGS) -I. -L. -o selpolltest $(srcdir)/selpolltest.c ../libpcap.a $(LIBS)
|
||||
|
||||
threadsignaltest: $(srcdir)/threadsignaltest.c ../libpcap.a
|
||||
$(CC) $(FULL_CFLAGS) -I. -L. -o threadsignaltest $(srcdir)/threadsignaltest.c ../libpcap.a $(LIBS) $(PTHREAD_LIBS)
|
||||
|
||||
valgrindtest: $(srcdir)/valgrindtest.c ../libpcap.a
|
||||
$(CC) $(FULL_CFLAGS) -I. -L. -o valgrindtest $(srcdir)/valgrindtest.c ../libpcap.a $(LIBS)
|
||||
|
||||
clean:
|
||||
rm -f $(CLEANFILES)
|
||||
rm -rf *.dSYM
|
||||
|
||||
distclean: clean
|
||||
rm -f Makefile config.cache config.log config.status \
|
||||
config.h stamp-h stamp-h.in
|
||||
rm -rf autom4te.cache
|
||||
|
||||
install:
|
||||
|
||||
uninstall:
|
||||
|
||||
tags: $(TAGFILES)
|
||||
ctags -wtd $(TAGFILES)
|
||||
|
||||
depend:
|
||||
../$(MKDEP) -c "$(CC)" -m "$(DEPENDENCY_CFLAG)" $(CFLAGS) $(DEFS) $(INCLS) $(SRC)
|
||||
96
libpcap/testprogs/can_set_rfmon_test.c
Normal file
96
libpcap/testprogs/can_set_rfmon_test.c
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that: (1) source code distributions
|
||||
* retain the above copyright notice and this paragraph in its entirety, (2)
|
||||
* distributions including binary code include the above copyright notice and
|
||||
* this paragraph in its entirety in the documentation or other materials
|
||||
* provided with the distribution, and (3) all advertising materials mentioning
|
||||
* features or use of this software display the following acknowledgement:
|
||||
* ``This product includes software developed by the University of California,
|
||||
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
|
||||
* the University nor the names of its contributors may be used to endorse
|
||||
* or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include "varattrs.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char copyright[] _U_ =
|
||||
"@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <pcap.h>
|
||||
|
||||
#include "pcap/funcattrs.h"
|
||||
|
||||
static const char *program_name;
|
||||
|
||||
/* Forwards */
|
||||
static void PCAP_NORETURN error(PCAP_FORMAT_STRING(const char *), ...) PCAP_PRINTFLIKE(1,2);
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
const char *cp;
|
||||
pcap_t *pd;
|
||||
char ebuf[PCAP_ERRBUF_SIZE];
|
||||
int status;
|
||||
|
||||
if ((cp = strrchr(argv[0], '/')) != NULL)
|
||||
program_name = cp + 1;
|
||||
else
|
||||
program_name = argv[0];
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "Usage: %s <device>\n", program_name);
|
||||
return 2;
|
||||
}
|
||||
|
||||
pd = pcap_create(argv[1], ebuf);
|
||||
if (pd == NULL)
|
||||
error("%s", ebuf);
|
||||
status = pcap_can_set_rfmon(pd);
|
||||
if (status < 0) {
|
||||
if (status == PCAP_ERROR)
|
||||
error("%s: pcap_can_set_rfmon failed: %s", argv[1],
|
||||
pcap_geterr(pd));
|
||||
else
|
||||
error("%s: pcap_can_set_rfmon failed: %s", argv[1],
|
||||
pcap_statustostr(status));
|
||||
return 1;
|
||||
}
|
||||
printf("%s: Monitor mode %s be set\n", argv[1], status ? "can" : "cannot");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* VARARGS */
|
||||
static void
|
||||
error(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
(void)fprintf(stderr, "%s: ", program_name);
|
||||
va_start(ap, fmt);
|
||||
(void)vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
if (*fmt) {
|
||||
fmt += strlen(fmt);
|
||||
if (fmt[-1] != '\n')
|
||||
(void)fputc('\n', stderr);
|
||||
}
|
||||
exit(1);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
299
libpcap/testprogs/capturetest.c
Normal file
299
libpcap/testprogs/capturetest.c
Normal file
@@ -0,0 +1,299 @@
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that: (1) source code distributions
|
||||
* retain the above copyright notice and this paragraph in its entirety, (2)
|
||||
* distributions including binary code include the above copyright notice and
|
||||
* this paragraph in its entirety in the documentation or other materials
|
||||
* provided with the distribution, and (3) all advertising materials mentioning
|
||||
* features or use of this software display the following acknowledgement:
|
||||
* ``This product includes software developed by the University of California,
|
||||
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
|
||||
* the University nor the names of its contributors may be used to endorse
|
||||
* or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include "varattrs.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char copyright[] _U_ =
|
||||
"@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <limits.h>
|
||||
#ifdef _WIN32
|
||||
#include "getopt.h"
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <pcap.h>
|
||||
|
||||
#include "pcap/funcattrs.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "portability.h"
|
||||
#endif
|
||||
|
||||
static char *program_name;
|
||||
|
||||
/* Forwards */
|
||||
static void countme(u_char *, const struct pcap_pkthdr *, const u_char *);
|
||||
static void PCAP_NORETURN usage(void);
|
||||
static void PCAP_NORETURN error(const char *, ...) PCAP_PRINTFLIKE(1, 2);
|
||||
static void warning(const char *, ...) PCAP_PRINTFLIKE(1, 2);
|
||||
static char *copy_argv(char **);
|
||||
|
||||
static pcap_t *pd;
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
register int op;
|
||||
register char *cp, *cmdbuf, *device;
|
||||
long longarg;
|
||||
char *p;
|
||||
int timeout = 1000;
|
||||
int immediate = 0;
|
||||
int nonblock = 0;
|
||||
pcap_if_t *devlist;
|
||||
bpf_u_int32 localnet, netmask;
|
||||
struct bpf_program fcode;
|
||||
char ebuf[PCAP_ERRBUF_SIZE];
|
||||
int status;
|
||||
int packet_count;
|
||||
|
||||
device = NULL;
|
||||
if ((cp = strrchr(argv[0], '/')) != NULL)
|
||||
program_name = cp + 1;
|
||||
else
|
||||
program_name = argv[0];
|
||||
|
||||
opterr = 0;
|
||||
while ((op = getopt(argc, argv, "i:mnt:")) != -1) {
|
||||
switch (op) {
|
||||
|
||||
case 'i':
|
||||
device = optarg;
|
||||
break;
|
||||
|
||||
case 'm':
|
||||
immediate = 1;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
nonblock = 1;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
longarg = strtol(optarg, &p, 10);
|
||||
if (p == optarg || *p != '\0') {
|
||||
error("Timeout value \"%s\" is not a number",
|
||||
optarg);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
if (longarg < 0) {
|
||||
error("Timeout value %ld is negative", longarg);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
if (longarg > INT_MAX) {
|
||||
error("Timeout value %ld is too large (> %d)",
|
||||
longarg, INT_MAX);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
timeout = (int)longarg;
|
||||
break;
|
||||
|
||||
default:
|
||||
usage();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
}
|
||||
|
||||
if (device == NULL) {
|
||||
if (pcap_findalldevs(&devlist, ebuf) == -1)
|
||||
error("%s", ebuf);
|
||||
if (devlist == NULL)
|
||||
error("no interfaces available for capture");
|
||||
device = strdup(devlist->name);
|
||||
pcap_freealldevs(devlist);
|
||||
}
|
||||
*ebuf = '\0';
|
||||
pd = pcap_create(device, ebuf);
|
||||
if (pd == NULL)
|
||||
error("%s", ebuf);
|
||||
status = pcap_set_snaplen(pd, 65535);
|
||||
if (status != 0)
|
||||
error("%s: pcap_set_snaplen failed: %s",
|
||||
device, pcap_statustostr(status));
|
||||
if (immediate) {
|
||||
status = pcap_set_immediate_mode(pd, 1);
|
||||
if (status != 0)
|
||||
error("%s: pcap_set_immediate_mode failed: %s",
|
||||
device, pcap_statustostr(status));
|
||||
}
|
||||
status = pcap_set_timeout(pd, timeout);
|
||||
if (status != 0)
|
||||
error("%s: pcap_set_timeout failed: %s",
|
||||
device, pcap_statustostr(status));
|
||||
status = pcap_activate(pd);
|
||||
if (status < 0) {
|
||||
/*
|
||||
* pcap_activate() failed.
|
||||
*/
|
||||
error("%s: %s\n(%s)", device,
|
||||
pcap_statustostr(status), pcap_geterr(pd));
|
||||
} else if (status > 0) {
|
||||
/*
|
||||
* pcap_activate() succeeded, but it's warning us
|
||||
* of a problem it had.
|
||||
*/
|
||||
warning("%s: %s\n(%s)", device,
|
||||
pcap_statustostr(status), pcap_geterr(pd));
|
||||
}
|
||||
if (pcap_lookupnet(device, &localnet, &netmask, ebuf) < 0) {
|
||||
localnet = 0;
|
||||
netmask = 0;
|
||||
warning("%s", ebuf);
|
||||
}
|
||||
cmdbuf = copy_argv(&argv[optind]);
|
||||
|
||||
if (pcap_compile(pd, &fcode, cmdbuf, 1, netmask) < 0)
|
||||
error("%s", pcap_geterr(pd));
|
||||
|
||||
if (pcap_setfilter(pd, &fcode) < 0)
|
||||
error("%s", pcap_geterr(pd));
|
||||
if (pcap_setnonblock(pd, nonblock, ebuf) == -1)
|
||||
error("pcap_setnonblock failed: %s", ebuf);
|
||||
printf("Listening on %s\n", device);
|
||||
for (;;) {
|
||||
packet_count = 0;
|
||||
status = pcap_dispatch(pd, -1, countme,
|
||||
(u_char *)&packet_count);
|
||||
if (status < 0)
|
||||
break;
|
||||
if (status != 0) {
|
||||
printf("%d packets seen, %d packets counted after pcap_dispatch returns\n",
|
||||
status, packet_count);
|
||||
}
|
||||
}
|
||||
if (status == -2) {
|
||||
/*
|
||||
* We got interrupted, so perhaps we didn't
|
||||
* manage to finish a line we were printing.
|
||||
* Print an extra newline, just in case.
|
||||
*/
|
||||
putchar('\n');
|
||||
}
|
||||
(void)fflush(stdout);
|
||||
if (status == -1) {
|
||||
/*
|
||||
* Error. Report it.
|
||||
*/
|
||||
(void)fprintf(stderr, "%s: pcap_loop: %s\n",
|
||||
program_name, pcap_geterr(pd));
|
||||
}
|
||||
pcap_close(pd);
|
||||
pcap_freecode(&fcode);
|
||||
free(cmdbuf);
|
||||
exit(status == -1 ? 1 : 0);
|
||||
}
|
||||
|
||||
static void
|
||||
countme(u_char *user, const struct pcap_pkthdr *h _U_, const u_char *sp _U_)
|
||||
{
|
||||
int *counterp = (int *)user;
|
||||
|
||||
(*counterp)++;
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
(void)fprintf(stderr, "Usage: %s [ -mn ] [ -i interface ] [ -t timeout] [expression]\n",
|
||||
program_name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* VARARGS */
|
||||
static void
|
||||
error(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
(void)fprintf(stderr, "%s: ", program_name);
|
||||
va_start(ap, fmt);
|
||||
(void)vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
if (*fmt) {
|
||||
fmt += strlen(fmt);
|
||||
if (fmt[-1] != '\n')
|
||||
(void)fputc('\n', stderr);
|
||||
}
|
||||
exit(1);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/* VARARGS */
|
||||
static void
|
||||
warning(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
(void)fprintf(stderr, "%s: WARNING: ", program_name);
|
||||
va_start(ap, fmt);
|
||||
(void)vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
if (*fmt) {
|
||||
fmt += strlen(fmt);
|
||||
if (fmt[-1] != '\n')
|
||||
(void)fputc('\n', stderr);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy arg vector into a new buffer, concatenating arguments with spaces.
|
||||
*/
|
||||
static char *
|
||||
copy_argv(register char **argv)
|
||||
{
|
||||
register char **p;
|
||||
register u_int len = 0;
|
||||
char *buf;
|
||||
char *src, *dst;
|
||||
|
||||
p = argv;
|
||||
if (*p == 0)
|
||||
return 0;
|
||||
|
||||
while (*p)
|
||||
len += strlen(*p++) + 1;
|
||||
|
||||
buf = (char *)malloc(len);
|
||||
if (buf == NULL)
|
||||
error("copy_argv: malloc");
|
||||
|
||||
p = argv;
|
||||
dst = buf;
|
||||
while ((src = *p++) != NULL) {
|
||||
while ((*dst++ = *src++) != '\0')
|
||||
;
|
||||
dst[-1] = ' ';
|
||||
}
|
||||
dst[-1] = '\0';
|
||||
|
||||
return buf;
|
||||
}
|
||||
359
libpcap/testprogs/filtertest.c
Normal file
359
libpcap/testprogs/filtertest.c
Normal file
@@ -0,0 +1,359 @@
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that: (1) source code distributions
|
||||
* retain the above copyright notice and this paragraph in its entirety, (2)
|
||||
* distributions including binary code include the above copyright notice and
|
||||
* this paragraph in its entirety in the documentation or other materials
|
||||
* provided with the distribution, and (3) all advertising materials mentioning
|
||||
* features or use of this software display the following acknowledgement:
|
||||
* ``This product includes software developed by the University of California,
|
||||
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
|
||||
* the University nor the names of its contributors may be used to endorse
|
||||
* or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include "varattrs.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char copyright[] _U_ =
|
||||
"@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <pcap.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#ifdef _WIN32
|
||||
#include "getopt.h"
|
||||
#include "unix.h"
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "pcap/funcattrs.h"
|
||||
|
||||
#ifdef BDEBUG
|
||||
/*
|
||||
* We have pcap_set_optimizer_debug() and pcap_set_print_dot_graph() in
|
||||
* libpcap; declare them (they're not declared by any libpcap header,
|
||||
* because they're special hacks, only available if libpcap was configured
|
||||
* to include them, and only intended for use by libpcap developers trying
|
||||
* to debug the optimizer for filter expressions).
|
||||
*/
|
||||
PCAP_API void pcap_set_optimizer_debug(int);
|
||||
PCAP_API void pcap_set_print_dot_graph(int);
|
||||
#endif
|
||||
|
||||
static char *program_name;
|
||||
|
||||
/* Forwards */
|
||||
static void PCAP_NORETURN usage(void);
|
||||
static void PCAP_NORETURN error(const char *, ...) PCAP_PRINTFLIKE(1, 2);
|
||||
static void warn(const char *, ...) PCAP_PRINTFLIKE(1, 2);
|
||||
|
||||
/*
|
||||
* On Windows, we need to open the file in binary mode, so that
|
||||
* we get all the bytes specified by the size we get from "fstat()".
|
||||
* On UNIX, that's not necessary. O_BINARY is defined on Windows;
|
||||
* we define it as 0 if it's not defined, so it does nothing.
|
||||
*/
|
||||
#ifndef O_BINARY
|
||||
#define O_BINARY 0
|
||||
#endif
|
||||
|
||||
static char *
|
||||
read_infile(char *fname)
|
||||
{
|
||||
register int i, fd, cc;
|
||||
register char *cp;
|
||||
struct stat buf;
|
||||
|
||||
fd = open(fname, O_RDONLY|O_BINARY);
|
||||
if (fd < 0)
|
||||
error("can't open %s: %s", fname, pcap_strerror(errno));
|
||||
|
||||
if (fstat(fd, &buf) < 0)
|
||||
error("can't stat %s: %s", fname, pcap_strerror(errno));
|
||||
|
||||
cp = malloc((u_int)buf.st_size + 1);
|
||||
if (cp == NULL)
|
||||
error("malloc(%d) for %s: %s", (u_int)buf.st_size + 1,
|
||||
fname, pcap_strerror(errno));
|
||||
cc = read(fd, cp, (u_int)buf.st_size);
|
||||
if (cc < 0)
|
||||
error("read %s: %s", fname, pcap_strerror(errno));
|
||||
if (cc != buf.st_size)
|
||||
error("short read %s (%d != %d)", fname, cc, (int)buf.st_size);
|
||||
|
||||
close(fd);
|
||||
/* replace "# comment" with spaces */
|
||||
for (i = 0; i < cc; i++) {
|
||||
if (cp[i] == '#')
|
||||
while (i < cc && cp[i] != '\n')
|
||||
cp[i++] = ' ';
|
||||
}
|
||||
cp[cc] = '\0';
|
||||
return (cp);
|
||||
}
|
||||
|
||||
/* VARARGS */
|
||||
static void
|
||||
error(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
(void)fprintf(stderr, "%s: ", program_name);
|
||||
va_start(ap, fmt);
|
||||
(void)vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
if (*fmt) {
|
||||
fmt += strlen(fmt);
|
||||
if (fmt[-1] != '\n')
|
||||
(void)fputc('\n', stderr);
|
||||
}
|
||||
exit(1);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/* VARARGS */
|
||||
static void
|
||||
warn(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
(void)fprintf(stderr, "%s: WARNING: ", program_name);
|
||||
va_start(ap, fmt);
|
||||
(void)vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
if (*fmt) {
|
||||
fmt += strlen(fmt);
|
||||
if (fmt[-1] != '\n')
|
||||
(void)fputc('\n', stderr);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy arg vector into a new buffer, concatenating arguments with spaces.
|
||||
*/
|
||||
static char *
|
||||
copy_argv(register char **argv)
|
||||
{
|
||||
register char **p;
|
||||
register u_int len = 0;
|
||||
char *buf;
|
||||
char *src, *dst;
|
||||
|
||||
p = argv;
|
||||
if (*p == 0)
|
||||
return 0;
|
||||
|
||||
while (*p)
|
||||
len += strlen(*p++) + 1;
|
||||
|
||||
buf = (char *)malloc(len);
|
||||
if (buf == NULL)
|
||||
error("copy_argv: malloc");
|
||||
|
||||
p = argv;
|
||||
dst = buf;
|
||||
while ((src = *p++) != NULL) {
|
||||
while ((*dst++ = *src++) != '\0')
|
||||
;
|
||||
dst[-1] = ' ';
|
||||
}
|
||||
dst[-1] = '\0';
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
char *cp;
|
||||
int op;
|
||||
int dflag;
|
||||
int gflag;
|
||||
char *infile;
|
||||
int Oflag;
|
||||
long snaplen;
|
||||
char *p;
|
||||
int dlt;
|
||||
int have_fcode = 0;
|
||||
bpf_u_int32 netmask = PCAP_NETMASK_UNKNOWN;
|
||||
char *cmdbuf;
|
||||
pcap_t *pd;
|
||||
struct bpf_program fcode;
|
||||
|
||||
#ifdef _WIN32
|
||||
if (pcap_wsockinit() != 0)
|
||||
return 1;
|
||||
#endif /* _WIN32 */
|
||||
|
||||
dflag = 1;
|
||||
gflag = 0;
|
||||
|
||||
infile = NULL;
|
||||
Oflag = 1;
|
||||
snaplen = 68;
|
||||
|
||||
if ((cp = strrchr(argv[0], '/')) != NULL)
|
||||
program_name = cp + 1;
|
||||
else
|
||||
program_name = argv[0];
|
||||
|
||||
opterr = 0;
|
||||
while ((op = getopt(argc, argv, "dF:gm:Os:")) != -1) {
|
||||
switch (op) {
|
||||
|
||||
case 'd':
|
||||
++dflag;
|
||||
break;
|
||||
|
||||
case 'g':
|
||||
#ifdef BDEBUG
|
||||
++gflag;
|
||||
#else
|
||||
error("libpcap and filtertest not built with optimizer debugging enabled");
|
||||
#endif
|
||||
break;
|
||||
|
||||
case 'F':
|
||||
infile = optarg;
|
||||
break;
|
||||
|
||||
case 'O':
|
||||
Oflag = 0;
|
||||
break;
|
||||
|
||||
case 'm': {
|
||||
bpf_u_int32 addr;
|
||||
|
||||
switch (inet_pton(AF_INET, optarg, &addr)) {
|
||||
|
||||
case 0:
|
||||
error("invalid netmask %s", optarg);
|
||||
break;
|
||||
|
||||
case -1:
|
||||
error("invalid netmask %s: %s", optarg,
|
||||
pcap_strerror(errno));
|
||||
break;
|
||||
|
||||
case 1:
|
||||
netmask = addr;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 's': {
|
||||
char *end;
|
||||
|
||||
snaplen = strtol(optarg, &end, 0);
|
||||
if (optarg == end || *end != '\0'
|
||||
|| snaplen < 0 || snaplen > 65535)
|
||||
error("invalid snaplen %s", optarg);
|
||||
else if (snaplen == 0)
|
||||
snaplen = 65535;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
usage();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
}
|
||||
|
||||
if (optind >= argc) {
|
||||
usage();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
dlt = pcap_datalink_name_to_val(argv[optind]);
|
||||
if (dlt < 0) {
|
||||
dlt = (int)strtol(argv[optind], &p, 10);
|
||||
if (p == argv[optind] || *p != '\0')
|
||||
error("invalid data link type %s", argv[optind]);
|
||||
}
|
||||
|
||||
if (infile)
|
||||
cmdbuf = read_infile(infile);
|
||||
else
|
||||
cmdbuf = copy_argv(&argv[optind+1]);
|
||||
|
||||
#ifdef BDEBUG
|
||||
pcap_set_optimizer_debug(dflag);
|
||||
pcap_set_print_dot_graph(gflag);
|
||||
#endif
|
||||
|
||||
pd = pcap_open_dead(dlt, snaplen);
|
||||
if (pd == NULL)
|
||||
error("Can't open fake pcap_t");
|
||||
|
||||
if (pcap_compile(pd, &fcode, cmdbuf, Oflag, netmask) < 0)
|
||||
error("%s", pcap_geterr(pd));
|
||||
|
||||
have_fcode = 1;
|
||||
if (!bpf_validate(fcode.bf_insns, fcode.bf_len))
|
||||
warn("Filter doesn't pass validation");
|
||||
|
||||
#ifdef BDEBUG
|
||||
if (cmdbuf != NULL) {
|
||||
// replace line feed with space
|
||||
for (cp = cmdbuf; *cp != '\0'; ++cp) {
|
||||
if (*cp == '\r' || *cp == '\n') {
|
||||
*cp = ' ';
|
||||
}
|
||||
}
|
||||
// only show machine code if BDEBUG defined, since dflag > 3
|
||||
printf("machine codes for filter: %s\n", cmdbuf);
|
||||
} else
|
||||
printf("machine codes for empty filter:\n");
|
||||
#endif
|
||||
|
||||
bpf_dump(&fcode, dflag);
|
||||
free(cmdbuf);
|
||||
if (have_fcode)
|
||||
pcap_freecode (&fcode);
|
||||
pcap_close(pd);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
(void)fprintf(stderr, "%s, with %s\n", program_name,
|
||||
pcap_lib_version());
|
||||
(void)fprintf(stderr,
|
||||
#ifdef BDEBUG
|
||||
"Usage: %s [-dgO] [ -F file ] [ -m netmask] [ -s snaplen ] dlt [ expression ]\n",
|
||||
#else
|
||||
"Usage: %s [-dO] [ -F file ] [ -m netmask] [ -s snaplen ] dlt [ expression ]\n",
|
||||
#endif
|
||||
program_name);
|
||||
exit(1);
|
||||
}
|
||||
311
libpcap/testprogs/findalldevstest.c
Normal file
311
libpcap/testprogs/findalldevstest.c
Normal file
@@ -0,0 +1,311 @@
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <pcap.h>
|
||||
|
||||
#include "pcap/funcattrs.h"
|
||||
|
||||
static int ifprint(pcap_if_t *d);
|
||||
static char *iptos(bpf_u_int32 in);
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "portability.h"
|
||||
|
||||
/*
|
||||
* Generate a string for a Win32-specific error (i.e. an error generated when
|
||||
* calling a Win32 API).
|
||||
* For errors occurred during standard C calls, we still use pcap_strerror()
|
||||
*/
|
||||
#define ERRBUF_SIZE 1024
|
||||
static const char *
|
||||
win32_strerror(DWORD error)
|
||||
{
|
||||
static char errbuf[ERRBUF_SIZE+1];
|
||||
size_t errlen;
|
||||
|
||||
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf,
|
||||
ERRBUF_SIZE, NULL);
|
||||
|
||||
/*
|
||||
* "FormatMessage()" "helpfully" sticks CR/LF at the end of the
|
||||
* message. Get rid of it.
|
||||
*/
|
||||
errlen = strlen(errbuf);
|
||||
if (errlen >= 2) {
|
||||
errbuf[errlen - 1] = '\0';
|
||||
errbuf[errlen - 2] = '\0';
|
||||
errlen -= 2;
|
||||
}
|
||||
return errbuf;
|
||||
}
|
||||
|
||||
static char *
|
||||
getpass(const char *prompt)
|
||||
{
|
||||
HANDLE console_handle = GetStdHandle(STD_INPUT_HANDLE);
|
||||
DWORD console_mode, save_console_mode;
|
||||
static char password[128+1];
|
||||
char *p;
|
||||
|
||||
fprintf(stderr, "%s", prompt);
|
||||
|
||||
/*
|
||||
* Turn off echoing.
|
||||
*/
|
||||
if (!GetConsoleMode(console_handle, &console_mode)) {
|
||||
fprintf(stderr, "Can't get console mode: %s\n",
|
||||
win32_strerror(GetLastError()));
|
||||
exit(1);
|
||||
}
|
||||
save_console_mode = console_mode;
|
||||
console_mode &= ~ENABLE_ECHO_INPUT;
|
||||
if (!SetConsoleMode(console_handle, console_mode)) {
|
||||
fprintf(stderr, "Can't set console mode: %s\n",
|
||||
win32_strerror(GetLastError()));
|
||||
exit(1);
|
||||
}
|
||||
if (fgets(password, sizeof password, stdin) == NULL) {
|
||||
fprintf(stderr, "\n");
|
||||
SetConsoleMode(console_handle, save_console_mode);
|
||||
exit(1);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
SetConsoleMode(console_handle, save_console_mode);
|
||||
p = strchr(password, '\n');
|
||||
if (p != NULL)
|
||||
*p = '\0';
|
||||
return password;
|
||||
}
|
||||
#endif
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
pcap_if_t *alldevs;
|
||||
pcap_if_t *d;
|
||||
bpf_u_int32 net, mask;
|
||||
int exit_status = 0;
|
||||
char errbuf[PCAP_ERRBUF_SIZE+1];
|
||||
#ifdef ENABLE_REMOTE
|
||||
struct pcap_rmtauth auth;
|
||||
char username[128+1];
|
||||
char *p;
|
||||
char *password;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_REMOTE
|
||||
if (argc >= 2)
|
||||
{
|
||||
if (pcap_findalldevs_ex(argv[1], NULL, &alldevs, errbuf) == -1)
|
||||
{
|
||||
/*
|
||||
* OK, try it with a user name and password.
|
||||
*/
|
||||
fprintf(stderr, "User name: ");
|
||||
if (fgets(username, sizeof username, stdin) == NULL)
|
||||
exit(1);
|
||||
p = strchr(username, '\n');
|
||||
if (p != NULL)
|
||||
*p = '\0';
|
||||
password = getpass("Password: ");
|
||||
auth.type = RPCAP_RMTAUTH_PWD;
|
||||
auth.username = username;
|
||||
auth.password = password;
|
||||
if (pcap_findalldevs_ex(argv[1], &auth, &alldevs, errbuf) == -1)
|
||||
{
|
||||
fprintf(stderr,"Error in pcap_findalldevs: %s\n",errbuf);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
if (pcap_findalldevs(&alldevs, errbuf) == -1)
|
||||
{
|
||||
fprintf(stderr,"Error in pcap_findalldevs: %s\n",errbuf);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
for(d=alldevs;d;d=d->next)
|
||||
{
|
||||
if (!ifprint(d))
|
||||
exit_status = 2;
|
||||
}
|
||||
|
||||
if (alldevs != NULL)
|
||||
{
|
||||
if (pcap_lookupnet(alldevs->name, &net, &mask, errbuf) < 0)
|
||||
{
|
||||
fprintf(stderr,"Error in pcap_lookupnet: %s\n",errbuf);
|
||||
exit_status = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Preferred device is on network: %s/%s\n",iptos(net), iptos(mask));
|
||||
}
|
||||
}
|
||||
|
||||
pcap_freealldevs(alldevs);
|
||||
exit(exit_status);
|
||||
}
|
||||
|
||||
static int ifprint(pcap_if_t *d)
|
||||
{
|
||||
pcap_addr_t *a;
|
||||
char ipv4_buf[INET_ADDRSTRLEN];
|
||||
char ipv6_buf[INET6_ADDRSTRLEN];
|
||||
const char *sep;
|
||||
int status = 1; /* success */
|
||||
|
||||
printf("%s\n",d->name);
|
||||
if (d->description)
|
||||
printf("\tDescription: %s\n",d->description);
|
||||
printf("\tFlags: ");
|
||||
sep = "";
|
||||
if (d->flags & PCAP_IF_UP) {
|
||||
printf("%sUP", sep);
|
||||
sep = ", ";
|
||||
}
|
||||
if (d->flags & PCAP_IF_RUNNING) {
|
||||
printf("%sRUNNING", sep);
|
||||
sep = ", ";
|
||||
}
|
||||
if (d->flags & PCAP_IF_LOOPBACK) {
|
||||
printf("%sLOOPBACK", sep);
|
||||
sep = ", ";
|
||||
}
|
||||
if (d->flags & PCAP_IF_WIRELESS) {
|
||||
printf("%sWIRELESS", sep);
|
||||
switch (d->flags & PCAP_IF_CONNECTION_STATUS) {
|
||||
|
||||
case PCAP_IF_CONNECTION_STATUS_UNKNOWN:
|
||||
printf(" (association status unknown)");
|
||||
break;
|
||||
|
||||
case PCAP_IF_CONNECTION_STATUS_CONNECTED:
|
||||
printf(" (associated)");
|
||||
break;
|
||||
|
||||
case PCAP_IF_CONNECTION_STATUS_DISCONNECTED:
|
||||
printf(" (not associated)");
|
||||
break;
|
||||
|
||||
case PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (d->flags & PCAP_IF_CONNECTION_STATUS) {
|
||||
|
||||
case PCAP_IF_CONNECTION_STATUS_UNKNOWN:
|
||||
printf(" (connection status unknown)");
|
||||
break;
|
||||
|
||||
case PCAP_IF_CONNECTION_STATUS_CONNECTED:
|
||||
printf(" (connected)");
|
||||
break;
|
||||
|
||||
case PCAP_IF_CONNECTION_STATUS_DISCONNECTED:
|
||||
printf(" (disconnected)");
|
||||
break;
|
||||
|
||||
case PCAP_IF_CONNECTION_STATUS_NOT_APPLICABLE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
sep = ", ";
|
||||
printf("\n");
|
||||
|
||||
for(a=d->addresses;a;a=a->next) {
|
||||
if (a->addr != NULL)
|
||||
switch(a->addr->sa_family) {
|
||||
case AF_INET:
|
||||
printf("\tAddress Family: AF_INET\n");
|
||||
if (a->addr)
|
||||
printf("\t\tAddress: %s\n",
|
||||
inet_ntop(AF_INET,
|
||||
&((struct sockaddr_in *)(a->addr))->sin_addr,
|
||||
ipv4_buf, sizeof ipv4_buf));
|
||||
if (a->netmask)
|
||||
printf("\t\tNetmask: %s\n",
|
||||
inet_ntop(AF_INET,
|
||||
&((struct sockaddr_in *)(a->netmask))->sin_addr,
|
||||
ipv4_buf, sizeof ipv4_buf));
|
||||
if (a->broadaddr)
|
||||
printf("\t\tBroadcast Address: %s\n",
|
||||
inet_ntop(AF_INET,
|
||||
&((struct sockaddr_in *)(a->broadaddr))->sin_addr,
|
||||
ipv4_buf, sizeof ipv4_buf));
|
||||
if (a->dstaddr)
|
||||
printf("\t\tDestination Address: %s\n",
|
||||
inet_ntop(AF_INET,
|
||||
&((struct sockaddr_in *)(a->dstaddr))->sin_addr,
|
||||
ipv4_buf, sizeof ipv4_buf));
|
||||
break;
|
||||
#ifdef INET6
|
||||
case AF_INET6:
|
||||
printf("\tAddress Family: AF_INET6\n");
|
||||
if (a->addr)
|
||||
printf("\t\tAddress: %s\n",
|
||||
inet_ntop(AF_INET6,
|
||||
((struct sockaddr_in6 *)(a->addr))->sin6_addr.s6_addr,
|
||||
ipv6_buf, sizeof ipv6_buf));
|
||||
if (a->netmask)
|
||||
printf("\t\tNetmask: %s\n",
|
||||
inet_ntop(AF_INET6,
|
||||
((struct sockaddr_in6 *)(a->netmask))->sin6_addr.s6_addr,
|
||||
ipv6_buf, sizeof ipv6_buf));
|
||||
if (a->broadaddr)
|
||||
printf("\t\tBroadcast Address: %s\n",
|
||||
inet_ntop(AF_INET6,
|
||||
((struct sockaddr_in6 *)(a->broadaddr))->sin6_addr.s6_addr,
|
||||
ipv6_buf, sizeof ipv6_buf));
|
||||
if (a->dstaddr)
|
||||
printf("\t\tDestination Address: %s\n",
|
||||
inet_ntop(AF_INET6,
|
||||
((struct sockaddr_in6 *)(a->dstaddr))->sin6_addr.s6_addr,
|
||||
ipv6_buf, sizeof ipv6_buf));
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
printf("\tAddress Family: Unknown (%d)\n", a->addr->sa_family);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "\tWarning: a->addr is NULL, skipping this address.\n");
|
||||
status = 0;
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
return status;
|
||||
}
|
||||
|
||||
/* From tcptraceroute */
|
||||
#define IPTOSBUFFERS 12
|
||||
static char *iptos(bpf_u_int32 in)
|
||||
{
|
||||
static char output[IPTOSBUFFERS][3*4+3+1];
|
||||
static short which;
|
||||
u_char *p;
|
||||
|
||||
p = (u_char *)∈
|
||||
which = (which + 1 == IPTOSBUFFERS ? 0 : which + 1);
|
||||
sprintf(output[which], "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
|
||||
return output[which];
|
||||
}
|
||||
236
libpcap/testprogs/opentest.c
Normal file
236
libpcap/testprogs/opentest.c
Normal file
@@ -0,0 +1,236 @@
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that: (1) source code distributions
|
||||
* retain the above copyright notice and this paragraph in its entirety, (2)
|
||||
* distributions including binary code include the above copyright notice and
|
||||
* this paragraph in its entirety in the documentation or other materials
|
||||
* provided with the distribution, and (3) all advertising materials mentioning
|
||||
* features or use of this software display the following acknowledgement:
|
||||
* ``This product includes software developed by the University of California,
|
||||
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
|
||||
* the University nor the names of its contributors may be used to endorse
|
||||
* or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include "varattrs.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char copyright[] _U_ =
|
||||
"@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif
|
||||
|
||||
#include <pcap.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#ifdef _WIN32
|
||||
#include "getopt.h"
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
|
||||
#include "pcap/funcattrs.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "portability.h"
|
||||
#endif
|
||||
|
||||
#define MAXIMUM_SNAPLEN 65535
|
||||
|
||||
static char *program_name;
|
||||
|
||||
/* Forwards */
|
||||
static void PCAP_NORETURN usage(void);
|
||||
static void PCAP_NORETURN error(const char *, ...) PCAP_PRINTFLIKE(1, 2);
|
||||
static void warning(const char *, ...) PCAP_PRINTFLIKE(1, 2);
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
register int op;
|
||||
register char *cp, *device;
|
||||
int dorfmon, dopromisc, snaplen, useactivate, bufsize;
|
||||
char ebuf[PCAP_ERRBUF_SIZE];
|
||||
pcap_if_t *devlist;
|
||||
pcap_t *pd;
|
||||
int status = 0;
|
||||
|
||||
device = NULL;
|
||||
dorfmon = 0;
|
||||
dopromisc = 0;
|
||||
snaplen = MAXIMUM_SNAPLEN;
|
||||
bufsize = 0;
|
||||
useactivate = 0;
|
||||
if ((cp = strrchr(argv[0], '/')) != NULL)
|
||||
program_name = cp + 1;
|
||||
else
|
||||
program_name = argv[0];
|
||||
|
||||
opterr = 0;
|
||||
while ((op = getopt(argc, argv, "i:Ips:aB:")) != -1) {
|
||||
switch (op) {
|
||||
|
||||
case 'i':
|
||||
device = optarg;
|
||||
break;
|
||||
|
||||
case 'I':
|
||||
dorfmon = 1;
|
||||
useactivate = 1; /* required for rfmon */
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
dopromisc = 1;
|
||||
break;
|
||||
|
||||
case 's': {
|
||||
char *end;
|
||||
|
||||
snaplen = strtol(optarg, &end, 0);
|
||||
if (optarg == end || *end != '\0'
|
||||
|| snaplen < 0 || snaplen > MAXIMUM_SNAPLEN)
|
||||
error("invalid snaplen %s", optarg);
|
||||
else if (snaplen == 0)
|
||||
snaplen = MAXIMUM_SNAPLEN;
|
||||
break;
|
||||
}
|
||||
|
||||
case 'B':
|
||||
bufsize = atoi(optarg)*1024;
|
||||
if (bufsize <= 0)
|
||||
error("invalid packet buffer size %s", optarg);
|
||||
useactivate = 1; /* required for bufsize */
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
useactivate = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
usage();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
}
|
||||
|
||||
if (device == NULL) {
|
||||
if (pcap_findalldevs(&devlist, ebuf) == -1)
|
||||
error("%s", ebuf);
|
||||
if (devlist == NULL)
|
||||
error("no interfaces available for capture");
|
||||
device = strdup(devlist->name);
|
||||
pcap_freealldevs(devlist);
|
||||
}
|
||||
if (useactivate) {
|
||||
pd = pcap_create(device, ebuf);
|
||||
if (pd == NULL)
|
||||
error("%s: pcap_create failed: %s", device, ebuf);
|
||||
status = pcap_set_snaplen(pd, snaplen);
|
||||
if (status != 0)
|
||||
error("%s: pcap_set_snaplen failed: %s",
|
||||
device, pcap_statustostr(status));
|
||||
if (dopromisc) {
|
||||
status = pcap_set_promisc(pd, 1);
|
||||
if (status != 0)
|
||||
error("%s: pcap_set_promisc failed: %s",
|
||||
device, pcap_statustostr(status));
|
||||
}
|
||||
if (dorfmon) {
|
||||
status = pcap_set_rfmon(pd, 1);
|
||||
if (status != 0)
|
||||
error("%s: pcap_set_rfmon failed: %s",
|
||||
device, pcap_statustostr(status));
|
||||
}
|
||||
status = pcap_set_timeout(pd, 1000);
|
||||
if (status != 0)
|
||||
error("%s: pcap_set_timeout failed: %s",
|
||||
device, pcap_statustostr(status));
|
||||
if (bufsize != 0) {
|
||||
status = pcap_set_buffer_size(pd, bufsize);
|
||||
if (status != 0)
|
||||
error("%s: pcap_set_buffer_size failed: %s",
|
||||
device, pcap_statustostr(status));
|
||||
}
|
||||
status = pcap_activate(pd);
|
||||
if (status < 0) {
|
||||
/*
|
||||
* pcap_activate() failed.
|
||||
*/
|
||||
error("%s: %s\n(%s)", device,
|
||||
pcap_statustostr(status), pcap_geterr(pd));
|
||||
} else if (status > 0) {
|
||||
/*
|
||||
* pcap_activate() succeeded, but it's warning us
|
||||
* of a problem it had.
|
||||
*/
|
||||
warning("%s: %s\n(%s)", device,
|
||||
pcap_statustostr(status), pcap_geterr(pd));
|
||||
} else
|
||||
printf("%s opened successfully\n", device);
|
||||
} else {
|
||||
*ebuf = '\0';
|
||||
pd = pcap_open_live(device, 65535, 0, 1000, ebuf);
|
||||
if (pd == NULL)
|
||||
error("%s", ebuf);
|
||||
else if (*ebuf)
|
||||
warning("%s", ebuf);
|
||||
else
|
||||
printf("%s opened successfully\n", device);
|
||||
}
|
||||
pcap_close(pd);
|
||||
exit(status < 0 ? 1 : 0);
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
(void)fprintf(stderr,
|
||||
"Usage: %s [ -Ipa ] [ -i interface ] [ -s snaplen ] [ -B bufsize ]\n",
|
||||
program_name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* VARARGS */
|
||||
static void
|
||||
error(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
(void)fprintf(stderr, "%s: ", program_name);
|
||||
va_start(ap, fmt);
|
||||
(void)vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
if (*fmt) {
|
||||
fmt += strlen(fmt);
|
||||
if (fmt[-1] != '\n')
|
||||
(void)fputc('\n', stderr);
|
||||
}
|
||||
exit(1);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/* VARARGS */
|
||||
static void
|
||||
warning(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
(void)fprintf(stderr, "%s: WARNING: ", program_name);
|
||||
va_start(ap, fmt);
|
||||
(void)vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
if (*fmt) {
|
||||
fmt += strlen(fmt);
|
||||
if (fmt[-1] != '\n')
|
||||
(void)fputc('\n', stderr);
|
||||
}
|
||||
}
|
||||
88
libpcap/testprogs/reactivatetest.c
Normal file
88
libpcap/testprogs/reactivatetest.c
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that: (1) source code distributions
|
||||
* retain the above copyright notice and this paragraph in its entirety, (2)
|
||||
* distributions including binary code include the above copyright notice and
|
||||
* this paragraph in its entirety in the documentation or other materials
|
||||
* provided with the distribution, and (3) all advertising materials mentioning
|
||||
* features or use of this software display the following acknowledgement:
|
||||
* ``This product includes software developed by the University of California,
|
||||
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
|
||||
* the University nor the names of its contributors may be used to endorse
|
||||
* or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include "varattrs.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char copyright[] _U_ =
|
||||
"@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif
|
||||
|
||||
#include <pcap.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include "pcap/funcattrs.h"
|
||||
|
||||
/* Forwards */
|
||||
static void PCAP_NORETURN error(PCAP_FORMAT_STRING(const char *), ...) PCAP_PRINTFLIKE(1,2);
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
char ebuf[PCAP_ERRBUF_SIZE];
|
||||
pcap_t *pd;
|
||||
int status = 0;
|
||||
|
||||
pd = pcap_open_live("lo0", 65535, 0, 1000, ebuf);
|
||||
if (pd == NULL) {
|
||||
pd = pcap_open_live("lo", 65535, 0, 1000, ebuf);
|
||||
if (pd == NULL) {
|
||||
error("Neither lo0 nor lo could be opened: %s",
|
||||
ebuf);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
status = pcap_activate(pd);
|
||||
if (status != PCAP_ERROR_ACTIVATED) {
|
||||
if (status == 0)
|
||||
error("pcap_activate() of opened pcap_t succeeded");
|
||||
else if (status == PCAP_ERROR)
|
||||
error("pcap_activate() of opened pcap_t failed with %s, not PCAP_ERROR_ACTIVATED",
|
||||
pcap_geterr(pd));
|
||||
else
|
||||
error("pcap_activate() of opened pcap_t failed with %s, not PCAP_ERROR_ACTIVATED",
|
||||
pcap_statustostr(status));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* VARARGS */
|
||||
static void
|
||||
error(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
(void)fprintf(stderr, "reactivatetest: ");
|
||||
va_start(ap, fmt);
|
||||
(void)vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
if (*fmt) {
|
||||
fmt += strlen(fmt);
|
||||
if (fmt[-1] != '\n')
|
||||
(void)fputc('\n', stderr);
|
||||
}
|
||||
exit(1);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
443
libpcap/testprogs/selpolltest.c
Normal file
443
libpcap/testprogs/selpolltest.c
Normal file
@@ -0,0 +1,443 @@
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that: (1) source code distributions
|
||||
* retain the above copyright notice and this paragraph in its entirety, (2)
|
||||
* distributions including binary code include the above copyright notice and
|
||||
* this paragraph in its entirety in the documentation or other materials
|
||||
* provided with the distribution, and (3) all advertising materials mentioning
|
||||
* features or use of this software display the following acknowledgement:
|
||||
* ``This product includes software developed by the University of California,
|
||||
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
|
||||
* the University nor the names of its contributors may be used to endorse
|
||||
* or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include "varattrs.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char copyright[] _U_ =
|
||||
"@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Tests how select() and poll() behave on the selectable file descriptor
|
||||
* for a pcap_t.
|
||||
*
|
||||
* This would be significantly different on Windows, as it'd test
|
||||
* how WaitForMultipleObjects() would work on the event handle for a
|
||||
* pcap_t.
|
||||
*/
|
||||
#include <pcap.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#ifdef HAVE_SYS_SELECT_H
|
||||
#include <sys/select.h>
|
||||
#else
|
||||
#include <sys/time.h> /* older UN*Xes */
|
||||
#endif
|
||||
#include <poll.h>
|
||||
|
||||
#include "pcap/funcattrs.h"
|
||||
|
||||
static char *program_name;
|
||||
|
||||
/* Forwards */
|
||||
static void countme(u_char *, const struct pcap_pkthdr *, const u_char *);
|
||||
static void PCAP_NORETURN usage(void);
|
||||
static void PCAP_NORETURN error(const char *, ...) PCAP_PRINTFLIKE(1, 2);
|
||||
static void warning(const char *, ...) PCAP_PRINTFLIKE(1, 2);
|
||||
static char *copy_argv(char **);
|
||||
|
||||
static pcap_t *pd;
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
register int op;
|
||||
bpf_u_int32 localnet, netmask;
|
||||
register char *cp, *cmdbuf, *device;
|
||||
int doselect, dopoll, dotimeout, dononblock;
|
||||
const char *mechanism;
|
||||
struct bpf_program fcode;
|
||||
char ebuf[PCAP_ERRBUF_SIZE];
|
||||
pcap_if_t *devlist;
|
||||
int selectable_fd;
|
||||
struct timeval *required_timeout;
|
||||
int status;
|
||||
int packet_count;
|
||||
|
||||
device = NULL;
|
||||
doselect = 0;
|
||||
dopoll = 0;
|
||||
mechanism = NULL;
|
||||
dotimeout = 0;
|
||||
dononblock = 0;
|
||||
if ((cp = strrchr(argv[0], '/')) != NULL)
|
||||
program_name = cp + 1;
|
||||
else
|
||||
program_name = argv[0];
|
||||
|
||||
opterr = 0;
|
||||
while ((op = getopt(argc, argv, "i:sptn")) != -1) {
|
||||
switch (op) {
|
||||
|
||||
case 'i':
|
||||
device = optarg;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
doselect = 1;
|
||||
mechanism = "select() and pcap_dispatch()";
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
dopoll = 1;
|
||||
mechanism = "poll() and pcap_dispatch()";
|
||||
break;
|
||||
|
||||
case 't':
|
||||
dotimeout = 1;
|
||||
break;
|
||||
|
||||
case 'n':
|
||||
dononblock = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
usage();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
}
|
||||
|
||||
if (doselect && dopoll) {
|
||||
fprintf(stderr, "selpolltest: choose select (-s) or poll (-p), but not both\n");
|
||||
return 1;
|
||||
}
|
||||
if (dotimeout && !doselect && !dopoll) {
|
||||
fprintf(stderr, "selpolltest: timeout (-t) requires select (-s) or poll (-p)\n");
|
||||
return 1;
|
||||
}
|
||||
if (device == NULL) {
|
||||
if (pcap_findalldevs(&devlist, ebuf) == -1)
|
||||
error("%s", ebuf);
|
||||
if (devlist == NULL)
|
||||
error("no interfaces available for capture");
|
||||
device = strdup(devlist->name);
|
||||
pcap_freealldevs(devlist);
|
||||
}
|
||||
*ebuf = '\0';
|
||||
pd = pcap_open_live(device, 65535, 0, 1000, ebuf);
|
||||
if (pd == NULL)
|
||||
error("%s", ebuf);
|
||||
else if (*ebuf)
|
||||
warning("%s", ebuf);
|
||||
if (pcap_lookupnet(device, &localnet, &netmask, ebuf) < 0) {
|
||||
localnet = 0;
|
||||
netmask = 0;
|
||||
warning("%s", ebuf);
|
||||
}
|
||||
cmdbuf = copy_argv(&argv[optind]);
|
||||
|
||||
if (pcap_compile(pd, &fcode, cmdbuf, 1, netmask) < 0)
|
||||
error("%s", pcap_geterr(pd));
|
||||
if (pcap_setfilter(pd, &fcode) < 0)
|
||||
error("%s", pcap_geterr(pd));
|
||||
|
||||
if (doselect || dopoll) {
|
||||
/*
|
||||
* We need either an FD on which to do select()/poll()
|
||||
* or, if there isn't one, a timeout to use in select()/
|
||||
* poll().
|
||||
*/
|
||||
selectable_fd = pcap_get_selectable_fd(pd);
|
||||
if (selectable_fd == -1) {
|
||||
printf("Listening on %s, using %s, with a timeout\n",
|
||||
device, mechanism);
|
||||
required_timeout = pcap_get_required_select_timeout(pd);
|
||||
if (required_timeout == NULL)
|
||||
error("select()/poll() isn't supported on %s, even with a timeout",
|
||||
device);
|
||||
|
||||
/*
|
||||
* As we won't be notified by select() or poll()
|
||||
* that a read can be done, we'll have to periodically
|
||||
* try reading from the device every time the required
|
||||
* timeout expires, and we don't want those attempts
|
||||
* to block if nothing has arrived in that interval,
|
||||
* so we want to force non-blocking mode.
|
||||
*/
|
||||
dononblock = 1;
|
||||
} else {
|
||||
printf("Listening on %s, using %s\n", device,
|
||||
mechanism);
|
||||
required_timeout = NULL;
|
||||
}
|
||||
} else
|
||||
printf("Listening on %s, using pcap_dispatch()\n", device);
|
||||
|
||||
if (dononblock) {
|
||||
if (pcap_setnonblock(pd, 1, ebuf) == -1)
|
||||
error("pcap_setnonblock failed: %s", ebuf);
|
||||
}
|
||||
if (doselect) {
|
||||
for (;;) {
|
||||
fd_set setread, setexcept;
|
||||
struct timeval seltimeout;
|
||||
|
||||
FD_ZERO(&setread);
|
||||
if (selectable_fd != -1) {
|
||||
FD_SET(selectable_fd, &setread);
|
||||
FD_ZERO(&setexcept);
|
||||
FD_SET(selectable_fd, &setexcept);
|
||||
}
|
||||
if (dotimeout) {
|
||||
seltimeout.tv_sec = 0;
|
||||
if (required_timeout != NULL &&
|
||||
required_timeout->tv_usec < 1000)
|
||||
seltimeout.tv_usec = required_timeout->tv_usec;
|
||||
else
|
||||
seltimeout.tv_usec = 1000;
|
||||
status = select(selectable_fd + 1, &setread,
|
||||
NULL, &setexcept, &seltimeout);
|
||||
} else if (required_timeout != NULL) {
|
||||
seltimeout = *required_timeout;
|
||||
status = select(selectable_fd + 1, &setread,
|
||||
NULL, &setexcept, &seltimeout);
|
||||
} else {
|
||||
status = select((selectable_fd == -1) ?
|
||||
0 : selectable_fd + 1, &setread,
|
||||
NULL, &setexcept, NULL);
|
||||
}
|
||||
if (status == -1) {
|
||||
printf("Select returns error (%s)\n",
|
||||
strerror(errno));
|
||||
} else {
|
||||
if (selectable_fd == -1) {
|
||||
if (status != 0)
|
||||
printf("Select returned a descriptor\n");
|
||||
} else {
|
||||
if (status == 0)
|
||||
printf("Select timed out: ");
|
||||
else
|
||||
printf("Select returned a descriptor: ");
|
||||
if (FD_ISSET(selectable_fd, &setread))
|
||||
printf("readable, ");
|
||||
else
|
||||
printf("not readable, ");
|
||||
if (FD_ISSET(selectable_fd, &setexcept))
|
||||
printf("exceptional condition\n");
|
||||
else
|
||||
printf("no exceptional condition\n");
|
||||
}
|
||||
packet_count = 0;
|
||||
status = pcap_dispatch(pd, -1, countme,
|
||||
(u_char *)&packet_count);
|
||||
if (status < 0)
|
||||
break;
|
||||
/*
|
||||
* Don't report this if we're using a
|
||||
* required timeout and we got no packets,
|
||||
* because that could be a very short timeout,
|
||||
* and we don't want to spam the user with
|
||||
* a ton of "no packets" reports.
|
||||
*/
|
||||
if (status != 0 || packet_count != 0 ||
|
||||
required_timeout != NULL) {
|
||||
printf("%d packets seen, %d packets counted after select returns\n",
|
||||
status, packet_count);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (dopoll) {
|
||||
for (;;) {
|
||||
struct pollfd fd;
|
||||
int polltimeout;
|
||||
|
||||
fd.fd = selectable_fd;
|
||||
fd.events = POLLIN;
|
||||
if (dotimeout)
|
||||
polltimeout = 1;
|
||||
else if (required_timeout != NULL &&
|
||||
required_timeout->tv_usec >= 1000)
|
||||
polltimeout = required_timeout->tv_usec/1000;
|
||||
else
|
||||
polltimeout = -1;
|
||||
status = poll(&fd, (selectable_fd == -1) ? 0 : 1, polltimeout);
|
||||
if (status == -1) {
|
||||
printf("Poll returns error (%s)\n",
|
||||
strerror(errno));
|
||||
} else {
|
||||
if (selectable_fd == -1) {
|
||||
if (status != 0)
|
||||
printf("Poll returned a descriptor\n");
|
||||
} else {
|
||||
if (status == 0)
|
||||
printf("Poll timed out\n");
|
||||
else {
|
||||
printf("Poll returned a descriptor: ");
|
||||
if (fd.revents & POLLIN)
|
||||
printf("readable, ");
|
||||
else
|
||||
printf("not readable, ");
|
||||
if (fd.revents & POLLERR)
|
||||
printf("exceptional condition, ");
|
||||
else
|
||||
printf("no exceptional condition, ");
|
||||
if (fd.revents & POLLHUP)
|
||||
printf("disconnect, ");
|
||||
else
|
||||
printf("no disconnect, ");
|
||||
if (fd.revents & POLLNVAL)
|
||||
printf("invalid\n");
|
||||
else
|
||||
printf("not invalid\n");
|
||||
}
|
||||
}
|
||||
packet_count = 0;
|
||||
status = pcap_dispatch(pd, -1, countme,
|
||||
(u_char *)&packet_count);
|
||||
if (status < 0)
|
||||
break;
|
||||
/*
|
||||
* Don't report this if we're using a
|
||||
* required timeout and we got no packets,
|
||||
* because that could be a very short timeout,
|
||||
* and we don't want to spam the user with
|
||||
* a ton of "no packets" reports.
|
||||
*/
|
||||
if (status != 0 || packet_count != 0 ||
|
||||
required_timeout != NULL) {
|
||||
printf("%d packets seen, %d packets counted after poll returns\n",
|
||||
status, packet_count);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (;;) {
|
||||
packet_count = 0;
|
||||
status = pcap_dispatch(pd, -1, countme,
|
||||
(u_char *)&packet_count);
|
||||
if (status < 0)
|
||||
break;
|
||||
printf("%d packets seen, %d packets counted after pcap_dispatch returns\n",
|
||||
status, packet_count);
|
||||
}
|
||||
}
|
||||
if (status == -2) {
|
||||
/*
|
||||
* We got interrupted, so perhaps we didn't
|
||||
* manage to finish a line we were printing.
|
||||
* Print an extra newline, just in case.
|
||||
*/
|
||||
putchar('\n');
|
||||
}
|
||||
(void)fflush(stdout);
|
||||
if (status == -1) {
|
||||
/*
|
||||
* Error. Report it.
|
||||
*/
|
||||
(void)fprintf(stderr, "%s: pcap_loop: %s\n",
|
||||
program_name, pcap_geterr(pd));
|
||||
}
|
||||
pcap_close(pd);
|
||||
exit(status == -1 ? 1 : 0);
|
||||
}
|
||||
|
||||
static void
|
||||
countme(u_char *user, const struct pcap_pkthdr *h _U_, const u_char *sp _U_)
|
||||
{
|
||||
int *counterp = (int *)user;
|
||||
|
||||
(*counterp)++;
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
(void)fprintf(stderr, "Usage: %s [ -sptn ] [ -i interface ] [expression]\n",
|
||||
program_name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* VARARGS */
|
||||
static void
|
||||
error(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
(void)fprintf(stderr, "%s: ", program_name);
|
||||
va_start(ap, fmt);
|
||||
(void)vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
if (*fmt) {
|
||||
fmt += strlen(fmt);
|
||||
if (fmt[-1] != '\n')
|
||||
(void)fputc('\n', stderr);
|
||||
}
|
||||
exit(1);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/* VARARGS */
|
||||
static void
|
||||
warning(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
(void)fprintf(stderr, "%s: WARNING: ", program_name);
|
||||
va_start(ap, fmt);
|
||||
(void)vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
if (*fmt) {
|
||||
fmt += strlen(fmt);
|
||||
if (fmt[-1] != '\n')
|
||||
(void)fputc('\n', stderr);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy arg vector into a new buffer, concatenating arguments with spaces.
|
||||
*/
|
||||
static char *
|
||||
copy_argv(register char **argv)
|
||||
{
|
||||
register char **p;
|
||||
register u_int len = 0;
|
||||
char *buf;
|
||||
char *src, *dst;
|
||||
|
||||
p = argv;
|
||||
if (*p == 0)
|
||||
return 0;
|
||||
|
||||
while (*p)
|
||||
len += strlen(*p++) + 1;
|
||||
|
||||
buf = (char *)malloc(len);
|
||||
if (buf == NULL)
|
||||
error("copy_argv: malloc");
|
||||
|
||||
p = argv;
|
||||
dst = buf;
|
||||
while ((src = *p++) != NULL) {
|
||||
while ((*dst++ = *src++) != '\0')
|
||||
;
|
||||
dst[-1] = ' ';
|
||||
}
|
||||
dst[-1] = '\0';
|
||||
|
||||
return buf;
|
||||
}
|
||||
393
libpcap/testprogs/threadsignaltest.c
Normal file
393
libpcap/testprogs/threadsignaltest.c
Normal file
@@ -0,0 +1,393 @@
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that: (1) source code distributions
|
||||
* retain the above copyright notice and this paragraph in its entirety, (2)
|
||||
* distributions including binary code include the above copyright notice and
|
||||
* this paragraph in its entirety in the documentation or other materials
|
||||
* provided with the distribution, and (3) all advertising materials mentioning
|
||||
* features or use of this software display the following acknowledgement:
|
||||
* ``This product includes software developed by the University of California,
|
||||
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
|
||||
* the University nor the names of its contributors may be used to endorse
|
||||
* or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include "varattrs.h"
|
||||
|
||||
#ifndef lint
|
||||
static const char copyright[] _U_ =
|
||||
"@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <limits.h>
|
||||
#ifdef _WIN32
|
||||
#include <winsock2.h>
|
||||
#include <windows.h>
|
||||
|
||||
#define THREAD_HANDLE HANDLE
|
||||
#define THREAD_FUNC_ARG_TYPE LPVOID
|
||||
#define THREAD_FUNC_RETURN_TYPE DWORD __stdcall
|
||||
|
||||
#include "getopt.h"
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define THREAD_HANDLE pthread_t
|
||||
#define THREAD_FUNC_ARG_TYPE void *
|
||||
#define THREAD_FUNC_RETURN_TYPE void *
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <pcap.h>
|
||||
|
||||
#include "pcap/funcattrs.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "portability.h"
|
||||
#endif
|
||||
|
||||
static char *program_name;
|
||||
|
||||
/* Forwards */
|
||||
static void countme(u_char *, const struct pcap_pkthdr *, const u_char *);
|
||||
static void PCAP_NORETURN usage(void);
|
||||
static void PCAP_NORETURN error(const char *, ...) PCAP_PRINTFLIKE(1, 2);
|
||||
static void warning(const char *, ...) PCAP_PRINTFLIKE(1, 2);
|
||||
static char *copy_argv(char **);
|
||||
|
||||
static pcap_t *pd;
|
||||
|
||||
#ifdef _WIN32
|
||||
/*
|
||||
* Generate a string for a Win32-specific error (i.e. an error generated when
|
||||
* calling a Win32 API).
|
||||
* For errors occurred during standard C calls, we still use pcap_strerror()
|
||||
*/
|
||||
#define ERRBUF_SIZE 1024
|
||||
static const char *
|
||||
win32_strerror(DWORD error)
|
||||
{
|
||||
static char errbuf[ERRBUF_SIZE+1];
|
||||
size_t errlen;
|
||||
|
||||
FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, error, 0, errbuf,
|
||||
ERRBUF_SIZE, NULL);
|
||||
|
||||
/*
|
||||
* "FormatMessage()" "helpfully" sticks CR/LF at the end of the
|
||||
* message. Get rid of it.
|
||||
*/
|
||||
errlen = strlen(errbuf);
|
||||
if (errlen >= 2) {
|
||||
errbuf[errlen - 1] = '\0';
|
||||
errbuf[errlen - 2] = '\0';
|
||||
errlen -= 2;
|
||||
}
|
||||
return errbuf;
|
||||
}
|
||||
#else
|
||||
static void
|
||||
catch_sigusr1(int sig _U_)
|
||||
{
|
||||
printf("Got SIGUSR1\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
sleep_secs(int secs)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
Sleep(secs*1000);
|
||||
#else
|
||||
unsigned secs_remaining;
|
||||
|
||||
if (secs <= 0)
|
||||
return;
|
||||
secs_remaining = secs;
|
||||
while (secs_remaining != 0)
|
||||
secs_remaining = sleep(secs_remaining);
|
||||
#endif
|
||||
}
|
||||
|
||||
static THREAD_FUNC_RETURN_TYPE
|
||||
capture_thread_func(THREAD_FUNC_ARG_TYPE arg)
|
||||
{
|
||||
char *device = arg;
|
||||
int packet_count;
|
||||
int status;
|
||||
#ifndef _WIN32
|
||||
struct sigaction action;
|
||||
sigset_t mask;
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
sigemptyset(&mask);
|
||||
action.sa_handler = catch_sigusr1;
|
||||
action.sa_mask = mask;
|
||||
action.sa_flags = 0;
|
||||
if (sigaction(SIGUSR1, &action, NULL) == -1)
|
||||
error("Can't catch SIGUSR1: %s", strerror(errno));
|
||||
#endif
|
||||
|
||||
printf("Listening on %s\n", device);
|
||||
for (;;) {
|
||||
packet_count = 0;
|
||||
status = pcap_dispatch(pd, -1, countme,
|
||||
(u_char *)&packet_count);
|
||||
if (status < 0)
|
||||
break;
|
||||
if (status != 0) {
|
||||
printf("%d packets seen, %d packets counted after pcap_dispatch returns\n",
|
||||
status, packet_count);
|
||||
} else
|
||||
printf("No packets seen by pcap_dispatch\n");
|
||||
}
|
||||
if (status == -2) {
|
||||
/*
|
||||
* We got interrupted, so perhaps we didn't
|
||||
* manage to finish a line we were printing.
|
||||
* Print an extra newline, just in case.
|
||||
*/
|
||||
putchar('\n');
|
||||
printf("Loop got broken\n");
|
||||
}
|
||||
(void)fflush(stdout);
|
||||
if (status == -1) {
|
||||
/*
|
||||
* Error. Report it.
|
||||
*/
|
||||
(void)fprintf(stderr, "%s: pcap_loop: %s\n",
|
||||
program_name, pcap_geterr(pd));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
register int op;
|
||||
register char *cp, *cmdbuf, *device;
|
||||
int immediate = 0;
|
||||
pcap_if_t *devlist;
|
||||
bpf_u_int32 localnet, netmask;
|
||||
struct bpf_program fcode;
|
||||
char ebuf[PCAP_ERRBUF_SIZE];
|
||||
int status;
|
||||
THREAD_HANDLE capture_thread;
|
||||
#ifndef _WIN32
|
||||
void *retval;
|
||||
#endif
|
||||
|
||||
device = NULL;
|
||||
if ((cp = strrchr(argv[0], '/')) != NULL)
|
||||
program_name = cp + 1;
|
||||
else
|
||||
program_name = argv[0];
|
||||
|
||||
opterr = 0;
|
||||
while ((op = getopt(argc, argv, "i:")) != -1) {
|
||||
switch (op) {
|
||||
|
||||
case 'i':
|
||||
device = optarg;
|
||||
break;
|
||||
|
||||
default:
|
||||
usage();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
}
|
||||
|
||||
if (device == NULL) {
|
||||
if (pcap_findalldevs(&devlist, ebuf) == -1)
|
||||
error("%s", ebuf);
|
||||
if (devlist == NULL)
|
||||
error("no interfaces available for capture");
|
||||
device = strdup(devlist->name);
|
||||
pcap_freealldevs(devlist);
|
||||
}
|
||||
*ebuf = '\0';
|
||||
pd = pcap_create(device, ebuf);
|
||||
if (pd == NULL)
|
||||
error("%s", ebuf);
|
||||
status = pcap_set_snaplen(pd, 65535);
|
||||
if (status != 0)
|
||||
error("%s: pcap_set_snaplen failed: %s",
|
||||
device, pcap_statustostr(status));
|
||||
if (immediate) {
|
||||
status = pcap_set_immediate_mode(pd, 1);
|
||||
if (status != 0)
|
||||
error("%s: pcap_set_immediate_mode failed: %s",
|
||||
device, pcap_statustostr(status));
|
||||
}
|
||||
status = pcap_set_timeout(pd, 5*60*1000);
|
||||
if (status != 0)
|
||||
error("%s: pcap_set_timeout failed: %s",
|
||||
device, pcap_statustostr(status));
|
||||
status = pcap_activate(pd);
|
||||
if (status < 0) {
|
||||
/*
|
||||
* pcap_activate() failed.
|
||||
*/
|
||||
error("%s: %s\n(%s)", device,
|
||||
pcap_statustostr(status), pcap_geterr(pd));
|
||||
} else if (status > 0) {
|
||||
/*
|
||||
* pcap_activate() succeeded, but it's warning us
|
||||
* of a problem it had.
|
||||
*/
|
||||
warning("%s: %s\n(%s)", device,
|
||||
pcap_statustostr(status), pcap_geterr(pd));
|
||||
}
|
||||
if (pcap_lookupnet(device, &localnet, &netmask, ebuf) < 0) {
|
||||
localnet = 0;
|
||||
netmask = 0;
|
||||
warning("%s", ebuf);
|
||||
}
|
||||
cmdbuf = copy_argv(&argv[optind]);
|
||||
|
||||
if (pcap_compile(pd, &fcode, cmdbuf, 1, netmask) < 0)
|
||||
error("%s", pcap_geterr(pd));
|
||||
|
||||
if (pcap_setfilter(pd, &fcode) < 0)
|
||||
error("%s", pcap_geterr(pd));
|
||||
|
||||
#ifdef _WIN32
|
||||
capture_thread = CreateThread(NULL, 0, capture_thread_func, device,
|
||||
0, NULL);
|
||||
if (capture_thread == NULL)
|
||||
error("Can't create capture thread: %s",
|
||||
win32_strerror(GetLastError()));
|
||||
#else
|
||||
status = pthread_create(&capture_thread, NULL, capture_thread_func,
|
||||
device);
|
||||
if (status != 0)
|
||||
error("Can't create capture thread: %s", strerror(status));
|
||||
#endif
|
||||
sleep_secs(60);
|
||||
pcap_breakloop(pd);
|
||||
#ifdef _WIN32
|
||||
printf("Setting event\n");
|
||||
if (!SetEvent(pcap_getevent(pd)))
|
||||
error("Can't set event for pcap_t: %s",
|
||||
win32_strerror(GetLastError()));
|
||||
if (WaitForSingleObject(capture_thread, INFINITE) == WAIT_FAILED)
|
||||
error("Wait for thread termination failed: %s",
|
||||
win32_strerror(GetLastError()));
|
||||
CloseHandle(capture_thread);
|
||||
#else
|
||||
printf("Sending SIGUSR1\n");
|
||||
status = pthread_kill(capture_thread, SIGUSR1);
|
||||
if (status != 0)
|
||||
warning("Can't interrupt capture thread: %s", strerror(status));
|
||||
status = pthread_join(capture_thread, &retval);
|
||||
if (status != 0)
|
||||
error("Wait for thread termination failed: %s",
|
||||
strerror(status));
|
||||
#endif
|
||||
|
||||
pcap_close(pd);
|
||||
pcap_freecode(&fcode);
|
||||
exit(status == -1 ? 1 : 0);
|
||||
}
|
||||
|
||||
static void
|
||||
countme(u_char *user, const struct pcap_pkthdr *h _U_, const u_char *sp _U_)
|
||||
{
|
||||
int *counterp = (int *)user;
|
||||
|
||||
(*counterp)++;
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
(void)fprintf(stderr, "Usage: %s [ -m ] [ -i interface ] [ -t timeout] [expression]\n",
|
||||
program_name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* VARARGS */
|
||||
static void
|
||||
error(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
(void)fprintf(stderr, "%s: ", program_name);
|
||||
va_start(ap, fmt);
|
||||
(void)vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
if (*fmt) {
|
||||
fmt += strlen(fmt);
|
||||
if (fmt[-1] != '\n')
|
||||
(void)fputc('\n', stderr);
|
||||
}
|
||||
exit(1);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/* VARARGS */
|
||||
static void
|
||||
warning(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
(void)fprintf(stderr, "%s: WARNING: ", program_name);
|
||||
va_start(ap, fmt);
|
||||
(void)vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
if (*fmt) {
|
||||
fmt += strlen(fmt);
|
||||
if (fmt[-1] != '\n')
|
||||
(void)fputc('\n', stderr);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy arg vector into a new buffer, concatenating arguments with spaces.
|
||||
*/
|
||||
static char *
|
||||
copy_argv(register char **argv)
|
||||
{
|
||||
register char **p;
|
||||
register u_int len = 0;
|
||||
char *buf;
|
||||
char *src, *dst;
|
||||
|
||||
p = argv;
|
||||
if (*p == 0)
|
||||
return 0;
|
||||
|
||||
while (*p)
|
||||
len += strlen(*p++) + 1;
|
||||
|
||||
buf = (char *)malloc(len);
|
||||
if (buf == NULL)
|
||||
error("copy_argv: malloc");
|
||||
|
||||
p = argv;
|
||||
dst = buf;
|
||||
while ((src = *p++) != NULL) {
|
||||
while ((*dst++ = *src++) != '\0')
|
||||
;
|
||||
dst[-1] = ' ';
|
||||
}
|
||||
dst[-1] = '\0';
|
||||
|
||||
return buf;
|
||||
}
|
||||
58
libpcap/testprogs/unix.h
Normal file
58
libpcap/testprogs/unix.h
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 1994, 1995, 1996
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the Computer Systems
|
||||
* Engineering Group at Lawrence Berkeley Laboratory.
|
||||
* 4. Neither the name of the University nor of the Laboratory may be used
|
||||
* to endorse or promote products derived from this software without
|
||||
* specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef unix_h
|
||||
#define unix_h
|
||||
|
||||
/*
|
||||
* Definitions to make MSVC C runtime library structures and functions
|
||||
* look like the UNIX structures and functions they are intended to
|
||||
* resemble.
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
#define stat _stat
|
||||
#define fstat _fstat
|
||||
|
||||
#define open _open
|
||||
#define O_RDONLY _O_RDONLY
|
||||
#define O_WRONLY _O_WRONLY
|
||||
#define O_RDWR _O_RDWR
|
||||
#define O_BINARY _O_BINARY
|
||||
#define O_CREAT _O_CREAT
|
||||
#define O_TRUNC _O_TRUNC
|
||||
#define read _read
|
||||
#define write _write
|
||||
#define close _close
|
||||
#endif
|
||||
|
||||
#endif
|
||||
427
libpcap/testprogs/valgrindtest.c
Normal file
427
libpcap/testprogs/valgrindtest.c
Normal file
@@ -0,0 +1,427 @@
|
||||
/*
|
||||
* Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that: (1) source code distributions
|
||||
* retain the above copyright notice and this paragraph in its entirety, (2)
|
||||
* distributions including binary code include the above copyright notice and
|
||||
* this paragraph in its entirety in the documentation or other materials
|
||||
* provided with the distribution, and (3) all advertising materials mentioning
|
||||
* features or use of this software display the following acknowledgement:
|
||||
* ``This product includes software developed by the University of California,
|
||||
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
|
||||
* the University nor the names of its contributors may be used to endorse
|
||||
* or promote products derived from this software without specific prior
|
||||
* written permission.
|
||||
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
|
||||
#include "varattrs.h"
|
||||
|
||||
/*
|
||||
* This doesn't actually test libpcap itself; it tests whether
|
||||
* valgrind properly handles the APIs libpcap uses. If it doesn't,
|
||||
* we end up getting patches submitted to "fix" references that
|
||||
* valgrind claims are being made to uninitialized data, when, in
|
||||
* fact, the OS isn't making any such references - or we get
|
||||
* valgrind *not* detecting *actual* incorrect references.
|
||||
*
|
||||
* Both BPF and Linux socket filters aren't handled correctly
|
||||
* by some versions of valgrind. See valgrind bug 318203 for
|
||||
* Linux:
|
||||
*
|
||||
* https://bugs.kde.org/show_bug.cgi?id=318203
|
||||
*
|
||||
* and valgrind bug 312989 for macOS:
|
||||
*
|
||||
* https://bugs.kde.org/show_bug.cgi?id=312989
|
||||
*
|
||||
* The fixes for both of those are checked into the official valgrind
|
||||
* repository.
|
||||
*
|
||||
* The unofficial FreeBSD port has similar issues to the official macOS
|
||||
* port, for similar reasons.
|
||||
*/
|
||||
#ifndef lint
|
||||
static const char copyright[] _U_ =
|
||||
"@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\
|
||||
The Regents of the University of California. All rights reserved.\n";
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "pcap/funcattrs.h"
|
||||
|
||||
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(_AIX) || defined(sun)
|
||||
/* OS with BPF - use BPF */
|
||||
#define USE_BPF
|
||||
#elif defined(linux)
|
||||
/* Linux - use socket filters */
|
||||
#define USE_SOCKET_FILTERS
|
||||
#else
|
||||
#error "Unknown platform or platform that doesn't support Valgrind"
|
||||
#endif
|
||||
|
||||
#if defined(USE_BPF)
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <net/bpf.h>
|
||||
|
||||
/*
|
||||
* Make "pcap.h" not include "pcap/bpf.h"; we are going to include the
|
||||
* native OS version, as we're going to be doing our own ioctls to
|
||||
* make sure that, in the uninitialized-data tests, the filters aren't
|
||||
* checked by libpcap before being handed to BPF.
|
||||
*/
|
||||
#define PCAP_DONT_INCLUDE_PCAP_BPF_H
|
||||
|
||||
#elif defined(USE_SOCKET_FILTERS)
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/filter.h>
|
||||
|
||||
#endif
|
||||
|
||||
#include <pcap.h>
|
||||
|
||||
static char *program_name;
|
||||
|
||||
/* Forwards */
|
||||
static void PCAP_NORETURN usage(void);
|
||||
static void PCAP_NORETURN error(const char *, ...) PCAP_PRINTFLIKE(1, 2);
|
||||
static void warning(const char *, ...) PCAP_PRINTFLIKE(1, 2);
|
||||
|
||||
/*
|
||||
* On Windows, we need to open the file in binary mode, so that
|
||||
* we get all the bytes specified by the size we get from "fstat()".
|
||||
* On UNIX, that's not necessary. O_BINARY is defined on Windows;
|
||||
* we define it as 0 if it's not defined, so it does nothing.
|
||||
*/
|
||||
#ifndef O_BINARY
|
||||
#define O_BINARY 0
|
||||
#endif
|
||||
|
||||
static char *
|
||||
read_infile(char *fname)
|
||||
{
|
||||
register int i, fd, cc;
|
||||
register char *cp;
|
||||
struct stat buf;
|
||||
|
||||
fd = open(fname, O_RDONLY|O_BINARY);
|
||||
if (fd < 0)
|
||||
error("can't open %s: %s", fname, pcap_strerror(errno));
|
||||
|
||||
if (fstat(fd, &buf) < 0)
|
||||
error("can't stat %s: %s", fname, pcap_strerror(errno));
|
||||
|
||||
cp = malloc((u_int)buf.st_size + 1);
|
||||
if (cp == NULL)
|
||||
error("malloc(%d) for %s: %s", (u_int)buf.st_size + 1,
|
||||
fname, pcap_strerror(errno));
|
||||
cc = read(fd, cp, (u_int)buf.st_size);
|
||||
if (cc < 0)
|
||||
error("read %s: %s", fname, pcap_strerror(errno));
|
||||
if (cc != buf.st_size)
|
||||
error("short read %s (%d != %d)", fname, cc, (int)buf.st_size);
|
||||
|
||||
close(fd);
|
||||
/* replace "# comment" with spaces */
|
||||
for (i = 0; i < cc; i++) {
|
||||
if (cp[i] == '#')
|
||||
while (i < cc && cp[i] != '\n')
|
||||
cp[i++] = ' ';
|
||||
}
|
||||
cp[cc] = '\0';
|
||||
return (cp);
|
||||
}
|
||||
|
||||
/* VARARGS */
|
||||
static void
|
||||
error(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
(void)fprintf(stderr, "%s: ", program_name);
|
||||
va_start(ap, fmt);
|
||||
(void)vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
if (*fmt) {
|
||||
fmt += strlen(fmt);
|
||||
if (fmt[-1] != '\n')
|
||||
(void)fputc('\n', stderr);
|
||||
}
|
||||
exit(1);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/* VARARGS */
|
||||
static void
|
||||
warning(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
(void)fprintf(stderr, "%s: WARNING: ", program_name);
|
||||
va_start(ap, fmt);
|
||||
(void)vfprintf(stderr, fmt, ap);
|
||||
va_end(ap);
|
||||
if (*fmt) {
|
||||
fmt += strlen(fmt);
|
||||
if (fmt[-1] != '\n')
|
||||
(void)fputc('\n', stderr);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy arg vector into a new buffer, concatenating arguments with spaces.
|
||||
*/
|
||||
static char *
|
||||
copy_argv(register char **argv)
|
||||
{
|
||||
register char **p;
|
||||
register u_int len = 0;
|
||||
char *buf;
|
||||
char *src, *dst;
|
||||
|
||||
p = argv;
|
||||
if (*p == 0)
|
||||
return 0;
|
||||
|
||||
while (*p)
|
||||
len += strlen(*p++) + 1;
|
||||
|
||||
buf = (char *)malloc(len);
|
||||
if (buf == NULL)
|
||||
error("copy_argv: malloc");
|
||||
|
||||
p = argv;
|
||||
dst = buf;
|
||||
while ((src = *p++) != NULL) {
|
||||
while ((*dst++ = *src++) != '\0')
|
||||
;
|
||||
dst[-1] = ' ';
|
||||
}
|
||||
dst[-1] = '\0';
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
#define INSN_COUNT 17
|
||||
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
char *cp, *device;
|
||||
int op;
|
||||
int dorfmon, useactivate;
|
||||
char ebuf[PCAP_ERRBUF_SIZE];
|
||||
char *infile;
|
||||
const char *cmdbuf;
|
||||
pcap_if_t *devlist;
|
||||
pcap_t *pd;
|
||||
int status = 0;
|
||||
int pcap_fd;
|
||||
#if defined(USE_BPF)
|
||||
struct bpf_program bad_fcode;
|
||||
struct bpf_insn uninitialized[INSN_COUNT];
|
||||
#elif defined(USE_SOCKET_FILTERS)
|
||||
struct sock_fprog bad_fcode;
|
||||
struct sock_filter uninitialized[INSN_COUNT];
|
||||
#endif
|
||||
struct bpf_program fcode;
|
||||
|
||||
device = NULL;
|
||||
dorfmon = 0;
|
||||
useactivate = 0;
|
||||
infile = NULL;
|
||||
|
||||
if ((cp = strrchr(argv[0], '/')) != NULL)
|
||||
program_name = cp + 1;
|
||||
else
|
||||
program_name = argv[0];
|
||||
|
||||
opterr = 0;
|
||||
while ((op = getopt(argc, argv, "aF:i:I")) != -1) {
|
||||
switch (op) {
|
||||
|
||||
case 'a':
|
||||
useactivate = 1;
|
||||
break;
|
||||
|
||||
case 'F':
|
||||
infile = optarg;
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
device = optarg;
|
||||
break;
|
||||
|
||||
case 'I':
|
||||
dorfmon = 1;
|
||||
useactivate = 1; /* required for rfmon */
|
||||
break;
|
||||
|
||||
default:
|
||||
usage();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
}
|
||||
|
||||
if (device == NULL) {
|
||||
/*
|
||||
* No interface specified; get whatever pcap_lookupdev()
|
||||
* finds.
|
||||
*/
|
||||
if (pcap_findalldevs(&devlist, ebuf) == -1)
|
||||
error("%s", ebuf);
|
||||
if (devlist == NULL)
|
||||
error("no interfaces available for capture");
|
||||
device = strdup(devlist->name);
|
||||
pcap_freealldevs(devlist);
|
||||
}
|
||||
|
||||
if (infile != NULL) {
|
||||
/*
|
||||
* Filter specified with "-F" and a file containing
|
||||
* a filter.
|
||||
*/
|
||||
cmdbuf = read_infile(infile);
|
||||
} else {
|
||||
if (optind < argc) {
|
||||
/*
|
||||
* Filter specified with arguments on the
|
||||
* command line.
|
||||
*/
|
||||
cmdbuf = copy_argv(&argv[optind+1]);
|
||||
} else {
|
||||
/*
|
||||
* No filter specified; use an empty string, which
|
||||
* compiles to an "accept all" filter.
|
||||
*/
|
||||
cmdbuf = "";
|
||||
}
|
||||
}
|
||||
|
||||
if (useactivate) {
|
||||
pd = pcap_create(device, ebuf);
|
||||
if (pd == NULL)
|
||||
error("%s: pcap_create() failed: %s", device, ebuf);
|
||||
status = pcap_set_snaplen(pd, 65535);
|
||||
if (status != 0)
|
||||
error("%s: pcap_set_snaplen failed: %s",
|
||||
device, pcap_statustostr(status));
|
||||
status = pcap_set_promisc(pd, 1);
|
||||
if (status != 0)
|
||||
error("%s: pcap_set_promisc failed: %s",
|
||||
device, pcap_statustostr(status));
|
||||
if (dorfmon) {
|
||||
status = pcap_set_rfmon(pd, 1);
|
||||
if (status != 0)
|
||||
error("%s: pcap_set_rfmon failed: %s",
|
||||
device, pcap_statustostr(status));
|
||||
}
|
||||
status = pcap_set_timeout(pd, 1000);
|
||||
if (status != 0)
|
||||
error("%s: pcap_set_timeout failed: %s",
|
||||
device, pcap_statustostr(status));
|
||||
status = pcap_activate(pd);
|
||||
if (status < 0) {
|
||||
/*
|
||||
* pcap_activate() failed.
|
||||
*/
|
||||
error("%s: %s\n(%s)", device,
|
||||
pcap_statustostr(status), pcap_geterr(pd));
|
||||
} else if (status > 0) {
|
||||
/*
|
||||
* pcap_activate() succeeded, but it's warning us
|
||||
* of a problem it had.
|
||||
*/
|
||||
warning("%s: %s\n(%s)", device,
|
||||
pcap_statustostr(status), pcap_geterr(pd));
|
||||
}
|
||||
} else {
|
||||
*ebuf = '\0';
|
||||
pd = pcap_open_live(device, 65535, 1, 1000, ebuf);
|
||||
if (pd == NULL)
|
||||
error("%s", ebuf);
|
||||
else if (*ebuf)
|
||||
warning("%s", ebuf);
|
||||
}
|
||||
|
||||
pcap_fd = pcap_fileno(pd);
|
||||
|
||||
/*
|
||||
* Try setting a filter with an uninitialized bpf_program
|
||||
* structure. This should cause valgrind to report a
|
||||
* problem.
|
||||
*
|
||||
* We don't check for errors, because it could get an
|
||||
* error due to a bad pointer or count.
|
||||
*/
|
||||
#if defined(USE_BPF)
|
||||
ioctl(pcap_fd, BIOCSETF, &bad_fcode);
|
||||
#elif defined(USE_SOCKET_FILTERS)
|
||||
setsockopt(pcap_fd, SOL_SOCKET, SO_ATTACH_FILTER, &bad_fcode,
|
||||
sizeof(bad_fcode));
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Try setting a filter with an initialized bpf_program
|
||||
* structure that points to an uninitialized program.
|
||||
* That should also cause valgrind to report a problem.
|
||||
*
|
||||
* We don't check for errors, because it could get an
|
||||
* error due to a bad pointer or count.
|
||||
*/
|
||||
#if defined(USE_BPF)
|
||||
bad_fcode.bf_len = INSN_COUNT;
|
||||
bad_fcode.bf_insns = uninitialized;
|
||||
ioctl(pcap_fd, BIOCSETF, &bad_fcode);
|
||||
#elif defined(USE_SOCKET_FILTERS)
|
||||
bad_fcode.len = INSN_COUNT;
|
||||
bad_fcode.filter = uninitialized;
|
||||
setsockopt(pcap_fd, SOL_SOCKET, SO_ATTACH_FILTER, &bad_fcode,
|
||||
sizeof(bad_fcode));
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Now compile a filter and set the filter with that.
|
||||
* That should *not* cause valgrind to report a
|
||||
* problem.
|
||||
*/
|
||||
if (pcap_compile(pd, &fcode, cmdbuf, 1, 0) < 0)
|
||||
error("can't compile filter: %s", pcap_geterr(pd));
|
||||
if (pcap_setfilter(pd, &fcode) < 0)
|
||||
error("can't set filter: %s", pcap_geterr(pd));
|
||||
|
||||
pcap_close(pd);
|
||||
exit(status < 0 ? 1 : 0);
|
||||
}
|
||||
|
||||
static void
|
||||
usage(void)
|
||||
{
|
||||
(void)fprintf(stderr, "%s, with %s\n", program_name,
|
||||
pcap_lib_version());
|
||||
(void)fprintf(stderr,
|
||||
"Usage: %s [-aI] [ -F file ] [ -I interface ] [ expression ]\n",
|
||||
program_name);
|
||||
exit(1);
|
||||
}
|
||||
Reference in New Issue
Block a user