def verbose_ping(address, count=4, interval=1, timeout=2, id=PID): # A payload of 56 bytes is used by default. You can modify it using # the 'payload_size' parameter of your ICMP request. print(f'PING {address}: 56 data bytes\n') # We detect the socket to use from the specified IP address if is_ipv6_address(address): sock = ICMPv6Socket() else: sock = ICMPv4Socket() for sequence in range(count): # We create an ICMP request request = ICMPRequest( destination=address, id=id, sequence=sequence) try: # We send the request sock.send(request) # We are awaiting receipt of an ICMP reply reply = sock.receive(request, timeout) # We received a reply # We display some information print(f' {reply.bytes_received} bytes from ' f'{reply.source}: ', end='') # We throw an exception if it is an ICMP error message reply.raise_for_status() # We calculate the round-trip time and we display it round_trip_time = (reply.time - request.time) * 1000 print(f'icmp_seq={sequence} ' f'time={round(round_trip_time, 3)} ms') # We wait before continuing if sequence < count - 1: sleep(interval) except TimeoutExceeded: # The timeout has been reached print(f' Request timeout for icmp_seq {sequence}') except ICMPError as err: # An ICMP error message has been received print(err) except ICMPLibError: # All other errors print(' An error has occurred.') print('\nCompleted.')
def broadcast_ping(address, count=4, timeout=1, id=PID): # ICMPRequest uses a payload of 56 bytes by default # You can modify it using the payload_size parameter print(f'PING {address}: 56 data bytes') # Broadcast is only possible in IPv4 socket = ICMPv4Socket() # We allow the socket to send broadcast packets socket.broadcast = True for sequence in range(count): # We create an ICMP request request = ICMPRequest(destination=address, id=id, sequence=sequence, timeout=timeout) print() try: # We send the request socket.send(request) while 'we receive replies': # We are awaiting receipt of an ICMP reply # If there is no more responses, the TimeoutExceeded # exception is thrown and the loop is stopped reply = socket.receive() # We calculate the round-trip time of the reply round_trip_time = (reply.time - request.time) * 1000 # We display some information print(f' {reply.bytes_received} bytes from ' f'{reply.source}: icmp_seq={sequence} ' f'time={round(round_trip_time, 3)} ms') except TimeoutExceeded: # The timeout has been reached # We use this exception to break the while loop pass except ICMPLibError: # All other errors print('An error has occurred.')
def check_connection(address, timeout=2, request_id=PID): sock = ICMPv4Socket() request = ICMPRequest(destination=address, id=request_id, sequence=1) try: sock.send(request) reply = sock.receive(request, timeout) reply.raise_for_status() except TimeoutExceeded as err: print(err) except DestinationUnreachable as err: print(err) except TimeExceeded as err: print(err) except ICMPLibError as err: print(err)
def verbose_traceroute(address, count=2, interval=0.05, timeout=2, id=PID, max_hops=30): # We perform a DNS resolution of the address passed in parameters. # If the address is already an IP address, no lookup is done. The # same address is returned. ip_address = resolve(address) # A payload of 56 bytes is used by default. You can modify it using # the 'payload_size' parameter of your ICMP request. print(f'Traceroute to {address} ({ip_address}): ' f'56 data bytes, {max_hops} hops max\n') # We detect the socket to use from the specified IP address if is_ipv6_address(ip_address): sock = ICMPv6Socket() else: sock = ICMPv4Socket() ttl = 1 host_reached = False while not host_reached and ttl <= max_hops: for sequence in range(count): # We create an ICMP request request = ICMPRequest( destination=ip_address, id=id, sequence=sequence, ttl=ttl) try: # We send the request sock.send(request) # We are awaiting receipt of an ICMP reply reply = sock.receive(request, timeout) # We received a reply # We display some information source_name = getfqdn(reply.source) print(f' {ttl:<2} {reply.source:15} ' f'{source_name:40} ', end='') # We throw an exception if it is an ICMP error message reply.raise_for_status() # We reached the destination host # We calculate the round-trip time and we display it round_trip_time = (reply.time - request.time) * 1000 print(round(round_trip_time, 2), 'ms') # We can stop the search host_reached = True break except TimeExceeded as err: # An ICMP Time Exceeded message has been received # The message was probably generated by an intermediate # gateway reply = err.reply # We calculate the round-trip time and we display it round_trip_time = (reply.time - request.time) * 1000 print(round(round_trip_time, 2), 'ms') sleep(interval) break except TimeoutExceeded: # The timeout has been reached and no host or gateway # has responded after multiple attempts if sequence >= count - 1: print(f' {ttl:<2} * * *') except ICMPLibError: # Other errors are ignored pass ttl += 1 print('\nCompleted.')
def do_traceroute( table: Table, address: str, count: int = 2, interval: float = 0.05, timeout: int = 3, id: int = PID, first_hop: int = 1, max_hops: int = 32, source: Optional[str] = None, fast: bool = False, **kwargs, ) -> List[Hop]: """ :param table: rich 动态表格 参数的含义与: `icmplib.traceroute` 保持一致 """ address = resolve(address) address = address[0] if isinstance(address, list) else address sock = ICMPv6Socket(source) if is_ipv6_address(address) else ICMPv4Socket(source) ttl = first_hop host_reached = False hops = [] while not host_reached and ttl <= max_hops: hop_address = None packets_sent = 0 rtts: List[float] = [] for sequence in range(count): request = ICMPRequest( destination=address, id=id, sequence=sequence, ttl=ttl, **kwargs ) reply: Optional[ICMPReply] = None try: sock.send(request) packets_sent += 1 reply = sock.receive(request, timeout) reply.raise_for_status() host_reached = True except TimeExceeded: sleep(interval) except ICMPLibError: continue assert reply is not None hop_address = reply.source round_trip_time = (reply.time - request.time) * 1000 rtts.append(round_trip_time) if fast: break if len(rtts) > 0: hop = Hop( address=hop_address, packets_sent=packets_sent, distance=ttl, rtts=rtts ) hops.append(hop) ip_info = get_ip_info(hop.address) if ip_info is None: position = "" isp = "" else: position = f"{ip_info.country} {ip_info.regionName} {ip_info.city}" isp = f"{ip_info.isp}" table.add_row( f"{hop.address}", # 地址 position, # 位置 isp, # ISP f"{min(hop.rtts):.2f}", # min f"{mean(hop.rtts):.2f}", # avg f"{max(hop.rtts):.2f}", # max ) else: table.add_row("*", "*", "*", "*", "*", "*") ttl += 1 sock.close() return hops
def do_one_ping( host, progress: Progress, cc: Optional[str] = None, seq_offset=0, count=8, interval=0.1, timeout=2, id=PID, source=None, **kwargs, ) -> PingResult: """ :raises NameLookupError: If you pass a hostname or FQDN in parameters and it does not exist or cannot be resolved. :raises SocketPermissionError: If the privileges are insufficient to create the socket. :raises SocketAddressError: If the source address cannot be assigned to the socket. :raises ICMPSocketError: If another error occurs. See the `ICMPv4Socket` or `ICMPv6Socket` class for details. """ address = resolve(host) if isinstance(address, list): address = address[0] log = logging.getLogger("rich") task_id = progress.add_task(host, total=count) # on linux `privileged` must be True if is_ipv6_address(address): sock = ICMPv6Socket(address=source, privileged=True) else: sock = ICMPv4Socket(address=source, privileged=True) times = [] for sequence in range(count): progress.update(task_id, advance=1) request = ICMPRequest( destination=address, id=id, sequence=sequence + seq_offset, **kwargs ) try: sock.send(request) reply = sock.receive(request, timeout) reply.raise_for_status() round_trip_time = (reply.time - request.time) * 1000 times.append(round_trip_time) if sequence < count - 1: sleep(interval) except ICMPLibError as e: log.error(f"接收 {host} Ping 返回信息失败: {e}") progress.remove_task(task_id=task_id) sock.close() log.info(f"{host} Ping 检测已经完成") return PingResult(host=host, cc=cc, count=count, times=times)
def do_traceroute_v2( host: str, count: int = 2, interval: float = 0.05, timeout: int = 3, id: int = PID, first_hop: int = 1, max_hops: int = 32, source: Optional[str] = None, fast: bool = False, **kwargs, ) -> TraceResult: """ :param table: rich 动态表格 参数的含义与: `icmplib.traceroute` 保持一致 """ address = resolve(host) if isinstance(address, list): address = address[0] if is_ipv6_address(address): sock = ICMPv6Socket(source) else: sock = ICMPv4Socket(source) ttl = first_hop host_reached = False hops: List[TraceHop] = [] while not host_reached and ttl <= max_hops: hop_address = None packets_sent = 0 packets_received = 0 times: List[float] = [] for sequence in range(count): request = ICMPRequest(destination=address, id=id, sequence=sequence, ttl=ttl, **kwargs) reply: Optional[ICMPReply] = None try: sock.send(request) packets_sent += 1 reply = sock.receive(request, timeout) reply.raise_for_status() host_reached = True except TimeExceeded: sleep(interval) except ICMPLibError: continue assert reply is not None hop_address = reply.source packets_received += 1 round_trip_time = (reply.time - request.time) * 1000 times.append(round_trip_time) if fast: break if packets_received: ip_info = get_ip_info(hop_address) info = ip_info.dict() if ip_info is not None else dict() hop = TraceHop(ip=hop_address, distance=ttl, count=count, times=times, info=info) hops.append(hop) ttl += 1 sock.close() return TraceResult(results=hops, host=host)
def tracingAlg(address, count=2, interval=0.05, timeout=2, id=PID, #hadi hop1=1, max_hops=17, source=None, fast=False, **kwargs): address = resolve(address) socket = ICMPv4Socket(source)#ICMPv4Socket is a custom socket class #creates a socket(socket.socket(family=socket.AF_INET,type=type,proto=socket.IPPROTO_ICMP)) #it sets for that socket a TTL and checks if broadcast support is enabled on the socket ttl = hop1 dest_reached = False #true when we reach final destination hopsList = []#empty list while not dest_reached and ttl <= max_hops: hop_address = None # adress that the hop reached sentPackets = 0 #number of packets sent to final host recievedPackets = 0 #number of packets recieved by either current or final host #initializing round trip times #min_rtt = float('inf')#minimum round trip time avRTT = 0.0#average round trip time #max_rtt = 0.0#maximum round trip time for sequence in range(count):#for loop to keep varying packets sent req = ICMPRequest( #ICMP echo request #payload size initialized to 56 #ttl initialized to 64 destination=address, id=id, #id of the request(to match reply with request) sequence=sequence, ttl=ttl,#initialized in ICMPRequest to 64 **kwargs)#traffic class try: socket.send(req)#sending request to host #raises errors such as socketunavailable and SocketBroadcastError sentPackets += 1 reply = socket.receive(req, timeout)#listening for the reply of current or final hosts #takes arguement timeout to set a timer in case socket doesn't recieve confirmation reply.raise_for_status()# function to make an exception if reply is not an icmp echo reply dest_reached = True except TimeExceeded:#icmplib error sleep(interval)#wait a given number of seconds except ICMPLibError:#Exception class for the icmplib package. continue hopAddress = reply.source# ip adress of the current or final host recievedPackets += 1 #increment packets recieved round_trip_time = (reply.time - req.time) * 1000# rtt in milliseconds avRTT += round_trip_time #min_rtt = min(round_trip_time, min_rtt) #max_rtt = max(round_trip_time, max_rtt) if fast: break if recievedPackets: avRTT = avRTT/recievedPackets #average rtt currentHop = Hops_Properties(#hop class created to store the properties bellow for every hop address=hopAddress, avRTT=avRTT, packets_sent=sentPackets, packets_received=recievedPackets, distance=ttl) hopsList.append(currentHop)#adding current hop to the list of hops ###################################################### elif recievedPackets==False: currentHop = Hops_Properties(#hop class created to store the properties bellow for every hop address='Not Responding :/', avRTT=avRTT, packets_sent=sentPackets, packets_received=recievedPackets, distance=ttl) hopsList.append(currentHop)#adding current hop to the list of hops ######################################################## ttl += 1#adding hop to reach the next destination socket.close()#closing socket return hopsList