def test_mac_address_generation(self): mac = create_mac_from_sid("IMSI00000000001") self.assertEqual(str(mac), "8A:00:00:00:00:01") mac = create_mac_from_sid("IMSI980000002918") self.assertEqual(str(mac), "8A:E4:2C:8D:53:66") mac = create_mac_from_sid("IMSI311980000002918") self.assertEqual(str(mac), "8A:E4:2C:8D:53:66") mac = create_mac_from_sid("IMSI02918") self.assertEqual(str(mac), "8A:00:00:00:0B:66")
def _process_dhcp_pkt(self, packet, state: DHCPState): mac_addr = create_mac_from_sid(packet[Ether].dst) mac_addr_key = mac_addr.as_redis_key() with self._dhcp_notify: if mac_addr_key in self.dhcp_client_state: ip_offered = packet[BOOTP].yiaddr subnet_mask = packet[DHCP].options[5][1] ip_subnet = IPv4Network(ip_offered + "/" + subnet_mask, strict=False) router_ip_addr = ip_address(packet[DHCP].options[7][1]) lease_time = packet[DHCP].options[2][1] dhcp_state = DHCPDescriptor(mac_addr, ip_offered, state, str(ip_subnet), packet[IP].src, router_ip_addr, lease_time, packet[BOOTP].xid) LOG.info("Record mac %s IP %s", mac_addr_key, dhcp_state) self.dhcp_client_state[mac_addr_key] = dhcp_state self.dhcp_gw_info.update_ip(router_ip_addr) self._dhcp_notify.notifyAll() if state == DHCPState.OFFER: # let other thread work on fulfilling IP allocation request. threading.Event().wait(self.THREAD_YIELD_TIME) self.send_dhcp_packet(mac_addr, DHCPState.REQUEST, dhcp_state) else: LOG.debug("Unknown MAC: %s " % packet.summary()) return
def _process_dhcp_pkt(self, packet, state: DHCPState): mac_addr = create_mac_from_sid(packet[Ether].dst) vlan = "" if Dot1Q in packet: vlan = str(packet[Dot1Q].vlan) mac_addr_key = mac_addr.as_redis_key(vlan) with self._dhcp_notify: if mac_addr_key in self.dhcp_client_state: state_requested = self.dhcp_client_state[ mac_addr_key].state_requested ip_offered = packet[BOOTP].yiaddr subnet_mask = self._get_option(packet, "subnet_mask") if subnet_mask is not None: ip_subnet = IPv4Network(ip_offered + "/" + subnet_mask, strict=False) else: ip_subnet = IPv4Network(ip_offered + "/" + "32", strict=False) dhcp_router_opt = self._get_option(packet, "router") if dhcp_router_opt is not None: router_ip_addr = ip_address(dhcp_router_opt) else: router_ip_addr = None lease_expiration_time = self._get_option(packet, "lease_time") dhcp_state = DHCPDescriptor( mac=mac_addr, ip=ip_offered, state=state, vlan=vlan, state_requested=state_requested, subnet=str(ip_subnet), server_ip=packet[IP].src, router_ip=router_ip_addr, lease_expiration_time=lease_expiration_time, xid=packet[BOOTP].xid) LOG.info("Record DHCP for: %s state: %s", mac_addr_key, dhcp_state) self.dhcp_client_state[mac_addr_key] = dhcp_state self.dhcp_gw_info.update_ip(router_ip_addr, vlan) self._dhcp_notify.notifyAll() if state == DHCPState.OFFER: # let other thread work on fulfilling IP allocation request. threading.Event().wait(self.THREAD_YIELD_TIME) self.send_dhcp_packet(mac_addr, vlan, DHCPState.REQUEST, dhcp_state) else: LOG.debug("Unknown MAC: %s " % packet.summary()) return
def test_ip_alloc(self): sid1 = "IMSI02917" ip1, _ = self._dhcp_allocator.alloc_ip_address(sid1) threading.Event().wait(2) dhcp_gw_info = self._dhcp_allocator._store.dhcp_gw_info dhcp_store = self._dhcp_allocator._store.dhcp_store self.assertEqual(str(dhcp_gw_info.get_gw_ip()), "192.168.128.211") self._dhcp_allocator.release_ip_address(sid1, ip1) # wait for DHCP release threading.Event().wait(7) mac1 = create_mac_from_sid(sid1) dhcp_state1 = dhcp_store.get(mac1.as_redis_key(None)) self.assertEqual(dhcp_state1, None) ip1_1, _ = self._dhcp_allocator.alloc_ip_address(sid1) threading.Event().wait(2) self.assertEqual(str(ip1), str(ip1_1)) self._dhcp_allocator.release_ip_address(sid1, ip1_1) threading.Event().wait(5) self.assertEqual(self._dhcp_allocator.list_added_ip_blocks(), []) ip1, _ = self._dhcp_allocator.alloc_ip_address("IMSI02918") self.assertEqual(str(ip1), "192.168.128.146") self.assertEqual( self._dhcp_allocator.list_added_ip_blocks(), [ip_network('192.168.128.0/24')], ) ip2, _ = self._dhcp_allocator.alloc_ip_address("IMSI029192") self.assertNotEqual(ip1, ip2) ip3, _ = self._dhcp_allocator.alloc_ip_address("IMSI0432") self.assertNotEqual(ip1, ip3) self.assertNotEqual(ip2, ip3) # release unallocated IP of SID ip_unallocated = IPDesc( ip=ip3, state=IPState.ALLOCATED, sid="IMSI033", ip_block=ip_network("1.1.1.0/24"), ip_type=IPType.DHCP, ) self._dhcp_allocator.ip_allocator.release_ip(ip_unallocated) self.assertEqual( self._dhcp_allocator.list_added_ip_blocks(), [ip_network('192.168.128.0/24')], ) sid4 = "IMSI54321" ip4, _ = self._dhcp_allocator.alloc_ip_address(sid4) threading.Event().wait(1) self._dhcp_allocator.release_ip_address(sid4, ip4) self.assertEqual( self._dhcp_allocator.list_added_ip_blocks(), [ip_network('192.168.128.0/24')], ) # wait for DHCP release threading.Event().wait(7) mac4 = create_mac_from_sid(sid4) dhcp_state = dhcp_store.get(mac4.as_redis_key(None)) self.assertEqual(dhcp_state, None) ip4_2, _ = self._dhcp_allocator.alloc_ip_address(sid4) self.assertEqual(ip4, ip4_2) try: self._dhcp_allocator.release_ip_address(sid1, ip1) self.assertEqual("should not", "reach here") except MappingNotFoundError: pass
def test_mac_to_hex(self): mac = create_mac_from_sid("12:34:56:78:90:12") self.assertEqual(mac.as_hex(), b'\x124Vx\x90\x12')
def test_mac_from_hex(self): mac = create_mac_from_sid("123456789012") self.assertEqual(str(mac), "12:34:56:78:90:12")
def test_ip_alloc(self): sid1 = "IMSI02917" ip1 = self._dhcp_allocator.alloc_ip_address(sid1) threading.Event().wait(2) gw_map = store.GatewayInfoMap() dhcp_gw_info = UplinkGatewayInfo(gw_map) dhcp_store = store.MacToIP() # mac => DHCP_State self.assertEqual(str(dhcp_gw_info.getIP()), "192.168.128.211") self._dhcp_allocator.release_ip_address(sid1, ip1) # wait for DHCP release threading.Event().wait(7) mac1 = create_mac_from_sid(sid1) dhcp_state1 = dhcp_store.get(mac1.as_redis_key()) self.assertEqual(dhcp_state1.state, DHCPState.RELEASE) ip1_1 = self._dhcp_allocator.alloc_ip_address(sid1) threading.Event().wait(2) self.assertEqual(str(ip1), str(ip1_1)) self._dhcp_allocator.release_ip_address(sid1, ip1_1) threading.Event().wait(5) self.assertEqual(self._dhcp_allocator.list_added_ip_blocks(), []) ip1 = self._dhcp_allocator.alloc_ip_address("IMSI02918") self.assertEqual(str(ip1), "192.168.128.146") self.assertEqual(self._dhcp_allocator.list_added_ip_blocks(), [ip_network('192.168.128.0/24')]) ip2 = self._dhcp_allocator.alloc_ip_address("IMSI029192") self.assertNotEqual(ip1, ip2) ip3 = self._dhcp_allocator.alloc_ip_address("IMSI0432") self.assertNotEqual(ip1, ip3) self.assertNotEqual(ip2, ip3) # release unallocated IP of SID self._dhcp_allocator.ip_allocator.release_ip("IMSI033", ip3, ip_network("1.1.1.0/24")) self.assertEqual(self._dhcp_allocator.list_added_ip_blocks(), [ip_network('192.168.128.0/24')]) sid4 = "IMSI54321" ip4 = self._dhcp_allocator.alloc_ip_address(sid4) threading.Event().wait(1) self._dhcp_allocator.release_ip_address(sid4, ip4) self.assertEqual(self._dhcp_allocator.list_added_ip_blocks(), [ip_network('192.168.128.0/24')]) # wait for DHCP release threading.Event().wait(7) mac4 = create_mac_from_sid(sid4) dhcp_state = dhcp_store.get(mac4.as_redis_key()) self.assertEqual(dhcp_state.state, DHCPState.RELEASE) ip4_2 = self._dhcp_allocator.alloc_ip_address(sid4) self.assertEqual(ip4, ip4_2) try: self._dhcp_allocator.release_ip_address(sid1, ip1) self.assertEqual("should not", "reach here") except MappingNotFoundError: pass