コード例 #1
0
class SimpleDhcp(Thread):

    def __init__(self, socket):
        Thread.__init__(self)
        self.sim = Simulation()
        self.dhcp_sock = socket
        self.arp_table = {}
        self.network_number = "192.168.1."
        self.arp_table[self.sim.get_gateway_recv_mac()] = self.sim.get_gateway_recv_ip()
        self.running = True

    def get_dhcp_sock(self):
        return self.dhcp_sock

    def find_available_ip_address(self):
        host_number = 2
        if len(self.arp_table.values()) != 0: 
            host_number = int(max(self.arp_table.values(), key = lambda x: int(x.split(".")[3])).split(".")[3]) + 1
        if len(self.arp_table.values()) == 254:
            return "0.0.0.0"
        return str(self.network_number) + str(host_number)     

    def get_arp_table(self):
        return self.arp_table

    def run(self):
        while self.running:
            print('\n\rWaiting to receive message...')
            # ascolto richieste di indirizzi ip
            data, address = self.dhcp_sock.recvfrom(1024)
            utils.print_pkt_size(data)
            pkt = pickle.loads(data)
            utils.print_packet_header(pkt, "IOT DEVICE")
            mac_address = pkt.get_source_mac()
            print("Received request for:",mac_address)
            if mac_address not in self.arp_table.keys():
                print("New device is requiring IP address")
                new_available_ip_address = self.find_available_ip_address()
                print("Device ", mac_address, " is granted of ", new_available_ip_address, " ip address")
                self.arp_table[mac_address] = new_available_ip_address
                
            
            self.dhcp_sock.sendto(pickle.dumps(Packet(
                self.sim.get_gateway_recv_mac(),
                pkt.get_source_mac(), 
                self.sim.get_gateway_recv_ip(),
                pkt.get_source_ip(),
                self.arp_table[pkt.get_source_mac()]
            )) , address)

    def stop_thread(self):
        self.running = False
コード例 #2
0
class Gateway:
    DHCP_PORT = 1075
    devices = {} # {ip_address: measurements}

    def __init__(self):
        self.sim = Simulation()

        self.rcv_sock = sk.socket(sk.AF_INET, sk.SOCK_DGRAM) # socket per invio delle misurazioni
        self.dhcp_sock = sk.socket(sk.AF_INET, sk.SOCK_DGRAM)

        self.dhcp_sock.bind(nc.dhcp_address)
        self.rcv_sock.bind(nc.gateway_address) 

        self.dhcp = SimpleDhcp(self.dhcp_sock)
        self.dhcp.start()  

    def get_rcv_ip_address(self):
        return self.sim.get_gateway_recv_ip()

    def get_udp_sock(self):
        return self.rcv_sock
    
    def get_devices(self):
        return self.devices

    def close_gateway():
        self.dhcp.stop_thread()
        self.dhcp_sock.close()
        self.recv_sock.close()

    def send_data_to_server(self):
        try:
            server_socket = sk.socket(sk.AF_INET, sk.SOCK_STREAM)
            server_socket.connect(nc.server_address)
            print("SENDING DEVICES DATA TO SERVER")
            server_socket.send(
                pickle.dumps(Packet(self.sim.get_gateway_send_mac(),
                    self.sim.get_server_mac(),
                    self.sim.get_gateway_send_ip(),
                    self.sim.get_server_ip(),
                    self.get_devices()
                ))
            )
            message = server_socket.recv(1024)
            utils.print_pkt_size(message)
            pkt = pickle.loads(message)
            utils.print_packet_header(pkt, "SERVER")
            print("Server answer:", pkt.get_payload())
            utils.print_divider()
            print()
        except Exception as error:
            print(error)
        finally:
            server_socket.close()    
        self.clear_measurments()
    
    def clear_measurments(self):
        self.get_devices().clear()
    
    
    def __send_answer(self, address, pkt, message):
        self.get_udp_sock().sendto(
            pickle.dumps(Packet(self.sim.get_gateway_recv_mac(),
                pkt.get_source_mac(),
                self.sim.get_gateway_recv_ip(),
                pkt.get_source_ip(),
                message
            )
        ), address)

    def confirm_reception(self, address, pkt):
        self.__send_answer(address, pkt, "Measurements received")

    def discard_reception(self, address, pkt):
        self.__send_answer(address, pkt, "Wrong Ip address")
コード例 #3
0
class Device:
    daily_measurements = []
    maximum_number_of_measurements_to_be_sent = 6
    empty_payload = ""
    unassigned_ip = "0.0.0.0"

    def __init__(self, mac_address):
        self.sim = Simulation()
        self.log_filename = "DailyDeviceLog_" + str(mac_address).replace(
            ":", "_") + ".json"
        self.mac_address = mac_address
        # richiesta di un indirizzo ip dal dhcp
        print("Device requesting Ip address from DHCP server")
        self.ip_address = self.obtain_ip_address()
        print("Ip address received from DHCP server on gateway: ",
              self.ip_address)
        self.create_file()

    def obtain_ip_address(self):
        dhcp_request_socket = sk.socket(sk.AF_INET, sk.SOCK_DGRAM)

        dhcp_request_socket.sendto(
            pickle.dumps(
                Packet(self.mac_address,
                       self.sim.gateway_recv_mac, self.unassigned_ip,
                       self.sim.get_gateway_recv_ip(), self.empty_payload)),
            nc.dhcp_address)

        data, server = dhcp_request_socket.recvfrom(1024)
        utils.print_pkt_size(data)
        pkt = pickle.loads(data)

        utils.print_packet_header(pkt, "DHCP SERVER")

        dhcp_request_socket.close()

        if data:
            return pkt.get_payload()

        return self.unassigned_ip

    def add_new_measurement(self, measurement):
        self.daily_measurements.append(measurement)
        if os.path.exists(self.log_filename):
            with open(self.log_filename, 'a') as file:
                file.write(measurement.to_string())

        if len(self.daily_measurements
               ) == self.maximum_number_of_measurements_to_be_sent:
            self.send_data()
            #To erase content from file
            open(self.log_filename, 'a').close()

    def send_data(self):
        print("\nDevice is sending data to GATEWAY...\n")
        # creo la socket e la richiudo non appena ho terminato l'invio dei dati
        # non impegnando inultimente le risorse allocate
        sending_socket = sk.socket(sk.AF_INET, sk.SOCK_DGRAM)
        received = False
        while not received:
            try:
                sending_socket.sendto(
                    pickle.dumps(
                        Packet(self.mac_address,
                               self.sim.get_gateway_recv_mac(),
                               self.ip_address, self.sim.get_gateway_recv_ip(),
                               self.daily_measurements)), nc.gateway_address)
                sending_socket.settimeout(2)
                data, address = sending_socket.recvfrom(
                    1024)  # attesa di conferma da parte del gateway
                utils.print_pkt_size(data)
                if data:
                    pkt = pickle.loads(data)
                    utils.print_divider()
                    utils.print_packet_header(pkt, "GATEWAY")
                    received = True
                    print("Gateway answer:", pkt.get_payload())
                    utils.print_divider()
                    #empty print for spacing
                    print()

            except sk.timeout:
                print("Timeout occurred, trying again...")
            except Exception as err:
                print(err)
                time.sleep(3)

        sending_socket.close()
        # after sending data I reset the dictionary to not keep in ram useless data
        self.daily_measurements.clear()

    def create_file(self):
        open(str(self.log_filename), 'w').close()