Most programmers have two types of sockets:
(1) stream socket (sock_stream): a connection-oriented socket for connection-oriented TCP Service applications;
(2) datagram socket (sock_dgram): a connectionless socket that corresponds to a connectionless UDP Service Application.
From the user's point of view, the sockets sock_stream and sock_dgram seem to cover all TCP/IP applications, because TCP/IP-based applications, at the protocol stack level, the transport layer can only be established over TCP or UDP (Figure 1), while sock_stream and sock_dgram correspond to TCP and UDP respectively, therefore, almost all applications can be implemented using these two types of sockets.
Figure 1 TCP/IP protocol stack |
However, when we are faced with the following problems, sock_stream and sock_dgram will look so helpless:
(1) how to send a custom IP package?
(2) how to send an ICMP protocol packet?
(3) How can I enable the local machine to enter the hybrid mode to enable network sniffer?
(4) how to analyze all packets passing through the network, regardless of whether the packets are sent to you?
(5) How to disguise a local IP address?
This makes us have to face another profound topic-raw socket ). Raw socket is widely used in advanced network programming and is also a widely used hacker. The well-known network sniffer, DOS, and IP spoofing can all be implemented using raw socket.
The difference between raw socket and standard socket (sock_stream and sock_dgram) is that the former directly sets "root" to the network core of the operating system ), sock_stream and sock_dgram are "suspended" outside TCP and UDP protocols, as shown in Figure 2:
Figure 2 raw socket and standard socket |
When we use raw socket, we can completely customize the IP package, and all forms of packages can be "manufactured. Therefore, this article must first explain the IP packet structure involved in TCP/IP.
Currently, the IPv4 header structure is:
Version (4) |
Header Length (4) |
Service type (8) |
Packet Length (16) |
ID (16) |
Offset (16) |
Survival time (8) |
Transmission Protocol (8) |
Checksum (16) |
Source Address (32) |
|
Destination Address (32) |
|
Option (8) |
......... |
Fill |
Encapsulate the data structure:
Typedef struct _ iphdr // defines the IP Header { Unsigned char h_lenver; // 4-bit Header Length + 4-bit IP version number Unsigned char TOS; // an 8-bit service type TOS Unsigned short total_len; // The total length of 16 bits (in bytes) Unsigned short ident; // 16-bit ID Unsigned short frag_and_flags; // 3-Bit Flag Unsigned char TTL; // 8-bit TTL Unsigned char proto; // 8-bit protocol (TCP, UDP, or other) Unsigned short checksum; // 16-bit IP header checksum Unsigned int sourceip; // 32-bit source IP address Unsigned int destip; // 32-bit destination IP address } Ip_header; |
Or split the first byte in the preceding definition by bit:
Typedef struct _ iphdr // defines the IP Header { Unsigned char h_len: 4; // 4-bit Header Length Unsigned char Ver: 4; // 4-bit IP version Unsigned char TOS; Unsigned short total_len; Unsigned short ident; Unsigned short frag_and_flags; Unsigned char TTL; Unsigned char proto; Unsigned short checksum; Unsigned int sourceip; Unsigned int destip; } Ip_header; |
Strictly speaking, the memory storage sequence of the h_len and Ver fields in the above definition is also related to the endian of the Specific CPU. Therefore, the stricter ip_header can be defined:
Typedef struct _ iphdr // defines the IP Header { # If defined (_ little_endian_bitfield) Unsigned char h_len: 4; // 4-bit Header Length Unsigned char Ver: 4; // 4-bit IP version # Elif defined (_ big_endian_bitfield) Unsigned char Ver: 4; // 4-bit IP version Unsigned char h_len: 4; // 4-bit Header Length # Endif Unsigned char TOS; Unsigned short total_len; Unsigned short ident; Unsigned short frag_and_flags; Unsigned char TTL; Unsigned char proto; Unsigned short checksum; Unsigned int sourceip; Unsigned int destip; } Ip_header; |
The TCP Header structure is:
Source Port (16) |
Destination Port (16) |
Serial number (32) |
Confirmation No. (32) |
TCP offset (4) |
Reserved (6) |
Logo (6) |
Window (16) |
Checksum (16) |
Emergency (16) |
Option (0 or 32) |
Data (variable) |
Corresponding data structure:
Typedef struct psd_hdr // defines the TCP pseudo-Report Header { Unsigned long saddr; // Source Address Unsigned long daddr; // Destination Address Char mbz; Char ptcl; // protocol type Unsigned short tcpl; // TCP Length } Psd_header; Typedef struct _ tcphdr // defines the TCP Header { Unsigned short th_sport; // 16-bit Source Port Unsigned short th_dport; // 16-bit destination port Unsigned int th_seq; // 32-bit serial number Unsigned int th_ack; // 32-bit confirmation number Unsigned char th_lenres; // 4-bit header length/4-bit reserved words Unsigned char th_flag; // 6-digit flag Unsigned short th_win; // 16-bit window size Unsigned short th_sum; // 16-bit checksum Unsigned short th_urp; // 16-bit emergency data offset } Tcp_header; |
Similarly, the TCP header definition can also split bit fields:
Typedef struct _ tcphdr { Unsigned short th_sport; Unsigned short th_dport; Unsigned int th_seq; Unsigned int th_ack; /* Little-Endian */ Unsigned short tcp_res1: 4, tcp_hlen: 4, tcp_fin: 1, tcp_syn: 1, tcp_rst: 1, latency: 1, tcp_ack: 1, tcp_urg: 1, tcp_res2: 2; Unsigned short th_win; Unsigned short th_sum; Unsigned short th_urp; } Tcp_header; |
UDP header:
Source Port (16) |
Destination Port (16) |
Packet Length (16) |
Checksum (16) |
The corresponding data structure is:
Typedef struct _ udphdr // defines the UDP Header { Unsigned short uh_sport; // 16-bit Source Port Unsigned short uh_dport; // 16-bit destination port Unsigned short uh_len; // 16-Bit Length Unsigned short uh_sum; // 16-bit checksum } Udp_header; |
ICMP is a very important protocol in the network layer. It is called Internet Control Message Protocol (Internet Control Message Protocol). ICMP makes up for the IP address shortage, it uses the IP protocol for information transmission and provides error information feedback at the network layer to the source node of the data packet. ICMP header:
Type (8) |
Code (8) |
Checksum (16) |
Message Content |
The data structure of the commonly used ICMP message is as follows:
Typedef struct _ icmphdr // defines the ICMP header (send back and or send back response) { Unsigned char I _type; // 8-bit type Unsigned char I _code; // 8-bit code Unsigned short I _cksum; // 16-bit checksum Unsigned short I _id; // identification number (process number is generally used as the identification number) Unsigned short I _seq; // message serial number Unsigned int timestamp; // Timestamp } Icmp_header; |
Common ICMP messages include echo-request, echo-reply, Destination Unreachable, and time exceeded) parameter problems, source quenchs, redirects, timestamps, and timestamp replies) address masks (Address Mask Request Message) and address mask replies (Address Mask Response Message) are important messages on the Internet. The ping commands, ICMP denial-of-service attacks, and route spoofing mentioned in later sections are closely related to the ICMP protocol.
In addition, part of the source code in this series references some open-source projects of excellent programmers. We cannot list them one by one due to the length of the article. I would like to express my gratitude here.
So, let's go.