Remember Master Steven S.
Best references:
1. Master from the Internet.
2. Linux man command: Man Netlink, man rtnetlink.
3. UNP V1 Chapter 1.
Article 1: Overview
The original interface allows us to read and write IP data that is not processed by the kernel, while access to the data link layer further expands this capability-read and write any type of data link frames, not just IP data packets.
Data access links provide the following capabilities:
1. Monitor groups received by the data link layer.
2. Make some programs run as common application processes rather than as part of the kernel, which is very helpful for reducing the kernel size.
Article 2: Linux Data Link socket
Root permission is required to create a data link socket!
You can create a data link socket descriptor in two ways.
Method 1: send and receive IP Packets: raw socket: see the previous article. We will not discuss it any more.
Int sockfd = socket (af_inet, sock_raw, ipproto_xxx );
Method 2: send and receive Ethernet data frames in two ways:
New Method: int sockfd = socket (pf_packet, sock_type, eth_protocol); // introduces more filtering and performance features.
Value of the sock_type parameter:
Sock_dgram: deducts the "cooked" group in the Link Layer header ).
Sock_raw: indicates the "uncooked" complete link layer group-Ethernet frame (raw ).
You can set this interface to promiscuous mode, as follows:
Int sockfd = socket (pf_packet, sock_raw, htons (eth_p_ip ));
Struct ifreq IFR;
Struct packet_mreq mreq;
Bzero (& IFR, sizeof (IFR); // initialize IFR
Strcpy (IFR. ifr_name, "eth0"); // here, "eth0" can be replaced with the name of another device.
If (IOCTL (sockfd, siocgifindex, & IFR) <0) // obtain the index corresponding to the device
{
Perror ("IOCTL siocgifindex :");
}
Mreq. mr_type = packet_mr_promisc; // Mixed Mode
Mreq. mr_ifindex = IFR. ifr_ifindex; // sets the device Index Number of the hybrid mode to be invested by the interface.
Mreq. mr_alen = 0;
Mreq. mr_address [0] = '/0 ';
If (setsockopt (sockfd, sol_packet, packet_add_membership, & mreq, sizeof (mreq) <0)
{
Perror ("setsockopt ");
Exit (0 );
}
The old method: int sockfd = socket (af_inet, sock_packet, eth_protocol); // In unpv1: This method is widely available but lacks flexibility. Only Ethernet frames are returned.
You can also add the socket created in the old method to the hybrid mode:
Int sockfd = socket (pf_packet, sock_raw, htons (eth_p_ip ));
Struct ifreq IFR;
Bzero (& IFR, sizeof (IFR ));
Strcpy (IFR. ifr_name, "eth0 ");
If (IOCTL (sockfd, siocgifflags, & IFR) <0 ){
Perror ("IOCTL siocgifflags :");
}
IFR. ifr_flags | = iff_promisc;
If (IOCTL (sockfd, siocsifflags, & IFR) <0 ){
Perror ("ioclt siocsifflags :");
}
Eth_protocolThe parameter value is as follows. this parameter is used to tell the data link layer what types of frames are passed to the socket created by the lock: defined in Linux/if_ether.h
# Define eth_p_all0x0003/* every packet (Be careful !!!) * /// Receives all frames from the data link
# Define eth_p_loop0x0060/* Ethernet loopback packet */
# Define eth_p_pup0x0200/* Xerox pup packet */
# Define eth_p_pupat0x0201/* Xerox pup ADDR trans packet */
# Define eth_p_ip0x0800/* Internet Protocol packet * // only receives IPv4 Frames
Article 3: Linux Data Link socket kernel buffering, kernel filtering, and device Filtering
The descriptions in unpv1 are as follows:
1. kernel buffering: Kernel buffering is not provided for both new and old methods.
2. kernel filter: the old method is not supported. The socket created by the new method can be installed as follows:
/* Try and keep these values and structures similar to BSD, especially the BPF code definitions which need to match so you can share filters */
// These two structures are defined in Linux/filter. h.
Struct sock_filter {/* filter block */
_ U16code;/* Actual filter code */
_ U8jt;/* Jump true */
_ U8jf;/* Jump false */
_ U32k;/* generic multiuse field */
};
Struct sock_fprog {/* required for so_attach_filter .*/
Unsigned comment Len;/* Number of filter blocks */
Struct sock_filter * filter;
};
Struct sock_fprog filter;
//////////////////////////////////
Filter initialization here;
//////////////////////////////////
Setsockopt (sockfd, sol_socket, so_attach_filter, & filter, sizeof (filter); // install the filter
Setsockopt (sockfd, sol_socket, so_detach_filter, null, 0); // uninstall the filter. If the sockfd filter is closed before, it will be automatically uninstalled !!
So_attach_filter and so_detach_filter:MAN 7 socket states:
Bugs:
The config_filter socket options so_attach_filter and so_detach_filter are not supported ented. The suggested interface to use them is via the libpcap library.
3. device Filtering: the old method is also not supported. The new method can use the BIND function to associate the socket with the relevant device:
Struct sockaddr_ll ADDR; // Linux/if_packet.h
Bzero (& ADDR, sizeof (ADDR ));
ADDR. sll_family = pf_packet;
ADDR. sll_protocol = htons (eth_p_all );
ADDR. sll_ifindex = IFR. ifr_ifindex; // method for obtaining this value, see the preceding figure.
If (BIND (sockfd, (struct sockaddr *) & ADDR, sizeof (ADDR) <0)
Perror ("BIND error :");
Article 4: libpcap and Libnet
Libnet Baidu Encyclopedia: http://baike.baidu.com/view/1520138.htm
Libpcap Baidu Encyclopedia: http://baike.baidu.com/view/1319961.htm
Libnet/libnids library function Introduction: http://blog.ccidnet.com/blog-htm-do-showone-uid-36931-itemid-138338-type-blog.html
Linux Libnet programming: http://xdz2005.blog.163.com/blog/static/107873282010710112519755/
Libpcap function library details: http://dev.firnow.com/course/3_program/c++/cppjs/2008324/106112.html