#endif
#ifdef BDEBUG
-int pcap_optimizer_debug;
+/*
+ * The internal "debug printout" flag for the filter expression optimizer.
+ * The code to print that stuff is present only if BDEBUG is defined, so
+ * the flag, and the routine to set it, are defined only if BDEBUG is
+ * defined.
+ */
+static int pcap_optimizer_debug;
+
+/*
+ * Routine to set that flag.
+ *
+ * This is intended for libpcap developers, not for general use.
+ * If you want to set these in a program, you'll have to declare this
+ * routine yourself, with the appropriate DLL import attribute on Windows;
+ * it's not declared in any header file, and won't be declared in any
+ * header file provided by libpcap.
+ */
+PCAP_API void pcap_set_optimizer_debug(int value);
+
+PCAP_API_DEF void
+pcap_set_optimizer_debug(int value)
+{
+ pcap_optimizer_debug = value;
+}
+
+/*
+ * The internal "print dot graph" flag for the filter expression optimizer.
+ * The code to print that stuff is present only if BDEBUG is defined, so
+ * the flag, and the routine to set it, are defined only if BDEBUG is
+ * defined.
+ */
+static int pcap_print_dot_graph;
+
+/*
+ * Routine to set that flag.
+ *
+ * This is intended for libpcap developers, not for general use.
+ * If you want to set these in a program, you'll have to declare this
+ * routine yourself, with the appropriate DLL import attribute on Windows;
+ * it's not declared in any header file, and won't be declared in any
+ * header file provided by libpcap.
+ */
+PCAP_API void pcap_set_print_dot_graph(int value);
+
+PCAP_API_DEF void
+pcap_set_print_dot_graph(int value)
+{
+ pcap_print_dot_graph = value;
+}
+
#endif
/*
{
#ifdef BDEBUG
- if (pcap_optimizer_debug > 1) {
+ if (pcap_optimizer_debug > 1 || pcap_print_dot_graph) {
printf("opt_loop(root, %d) begin\n", do_stmts);
opt_dump(cstate, ic);
}
find_edom(opt_state, ic->root);
opt_blks(cstate, opt_state, ic, do_stmts);
#ifdef BDEBUG
- if (pcap_optimizer_debug > 1) {
+ if (pcap_optimizer_debug > 1 || pcap_print_dot_graph) {
printf("opt_loop(root, %d) bottom, done=%d\n", do_stmts, opt_state->done);
opt_dump(cstate, ic);
}
opt_loop(cstate, &opt_state, ic, 1);
intern_blocks(&opt_state, ic);
#ifdef BDEBUG
- if (pcap_optimizer_debug > 1) {
+ if (pcap_optimizer_debug > 1 || pcap_print_dot_graph) {
printf("after intern_blocks()\n");
opt_dump(cstate, ic);
}
#endif
opt_root(&ic->root);
#ifdef BDEBUG
- if (pcap_optimizer_debug > 1) {
+ if (pcap_optimizer_debug > 1 || pcap_print_dot_graph) {
printf("after opt_root()\n");
opt_dump(cstate, ic);
}
static void
opt_dump(compiler_state_t *cstate, struct icode *ic)
{
- /* if optimizer debugging is enabled, output DOT graph
- * `pcap_optimizer_debug=4' is equivalent to -dddd to follow -d/-dd/-ddd
- * convention in tcpdump command line
+ /*
+ * If the CFG, in DOT format, is requested, output it rather than
+ * the code that would be generated from that graph.
*/
- if (pcap_optimizer_debug > 3)
+ if (pcap_print_dot_graph)
dot_dump(cstate, ic);
else
plain_dump(cstate, ic);
* Some stuff for use when debugging the optimizer.
*/
#ifdef BDEBUG
-extern int pcap_optimizer_debug; /* optimizer debugging level */
-
#define NBIDS 1000
extern int bids[NBIDS];
#endif
pcap_debug = value;
}
#endif
-
-#ifdef BDEBUG
-/*
- * Set the internal "debug printout" flag for the filter expression optimizer.
- * The code to print that stuff is present only if BDEBUG is defined, so
- * the flag, and the routine to set it, are defined only if BDEBUG is
- * defined.
- *
- * This is intended for libpcap developers, not for general use.
- * If you want to set these in a program, you'll have to declare this
- * routine yourself, with the appropriate DLL import attribute on Windows;
- * it's not declared in any header file, and won't be declared in any
- * header file provided by libpcap.
- */
-PCAP_API void pcap_set_optimizer_debug(int value);
-
-PCAP_API_DEF void
-pcap_set_optimizer_debug(int value)
-{
- pcap_optimizer_debug = value;
-}
-#endif
#ifdef BDEBUG
/*
- * We have pcap_set_optimizer_debug() in libpcap; declare it (it's not declared
- * by any libpcap header, because it's a special hack, only available if
- * libpcap was configured to include it, and only intended for use by
- * libpcap developers trying to debug the optimizer for filter expressions).
+ * 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;
char *cp;
int op;
int dflag;
+ int gflag;
char *infile;
int Oflag;
long snaplen;
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
+ gflag = 0;
+
infile = NULL;
Oflag = 1;
snaplen = 68;
program_name = argv[0];
opterr = 0;
- while ((op = getopt(argc, argv, "dF:m:Os:")) != -1) {
+ 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;
#ifdef BDEBUG
pcap_set_optimizer_debug(dflag);
+ pcap_set_print_dot_graph(gflag);
#endif
pd = pcap_open_dead(dlt, snaplen);
(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);
}
./configure --enable-optimizer-dbg
make
make testprogs
-2. Run filtertest to compile BPF expression, save to output a.txt
- testprogs/filtertest EN10MB host 192.168.1.1 > a.txt
+2. Run filtertest to compile BPF expression and produce the CFG as a
+ DOT graph, save to output a.txt
+ testprogs/filtertest -g EN10MB host 192.168.1.1 > a.txt
3. Send a.txt to this program's standard input
cat a.txt | testprogs/visopts.py
4. Step 2&3 can be merged:
- testprogs/filtertest EN10MB host 192.168.1.1 | testprogs/visopts.py
+ testprogs/filtertest -g EN10MB host 192.168.1.1 | testprogs/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.
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
+1. The CFG is translated to SVG an 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: