Skip to content

Commit 578521e

Browse files
committed
the great refactoring
1 parent 77bd46f commit 578521e

22 files changed

+389
-416
lines changed

README.md

+8-7
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Floodgate
1+
BPF Tools
22
=========
33

44
Here you can find a set of tool for analyzing and processing of pcap
@@ -7,14 +7,15 @@ that will match (and drop) malicious traffic.
77

88
To run these scripts you will need:
99

10-
- kernel 3.10+ (we need a decent <linux/netfilter.h> header)
11-
- sudo apt-get install python-setuptools
12-
- sudo easy_install pcappy
13-
- sudo apt-get install binutils-dev libreadline-dev python-scapy
10+
- recent kernel headers (3.10? we need a decent <linux/netfilter.h>)
11+
- install the dependencies:
1412

15-
To build:
13+
sudo apt-get install python-setuptools binutils-dev libreadline-dev python-scapy
14+
sudo easy_install pcappy
1615

17-
$ make
16+
- build binary tools in `linux_tools` directory:
17+
18+
make
1819

1920

2021
iptables_bpf.py

bpf_dns_validate.py

-120
This file was deleted.

bpf_suffix.py

-96
This file was deleted.

bpfgen

+78
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#!/usr/bin/env python
2+
3+
import argparse
4+
import os
5+
import stat
6+
import string
7+
import sys
8+
9+
import bpftools
10+
11+
12+
def main():
13+
parser = argparse.ArgumentParser(
14+
formatter_class=argparse.RawDescriptionHelpFormatter,
15+
description=r'''
16+
17+
This tool creates a Berkeley Packet Filter (BPF) bytecode that will
18+
match packets based on given criteria. Right now we support the
19+
following generators:
20+
21+
dns - matches dns queries for given domains
22+
dns_validate - matches dns malformed requests
23+
suffix - matches packets with given suffix
24+
25+
Generators can take arbitrary parameters and command line options. To
26+
read more on their usage pass '--help' option to the genrator (not to
27+
this wrapper), for example:
28+
29+
%(prog)s dns -- --help
30+
31+
Example of use:
32+
33+
%(prog)s dns -- -i *.example.com
34+
%(prog)s dns -- -i example.com *.example.com *.*.example.com
35+
%(prog)s dns_validate
36+
%(prog)s dns_validate -- --strict
37+
%(prog)s suffix -- 010203
38+
39+
Note that some common options are accepted by this wrapper, not by the
40+
BPF generators, for example:
41+
42+
%(prog)s -s suffix -- 010203
43+
%(prog)s -s -n suffix -- 010203
44+
%(prog)s -s -n -o 14 suffix -- 010203
45+
%(prog)s -s -n -o 14 -6 suffix -- 010203
46+
''')
47+
48+
parser.add_argument('-6', '--inet6', action='store_true',
49+
help='generate script for IPv6')
50+
parser.add_argument('-n', '--negate', action='store_true',
51+
help='negate the logic')
52+
parser.add_argument('-o', '--offset', type=int, default=0,
53+
help='offset of an L3 header')
54+
parser.add_argument('-s', '--assembly', action='store_true',
55+
help='print readable assembly, not numeric bytecode')
56+
parser.add_argument('type', nargs=1, choices=bpftools.generator_names,
57+
help='BPF generator type')
58+
parser.add_argument('parameters', nargs='*',
59+
help='parameters passed to the BPF generator')
60+
61+
args = parser.parse_args()
62+
63+
if len(args.type) != 1:
64+
parser.print_help()
65+
sys.exit(-1)
66+
67+
name, ret = bpftools.gen(args.type[0],
68+
args.parameters,
69+
assembly=args.assembly,
70+
l3_off=args.offset,
71+
ipversion=4 if not args.inet6 else 6,
72+
negate=args.negate,
73+
)
74+
print ret
75+
76+
77+
if __name__ == "__main__":
78+
main()

bpftools/__init__.py

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import StringIO as stringio
2+
import os
3+
import sys
4+
5+
from . import gen_dns
6+
from . import gen_dns_validate
7+
from . import gen_suffix
8+
from . import utils
9+
10+
11+
name_to_gen = {
12+
'dns': gen_dns.gen,
13+
'dns_validate': gen_dns_validate.gen,
14+
'suffix': gen_suffix.gen,
15+
}
16+
17+
generator_names = name_to_gen.keys()
18+
19+
20+
def gen(typename, params, **kwargs):
21+
gentype = name_to_gen[typename]
22+
23+
assembly = kwargs.get('assembly', False)
24+
del kwargs['assembly']
25+
26+
sys.stdout, saved_stdout = stringio.StringIO(), sys.stdout
27+
def new_exit(s):
28+
sys.stdout.seek(0)
29+
data = sys.stdout.read()
30+
sys.stdout = saved_stdout
31+
print data
32+
os._exit(s)
33+
sys.exit, saved_exit = new_exit, sys.exit
34+
35+
name = gentype(params, **kwargs)
36+
37+
data = sys.stdout.seek(0)
38+
data = sys.stdout.read()
39+
sys.stdout = saved_stdout
40+
sys.exit = saved_exit
41+
42+
if assembly:
43+
return name, data
44+
return name, utils.bpf_compile(data)

0 commit comments

Comments
 (0)