ICMP messages are sent using the basic IP header. The first octet of the data portion of the datagram is a ICMP type field; the value of this field determines the format of the remaining data. Any field labeled "unused" is reserved for later extensions and must be zero when sent, but receivers should not use these fields (except to include them in the checksum). Unless otherwise noted under the individual format descriptions, the values of the internet header fields are as follows:
Version
4
IHL
Internet header length in 32-bit words.
Type of Service
0
Total Length
Length of internet header and data in octets.
Identification, Flags, Fragment Offset
Used in fragmentation, see [1].
Time to Live
Time to live in seconds; as this field is decremented at each machine in which the datagram is processed, the value in this field should be at least as great as the number of gateways which this datagram will traverse.
Protocol
ICMP = 1
Header Checksum
The 16 bit one's complement of the one's complement sum of all 16 bit words in the header. For computing the checksum, the checksum field should be zero. This checksum may be replaced in the future.
Source Address
The address of the gateway or host that composes the ICMP message. Unless otherwise noted, this can be any of a gateway's addresses.
Destination Address
The address of the gateway or host to which the message should be sent.
The source network and address from the original datagram's data.
ICMP Fields:
Type
3
Code
0 = net unreachable;
1 = host unreachable;
2 = protocol unreachable;
3 = port unreachable;
4 = fragmentation needed and DF set;
5 = source route failed.
Checksum
The checksum is the 16-bit ones's complement of the one's complement sum of the ICMP message starting with the ICMP Type. For computing the checksum , the checksum field should be zero. This checksum may be replaced in the future.
Internet Header + 64 bits of Data Datagram
The internet header plus the first 64 bits of the original
datagram's data. This data is used by the host to match the message to the appropriate process. If a higher level protocol uses port numbers, they are assumed to be in the first 64 data bits of the original datagram's data.
Description
If, according to the information in the gateway's routing tables, the network specified in the internet destination field of a datagram is unreachable, e.g., the distance to the network is infinity, the gateway may send a destination unreachable message to the internet source host of the datagram. In addition, in some networks, the gateway may be able to determine if the internet destination host is unreachable. Gateways in these networks may send destination unreachable messages to the source host when the destination host is unreachable.
If, in the destination host, the IP module cannot deliver the datagram because the indicated protocol module or process port is not active, the destination host may send a destination unreachable message to the source host.
Another case is when a datagram must be fragmented to be forwarded by a gateway yet the Don't Fragment flag is on. In this case the gateway must discard the datagram and may return a destination unreachable message.
Codes 0, 1, 4, and 5 may be received from a gateway. Codes 2 and 3 may be received from a host.
这里我们只实现一个简单的ping,所以其他的部分留给感兴趣读者继续阅读RFC文档了
实现
看了上面的信息,我们开始尝试实现结构体:
这是ip的结构体:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
struct ip_struct { /*LITTLE_ENDIAN!!!*/ unsigned char ip_hl:4; unsigned char ip_v:4; unsigned char ip_tos; short ip_len; unsigned short ip_id; short ip_off; unsigned char ip_ttl; unsigned char ip_p; unsigned short ip_sum; struct _in_addr ip_src; struct _in_addr ip_dst;
PING 192.168.1.200 (192.168.1.200) 56(84) bytes of data. 64 bytes from 192.168.1.200: icmp_seq=1 ttl=64 time=0.314 ms 64 bytes from 192.168.1.200: icmp_seq=2 ttl=64 time=0.461 ms 64 bytes from 192.168.1.200: icmp_seq=3 ttl=64 time=0.391 ms 64 bytes from 192.168.1.200: icmp_seq=4 ttl=64 time=0.264 ms