Repo created

This commit is contained in:
Fr4nz D13trich 2025-11-20 14:05:12 +01:00
parent 6e9a0d01ce
commit 7ee9806fba
2415 changed files with 312708 additions and 2 deletions

View file

@ -0,0 +1,2 @@
# common block merging, same block elimination, result propogation
host 192.168.1.1

View file

@ -0,0 +1,2 @@
# common block merging
port 80

View file

@ -0,0 +1 @@
tcp[tcpflags]&tcp-syn != 0 or tcp[tcpflags]&tcp-fin != 0 or tcp[tcpflags]&tcp-rst != 0

View file

@ -0,0 +1,2 @@
# or pullup
ether[12:2] = 0x800 or ether[12:2] = 0x8100 or ether[0] & 0x80 != 0 or ether[12:2] = 0x9100

View file

@ -0,0 +1 @@
vlan 186 and ip

View file

@ -0,0 +1 @@
ip and ((icmp and dst host 1.1.1.1 and not host 2.2.2.2) or (host 1.1.1.1 and src host 3.3.3.3))

View file

@ -0,0 +1 @@
not vlan and tcp port 80

View file

@ -0,0 +1,287 @@
/*
* 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.
*/
#ifndef lint
static const char copyright[] =
"@(#) 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>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/select.h>
#include <poll.h>
#include <pcap.h>
static char *program_name;
/* Forwards */
static void countme(u_char *, const struct pcap_pkthdr *, const u_char *);
static void usage(void) __attribute__((noreturn));
static void error(const char *, ...);
static void warning(const char *, ...);
static char *copy_argv(char **);
static pcap_t *pd;
extern int optind;
extern int opterr;
extern char *optarg;
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;
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) {
device = pcap_lookupdev(ebuf);
if (device == NULL)
error("%s", ebuf);
}
*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);
exit(status == -1 ? 1 : 0);
}
static void
countme(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
{
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,315 @@
/*
* 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.
*/
#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>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifndef HAVE___ATTRIBUTE__
#define __attribute__(x)
#endif
static char *program_name;
/* Forwards */
static void usage(void) __attribute__((noreturn));
static void error(const char *, ...)
__attribute__((noreturn, format (printf, 1, 2)));
static void warn(const char *, ...)
__attribute__((format (printf, 1, 2)));
extern int optind;
extern int opterr;
extern char *optarg;
#ifdef BDEBUG
int dflag;
#endif
/*
* 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;
#ifndef BDEBUG
int dflag;
#endif
char *infile;
int Oflag;
long snaplen;
char *p;
int dlt;
bpf_u_int32 netmask = PCAP_NETMASK_UNKNOWN;
char *cmdbuf;
pcap_t *pd;
struct bpf_program fcode;
#ifdef WIN32
if(wsockinit() != 0) return 1;
#endif /* WIN32 */
#ifndef BDEBUG
dflag = 1;
#else
/* if optimizer debugging is enabled, output DOT graph
* `dflag=4' is equivalent to -dddd to follow -d/-dd/-ddd
* convention in tcpdump command line
*/
dflag = 4;
#endif
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:m:Os:")) != -1) {
switch (op) {
case 'd':
++dflag;
break;
case 'F':
infile = optarg;
break;
case 'O':
Oflag = 0;
break;
case 'm': {
in_addr_t addr;
addr = inet_addr(optarg);
if (addr == INADDR_NONE)
error("invalid netmask %s", optarg);
netmask = addr;
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]);
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));
if (!bpf_validate(fcode.bf_insns, fcode.bf_len))
warn("Filter doesn't pass validation");
#ifdef BDEBUG
// 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);
#endif
bpf_dump(&fcode, dflag);
pcap_close(pd);
exit(0);
}
static void
usage(void)
{
(void)fprintf(stderr, "%s, with %s\n", program_name,
pcap_lib_version());
(void)fprintf(stderr,
"Usage: %s [-dO] [ -F file ] [ -m netmask] [ -s snaplen ] dlt [ expression ]\n",
program_name);
exit(1);
}

View file

@ -0,0 +1,142 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <pcap.h>
static int ifprint(pcap_if_t *d);
static char *iptos(bpf_u_int32 in);
int main(int argc, char **argv)
{
pcap_if_t *alldevs;
pcap_if_t *d;
char *s;
bpf_u_int32 net, mask;
int exit_status = 0;
char errbuf[PCAP_ERRBUF_SIZE+1];
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 ( (s = pcap_lookupdev(errbuf)) == NULL)
{
fprintf(stderr,"Error in pcap_lookupdev: %s\n",errbuf);
exit_status = 2;
}
else
{
printf("Preferred device name: %s\n",s);
}
if (pcap_lookupnet(s, &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));
}
exit(exit_status);
}
static int ifprint(pcap_if_t *d)
{
pcap_addr_t *a;
#ifdef INET6
char ntop_buf[INET6_ADDRSTRLEN];
#endif
int status = 1; /* success */
printf("%s\n",d->name);
if (d->description)
printf("\tDescription: %s\n",d->description);
printf("\tLoopback: %s\n",(d->flags & PCAP_IF_LOOPBACK)?"yes":"no");
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_ntoa(((struct sockaddr_in *)(a->addr))->sin_addr));
if (a->netmask)
printf("\t\tNetmask: %s\n",
inet_ntoa(((struct sockaddr_in *)(a->netmask))->sin_addr));
if (a->broadaddr)
printf("\t\tBroadcast Address: %s\n",
inet_ntoa(((struct sockaddr_in *)(a->broadaddr))->sin_addr));
if (a->dstaddr)
printf("\t\tDestination Address: %s\n",
inet_ntoa(((struct sockaddr_in *)(a->dstaddr))->sin_addr));
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,
ntop_buf, sizeof ntop_buf));
if (a->netmask)
printf("\t\tNetmask: %s\n",
inet_ntop(AF_INET6,
((struct sockaddr_in6 *)(a->netmask))->sin6_addr.s6_addr,
ntop_buf, sizeof ntop_buf));
if (a->broadaddr)
printf("\t\tBroadcast Address: %s\n",
inet_ntop(AF_INET6,
((struct sockaddr_in6 *)(a->broadaddr))->sin6_addr.s6_addr,
ntop_buf, sizeof ntop_buf));
if (a->dstaddr)
printf("\t\tDestination Address: %s\n",
inet_ntop(AF_INET6,
((struct sockaddr_in6 *)(a->dstaddr))->sin6_addr.s6_addr,
ntop_buf, sizeof ntop_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,226 @@
/*
* 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.
*/
#ifndef lint
static const char copyright[] =
"@(#) 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 <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/select.h>
#include <poll.h>
char *program_name;
/* Forwards */
static void countme(u_char *, const struct pcap_pkthdr *, const u_char *);
static void usage(void) __attribute__((noreturn));
static void error(const char *, ...);
static void warning(const char *, ...);
static char *copy_argv(char **);
static pcap_t *pd;
extern int optind;
extern int opterr;
extern char *optarg;
int
main(int argc, char **argv)
{
register int op;
bpf_u_int32 localnet, netmask;
register char *cp, *cmdbuf, *device;
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:")) != -1) {
switch (op) {
case 'i':
device = optarg;
break;
default:
usage();
/* NOTREACHED */
}
}
if (device == NULL) {
device = pcap_lookupdev(ebuf);
if (device == NULL)
error("%s", ebuf);
}
*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 (pcap_setnonblock(pd, 1, 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);
exit(status == -1 ? 1 : 0);
}
static void
countme(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
{
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,216 @@
/*
* 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.
*/
#ifndef lint
static const char copyright[] =
"@(#) 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 <unistd.h>
#include <errno.h>
#define MAXIMUM_SNAPLEN 65535
static char *program_name;
/* Forwards */
static void usage(void) __attribute__((noreturn));
static void error(const char *, ...);
static void warning(const char *, ...);
extern int optind;
extern int opterr;
extern char *optarg;
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_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 (useactivate) {
pd = pcap_create(device, ebuf);
if (pd == NULL)
error("%s", 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 {
*ebuf = '\0';
pd = pcap_open_live(device, 65535, 0, 1000, ebuf);
if (pd == NULL)
error("%s", ebuf);
else if (*ebuf)
warning("%s", ebuf);
}
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,11 @@
pcap = pcap_open_dead(link, snaplen);
/* todo: hook together argv to a single string */
prog = argv[0];
if (pcap_compile(pcap, &p, prog, optimize, 0) < 0) {
fprintf(stderr, pcap_geterr(pcap));
exit(1);
}
bpf_dump(&p, option);
pcap_freecode(&p);
pcap_close(pcap);

View file

@ -0,0 +1,84 @@
/*
* 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.
*/
#ifndef lint
static const char copyright[] =
"@(#) 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>
/* Forwards */
static void error(const char *, ...);
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,350 @@
/*
* 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.
*/
#ifndef lint
static const char copyright[] =
"@(#) 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 <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/select.h>
#include <poll.h>
char *program_name;
/* Forwards */
static void countme(u_char *, const struct pcap_pkthdr *, const u_char *);
static void usage(void) __attribute__((noreturn));
static void error(const char *, ...);
static void warning(const char *, ...);
static char *copy_argv(char **);
static pcap_t *pd;
extern int optind;
extern int opterr;
extern char *optarg;
int
main(int argc, char **argv)
{
register int op;
bpf_u_int32 localnet, netmask;
register char *cp, *cmdbuf, *device;
int doselect, dopoll, dotimeout, dononblock;
struct bpf_program fcode;
char ebuf[PCAP_ERRBUF_SIZE];
int selectable_fd;
int status;
int packet_count;
device = NULL;
doselect = 0;
dopoll = 0;
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;
break;
case 'p':
dopoll = 1;
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) {
device = pcap_lookupdev(ebuf);
if (device == NULL)
error("%s", ebuf);
}
*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 (pcap_get_selectable_fd(pd) == -1)
error("pcap_get_selectable_fd() fails");
if (dononblock) {
if (pcap_setnonblock(pd, 1, ebuf) == -1)
error("pcap_setnonblock failed: %s", ebuf);
}
selectable_fd = pcap_get_selectable_fd(pd);
printf("Listening on %s\n", device);
if (doselect) {
for (;;) {
fd_set setread, setexcept;
struct timeval seltimeout;
FD_ZERO(&setread);
FD_SET(selectable_fd, &setread);
FD_ZERO(&setexcept);
FD_SET(selectable_fd, &setexcept);
if (dotimeout) {
seltimeout.tv_sec = 0;
seltimeout.tv_usec = 1000;
status = select(selectable_fd + 1, &setread,
NULL, &setexcept, &seltimeout);
} else {
status = select(selectable_fd + 1, &setread,
NULL, &setexcept, NULL);
}
if (status == -1) {
printf("Select returns error (%s)\n",
strerror(errno));
} 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;
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
polltimeout = -1;
status = poll(&fd, 1, polltimeout);
if (status == -1) {
printf("Poll returns error (%s)\n",
strerror(errno));
} 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;
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, const u_char *sp)
{
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,406 @@
/*
* 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.
*/
#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>
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
/* BSD-flavored OS - 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>
#ifndef HAVE___ATTRIBUTE__
#define __attribute__(x)
#endif
static char *program_name;
/* Forwards */
static void usage(void) __attribute__((noreturn));
static void error(const char *, ...)
__attribute__((noreturn, format (printf, 1, 2)));
static void warning(const char *, ...)
__attribute__((format (printf, 1, 2)));
extern int optind;
extern int opterr;
extern char *optarg;
/*
* 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;
char *cmdbuf;
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.
*/
device = pcap_lookupdev(ebuf);
if (device == NULL) {
error("couldn't find interface to use: %s",
ebuf);
}
}
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);
}

View file

@ -0,0 +1,309 @@
#!/usr/bin/env python
"""
This program parse the output from pcap_compile() to visualize the CFG after
each optimize phase.
Usage guide:
1. Enable optimizier debugging code when configure libpcap,
and build libpcap & filtertest
./configure --enable-optimizer-dbg
make
make filtertest
2. Run filtertest to compile BPF expression, save to output a.txt
./filtertest EN10MB host 192.168.1.1 > a.txt
3. Send a.txt to this program's standard input
cat a.txt | tests/visopts.py
4. Step 2&3 can be merged:
./filtertest EN10MB host 192.168.1.1 | tests/visopts.py
5. The standard output is something like this:
generated files under directory: /tmp/visopts-W9ekBw
the directory will be removed when this programs finished.
open this link: http://localhost:39062/expr1.html
6. Using open link at the 3rd line `http://localhost:39062/expr1.html'
Note:
1. CFG graph is translated to SVG document, expr1.html embeded them as external
document. If you open expr1.html as local file using file:// protocol, some
browsers will deny such requests so the web pages will not shown properly.
For chrome, you can run it using following command to avoid this:
chromium --disable-web-security
That's why this program start a localhost http server.
2. expr1.html use jquery from http://ajax.googleapis.com, so you need internet
access to show the web page.
"""
import sys, os
import string
import subprocess
import json
html_template = string.Template("""
<html>
<head>
<title>BPF compiler optimization phases for $expr </title>
<style type="text/css">
.hc {
/* half width container */
display: inline-block;
float: left;
width: 50%;
}
</style>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"/></script>
<!--script type="text/javascript" src="./jquery.min.js"/></script-->
<script type="text/javascript">
var expr = '$expr';
var exprid = 1;
var gcount = $gcount;
var logs = JSON.parse('$logs');
logs[gcount] = "";
var leftsvg = null;
var rightsvg = null;
function gurl(index) {
index += 1;
if (index < 10)
s = "00" + index;
else if (index < 100)
s = "0" + index;
else
s = "" + index;
return "./expr" + exprid + "_g" + s + ".svg"
}
function annotate_svgs() {
if (!leftsvg || !rightsvg) return;
$$.each([$$(leftsvg), $$(rightsvg)], function() {
$$(this).find("[id|='block'][opacity]").each(function() {
$$(this).removeAttr('opacity');
});
});
$$(leftsvg).find("[id|='block']").each(function() {
var has = $$(rightsvg).find("#" + this.id).length != 0;
if (!has) $$(this).attr("opacity", "0.4");
else {
$$(this).click(function() {
var target = $$(rightsvg).find("#" + this.id);
var offset = $$("#rightsvgc").offset().top + target.position().top;
window.scrollTo(0, offset);
target.focus();
});
}
});
$$(rightsvg).find("[id|='block']").each(function() {
var has = $$(leftsvg).find("#" + this.id).length != 0;
if (!has) $$(this).attr("opacity", "0.4");
else {
$$(this).click(function() {
var target = $$(leftsvg).find("#" + this.id);
var offset = $$("#leftsvgc").offset().top + target.position().top;
window.scrollTo(0, offset);
target.focus();
});
}
});
}
function init_svgroot(svg) {
svg.setAttribute("width", "100%");
svg.setAttribute("height", "100%");
}
function wait_leftsvg() {
if (leftsvg) return;
var doc = document.getElementById("leftsvgc").getSVGDocument();
if (doc == null) {
setTimeout(wait_leftsvg, 500);
return;
}
leftsvg = doc.documentElement;
//console.log(leftsvg);
// initialize it
init_svgroot(leftsvg);
annotate_svgs();
}
function wait_rightsvg() {
if (rightsvg) return;
var doc = document.getElementById("rightsvgc").getSVGDocument();
if (doc == null) {
setTimeout(wait_rightsvg, 500);
return;
}
rightsvg = doc.documentElement;
//console.log(rightsvg);
// initialize it
init_svgroot(rightsvg);
annotate_svgs();
}
function load_left(index) {
var url = gurl(index);
var frag = "<embed id='leftsvgc' type='image/svg+xml' pluginspage='http://www.adobe.com/svg/viewer/install/' src='" + url + "'/>";
$$("#lsvg").html(frag);
$$("#lcomment").html(logs[index]);
$$("#lsvglink").attr("href", url);
leftsvg = null;
wait_leftsvg();
}
function load_right(index) {
var url = gurl(index);
var frag = "<embed id='rightsvgc' type='image/svg+xml' pluginspage='http://www.adobe.com/svg/viewer/install/' src='" + url + "'/>";
$$("#rsvg").html(frag);
$$("#rcomment").html(logs[index]);
$$("#rsvglink").attr("href", url);
rightsvg = null;
wait_rightsvg();
}
$$(document).ready(function() {
for (var i = 0; i < gcount; i++) {
var opt = "<option value='" + i + "'>loop" + i + " -- " + logs[i] + "</option>";
$$("#lselect").append(opt);
$$("#rselect").append(opt);
}
var on_selected = function() {
var index = parseInt($$(this).children("option:selected").val());
if (this.id == "lselect")
load_left(index);
else
load_right(index);
}
$$("#lselect").change(on_selected);
$$("#rselect").change(on_selected);
$$("#backward").click(function() {
var index = parseInt($$("#lselect option:selected").val());
if (index <= 0) return;
$$("#lselect").val(index - 1).change();
$$("#rselect").val(index).change();
});
$$("#forward").click(function() {
var index = parseInt($$("#rselect option:selected").val());
if (index >= gcount - 1) return;
$$("#lselect").val(index).change();
$$("#rselect").val(index + 1).change();
});
if (gcount >= 1) $$("#lselect").val(0).change();
if (gcount >= 2) $$("#rselect").val(1).change();
});
</script>
</head>
<body style="width: 96%">
<div>
<h1>$expr</h1>
<div style="text-align: center;">
<button id="backward" type="button">&lt;&lt;</button>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
<button id="forward" type="button">&gt;&gt;</button>
</div>
</div>
<br/>
<div style="clear: both;">
<div class="hc lc">
<select id="lselect"></select>
<a id="lsvglink" target="_blank">open this svg in browser</a>
<p id="lcomment"></p>
</div>
<div class="hc rc">
<select id="rselect"></select>
<a id="rsvglink" target="_blank">open this svg in browser</a>
<p id="rcomment"></p>
</div>
</div>
<br/>
<div style="clear: both;">
<div id="lsvg" class="hc lc"></div>
<div id="rsvg" class="hc rc"></div>
</div>
</body>
</html>
""")
def write_html(expr, gcount, logs):
logs = map(lambda s: s.strip().replace("\n", "<br/>"), logs)
global html_template
html = html_template.safe_substitute(expr=expr.encode("string-escape"), gcount=gcount, logs=json.dumps(logs).encode("string-escape"))
with file("expr1.html", "wt") as f:
f.write(html)
def render_on_html(infile):
expr = None
gid = 1
log = ""
dot = ""
indot = 0
logs = []
for line in infile:
if line.startswith("machine codes for filter:"):
expr = line[len("machine codes for filter:"):].strip()
break
elif line.startswith("digraph BPF {"):
indot = 1
dot = line
elif indot:
dot += line
if line.startswith("}"):
indot = 2
else:
log += line
if indot == 2:
p = subprocess.Popen(['dot', '-Tsvg'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
svg = p.communicate(dot)[0]
with file("expr1_g%03d.svg" % (gid), "wt") as f:
f.write(svg)
logs.append(log)
gid += 1
log = ""
dot = ""
indot = 0
if indot != 0:
#unterminated dot graph for expression
return False
if expr is None:
# BPF parser encounter error(s)
return False
write_html(expr, gid - 1, logs)
return True
def run_httpd():
import SimpleHTTPServer
import SocketServer
class MySocketServer(SocketServer.TCPServer):
allow_reuse_address = True
Handler = SimpleHTTPServer.SimpleHTTPRequestHandler
httpd = MySocketServer(("localhost", 0), Handler)
print "open this link: http://localhost:%d/expr1.html" % (httpd.server_address[1])
try:
httpd.serve_forever()
except KeyboardInterrupt as e:
pass
def main():
import tempfile
import atexit
import shutil
os.chdir(tempfile.mkdtemp(prefix="visopts-"))
atexit.register(shutil.rmtree, os.getcwd())
print "generated files under directory: %s" % os.getcwd()
print " the directory will be removed when this programs finished."
if not render_on_html(sys.stdin):
return 1
run_httpd()
return 0
if __name__ == "__main__":
if '-h' in sys.argv or '--help' in sys.argv:
print __doc__
exit(0)
exit(main())