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