|
1
|
|
|
"""Help reading raw dump files.""" |
|
2
|
|
|
from pyof.v0x01.common.header import Header |
|
3
|
|
|
from pyof.v0x01.common.utils import new_message_from_header |
|
4
|
|
|
|
|
5
|
|
|
|
|
6
|
|
|
class RawDump: |
|
7
|
|
|
"""A helper to deal with paths and reading raw files. |
|
8
|
|
|
|
|
9
|
|
|
Attributes: |
|
10
|
|
|
content (bytes): Raw file's content. |
|
11
|
|
|
""" |
|
12
|
|
|
|
|
13
|
|
|
_HEADER_BYTES = 8 # According to OF Protocol specification |
|
14
|
|
|
|
|
15
|
|
|
def __init__(self, version, basename): |
|
16
|
|
|
"""Information to locate the dump file. |
|
17
|
|
|
|
|
18
|
|
|
Args: |
|
19
|
|
|
version (str): OpenFlow protocol version, e.g. ``v0x01``. |
|
20
|
|
|
basename (str): Only the filename without extension. |
|
21
|
|
|
E.g. ``ofpt_echo_reply``. |
|
22
|
|
|
""" |
|
23
|
|
|
self._path = 'raw/{}/{}.dat'.format(version, basename) |
|
24
|
|
|
|
|
25
|
|
|
def __repr__(self): |
|
26
|
|
|
return repr(self.unpack()) |
|
27
|
|
|
|
|
28
|
|
|
def __bytes__(self): |
|
29
|
|
|
return self.read() |
|
30
|
|
|
|
|
31
|
|
|
def read(self): |
|
32
|
|
|
"""Read the raw file. |
|
33
|
|
|
|
|
34
|
|
|
Returns: |
|
35
|
|
|
bytes: Raw file's content. |
|
36
|
|
|
""" |
|
37
|
|
|
with open(self._path, 'rb') as file: |
|
38
|
|
|
return file.read() |
|
39
|
|
|
|
|
40
|
|
|
def unpack(self): |
|
41
|
|
|
"""Unpack header and message from a byte sequence. |
|
42
|
|
|
|
|
43
|
|
|
Returns: |
|
44
|
|
|
The object type specified in the header with the corresponding |
|
45
|
|
|
header. |
|
46
|
|
|
""" |
|
47
|
|
|
content = self.read() |
|
48
|
|
|
raw_header = content[:self._HEADER_BYTES] |
|
49
|
|
|
header = _unpack_header(raw_header) |
|
50
|
|
|
raw_msg = content[self._HEADER_BYTES:header.length.value] |
|
51
|
|
|
return _unpack_message(header, raw_msg) |
|
52
|
|
|
|
|
53
|
|
|
|
|
54
|
|
|
def _unpack_header(raw_header): |
|
55
|
|
|
header = Header() |
|
56
|
|
|
header.unpack(raw_header) |
|
57
|
|
|
return header |
|
58
|
|
|
|
|
59
|
|
|
|
|
60
|
|
|
def _unpack_message(header, raw_msg): |
|
61
|
|
|
msg = new_message_from_header(header) |
|
62
|
|
|
msg.unpack(raw_msg) |
|
63
|
|
|
return msg |
|
64
|
|
|
|