The ping command

Ping, which tests whether another host is reachable, has become a common tool for checking network status.

Common ping commands:

/**** Send a fixed number of packets to the destination ****/ ping -c 3 www.baidu.com // ping Baidu send three packets /**** Set the waiting time between sending packets Ping -i 0.1 www.baidu.com // Interval between two packets 0.1s /**** Check whether the local network interface is up and running ****/ ping 127.0.0.1 (Linux: Ping 0) ping localhost /**** Can be used by super users-fSending hundreds of thousands of packets in seconds strains the main service *****/ sudo ping-fwww.baidu.com /**** Let the computer beep: when the response packet arrives, it sounds ****/ ping-awww.baidu.com /**** Displays only the summary result of ping ****/ ping -c 5 -q www.baidu.com /**** Changes the size of the ping packet (ICMP packet) at www.baidu.com/ping-s 100 -c 5 www.baidu.com




Copy the code

Example:

MacdeiMac :PhoneNetSDK Ethan $ping www.baidu.com ping www.a.shifen.com (61.135.169.121): 56 data bytes 64 bytes from 61.135.169.121: ICmp_seq =0 TTL =49 time=32.559 ms 64 bytes from 61.135.169.121: Icmp_seq =1 TTL =49 time=32.413 ms 64 bytes from 61.135.169.121: Icmp_seq =2 TTL =49 time=32.489 ms ^C -- www.a.shifen.com ping statistics -- 3 packets transmitted, 3 packets received 0.0% packet loss round - trip min/avg/Max/stddev 32.559/0.060 = 32.413/32.487 / ms macdeiMac: PhoneNetSDK Ethan $Copy the code

Analyze the above results:

  • Sender information

    • www.a.shifen.com (61.135.169.121): Automatic DNS resolution is performed for the domain name
    • 56 Data bytes: indicates that data packets with the size of 56 bytes are sent to the host.
  • Host response information

    • Icmp_seq: indicates the sequence number of the response packet.
    • TTL: INDICATES the TTL value of an IP packet.
    • Time: round-trip request time.
    • 64 bytes: The size of the response packet is 64 bytes.
  • Statistical summary information

    • 0.0% Packet loss: Three packets are sent and the packet loss rate is 0%
    • Min/AVg/Max = 32.413/32.487/32.559: Minimum/average/maximum round-trip time 32.413/32.487/32.559

TTL(Time to Live): indicates the TTL of an IP packet. The unit is Hop. For example, the value of 64 is reduced by 1 with each passing router. If the value is reduced to 0, the route is too long and still cannot find the network of the destination host, and the packet is discarded.

Question: when sending a packet, why does the host respond with a packet of 64 bytes when sending a packet of 56 bytes? Are 56 and 64 the same thing here?

icmp

Internet Control Message Protocol (ICMP) is one of the core protocols of the Internet Protocol family. It is a sub-protocol of TCP/IP protocol family. It is used to send control messages in TCP/IP network and provide feedback of various problems that may occur in the communication environment. Through this information, managers can diagnose the problems and then take appropriate measures to solve them.

The control messages are: destination unreachable next time, timeout message, redirection message, timestamp request and timestamp response message, echo request and echo reply message.

ICMP [1] relies on IP to accomplish its tasks and is a major part of IP. It differs significantly from transport protocols such as TCP and UDP: it is generally not used to transfer data between two points. It is usually not used directly by network programs, except in the special cases of ping and Traceroute. ICMP in IPv4 is called ICMPv4, and ICMP in IPv6 is called ICMPv6.

Icmp Technical Details

CMP is one of the family of Internet protocols defined in RFC 792. Usually used to return error messages or analyze routes. ICMP error messages always contain the source data and are returned to the sender. An example of an ICMP error message is when the TTL value expires. When forwarding datagrams, each router reduces the TTL value in the IP packet header by one. If the TTL value is 0, the “TTL expired in transit” message will be returned to the source address. Each ICMP message is wrapped directly in an IP packet, so, like UDP, ICMP is unreliable.

Although ICMP is included in IP packets, ICMP messages are usually treated differently than normal IP packets, rather than as a subprotocol of IP. In many cases, it is necessary to look at the contents of the ICMP message and then send an improper error message to the program that originally generated the IP packet that caused the ICMP message to be transmitted.

Many common tools are based on ICMP messages. Traceroute is achieved by sending a packet that contains a special TTL and then receiving ICMP supersuper messages and destination unreachable messages. Ping is implemented using ICMP Echo Request (category code: 8) and Echo Reply (category code: 0) messages.

Icmp Packet Structure

The header

ICMP headers start at bit 160 of the IP header (IP header 20 bytes)

  • Type: indicates the ICMP Type, which identifies generated error packets
  • Code: This field is used to find the cause of the error. For example, the target unreachable type of ICMP can be set to 1-15 to indicate different meanings.
  • Checksum: The Checksum part. This field contains data calculated from the ICMP header and data section to check for errors. The value of this Checksum field is 0
  • ID: This field contains the ID value inEcho ReplyType of message to return this field
  • Sequence: This field contains an ordinal number, also in theEcho ReplyType of message to return this field

Fill in the data

The data is populated immediately after the ICMP header (in groups of 8 bits) :

  • The Linux ping tool populates ICMP in addition to the eight 8-bit headers, and by default populates additional data to a total size of 64 bytes.
  • Windows ping.exe populates ICMP in addition to the eight 8-bit headers, and by default populates additional data to make the total size bit 40 bytes.

ping

Ping Implementation Principle

Ping, which tests whether another host is reachable, has become a common tool for checking network status. The program sends an ICMP echo request to the remote host and waits for an ICMP echo reply.

Ping uses the ICMP protocol and sends an ICMP echo request message to the destination host. ICMP: The destination host must return an ICMP reply message to the source host. If the source host receives a reply within a certain amount of time, the host is considered reachable. Most TCP/IP implementations directly support the Ping server in the kernel. The following figure shows the ICMP request and reply packets.

How ping works:

Ping sends an ICMP request with type code 8, and the host that receives the request responds with type code 0. You can determine the current network status by calculating the number of ICMP reply packets and the time difference between receiving and sending packets. The round-trip time is calculated as follows: When the ping command sends an ICMP packet, the current time value is stored in the ICMP packet. When the reply packet returns, the current time value is deducted from the time value stored in the ICMP packet data to calculate the round-trip time. Ping Returns the received data packet size, TTL value, and round trip time.

Use the Wireshark to view ping information

I ping www.baidu.com from the command line and the following is the result:

As shown in the figure above, the ICMP packet type is 8, which is a request request. The packet type of ICMP is 0 and is reply.

Basic knowledge of computer network

TCP/IP protocol stack and packet encapsulation

OSI seven-layer model and TCP/IP model:

The communication process between two computers through TCP/IP is as follows:

The transport layer and its underlying mechanisms are provided by the kernel, the application layer is provided by the user process, the application program interprets the meaning of the communication data, and the transport layer and its underlying mechanisms handle the details of the communication, sending the data from one computer to another through a certain path. When application layer data is sent to the network through the protocol stack, a data header is added to each layer protocol, which is called Encapsulation.

TCP/IP packet encapsulation:

After receiving the packet, the destination host passes through each layer protocol stack and finally reaches the application program.

The Ethernet driver determines whether the payload of the data frame is an IP, ARP, or RARP datagram according to the Upper Layer Protocol field in the Ethernet header, and then submits the payload to the corresponding protocol. If the packet is an IP packet, the IP protocol determines whether the payload of the packet is TCP, UDP, ICMP, or IGMP based on the Upper-layer Protocol field in the IP header, and then sends the packet to the corresponding protocol for processing. In the case of TCP or UDP, TCP or UDP determines the user process to which the application-layer data should be sent based on the port number field in the TCP header or UDP header. An IP address is an ADDRESS that identifies different hosts on the network, and a port number is an address that identifies different processes on the same host. The IP address and port number together identify unique processes on the network.

Note that although IP, ARP, and RARP datagrams all require Ethernet drivers to encapsulate them into frames, FUNCtionally ARP and RARP belong to the link layer and IP belongs to the network layer. Although ICMP, IGMP, TCP, and UDP data are encapsulated into datagrams by IP protocol, ICMP, IGMP, and IP belong to the network layer, while TCP and UDP belong to the transport layer.

IP datagram format

IPv4 packets are in the following format:

About the length of the bow:

Determine whether the current packet is IPv4 based on the IP datagram

Version contains 4 bits and the header length contains 4 bits. Version = 4(IPv4) and IPheader =20. Because the header length is 4 bytes -> version: 0100; Version: 0100 0101&0xfo (11110000) = 01000000 = 0x40 0100 0101&0x0F (00001111) = 0000 0101 = 5 4 bytes = 20 bytesCopy the code

Ping (c + + & oc)

Technical pre-research and conception

Based on the results of ping, we need to solve the following problems:

MacdeiMac :PhoneNetSDK Ethan $ping www.baidu.com ping www.a.shifen.com (61.135.169.121): 56 data bytes 64 bytes from 61.135.169.121: ICmp_seq =0 TTL =49 time=32.559 ms 64 bytes from 61.135.169.121: Icmp_seq =1 TTL =49 time=32.413 ms 64 bytes from 61.135.169.121: Icmp_seq =2 TTL =49 time=32.489 ms ^C -- www.a.shifen.com ping statistics -- 3 packets transmitted, 3 packets received 0.0% packet loss round - trip min/avg/Max/stddev 32.559/0.060 = 32.413/32.487 / ms macdeiMac: PhoneNetSDK Ethan $Copy the code
  • DNS resolution (domain name -> IP)
  • Indicates the host from which each ICMP packet received by the local terminal is sent
  • icmp_seq
  • ttl
  • time

Solutions to the above problems are as follows:

  • DNS resolution: Socket support
  • Host from which each ICMP packet is received by the local terminal: Source in the IP packet
  • Icmp_seq: sequence number in icmp packets
  • TTL: Time to live in an IP packet
  • Time: indicates the time difference between sending and receiving packets

The specific implementation

IP packet definition:

typedef struct PNetIPHeader {
    uint8_t versionAndHeaderLength;
    uint8_t differentiatedServices;
    uint16_t totalLength;
    uint16_t identification;
    uint16_t flagsAndFragmentOffset;
    uint8_t timeToLive;
    uint8_t protocol;
    uint16_t headerChecksum;
    uint8_t sourceAddress[4];
    uint8_t destinationAddress[4];
    // options...
    // data...
}PNetIPHeader;
Copy the code

ICMP packet definition:

/*
 use linux style . totals 64B
 */
typedef struct UICMPPacket
{
    uint8_t type;
    uint8_t code;
    uint16_t checksum;
    uint16_t identifier;
    uint16_t seq;
    char fills[56];  // data
}UICMPPacket;
Copy the code

Constructing ICMP packets:

+ (UICMPPacket *)constructPacketWithSeq:(uint16_t)seq andIdentifier:(uint16_t)identifier
{
    UICMPPacket *packet = (UICMPPacket *)malloc(sizeof(UICMPPacket));
    packet->type  = ENU_U_ICMPType_EchoRequest;
    packet->code = 0;
    packet->checksum = 0;
    packet->identifier = OSSwapHostToBigInt16(identifier);
    packet->seq = OSSwapHostToBigInt16(seq);
    memset(packet->fills, 65, 56);
    packet->checksum = [self in_cksumWithBuffer:packet andSize:sizeof(UICMPPacket)];
    return packet;
}
Copy the code

Sending ICMP packets:

 UICMPPacket *packet = [PhoneNetDiagnosisHelper constructPacketWithSeq:index andIdentifier:identifier];
        _sendDate = [NSDate date];
        ssize_t sent = sendto(socket_client, packet, sizeof(UICMPPacket), 0, (struct sockaddr *)&remote_addr, (socklen_t)sizeof(struct sockaddr));
        if (sent < 0) {
            log4cplus_warn("PhoneNetPing"."ping %s , send icmp packet error.. \n",[self.host UTF8String]);
        }
Copy the code

Receiving ICMP packets:

 size_t bytesRead = recvfrom(socket_client, buffer, 65535, 0, (struct sockaddr *)&ret_addr, &addrLen);
  if ((int)bytesRead < 0) {
            [self reporterPingResWithSorceIp:self.host ttl:0 timeMillSecond:0 seq:0 icmpId:0 dataSize:0 pingStatus:PhoneNetPingStatusDidTimeout];
            res = YES;
        }else if(bytesRead == 0){
            log4cplus_warn("PhoneNetPing"."ping %s , receive icmp packet error , bytesRead=0",[self.host UTF8String]);
        }else{
            
            if ([PhoneNetDiagnosisHelper isValidPingResponseWithBuffer:(char *)buffer len:(int)bytesRead]) {
                
                UICMPPacket *icmpPtr = (UICMPPacket *)[PhoneNetDiagnosisHelper icmpInpacket:(char *)buffer andLen:(int)bytesRead];
                
                int seq = OSSwapBigToHostInt16(icmpPtr->seq);
                
                NSTimeInterval duration = [[NSDate date] timeIntervalSinceDate:_sendDate];
                
                int ttl = ((PNetIPHeader *)buffer)->timeToLive;
                int size = (int)(bytesRead-sizeof(PNetIPHeader));
                NSString *sorceIp = self.host;
                
                
//                NSLog(@"PhoneNetPing, ping %@ , receive icmp packet.. \n",self.host );
                [self reporterPingResWithSorceIp:sorceIp  ttl:ttl timeMillSecond:duration*1000 seq:seq icmpId:OSSwapBigToHostInt16(icmpPtr->identifier) dataSize:size pingStatus:PhoneNetPingStatusDidReceivePacket];
                res = YES;
            }
Copy the code

Separating ICMP packets from the received buffer:

*/ + (char *)icmpInpacket:(char *)packet andLen:(int)len {if (len < (sizeof(PNetIPHeader) + sizeof(UICMPPacket))) {
        return NULL;
    }
    const struct PNetIPHeader *ipPtr = (const PNetIPHeader *)packet;
    if((ipPtr->versionAndHeaderLength & 0xF0) ! = 0x40 // IPv4 || ipPtr->protocol ! = 1) { //ICMPreturn NULL;
    }
    size_t ipHeaderLength = (ipPtr->versionAndHeaderLength & 0x0F) * sizeof(uint32_t);
    
    if (len < ipHeaderLength + sizeof(UICMPPacket)) {
        return NULL;
    }
    
    return (char *)packet + ipHeaderLength;
}
Copy the code

Verify the received ICMP packet:

+ (BOOL)isValidPingResponseWithBuffer:(char *)buffer len:(int)len
{
    UICMPPacket *icmpPtr = (UICMPPacket *)[self icmpInpacket:buffer andLen:len];
    if (icmpPtr == NULL) {
        return NO;
    }
    uint16_t receivedChecksum = icmpPtr->checksum;
    icmpPtr->checksum = 0;
    uint16_t calculatedChecksum = [self in_cksumWithBuffer:icmpPtr andSize:len-((char*)icmpPtr - buffer)];
    
    return receivedChecksum == calculatedChecksum &&
    icmpPtr->type == ENU_U_ICMPType_EchoReplay &&
    icmpPtr->code == 0 &&
    OSSwapBigToHostInt16(icmpPtr->identifier)>=KPingIcmpIdBeginNum;;
}
Copy the code

TCP ping

If the ping function is disabled on some servers, select TCP ping.

TCP ping principle

The connection time is calculated by establishing a TCP connection with the destination host and its port.

traceroute

Traceroute command

/**** Set the number of packets to be sent by each route ****/ traceroute -q 5 baidu.com /**** Set the maximum number of hops ****/ traceroute -m 5 baidu.com /**** Do not perform DNS resolution for ****/ Traceroute -n baidu.com /**** Bypass the routing table and send the packet to the destination fixture ****/ traceroute -r baidu.com /****. Use ICMP packets instead of UDP packets ****/ traceroute -i baidu.comCopy the code

Traceroute principle

Tacceroute does this by increasing the TTL value. Each time an ICMP packet passes through a router, the TTL value decreases by 1. When the TTL reaches 0, the router cancels the packet sending and sends an ICMP TTL packet to the originator.

Traceroute process

The calling party first sends the packet with TTL = 1. After the first router reduces the TTL by 1 to get 0, it no longer forwards the packet but returns an ICMP timeout packet. The calling party can extract the address of the first router through which the packet passes from the hypertime packet. Then it sends an ICMP packet with TTL=2 to obtain the address of the second router. By increasing the TTL in turn, it obtains the bit addresses of all routers along the way.

Note that not all routers faithfully return ICMP timeout packets. For security purposes, most firewalls and routers with the firewall function enabled are configured not to return ICMP packets by default. The administrator can modify the configurations of routers or switches to not return ICMP packets. Therefore, the Traceroute program may not be able to pick up all the router addresses along the route. Therefore, when the packet with a TTL value can not get a response, it cannot stop the tracking process, and the program will still increase the TTL and send the next packet. Tracing does not end until a preset or parameter setting tracing limit is reached.

According to the above principle, the Traceroute program using UDP packets may simply discard the packets when they reach the real destination host because the host does not provide UDP services. To solve this problem, Traceroute deliberately uses a port number greater than 30,000. Because UDP requires a port number smaller than 30,000, the only thing the destination host can do after receiving the packet is to return an ICMP message indicating that the port is unreachable. Therefore, the calling party regards the port unreachable packet as the end of tracing.

Use Wireshark to view Traceroute

I traceroute www.baidu.com on the command line and here is the result:

As shown in the figure above, for UDP requests, the port number for the first request is 33435, and for subsequent UDP requests, the port number increases.

When the destination address is reached, the destination address replay packets of type 3.

As shown in the figure above, it is an ICMP packet returned by the router with type 11.

UDP Traceroute implementation

Sends UDP packets, receives IP and ICMP packets, and filters the route IP calculation time.

Github.com/mediaios/ne…

UDP Traceroute has problems

With UDP Traceroute, failures are relatively common. This is often due to the fact that UDP and ICMP are treated very differently on carrier routers. ICMP Request and replay are not sealed for troubleshooting, whereas UDP is different. UDP is often used for network attacks. Because UDP does not require connection, it is not restricted by any state. Therefore, it is convenient for attackers to forge source IP addresses and destination ports and send UDP packets of any length. To ensure security, carriers use whitelisted ACLs for UDP ports. That is, only the ports that are allowed by the ACL can pass through UDP ports, and those that are not explicitly allowed are discarded. For example, DNS, DHCP, and SNMP are allowed.

icmp traceroute

Icmp packets of type 8 are sent. Each route returns icmp timeout packets of type 11. When the destination IP address is replayed, the destination IP address replay packets of type 0

Icmp Traceroute implementation

Github.com/mediaios/ne…

Net-diagnosis (Ios Network Diagnosis SDK)

Net-diagnosis is an ios network diagnosis SDK that provides the following functions:

  • ping
  • tcp ping
  • traceroute
  • icmp traceroute
  • nslookup
  • port scan

Project address: Github

In the future, more functions about network diagnosis will be continuously developed and improved. Welcome to submit the issue

Also, welcome fork and Star!