-
Notifications
You must be signed in to change notification settings - Fork 899
/
Copy pathcalc.py
105 lines (88 loc) · 3.05 KB
/
calc.py
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
#!/usr/bin/env python3
# SPDX-License-Identifier: GPL-2.0-only
# Reason-GPL: import-scapy
import re
from scapy.all import (
Ether,
IntField,
Packet,
StrFixedLenField,
XByteField,
bind_layers,
srp1
)
# Define custom packet class for P4calc
class P4calc(Packet):
name = "P4calc"
# Define fields for the P4calc packet
fields_desc = [ StrFixedLenField("P", "P", length=1),
StrFixedLenField("Four", "4", length=1),
XByteField("version", 0x01),
StrFixedLenField("op", "+", length=1),
IntField("operand_a", 0),
IntField("operand_b", 0),
IntField("result", 0xDEADBABE)]
# Bind custom packet class to Ethernet type 0x1234
bind_layers(Ether, P4calc, type=0x1234)
# Custom exception for number parsing error
class NumParseError(Exception):
pass
# Custom exception for operator parsing error
class OpParseError(Exception):
pass
# Token class for representing parsed tokens
class Token:
def __init__(self, type, value=None):
self.type = type
self.value = value
# Parser function for parsing number literals
def num_parser(s, i, ts):
pattern = "^\s*([0-9]+)\s*"
match = re.match(pattern,s[i:])
if match:
ts.append(Token('num', match.group(1)))
return i + match.end(), ts
raise NumParseError('Expected number literal.')
# Parser function for parsing binary operators
def op_parser(s, i, ts):
pattern = "^\s*([-+&|^])\s*"
match = re.match(pattern,s[i:])
if match:
ts.append(Token('op', match.group(1)))
return i + match.end(), ts
raise OpParseError("Expected binary operator '-', '+', '&', '|', or '^'.")
# Function to create a sequence of parsers
def make_seq(p1, p2):
def parse(s, i, ts):
i,ts2 = p1(s,i,ts)
return p2(s,i,ts2)
return parse
def main():
p = make_seq(num_parser, make_seq(op_parser,num_parser)) # Create parser for number and operator sequence
s = ''
iface = 'eth0'
while True:
s = input('> ')
if s == "quit":
break
print(s)
try:
i,ts = p(s,0,[])
# Construct packet using parsed tokens
pkt = Ether(dst='00:04:00:00:00:00', type=0x1234) / P4calc(op=ts[1].value,
operand_a=int(ts[0].value),
operand_b=int(ts[2].value))
pkt = pkt/' '
resp = srp1(pkt, iface=iface, timeout=1, verbose=False) # Send packet and receive response
if resp:
p4calc=resp[P4calc]
if p4calc:
print(p4calc.result) # Print the result from the response packet
else:
print("cannot find P4calc header in the packet")
else:
print("Didn't receive response")
except Exception as error:
print(error) # Print any exceptions that occur during parsing or packet handling
if __name__ == '__main__':
main()