traffic-taffy 0.5.8__py3-none-any.whl → 0.6.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- traffic_taffy/__init__.py +1 -1
- traffic_taffy/compare.py +86 -54
- traffic_taffy/comparison.py +13 -5
- traffic_taffy/dissection.py +31 -17
- traffic_taffy/dissectmany.py +52 -27
- traffic_taffy/dissector.py +22 -1
- traffic_taffy/dissector_engine/__init__.py +24 -1
- traffic_taffy/dissector_engine/dnstap.py +121 -0
- traffic_taffy/dissector_engine/dpkt.py +207 -41
- traffic_taffy/dissector_engine/scapy.py +27 -32
- traffic_taffy/graph.py +22 -13
- traffic_taffy/output/__init__.py +36 -20
- traffic_taffy/output/console.py +32 -17
- traffic_taffy/output/fsdb.py +17 -12
- traffic_taffy/output/memory.py +23 -16
- traffic_taffy/tests/test_compare_results.py +37 -37
- traffic_taffy/tests/test_dpkt_engine.py +15 -0
- traffic_taffy/tests/test_pcap_dissector.py +4 -4
- traffic_taffy/tests/test_pcap_splitter.py +0 -1
- traffic_taffy/tools/cache_info.py +10 -7
- traffic_taffy/tools/compare.py +10 -16
- traffic_taffy/tools/dissect.py +8 -6
- traffic_taffy/tools/explore.py +20 -46
- traffic_taffy/tools/graph.py +6 -5
- {traffic_taffy-0.5.8.dist-info → traffic_taffy-0.6.1.dist-info}/METADATA +11 -2
- traffic_taffy-0.6.1.dist-info/RECORD +35 -0
- traffic_taffy-0.6.1.dist-info/licenses/LICENSE.txt +204 -0
- traffic_taffy/dissectorresults.py +0 -21
- traffic_taffy/tests/test_result_storage.py +0 -16
- traffic_taffy-0.5.8.dist-info/RECORD +0 -34
- {traffic_taffy-0.5.8.dist-info → traffic_taffy-0.6.1.dist-info}/WHEEL +0 -0
- {traffic_taffy-0.5.8.dist-info → traffic_taffy-0.6.1.dist-info}/entry_points.txt +0 -0
traffic_taffy/output/__init__.py
CHANGED
@@ -1,25 +1,40 @@
|
|
1
|
+
"""Base module for output classes."""
|
2
|
+
|
3
|
+
from __future__ import annotations
|
4
|
+
from typing import TYPE_CHECKING
|
5
|
+
|
6
|
+
if TYPE_CHECKING:
|
7
|
+
from traffic_taffy.comparison import Comparison
|
8
|
+
|
9
|
+
|
1
10
|
class Output:
|
2
|
-
|
11
|
+
"""Base class for outputting reports."""
|
12
|
+
|
13
|
+
def __init__(self, report: Comparison, options: dict | None = None):
|
14
|
+
"""Initialize the base."""
|
3
15
|
self.report = report
|
4
|
-
self.output_options = options
|
16
|
+
self.output_options = options or {}
|
5
17
|
|
6
18
|
@property
|
7
|
-
def report(self):
|
19
|
+
def report(self) -> Comparison:
|
20
|
+
"""The report itself."""
|
8
21
|
return self._report
|
9
22
|
|
10
23
|
@report.setter
|
11
|
-
def report(self, new_report):
|
24
|
+
def report(self, new_report: Comparison) -> None:
|
12
25
|
self._report = new_report
|
13
26
|
|
14
27
|
@property
|
15
|
-
def output_options(self):
|
28
|
+
def output_options(self) -> dict:
|
29
|
+
"""A list of output options."""
|
16
30
|
return self._output_options
|
17
31
|
|
18
32
|
@output_options.setter
|
19
|
-
def output_options(self, new_output_options):
|
33
|
+
def output_options(self, new_output_options: dict) -> None:
|
20
34
|
self._output_options = new_output_options
|
21
35
|
|
22
|
-
def output(self, report=None):
|
36
|
+
def output(self, report: Comparison | None = None) -> None:
|
37
|
+
"""Dump a report to the output stream."""
|
23
38
|
if not report:
|
24
39
|
report = self.report
|
25
40
|
contents = report.contents
|
@@ -55,12 +70,12 @@ class Output:
|
|
55
70
|
):
|
56
71
|
continue
|
57
72
|
|
58
|
-
# TODO: we don't do match_value here?
|
73
|
+
# TODO(hardaker): we don't do match_value here?
|
59
74
|
|
60
75
|
record_count = 0
|
61
76
|
for subkey, data in sorted(
|
62
77
|
contents[key].items(),
|
63
|
-
key=lambda x: x[1]
|
78
|
+
key=lambda x: getattr(x[1], sort_by),
|
64
79
|
reverse=sort_order,
|
65
80
|
):
|
66
81
|
if not self.filter_check(data):
|
@@ -84,16 +99,18 @@ class Output:
|
|
84
99
|
|
85
100
|
self.output_close()
|
86
101
|
|
87
|
-
def output_new_section(self, key):
|
102
|
+
def output_new_section(self, key: str) -> None:
|
103
|
+
"""Create a new section header."""
|
88
104
|
return
|
89
105
|
|
90
|
-
def output_close(self):
|
106
|
+
def output_close(self) -> None:
|
107
|
+
"""Close the output stream."""
|
91
108
|
return
|
92
109
|
|
93
110
|
def filter_check(self, data: dict) -> bool:
|
94
|
-
"Return true if we should include it."
|
95
|
-
delta: float = data
|
96
|
-
total: int = data
|
111
|
+
"""Return true if we should include it."""
|
112
|
+
delta: float = data.delta_percentage
|
113
|
+
total: int = data.total
|
97
114
|
|
98
115
|
if self.output_options["only_positive"] and delta <= 0:
|
99
116
|
return False
|
@@ -122,12 +139,11 @@ class Output:
|
|
122
139
|
# just check output_options["minimum_count"]
|
123
140
|
if total > self.output_options["minimum_count"]:
|
124
141
|
return True
|
125
|
-
|
142
|
+
elif (
|
143
|
+
total > self.output_options["minimum_count"]
|
144
|
+
and abs(delta) > self.output_options["print_threshold"]
|
145
|
+
):
|
126
146
|
# require both
|
127
|
-
|
128
|
-
total > self.output_options["minimum_count"]
|
129
|
-
and abs(delta) > self.output_options["print_threshold"]
|
130
|
-
):
|
131
|
-
return True
|
147
|
+
return True
|
132
148
|
|
133
149
|
return False
|
traffic_taffy/output/console.py
CHANGED
@@ -1,21 +1,36 @@
|
|
1
|
+
"""A module to output comparison results to the console."""
|
2
|
+
|
3
|
+
from __future__ import annotations
|
4
|
+
from typing import Dict, Any, TYPE_CHECKING
|
5
|
+
from rich.console import Console as RichConsole
|
6
|
+
|
1
7
|
from traffic_taffy.output import Output
|
2
8
|
from traffic_taffy.dissection import Dissection
|
3
|
-
|
9
|
+
|
10
|
+
if TYPE_CHECKING:
|
11
|
+
from traffic_taffy.comparison import Comparison
|
4
12
|
|
5
13
|
|
6
14
|
class Console(Output):
|
7
|
-
|
15
|
+
"""An output class for reporting to a console."""
|
16
|
+
|
17
|
+
BOLD_LIMIT = 0.5
|
18
|
+
POSITIVE = 0.0
|
19
|
+
|
20
|
+
def __init__(self, *args: list, **kwargs: Dict[str, Any]):
|
21
|
+
"""Create a console reporting object."""
|
8
22
|
super().__init__(*args, **kwargs)
|
9
23
|
self.console = None
|
10
24
|
self.have_done_header = False
|
11
25
|
|
12
26
|
# actual routines to print stuff
|
13
|
-
def init_console(self):
|
27
|
+
def init_console(self) -> None:
|
28
|
+
"""Initialize the rich console object."""
|
14
29
|
if not self.console:
|
15
30
|
self.console = RichConsole()
|
16
31
|
|
17
|
-
def output_start(self, report):
|
18
|
-
"
|
32
|
+
def output_start(self, report: Comparison) -> None:
|
33
|
+
"""Print the header about columns being displayed."""
|
19
34
|
# This should match the spacing in print_contents()
|
20
35
|
self.init_console()
|
21
36
|
|
@@ -42,31 +57,31 @@ class Console(Output):
|
|
42
57
|
|
43
58
|
self.console.print(line)
|
44
59
|
|
45
|
-
def output_new_section(self, key):
|
46
|
-
|
47
|
-
|
48
|
-
def output_record(self, key, subkey, data) -> None:
|
49
|
-
"prints a report to the console"
|
60
|
+
def output_new_section(self, key: str) -> None:
|
61
|
+
"""Print a new section border."""
|
62
|
+
self.console.print(f"----- {key}")
|
50
63
|
|
51
|
-
|
64
|
+
def output_record(self, key: str, subkey: Any, data: Dict[str, Any]) -> None:
|
65
|
+
"""Print a report to the console."""
|
66
|
+
delta_percentage: float = data.delta_percentage
|
52
67
|
|
53
68
|
# apply some fancy styling
|
54
69
|
style = ""
|
55
|
-
if delta_percentage < -
|
70
|
+
if delta_percentage < -Console.BOLD_LIMIT:
|
56
71
|
style = "[bold red]"
|
57
|
-
elif delta_percentage <
|
72
|
+
elif delta_percentage < Console.POSITIVE:
|
58
73
|
style = "[red]"
|
59
|
-
elif delta_percentage >
|
74
|
+
elif delta_percentage > Console.BOLD_LIMIT:
|
60
75
|
style = "[bold green]"
|
61
|
-
elif delta_percentage >
|
76
|
+
elif delta_percentage > Console.POSITIVE:
|
62
77
|
style = "[green]"
|
63
78
|
endstyle = style.replace("[", "[/")
|
64
79
|
|
65
80
|
# construct the output line with styling
|
66
81
|
subkey = Dissection.make_printable(key, subkey)
|
67
82
|
line = f" {style}{subkey:<50}{endstyle}"
|
68
|
-
line += f" {data
|
69
|
-
line += f" {100*data
|
83
|
+
line += f" {data.left_count:>8} {data.right_count:>8} {data.delta_absolute:>8}"
|
84
|
+
line += f" {100*data.left_percentage:>7.2f} {100*data.right_percentage:>7.2f} {100*delta_percentage:>7.2f}"
|
70
85
|
|
71
86
|
# print it to the rich console
|
72
87
|
self.console.print(line)
|
traffic_taffy/output/fsdb.py
CHANGED
@@ -1,12 +1,18 @@
|
|
1
|
+
"""A module to output comparison results to an FSDB output."""
|
1
2
|
import sys
|
2
3
|
import pyfsdb
|
4
|
+
from typing import Any
|
3
5
|
|
4
6
|
from traffic_taffy.output import Output
|
5
7
|
from traffic_taffy.dissection import Dissection
|
8
|
+
from traffic_taffy.comparison import Comparison
|
6
9
|
|
7
10
|
|
8
11
|
class Fsdb(Output):
|
9
|
-
|
12
|
+
"""An FSDB report generator."""
|
13
|
+
|
14
|
+
def __init__(self, *args: list, **kwargs: dict):
|
15
|
+
"""Create an FSDB report generator."""
|
10
16
|
super().__init__(*args, **kwargs)
|
11
17
|
self.console = None
|
12
18
|
self.have_done_header = False
|
@@ -26,25 +32,24 @@ class Fsdb(Output):
|
|
26
32
|
]
|
27
33
|
self.fsdb.converters = [str, str, str, int, int, int, float, float, float]
|
28
34
|
|
29
|
-
def output_start(self, report):
|
30
|
-
"
|
35
|
+
def output_start(self, report: Comparison) -> None:
|
36
|
+
"""Print the header about columns being displayed."""
|
31
37
|
# This should match the spacing in print_contents()
|
32
38
|
self.in_report = report.title
|
33
39
|
|
34
|
-
def output_record(self, key, subkey, data) -> None:
|
35
|
-
"
|
36
|
-
|
40
|
+
def output_record(self, key: str, subkey: Any, data: dict) -> None:
|
41
|
+
"""Print a report to the console."""
|
37
42
|
subkey = Dissection.make_printable(key, subkey)
|
38
43
|
self.fsdb.append(
|
39
44
|
[
|
40
45
|
self.in_report,
|
41
46
|
key,
|
42
47
|
subkey,
|
43
|
-
data
|
44
|
-
data
|
45
|
-
data
|
46
|
-
data
|
47
|
-
data
|
48
|
-
data
|
48
|
+
data.left_count,
|
49
|
+
data.right_count,
|
50
|
+
data.delta_absolute,
|
51
|
+
data.left_percentage,
|
52
|
+
data.right_percentage,
|
53
|
+
data.delta_percentage,
|
49
54
|
]
|
50
55
|
)
|
traffic_taffy/output/memory.py
CHANGED
@@ -1,11 +1,17 @@
|
|
1
|
+
"""Store contents of a report in memory."""
|
1
2
|
from collections import defaultdict
|
3
|
+
from typing import Any
|
2
4
|
|
3
5
|
from traffic_taffy.output import Output
|
4
6
|
from traffic_taffy.dissection import Dissection
|
7
|
+
from traffic_taffy.comparison import Comparison
|
5
8
|
|
6
9
|
|
7
10
|
class Memory(Output):
|
8
|
-
|
11
|
+
"""A class for storing report contents in memory."""
|
12
|
+
|
13
|
+
def __init__(self, *args: list, **kwargs: dict):
|
14
|
+
"""Create a Memory object."""
|
9
15
|
super().__init__(*args, **kwargs)
|
10
16
|
self.console = None
|
11
17
|
self.have_done_header = False
|
@@ -13,39 +19,40 @@ class Memory(Output):
|
|
13
19
|
self.memory = None
|
14
20
|
|
15
21
|
@property
|
16
|
-
def title(self):
|
22
|
+
def title(self) -> str:
|
23
|
+
"""The title of the report."""
|
17
24
|
return self._title
|
18
25
|
|
19
26
|
@title.setter
|
20
|
-
def title(self, new_title):
|
27
|
+
def title(self, new_title: str) -> None:
|
21
28
|
self._title = new_title
|
22
29
|
|
23
30
|
@property
|
24
|
-
def memory(self):
|
31
|
+
def memory(self) -> dict:
|
32
|
+
"""The data for the report."""
|
25
33
|
return self._memory
|
26
34
|
|
27
35
|
@memory.setter
|
28
|
-
def memory(self, new_memory):
|
36
|
+
def memory(self, new_memory: dict) -> None:
|
29
37
|
self._memory = new_memory
|
30
38
|
|
31
|
-
def output_start(self, report):
|
32
|
-
"
|
39
|
+
def output_start(self, report: Comparison) -> None:
|
40
|
+
"""Print the header about columns being displayed."""
|
33
41
|
# This should match the spacing in print_contents()
|
34
42
|
self.title = report.title
|
35
43
|
self.memory = defaultdict(list)
|
36
44
|
|
37
|
-
def output_record(self, key, subkey, data) -> None:
|
38
|
-
"
|
39
|
-
|
45
|
+
def output_record(self, key: str, subkey: Any, data: dict) -> None:
|
46
|
+
"""Print a report to the console."""
|
40
47
|
subkey = Dissection.make_printable(key, subkey)
|
41
48
|
self.memory[key].append(
|
42
49
|
{
|
43
50
|
"subkey": subkey,
|
44
|
-
"left_count": data
|
45
|
-
"right_count": data
|
46
|
-
"delta_absolute": data
|
47
|
-
"left_percentage": data
|
48
|
-
"right_percentage": data
|
49
|
-
"delta_percentage": data
|
51
|
+
"left_count": data.left_count,
|
52
|
+
"right_count": data.right_count,
|
53
|
+
"delta_absolute": data.delta_absolute,
|
54
|
+
"left_percentage": data.left_percentage,
|
55
|
+
"right_percentage": data.right_percentage,
|
56
|
+
"delta_percentage": data.delta_percentage,
|
50
57
|
}
|
51
58
|
)
|
@@ -1,5 +1,5 @@
|
|
1
1
|
from collections import Counter
|
2
|
-
from traffic_taffy.compare import PcapCompare
|
2
|
+
from traffic_taffy.compare import PcapCompare, Report
|
3
3
|
|
4
4
|
|
5
5
|
def test_compare_results():
|
@@ -9,42 +9,42 @@ def test_compare_results():
|
|
9
9
|
# this should be positive when right_data is larger
|
10
10
|
expected = {
|
11
11
|
"src": {
|
12
|
-
"a":
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
"b":
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
"c":
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
"__NEW_VALUES__":
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
12
|
+
"a": Report(
|
13
|
+
total=20,
|
14
|
+
left_count=5,
|
15
|
+
right_count=15,
|
16
|
+
delta_absolute=15 - 5,
|
17
|
+
left_percentage=5.0 / 15.0,
|
18
|
+
right_percentage=15.0 / 30.0,
|
19
|
+
delta_percentage=15.0 / 30.0 - 5.0 / 15.0,
|
20
|
+
),
|
21
|
+
"b": Report(
|
22
|
+
total=-10, # only in 1
|
23
|
+
left_count=10,
|
24
|
+
right_count=0,
|
25
|
+
delta_absolute=0 - 10,
|
26
|
+
left_percentage=10.0 / 15.0,
|
27
|
+
right_percentage=0.0,
|
28
|
+
delta_percentage=-1.0,
|
29
|
+
),
|
30
|
+
"c": Report(
|
31
|
+
total=15, # only in 2
|
32
|
+
left_count=0,
|
33
|
+
right_count=15,
|
34
|
+
delta_absolute=15 - 0,
|
35
|
+
left_percentage=0.0,
|
36
|
+
right_percentage=15.0 / 30.0,
|
37
|
+
delta_percentage=1.0,
|
38
|
+
),
|
39
|
+
"__NEW_VALUES__": Report(
|
40
|
+
total=2, # 1 on each side
|
41
|
+
left_count=1, # b
|
42
|
+
right_count=1, # c
|
43
|
+
delta_absolute=1 - 1,
|
44
|
+
left_percentage=1.0 / 15.0, # TODO: nuke this
|
45
|
+
right_percentage=1.0 / 30.0, # TODO: nuke this
|
46
|
+
delta_percentage=1.0 / 30.0 - 1.0 / 15.0,
|
47
|
+
),
|
48
48
|
}
|
49
49
|
}
|
50
50
|
|
@@ -0,0 +1,15 @@
|
|
1
|
+
import os
|
2
|
+
from traffic_taffy.dissection import PCAPDissectorLevel
|
3
|
+
from traffic_taffy.dissector_engine.dpkt import DissectionEngineDpkt
|
4
|
+
|
5
|
+
def test_dpkt_engine():
|
6
|
+
test_pcap = "dns.pcap"
|
7
|
+
test_pcap = "port53-2023-30-31_20.pcap"
|
8
|
+
test_pcap = "airplane-wireless.pcap"
|
9
|
+
if not os.path.exists(test_pcap):
|
10
|
+
return
|
11
|
+
|
12
|
+
engine = DissectionEngineDpkt(test_pcap,
|
13
|
+
dissector_level = PCAPDissectorLevel.COMMON_LAYERS)
|
14
|
+
dissection = engine.load()
|
15
|
+
|
@@ -4,7 +4,7 @@ from traffic_taffy.dissection import Dissection
|
|
4
4
|
from traffic_taffy.dissector import PCAPDissector, PCAPDissectorLevel
|
5
5
|
|
6
6
|
|
7
|
-
def test_dissector_load():
|
7
|
+
def test_dissector_load() -> None:
|
8
8
|
from traffic_taffy.dissector import PCAPDissector
|
9
9
|
|
10
10
|
pd = PCAPDissector("bogus")
|
@@ -12,7 +12,7 @@ def test_dissector_load():
|
|
12
12
|
assert pd.pcap_file == "bogus"
|
13
13
|
|
14
14
|
|
15
|
-
def test_dissector_simple_callback():
|
15
|
+
def test_dissector_simple_callback() -> None:
|
16
16
|
base_pcap = "/tmp/dissector-test.pcap" # doesn't need to exist
|
17
17
|
save_file = base_pcap + ".taffy"
|
18
18
|
|
@@ -52,7 +52,7 @@ def test_dissector_simple_callback():
|
|
52
52
|
# create a new one to make sure it's blank
|
53
53
|
pd = PCAPDissector(
|
54
54
|
base_pcap,
|
55
|
-
dissector_level=PCAPDissectorLevel.
|
55
|
+
dissector_level=PCAPDissectorLevel.COUNT_ONLY.value,
|
56
56
|
cache_results=True,
|
57
57
|
)
|
58
58
|
|
@@ -67,5 +67,5 @@ def test_dissector_simple_callback():
|
|
67
67
|
os.unlink(save_file)
|
68
68
|
|
69
69
|
|
70
|
-
def test_dissector_scapy_callback():
|
70
|
+
def test_dissector_scapy_callback() -> None:
|
71
71
|
assert True
|
@@ -1,13 +1,14 @@
|
|
1
|
-
"""Loads the cached data for a file to display the results about it"""
|
1
|
+
"""Loads the cached data for a file to display the results about it."""
|
2
2
|
|
3
|
-
from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
|
3
|
+
from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter, Namespace
|
4
|
+
from pathlib import Path
|
4
5
|
from rich import print
|
5
6
|
import logging
|
6
7
|
import msgpack
|
7
8
|
|
8
9
|
|
9
|
-
def parse_args():
|
10
|
-
"Parse the command line arguments."
|
10
|
+
def parse_args() -> Namespace:
|
11
|
+
"""Parse the command line arguments."""
|
11
12
|
parser = ArgumentParser(
|
12
13
|
formatter_class=ArgumentDefaultsHelpFormatter,
|
13
14
|
description=__doc__,
|
@@ -34,15 +35,17 @@ def parse_args():
|
|
34
35
|
return args
|
35
36
|
|
36
37
|
|
37
|
-
def main():
|
38
|
+
def main() -> None:
|
39
|
+
"""Run taffy-cache-info."""
|
38
40
|
args = parse_args()
|
39
41
|
|
40
42
|
for cache_file in args.cache_file:
|
41
43
|
print(f"===== {cache_file} ======")
|
42
|
-
|
44
|
+
with Path(cache_file).open("rb") as fh:
|
45
|
+
contents = msgpack.load(fh, strict_map_key=False)
|
43
46
|
|
44
47
|
# play the major keys
|
45
|
-
for key in contents
|
48
|
+
for key in contents:
|
46
49
|
if key != "dissection" and key != "parameters":
|
47
50
|
print(f"{key:<20} {contents[key]}")
|
48
51
|
|
traffic_taffy/tools/compare.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1
|
-
"""Takes a set of pcap files to compare and creates a report"""
|
1
|
+
"""Takes a set of pcap files to compare and creates a report."""
|
2
2
|
|
3
|
-
|
3
|
+
import sys
|
4
|
+
from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter, Namespace
|
4
5
|
import logging
|
5
6
|
from traffic_taffy.output.console import Console
|
6
7
|
from traffic_taffy.output.fsdb import Fsdb
|
@@ -14,8 +15,8 @@ from traffic_taffy.dissector import (
|
|
14
15
|
from traffic_taffy.compare import PcapCompare
|
15
16
|
|
16
17
|
|
17
|
-
def parse_args():
|
18
|
-
"Parse the command line arguments."
|
18
|
+
def parse_args() -> Namespace:
|
19
|
+
"""Parse the command line arguments."""
|
19
20
|
parser = ArgumentParser(
|
20
21
|
formatter_class=ArgumentDefaultsHelpFormatter,
|
21
22
|
description=__doc__,
|
@@ -31,7 +32,7 @@ def parse_args():
|
|
31
32
|
)
|
32
33
|
|
33
34
|
limitor_parser = limitor_add_parseargs(parser)
|
34
|
-
compare_add_parseargs(limitor_parser, False)
|
35
|
+
compare_add_parseargs(limitor_parser, add_subgroup=False)
|
35
36
|
dissector_add_parseargs(parser)
|
36
37
|
|
37
38
|
debugging_group = parser.add_argument_group("Debugging options")
|
@@ -43,14 +44,6 @@ def parse_args():
|
|
43
44
|
help="Define the logging verbosity level (debug, info, warning, error, ...).",
|
44
45
|
)
|
45
46
|
|
46
|
-
parser.add_argument(
|
47
|
-
"-s",
|
48
|
-
"--sort-by",
|
49
|
-
default="delta%",
|
50
|
-
type=str,
|
51
|
-
help="Sort report entries by this column",
|
52
|
-
)
|
53
|
-
|
54
47
|
parser.add_argument("pcap_files", type=str, nargs="*", help="PCAP files to analyze")
|
55
48
|
|
56
49
|
args = parser.parse_args()
|
@@ -62,7 +55,8 @@ def parse_args():
|
|
62
55
|
return args
|
63
56
|
|
64
57
|
|
65
|
-
def main():
|
58
|
+
def main() -> None:
|
59
|
+
"""Run taffy-compare."""
|
66
60
|
args = parse_args()
|
67
61
|
|
68
62
|
# setup output options
|
@@ -88,7 +82,7 @@ def main():
|
|
88
82
|
cache_file_suffix=args.cache_file_suffix,
|
89
83
|
maximum_count=printing_arguments["maximum_count"],
|
90
84
|
dissection_level=args.dissection_level,
|
91
|
-
between_times=args.between_times,
|
85
|
+
# between_times=args.between_times, # TODO(hardaker): TBD
|
92
86
|
bin_size=args.bin_size,
|
93
87
|
ignore_list=args.ignore_list,
|
94
88
|
pcap_filter=args.filter,
|
@@ -101,7 +95,7 @@ def main():
|
|
101
95
|
try:
|
102
96
|
reports = pc.compare()
|
103
97
|
except ValueError:
|
104
|
-
exit()
|
98
|
+
sys.exit()
|
105
99
|
|
106
100
|
if args.fsdb:
|
107
101
|
output = Fsdb(None, printing_arguments)
|
traffic_taffy/tools/dissect.py
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
"""Performs generic dissection of a PCAP file."""
|
2
|
+
import logging
|
1
3
|
from traffic_taffy.dissector import (
|
2
4
|
dissector_add_parseargs,
|
3
5
|
limitor_add_parseargs,
|
@@ -5,14 +7,14 @@ from traffic_taffy.dissector import (
|
|
5
7
|
PCAPDissector,
|
6
8
|
)
|
7
9
|
from traffic_taffy.dissectmany import PCAPDissectMany
|
10
|
+
from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter, Namespace
|
8
11
|
|
9
12
|
|
10
|
-
def main():
|
11
|
-
|
12
|
-
import logging
|
13
|
+
def main() -> None:
|
14
|
+
"""Dissect a pcap file and report contents."""
|
13
15
|
|
14
|
-
def parse_args():
|
15
|
-
"Parse the command line arguments."
|
16
|
+
def parse_args() -> Namespace:
|
17
|
+
"""Parse the command line arguments."""
|
16
18
|
parser = ArgumentParser(
|
17
19
|
formatter_class=ArgumentDefaultsHelpFormatter,
|
18
20
|
description=__doc__,
|
@@ -67,7 +69,7 @@ def main():
|
|
67
69
|
force_overwrite=args.force_overwrite,
|
68
70
|
force_load=args.force_load,
|
69
71
|
)
|
70
|
-
dissections = pdm.load_all(True, dont_fork=args.dont_fork)
|
72
|
+
dissections = pdm.load_all(return_as_list=True, dont_fork=args.dont_fork)
|
71
73
|
|
72
74
|
# merge them into a single dissection
|
73
75
|
dissection = dissections.pop(0)
|