Skip to content

Commit 7d217c7

Browse files
committed
Merge branch 'marushchenko-feat-uvm-packet_generators-add_new_protocols' into 'devel'
Add new protocols to the PKG_GEN See merge request ndk/ndk-fpga!216
2 parents 53a9b8f + a665063 commit 7d217c7

File tree

7 files changed

+197
-67
lines changed

7 files changed

+197
-67
lines changed

comp/uvm/packet_generators/search/config.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ def __init__(self, constraints=None):
2626
self.vlan = 4
2727
self.mpls = 4
2828
self.ipv6ext = 4
29+
self.vxlan = 1
30+
self.gre = 1
2931

3032
self.constraints = constraints
3133

@@ -48,6 +50,8 @@ def copy(self):
4850
ret.vlan = self.vlan
4951
ret.mpls = self.mpls
5052
ret.ipv6ext = self.ipv6ext
53+
ret.vxlan = self.vxlan
54+
ret.gre = self.gre
5155
return ret
5256

5357
def object_get(self, path):

comp/uvm/packet_generators/search/parser.py

Lines changed: 77 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,9 @@ def protocol_next(self, config):
3737

3838

3939
#################################
40-
# PAYLOAD protocols
40+
# L7 protocols
4141
#################################
42+
4243
class Empty(base_node):
4344
def __init__(self):
4445
super().__init__("Empty")
@@ -66,25 +67,26 @@ def protocol_next(self, config):
6667
return proto
6768

6869

69-
#################################
70-
# L7 protocols
71-
#################################
72-
class ICMPv4(base_node):
70+
class VXLAN(base_node):
7371
def __init__(self):
74-
super().__init__("ICMPv4")
72+
super().__init__("VXLAN")
7573

7674
def protocol_add(self, config):
77-
return scapy.all.ICMP()
75+
return scapy.all.VXLAN()
7876

77+
def protocol_next(self, config):
78+
proto = {"ETH": 1}
7979

80-
class ICMPv6(base_node):
81-
def __init__(self):
82-
super().__init__("ICMPv6")
80+
if config.vxlan != 0:
81+
config.vxlan -= 1
8382

84-
def protocol_add(self, config):
85-
return scapy.all.ICMPv6Unknown()
83+
return proto
8684

8785

86+
#################################
87+
# L4 protocols
88+
#################################
89+
8890
class UDP(base_node):
8991
def __init__(self):
9092
super().__init__("UDP")
@@ -93,10 +95,14 @@ def protocol_add(self, config):
9395
return scapy.all.UDP()
9496

9597
def protocol_next(self, config):
96-
proto = {"Empty": 1, "Payload": 1}
98+
proto = {"Empty": 1, "Payload": 1, "VXLAN": 1}
9799
cfg_obj = config.object_get([self.name, "weight"])
98100
if cfg_obj is not None:
99101
proto.update(cfg_obj)
102+
103+
if config.vxlan == 0:
104+
proto["VXLAN"] = 0
105+
100106
return proto
101107

102108

@@ -130,9 +136,29 @@ def protocol_next(self, config):
130136
return proto
131137

132138

139+
class GRE(base_node):
140+
def __init__(self):
141+
super().__init__("GRE")
142+
143+
def protocol_add(self, config):
144+
return scapy.all.GRE(routing_present = 0)
145+
146+
def protocol_next(self, config):
147+
proto = {"ETH": 1, "IPv4": 1, "IPv6": 1}
148+
proto_weight = config.object_get([self.name, "weight"])
149+
if proto_weight is not None:
150+
proto.update(proto_weight)
151+
152+
if config.gre != 0:
153+
config.gre -= 1
154+
155+
return proto
156+
157+
133158
#################################
134-
# IP protocols
159+
# L3 protocols
135160
#################################
161+
136162
class IPv4(base_node):
137163
def __init__(self):
138164
super().__init__("IPv4")
@@ -158,10 +184,14 @@ def protocol_add(self, config):
158184
return scapy.all.IP(version=4, src=src, dst=dst)
159185

160186
def protocol_next(self, config):
161-
proto = {"Payload": 1, "Empty": 1, "ICMPv4": 1, "UDP": 1, "TCP": 1, "SCTP": 1}
187+
proto = {"Payload": 1, "Empty": 1, "ICMPv4": 1, "UDP": 1, "TCP": 1, "SCTP": 1, "GRE": 1}
162188
proto_weight = config.object_get([self.name, "weight"])
163189
if proto_weight is not None:
164190
proto.update(proto_weight)
191+
192+
if config.gre == 0:
193+
proto["GRE"] = 0
194+
165195
return proto
166196

167197

@@ -174,7 +204,7 @@ def protocol_add(self, config):
174204
return random.choice(possible_protocols)
175205

176206
def protocol_next(self, config):
177-
proto = {"Payload": 1, "Empty": 1, "ICMPv4": 1, "ICMPv6": 1, "UDP": 1, "TCP": 1, "SCTP": 1, "IPv6Ext": 1}
207+
proto = {"Payload": 1, "Empty": 1, "ICMPv6": 1, "UDP": 1, "TCP": 1, "SCTP": 1, "IPv6Ext": 1, "GRE": 1}
178208
proto_weight = config.object_get([self.name, "weight"])
179209
if proto_weight is not None:
180210
proto.update(proto_weight)
@@ -184,6 +214,9 @@ def protocol_next(self, config):
184214
if (config.ipv6ext == 0):
185215
proto["IPv6Ext"] = 0
186216

217+
if config.gre == 0:
218+
proto["GRE"] = 0
219+
187220
return proto
188221

189222

@@ -212,17 +245,37 @@ def protocol_add(self, config):
212245
return scapy.all.IPv6(version=6, src=src, dst=dst)
213246

214247
def protocol_next(self, config):
215-
proto = {"Payload": 1, "Empty": 1, "ICMPv4": 1, "ICMPv6": 1, "UDP": 1, "TCP": 1, "SCTP": 1, "IPv6Ext": 1}
248+
proto = {"Payload": 1, "Empty": 1, "ICMPv6": 1, "UDP": 1, "TCP": 1, "SCTP": 1, "IPv6Ext": 1, "GRE": 1}
216249
proto_weight = config.object_get([self.name, "weight"])
217250
if proto_weight is not None:
218251
proto.update(proto_weight)
252+
253+
if config.gre == 0:
254+
proto["GRE"] = 0
255+
219256
return proto
220257

258+
259+
class ICMPv4(base_node):
260+
def __init__(self):
261+
super().__init__("ICMPv4")
262+
263+
def protocol_add(self, config):
264+
return scapy.all.ICMP()
265+
266+
267+
class ICMPv6(base_node):
268+
def __init__(self):
269+
super().__init__("ICMPv6")
270+
271+
def protocol_add(self, config):
272+
return scapy.all.ICMPv6Unknown()
273+
274+
221275
#################################
222-
# ETHERNET protocols
276+
# L2 protocols
223277
#################################
224278

225-
226279
class MPLS(base_node):
227280
def __init__(self):
228281
super().__init__("MPLS")
@@ -307,12 +360,16 @@ def protocol_next(self, config):
307360
return proto
308361

309362

363+
#################################
364+
# Parser
365+
#################################
366+
310367
class Parser:
311368
def __init__(self, pcap_file, cfg, seed):
312369
self.protocols = {
313370
"ETH": ETH(), "VLAN": VLAN(), "TRILL": TRILL(), "PPP": PPP(), "MPLS": MPLS(), "IPv6": IPv6(), "IPv6Ext": IPv6Ext(),
314371
"IPv4": IPv4(), "TCP": TCP(), "UDP": UDP(), "ICMPv6": ICMPv6(), "ICMPv4": ICMPv4(), "SCTP": SCTP(),
315-
"Payload": Payload(), "Empty": Empty()
372+
"Payload": Payload(), "Empty": Empty(), "VXLAN": VXLAN(), "GRE": GRE()
316373
}
317374
self.pcap_file = scapy.utils.PcapWriter(pcap_file, append=False, sync=True)
318375
self.cfg = None

comp/uvm/packet_generators/search/parser_dfs.py

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
# Radek Iša <isa@cesnet.cz>
1111

1212
import scapy
13+
import random
1314

1415
from config import packet_config
1516
from parser import Parser
@@ -19,15 +20,16 @@ class dfs_item:
1920
def __init__(self, protocol, cfg):
2021
self.protocol = protocol
2122
self.index = 0
23+
self.depth = 0
2224
self.cfg = cfg.copy()
2325
proto_next = protocol.protocol_next(self.cfg)
2426
self.protocols_next = []
2527
for it in proto_next:
2628
if (proto_next[it] != 0):
2729
self.protocols_next.append(it)
2830

29-
def last(self):
30-
return len(self.protocols_next) == 0
31+
def last(self, max_depth):
32+
return (len(self.protocols_next) == 0) or (max_depth <= self.depth)
3133

3234
def next(self):
3335
if self.protocols_next is None or self.index >= len(self.protocols_next):
@@ -39,44 +41,53 @@ def next(self):
3941

4042

4143
class Parser_dfs(Parser):
42-
def __init__(self, pcap_file, cfg, seed):
44+
def __init__(self, pcap_file, cfg, seed, max_packets, min_depth, max_depth):
4345
super().__init__(pcap_file, cfg, seed)
46+
self.max_packets = max_packets
47+
self.min_depth = min_depth
48+
self.max_depth = max_depth
4449

4550
def gen(self):
51+
packets_to_generate = []
4652
next_items = []
4753

4854
cfg_act = packet_config(self.cfg)
4955
item = dfs_item(self.protocols["ETH"], cfg_act)
5056
next_items.append(item)
5157

52-
packets = 0
5358
while len(next_items) > 0:
5459
# get last item
5560
item = next_items[-1]
5661
# get next generated protocol
5762
proto_next = item.next()
5863

59-
if not item.last():
64+
if not item.last(self.max_depth):
6065
if proto_next is not None:
6166
item_next = dfs_item(self.protocols[proto_next], item.cfg)
67+
item_next.depth = item.depth + 1
6268
next_items.append(item_next)
6369
else:
6470
#remove last index there is no next protocol
6571
del next_items[-1]
66-
else:
72+
elif len(next_items)-1 >= self.min_depth:
6773
#generate packet
68-
packets += 1
6974
packet = scapy.packet.Packet()
7075

7176
for it in next_items:
7277
pkt_proto = it.protocol.protocol_add(it.cfg)
7378
if pkt_proto is not None:
74-
packet = packet / pkt_proto
79+
packet = packet / pkt_proto
7580

7681
#write packet
77-
self.write(packet)
82+
packets_to_generate.append(packet)
7883
#remove last index
7984
del next_items[-1]
85+
else:
86+
del next_items[-1]
87+
88+
# Pick some packets
89+
packets_to_generate = random.sample(packets_to_generate, min(self.max_packets, len(packets_to_generate)))
90+
for p in packets_to_generate:
91+
self.write(p)
8092

81-
print("PACKETS %d" % (packets))
82-
pass
93+
print("PACKETS %d" % len(packets_to_generate))

comp/uvm/packet_generators/search/parser_rand.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,11 @@ def gen(self):
3434
proto_next = proto_act.protocol_next(cfg)
3535
if len(proto_next) > 0:
3636
(proto_next_indexs, proto_next_weights) = self.proto_weight_get(proto_next)
37-
protocol_next_name = random.choices(proto_next_indexs, proto_next_weights)[0]
38-
proto_act = self.protocols.get(protocol_next_name)
37+
if sum(proto_next_weights) > 0:
38+
protocol_next_name = random.choices(proto_next_indexs, proto_next_weights)[0]
39+
proto_act = self.protocols.get(protocol_next_name)
40+
else:
41+
proto_act = None
3942
else:
4043
proto_act = None
4144

comp/uvm/packet_generators/search/pkt_gen.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import argparse
1616
import time
1717
import enum
18+
import sys
1819

1920

2021
class parse_alg(enum.Enum):
@@ -43,6 +44,12 @@ def main():
4344
arg_parser.add_argument(
4445
"-p", "--packets", type=int,
4546
help="number of generated packets", default=20)
47+
arg_parser.add_argument(
48+
"--mindepth", type=int,
49+
help="min depth for DFS", default=0)
50+
arg_parser.add_argument(
51+
"--maxdepth", type=int,
52+
help="max depth for DFS", default=sys.maxsize)
4653
arg_parser.add_argument(
4754
"-a", "--algorithm", type=parse_alg,
4855
help=("parse algorithms possible values [" + ' '.join(parse_alg.values()) + "]"), default="rand")
@@ -63,7 +70,7 @@ def main():
6370
if (args.algorithm == parse_alg.rand):
6471
gen = Parser_rand(args.file_output, args.conf, args.seed, args.packets)
6572
if (args.algorithm == parse_alg.dfs):
66-
gen = Parser_dfs(args.file_output, args.conf, args.seed)
73+
gen = Parser_dfs(args.file_output, args.conf, args.seed, args.packets, args.mindepth, args.maxdepth)
6774

6875
#run generator
6976
gen.gen()

0 commit comments

Comments
 (0)