Skip to content

Commit

Permalink
refactor: observation domain id management simplified
Browse files Browse the repository at this point in the history
  • Loading branch information
ahuangfeng committed Feb 10, 2023
1 parent 175b502 commit 47bf69d
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 118 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -138,5 +138,6 @@ dmypy.json
cython_debug/

# own custom files
filtered.pcap
captured_udp_notif.pcap
pids
.DS_Store
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ $ sudo python3 src/main.py <src_ipv4> <dst_ipv4> <port_src> <port_dst>

- `--capture x` or `-c x` : (INT) Set to 1 if you need a wireshark capture of the forwarded packets, x = 1 or x = 0, Default: `0`

- `--legacy x` or `-e x` : (INT) Set to 1 if you generate legacy headers: [draft-ietf-netconf-udp-pub-channel-05](https://datatracker.ietf.org/doc/draft-ietf-netconf-udp-pub-channel/), x = 1 or x = 0, Default: `0`
- `--legacy x` or `-e x` : (INT) Set to 1 if you generate legacy headers: [draft-ietf-netconf-udp-pub-channel-05](https://datatracker.ietf.org/doc/draft-ietf-netconf-udp-pub-channel/), /!\ No segmentation is possible. x = 1 or x = 0, Default: `0`

## Examples

Expand Down
74 changes: 37 additions & 37 deletions src/resources/small.json
Original file line number Diff line number Diff line change
@@ -1,39 +1,39 @@
{
"random": 17,
"random float": 26.838,
"bool": true,
"date": "1989-10-28",
"regEx": "hellooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo world",
"enum": "json",
"firstname": "Ellette",
"lastname": "Arne",
"city": "Hagåtña",
"country": "Uzbekistan",
"countryCode": "OM",
"email uses current data": "[email protected]",
"email from expression": "[email protected]",
"array": [
"Cristine",
"Allis",
"Feliza",
"Tomasina",
"Annice"
],
"array of objects": [
{
"index": 0,
"index start at 5": 5
},
{
"index": 1,
"index start at 5": 6
},
{
"index": 2,
"index start at 5": 7
}
],
"Courtnay": {
"age": 57
}
"random": 17,
"random float": 26.838,
"bool": true,
"date": "1989-10-28",
"regEx": "hellooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo world",
"enum": "json",
"firstname": "Ellette",
"lastname": "Arne",
"city": "Tokyo",
"country": "Japan",
"countryCode": "OM",
"email uses current data": "[email protected]",
"email from expression": "[email protected]",
"array": [
"Cristine",
"Allis",
"Feliza",
"Tomasina",
"Annice"
],
"array of objects": [
{
"index": 0,
"index start at 5": 5
},
{
"index": 1,
"index start at 5": 6
},
{
"index": 2,
"index start at 5": 7
}
],
"Courtnay": {
"age": 57
}
}
102 changes: 52 additions & 50 deletions src/unyte_generator/unyte_generator.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
import time
import logging
import os
import random
from unyte_generator.utils.unyte_message_gen import mock_message_generator
from unyte_generator.utils.unyte_logger import unyte_logger
from unyte_generator.models.unyte_global import UDPN_HEADER_LEN, UDPN_SEGMENTATION_OPT_LEN
from unyte_generator.models.udpn import UDPN
import time

from scapy.all import send, wrpcap
from scapy.layers.inet import IP, UDP

from unyte_generator.models.opt import SEGMENTATION_OPT
from unyte_generator.models.payload import PAYLOAD
from scapy.layers.inet import IP, UDP
from scapy.all import send, wrpcap
from unyte_generator.models.udpn import UDPN
from unyte_generator.models.unyte_global import (UDPN_HEADER_LEN,
UDPN_SEGMENTATION_OPT_LEN)
from unyte_generator.utils.unyte_logger import unyte_logger
from unyte_generator.utils.unyte_message_gen import mock_message_generator


class UDP_notif_generator:
Expand All @@ -28,7 +31,7 @@ def __init__(self, args):
self.mtu = args.mtu
self.waiting_time = args.waiting_time
self.probability_of_loss = args.probability_of_loss
self.random_order = args.random_order
self.random_order: bool = args.random_order == 1
self.logging_level = args.logging_level
self.capture = args.capture
self.legacy = args.legacy == 1
Expand All @@ -46,95 +49,94 @@ def save_pcap(self, filename, packet):
def generate_mock_message(self):
return self.mock_generator.generate_message(self.message_size)

def generate_packet_list(self, packet_amount, maximum_length, current_message):
packet_list = []
def generate_udp_notif_packets(self, msg_payload):
payload_per_msg_len = self.mtu - UDPN_HEADER_LEN
packet_amount = 1

if (len(msg_payload) + UDPN_HEADER_LEN) > self.mtu:
payload_per_msg_len = self.mtu - UDPN_HEADER_LEN - UDPN_SEGMENTATION_OPT_LEN
packet_amount = len(msg_payload) // payload_per_msg_len
if len(msg_payload) % payload_per_msg_len != 0:
packet_amount += 1

udp_notif_packets = []
for packet_increment in range(packet_amount):
if packet_amount == 1:
packet = IP(src=self.source_ip, dst=self.destination_ip)/UDP()/UDPN()/PAYLOAD()
else:
packet = IP(src=self.source_ip, dst=self.destination_ip)/UDP()/UDPN()/SEGMENTATION_OPT()/PAYLOAD()
packet.sport = self.source_port
packet.dport = self.destination_port

if packet_amount == 1:
packet[PAYLOAD].message = current_message
packet[UDPN].header_length = UDPN_HEADER_LEN
packet[UDPN].message_length = packet[UDPN].header_length + len(packet[PAYLOAD].message)
packet[PAYLOAD].message = msg_payload
else:
packet[UDPN].header_length = UDPN_HEADER_LEN + UDPN_SEGMENTATION_OPT_LEN
packet[SEGMENTATION_OPT].segment_id = packet_increment
if (len(current_message[maximum_length * packet_increment:]) > maximum_length):
packet[PAYLOAD].message = current_message[maximum_length * packet_increment:maximum_length * (packet_increment + 1)]
if (len(msg_payload[payload_per_msg_len * packet_increment:]) > payload_per_msg_len):
packet[PAYLOAD].message = msg_payload[payload_per_msg_len * packet_increment:payload_per_msg_len * (packet_increment + 1)]
packet[UDPN].message_length = packet[UDPN].header_length + len(packet[PAYLOAD].message)
else:
packet[PAYLOAD].message = current_message[maximum_length * packet_increment:]
packet[PAYLOAD].message = msg_payload[payload_per_msg_len * packet_increment:]
packet[UDPN].message_length = packet[UDPN].header_length + len(packet[PAYLOAD].message)
packet[SEGMENTATION_OPT].last = 1
packet_list.append(packet)
return packet_list
udp_notif_packets.append(packet)
return udp_notif_packets

def forward_current_message(self, packet_list, current_domain_id, current_message_id):
def forward_current_message(self, udp_notif_msgs: list, current_domain_id: int) -> int:
current_message_lost_packets = 0
if (self.random_order == 1):
random.shuffle(packet_list)

for packet in packet_list:
if self.random_order:
random.shuffle(udp_notif_msgs)

msg_id = 0
for packet in udp_notif_msgs:
packet[UDPN].observation_domain_id = current_domain_id
packet[UDPN].message_id = current_message_id
packet[UDPN].message_id = msg_id
if (self.probability_of_loss == 0):
send(packet, verbose=0)
elif random.randint(1, int(1000 * (1 / self.probability_of_loss))) >= 1000:
send(packet, verbose=0)
else:
current_message_lost_packets += 1
if len(packet_list) == 1:
if len(udp_notif_msgs) == 1:
logging.info("simulating packet number 0 from message_id " + str(packet[UDPN].message_id) + " lost")
else:
logging.info("simulating packet number " + str(packet[SEGMENTATION_OPT].segment_id) +
" from message_id " + str(packet[UDPN].message_id) + " lost")
if len(packet_list) == 1:
if len(udp_notif_msgs) == 1:
self.logger.log_packet(packet, self.legacy)
else:
self.logger.log_segment(packet, packet[SEGMENTATION_OPT].segment_id)
self.save_pcap('filtered.pcap', packet)
self.save_pcap('captured_udp_notif.pcap', packet)
msg_id += 1
return current_message_lost_packets

def send_udp_notif(self):
timer_start = time.time()
observation_domains = []
message_ids = {}
for i in range(1 + self.additional_domains):
observation_domains.append(self.initial_domain + i)
message_ids[observation_domains[i]] = 0

self.logger.log_used_args(self)
current_message = self.generate_mock_message()
maximum_length = self.mtu - UDPN_HEADER_LEN
msg_payload = self.generate_mock_message()

lost_packets = 0
forwarded_packets = 0
message_increment = 0

if len(current_message) > maximum_length:
maximum_length = self.mtu - UDPN_HEADER_LEN - UDPN_SEGMENTATION_OPT_LEN
packet_amount = len(current_message) // maximum_length
if len(current_message) % maximum_length != 0:
packet_amount += 1
else:
packet_amount = 1

# Generate packet only once
packets_list = self.generate_packet_list(packet_amount, maximum_length, current_message)
udp_notif_msgs = self.generate_udp_notif_packets(msg_payload)
observation_domain_id = self.initial_domain

while message_increment < self.message_amount:
current_domain_id = observation_domains[message_increment % len(observation_domains)]
current_message_id = message_ids[current_domain_id]
message_ids[current_domain_id] += 1
for _ in range(self.message_amount):

current_message_lost_packets = self.forward_current_message(packets_list, current_domain_id, current_message_id)

forwarded_packets += len(packets_list) - current_message_lost_packets
current_message_lost_packets: int = self.forward_current_message(udp_notif_msgs, observation_domain_id)
forwarded_packets += len(udp_notif_msgs) - current_message_lost_packets
lost_packets += current_message_lost_packets

time.sleep(self.waiting_time)
message_increment += 1
observation_domain_id += 1

if observation_domain_id > (self.initial_domain + self.additional_domains):
observation_domain_id = self.initial_domain

timer_end = time.time()
generation_total_duration = timer_end - timer_start
Expand Down
51 changes: 22 additions & 29 deletions src/unyte_generator/unyte_generator_legacy_proto.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import time
import logging
import os
import random
from unyte_generator.utils.unyte_message_gen import mock_message_generator
from unyte_generator.utils.unyte_logger import unyte_logger
from unyte_generator.models.unyte_global import UDPN_LEGACY_HEADER_LEN
from unyte_generator.models.udpn_legacy import UDPN_legacy
from unyte_generator.models.payload import PAYLOAD
from scapy.layers.inet import IP, UDP
import time

from scapy.all import send, wrpcap
from scapy.layers.inet import IP, UDP

from unyte_generator.models.payload import PAYLOAD
from unyte_generator.models.udpn_legacy import UDPN_legacy
from unyte_generator.models.unyte_global import UDPN_LEGACY_HEADER_LEN
from unyte_generator.utils.unyte_logger import unyte_logger
from unyte_generator.utils.unyte_message_gen import mock_message_generator


class UDP_notif_generator_legacy:
Expand Down Expand Up @@ -55,14 +57,15 @@ def generate_packet_list(self, current_message):
packet_list.append(packet)
return packet_list

def forward_current_message(self, packet_list, current_domain_id, current_message_id):
def forward_current_message(self, packet_list, current_domain_id):
current_message_lost_packets = 0
if (self.random_order == 1):
random.shuffle(packet_list)


msg_id = 0
for packet in packet_list:
packet[UDPN_legacy].observation_domain_id = current_domain_id
packet[UDPN_legacy].message_id = current_message_id
packet[UDPN_legacy].message_id = msg_id
if (self.probability_of_loss == 0):
send(packet, verbose=0)
elif random.randint(1, int(1000 * (1 / self.probability_of_loss))) >= 1000:
Expand All @@ -71,42 +74,32 @@ def forward_current_message(self, packet_list, current_domain_id, current_messag
current_message_lost_packets += 1
logging.info("simulating packet number 0 from message_id " + str(packet[UDPN_legacy].message_id) + " lost")
self.logger.log_packet(packet, self.legacy)

msg_id += 1
self.save_pcap('filtered.pcap', packet)

return current_message_lost_packets

def send_udp_notif(self):
timer_start = time.time()
observation_domains = []
message_ids = {}
for i in range(1 + self.additional_domains):
observation_domains.append(self.initial_domain + i)
message_ids[observation_domains[i]] = 0

self.logger.log_used_args(self)
current_message = self.generate_mock_message()
maximum_length = self.mtu - UDPN_LEGACY_HEADER_LEN

lost_packets = 0
forwarded_packets = 0
message_increment = 0

packet_amount = 1

# Generate packet only once
packets_list = self.generate_packet_list(current_message)

while message_increment < self.message_amount:
current_domain_id = observation_domains[message_increment % len(observation_domains)]
current_message_id = message_ids[current_domain_id]
message_ids[current_domain_id] += 1

current_message_lost_packets = self.forward_current_message(packets_list, current_domain_id, current_message_id)

obs_domain_id = self.initial_domain
for _ in range(self.message_amount):
current_message_lost_packets = self.forward_current_message(packets_list, obs_domain_id)
forwarded_packets += len(packets_list) - current_message_lost_packets
lost_packets += current_message_lost_packets
time.sleep(self.waiting_time)
message_increment += 1

obs_domain_id += 1
if obs_domain_id > (self.initial_domain + self.additional_domains):
obs_domain_id = self.initial_domain

timer_end = time.time()
generation_total_duration = timer_end - timer_start
Expand Down

0 comments on commit 47bf69d

Please sign in to comment.