def note_on(track, ptr, ev): poly_id = ptr.u8() note = ev velocity = ptr.u8() track.insert(NoteOn, poly_id=poly_id, note=note, velocity=velocity ) track.touched[poly_id] = True # Note history... if poly_id not in range(1, 8): LOG.error('Invalid poly_id at %06X = %02X (%02X v=%02X) %s', track._prev_addr, poly_id, note, velocity, track.note_history) else: old = track.note_history[poly_id] if isinstance(old, int): LOG.error('Double note_on at %06X = %02X (%02X v=%02X) %s', track._prev_addr, poly_id, note, velocity, track.note_history) track.note_history[poly_id] = note
async def get_peers(self): peers_resp = await self.request_peers() if b'failure reason' in peers_resp: # I added this LOG.error('Request to tracker for Peers failed with reason : {}'. peers_resp[b'failure reason']) return peers = self.parse_peers(peers_resp[b'peers']) return peers
def do_next_timestamp(self, line): """ increase the Timestamp """ # global Timestamp if self.Timestamp + 1 < len(self.TIME): self.Timestamp += 1 else: LOG.error('No more Timestamp available')
def do_dump_database_router(self, router): """ Run a tcpdump on the router """ if router not in self.network.keys(): LOG.error('Router %s does not exists' % router) else: Router = self.network[router] File = 'database_dump_%s.txt' % router Router.cmd('python telnet.py > %s' % File)
def do_tcpdump_router(self, router): """ Run a tcpdump on the router """ if router not in self.network.keys(): LOG.error('Router %s does not exists' % router) else: tcpdump = threading.Thread(target=self.tcpdump_router_th, args=(router, )) tcpdump.start()
def is_ok_path_req(req): """ checks if path of requirement is ok """ for i in range(len(req)): if i != len(req) - 1: if req[i] == '*' and req[i + 1] == '*': LOG.error('Cannot have two consecutive * in requirement') return False return True
def get_time(self): """ OVERRIDE return the time value NB: for simulation override this function to fast forward in time """ # global Timestamp if self.Timestamp <= len(self.TIME): return self.TIME[self.Timestamp] else: LOG.error('TIME out of bound') return 0
def check_ip(base_net, private_net, ip, Error): ip_pfx = str(ip.split('/')[0]) + '/8' ip_intf = ipaddress.ip_interface(unicode(ip_pfx)) if private_net == str(ip_intf.network): LOG.error('IP address has same prefix than private_net :' + str(ip)) Error = True ip_pfx = str(ip.split('/')[0]) + '/16' ip_intf = ipaddress.ip_interface(unicode(ip_pfx)) if base_net == str(ip_intf.network): LOG.error('IP address has same prefix than base_net :' + str(ip)) Error = True return Error
def do_traceroute(self, line): args = line.split() if len(args) != 2: LOG.error('invalid number of args: traceroute source dest\n') else: if self.running: if args[0] in self.network and args[1] in self.network: node1 = self.network[args[0]] node2 = self.network[args[1]] Route = node1.cmd('traceroute -n ' + node2.IP()) LOG.info(str(Route)) else: LOG.error('Network must be running')
def after(self, track: BmsTrack): addr = self.addr hist = track._ptr.hist(addr) if hist == Visit.MIDDLE: raise OverlapError('%s %s - middle of command' % (getname(self), hex(addr))) # We are either visiting NONE or BEGIN. # Not visited: # Visit target. # Visited: # (addr) Check preconditions and apply postconditions. # Note that OldNote compares == None. if hist == Visit.NONE: track = BmsTrack(track._file, addr, None, track.note_history).parse() else: assert hist == Visit.BEGIN # **** ASSERTION **** # We will encounter issues if any touched notes differ from the original call. # TODO: We assume we're not calling into the middle of a visited section... :'( track = track._file.track_at[addr] different = (track.pre_history != track.note_history) if any(different & track.touched): LOG.error( '''Invalid call from %06X to %06X new:%s old:%s out:%s touched:%s''', track._prev_addr, addr, track.note_history, track.pre_history, track.note_history, track.touched) # endif already visited # BMS really shouldn't be touching notes, AND leaving running notes untouched... if any(track.touched): untouched = ~track.touched if any(track.pre_history.astype(bool) & untouched): LOG.warning('Function leaves running notes untouched %s %s %s', track.touched, track.pre_history, track.note_history) # Knowing that all "touched" entries entered identically... # We must apply all "touched" entries of the note history. track.note_history[track.touched] = track.note_history[track.touched]
async def request_peers(self): async with aiohttp.ClientSession() as session: resp = await session.get(self.tracker_url, params=self._get_request_params()) resp_data = await resp.read() LOG.info('Tracker response: {}'.format(resp)) peers = None try: peers = bencoder.decode(resp_data) except AssertionError: LOG.error( 'Failed to decode Tracker response: {}'.format(resp_data)) LOG.error('Tracker request URL: {}'.format( str(resp.url).split('&'))) raise RuntimeError('Failed to get Peers from Tracker') return peers
def control_change(track, ptr, ev) -> ControlChange: # u8 cctype, [layout/4] value, [layout%4] duration # duration # val | 0 ? u8 u16 # -----+---- ---- ---- ----- # u8 | 94 95 96 97 # s8 | 98 99 9a 9b # s16 | 9c 9d 9e 9f layout = ev - 0x94 # READ CCTYPE cctype = ptr.u8() # READ VALUE values = [ptr.u8, ptr.s8, ptr.s16] value = values[layout // 4]() # READ LENGTH durations = [lambda: 0, None, ptr.u8, ptr.u16] duration = durations[layout % 4] if duration is not None: duration = duration() else: duration = None LOG.error('Unknown event 0x%s', b2h(ev)) # TODO: missing CCTYPEs try: cctype = BMS2CC[cctype] except KeyError: LOG.info('[CC %s] Unknown control change %s = %s', b2h(ev), b2h(cctype), value) cctype = 'unknown %s' % b2h(cctype) # LOG.info('control change - %s', cctype) # # ', %02X, %02X', value, duration # LOG.info(' value %s', 'u8 s8 s16'.split()[layout // 4]) # LOG.info(' duration %s', '0 ? u8 u16'.split()[layout % 4]) track.insert(ControlChange, cctype=cctype, value=value, length=duration )
def check_path(ospf_links, error, requirement): edge = [] for x in ospf_links: src = x.get('src') dest = x.get('dest') edge.append((src.get('name'), dest.get('name'))) edge.append((dest.get('name'), src.get('name'))) for req in requirement: if '*' not in req.get('requirement'): for (s, d) in zip( req.get('requirement')[:-1], req.get('requirement')[1:]): if (s, d) not in edge: error = True LOG.error('Unvalid path') return error
def __init__(self, file: BmsFile, addr:int, tracknum: Union[int, None], note_history: 'Union[array[int], None]'): super().__init__() # Initialize stuff. self._file = file # type: BmsFile self._data = file._data self._ptr = Pointer(self._data, addr, file._visited) # Insert track into file. if tracknum is not None: if tracknum in file.tracks: LOG.error('Duplicate track %d', tracknum) file.tracks[tracknum] = self # Insert track at address. file.track_at[addr] = self # Initialize track. self.type = 'track' self.tracknum = tracknum self.addr = addr self.segment = [] # type: List[BmsType] # Note history (for note_off commands) if note_history is None: self.note_history = [None] * 8 else: self.note_history = note_history[:] self.note_history = array(self.note_history) # Does this track modify note_history? # True whenever notes are started/stopped. self.touched = array([False] * 8) # HISTORY_MODE == 'LAZY' self.pre_history = np.copy(self.note_history)
def note_off(track, ptr, ev): poly_id = ev % 8 # magrittr %<>% ? # Expression object for track._note_history[poly_id] ? # Python sucks. note = track.note_history[poly_id] track.insert(NoteOff, note=note, poly_id=poly_id) track.note_history[poly_id] = OldNote(note) track.touched[poly_id] = True # Error checking... if not isinstance(note, int): LOG.error('Double note_off at %06X = %02X %s', track._prev_addr, poly_id, track.note_history)
def bms_iter(self): # TODO: Do we use segment-based or linked-list iteration? # Segment-based iteration loses event address information! it = iter(self.segment) addr = self.addr while 1: ev = self._file.at[addr] # type: BmsType ev_seg = next(it) if ev != ev_seg: LOG.error('BmsIter != segment at address %06X', addr) yield ev if 'next' in ev: addr = ev.next else: break
def after(event, file: 'BmsFile', ptr: Pointer): addr = event.addr hist = ptr.hist(addr) if hist == Visit.NONE: track = BmsTrack(track._file, addr, None, track.note_history).parse() else: assert hist == Visit.BEGIN # **** ASSERTION **** # We will encounter issues if any touched notes differ from the original call. # TODO: We assume we're not calling into the middle of a visited section... :'( track = track._file.track_at[addr] different = (track.pre_history != track.note_history) if any(different & track.touched): LOG.error( '''Invalid call from %06X to %06X new:%s old:%s out:%s touched:%s''', track._prev_addr, addr, track.note_history, track.pre_history, track.note_history, track.touched) # endif already visited # BMS really shouldn't be touching notes, AND leaving running notes untouched... if any(track.touched): untouched = ~track.touched if any(track.pre_history.astype(bool) & untouched): LOG.warning('Function leaves running notes untouched %s %s %s', track.touched, track.pre_history, track.note_history) # Knowing that all "touched" entries entered identically... # We must apply all "touched" entries of the note history. track.note_history[track.touched] = track.note_history[track.touched]
def checkRequirementConfig(d, d_req): config = d['config'] fibbing_ctrl = config.get('fibbing-controller') hosts_link = config.get('hosts-link') links = config.get('links') main_controller = config.get('main-controller') ospf_links = config.get('ospf-links') routers = config.get('routers') conf = d_req['config'] link = conf["link"] Error = False # Set up the Controller requirements for x in link: # set up router connected to dest as last one of the path rs = x.get('requirement')[-1] if rs == '*': LOG.error('The Path cannot end with the * router') Error = True continue ds = str(x.get('dest')) R = () for r in x.get('requirement'): R += (str(r), ) IS_OK = False for dsr in hosts_link: host = dsr.get('host') router = dsr.get('router') # check if dest is indeed connected to router # in the topology if host.get('name') == ds and router.get('name') == rs: IS_OK = True if not IS_OK: LOG.warning('Destination ' + ds + ' is not connected to ' + ds) if str(x.get('status')) == SCHED: start_hour = x.get('scheduled').get('start-hour') end_hour = x.get('scheduled').get('end-hour') tmp = compare(start_hour, end_hour) if (tmp == False): Error = True LOG.error('start-hour must be smaller than end-hour') if str(x.get('status')) == SCHED and\ (str(x.get('scheduled').get('type')) == BAND or\ str(x.get('scheduled').get('type')) == BACK): if not x.get('scheduled').get('link').get('from') or \ not x.get('scheduled').get('link').get('to') : Error = True LOG.error( 'router from and to of link bandwidth or backup not set') Error = check_path(links, Error, link) return Error
def checkRequirementConfig(network, requirement): """ Check the config received from the ConfD agent, concerning the requirement Input : network is the dictionary that contains the network config, requirement is the dictionary that contains the requirements config, return False if no Error was found, retrun True if at least one Error was found """ Error = False conf = requirement['config'] link = conf["link"] for x in link: if x.get('requirement')[-1] == '*': LOG.error('Path of requirement cannnot end by *') continue rs = x.get('requirement')[-1] ds = str(x.get('dest')) IS_OK = False for lk in network.get('link'): src = lk.get('src') dest = lk.get('dest') # check if dest is indeed connected to router # in the topology if (src.get('name') == ds and dest.get('name') == rs)\ or (src.get('name') == rs and dest.get('name') == ds) : IS_OK = True if not IS_OK: LOG.warning('Destination ' + ds + ' is not connected to ' + rs) if str(x.get('status')) == SCHED: start_hour = x.get('scheduled').get('start-hour') end_hour = x.get('scheduled').get('end-hour') tmp = compare(start_hour, end_hour) if (tmp == False): Error = True LOG.error('start-hour must be smaller than end-hour') if str(x.get('status')) == SCHED and\ (str(x.get('scheduled').get('type')) == BAND or\ str(x.get('scheduled').get('type')) == BACK): if not x.get('scheduled').get('link').get('from') or \ not x.get('scheduled').get('link').get('to') : Error = True LOG.error( 'router from and to of link bandwidth or backup not set') Error = check_path(network.get('link'), Error, link) return Error
def do_link(self, line): """ NB Function from Mininet CLI Bring link(s) between two nodes up or down. Usage: link node1 node2 [up/down]""" args = line.split() if len(args) != 3: LOG.error('invalid number of args: link end1 end2 [up down]\n') elif args[2] not in ['up', 'down']: LOG.error('invalid type: link end1 end2 [up down]\n') else: if self.running: self.network.configLinkStatus(*args) else: LOG.error('Network must be running')
async def _download(self): try: reader, writer = await asyncio.wait_for(asyncio.open_connection( self.host, self.port), timeout=10) except TimeoutError: LOG.error('Failed to connect to peer {}'.format(self.host)) return LOG.info('{} sending handshake'.format(self)) writer.write(self.handshake()) await writer.drain() hndshake = await reader.read(68) await self.interested(writer) buf = b'' while True: resp = await reader.read(REQUEST_SIZE) buf += resp if not buf and not resp: return while True: if len(buf) < 4: break length = struct.unpack('>I', buf[0:4])[0] if not len(buf) >= length: break def consume(buf): buf = buf[4 + length:] return buf def get_data(buf): return buf[:4 + length] if length == 0: LOG.info('[Message] keep alive') buf = consume(buf) data = get_data(buf) LOG.info('[Data]', data) continue if len(buf) < 5: LOG.info('Buffer is less than 5 bytes...breaking') break msg_id = struct.unpack('>b', buf[4:5])[0] if msg_id == 0: LOG.info('[Message] CHOKE') data = get_data(buf) buf = consume(buf) LOG.info('[DATA] {}'.format(data)) elif msg_id == 1: LOG.info('[Message] UNCHOKE') data = get_data(buf) buf = consume(buf) self.peer_choke = False elif msg_id == 2: LOG.info('[Message] INTERESTED') data = get_data(buf) buf = consume(buf) elif msg_id == 3: LOG.info('[Message] UNINTERESTED') data = get_data(buf) buf = consume(buf) elif msg_id == 4: buf = buf[5:] data = get_data(buf) buf = consume(buf) LOG.info('[Message] HAVE') elif msg_id == 5: bitfield = buf[5:4 + length] self.have_pieces = bitstring.BitArray(bitfield) LOG.info('[Message] Bitfield {}'.format(bitfield)) buf = buf[4 + length:] await self.interested(writer) elif msg_id == 7: self.inflight_requests -= 1 data = get_data(buf) buf = consume(buf) l = struct.unpack('>I', data[:4])[0] try: parts = struct.unpack('>IbII' + str(l - 9) + 's', data[:length + 4]) piece_idx, begin, data = parts[2], parts[3], parts[4] self.session.on_block_received(piece_idx, begin, data) except struct.error: LOG.error("Error decoding piece") return None else: LOG.info('Unknown message id {}'.format(msg_id)) if msg_id == 159: exit(1) await self.request_a_piece(writer)
def check_network(network, Error): """ return True if and Error has been detected otherwise return Error """ controller = network.get('controller') if not controller: LOG.error('A controller must be specified') Error = True if not network.get('destinations'): LOG.warning( 'Destinations should be configured to specify requirements') ips = {} routerids = {} routerospf = [] hosts = [] for router in network.get('routers'): if router.get('ospf6').get('enable') and\ not router.get('ospf6').get('router-id') : LOG.error('If ospf is enable router %s must have a router-id ' % router.get('name')) Error = True if not router.get('ospf6').get('enable'): hosts.append(router.get('name')) if router.get('ospf6').get('enable') and\ routerids.get(router.get('ospf6').get('router-id') ) : LOG.error('routerid should be unique %s' % router.get('ospf6').get('router-id')) LOG.info('already found here %s ' % routerids.get(router.get('ospf6').get('router-id'))) Error = True else: routerids[router.get('ospf6').get('router-id')] = router.get( 'name') routerospf.append(router.get('name')) if not router.get('loopback-addr'): LOG.error('router %s have a loopback-addr' % router.get('name')) Error = True else: if ips.get(router.get('loopback-addr')): LOG.error('loopback-addr must be unique %s' % router.get('loopback-addr')) LOG.info('already found here %s ' % ips.get(router.get('loopback-addr'))) Error = True else: ips[router.get('loopback-addr')] = router.get('name') ospfconfig = {} host_link = {} ospf_link = [] link_name_map = {} for link in network.get('link'): link_name_map[link.get('name')] = link for link in network.get('ospf-links'): l = link_name_map[link.get('name')] ospf_link.append(link.get('name')) for intf in [link.get('src'), link.get('dest')]: area = intf.get('ospf').get('area') if not ospfconfig or ospfconfig.get(area): ospfconfig[area] = { 'area': intf.get('ospf').get('area'), 'hello-interval': intf.get('ospf').get('hello-interval'), 'dead-interval': intf.get('ospf').get('dead-interval'), } else: if ospfconfig.get(area).get('hello-interval') != intf.get( 'ospf').get('hello-interval'): LOG.error( 'hello-interval should be the same for the same area %s' % area) Error = True if ospfconfig.get(area).get('hello-interval') != intf.get( 'ospf').get('hello-interval'): LOG.error( 'hello-interval should be the same for the same area %s' % area) Error = True if l.get('src').get('name') not in routerospf: LOG.error( 'To enable ospf on a link both router must have ospf enable %s' % l.get('src').get('name')) Error = True if l.get('dest').get('name') not in routerospf: LOG.error( 'To enable ospf on a link both router must have ospf enable %s' % l.get('dest').get('name')) Error = True for link in network.get('link'): src = link.get('src') dest = link.get('dest') if not src.get('name'): LOG.error('Link must have a src ') Error = True continue if not dest.get('name'): LOG.error('Link must have a dest ') Error = True continue if not src.get('ip'): LOG.error('Link must have an ip address') Error = True continue if not dest.get('ip'): LOG.error('Link must have an ip address') Error = True continue if ips.get(src.get('ip')): LOG.error('ip address should be different %s than loopback-addr' % src.get('ip')) LOG.info('already found %s' % ips.get(src.get('ip'))) Error = True if ips.get(dest.get('ip')): LOG.error('ip address should be different %s' % dest.get('ip')) LOG.info('already found %s' % ips.get(dest.get('ip'))) Error = True if link.get('name') not in ospf_link: # checking static link if src.get('name') in hosts and src.get('name') in host_link: LOG.error( 'A router without ospf can only have one static link') Error = True else: if src.get('name') in hosts and dest.get('name') in hosts: LOG.error( 'Cannot have a static link between two router without ospf' ) Error = True else: host_link[src.get('name')] = dest.get('name') if dest.get('name') in hosts and dest.get('name') in host_link: LOG.error( 'A router without ospf can only have one static link') Error = True else: if src.get('name') in hosts and dest.get('name') in hosts: LOG.error( 'Cannot have a static link between two router without ospf' ) Error = True else: host_link[dest.get('name')] = src.get('name') return Error
def build(self, *args, **kwargs): if not self.config: LOG.error(' not received config') else: LOG.info(' SUCCESS received config') conf = self.config fibbing_ctrl = conf.get('fibbing-controller') ospf_links = conf.get('link-ospf') hosts_link = conf.get('hosts-link') ctrl_links = fibbing_ctrl.get('links') ospf_routers = conf.get('routers') # get private network private_net = fibbing_ctrl.get('controller-config').get( 'private-ip-prefix') base_net = fibbing_ctrl.get('controller-config').get('base-net-perfix') # mapping router name, iprouter obj routers = {} # configure ospf routers for o_r in ospf_routers: name = o_r.get('name') routers[name] = self.addRouter( name, routerid=str(o_r.get('ospf').get('router-id')), private_net=private_net) # configure ospf links for ol in ospf_links: src = ol.get('src') dest = ol.get('dest') src_router = routers.get(src.get('name')) dest_router = routers.get(dest.get('name')) src_intfName = src.get('intf') dest_intfName = dest.get('intf') src_cost = int(ol.get('cost')) dest_cost = int(ol.get('cost')) if not ol.get('bidirectional'): src_cost = int(ol.get('src').get('cost')) dest_cost = int(ol.get('dest').get('cost')) src_params = { 'cost': src_cost, 'bw': int(ol.get('bw')), 'ip': src.get('ip'), PRIVATE_IP_KEY: src.get('private-ip'), 'prefixLen': int(src.get('ip').split('/')[1]), 'area': src.get('ospf').get('area'), 'hello-interval': src.get('ospf').get('hello-interval'), 'dead-interval': src.get('ospf').get('dead-interval'), 'secondary-ips': [], 'min_ls_arrival': int(src.get('ospf').get('lsa').get('min_ls_arrival')), 'min_ls_interval': int(src.get('ospf').get('lsa').get('min_ls_interval')), 'odelay': int(src.get('ospf').get('throttle').get('delay')), 'initial_holdtime': int(src.get('ospf').get('throttle').get('initial_holdtime')), 'max_holdtime': int(src.get('ospf').get('throttle').get('max_holdtime')) } dest_params = { 'cost': dest_cost, 'bw': int(ol.get('bw')), 'ip': dest.get('ip'), PRIVATE_IP_KEY: dest.get('private-ip'), 'prefixLen': int(dest.get('ip').split('/')[1]), 'area': dest.get('ospf').get('area'), 'hello-interval': dest.get('ospf').get('hello-interval'), 'dead-interval': str(dest.get('ospf').get('dead-interval')), 'secondary-ips': [], 'min_ls_arrival': int(dest.get('ospf').get('lsa').get('min_ls_arrival')), 'min_ls_interval': int(dest.get('ospf').get('lsa').get('min_ls_interval')), 'odelay': int(dest.get('ospf').get('throttle').get('delay')), 'initial_holdtime': int(dest.get('ospf').get('throttle').get('initial_holdtime')), 'max_holdtime': int(dest.get('ospf').get('throttle').get('max_holdtime')) } self.addLink(routers[src.get('name')], routers[dest.get('name')], intfName1=src_intfName, intfName2=dest_intfName, params1=src_params, params2=dest_params) # configure destinations link for d in hosts_link: host = d.get('host') router = d.get('router') routerip = router.get('ip') host_obj = self.addHost(host.get('name'), ip=str(host.get('ip')), defaultRoute='via ' + str(routerip.split('/')[0])) # host_intfname = host.get('intf') router_intfname = router.get('intf') host_params = { 'ip': str(host.get('ip')), 'cost': 1000, 'bw': int(d.get('bw')), 'prefixLen': int(host.get('ip').split('/')[1]) } router_params = { 'ip': str(router.get('ip')), 'cost': 1000, 'bw': int(d.get('bw')), 'prefixLen': int(router.get('ip').split('/')[1]), 'Host': True } self.addLink(host_obj, routers[router.get('name')], intfName1=host_intfname, intfName2=router_intfname, params1=host_params, params2=router_params) # Get controller configurations controller_o_conf = fibbing_ctrl.get('controller-config').get('ospf') th_initial_holdtime = controller_o_conf.get('throttle').get( 'initial_holdtime') th_delay = controller_o_conf.get('throttle').get('delay') th_max_holdtime = controller_o_conf.get('throttle').get('max_holdtime') min_ls_arrival = controller_o_conf.get('lsa').get('min_ls_arrival') min_ls_interval = controller_o_conf.get('lsa').get('min_ls_interval') hello = controller_o_conf.get('hello-interval') dead = controller_o_conf.get('dead-interval') area = controller_o_conf.get('area') defaults = { CFG_KEY: { 'base_net': base_net, 'controller_prefixlen': 24, 'debug': int(_lib.DEBUG_FLAG), 'private_net': private_net, 'draw_graph': 0, 'private_ips': 'private_ip_binding.json', 'area': str(area), 'hello_interval': str(hello), 'dead_interval': str(dead), 'min_ls_arrival': int(min_ls_arrival), 'min_ls_interval': int(min_ls_interval), 'delay': int(th_delay), 'initial_holdtime': int(th_initial_holdtime), 'max_holdtime': int(th_max_holdtime) } } ctrl_map = {} for c_l in ctrl_links: router = c_l.get('router') controller = c_l.get('controller') if not ctrl_map.get(controller.get('name')): # configure the fibbing controllers CFG_path = '/tmp/%s.cfg' % controller.get('name') ctrl = self.addController(controller.get('name'), cfg_path=None, **defaults) ctrl_map[controller.get('name')] = ctrl ctrl_ip = controller.get('ip') rc = routers[router.get('name')] ctrl_intfname = controller.get('intf') rc_intfname = router.get('intf') ctrl_params = {'bw': int(c_l.get('bw')), 'ip': str(ctrl_ip)} rc_params = { 'bw': int(c_l.get('bw')), 'ip': str(router.get('ip')), 'area': str(area), 'hello-interval': str(hello), 'dead-interval': str(dead), 'min_ls_arrival': int(min_ls_arrival), 'min_ls_interval': int(min_ls_interval), 'delay': int(th_delay), 'initial_holdtime': int(th_initial_holdtime), 'max_holdtime': int(th_max_holdtime) } # default cost=100000 ctrl = ctrl_map[controller.get('name')] self.addLink(ctrl, rc, cost=10000, intfName1=ctrl_intfname, intfName2=rc_intfname, params1=ctrl_params, params2=rc_params)
def checkExist_controllerlink(controller_link, Error): try: links = controller_link.get('links') if not links: LOG.error('NO fibbing controller configured') Error = True return Error for cont in links: if not cont.get('controller').get('ip'): LOG.error('NO fibbing controller ip configured') Error = True if not cont.get('controller').get('name'): LOG.error('NO fibbing controller name configured') Error = True if not cont.get('router').get('ip'): LOG.error('NO fibbing controller connected router configured') Error = True if not cont.get('router').get('name'): LOG.error( 'NO fibbing controller connected router name configured') Error = True return Error except KeyError: LOG.error('checkExist_controllerlink :' + 'KeyError') Error = True return Error
def check_network(config, Error): try: fibbing_ctrl = config.get('fibbing-controller') hosts_link = config.get('hosts-link') links = config.get('links') main_controller = config.get('main-controller') ospf_links = config.get('ospf-links') routers = config.get('routers') routerid = [] ospf_router = [] for r in routers: if r.get('ospf').get('enable'): if r.get('ospf').get('router-id') in routerid: LOG.error('Router id already used %s' % r.get('ospf').get('router-id')) Error = True else: routerid.append(r.get('ospf').get('router-id')) else: LOG.warning( 'For this framework all routers must have ospf enable') ospf_router.append(r.get('name')) link_key_map = {} for link in links: if not link.get('src').get('name'): LOG.error('A link must have a src router name') Error = True if not link.get('src').get('ip'): LOG.error('A link must have a src router ip') Error = True if not link.get('dest').get('name'): LOG.error('A link must have a dest router name') Error = True if not link.get('dest').get('ip'): LOG.error('A link must have a dest router ip') Error = True link_key_map[link.get('name')] = link ospf_config = {} for o_l in ospf_links: link = link_key_map.get(o_l.get('name')) if link.get('src').get('name') not in ospf_router or \ link.get('dest').get('name') not in ospf_router: LOG.error( 'A link with ospf configured must have both src and dest with ospf enabled' ) Error = True src_o_conf = o_l.get('src').get('ospf') dest_o_conf = o_l.get('dest').get('ospf') if src_o_conf.get('area') not in ospf_config: ospf_config[src_o_conf.get('area')] = src_o_conf else: area_conf = ospf_config[src_o_conf.get('area')] if src_o_conf.get('hello-interval') != area_conf.get('hello-interval') or\ src_o_conf.get('dead-interval') != area_conf.get('dead-interval') : LOG.error( 'Hello and dead interval must be the same for the same broadcast domain' ) Error = True if dest_o_conf.get('area') not in ospf_config: ospf_config[dest_o_conf.get('area')] = dest_o_conf else: area_conf = ospf_config[dest_o_conf.get('area')] if dest_o_conf.get('hello-interval') != area_conf.get('hello-interval') or\ dest_o_conf.get('dead-interval') != area_conf.get('dead-interval') : LOG.error( 'Hello and dead interval must be the same for the same broadcast domain' ) Error = True controller_o_conf = fibbing_ctrl.get('controller-config').get('ospf') if controller_o_conf.get('area') not in ospf_config: LOG.error( 'The Fibbing controller should be in the same area of at least some other router' ) Error = True else: area_conf = ospf_config[controller_o_conf.get('area')] if controller_o_conf.get('hello-interval') != area_conf.get('hello-interval') or\ controller_o_conf.get('dead-interval') != area_conf.get('dead-interval') : LOG.error( 'Hello and dead interval must be the same for the same broadcast domain' ) Error = True if not main_controller: LOG.error( 'The host acting as the main controller must be specified') Error = True return Error except Exception as e: LOG.critical('Error :' + str(e)) Error = True return Error
def call_jump(track, ev, ptr): jumps = {0xC4: Call, 0xC8: Jump} evtype = jumps[ev] mode = BmsSeekMode(ptr.u8()) addr = ptr.u24() track.insert(evtype, mode=mode, addr=addr) # Assert that we aren't jumping into the middle of an instruction. hist = ptr.hist(addr) if hist == Visit.MIDDLE: raise OverlapError('%s %s - middle of command' % (jumps[ev], hex(addr))) # We are either visiting NONE or BEGIN. # Jump: Visit target (if necessary), then continue. # Call # Not visited: # Visit target. # Visited: # (addr) Check preconditions and apply postconditions. # Note that OldNote compares == None. # HISTORY_MODE == 'LAZY' # **** CALL **** if hist == Visit.NONE: track = BmsTrack(track._file, addr, None, track.note_history).parse() else: assert hist == Visit.BEGIN # **** ASSERTION **** # We will encounter issues if any touched notes differ from the original call. # TODO: We assume we're not calling into the middle of a visited section... :'( track = track._file.track_at[addr] different = (track.pre_history != track.note_history) if any(different & track.touched): LOG.error( '''Invalid call from %06X to %06X new:%s old:%s out:%s touched:%s''', track._prev_addr, addr, track.note_history, track.pre_history, track.note_history, track.touched) # endif already visited # BMS really shouldn't be touching notes, AND leaving running notes untouched... if any(track.touched): untouched = ~track.touched if any(track.pre_history.astype(bool) & untouched): LOG.warning('Function leaves running notes untouched %s %s %s', track.touched, track.pre_history, track.note_history) # Knowing that all "touched" entries entered identically... # We must apply all "touched" entries of the note history. track.note_history[track.touched] = track.note_history[track.touched] # **** JUMP **** if hist == Visit.NONE: track._ptr.addr = addr else: assert hist == Visit.BEGIN
async def _download(self): try: reader, writer = await asyncio.wait_for(asyncio.open_connection( self.host, self.port), timeout=10) except ConnectionError: LOG.error('Failed to connect to Peer {}'.format(self)) return LOG.info('{} Sending handshake'.format(self)) writer.write(self.handshake()) await writer.drain() # TODO: Validate handshake handshake = await reader.read( 68) # Suspends here if there's nothing to be read await self.send_interested(writer) # TODO: use async iterator buf = b'' while True: resp = await reader.read( REQUEST_SIZE) # Suspends here if there's nothing to be read # LOG.info('{} Read from peer: {}'.format(self, resp[:8])) buf += resp #LOG.info('Buffer len({}) is {}'.format(len(buf), buf[:8])) if not buf and not resp: return while True: if len(buf) < 4: # LOG.info('Buffer is too short') break length = struct.unpack('>I', buf[0:4])[0] if not len(buf) >= length: break def consume(buf): buf = buf[4 + length:] return buf def get_data(buf): return buf[:4 + length] if length == 0: LOG.info('[Message] Keep Alive') buf = consume(buf) data = get_data(buf) LOG.info('[DATA]', data) continue if len(buf) < 5: LOG.info('Buffer is less than 5... breaking') break msg_id = struct.unpack('>b', buf[4:5])[0] # 5th byte is the ID if msg_id == 0: LOG.info('[Message] CHOKE') data = get_data(buf) buf = consume(buf) LOG.info('[DATA]', data) elif msg_id == 1: data = get_data(buf) buf = consume(buf) LOG.info('[Message] UNCHOKE') self.peer_choke = False elif msg_id == 2: data = get_data(buf) buf = consume(buf) LOG.info('[Message] Interested') pass elif msg_id == 3: data = get_data(buf) buf = consume(buf) LOG.info('[Message] Not Interested') pass elif msg_id == 4: buf = buf[5:] data = get_data(buf) buf = consume(buf) LOG.info('[Message] Have') pass elif msg_id == 5: bitfield = buf[5:5 + length - 1] self.have_pieces = bitstring.BitArray(bitfield) LOG.info('[Message] Bitfield: {}'.format(bitfield)) # buf = buf[5 + length - 1:] buf = buf[4 + length:] await self.send_interested(writer) elif msg_id == 7: self.inflight_requests -= 1 data = get_data(buf) buf = consume(buf) l = struct.unpack('>I', data[:4])[0] try: parts = struct.unpack('>IbII' + str(l - 9) + 's', data[:length + 4]) piece_idx, begin, data = parts[2], parts[3], parts[4] self.torrent_session.on_block_received( piece_idx, begin, data) # LOG.info('Got piece idx {} begin {}'.format(piece, begin)) except struct.error: LOG.info('error decoding piece') return None # piece_index = buf[5] # piece_begin = buf[6] # block = buf[13: 13 + length] # # buf = buf[13 + length:] # buf = buf[4 + length:] # LOG.info('Buffer is reduced to {}'.format(buf)) # LOG.info('Got piece idx {} begin {}'.format(piece_index, piece_begin)) # LOG.info('Block has len {}'.format(len(block))) # LOG.info('Got this piece: {}'.format(block)) # TODO: delegate to torrent session # with open(self.torrent_session.torrent.info[b'info'][b'name'].decode(), 'wb') as f: # f.write(block) # continue else: LOG.info('unknown ID {}'.format(msg_id)) if msg_id == 159: exit(1) await self.request_a_piece(writer)