def _process_message(msgid, uptime, payload): logging.debug('msgid = %s, uptime = %s, payload = %s' % (msgid, uptime, payload)) if msgid == SYSLOG_MSG_ID_CACHE_DEL: cached_eids = db.get('ncp_eid_cache') try: cached_eids.remove(payload) db.set('ncp_eid_cache', cached_eids) except: pass # It didn't exist in the list logging.info('Address %s is not cached anymore.' % payload) elif msgid == SYSLOG_MSG_ID_CACHE_ADD: cached_eids = db.get('ncp_eid_cache') cached_eids.append(payload) db.set('ncp_eid_cache', cached_eids) logging.info('Address %s is now cached.' % payload) elif msgid == SYSLOG_MSG_ID_ALOC_DEL: NETWORK.handle_addr(payload, 'del') elif msgid == SYSLOG_MSG_ID_ALOC_ADD: NETWORK.handle_addr(payload, 'add') elif msgid == SYSLOG_MSG_ID_UNICAST_SYS_ADD: NETWORK.handle_addr(payload, 'add') elif msgid == SYSLOG_MSG_ID_AOPD_SAVED: _parse_active_dataset(payload) logging.info('Active dataset changed.') elif msgid == SYSLOG_MSG_ID_JOIN_STATUS_OK: db.set('ncp_status', 'joined') logging.info('Device just joined to the Thread network') elif msgid == SYSLOG_MSG_ID_JOIN_STATUS_ERR: # TODO: notify user logging.info('Device could not join to the Thread network')
def set_ext_iface(): '''Select the right external interface''' if not db.get('exterior_ifname'): links = IPR.get_links() for link in links: # Don't choose the loopback interface if link['flags'] & IFF_LOOPBACK: continue # Must be up if not link['flags'] & IFF_UP: continue # Must have multicast enabled if not link['flags'] & IFF_MULTICAST: continue # Don't choose the Kirale's Thread device if link.get_attr('IFLA_ADDRESS').startswith('84:04:d2'): continue # First interface matching all criteria is selected db.set('exterior_ifname', link.get_attr('IFLA_IFNAME')) break # No appropiate interface was found if not db.get('exterior_ifname'): raise Exception('No exterior interface available.') # Set exterior index idx = IPR.link_lookup(ifname=db.get('exterior_ifname'))[0] db.set('exterior_ifnumber', idx) # Set exterior MAC db.set('exterior_mac', IPR.get_links(idx)[0].get_attr('IFLA_ADDRESS'))
def _ifdown(): ifname = db.get('interior_ifname') # Remove custom routing table db.del_from_file( '/etc/iproute2/rt_tables', '\n%s\t%s\n' % (BR_TABLE_NR, db.get('bridging_table')), '', ) # Don't continue if the interface is already down idx = IPR.link_lookup(ifname=ifname, operstate='UP') if not idx: return # Delete traffic limits bash('tc qdisc del dev %s root handle 1: cbq avpkt 1000 bandwidth 12mbit' % ifname) # Delete custom rule IPR.rule( 'delete', family=socket.AF_INET6, table=BR_TABLE_NR, priority=100, fwmark=int(db.get('bridging_mark')), ) # Bring interior interface down logging.info('Bringing %s interface down.', ifname) try: IPR.link('set', index=db.get('interior_ifnumber'), state='down') except: logging.error('Exception bringing %s interface down.', ifname)
async def render_post(self, request): # Incoming TLVs parsing logging.info('in %s qry: %s' % (URI.A_AQ, ThreadTLV.sub_tlvs_str(request.payload))) # Message not handled by Secondary BBR if not 'primary' in db.get('bbr_status'): return COAP_NO_RESPONSE # Find sub TLVs dua = None value = ThreadTLV.get_value(request.payload, TLV.A_TARGET_EID) if value: dua = ipaddress.IPv6Address(bytes(value)) if not dua: return COAP_NO_RESPONSE # Don't process requests for different prefixes than DUA dua_prefix = ipaddress.IPv6Address(db.get('prefix').split('/')[0]) if dua.packed[:8] != dua_prefix.packed[:8]: return COAP_NO_RESPONSE # Obtain the RLOC16 from the source's RLOC rloc16 = ipaddress.IPv6Address(request.remote.sockaddr[0]).packed[-2:] # TODO: mantain a cache # Propagate Address Query to the Backbone await DUA_HNDLR.send_bb_query(DUA_HNDLR.coap_client, dua, rloc16) return COAP_NO_RESPONSE
def dongle_conf(): '''Configure several network parameters''' # By Kirale convention, interior MAC address is obtained from the dongle # serial serial = db.get('dongle_serial').split('+')[-1] interior_mac = ':'.join([ serial[0:2], serial[2:4], serial[4:6], serial[10:12], serial[12:14], serial[14:16] ]) db.set('interior_mac', interior_mac) # Also dongle MAC is related to interior MAC dongle_mac = bytearray.fromhex(interior_mac.replace(':', '')) dongle_mac[0] |= 0x02 db.set('dongle_mac', ':'.join(['%02x' % byte for byte in dongle_mac])) # Find the device with the configured MAC address links = IPR.get_links(IFLA_ADDRESS=db.get('interior_mac').lower()) if links: db.set('interior_ifname', links[0].get_attr('IFLA_IFNAME')) db.set('interior_ifnumber', links[0]['index']) else: raise Exception('Error: Device not found with MAC ' + db.get('interior_mac')) # Use last 32 bits of interior MAC as bridging mark db.set('bridging_mark', int(db.get('interior_mac').replace(':', '')[-8:], 16)) db.set('bridging_table', db.get('interior_mac'))
def bbr_dataset_update(): ''' Update Thread BBR Service Data Automatically increases the sequence number ''' # Increase sequence number bbr_sequence_number = (db.get('bbr_seq') + 1) % 0xFF # Build s_server_data reregistration_delay = db.get('rereg_delay') mlr_timeout = db.get('mlr_timeout') s_server_data = struct.pack( DEFS.THREAD_SERVICE_DATA_FMT, bbr_sequence_number, reregistration_delay, mlr_timeout, ) # Store used values db.set('bbr_seq', bbr_sequence_number) # Enable BBR send_cmd('config service add %u %s %s' % ( DEFS.THREAD_ENTERPRISE_NUMBER, DEFS.THREAD_SERVICE_DATA_BBR, bytes(s_server_data).hex(), )) logging.info('BBR update: Seq. = %d MLR Timeout = %d, Rereg. Delay = %d' % (bbr_sequence_number, mlr_timeout, reregistration_delay))
def start(): global HTTPD, ANNOUNCER, LOOP LOOP = asyncio.get_event_loop() print('Loading web server...') while not HTTPD: # The port may have not been closed from the previous session # TODO: properly close server when stopping app try: HTTPD = V6Server(('', WEB_PORT), WebServer) except OSError: time.sleep(1) LOOP.run_in_executor(None, HTTPD.serve_forever) print('Webserver is up') if kibra.__harness__: props = { 'ven': db.get('kibra_vendor'), 'mod': db.get('kibra_model'), 'ver': db.get('kibra_version'), } # Announce via Harness Discovery Protocol props['add'] = db.get('exterior_ipv6_ll') props['por'] = WEB_PORT ANNOUNCER = HDP_Announcer() LOOP.run_in_executor(None, ANNOUNCER.start, props) print('BBR announced via HDP')
def run_daemon(self): while self.ndp_on: # Wait for some multicast traffic to arrive try: data, src = self.icmp6_sock.recvfrom(1280) except: # socket.timeout: timed out time.sleep(0.2) # Accepting Neighbor solicit only if data[0] != ND_NEIGHBOR_SOLICIT: continue # Get the paramters _, _, _, _, tgt = struct.unpack(NS_FMT, data[: struct.calcsize(NS_FMT)]) # Debug ns_tgt = ipaddress.IPv6Address(tgt).compressed logging.info('in ns from %s for %s' % (src[0], ns_tgt)) # Generate Neighbor Advertisement if ns_tgt in db.get('exterior_addrs'): self.send_na(src[0], ns_tgt) elif ns_tgt in list(self.duas.keys()): delayed = not ns_tgt in db.get('ncp_eid_cache') self.send_na(src[0], ns_tgt, delayed=delayed)
async def render_post(self, request): # Incoming TLVs parsing logging.info('in %s ntf: %s' % (URI.A_AE, ThreadTLV.sub_tlvs_str(request.payload))) # Message not handled by Secondary BBR if not 'primary' in db.get('bbr_status'): return COAP_NO_RESPONSE # Find sub TLVs dua = None eid = None value = ThreadTLV.get_value(request.payload, TLV.A_TARGET_EID) if value: dua = ipaddress.IPv6Address(bytes(value)) value = ThreadTLV.get_value(request.payload, TLV.A_ML_EID) if value: eid = value.hex() if not dua or not eid: return COAP_NO_RESPONSE # Don't process notifications for different prefixes than DUA dua_prefix = ipaddress.IPv6Address(db.get('prefix').split('/')[0]) if dua.packed[:8] != dua_prefix.packed[:8]: return COAP_NO_RESPONSE # Remove entry if it's registered with different EID entry_eid, _, dad = DUA_HNDLR.find_eid(dua.compressed) if not dad and entry_eid != eid: DUA_HNDLR.remove_entry(dua=dua) return COAP_NO_RESPONSE
async def render_post(self, request): # Incoming TLVs parsing logging.info('in %s ans: %s' % (URI.B_BA, ThreadTLV.sub_tlvs_str(request.payload))) # Message not handled by Secondary BBR if not 'primary' in db.get('bbr_status'): return COAP_NO_RESPONSE # TODO: 9.4.8.2.9 Caching DUAs Advertised on the Backbone Link # Check if all required TLVs are present dua, eid, rloc16, elapsed, net_name = _get_b_ba_params(request.payload) if None in (dua, eid, elapsed, net_name): return COAP_NO_RESPONSE logging.info( 'BB.ans: DUA=%s, ML-EID=%s, Time=%d, Net Name=%s, RLOC16=%s' % (dua, eid, elapsed, net_name, rloc16)) # See if we have this DUA in our table src_rloc, entry_eid, _, dad = DUA_HNDLR.find_eid(dua) # 9.4.8.2.8 Receipt of Backbone Answer BB.ans if not rloc16: if not entry_eid: # Nothing to do for this EID return COAP_NO_RESPONSE elif dad is True: if entry_eid == eid: # This DUA is still registered somewhere else, inform others DUA_HNDLR.duplicated_found(dua, delete=False) # Send PRO_BB.ntf asyncio.ensure_future(DUA_HNDLR.send_pro_bb_ntf(dua)) else: # Duplication detected during DAD DUA_HNDLR.duplicated_found(dua, delete=True) # Send ADDR_ERR.ntf asyncio.ensure_future( DUA_HNDLR.send_addr_err(src_rloc, aiocoap.CON, dua, eid)) else: # Send ADDR_NTF.ans bbr_rloc16 = ipaddress.IPv6Address(db.get('ncp_rloc')).packed[-2:] # If this BBR NCP originated the addr_qry, send addr_ntf to its # link local address if rloc16 == bbr_rloc16: dst = db.get('ncp_ll') else: dst = THREAD.get_rloc_from_short(db.get('ncp_prefix'), rloc16) asyncio.ensure_future( DUA_HNDLR.send_addr_ntf_ans(dst, dua, eid=eid, rloc16=bbr_rloc16, elapsed=elapsed)) # ACK return aiocoap.Message(mtype=Type.ACK, code=Code.CHANGED)
async def render_post(self, request): req_dua = None status = DMStatus.ST_UNSPEC # Incoming TLVs parsing logging.info('in %s req: %s' % (URI.N_DR, ThreadTLV.sub_tlvs_str(request.payload))) # BBR Primary/Secondary status if 'primary' not in db.get('bbr_status'): status = DMStatus.ST_NOT_PRI elif len(DUA_HNDLR.entries) >= DUA_LIMIT: status = DMStatus.ST_RES_SHRT else: dua = None eid = None elapsed = 0 # ML-EID TLV value = ThreadTLV.get_value(request.payload, TLV.A_ML_EID) if value: eid = value.hex() # Target EID TLV value = ThreadTLV.get_value(request.payload, TLV.A_TARGET_EID) if value: try: req_dua = bytes(value) dua = ipaddress.IPv6Address(req_dua).compressed except: status = DMStatus.ST_INV_ADDR # Time Since Last Transaction TLV value = ThreadTLV.get_value(request.payload, TLV.A_TIME_SINCE_LAST_TRANSACTION) if value: elapsed = struct.unpack('!I', value)[0] if eid and dua: # Thread Harness may force response status if db.get('dua_next_status'): status = int(db.get('dua_next_status')) db.set('dua_next_status', '') elif DUA_HNDLR.reg_update(eid, dua, elapsed): status = DMStatus.ST_SUCESS else: # Duplication detected (resource shortage not contemplated) status = DMStatus.ST_DUP_ADDR # Fill and return the response payload = ThreadTLV(t=TLV.A_STATUS, l=1, v=[status]).array() if req_dua: payload += ThreadTLV(t=TLV.A_TARGET_EID, l=16, v=req_dua).array() logging.info( 'out %s rsp: %s' % (URI.N_DR, ThreadTLV.sub_tlvs_str(payload))) return aiocoap.Message(code=Code.CHANGED, payload=payload)
async def periodic(self): try: interior_link_up = IPR.link_lookup( ifname=db.get('interior_ifname'), operstate='UP') except: interior_link_up = False if not interior_link_up: logging.error('Interface %s went down.', db.get('interior_ifname')) self.kstop() self.kill()
def kstart(self): ll_addr = ipaddress.IPv6Address(db.get('dongle_ll')).compressed self.br_permanent_addr = '%s%%%s' % (ll_addr, db.get('interior_ifname')) DIAGS_DB['nodes'] = [] # Delete old values to prevent MDNS from using them before obtaning # the updated ones db.delete('dongle_xpanid') db.delete('dongle_netname') db.set('bbr_status', 'off')
async def send_bb_query(self, client, dua, rloc16=None): dua_bytes = ipaddress.IPv6Address(dua).packed payload = ThreadTLV(t=TLV.A_TARGET_EID, l=16, v=dua_bytes).array() if rloc16: payload += ThreadTLV(t=TLV.A_RLOC16, l=2, v=rloc16).array() dst = '%s%%%s' % (db.get('all_domain_bbrs'), db.get('exterior_ifname')) logging.info( 'out %s qry: %s' % (URI.B_BQ, ThreadTLV.sub_tlvs_str(payload))) await client.non_request(dst, DEFS.PORT_BB, URI.B_BQ, payload)
def run_daemon(self): while self.mcr_on: # Wait for some multicast traffic to arrive try: data = self.mc6r_sock.recv(1280) except: # socket.timeout: timed out time.sleep(0.2) if not 'primary' in db.get('bbr_status'): continue # Signal must start with zero if data[0] != 0: continue # Get the upcall paramters _, type_, in_mif, _, src, dst = struct.unpack( mrt6msg_fmt, data[:struct.calcsize(mrt6msg_fmt)]) # Debug src_addr = ipaddress.IPv6Address(src).compressed dst_addr = ipaddress.IPv6Address(dst).compressed logging.debug('Upcall: type=%d mif=%d src=%s dst=%s' % (type_, in_mif, src_addr, dst_addr)) if type_ != MRT6MSG_NOCACHE: continue # Packet from Backbone Network (9.4.7.3) if in_mif == EXT_MIF: # Filter by registered multicast groups if not db.get('mlr_cache'): continue maddrs = list(db.get('mlr_cache').keys()) if str(dst_addr) not in maddrs: continue out_mif = INT_MIF # Packet from Thread Network (9.4.7.4) elif in_mif == INT_MIF: # Rules 1 and 3 handled by KiNOS # Filter by forwarding flags dst_scope = dst[1] & 0x0F if dst_scope < 4: continue if db.get('mcast_out_fwd') == 0: continue if dst_scope == 4 and db.get('mcast_admin_fwd') == 0: continue out_mif = EXT_MIF else: continue self.add_route(MCRoute(src, dst, in_mif, out_mif))
def _nat_enable(): bash('/sbin/modprobe jool') if 'default' not in str(bash('jool instance display')): bash('jool instance add --netfilter --pool6 64:ff9b::/96') bash('jool global update logging-session true') bash('jool global update logging-bib true') logging.info('Prefix 64:ff9b::/96 added to NAT64 engine.') bash('jool pool4 add --udp %s' % db.get('exterior_ipv4')) bash('jool pool4 add --icmp %s' % db.get('exterior_ipv4')) logging.info('%s used as stateful NAT64 masking address.', db.get('exterior_ipv4'))
def service_update(self): r_txt = '\t\t<txt-record>%s=%s</txt-record>' r_bin = '\t\t<txt-record value-format="binary-hex">%s=%s</txt-record>' try: records = get_records() hostname = socket.gethostname() except: logging.warning('Unable to get the mDNS records.') return # Compose the new service data snw = [] snw.append('<?xml version="1.0" encoding="utf-8" standalone="no"?>') snw.append('<!DOCTYPE service-group SYSTEM "avahi-service.dtd">') snw.append('<service-group>') snw.append('\t<name>%s %s %s</name>' % (db.get('dongle_name'), records['vn'], records['mn'])) snw.append('\t<service>') snw.append('\t\t<type>_meshcop._udp</type>') snw.append('\t\t<host-name>%s.local</host-name>' % hostname) snw.append('\t\t<port>%d</port>' % db.get('exterior_port_mc')) snw.append(r_txt % ('rv', '1')) snw.append(r_txt % ('tv', '1.2.0')) snw.append(r_bin % ('sb', records['sb'])) snw.append(r_txt % ('vn', records['vn'])) snw.append(r_txt % ('mn', records['mn'])) if 'nn' in records.keys(): snw.append(r_txt % ('nn', records['nn'])) if 'xp' in records.keys(): snw.append(r_bin % ('xp', records['xp'])) if 'sq' in records.keys(): snw.append(r_bin % ('sq', records['sq'])) if 'bb' in records.keys(): snw.append(r_bin % ('bb', records['bb'])) snw.append('\t</service>') snw.append('</service-group>\n') snw = '\n'.join(snw) # Load the previous service file, or create it pathlib.Path(MDNS_SERVICES).mkdir(parents=True, exist_ok=True) service_file = '%s/%s.service' % (MDNS_SERVICES, db.get('dongle_name')) file_name = pathlib.Path(service_file) file_name.touch(exist_ok=True) with open(str(service_file), 'r') as file_: sod = file_.read() # Only restart service if something changed if snw != sod: with open(str(file_name), 'w') as file_: file_.write(snw) bash('service avahi-daemon reload') logging.info('mDNS service updated.')
async def periodic(self): # Detect if serial was disconnected try: SERIAL_DEV.is_active() except IOError: logging.error('Device %s has been disconnected.', db.get('serial_device')) self.kstop() self.kill() except Exception: logging.error('Device %s is not responding.', db.get('serial_device')) return # Don't continue if device is not joined if db.get('ncp_status') != 'joined' or db.get( 'status_serial') != 'running': return if not db.get('prefix_active'): slaac, dhcp, dp = _get_prefix_flags() # Don't continue if servers are not running if dhcp and db.get('status_dhcp') not in 'running': return if dp and db.get('status_coapserver') not in 'running': return # Enable border agent _bagent_on() # Add route NETWORK.ncp_route_enable(db.get('prefix')) # Announce prefix to the network prefix_handle( 'prefix', 'add', db.get('prefix'), stable=True, on_mesh=True, default=True, slaac=slaac, dhcp=dhcp, dp=dp, ) # Start as Secondary (KiNOS will notify the change to Primary) db.set('bbr_status', 'secondary') logging.info('This BBR is now Secondary.') # Announce service bbr_dataset_update() # Mark prefix as active db.set('prefix_active', 1)
def handle_diag(action): '''handle_diag('I') -> Insert the rules diagNetfilter('D') -> Delete the rules''' if action is 'I': logging.info('Redirecting MM port traffic to interior interface.') elif action is 'D': logging.info('Deleting ip6tables diagnostics rules.') else: return bash( 'ip6tables -w -t mangle -%s OUTPUT -o lo -d %s -p udp --dport %s -j MARK --set-mark "%s"' % (action, db.get('dongle_rloc'), DEFS.PORT_MM, db.get('bridging_mark')))
def _get_prefix_flags(): slaac = True if db.get('prefix_slaac') else False dhcp = True if db.get('prefix_dhcp') else False dp = True if db.get('prefix_dua') else False # Force SLAAC if no other flags are set if not dp and not dhcp: slaac = True # DHCP overrides SLAAC if dhcp: slaac = False return slaac, dhcp, dp
def dhcp_server_stop(): # Don't stop if DHCP is not to be used if not db.get('prefix_dhcp'): return # Stop DHCP daemon bash(DHCP_DAEMON + ' stop') # Remove previous configuration for this NCP db.del_from_file(DHCP_CONFIG, '\niface %s' % db.get('interior_ifname'), '\n}\n') # Allow for the file to be stored time.sleep(0.2) # Start DHCP daemon bash(DHCP_DAEMON + ' start')
def __init__(self): # List of PBBR DUAs with finished DAD self.duas = {} try: # Create and init the ICMPv6 socket self.icmp6_sock = socket.socket(socket.AF_INET6, socket.SOCK_RAW, IPPROTO_ICMPV6) # Bind to exterior interface only self.icmp6_sock.setsockopt(SOL_SOCKET, SO_BINDTODEVICE, db.get('exterior_ifname').encode()) # Receive Neighbor Solicitation messages in this socket icmp6_filter = bytearray(32) # 256 bit flags icmp6_filter = icmp6_filter_setpass(icmp6_filter, ND_NEIGHBOR_SOLICIT) self.icmp6_sock.setsockopt(IPPROTO_ICMPV6, ICMP6_FILTER, icmp6_filter) # Set the outgoing hop limit self.icmp6_sock.setsockopt(IPPROTO_IPV6, IPV6_UNICAST_HOPS, 255) self.icmp6_sock.setsockopt(IPPROTO_IPV6, IPV6_MULTICAST_HOPS, 255) # Run the daemon self.ndp_on = True #asyncio.ensure_future(self.run_daemon()) asyncio.get_event_loop().run_in_executor(None, self.run_daemon) except: logging.error('Unable to create the ND Proxy socket.')
def run_daemon(self): ext_ifname = db.get('exterior_ifname') while self.ndp_on: # Wait for some multicast traffic to arrive data, src = self.icmp6_sock.recvfrom(1280) #print('%s | %d: %s' % (src[0], len(data), data.hex())) # Accepting Neighbor solicit only if data[0] != ND_NEIGHBOR_SOLICIT: continue # Get the paramters _, _, _, _, tgt = struct.unpack(NS_FMT, data[:struct.calcsize(NS_FMT)]) # Debug ns_tgt = ipaddress.IPv6Address(tgt).compressed logging.info('in ns from %s for %s' % (src[0], ns_tgt)) # Generate Neighbor Advertisement try: EXT_IPV6_ADDRS = NETWORK.get_addrs(ext_ifname, socket.AF_INET6) except: # pyroute2.netlink.exceptions.NetlinkError: # (16, 'Device or resource busy') pass addrs = list(self.duas.keys()) + EXT_IPV6_ADDRS if ns_tgt in addrs: self.send_na(src[0], ns_tgt)
def kstart(self): logging.info('Configuring Avahi daemon.') ip4 = 'yes' if db.has_keys(['exterior_ipv4']) else 'no' ip6 = 'yes' if db.has_keys(['exterior_ipv6_ll']) else 'no' with open(MDNS_CONFIG, 'w') as file_: lines = [] lines.append('[server]') lines.append('use-ipv4=%s' % ip4) lines.append('use-ipv6=%s' % ip6) lines.append('allow-interfaces=%s' % db.get('exterior_ifname')) lines.append('disallow-other-stacks=yes\n') lines.append('[publish]') lines.append('publish-addresses=yes') lines.append('publish-hinfo=no') lines.append('publish-workstation=no') lines.append('publish-domain=no') lines.append('publish-aaaa-on-ipv4=no') lines.append('publish-a-on-ipv6=no\n') lines.append('[rlimits]') lines.append('rlimit-core=0') lines.append('rlimit-data=4194304') lines.append('rlimit-fsize=0') lines.append('rlimit-nofile=30') lines.append('rlimit-stack=4194304') lines.append('rlimit-nproc=3') lines = '\n'.join(lines) file_.write(lines) # Enable service self.service_update()
async def render_post(self, request): # Incoming TLVs parsing logging.info('in %s ntf: %s' % (URI.B_BMR, ThreadTLV.sub_tlvs_str(request.payload))) # Primary BBR shouldn't receive this message if not 'secondary' in db.get('bbr_status'): return COAP_NO_RESPONSE ''' # IPv6 Addresses TLV addrs = [] value = ThreadTLV.get_value(request.payload, TLV.A_IPV6_ADDRESSES) if value: _, addrs, _ = Res_N_MR.parse_addrs(value) # Timeout TLV timeout = ThreadTLV.get_value(request.payload, TLV.A_TIMEOUT) # Register valid addresses if addrs and timeout: MCAST_HNDLR.reg_update(addrs, timeout) ''' # TODO: mantain a Backup Multicast Listeners Table return COAP_NO_RESPONSE
def _main(): global SERVER # Load database db.load() # Exterior network configuration global_netconfig() # Find connected dongle enable_ncp() # Start web interface webserver.start() # Start subtasks mdns = MDNS() TASKS.append(SERIAL()) TASKS.append(NETWORK()) TASKS.append(DHCP()) TASKS.append(NAT()) TASKS.append(DNS()) TASKS.append(MDNS()) TASKS.append(DIAGS()) TASKS.append(COAPSERVER()) # Launch mDNS already asyncio.ensure_future(mdns.run()) if db.get('autostart') == 1: db.set('action_kibra', 'start') asyncio.ensure_future(_master()) asyncio.get_event_loop().run_forever()
def _get_oobcom(brouter): try: if brouter.ksh_cmd('show status')[0] != 'joined': return None except: print('%s is busy' % brouter.port.port) return None oobcom = {} settings = brouter.ksh_cmd('show netconfig') for line in settings: if '| Channel' in line: oobcom['channel'] = line.split(':')[-1].strip() elif '| PAN ID' in line: oobcom['panid'] = line.split(':')[-1].strip() elif '| Extended PAN ID' in line: oobcom['xpanid'] = ''.join(line.split()[5:9]) elif '| Network Name' in line: oobcom['netname'] = '"%s"' % line.split(':')[1].strip() elif '| Mesh-Local ULA' in line: oobcom['mlprefix'] = line.split(' : ')[-1].split('/')[0] elif '| Active Timestamp' in line: oobcom['actstamp'] = line.split(':')[-1].strip() elif '| Master Key' in line: oobcom['mkey'] = line.split(':')[-1].strip() oobcom['commcred'] = '"%s"' % db.get('ncp_commcred') return oobcom
def clear_topology(): db.load() _, ncps = _get_devices(db.get('ncp_serial')) threads = [] for device in ncps: threads.append(Thread(target=_stop_topology, args=[device]))
def _handle_ipv4(action): ''' Block most of the exterior traffic _handle_ipv4('A') --> Add the rules _handle_ipv4('D') --> Delete the rules ''' if action == 'A': # This should not be needed if KiBRA was closed correctly bash('iptables -F -t mangle') exterior_ifname = db.get('exterior_ifname') bash('iptables -w -t filter -%s INPUT -i %s -p icmp -j ACCEPT' % (action, exterior_ifname)) bash( 'iptables -w -t filter -%s INPUT -i %s -p udp --dport mdns -j ACCEPT' % (action, exterior_ifname)) bash( 'iptables -w -t filter -%s INPUT -i %s -p udp --dport dhcpv6-client -j ACCEPT' % (action, exterior_ifname)) bash( 'iptables -w -t filter -%s INPUT -i %s -m state --state ESTABLISHED,RELATED -j ACCEPT' % (action, exterior_ifname)) bash('iptables -w -t filter -%s INPUT -i %s -j DROP' % (action, exterior_ifname))
async def periodic(self): MCAST_HNDLR.reg_periodic() # Keept track of RLOC changes current_ncp_rloc = db.get('ncp_rloc') if current_ncp_rloc != self.last_ncp_rloc: self._ncp_rloc_changed(self.last_ncp_rloc) self.last_ncp_rloc = current_ncp_rloc # Keep track of BBR status changes current_bbr_status = db.get('bbr_status') if current_bbr_status != self.last_bbr_status: if current_bbr_status == 'primary': self._launch_servers() self.last_bbr_status = current_bbr_status