The original socket programming of sock_raw can receive data frames or data packets on the local Nic, which is very useful for the traffic and Analysis of the listener network. there are three ways to create this socket. socket (af_inet, sock_raw, ipproto_tcp | ipproto_udp | ipproto_icmp) sends and receives IP data packets. socket (pf_packet, sock_raw, htons (eth_p_ip | eth_p_arp | eth_p_all) sends and receives Ethernet data frames. socket (af_inet, sock_packet, htons (eth_p_ip | eth_p_arp | eth_p_all) is out of date. Do not use it to understand the principle of sock_raw, for example, the network adapter receives a UDP Ethernet data frame of 14 + 20 + 8 + 100 + 4. first, the NIC performs a hard filter on the data frame (depending on the NIC mode, there will be different actions. If promisc hybrid mode is set, no filtering will be performed and it will be handed over to the next input routine, otherwise, non-local Mac or broadcast MAC will be directly discarded ). according to the above example, if the input is successful, the IP address input routine will be entered. however, before entering the IP input routine, the system will check whether socket (af_packet, sock_raw,...) is used in the system ,..) the socket. if yes and the Protocol is consistent, the eth_p_ip or eth_p_all type is required in this example. the system sends a data frame copy to each socket receiving buffer. then proceed to the next step. next, enter the IP input routine (the IP layer performs soft filtering on this packet, that is, checks and verifies or discards packets other than the local IP address or broadcast IP address. For details, refer to the source code ), in this example, if the input is successful, the UDP input routine will be entered. however, before being handed over to the UDP input routine, the system checks whether socket (af_inet, sock_raw,...) is used in the system ,..) the socket. if the protocol is correct, ipproto_udp is required in this example. the system sends a data frame copy to each socket receiving buffer. then proceed to the next step. finally, enter the UDP input routine... PS: If a checksum error occurs, the kernel will directly discard this packet. instead of copying it to the socket of sock_raw, because the checksum is incorrect, the data must be faulty, including all information, which makes no sense. further analyze their capabilities. 1. socket (af_inet, sock_raw, ipproto_udp); yes: This socket can receive IP data packets sent to the local machine for the protocol type (tcp udp icmp, etc, from the above, we can see 20 + 8 + 100. no: cannot receive data packets not sent to the local IP address (IP soft filter discards data packets not sent to the local IP address ). no: cannot receive data packets sent from the local machine. you need to organize the tcp udp icmp and other headers. you can use setsockopt to package the IP header. This socket is suitable for writing a Ping program. socket (pf_packet, sock_raw, htons (x); this socket is powerful. You can create this socket to listen to all data frames on the NIC. from the above, we can see 20 + 20 + 8 + 100. the last Ethernet CRC never came in, because the kernel has been judged and it makes no sense for the program. yes: can receive data frames sent to the local Mac: can receive data frames sent from the Local Machine (the 3rd parameters need to be set to eth_p_all: receive data frames not sent to the local MAC (NIC needs to be set to promisc hybrid mode) protocol type: a total of four eth_p_ip 0x800 only receive data frames of the IP type sent to the MAC of the Local Machine eth_p_arp 0x806 only accept data frames of the ARP type sent to MAC of the Local Machine eth_p_arp 0x8035 only accept data frames sent the RARP data frame eth_p_all 0x3 of the local Mac receives data frames of all types of ip arp rarp sent to the local Mac, receives all types of data frames from the local machine. (When the hybrid mode is enabled, it will receive data frames that are not sent to the local Mac), you need to organize the entire ethernet data frame. all related addresses use struct sockaddr_ll instead of struct sockaddr_in (because the protocol cluster is pf_packet and not af_inet). For example, if the address is sent to a machine, struct sockaddr_ll is used. differences between using sock_raw, sock_dgram and sock_packet (see http://blog.csdn.net/tqyou85/archive/2008/10/21/3115664.aspx for details)
When the first socket parameter uses pf_packet, the above three socket types can be used. But there are differences.
(1) data sent using sock_raw must contain the protocol header of the link layer, and the received data packet, including the protocol header of the link layer. The use of sock_dgram does not contain the link layer protocol header.
(2) sock_packet can also be used, but it has been deprecated and will not be supported in the future. It is not recommended.
(3) When using sock_raw, sock_dgram, and sock_packet, the address types used in sendto and recvfrom are different. The first two use sockaddr_ll addresses, while the latter uses sockaddr addresses.
(4) If the first parameter of socket uses pf_inet and the second parameter uses sock_raw, the original IP package can be obtained.