def start(self): self.server_socket = socket(AF_INET, SOCK_DGRAM) # We can specify a specific address when running the server (defaults to '') logger.info("connecting to {}:{}".format(self.connection_address, self.tftp_port)) self.server_socket.bind((self.connection_address, self.tftp_port)) logger.info("serving files from {} on port {}".format(self.data_dir, self.tftp_port)) self.tftp_thread = Thread(target=self.__process_requests, name="tftpd") self.tftp_thread.start()
def do_tcp(data_dir, tcp_port, connection_address): """ this is a simple TCP server that will listen on the specified port and serve data rooted at the specified data. only read requests are supported for security reasons. """ logger.info("tcp running...") srvr = TCPServer(data_dir, tcp_port, connection_address) srvr.start() srvr.join()
def __process_requests(self): # this while loop keeps our server running also accounting for ensuring the initial # data packet is retrieved by the host # accepts RRQ's for files and starts a thread to proccess it logger.info("TFTP waiting for request") while True: pkt, addr = self.server_socket.recvfrom(self.BUFFER_SIZE) t1 = Thread( target=self.__create_thread_and_process_requests, args=(pkt, addr)) t1.daemon = True t1.start()
def do_dhcp(hosts_file, subnet_mask, ip, lease_time, net_inter): configuration = DHCPServerConfiguration(ip, subnet_mask, hosts_file, lease_time, net_inter) configuration.tftp_server_name = ip #configuration.debug = print #configuration.adjust_if_this_computer_is_a_router() #configuration.router #+= ['192.168.0.1'] server = DHCPServer(configuration) for ip in server.configuration.all_ip_addresses(): assert ip == server.configuration.network_filter() logger.info("DHCP server is running...") server.run()
def get_ip_address(self, packet): mac_address = packet.client_mac_address requested_ip_address = packet.requested_ip_address known_hosts = self.hosts.get(mac = CASEINSENSITIVE(mac_address)) ip = None if known_hosts: # 1. choose known ip address for host in known_hosts: if self.is_valid_client_address(host.ip): ip = host.ip str_known_ip = "known ip: " + str(ip) logger.info(str_known_ip) return ip
def __transfer_file(self, client_socket): """ This function serves the file socket's coming requests. """ logger.info("TCP - started file_transferring") try: # opens the specified file in a read only binary form transfer_file = open("{}/{}".format(self.data_dir, "rootfs.tgz"), "rb") data = transfer_file.read() logger.debug("TCP - read rootfs.tgz") if data: # send the data logger.debug("TCP - sending rootfs.tgz") client_socket.send(data) logger.debug("TCP - finished sending rootfs.tgz") except: logger.error(traceback.print_exc()) logger.info("TCP - finished file_transferring") client_socket.close() transfer_file.close()
def get_ip_address(self, packet): mac_address = packet.client_mac_address requested_ip_address = packet.requested_ip_address known_hosts = self.hosts.get(mac=CASEINSENSITIVE(mac_address)) ip = None if known_hosts: # 1. choose known ip address for host in known_hosts: if self.is_valid_client_address(host.ip): ip = host.ip str_known_ip = "known ip: " + str(ip) logger.info(str_known_ip) if ip is None and self.is_valid_client_address(requested_ip_address): # 2. choose valid requested ip address ip = requested_ip_address str_valid_ip = "valid ip: " + str(ip) logger.info(str_valid_ip) if ip is None: # 3. choose new, free ip address chosen = False network_hosts = self.hosts.get( ip=self.configuration.network_filter()) for ip in self.configuration.all_ip_addresses(): if not any(host.ip == ip for host in network_hosts): chosen = True break if not chosen: # 4. reuse old valid ip address network_hosts.sort(key=lambda host: host.last_used) ip = network_hosts[0].ip assert self.is_valid_client_address(ip) str_new_ip = "new ip: " + str(ip) logger.info(str_new_ip) if not any([host.ip == ip for host in known_hosts]): str_add_mac = "add " + str(mac_address) + "ip: " + str( ip) + "hostname: " + str(packet.host_name) logger.info(str_add_mac) #print('add', mac_address, ip, packet.host_name) self.hosts.replace( Host(mac_address, ip, packet.host_name or '', time.time())) return ip
def __create_thread_and_process_requests(self, pkt, addr): # initial block number and variable for filename block_number = 0 filename = '' # prepare the UDP socket client_dedicated_sock = socket(AF_INET, SOCK_DGRAM) # bind to 0 for an ephemeral port client_dedicated_sock.bind((self.connection_address, 0)) # set timeout for the socket client_dedicated_sock.settimeout(10) # RRQ is a series of strings, the first two being the filename # and mode but there may also be options. see RFC 2347. # # we skip the first 2 bytes (the opcode) and split on b'\0' # since the strings are null terminated. # # because b'\0' is at the end of all strings split will always # give us an extra empty string at the end, so skip it with [:-1] packet = serializeme.Deserialize(pkt, { "opcode": ("2B", 1), "filename": (serializeme.NULL_TERMINATE, serializeme.HOST), "mode": (serializeme.NULL_TERMINATE, serializeme.HOST), "ANSWERS": { "option": (serializeme.NULL_TERMINATE, serializeme.HOST), "value": (serializeme.NULL_TERMINATE, serializeme.HOST) } }) strings_in_RRQ = pkt[2:].split(b"\0")[:-1] logger.info("got {} from {}".format(strings_in_RRQ, addr)) filename = packet.get_field("filename") # opens the file once for the socket, opening multiple times causes tftp to be slow try: transfer_file = self.res_open(filename) while True: # the first two bytes of all TFTP packets is the opcode, so we can # extract that here. the '!' is for big endian, and 'H' is to say it is an integer [opcode] = packet.get_field("opcode") if opcode == TFTPServer.RRQ_OPCODE: if len(strings_in_RRQ) > 4: for index, string in enumerate(strings_in_RRQ[2:]): if string.decode() == 'tsize': temp_file = self.res_open(filename) temp_file.seek(0, 2) t_size = temp_file.tell() if string.decode() == 'blksize': block_size = int(strings_in_RRQ[index + 1]) # construct oack packet = serializeme.Serialize({ "OACK_opcode": ("2B", TFTPServer.OACK_OPCODE), "t_size_str": (serializeme.NULL_TERMINATE, "tsize"), "t_size_len": ("4B", t_size), "t_zero": "1B", "block_size_str": (serializeme.NULL_TERMINATE, "block_size"), "block_size": ("2B", block_size), "blk_zero": "1B" }) client_dedicated_sock.sendto(packet.packetize(), addr) # read up to the appropriate 512 bytes of data if len(strings_in_RRQ) > 4: data = transfer_file.read(block_size) else: data = transfer_file.read(512) # if data is received increment block number, contruct the packet, and send it if data: block_number += 1 packet_format = {"opcode": ("2B", TFTPServer.DATA_OPCODE), "blk": ("2B", block_number), "data": "TBD"} if len(strings_in_RRQ) > 4: packet_format['data'] = (str(block_size) + "B", data) else: packet_format['data'] = ("512B", data) packet = serializeme.Serialize(packet_format) client_dedicated_sock.sendto(packet.packetize(), addr) # ACK received, so we can now read the next block, if it doesn't match resend the previous block of data elif opcode == TFTPServer.ACK_OPCODE: packet = serializeme.Deserialize(pkt, { "opcode": "2B", "Block#": "2B" }) [acked_block] = packet.get_field("Block#") # block number matches, the block sent was successfully received if acked_block == block_number: data = transfer_file.read(512) # if data read, increment block number, construct packet, and send it on the socket if data: block_number += 1 # transfer_block_number = pack("!H", block_number) pkt_format = { "opcode": ("2B", TFTPServer.DATA_OPCODE), "block": ("2B", block_number), "data": ("512B", data) } packet = serializeme.Serialize(pkt_format) client_dedicated_sock.sendto(packet.packetize(), addr) # if no data was read, read returns b'', then EOF was reached and download complete else: # sending a packet of zero data - to acknowledge end of transfer block_number += 1 # transfer_block_number = pack("!H", block_number) pkt_format = { "opcode": ("2B", TFTPServer.DATA_OPCODE), "block": ("2B", block_number) } packet = serializeme.Serialize(pkt_format) client_dedicated_sock.sendto(packet.packetize(), addr) logger.warning('download complete, closing socket') client_dedicated_sock.close() break # if the block number doesn't match, means data sent was not received # here you can just resend the data you already read because, no need for seek or another read # because you already read it and it was not received, doing seek or read would slow down tftp elif block_number != acked_block: # decrement block number block_number = block_number - 1 # transfer_block_number = pack("!H", block_number) pkt_format = { "opcode": ("2B", TFTPServer.DATA_OPCODE), "block": ("2B", block_number), "data": ("512B", data) } packet = serializeme.Serialize(pkt_format) client_dedicated_sock.sendto(packet.packetize(), addr) else: # form an error packet and send it to the invalid TID # error_opcode = pack("!H", TFTPServer.ERROR_OPCODE) # error_code = pack("!H", 21) # error_message = b"incorrect TID\0" pkt_format = { "opcode": ("2B", TFTPServer.ERROR_OPCODE), "errorcode": ("2B", 21), "errormsg": (serializeme.NULL_TERMINATE, "incorrect TID") } logger.error("incorrect TID") packet = serializeme.Serialize(pkt_format) client_dedicated_sock.sendto(packet.packetize(), addr) else: # form an error packet and send it to the invalid TID # error_opcode = pack("!H", TFTPServer.ERROR_OPCODE) # error_code = pack("!H", 20) # error_message = b"illegal operation specified\0" pkt_format = { "opcode": ("2B", TFTPServer.ERROR_OPCODE), "errorcode": ("2B", 20), "errormsg": (serializeme.NULL_TERMINATE, "Illegal operation specified") } logger.error("illegal operation specified") packet = serializeme.Serialize(pkt_format) client_dedicated_sock.sendto(packet.packetize(), addr) # listen for a client response for 10 seconds # close everything and terminate if no response try: pkt, addr = client_dedicated_sock.recvfrom( self.BUFFER_SIZE) except: logger.error("Socket Timed Out") client_dedicated_sock.close() logger.error('closed socket') break except FileNotFoundError: # send an error packet to the requesting host # error_opcode = pack("!H", TFTPServer.ERROR_OPCODE) # error_code = pack("!H", 17) # error_message = b"No such file within the directory\0" pkt_format = { "opcode": ("2B", TFTPServer.ERROR_OPCODE), "errorcode": ("2B", 17), "errormsg": (serializeme.NULL_TERMINATE, "No such file within the directory") } logger.error("No such file within the directory") packet = serializeme.Serialize(pkt_format) client_dedicated_sock.sendto(packet.packetize(), addr) client_dedicated_sock.close()
power_cycle.power_cycle(switch_address,interface, portNum) time.sleep(30) mac_mapper.mac_mapper(file) def config_ui(name, config_path, hosts_csv_path): web_ui.start(name, config_path, hosts_csv_path) def exit_piman(): logger.error("Insufficient amount of arguments") exit(1) if __name__ == "__main__": args = "Arguments: " for a in argv: args += a + " " logger.info(args) if len(argv) < 2: exit_piman() if argv[1] == "server": server() elif argv[1] == "restart": if len(argv) < 5: exit_piman() restart(argv[2], argv[3],argv[4]) elif argv[1] == "mapper": if len(argv) < 5: exit_piman() mapper(argv[2],argv[3],argv[4]) elif argv[1] == "reinstall":
def __process_requests(self, client_socket, client_addr): """ This function serves the control socket's coming requests. """ reinstall_file = list() with open('reinstall.txt') as fp: reinstall_file = fp.read() try: logger.info("serving client from: {}".format(client_addr)) fd = client_socket.makefile() date = datetime.now() dt_string = date.strftime('%Y%m%d%H%M.%S') dt_string = 'busybox date -s ' + dt_string + "\n" + "EOM\n" print("Sending date command to pi:", dt_string) client_socket.send(dt_string.encode()) req = fd.readline() while req: req = req.strip() logger.info("TCP - recieved request {}".format(req)) if req == RECV_IS_UNINSTALLED: logger.info("TCT - uninstalled, sending format") # this line of code is suggested by team fire client_socket.send(SEND_FORMAT) elif req == RECV_IS_INSTALLED: if client_addr[0] in reinstall_file: logger.info("TCP - need to reinstall, sending format") client_socket.send(SEND_FORMAT) else: logger.info("TCP - installed, sending boot") client_socket.send(SEND_BOOT) elif req == RECV_IS_FORMATTED: logger.info("TCP - is formatted, sending file") break else: pass #print("TCP - not supported request") req = fd.readline() except: logger.error(traceback.print_exc()) logger.info("tcpdump") client_socket.close()
def __create_thread_and_process_requests(self, pkt, addr): # initial block number and variable for filename block_number = 0 filename = '' # prepare the UDP socket client_dedicated_sock = socket(AF_INET, SOCK_DGRAM) # bind to 0 for an ephemeral port client_dedicated_sock.bind((self.connection_address, 0)) # set timeout for the socket client_dedicated_sock.settimeout(10) # RRQ is a series of strings, the first two being the filename # and mode but there may also be options. see RFC 2347. # # we skip the first 2 bytes (the opcode) and split on b'\0' # since the strings are null terminated. # # because b'\0' is at the end of all strings split will always # give us an extra empty string at the end, so skip it with [:-1] strings_in_RRQ = pkt[2:].split(b"\0")[:-1] logger.info("got {} from {}".format(strings_in_RRQ, addr)) filename = strings_in_RRQ[0] # opens the file once for the socket, opening multiple times causes tftp to be slow try: transfer_file = self.res_open(strings_in_RRQ[0].decode()) while True: # the first two bytes of all TFTP packets is the opcode, so we can # extract that here. the '!' is for big endian, and 'H' is to say it is an integer [opcode] = unpack("!H", pkt[0:2]) if opcode == TFTPServer.RRQ_OPCODE: # set the opcode for the packet we are sending transfer_opcode = pack("!H", TFTPServer.DATA_OPCODE) # read up to the appropriate 512 bytes of data data = transfer_file.read(512) # if data is received increment block number, contruct the packet, and send it if data: block_number += 1 transfer_block_number = pack("!H", block_number) packet = transfer_opcode + transfer_block_number + data client_dedicated_sock.sendto(packet, addr) # ACK received, so we can now read the next block, if it doesn't match resend the previous block of data elif opcode == TFTPServer.ACK_OPCODE: [acked_block] = unpack("!H", pkt[2:4]) # block number matches, the block sent was successfully received if acked_block == block_number: data = transfer_file.read(512) # if data read, increment block number, construct packet, and send it on the socket if data: block_number += 1 transfer_block_number = pack("!H", block_number) packet = transfer_opcode + transfer_block_number + data client_dedicated_sock.sendto(packet, addr) # if no data was read, read returns b'', then EOF was reached and download complete else: logger.warning('download complete, closing socket') client_dedicated_sock.close() break # if the block number doesn't match, means data sent was not received # here you can just resend the data you already read because, no need for seek or another read # because you already read it and it was not received, doing seek or read would slow down tftp elif block_number != acked_block: # decrement block number block_number = block_number - 1 transfer_block_number = pack("!H", block_number) packet = transfer_opcode + transfer_block_number + data client_dedicated_sock.sendto(packet, addr) else: # form an error packet and send it to the invalid TID error_opcode = pack("!H", TFTPServer.ERROR_OPCODE) error_code = pack("!H", 21) error_message = b"incorrect TID\0" logger.error("incorrect TID") packet = error_opcode + error_code + error_message client_dedicated_sock.sendto(packet, addr) else: # form an error packet and send it to the invalid TID error_opcode = pack("!H", TFTPServer.ERROR_OPCODE) error_code = pack("!H", 20) error_message = b"illegal operation specified\0" logger.error("illegal operation specified") packet = error_opcode + error_code + error_message client_dedicated_sock.sendto(packet, addr) # listen for a client response for 10 seconds # close everything and terminate if no response try: pkt, addr = client_dedicated_sock.recvfrom( self.BUFFER_SIZE) except: logger.error("Socket Timed Out") client_dedicated_sock.close() logger.error('closed socket') break except FileNotFoundError: # send an error packet to the requesting host error_opcode = pack("!H", TFTPServer.ERROR_OPCODE) error_code = pack("!H", 17) error_message = b"No such file within the directory\0" logger.error("No such file within the directory") packet = error_opcode + error_code + error_message client_dedicated_sock.sendto(packet, addr) client_dedicated_sock.close()
def do_dns(): logger.info("DNS server is running...") server = DNSServer() server.start()
def __process_requests(self, client_socket, client_addr): """ This function serves the control socket's coming requests. """ reinstall_file = self.__read_reinstall_file() try: logger.info("serving client from: {}".format(client_addr)) fd = client_socket.makefile() date = datetime.now() dt_string = date.strftime('%Y%m%d%H%M.%S') dt_string = 'busybox date -s ' + dt_string + "\n" + "EOM\n" req_dict = { # this dict is used only when the received command results in logging only RECV_RECEIVED_DATE: lambda: logger.info( "TCP - pi successfully received date string"), RECV_SET_DATE: lambda: logger.info("TCP - pi successfully set local datetime" ), RECVD_MOUNTING: lambda: logger.info("TCP - pi mounting has started"), RECVD_MOUNTED: lambda: logger.info("TCP - pi successfully mounted filesystem" ), RECVD_UNMOUNTING: lambda: logger.info("TCP - pi unmounting has started"), RECVD_UNMOUNTED: lambda: logger.info( "TCP - pi successfully unmounted filesystem"), RECVD_BOOT: lambda: logger.info( "TCP - pi successfully received boot command"), RECVD_FORMAT: lambda: logger.info( "TCP - pi successfully received format command"), RECVD_REINSTALL: lambda: logger.info( "TCP - pi successfully received reinstall command") } print("Sending date command to pi:", dt_string) client_socket.send(dt_string.encode()) req = fd.readline() while req: req = req.strip() if req == RECV_IS_UNINSTALLED: logger.info("TCT - uninstalled, sending format") # this line of code is suggested by team fire client_socket.send(SEND_FORMAT) elif req == RECV_IS_INSTALLED: if client_addr[0] in reinstall_file: logger.info("TCP - need to reinstall, sending format") client_socket.send(SEND_FORMAT) #clear reinstall.txt file after sending format signal self.__clear_reinstall_file() else: logger.info("TCP - installed, sending boot") client_socket.send(SEND_BOOT) elif req == RECV_IS_FORMATTED: logger.info("TCP - is formatted, sending file") break else: if req in req_dict: req_dict[req]( ) # log changed state if command is valid and not handled above else: logger.info("TCP - unsupported request: {}".format( req)) # otherwise log unsupported command req = fd.readline() except: logger.error(traceback.print_exc()) logger.info("tcpdump") client_socket.close()
else: result = varBinds[0].prettyPrint() return result.split(" = ")[1] def mac_in_decimal(mac_address): parts = [] for part in mac_address.split(":"): parts.append(str(int(part, 16))) return ".".join(parts) if __name__ == "__main__": if len(sys.argv) != 4: logger.info( "Usage: '$ python3 findport.py XX:XX:XX:XX:XX:XX SWITCH_ADDRESS VLAN_NUMBER'" ) sys.exit(1) mac_address = sys.argv[1] switch_address = sys.argv[2] vlan_number = sys.argv[3] try: port = find_port(mac_address, switch_address, vlan_number) if port is None: raise Exception('Oops!') logger.debug(port) except Exception as e: # print(e) logger.warning("{} not found".format(mac_address))