def test_pack_and_unpack_packet_to_error(self): packet_data = "\x00\x05\x15\x12error_message_example\x00" packet = packets.unpack_packet(packet_data) self.assertEqual(packet.__class__, packets.ErrorPacket) self.assertEqual(packet.error_code, 5394) self.assertEqual(packet.error_message, "error_message_example") self.assertEqual(packet.pack(), packet_data)
def test_pack_and_unpack_packet_to_rrq(self): packet_data = "\x00\x01filename_example\x00mode_example\x00" packet = packets.unpack_packet(packet_data) self.assertEqual(packet.__class__, packets.ReadRequestPacket) self.assertEqual(packet.filename, "filename_example") self.assertEqual(packet.mode, "mode_example") self.assertEqual(packet.options, {}) self.assertEqual(packet.pack(), packet_data)
def test_pack_and_unpack_packet_to_data(self): data = "X" * 512 packet_data = "\x00\x03\x15\x12" + data packet = packets.unpack_packet(packet_data) self.assertEqual(packet.__class__, packets.DataPacket) self.assertEqual(packet.block_num, 5394) self.assertEqual(packet.data, data) self.assertEqual(packet.pack(), packet_data)
def test_pack_and_unpack_packet_to_wrq_with_options(self): packet_data = "\x00\x02filename_example\x00mode_example\x00blksize\x003128\x00timeout\x008\x00" packet = packets.unpack_packet(packet_data) self.assertEqual(packet.__class__, packets.WriteRequestPacket) self.assertEqual(packet.filename, "filename_example") self.assertEqual(packet.mode, "mode_example") self.assertEqual(packet.options, {'blksize':"3128", 'timeout': "8"}) self.assertEqual(packet.pack(), packet_data)
def test_pack_and_unpack_packet_to_wrq_with_options(self): packet_data = "\x00\x02filename_example\x00mode_example\x00blksize\x003128\x00timeout\x008\x00" packet = packets.unpack_packet(packet_data) self.assertEqual(packet.__class__, packets.WriteRequestPacket) self.assertEqual(packet.filename, "filename_example") self.assertEqual(packet.mode, "mode_example") self.assertEqual(packet.options, {'blksize': "3128", 'timeout': "8"}) self.assertEqual(packet.pack(), packet_data)
def run_conversation(state, thread_num): """ Run a single TFTP conversation against the TFTP server. Acts as a lousy client through the following properties: * Waits between two and six seconds before responding to a received message * Has a chance of dropping the connection after receiving any particular message. * In some cases will stall for twenty seconds before responding to a received message. """ sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) port = random.randint(2000, 65535) sock.bind(("0.0.0.0", port)) packet_data = packets.ReadRequestPacket(state.get_filename(), "netascii").pack() print state.host, state.port sock.sendto(packet_data, (state.host, state.port)) finished = False while not finished: response = sock.recvfrom(1024) packet_data = response[0] response_packet = packets.unpack_packet(packet_data) print " [thread_num: %s][outward_port: %s] received %s" % ( thread_num, port, response_packet) # A data packet of under size 512 is considered a final packet if len(response_packet.data) < 512: finished = True # Implement the lousy client properties as described in docstring time.sleep(random.randint(2, 6)) if random.randint(0, 8) == 0: finished = True if random.randint(0, 8) == 0: time.sleep(20) ack_packet = packets.AcknowledgementPacket(response_packet.block_num) print " [%s][%s] sending %s" % (thread_num, port, ack_packet) sock.sendto(ack_packet.pack(), (state.host, state.port)) sock.close()
def run_conversation(state, thread_num): """ Run a single TFTP conversation against the TFTP server. Acts as a lousy client through the following properties: * Waits between two and six seconds before responding to a received message * Has a chance of dropping the connection after receiving any particular message. * In some cases will stall for twenty seconds before responding to a received message. """ sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) port = random.randint(2000, 65535) sock.bind(("0.0.0.0", port)) packet_data = packets.ReadRequestPacket(state.get_filename(), "netascii").pack() print state.host, state.port sock.sendto(packet_data, (state.host, state.port)) finished = False while not finished: response = sock.recvfrom(1024) packet_data = response[0] response_packet = packets.unpack_packet(packet_data) print " [thread_num: %s][outward_port: %s] received %s" % (thread_num, port, response_packet) # A data packet of under size 512 is considered a final packet if len(response_packet.data) < 512: finished = True # Implement the lousy client properties as described in docstring time.sleep(random.randint(2, 6)) if random.randint(0, 8) == 0: finished = True if random.randint(0, 8) == 0: time.sleep(20) ack_packet = packets.AcknowledgementPacket(response_packet.block_num) print " [%s][%s] sending %s" % (thread_num, port, ack_packet) sock.sendto(ack_packet.pack(), (state.host, state.port)) sock.close()
def handle_message(self, sock, addr, data): """Accepts and responds (if applicable) to a message. Args: sock: The socket that the message originated from. addr: A tuple representing (client host, client port). data: Data received in a message from the client. """ client_host = addr[0] client_port = addr[1] packet = packets.unpack_packet(data) logging.debug("%s:%s: received: %s" % (client_host, client_port, packet)) # Invalid Packets are NoOp if isinstance(packet, packets.NoOpPacket): logging.info("Invalid packet received: %s" % data) return conversation = self.get_conversation(client_host, client_port, packet) response_packet = conversation.handle_packet(packet) self.respond_with_packet(client_host, client_port, response_packet)
def test_pack_and_unpack_packet_to_ack(self): packet_data = "\x00\x04\x15\x12" packet = packets.unpack_packet(packet_data) self.assertEqual(packet.__class__, packets.AcknowledgementPacket) self.assertEqual(packet.block_num, 5394) self.assertEqual(packet.pack(), packet_data)