Created
January 15, 2020 11:58
-
-
Save initialed85/b184593945f0b1e89fbd2fbb18065ed6 to your computer and use it in GitHub Desktop.
Python packet generator
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# to simulate DGPS generation | |
# python pktgen.py tb 3784 1 305 | |
# to receive | |
# python pktgen.py rb 3784 1 305 | |
# to simulate AMP generation | |
# python pktgen.py tm 13000 2.77 372 | |
# to receive | |
# python pktgen.py rm 13000 2.77 372 | |
import sys | |
import socket | |
import struct | |
import time | |
from datetime import datetime, timedelta | |
MCAST_GROUP = '239.255.192.137' | |
BCAST_ADDR = '192.168.43.255' | |
PADDING = '_you_are_something_socially_appropriate' | |
def generate_packet(length): | |
s = '' | |
while(len(s) < length): | |
s += PADDING | |
return s[0:length] | |
def in_tolerance(constant, value, tolerance): | |
if value > (constant - (constant * tolerance)) and value < (constant + (constant * tolerance)): | |
return True | |
return False | |
def log(data): | |
with open('/tmp/%s_%s_%s.log' % (mode, port, length), 'a') as f: | |
f.write('%s - %s, %i, %0.2f, %i - %s\n' % (datetime.now().strftime('%d/%m/%y %H:%M:%S.%f'), mode, port, freq, length, data.rstrip())) | |
try: | |
mode, port, freq, length = sys.argv[1].strip().lower()[:2], int(sys.argv[2]), float(sys.argv[3]), int(sys.argv[4]) | |
except: | |
print 'python pktgen.py tb 3784 1 512' | |
print 'python pktgen.py rb 3784 1 512' | |
print 'python pktgen.py tm 13000 4 1024' | |
print 'python pktgen.py rm 13000 4 1024' | |
sys.exit(1) | |
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) | |
if mode == 'tm': | |
s.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, 1) | |
addr = MCAST_GROUP | |
elif mode == 'rm': | |
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) | |
addrinfo = socket.getaddrinfo(MCAST_GROUP, None)[0] | |
group_bin = socket.inet_pton(addrinfo[0], addrinfo[4][0]) | |
mreq = group_bin + struct.pack('=I', socket.INADDR_ANY) | |
s.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) | |
s.bind(('', port)) | |
elif mode == 'tb': | |
s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) | |
addr = BCAST_ADDR | |
elif mode == 'rb': | |
s.bind(('', port)) | |
else: | |
print 'invalid syntax' | |
sys.exit(1) | |
start_time = datetime.now().strftime('%d/%m/%y %H:%M:%S.%f') | |
if mode in ['rm', 'rb']: | |
i = int(s.recvfrom(length + 32)[0].split(PADDING)[0]) + 1 | |
last_timestamp, resync, last_resync, count, status, history = datetime.now(), 0, 'never', 1, '', [] | |
log('Receiver started') | |
while True: | |
if mode in ['tm', 'tb']: | |
for i in range(0, 128): | |
s.sendto(str(i) + generate_packet(length - len(str(i))), (addr, port)) | |
sys.stderr.write("\x1b[2J\x1b[H") | |
print '%s - %scasting %i byte packets to port %i at %.02f Hz' % (start_time, 'multi' if mode == 'tm' else 'broad', length, port, freq) | |
print 'Sent "%i" (%i bytes) @ %0.2f Hz' % (i, length, freq) | |
time.sleep(1.0 / freq) | |
elif mode in ['rm', 'rb']: | |
while i < 128: | |
period = datetime.now() - last_timestamp | |
data = s.recvfrom(length + 32)[0] | |
j = int(data.split(PADDING)[0]) | |
if j == 0: | |
if i != j: | |
resync += 1 | |
i = 0 | |
last_resync = datetime.now().strftime('%d/%m/%y %H:%M:%S.%f') | |
log('Needed resync - %i, %0.2f, %i' % (port, freq, length)) | |
now = datetime.now() | |
rxfreq = 1 / (float(str(now - last_timestamp).split(':')[-1])) | |
status = 'in sync' | |
reasons = ['%i resync%s' % (resync, 's' if resync != 1 else '')] | |
if i != j: | |
status = 'out of sync' | |
reasons += ['sequence'] | |
if length != len(data): | |
status = 'out of sync' | |
reasons += ['length'] | |
if not in_tolerance(freq, rxfreq, 0.01): | |
status = 'out of sync' | |
reasons += ['frequency'] | |
avg_freq = 1 / ((last_timestamp - datetime.strptime(start_time, '%d/%m/%y %H:%M:%S.%f')).total_seconds() / count) | |
if len(history) >= 10: | |
history = history[-10:] | |
history += [[str(now).split()[1], str(i), str(j), '%.06f' % period.total_seconds(), '%.02f' % rxfreq]] | |
last_timestamp = now | |
count += 1 | |
sys.stderr.write("\x1b[2J\x1b[H") | |
print '%s - listening for %scasted %i byte packets to port %i at %.02f Hz' % (start_time, 'multi' if mode == 'rm' else 'broad', length, port, freq) | |
print 'Expected "%i" (%i bytes) @ %0.2f Hz' % (i, length, freq) | |
print 'Received "%i" (%i bytes) @ %0.2f Hz' % (j, len(data), rxfreq) | |
print 'Status: %s - %s' % (status, ', '.join(reasons)) | |
print 'Last resync: %s' % (last_resync) | |
print 'Average frequency: %0.2f Hz' % (avg_freq) | |
for record in history: | |
print '\t'.join(record) | |
log('%s (%s)' % (status, ', '.join(reasons))) | |
i += 1 | |
i = 0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
NOTE: You'll need to change the BCAST_ADDR IP to whatever the broadcast address for your network is, and you may want to change the MCAST_GROUP and PADDING variables also (though it's not necessary).