Skip to content

Instantly share code, notes, and snippets.

@initialed85
Created January 15, 2020 11:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save initialed85/b184593945f0b1e89fbd2fbb18065ed6 to your computer and use it in GitHub Desktop.
Save initialed85/b184593945f0b1e89fbd2fbb18065ed6 to your computer and use it in GitHub Desktop.
Python packet generator
# 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
@initialed85
Copy link
Author

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).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment