def target_on_listening(s: socket, target: tuple): host = target[0] if target[0] != 'localhost' else '127.0.0.1' port = target[1] s.settimeout(1) try: SYN = struct.pack('iii', 1, 1, 0) s.sendto(SYN, target) s.recvfrom(1024) s.settimeout(None) return True except timeout: s.settimeout(None) return False
def recv_ack(self, s: socket, e: threading.Event): buffer = 2 while True: ack_b, addr = s.recvfrom(buffer) ack = int.from_bytes(ack_b, 'big') logging.debug('recv ack {0}'.format(ack)) with self.mutex: if ack == self.send_base: if not self.next_seq > len(self.pac_lis) - 1: s.sendto(self.pac_lis[self.next_seq], self.dst_addr) self.send_base += 1 if self.next_seq < len(self.pac_lis) - 1: self.next_seq += 1 logging.debug('Forward Window {0}'.format( list(range(self.send_base, self.next_seq)))) e.set() elif ack > self.send_base: self.send_base = ack + 1 self.next_seq = self.send_base logging.debug('Reset Window {0}'.format( list(range(self.send_base, self.next_seq)))) e.set() if ack == len(self.pac_lis) - 1: break
def recvMsg(udpSocket: socket): ''' receive message function :param udpSocket: :return: ''' recvData = udpSocket.recvfrom(2048) print('%s %s' % (str(recvData[1]), recvData[0].decode('utf-8')))
def untilRequestFromClient(sock1: socket): firstPartOfHandshake: bool = False while firstPartOfHandshake is False: # keep receiving incoming message until three way handshake data, address = sock1.recvfrom(4096) # if the first msg received equals the first msg in the protocol then send accept if data.decode() == request(address[0]): sent = sock1.sendto(serverAccept(address[0]).encode(), address) firstPartOfHandshake = True
def handshake(s: socket, target: tuple): global identifier, version SYN = struct.pack('iii', 1, 1, 0) print('Handshake : Send SYN') s.sendto(SYN, target) print('Handshake : Receive SYNACK') SYNACK, addr = s.recvfrom(1024) _, _, identifier, version, _, _ = decode_synack(SYNACK) ACK = struct.pack('iii', identifier, version, 1) print('Handshake : Send ACK') s.sendto(ACK, target) print('Handshake : Done')
def untilAccept(sock1: socket): secondPartOfHandshake: bool = False while secondPartOfHandshake is False: data, address = sock1.recvfrom(4096) # if the 2 msg equals the 2 msg in the protocol accept client if data.decode() == clientAccept(): secondPartOfHandshake = True timeOfEvent = datetime.now() logging.info( str(timeOfEvent) + ': Handshake completed with client with IP address' + str(address)) return address, secondPartOfHandshake
def handle_new_client(client: socket, client_list: list, _is_running: bool, t_id: int): while _is_running[t_id]: data = client.recvfrom(1024)[0].decode('ISO-8859-1') if len(data) == 0: client_list.remove(client) break else: lock.acquire() try: print('\n' + data) finally: lock.release()
def receiveMessages(sock1: socket): global clientAccepted, count, clientCount serverMessageCount = 1 while clientAccepted is True: isMsg: bool # sets a timer that runs the reset function when 4.0 sec has elapsed t = threading.Timer(4.0, resetCon, args=(sock1, )) t.start() try: data, address = sock1.recvfrom(1024) except ConnectionResetError: break except OSError: break # timer resets after every msg received t.cancel() try: clientCount = testCountMsg(data.decode()) isMsg = True except ValueError: isMsg = False if data.decode() == heartbeat(): t.cancel() else: resetCon(sock1) if isMsg: if serverMessageCount == clientCount + 1: print('\nClient: {} '.format(data.decode())) sock1.sendto( serverMessage(serverMessageCount).encode(), address) print('\nServer: {} '.format( serverMessage(serverMessageCount))) serverMessageCount = serverMessageCount + 2 else: logging.info(": Wrong count in messages") clientAccepted = False timeOfEvent = datetime.now() logging.info(str(timeOfEvent) + ": Resetting Connection") resetCon(sock1)
def receive_one_ping(sock: socket, icmp_id: int, seq: int, timeout: int) -> float or None: """Receives the ping from the socket. IP Header (bits): version (8), type of service (8), length (16), id (16), flags (16), time to live (8), protocol (8), checksum (16), source ip (32), destination ip (32). ICMP Packet (bytes): IP Header (20), ICMP Header (8), ICMP Payload (*). Ping Wikipedia: https://en.wikipedia.org/wiki/Ping_(networking_utility) ToS (Type of Service) in IP header for ICMP is 0. Protocol in IP header for ICMP is 1. Args: sock: The same socket used for send the ping. icmp_id: ICMP packet id. Sent packet id should be identical with received packet id. seq: ICMP packet sequence. Sent packet sequence should be identical with received packet sequence. timeout: Timeout in seconds. Returns: The delay in seconds or None on timeout. Raises: TimeToLiveExpired: If the Time-To-Live in IP Header is not large enough for destination. TimeExceeded: If time exceeded but Time-To-Live does not expired. """ ip_header_slice = slice(0, struct.calcsize(IP_HEADER_FORMAT)) # [0:20] icmp_header_slice = slice(ip_header_slice.stop, ip_header_slice.stop + struct.calcsize(ICMP_HEADER_FORMAT)) # [20:28] ip_header_keys = ('version', 'tos', 'len', 'id', 'flags', 'ttl', 'protocol', 'checksum', 'src_addr', 'dest_addr') icmp_header_keys = ('type', 'code', 'checksum', 'id', 'seq') while True: selected = select.select([sock], [], [], timeout) if selected[0] == []: # Timeout raise errors.Timeout(timeout) time_recv = time.time() recv_data, addr = sock.recvfrom(1024) ip_header_raw, icmp_header_raw, icmp_payload_raw = recv_data[ip_header_slice], recv_data[icmp_header_slice], recv_data[icmp_header_slice.stop:] ip_header = dict(zip(ip_header_keys, struct.unpack(IP_HEADER_FORMAT, ip_header_raw))) _debug("IP HEADER:", ip_header) icmp_header = dict(zip(icmp_header_keys, struct.unpack(ICMP_HEADER_FORMAT, icmp_header_raw))) _debug("ICMP HEADER:", icmp_header) if icmp_header['type'] == IcmpType.TIME_EXCEEDED: # TIME_EXCEEDED has no icmp_id and icmp_seq. Usually they are 0. if icmp_header['code'] == IcmpTimeExceededCode.TTL_EXPIRED: raise errors.TimeToLiveExpired() # Some router does not report TTL expired and then timeout shows. raise errors.TimeExceeded() if icmp_header['id'] == icmp_id and icmp_header['seq'] == seq: # ECHO_REPLY should match the if icmp_header['type'] == IcmpType.ECHO_REQUEST: # filters out the ECHO_REQUEST itself. _debug("ECHO_REQUEST filtered out.") continue if icmp_header['type'] == IcmpType.ECHO_REPLY: time_sent = struct.unpack(ICMP_TIME_FORMAT, icmp_payload_raw[0:struct.calcsize(ICMP_TIME_FORMAT)])[0] return time_recv - time_sent
def receive_reply(open_socket: socket, timeout: int = 1) -> tuple: """Receive an ICMP reply""" time_left = timeout started_select = time.time() what_ready = select.select([open_socket], [], [], time_left) how_long_in_select = time.time() - started_select if not what_ready[0]: raise TimeoutError("Request timed out") pkt_rcvd, addr = open_socket.recvfrom(1024) time_left = time_left - how_long_in_select if time_left <= 0: raise TimeoutError("Request timed out") return (pkt_rcvd, addr[0])
def recv_packet(s: socket, packets): while True: try: data, addr = s.recvfrom(2048) data, question, query = server_wrapper.server_decrypt(data) p = Packet(data, question, query, addr) if packets.full(): p2 = packets.get() s.sendto( server_wrapper.server_encrypt(p2.query, b'hi', p2.question), p2.addr) packets.put(p) if question != 'aGVsbG8=.group-7.cs305.fun' and question: tun.write(data) else: print('receive empty packet') except binascii.Error: continue
def untilRequestFromClient(sock1: socket): firstPartOfHandshake: bool = False while firstPartOfHandshake is False: # keep receiving incoming message until three way handshake print(validate_ip('127.0.0.1')) data, address = sock1.recvfrom(4096) # if the first msg received equals the first msg in the protocol then send accept print() if data.decode() == request(address[0]) and validate_ip( address[0]) == True: print("my timemachineworks") sock1.sendto(serverAccept(address[0]).encode(), address) firstPartOfHandshake = True else: timeOfEvent = datetime.now() logging.info( str(timeOfEvent) + ": Handshake didn't complete. Either not an IP address or wrong request " "protocol message ")
def receiveMessages(sock1: socket): global clientCount, clientAccepted, count while clientAccepted is True: isMsg: bool # sets a timer that runs the reset function when 4.0 sec has elapsed t = threading.Timer(4.0, resetCon, args=(sock1, )) t.start() try: data, address = sock1.recvfrom(4096) except ConnectionResetError: break except OSError: break # timer resets after every msg received t.cancel() try: clientCount = getCountFromMsg(data.decode()) isMsg = True # try to get count from every msg. When a msg that doesnt follow protocol is received it will raise a # ValueError if the received msg is a heartbeat it resets the timer else the connection is reset except ValueError: isMsg = False if data.decode() == heartbeat(): t.cancel() else: resetCon(sock1) # if the recevied is a msg send a servermessage and increment the count by 2. One for msg recieved and one for # msg send if isMsg: if clientCount != count: print('Count was: ' + str(count) + ' ClientCount was: ' + str(clientCount)) clientAccepted = False resetCon(sock1) break print('\nClient: {} '.format(data.decode())) count = count + 1 sent = sock1.sendto(serverMessage(count).encode(), address) print('\nServer: {} '.format(serverMessage(count))) count = count + 1
def spoof(s: socket) -> None: while True: (packet, addr) = s.recvfrom(ETH_P_SIZE) eth_header = packet[:ETH_LEN] eth_data = packet[ETH_LEN:] eth = struct.unpack('!6s6sH', eth_header) print('\nMAC src:', bytesToMac(eth[1])) print('MAC dst:', bytesToMac(eth[0])) print('eth type:', hex(eth[2])) if isIP(eth): (ip_s, ip_d, ip_p, ip_data) = decodeIP(eth_data) print('IP Src:', ip_s) print('IP Dest:', ip_d) print('IP Proto:', ip_p) if isUDP(ip_p): (psrc, pdst, plen, udp_data) = decodeUDP(ip_data) print('UDP p_src:', psrc) print('UDP p_dst:', pdst) print('UDP len:', plen) if isDHCP(psrc, pdst): print('IPs...', offeredIPs) print('used', usedIPs) print('suff', usedSuffixes) (dhcp, dhcp_data) = decodeDHCP(udp_data) # print('DHCP:', dhcp) print('DHCP xid', hex(dhcp['xid'])) dhcpToSpoof = { 'eth': eth, 'ip': { 'ip_s': ip_s, 'ip_d': ip_d, }, 'udp': { 'psrc': psrc, 'pdst': pdst, }, 'dhcp': dhcp, } msgType = getDHCPMessageType(dhcp['opts']) print('DHCP Message Type', msgType) hasReqId = hasRequestedIP(dhcp['opts']) if msgType == DHCPDISCOVER: print('DHCP discover') if hasReqId: print('DHCP has Requested IP') sendDHCPAckSpoofed(s, dhcpToSpoof, True) sendDHCPOfferSpoofed(s, dhcpToSpoof) elif msgType == DHCPREQUEST: print('DHCP request') if isMe(dhcp['opts']): if hasReqId: sendDHCPAckSpoofed(s, dhcpToSpoof, True) else: sendDHCPAckSpoofed(s, dhcpToSpoof) else: print('Don\'t know this one :/')
def recv_ensure_from(s: socket, ip_port_tuple: tuple, chunk_sz: int) -> bytes: addr: tuple = () while addr != ip_port_tuple: data, addr = s.recvfrom(chunk_sz) return data
def recvMsg(udpSocket: socket): recvData = udpSocket.recvfrom(2048) print('%s %s' % (str(recvData[1]), recvData[0].decode('utf-8')))
def receive_one_ping(sock: socket, icmp_id: int, seq: int, timeout: int) -> float or None: """Receives the ping from the socket. IP Header (bits): version (8), type of service (8), length (16), id (16), flags (16), time to live (8), protocol (8), checksum (16), source ip (32), destination ip (32). ICMP Packet (bytes): IP Header (20), ICMP Header (8), ICMP Payload (*). Ping Wikipedia: https://en.wikipedia.org/wiki/Ping_(networking_utility) ToS (Type of Service) in IP header for ICMP is 0. Protocol in IP header for ICMP is 1. Args: sock: The same socket used for send the ping. icmp_id: ICMP packet id. Sent packet id should be identical with received packet id. seq: ICMP packet sequence. Sent packet sequence should be identical with received packet sequence. timeout: Timeout in seconds. Returns: The delay in seconds or None on timeout. Raises: TimeToLiveExpired: If the Time-To-Live in IP Header is not large enough for destination. TimeExceeded: If time exceeded but Time-To-Live does not expired. DestinationHostUnreachable: If the destination host is unreachable. DestinationUnreachable: If the destination is unreachable. """ ip_header_slice = slice(0, struct.calcsize(IP_HEADER_FORMAT)) # [0:20] icmp_header_slice = slice(ip_header_slice.stop, ip_header_slice.stop + struct.calcsize(ICMP_HEADER_FORMAT)) # [20:28] timeout_time = time.time() + timeout # Exactly time when timeout. _debug("Timeout time:", time.ctime(timeout_time)) while True: timeout_left = timeout_time - time.time( ) # How many seconds left until timeout. timeout_left = timeout_left if timeout_left > 0 else 0 # Timeout must be non-negative _debug("Timeout left: {:.2f}s".format(timeout_left)) selected = select.select( [ sock, ], [], [], timeout_left) # Wait until sock is ready to read or time is out. if selected[0] == []: # Timeout raise errors.Timeout(timeout) time_recv = time.time() recv_data, addr = sock.recvfrom(1024) ip_header_raw, icmp_header_raw, icmp_payload_raw = recv_data[ ip_header_slice], recv_data[icmp_header_slice], recv_data[ icmp_header_slice.stop:] ip_header = read_ip_header(ip_header_raw) _debug("Received IP Header:", ip_header) icmp_header = read_icmp_header(icmp_header_raw) _debug("Received ICMP Header:", icmp_header) _debug("Received ICMP Payload:", icmp_payload_raw) if icmp_header['id'] and icmp_header[ 'id'] != icmp_id: # ECHO_REPLY should match the ID field. _debug("ICMP ID dismatch. Packet filtered out.") continue if icmp_header[ 'type'] == IcmpType.TIME_EXCEEDED: # TIME_EXCEEDED has no icmp_id and icmp_seq. Usually they are 0. if icmp_header['code'] == IcmpTimeExceededCode.TTL_EXPIRED: raise errors.TimeToLiveExpired( ) # Some router does not report TTL expired and then timeout shows. raise errors.TimeExceeded() if icmp_header[ 'type'] == IcmpType.DESTINATION_UNREACHABLE: # DESTINATION_UNREACHABLE has no icmp_id and icmp_seq. Usually they are 0. if icmp_header[ 'code'] == IcmpDestinationUnreachableCode.DESTINATION_HOST_UNREACHABLE: raise errors.DestinationHostUnreachable() raise errors.DestinationUnreachable() if icmp_header['id'] and icmp_header[ 'seq'] == seq: # ECHO_REPLY should match the SEQ field. if icmp_header[ 'type'] == IcmpType.ECHO_REQUEST: # filters out the ECHO_REQUEST itself. _debug("ECHO_REQUEST received. Packet filtered out.") continue if icmp_header['type'] == IcmpType.ECHO_REPLY: time_sent = struct.unpack( ICMP_TIME_FORMAT, icmp_payload_raw[0:struct.calcsize(ICMP_TIME_FORMAT)])[0] return time_recv - time_sent _debug("Uncatched ICMP Packet:", icmp_header)
def receive_one_ping(sock: socket, icmp_id: int, seq: int, timeout: int) -> float: """Receives the ping from the socket. IP Header (bits): version (8), type of service (8), length (16), id (16), flags (16), time to live (8), protocol (8), checksum (16), source ip (32), destination ip (32). ICMP Packet (bytes): IP Header (20), ICMP Header (8), ICMP Payload (*). Ping Wikipedia: https://en.wikipedia.org/wiki/Ping_(networking_utility) ToS (Type of Service) in IP header for ICMP is 0. Protocol in IP header for ICMP is 1. Args: sock: The same socket used for send the ping. icmp_id: ICMP packet id. Sent packet id should be identical with received packet id. seq: ICMP packet sequence. Sent packet sequence should be identical with received packet sequence. timeout: Timeout in seconds. Returns: The delay in seconds or None on timeout. Raises: TimeToLiveExpired: If the Time-To-Live in IP Header is not large enough for destination. TimeExceeded: If time exceeded but Time-To-Live does not expired. DestinationHostUnreachable: If the destination host is unreachable. DestinationUnreachable: If the destination is unreachable. """ has_ip_header = (os.name != 'posix') or (platform.system() == 'Darwin') or ( sock.type == socket.SOCK_RAW ) # No IP Header when unprivileged on Linux. if has_ip_header: ip_header_slice = slice(0, struct.calcsize(IP_HEADER_FORMAT)) # [0:20] icmp_header_slice = slice( ip_header_slice.stop, ip_header_slice.stop + struct.calcsize(ICMP_HEADER_FORMAT)) # [20:28] else: _debug("Unprivileged on Linux") icmp_header_slice = slice(0, struct.calcsize(ICMP_HEADER_FORMAT)) # [0:8] timeout_time = time.time() + timeout # Exactly time when timeout. _debug("Timeout time: {} ({})".format(time.ctime(timeout_time), timeout_time)) while True: timeout_left = timeout_time - time.time( ) # How many seconds left until timeout. timeout_left = timeout_left if timeout_left > 0 else 0 # Timeout must be non-negative _debug("Timeout left: {:.2f}s".format(timeout_left)) selected = select.select( [ sock, ], [], [], timeout_left) # Wait until sock is ready to read or time is out. if selected[0] == []: # Timeout raise errors.Timeout(timeout=timeout) time_recv = time.time() _debug("Received time: {} ({}))".format(time.ctime(time_recv), time_recv)) recv_data, addr = sock.recvfrom( 1500 ) # Single packet size limit is 65535 bytes, but usually the network packet limit is 1500 bytes. if has_ip_header: ip_header_raw = recv_data[ip_header_slice] ip_header = read_ip_header(ip_header_raw) _debug("Received IP header:", ip_header) else: ip_header = None icmp_header_raw, icmp_payload_raw = recv_data[ icmp_header_slice], recv_data[icmp_header_slice.stop:] icmp_header = read_icmp_header(icmp_header_raw) _debug("Received ICMP header:", icmp_header) _debug("Received ICMP payload:", icmp_payload_raw) if not has_ip_header: # When unprivileged on Linux, ICMP ID is rewrited by kernel. icmp_id = sock.getsockname()[ 1] # According to https://stackoverflow.com/a/14023878/4528364 if icmp_header[ 'type'] == IcmpType.TIME_EXCEEDED: # TIME_EXCEEDED has no icmp_id and icmp_seq. Usually they are 0. if icmp_header[ 'code'] == IcmpTimeExceededCode.TTL_EXPIRED: # Windows raw socket cannot get TTL_EXPIRED. See https://stackoverflow.com/questions/43239862/socket-sock-raw-ipproto-icmp-cant-read-ttl-response. raise errors.TimeToLiveExpired( ip_header=ip_header, icmp_header=icmp_header ) # Some router does not report TTL expired and then timeout shows. raise errors.TimeExceeded() if icmp_header[ 'type'] == IcmpType.DESTINATION_UNREACHABLE: # DESTINATION_UNREACHABLE has no icmp_id and icmp_seq. Usually they are 0. if icmp_header[ 'code'] == IcmpDestinationUnreachableCode.DESTINATION_HOST_UNREACHABLE: raise errors.DestinationHostUnreachable( ip_header=ip_header, icmp_header=icmp_header) raise errors.DestinationUnreachable(ip_header=ip_header, icmp_header=icmp_header) if icmp_header['id']: if icmp_header[ 'type'] == IcmpType.ECHO_REQUEST: # filters out the ECHO_REQUEST itself. _debug("ECHO_REQUEST received. Packet filtered out.") continue if icmp_header[ 'id'] != icmp_id: # ECHO_REPLY should match the ICMP ID field. _debug("ICMP ID dismatch. Packet filtered out.") continue if icmp_header[ 'seq'] != seq: # ECHO_REPLY should match the ICMP SEQ field. _debug("IMCP SEQ dismatch. Packet filtered out.") continue if icmp_header['type'] == IcmpType.ECHO_REPLY: time_sent = struct.unpack( ICMP_TIME_FORMAT, icmp_payload_raw[0:struct.calcsize(ICMP_TIME_FORMAT)])[0] _debug("Received sent time: {} ({})".format( time.ctime(time_sent), time_sent)) return time_recv - time_sent _debug("Uncatched ICMP packet:", icmp_header)
def handle_client(self, conn_tcp: socket, conn_udp: socket, addr: tuple, event: threading.Event): """Función que maneja las nuevas conexiones con el cliente Args: conn_tcp ([type]): Conexión del cliente addr (str): Dirección del cliente """ try: # Logea la nueva conexión self.logger.log_info(f"[CONNECTION] {addr}CONNECTION") msg = conn_tcp.recv(self.SIZE).decode() if msg == self.HELLO: #Se envia metadata y el hash self.synch(event) fileSize = f"{self.getSyzeInMB()}" fileName = f"{self.PATHS[self.fileIndex].split('/')[-1]}" self.logger.log_info( f"[MESSAGE] File to be send is: {fileName}") self.logger.log_info(f"[MESSAGE] File size is of {fileSize}") conn_tcp.sendall(fileName.encode() + b'\n') conn_tcp.sendall(fileSize.encode() + b'\n') conn_tcp.sendall( self.PATHS[self.fileIndex].split(".")[-1].encode() + b'\n') conn_tcp.sendall(self.getHashFile().encode() + b'\n', ) self.logger.log_info( f"[MESSAGE] Hash File has been sent to {addr}") msg = conn_tcp.recv(self.SIZE).decode() #Se envia el archivo si llego ell hash if msg == self.CONFIRM: self.logger.log_info( f"[MESSAGE] File transfer via UDP will begin") data, address = conn_udp.recvfrom(self.SIZE) with open(self.PATHS[self.fileIndex], 'rb') as f: init_time = time.time() data = f.read(self.SIZE) paquetes = 1 while data: time.sleep(0.0000001) conn_udp.sendto(data, address) data = f.read(self.SIZE) paquetes += 1 self.logger.log_info( f"[MESSAGE] File is has been sent to {addr} in {paquetes} packets" ) #Se envia y recibe el tiempo cuando se acaba msg = conn_tcp.recv(self.SIZE).decode() if msg == self.CONFIRM: #Intercambio de tiempo conn_tcp.sendall(str(init_time).encode()) end_time = float(conn_tcp.recv(self.SIZE).decode()) self.logger.log_info( f"[MESSAGE] File has been send to {addr} in {end_time-init_time} seconds" ) else: self.logger.log_critical("Integrity check failed") else: self.logger.log_error( f"[MESSAGE] Unexpected message of {addr}, bad handshake") conn_tcp.close() self.logger.log_info(f"[CONNECTION] {addr} connection closed") except Exception as ex: self.logger.log_critical(ex) raise ex
def extract_info_from_socket(connection: socket) -> EthernetPacket: socket_info: Tuple[bytes, Any] = connection.recvfrom(65535) raw_data: bytes = socket_info[0] address: object = socket_info[1] return __unpack_ethernet_frame(raw_data)