-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrequest.py
More file actions
125 lines (90 loc) · 2.93 KB
/
request.py
File metadata and controls
125 lines (90 loc) · 2.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# coding: utf-8
from struct import pack, pack_into
__all__ = [
"TCP_PROTOCOL",
"IP_V4",
"NORMAL_ERL_NODE",
"HIDDEN_NODE",
"HIGHEST_VERSION",
"LOWEST_VERSION",
"EPMDRequest",
"Alive2Request",
"NamesRequest",
"PortRequest"
]
ALIVE2_REQ = 120
NAMES_REQ = 110
PORT_PLEASE_REQ = 122
TCP_PROTOCOL = 0
IP_V4 = 1
NORMAL_ERL_NODE = 77
HIDDEN_NODE = 72
HIGHEST_VERSION = 5
LOWEST_VERSION = 5
class EPMDRequest:
def encode(self):
raw_packet = self.get_raw_data()
packet_len = len(raw_packet)
return pack('>H{pack_len}s'.format(pack_len=packet_len),
packet_len, raw_packet)
def get_raw_data(self):
raise NotImplementedError("protected method _get_raw_data should be "
"implemented!")
class EmptyEPMDRequest(EPMDRequest):
def get_raw_data(self):
return b'\x00'
def encode(self):
return b'\x00'
class Alive2Request(EPMDRequest):
expected_response_len = 4
def __init__(self, port_no,
node_type=NORMAL_ERL_NODE,
protocol=TCP_PROTOCOL,
high_ver=HIGHEST_VERSION,
low_ver=LOWEST_VERSION,
node_name='pynode',
extra=None):
self.port_no = port_no
self.node_type = node_type
self.protocol = protocol
self.high_ver = high_ver
self.low_ver = low_ver
self.node_name = node_name
self.extra = extra
def get_raw_data(self):
node_name_encoded = self.node_name.encode()
nlen = len(node_name_encoded)
if self.extra is not None:
extra_encoded = self.extra.encode()
elen = len(extra_encoded)
else:
elen = 0
packet = pack(
'>BHBBHHH{nlen}sH'.format(nlen=nlen),
ALIVE2_REQ, # B, ALIVE2_REQ
self.port_no, # H, PORT_NO
self.node_type, # B, NODE_TYPE
self.protocol, # B, PROTOCOL
self.high_ver, # H, HIGHEST_VERSION
self.low_ver, # H, LOWEST_VERSION
nlen, # H, NLEN
node_name_encoded, # {nlen}s, NODENAME
elen # H, EXTRA_LEN
)
if elen:
packet = pack_into('{elen}s'.format(elen=elen),
packet, len(packet))
return packet
class NamesRequest(EPMDRequest):
''' NAMES_REQ packet coder '''
def get_raw_data(self):
return pack('B', NAMES_REQ)
class PortRequest(EPMDRequest):
''' PORT_PLEASE_REQ packet coder '''
def __init__(self, nodename):
self._nodename = nodename
def get_raw_data(self):
node_name_encoded = self._nodename.encode()
nlen = len(node_name_encoded)
return pack('>B{nlen}s'.format(nlen=nlen), PORT_PLEASE_REQ,
node_name_encoded)