1
0
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:
dmiller
2019-03-30 03:24:50 +00:00
parent bea1ff6d61
commit 2a1b900adf
15 changed files with 3306 additions and 0 deletions

View File

@@ -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

View 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
View 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 */

View 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()

View 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)

View 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 */
}

View 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;
}

View 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);
}

View 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 *)&in;
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];
}

View 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);
}
}

View 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 */
}

View 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;
}

View 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
View 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

View 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);
}