traffic-taffy 0.3.6__py3-none-any.whl → 0.4.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.
Files changed (36) hide show
  1. traffic_taffy/cache_info.py +0 -6
  2. traffic_taffy/compare.py +154 -250
  3. traffic_taffy/comparison.py +26 -0
  4. traffic_taffy/dissection.py +383 -0
  5. traffic_taffy/dissectmany.py +20 -18
  6. traffic_taffy/dissector.py +128 -476
  7. traffic_taffy/dissector_engine/__init__.py +35 -0
  8. traffic_taffy/dissector_engine/dpkt.py +98 -0
  9. traffic_taffy/dissector_engine/scapy.py +98 -0
  10. traffic_taffy/graph.py +23 -90
  11. traffic_taffy/graphdata.py +35 -20
  12. traffic_taffy/output/__init__.py +118 -0
  13. traffic_taffy/output/console.py +72 -0
  14. traffic_taffy/output/fsdb.py +50 -0
  15. traffic_taffy/output/memory.py +51 -0
  16. traffic_taffy/pcap_splitter.py +17 -36
  17. traffic_taffy/tools/cache_info.py +65 -0
  18. traffic_taffy/tools/compare.py +110 -0
  19. traffic_taffy/tools/dissect.py +77 -0
  20. traffic_taffy/tools/explore.py +686 -0
  21. traffic_taffy/tools/graph.py +85 -0
  22. {traffic_taffy-0.3.6.dist-info → traffic_taffy-0.4.1.dist-info}/METADATA +1 -1
  23. traffic_taffy-0.4.1.dist-info/RECORD +29 -0
  24. traffic_taffy-0.4.1.dist-info/entry_points.txt +6 -0
  25. pcap_compare/cache_info.py +0 -46
  26. pcap_compare/compare.py +0 -288
  27. pcap_compare/dissectmany.py +0 -21
  28. pcap_compare/dissector.py +0 -512
  29. pcap_compare/dissectorresults.py +0 -21
  30. pcap_compare/graph.py +0 -210
  31. traffic_taffy/explore.py +0 -221
  32. traffic_taffy-0.3.6.dist-info/RECORD +0 -22
  33. traffic_taffy-0.3.6.dist-info/entry_points.txt +0 -5
  34. {pcap_compare → traffic_taffy/tools}/__init__.py +0 -0
  35. {traffic_taffy-0.3.6.dist-info → traffic_taffy-0.4.1.dist-info}/WHEEL +0 -0
  36. {traffic_taffy-0.3.6.dist-info → traffic_taffy-0.4.1.dist-info}/top_level.txt +0 -0
pcap_compare/graph.py DELETED
@@ -1,210 +0,0 @@
1
- """Read a PCAP file and graph it or parts of it"""
2
-
3
- import os
4
- import seaborn as sns
5
- import matplotlib.pyplot as plt
6
- import pandas
7
- from pandas import DataFrame, to_datetime
8
- from pcap_compare.dissector import (
9
- PCAPDissectorType,
10
- dissector_add_parseargs,
11
- limitor_add_parseargs,
12
- check_dissector_level,
13
- )
14
- from pcap_compare.dissectmany import PCAPDissectMany, PCAPDissector
15
-
16
- from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
17
- from logging import debug, info
18
- import logging
19
-
20
-
21
- def parse_args():
22
- "Parse the command line arguments."
23
- parser = ArgumentParser(
24
- formatter_class=ArgumentDefaultsHelpFormatter,
25
- description=__doc__,
26
- epilog="Exmaple Usage: ",
27
- )
28
-
29
- parser.add_argument(
30
- "-g",
31
- "--graph-elements",
32
- default=None,
33
- type=str,
34
- help="Graph these particular elements; the default is packet counts",
35
- )
36
-
37
- parser.add_argument(
38
- "-o",
39
- "--output-file",
40
- default=None,
41
- type=str,
42
- help="Where to save the output (png)",
43
- )
44
-
45
- parser.add_argument(
46
- "--log-level",
47
- "--ll",
48
- default="info",
49
- help="Define verbosity level (debug, info, warning, error, fotal, critical).",
50
- )
51
-
52
- parser.add_argument(
53
- "-b",
54
- "--bin-size",
55
- type=int,
56
- default=1,
57
- help="Bin results into this many seconds",
58
- )
59
-
60
- dissector_add_parseargs(parser)
61
- limitor_add_parseargs(parser)
62
-
63
- parser.add_argument("input_file", type=str, help="PCAP file to graph", nargs="+")
64
-
65
- args = parser.parse_args()
66
- log_level = args.log_level.upper()
67
- logging.basicConfig(level=log_level, format="%(levelname)-10s:\t%(message)s")
68
- logging.getLogger("matplotlib.font_manager").setLevel(logging.ERROR)
69
- return args
70
-
71
-
72
- class PcapGraph:
73
- def __init__(
74
- self,
75
- pcap_files: str,
76
- output_file: str,
77
- maximum_count: int = None,
78
- minimum_count: int = None,
79
- bin_size: int = None,
80
- match_key: str = None,
81
- match_value: str = None,
82
- cache_pcap_results: bool = False,
83
- dissector_level: PCAPDissectorType = PCAPDissectorType.COUNT_ONLY,
84
- ):
85
- self.pcap_files = pcap_files
86
- self.output_file = output_file
87
- self.maximum_count = maximum_count
88
- self.minimum_count = minimum_count
89
- self.bin_size = bin_size
90
- self.subsections = None
91
- self.pkt_filter = None
92
- self.match_key = match_key
93
- self.match_value = match_value
94
- self.cache_pcap_results = cache_pcap_results
95
- self.dissector_level = dissector_level
96
-
97
- def load_pcaps(self):
98
- "loads the pcap and counts things into bins"
99
- self.data = {}
100
-
101
- info("reading pcap files")
102
- pdm = PCAPDissectMany(
103
- self.pcap_files,
104
- bin_size=self.bin_size,
105
- maximum_count=self.maximum_count,
106
- dissector_level=self.dissector_level,
107
- pcap_filter=self.pkt_filter,
108
- cache_results=self.cache_pcap_results,
109
- )
110
- results = pdm.load_all()
111
-
112
- for result in results:
113
- self.data[result["file"]] = result["data"]
114
- info("done reading pcap files")
115
-
116
- def normalize_bins(self, counters):
117
- results = {}
118
- time_keys = list(counters.keys())
119
- if time_keys[0] == 0: # likely always
120
- time_keys.pop(0)
121
- time_keys[0]
122
- time_keys[-1]
123
-
124
- results = {"time": [], "count": [], "index": []}
125
-
126
- # TODO: this could likely be made much more efficient and needs hole-filling
127
- info(f"match value: {self.match_value}")
128
- for (timestamp, key, subkey, value) in PCAPDissector.find_data(
129
- counters,
130
- timestamps=time_keys,
131
- match_string=self.match_key,
132
- match_value=self.match_value,
133
- minimum_count=self.minimum_count,
134
- make_printable=True,
135
- ):
136
- index = key + "=" + subkey
137
- results["count"].append(int(value))
138
- results["index"].append(index)
139
- results["time"].append(timestamp)
140
-
141
- return results
142
-
143
- def merge_datasets(self):
144
- datasets = []
145
- for dataset in self.data:
146
- data = self.normalize_bins(self.data[dataset])
147
- data = DataFrame.from_records(data)
148
- data["filename"] = os.path.basename(dataset)
149
- data["time"] = to_datetime(data["time"], unit="s")
150
- datasets.append(data)
151
- datasets = pandas.concat(datasets)
152
- return datasets
153
-
154
- def create_graph(self):
155
- "Graph the results of the data collection"
156
- debug("creating the graph")
157
- sns.set_theme()
158
-
159
- df = self.merge_datasets()
160
- debug(df)
161
-
162
- hue_variable = "index"
163
- if df[hue_variable].nunique() == 1:
164
- hue_variable = None
165
-
166
- ax = sns.relplot(
167
- data=df,
168
- kind="line",
169
- x="time",
170
- y="count",
171
- hue=hue_variable,
172
- aspect=1.77,
173
- )
174
- ax.set(xlabel="time", ylabel="count")
175
- plt.xticks(rotation=45)
176
-
177
- info(f"saving graph to {self.output_file}")
178
- if self.output_file:
179
- plt.savefig(self.output_file)
180
- else:
181
- plt.show()
182
-
183
- def graph_it(self):
184
- debug("--- loading pcaps")
185
- self.load_pcaps()
186
- debug("--- creating graph")
187
- self.create_graph()
188
-
189
-
190
- def main():
191
- args = parse_args()
192
-
193
- check_dissector_level(args.dissection_level)
194
-
195
- pc = PcapGraph(
196
- args.input_file,
197
- args.output_file,
198
- maximum_count=args.packet_count,
199
- minimum_count=args.minimum_count,
200
- bin_size=args.bin_size,
201
- match_key=args.match_string,
202
- match_value=args.match_value,
203
- cache_pcap_results=args.cache_pcap_results,
204
- dissector_level=args.dissection_level,
205
- )
206
- pc.graph_it()
207
-
208
-
209
- if __name__ == "__main__":
210
- main()
traffic_taffy/explore.py DELETED
@@ -1,221 +0,0 @@
1
- import sys
2
- import logging
3
- from argparse import ArgumentParser, ArgumentDefaultsHelpFormatter
4
- from traffic_taffy.dissector import (
5
- dissector_add_parseargs,
6
- limitor_add_parseargs,
7
- check_dissector_level,
8
- )
9
- from traffic_taffy.graphdata import PcapGraphData
10
- from traffic_taffy.compare import PcapCompare
11
- from PyQt6.QtCharts import QLineSeries, QChart, QChartView
12
-
13
- # https://stackoverflow.com/questions/32476006/how-to-make-an-expandable-collapsable-section-widget-in-qt
14
-
15
- # class Widget(QWidget):
16
- # def __init__(self):
17
- # super().__init__()
18
- # self.__initUi()
19
-
20
- # def __initUi(self):
21
- # addBtn = QPushButton('Add')
22
- # addBtn.clicked.connect(self.__add)
23
- # self.__foldableListWidget = FoldableListWidget()
24
- # lay = QVBoxLayout()
25
- # lay.addWidget(addBtn)
26
- # lay.addWidget(self.__foldableListWidget)
27
- # self.setLayout(lay)
28
-
29
- # def __add(self):
30
- # foldedItem = QLabel("folded")
31
- # # foldedItem.setPlaceholderText('Input...')
32
-
33
- # sublist = FoldableListWidget()
34
- # subitem1 = QLabel("main item")
35
- # subitem2 = QLabel("sub item")
36
- # sublist.setFoldableListWidgetItem(subitem1, subitem2)
37
-
38
- # self.__foldableListWidget.setFoldableListWidgetItem(foldedItem, sublist)
39
-
40
-
41
- from PyQt6.QtWidgets import (
42
- QPushButton,
43
- QDialog,
44
- QGridLayout,
45
- QVBoxLayout,
46
- QHBoxLayout,
47
- QApplication,
48
- QWidget,
49
- )
50
-
51
-
52
- class TaffyExplorer(QDialog, PcapGraphData):
53
- """Explore PCAP files by comparison slices"""
54
-
55
- def __init__(self, args):
56
- super().__init__()
57
-
58
- # TODO: allow varying
59
- self.minimum_count = 2
60
-
61
- self.mainLayout = QVBoxLayout()
62
- self.setLayout(self.mainLayout)
63
-
64
- # create the graph at the top
65
- self.detail_graph = QChart()
66
- self.detail_graph_view = QChartView(self.detail_graph)
67
- self.mainLayout.addWidget(self.detail_graph_view)
68
-
69
- # create the mini graph next
70
- self.traffic_graph = QChart()
71
- self.traffic_graph.legend().hide()
72
- self.traffic_graph.setTitle("All Traffic")
73
- self.traffic_graph_view = QChartView(self.traffic_graph)
74
- self.mainLayout.addWidget(self.traffic_graph_view)
75
-
76
- # create the traffic source menu bar
77
- self.source_menus = QHBoxLayout() # TODO: line graph
78
- self.source_menus_w = QWidget()
79
- self.source_menus_w.setLayout(self.source_menus)
80
- self.mainLayout.addWidget(self.source_menus_w)
81
-
82
- # the comparison panel contains deltas between them
83
- self.comparison_panel = QGridLayout()
84
- self.comparison_panel_w = QWidget()
85
- self.comparison_panel_w.setLayout(self.comparison_panel)
86
- self.mainLayout.addWidget(self.comparison_panel_w)
87
-
88
- self.quit_button = QPushButton("Quit")
89
- self.mainLayout.addWidget(self.quit_button)
90
- self.quit_button.clicked.connect(self.quit)
91
-
92
- # self.tree = QTreeWidget()
93
- # self.tree.setHeaderHidden(True)
94
- # self.tree.setIndentation(0)
95
-
96
- self.args = args
97
-
98
- def quit(self):
99
- exit()
100
-
101
- def create_comparison(self):
102
- self.pc = PcapCompare(
103
- self.args.pcap_files,
104
- maximum_count=self.args.packet_count,
105
- print_threshold=float(self.args.print_threshold) / 100.0,
106
- print_minimum_count=self.args.minimum_count,
107
- print_match_string=self.args.match_string,
108
- only_positive=self.args.only_positive,
109
- only_negative=self.args.only_negative,
110
- cache_results=self.args.cache_pcap_results,
111
- dissection_level=self.args.dissection_level,
112
- between_times=self.args.between_times,
113
- bin_size=self.args.bin_size,
114
- )
115
-
116
- # create the graph data storage
117
- # and load everything in
118
- datasets = list(self.pc.load_pcaps())
119
-
120
- self.data = {}
121
- for dataset in datasets:
122
- self.data[dataset["file"]] = dataset["data"]
123
-
124
- def update_chart(
125
- self, chart: QChart, match_key: str, match_value: str | None = None
126
- ):
127
- self.match_key = match_key
128
- self.match_value = match_value
129
-
130
- df = self.merge_datasets()
131
-
132
- series = QLineSeries()
133
-
134
- # TODO: there must be a better way!
135
- for index in df.index:
136
- series.append(
137
- df["time"][index].to_pydatetime().timestamp(), df["count"][index]
138
- )
139
-
140
- chart.addSeries(series)
141
-
142
- def update_detail_chart(
143
- self, match_key: str = "__TOTAL__", match_value: str | None = None
144
- ):
145
- self.update_chart(self.detail_graph, match_key, match_value)
146
-
147
- def update_traffic_chart(self):
148
- self.update_chart(self.traffic_graph, "__TOTAL__")
149
-
150
- # def show_comparison(self, pcap_one, timestamp_one, pcap_two, timestamp_two):
151
-
152
-
153
- def parse_args():
154
- "Parse the command line arguments."
155
- parser = ArgumentParser(
156
- formatter_class=ArgumentDefaultsHelpFormatter,
157
- description=__doc__,
158
- epilog="Exmaple Usage: ",
159
- )
160
-
161
- limiting_parser = limitor_add_parseargs(parser)
162
-
163
- limiting_parser.add_argument(
164
- "-t",
165
- "--print-threshold",
166
- default=0.0,
167
- type=float,
168
- help="Don't print results with abs(percent) less than this threshold",
169
- )
170
-
171
- limiting_parser.add_argument(
172
- "-P", "--only-positive", action="store_true", help="Only show positive entries"
173
- )
174
-
175
- limiting_parser.add_argument(
176
- "-N", "--only-negative", action="store_true", help="Only show negative entries"
177
- )
178
-
179
- limiting_parser.add_argument(
180
- "-T",
181
- "--between-times",
182
- nargs=2,
183
- type=int,
184
- help="For single files, only display results between these timestamps",
185
- )
186
-
187
- dissector_add_parseargs(parser)
188
-
189
- debugging_group = parser.add_argument_group("Debugging options")
190
-
191
- debugging_group.add_argument(
192
- "--log-level",
193
- "--ll",
194
- default="info",
195
- help="Define the logging verbosity level (debug, info, warning, error, ...).",
196
- )
197
-
198
- parser.add_argument("pcap_files", type=str, nargs="+", help="PCAP files to analyze")
199
-
200
- args = parser.parse_args()
201
- log_level = args.log_level.upper()
202
- logging.basicConfig(level=log_level, format="%(levelname)-10s:\t%(message)s")
203
-
204
- check_dissector_level(args.dissection_level)
205
-
206
- return args
207
-
208
-
209
- def main():
210
- args = parse_args()
211
-
212
- app = QApplication(sys.argv)
213
- window = TaffyExplorer(args)
214
- window.create_comparison()
215
- window.update_traffic_chart()
216
- window.show()
217
- sys.exit(app.exec())
218
-
219
-
220
- if __name__ == "__main__":
221
- main()
@@ -1,22 +0,0 @@
1
- pcap_compare/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- pcap_compare/cache_info.py,sha256=22Fs5fNU_GzWwcAua_XfEFswRmlM8TmTbHXe2CYKQDE,1468
3
- pcap_compare/compare.py,sha256=xVRNmCsdUp1mEZub0SN2CW7osOZMgJuW__Cj9UA2DRE,9169
4
- pcap_compare/dissectmany.py,sha256=dxxChV0Qq9LeoPXiS0cCIEKFtO_RJwHxwOoPOZ3rwU8,681
5
- pcap_compare/dissector.py,sha256=iEZzLHJ7HubM3-UbZR461irXkZcpM8u_Aoa7GzWUMEY,17571
6
- pcap_compare/dissectorresults.py,sha256=LKoyX04Qjc6B7RnqtJgIWsyVnselJ9CygLkMAp3lhw0,647
7
- pcap_compare/graph.py,sha256=cioVq9JYNRVqzlRJSKLveGnGSEL9FkXDUyp-Y7osSkM,5935
8
- traffic_taffy/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
- traffic_taffy/cache_info.py,sha256=zpuuJcPzJzyma37YJE4FwKSaOBAmzImDj0Khdn2x1FI,1623
10
- traffic_taffy/compare.py,sha256=IDcO2rzYoVs_9NrUTF5TaJHzrETOw0eheu98vu_h8O4,12359
11
- traffic_taffy/dissectmany.py,sha256=DDz2Kv_0TIuSRwb2jgl2ffHEHWhwTrnhkIyzDH8pJvA,2514
12
- traffic_taffy/dissector.py,sha256=qYsSGTuxT0bYy5WW1EZaAua2guPBetEjunJk-ZMTVWU,21484
13
- traffic_taffy/dissectorresults.py,sha256=LKoyX04Qjc6B7RnqtJgIWsyVnselJ9CygLkMAp3lhw0,647
14
- traffic_taffy/explore.py,sha256=O4C5X9yKUbu0LZNKcBhwpEEoLomHWH7MqMUm2ike_Lc,6595
15
- traffic_taffy/graph.py,sha256=-fluyt-REEIzM9h3uoExrJT0K5s1LUTdcHllrr_quoM,4952
16
- traffic_taffy/graphdata.py,sha256=mXzRWAReV_oDfnRIVlxqaOCk5nZKZ07mutHPdnX5eeA,1583
17
- traffic_taffy/pcap_splitter.py,sha256=qDZ0Nd81fIteQRVElyKsD1ncBi4lg07cmx8KPl_q3rY,4585
18
- traffic_taffy-0.3.6.dist-info/METADATA,sha256=qC5mASfshWYRXyplqLMoE_yxAUdyx_H2CVn77cw118k,1014
19
- traffic_taffy-0.3.6.dist-info/WHEEL,sha256=pkctZYzUS4AYVn6dJ-7367OJZivF2e8RA9b_ZBjif18,92
20
- traffic_taffy-0.3.6.dist-info/entry_points.txt,sha256=xabsmMHgr0Pek8ccdQoW6iAKqljueozDZW-q1hJ79eU,194
21
- traffic_taffy-0.3.6.dist-info/top_level.txt,sha256=wjeQaxXSKqUzrRtfbUlbSn8SoaL4VC73yudFAEtnIuo,14
22
- traffic_taffy-0.3.6.dist-info/RECORD,,
@@ -1,5 +0,0 @@
1
- [console_scripts]
2
- taffy-cache-info = traffic_taffy.cache_info:main
3
- taffy-compare = traffic_taffy.compare:main
4
- taffy-dissect = traffic_taffy.dissector:main
5
- taffy-graph = traffic_taffy.graph:main
File without changes