Loading s7crs_memo...
#!/usr/bin/env python # -*- coding: utf-8 -*- #-----------------------------------------------------------------------------
import sys import traceback import socket import select import struct import threading import time import readline
commands=[] hub_switches=[] lock=None prompt='HubSwitch> ' comp=[]
#-----------------------------------------------------------------------------
class Record: __init__=lambda self, **kw: self.__dict__.update(**kw) __repr__=lambda self: repr(self.__dict__) __eq__=lambda self, oth: oth is not None and self.__dict__==oth.__dict__ __getitem__=lambda self, attr: self.__dict__.__getitem__(attr) __setitem__=lambda self, attr, value: self.__dict__.__setitem__(attr, value) get=lambda self, attr, default=None: self.__dict__.get(attr, default)
def show_msg(msg): sys.stdout.write('\n... %s\n%s%s'%(msg, prompt, readline.get_line_buffer())) sys.stdout.flush()
#-----------------------------------------------------------------------------
def make_link(sock, addr): return Record(fd=sock.fileno(), sock=sock, addr=addr)
def recv_frame(link): def recv_fully(sock, sz): data=bytearray(sz) view=memoryview(data) n=0 while n<sz: r=sock.recv_into(view[n:]) if r>0: n+=r else: return None return bytes(data) try: sz=recv_fully(link.sock, 4) if sz: return recv_fully(link.sock, struct.unpack('!l', sz)[0]) else: return None except: traceback.print_exc() return None
def send_frame(link, frm): def send_fully(sock, data): view=memoryview(data) sz=len(data) n=0 while n<sz: r=sock.send(view[n:]) if r>0: n+=r else: return False return True try: if send_fully(link.sock, struct.pack('!l', len(frm))): return send_fully(link.sock, frm) else: return None except: traceback.print_exc() return None
#-----------------------------------------------------------------------------
def make_hub_switch(sock, port): return Record(fd=sock.fileno(), sock=sock, port=port, links=[], bdcast=[6*b'\xFF', 6*b'\x00'], mac_table={}, hub=False)
def handle_connection(hs): try: (conn, addr)=hs.sock.accept() try: host=socket.gethostbyaddr(addr[0])[0] except: host=addr[0] port=addr[1] hs.links.append(make_link(conn, (host, port))) mode='hub' if hs.hub else 'switch' show_msg('accepting %s on %s with port %d'% ((host, port), mode, hs.port)) except: traceback.print_exc()
def close_link(hs, link): try: mode='hub' if hs.hub else 'switch' show_msg('closing %s on %s with port %d'% (link.addr, mode, hs.port)) for mac in list(hs.mac_table.keys()): if hs.mac_table[mac] is link: del hs.mac_table[mac] link.sock.close() hs.links.remove(link) except: traceback.print_exc()
def handle_traffic(hs, link): try: frm=recv_frame(link) if frm: dst_mac=frm[0:6] src_mac=frm[6:12] if src_mac not in hs.bdcast: hs.mac_table[src_mac]=link if hs.hub or dst_mac in hs.bdcast: dst_links=None else: dst_links=hs.mac_table.get(dst_mac) if dst_links: dst_links=[dst_links] else: dst_links=[l for l in hs.links if l is not link] for dst in dst_links: if not send_frame(dst, frm): close_link(hs, dst) else: close_link(hs, link) except: traceback.print_exc()
#-----------------------------------------------------------------------------
def handle_hub_switches(): while True: try: with lock: rd_list=[hs.fd for hs in hub_switches] rd_list+=[link.fd for hs in hub_switches for link in hs.links] rd_list=select.select(rd_list, [], [], 0.1)[0] if rd_list: with lock: for hs in hub_switches: if hs.fd in rd_list: handle_connection(hs) for link in hs.links: if link.fd in rd_list: handle_traffic(hs, link) except: traceback.print_exc()
#-----------------------------------------------------------------------------
def get_command(name): for cmd in commands: if cmd.name==name: return cmd return None
def get_completion(txt, nb): try: global comp if not nb: cmd_line=readline.get_line_buffer().split() if not cmd_line or len(cmd_line)==1 and txt==cmd_line[0]: comp=[cmd.name for cmd in commands if cmd.name.startswith(txt)] else: cmd=get_command(cmd_line[0]) if cmd: comp=cmd.comp(txt, cmd_line) else: comp=[] if nb<len(comp): return comp[nb]+' ' except: traceback.print_exc()
def handle_command(): try: try: input_fnct=raw_input except: input_fnct=input cmd_line=input_fnct(prompt).split() with lock: if cmd_line: cmd=get_command(cmd_line[0]) if cmd: if not cmd.action(cmd_line): return False else: help_cmd(cmd_line) except: traceback.print_exc() return True
def hub_switch_cmd(cmd_line): try: if len(cmd_line)<2: sys.stdout.write(' %s\n'%get_command(cmd_line[0]).help) else: for port in cmd_line[1:]: port=int(port) new_hs=None for hs in hub_switches: if hs.port==port: new_hs=hs break if not new_hs: sock=socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) sock.bind(('', port)) sock.listen(10) new_hs=make_hub_switch(sock, port) hub_switches.append(new_hs) if cmd_line[0]=='hub': new_hs.hub=True mode='hub' else: new_hs.hub=False mode='switch' sys.stdout.write(' emulating a %s with port %d\n'%(mode, port)) except: traceback.print_exc() return True
def del_cmd(cmd_line): try: force=False if '!' in cmd_line: cmd_line.remove('!') force=True if len(cmd_line)<2: sys.stdout.write(' %s\n'%get_command(cmd_line[0]).help) else: for port in cmd_line[1:]: port=int(port) found=False for hs in hub_switches: if hs.port==port: mode='hub' if hs.hub else 'switch' if hs.links and not force: sys.stdout.write(' %s with port %d has links\n'%(mode, port)) else: sys.stdout.write(' deleting %s with port %d\n'%(mode, port)) for link in hs.links[:]: close_link(hs, link) hs.sock.close() hub_switches.remove(hs) found=True break if not found: sys.stdout.write(' no hub/switch with port %d\n'%port) except: traceback.print_exc() return True
def list_cmd(cmd_line): try: if len(cmd_line)<2: cmd_line+=[hs.port for hs in hub_switches] if len(cmd_line)<2: sys.stdout.write(' no hub/switch emulated\n') else: for port in cmd_line[1:]: port=int(port) found=False for hs in hub_switches: if hs.port==port: mode='hub' if hs.hub else 'switch' sys.stdout.write(' %s with port %d:\n'%(mode, port)) for link in hs.links: sys.stdout.write(' %s\n'%repr(link.addr)) for mac in hs.mac_table.keys(): if hs.mac_table[mac] is link: if bytes==str: # python 2 mac=[ord(i) for i in mac] sys.stdout.write(' %s\n'% ':'.join(['%.2X'%i for i in mac])) found=True break if not found: sys.stdout.write(' no hub/switch with port %d\n'%port) except: traceback.print_exc() return True
def flush_cmd(cmd_line): try: if len(cmd_line)<2: cmd_line+=[hs.port for hs in hub_switches] if len(cmd_line)<2: sys.stdout.write(' no hub/switch emulated\n') else: for port in cmd_line[1:]: port=int(port) found=False for hs in hub_switches: if hs.port==port: mode='hub' if hs.hub else 'switch' sys.stdout.write(' flushing %s with port %d\n'%(mode, port)) for link in hs.links: hs.mac_table={} found=True break if not found: sys.stdout.write(' no hub/switch with port %d\n'%port) except: traceback.print_exc() return True
def quit_cmd(cmd_line): try: if len(cmd_line)>1: if len(cmd_line)==2 and cmd_line[1]=='!': return False sys.stdout.write(' %s\n'%get_command(cmd_line[0]).help) else: used=[hs.port for hs in hub_switches if hs.links] if used: sys.stdout.write(' hubs/switches %s are currently used\n'%used) else: return False except: traceback.print_exc() return True
def help_cmd(cmd_line): try: for cmd in commands: sys.stdout.write(' %s\n'%cmd.help) except: traceback.print_exc() return True
def port_comp(txt, cmd_line): if cmd_line[0]=='hub': hub_mode=True elif cmd_line[0]=='switch': hub_mode=False else: hub_mode=None ports=[] for hs in hub_switches: if hs.hub!=hub_mode: port=str(hs.port) if port==txt or port not in cmd_line and port.startswith(txt): ports.append(port) return ports
def no_comp(txt, cmd_line): return []
#-----------------------------------------------------------------------------
if __name__=='__main__': commands.append(Record(name='help', action=help_cmd, comp=no_comp, help='help --> display this help message')) commands.append(Record(name='hub', action=hub_switch_cmd, comp=port_comp, help='hub ports --> emulate hubs with the given ports')) commands.append(Record(name='switch', action=hub_switch_cmd, comp=port_comp, help='switch ports --> emulate switches with the given ports')) commands.append(Record(name='del', action=del_cmd, comp=port_comp, help='del ports [!] --> delete hubs/switches with given ports\n'+ ' (if unused, or force with `!\')')) commands.append(Record(name='list', action=list_cmd, comp=port_comp, help='list [ports] --> list hubs/switches')) commands.append(Record(name='flush', action=flush_cmd, comp=port_comp, help='flush [ports] --> flush MAC entries on hubs/switches')) commands.append(Record(name='quit', action=quit_cmd, comp=no_comp, help='quit [!] --> quit (if unused, or force with `!\')')) hub_switches=[] for port in sys.argv[1:]: if port.startswith('h:'): hub_switch_cmd(['hub', port[2:]]) elif port.startswith('s:'): hub_switch_cmd(['switch', port[2:]]) else: sys.stdout.write('argument `%s\' should start with `s:\' or `h:\'\n'% port) readline.set_completer(get_completion) readline.parse_and_bind('tab: complete') lock=threading.Lock() th=threading.Thread(target=handle_hub_switches) th.daemon=True # th.setDaemon(True) th.start() while handle_command(): pass for hs in hub_switches[:]: del_cmd(['del', str(hs.port)])
#-----------------------------------------------------------------------------
#!/usr/bin/env python # -*- coding: utf-8 -*- #-----------------------------------------------------------------------------
import sys import os import socket
img_name='s7crs_base.img' img_path=None for d in [os.path.dirname(__file__), '/local']: # '/home/TP/sujets' p=os.path.join(d, img_name) if os.path.isfile(p): img_path=p break if not img_path: sys.stderr.write('cannot find %s\n'%img_name) sys.exit(1)
ident=None net=[] if len(sys.argv)>1: for a in sys.argv[1:]: if ident is None: ident=a.strip() else: net.append(a) if not ident: sys.stderr.write('a VM identifier is required\n') sys.exit(1) if len(ident)>4 or not all([c in '0123456789acbdef' for c in ident.lower()]): sys.stderr.write('VM identifier should be a 16-bit hexadecimal value\n') sys.exit(1) else: ident='S7CRS'
local_cmd='/usr/local/bin/qemu-system-x86_64' win_cmd='/mnt/c/Program Files/qemu/qemu-system-x86_64.exe' if os.path.isfile(local_cmd): cmd=local_cmd cmd+=' -enable-kvm' elif os.path.isfile(win_cmd): cmd=win_cmd.replace(' ', '\\ ') # no kvm else: # default qemu cmd='qemu-system-x86_64' cmd+=' -enable-kvm' cmd+=' -name %s'%ident cmd+=' -vga std' cmd+=' -display gtk' cmd+=' -m 512M' cmd+=' -boot c' cmd+=' -hda %s'%img_path cmd+=' -snapshot'
# cmd+=' -serial unix:serial_%s,server,nowait'%ident
try: os.mkdir('SHARED') except: pass if os.path.isdir('SHARED'): cmd+=' -virtfs local,path=SHARED,mount_tag=host0,' cmd+='security_model=none,id=host0' # mkdir /root/SHARED # mount -t 9p -o trans=virtio,msize=16384 host0 /root/SHARED
if not net: cmd+=' -net none' else: mac_pfx='C0:DE' try: mac_pfx+=':%2.2X'% \ int(socket.gethostbyname(socket.gethostname()).split('.')[3]) except: mac_pfx+=':00' ident=int(ident, 16) mac_pfx+=':%2.2X'%(ident>>8) mac_pfx+=':%2.2X'%(ident&255) for (id, host_port) in enumerate(net): host_port=host_port.split(':', 1) if len(host_port)==1: host_port.insert(0, 'localhost') (host, port)=(socket.gethostbyname(host_port[0]), int(host_port[1])) cmd+=' -netdev socket,id=eth%d,connect=%s:%d'%(id, host, port) cmd+=' -device e1000,netdev=eth%d,mac=%s:%2.2X'%(id, mac_pfx, id)
cmd+=' &' # sys.stdout.write('%s\n'%cmd) os.system(cmd)
#-----------------------------------------------------------------------------