Explanation of phdr and tcphdr (skb_header_pointer Function Analysis)

Source: Internet
Author: User

Obtain TCP information under Linux 2.6.26:
Tcph = skb_header_pointer (SKB, protoff, sizeof (tcph), & tcph); // skb_header_pointer is a library function
Skb_header_pointer Function
This function is simple and defined as follows:
/* # Include <Linux/skbuff. h> */
Static inline void * skb_header_pointer (const struct sk_buff * SKB, int offset, int Len, void * buffer)
{
Int hlen = skb_headlen (SKB );
If (hlen-Offset> = Len)
Return SKB-> Data + offset;
If (skb_copy_bits (SKB, offset, buffer, Len) <0)
Return NULL;
Return buffer;
}
The parameters are as follows:
SKB: pointer of the data packet struct sk_buff
Offset: the offset relative to the starting data header (such as the IP header)
Len: Data Length
Buffer: buffer, not smaller than Len

Skb_headlen () is defined:
/* # Include <Linux/skbuff. h> */
Static inline unsigned int skb_headlen (const struct sk_buff * SKB)
{
Return SKB-> len-SKB-> data_len;
}
SKB-> Len indicates the packet length. In IPv4, it indicates the total length of a single complete IP packet. However, these data are not necessarily on the current Memory Page; SKB-> data_len indicates the Data Length on other pages, so SKB-> len-SKB-> data_len indicates the data size on the current page.

/* Net/CORE/skbuff. C */
/* Copy some data bits from SKB to kernel buffer .*/
Int skb_copy_bits (const struct sk_buff * SKB, int offset, void * To, int Len)
{
Int I, copy;
Int start = skb_headlen (SKB );
If (Offset> (INT) SKB-> len-len)
Goto fault;
/* Copy header .*/
If (copy = start-offset)> 0 ){
// Copy the part on the current page
If (copy> Len)
Copy = Len;
Memcpy (to, SKB-> Data + offset, copy );
If (LEN-= copy) = 0)
Return 0;
Offset + = copy;
To + = copy;
}
// Copy other parts of this SKB
For (I = 0; I <skb_shinfo (SKB)-> nr_frags; I ++ ){
Int end;
Bug_trap (start <= offset + Len );
End = start + skb_shinfo (SKB)-> frags [I]. size;
If (copy = end-offset)> 0 ){
U8 * vaddr;
If (copy> Len)
Copy = Len;
Vaddr = kmap_skb_frag (& skb_shinfo (SKB)-> frags [I]);
Memcpy (,
Vaddr + skb_shinfo (SKB)-> frags [I]. page_offset +
Offset-start, copy );
Kunmap_skb_frag (vaddr );
If (LEN-= copy) = 0)
Return 0;
Offset + = copy;
To + = copy;
}
Start = end;
}
// Copy the data part of another shard SKB
If (skb_shinfo (SKB)-> frag_list ){
Struct sk_buff * List = skb_shinfo (SKB)-> frag_list;
For (; List = List-> next ){
Int end;
Bug_trap (start <= offset + Len );
End = start + list-> Len;
If (copy = end-offset)> 0 ){
If (copy> Len)
Copy = Len;
If (skb_copy_bits (list, offset-start,
To, copy ))
Goto fault;
If (LEN-= copy) = 0)
Return 0;
Offset + = copy;
To + = copy;
}
Start = end;
}
}
If (! Len)
Return 0;
Fault:
Return-efault;
}

Detailed description of the iphdr structure:
Include <Linux/IP. h>
Struct iphdr {
# If defined (_ little_endian_bitfield)
_ U8 IHL: 4,
Version: 4;
# Elif defined (_ big_endian_bitfield)
_ U8 version: 4,
IHL: 4;
# Else
# Error "Please fix"
# Endif
_ U8 TOS;
_ Be16-tot_len;
_ Be16-ID;
_ Be16-frag_off;
_ U8 TTL;
_ U8 protocol;
_ Be16-check;
_ Be32-saddr;
_ Be32-daddr;
};

IPhone dr-> Version
Version (4 bits). The current Protocol version is 4, so the IP address is also called IPv4.
IPhone dr-> IHL
Header Length (4 bits): the header length refers to the number of 32 bits in the IP layer header (that is, the number of 4-32 bits in the IP layer header ), includes any options. Because it is a 4-bit field, the unit is 4 bytes, so the length of an IP header is up to 1111, that is, 15*4 = 60 bytes, therefore, the header cannot exceed 60 bytes. The value of the common IP datagram (no choice) field is 5 5*32/8 = 5*4 = 20 bytes.
IPhone dr-> TOS
Service type field (8 bits): the service type field (ToS) includes a 3-bit priority subfield (ignored now ), the 4-bit TOS subfield and the 1-bit unused bit must be set to 0. The 4-bit sub-field of TOS represents the minimum latency, maximum throughput, maximum reliability, and minimum cost. Only 1 bit can be set in 4 bits. If all 4 bits are 0, it means a General Service.
Example:
The meaning of the 8 bits is:
000 first three
0 indicates the minimum latency. If the telnet service uses this bit
0 indicates the throughput. If the FTP service uses this bit
0 indicates reliability. For example, this bit is used by the SNMP service.
0 indicates the minimum cost.
0 No
Iphdr-> tot_len
The total length field (16 bits) refers to the length of the entire IP datagram, in bytes. By using the header length field and the total length field, you can know the start position and length of the data content in the IP datagram. Because this field is 16 bits long (the maximum length of an IP packet is 2 to the power of 16 minus 1, that is, 65535 bytes ), therefore, the maximum IP data packet that can be transmitted over Ethernet is 65535 bytes. The total length field is necessary in the IP header, because some data links (such as Ethernet) need to fill in some data to reach the minimum length. Although the minimum frame length of Ethernet is 46 bytes, the IP data may be shorter. If there is no total length field, the IP layer does not know how many of the 46 bytes are IP datagram content.
IPhone dr-> ID
The ID field (16 bits) uniquely identifies each datagram sent by the host. Generally, the value of each sent packet is increased by 1. (For example, identification = 363 indicates that the IP package identification number is 363. This part occupies 16 bits, expressed in decimal number .) The frag_off (16-bit) frag_off field specifies the position of the segment in the current datagram. Except for the last part of a datagram, all parts must be multiples of 8 bytes. This is an 8-byte basic unit of segmentation. Because this field has 13 digits, each datagram has a maximum of 8192 segments. Therefore, the maximum datagram length is 65,536 bytes, which is 1 larger than that of the iphdr-> tot_len domain. The height of iPhone dr-> frag_off:
(1) Bit 0 is reserved and must be 0;
(2) bit 1 indicates "more fragments" (MF-More Fragment. Except for the last piece, the bit must be set to 1 for each piece of data.
(3) Bit 2 is the DF-Don't fragment mark. If you set this bit to 1, the IP address will not partition the datagram, if a part-based datagram arrives, the datagram is discarded and an ICMP error message is sent to the start end.
Iphdr-> TTL
TTL (time-to-live)-8 bits. The TTL field sets the maximum number of routers that can pass through the datagram. It specifies the survival time of the datagram. The initial value of TTL is set by the source host (usually 32 or 64). Once a router processes it, its value is equal to 1. When the value of this field is 0, the datagram is discarded and an ICMP message is sent to the source host. The TTL (time to live) domain is a counter used to limit the lifetime of a group. The count time is measured in seconds, so the maximum lifetime is 255 seconds. In each hop, the counter must be decreased. In addition, when the datagram queue time on a vro is long, the counter must be decreased multiple times. In practice, it is only a hop counter. When it decreases to 0, the group is discarded, and the router sends a warning group to the source host. This feature prevents the datagram from staying in the network for a long time. Sometimes, when the route table is damaged, this kind of thing may happen.
Iphdr-> Protocol
Protocol field (8 bits): identifies which Protocol transmits data to an IP address. After the network layer assembles a complete datagram, it needs to know how to process it. The protocol field specifies the transfer process to which it is handed over. TCP is a possibility, but UDP or other protocols are also possible. Proctol = 6 (TCP) indicates that the protocol type is TCP and the protocol code is 6. For UDP protocol, the protocol code here should be 17. For ICMP protocol, the protocol code here should be 1. This part occupies 8 bits. (Ipproto_tcp, ipproto_udp, ipproto_icmp etc .)
IPhone dr-> check
The header check field (16 bits) is the verification code calculated based on the IP header. It does not calculate the data after the header. ICMP, IGMP, UDP, and TCP contain both header and data verification code in their respective headers. In order to calculate the IP address check of a datagram, the test field is set to 0. Then, calculate the binary inverse sum of each 16 bit in the header (the whole header is regarded as composed of a string of 16 bit characters), and the result is included in the test field. After receiving an IP datagram, the system also sums each 16 bit in the header with a binary inverse code. Because the receiver contains a checksum in the sender's header during the computation process, if the header has no errors during transmission, the receiver's computation result should be 1 in total. If the result is not all 1 (namely, check and error), the IP address discards the received datagram. However, no error messages are generated. The upper layer discovers the lost data packets and re-transmits them.
IPhone dr-> saddr
32-bit source IP address
Iphdr-> daddr
32-bit destination IP address
Network byte order
The 32-bit values of four bytes are transmitted in the following order: the first is 0 ~ 7 bit, followed by 8 ~ 15bit, then 16 ~ 23bit, last 24 ~ 31 bit. This transmission order is called the Big endian byte order. Because all the binary integers in the TCP/IP Header must be transmitted in this order, it is also called the network byte order.

Tcphdr structure details:
Sk_buff-> tcphdr
/Usr/src/linux-2.6.19/include/Linux/tcp. h
Struct tcphdr {
_ Be16 source;
_ Be16 DEST;
_ Be32 seq;
_ Be32 ack_seq;
# If defined (_ little_endian_bitfield)
_ 2010res1: 4,
Doff: 4,
Fin: 1,
SYN: 1,
RST: 1,
Psh: 1,
Ack: 1,
URG: 1,
ECE: 1,
CWR: 1;
# Elif defined (_ big_endian_bitfield)
_ 2010doff: 4,
RES1: 4,
CWR: 1,
ECE: 1,
URG: 1,
Ack: 1,
Psh: 1,
RST: 1,
SYN: 1,
Fin: 1;
# Else
# Error "adjust your <ASM/byteorder. h> defines"
# Endif
_ Be16 window;
_ Be16 check;
_ Be16 urg_ptr;
};
| ---------------- | -------------
| Source | DEST |
| ---------------- |
| Seq |
| --------------------------------- |
| Ack_seq | 20 bytes
| ---- | ------ | ---------------- |
| Doff | res1 | window |
| ---- | ------ | ---------------- |
| Check | urg_ptr |
| ---------------- | -------------
| Options | 4 bytes
| --------------------------------- |

TCP Header
Tcphdr-> Source
16-bit source port number
Tcphdr-> dest
16-bit destination port number
Tcphdr-> seq
Indicates the number of starting bytes of the data sent this time in the entire packet segment. The serial number is a 32-bit unsigned number. For the sake of security, its initial value is a randomly generated number. After it reaches the 32-bit maximum value, it starts from scratch.
Tcphdr-> ack_seq
Specify the next expected byte instead of the last byte that has been correctly received.
Tcphdr-> doff
The length of the TCP Header, indicating the number of 32 characters contained in the TCP header. This information is required, because the length of the options field is variable, so the length of the entire TCP header is also changed. Technically speaking, this domain actually specifies the starting address of the Data part within the segment (measured in 32-bit characters ), because the value is exactly the length of the TCP Header in the unit of words, the effect of the two is equivalent.
Tcphdr-> RES1 is reserved
Tcphdr-> window
It is the size of the 16-bit sliding window, in bytes. It starts with the value specified in the confirm serial number field. This value is the number of bytes that are expected to be received correctly, and its maximum value is 63353 bytes.
Traffic Control in TCP is implemented through a sliding window of a variable size. The window field specifies the number of bytes that can be received from the confirmed bytes. Window = 0 is also legal, which is equivalent to saying that up to ack_seq-1 bytes have been received so far, but the recipient is in poor state now, you need to take a break, wait for a while before receiving more data. Later, the receiver can send a data segment with the same ack_seq but not 0 in the window, telling the sender to continue sending the data segment.
Tcphdr-> check
This is a mandatory field that covers the entire TCP packet segment. It must be calculated and stored by the sending end and verified by the receiving end.
Tcphdr-> urg_ptr
This field is used to indicate the location of the emergency data in the current data segment. It is a byte offset value relative to the current serial number. This facility can replace the interrupt information.

Fin, Syn, RST, Psh, ack, and URG are 6 flags.
These six fields have been retained for more than 1/4 centuries and remain intact. This fact also shows how thoughtful TCP designers are considering. Their meanings are as follows:
Tcphdr-> finThe fin bit is used to release a connection. It indicates that the sender has no data to transmit.
Tcphdr-> SYNSynchronization sequence number, used to initiate a connection. SYN bit is used to establish a connection. In the connection request, SYN = 1; ACK = 0 indicates that the data segment does not use the validation domain of the bandwidth. The connection response token carries a confirmation, So SYN = 1; ACK = 1. In essence, Syn bits are used to indicate connection request and connection accepted. However, Ack bits are further used to distinguish the two cases.
Tcphdr-> RSTThis is used to reset a chaotic connection. The reason for this confusion may be due to host crash or other reasons. This bit can also be used to reject an invalid data segment or a connection request. Generally, if you have set the RST bit for the data segment, it indicates that you have a problem at this end.
Tcphdr-> PSHThe recipient should request to submit the data to the application immediately after receiving the data, instead of buffering it until the entire buffer zone is fully received (this may be due to efficiency)
Tcphdr-> ACKIf the ACK bit is set to 1, tcphdr-> ack_seq is valid. If Ack is 0, the data segment does not contain the validation message. Therefore, the tcphdr-> ack_seq field should be ignored.
Tcphdr-> URGValid emergency pointers
Tcphdr-> ECEUsage unknown
Tcphdr-> CWRUsage unknown
The kernel source code is used to create a TCP header in the tcp_transmit_skb () function.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.