This provides the following capabilities:
- The ability to watch the packets received by the datalink layer, allowing programs such as tcpdump to be run on normal computer systems (as opposed to dedicated
hardware devices to watch packets). When combined with the capability of the network interface to go into a promiscuous mode, this allows an application to watch
all the packets on the local cable, not just the packets destined for the host on which the program is running.
This ability is less useful in switched networks, which have become quite common. This is because the switch only passes traffic to a port if it is addressed to the
device or devices attached to that port (unicast, multicast, or broadcast). To monitor traffic carried on other ports of the switch, the switch port must be configured to
receive other traffic, often called monitor mode or port mirroring. Note that many devices that you might not expect to be switches actually are, for example, a
dual-speed 10/100Mbps hub is usually a two-port switch: one port for the 100Mbps systems and the other for the 10Mbps systems. - The ability to run certain programs as normal applications instead of as part of the kernel. For example, most Unix versions of an RARP server are normal applications
that read RARP requests from the datalink (RARP requests are not IP datagrams) and then write the reply back to the datalink.
可以看到本地链路层的所有包。三种方法可以用:
- BPF(BSD Packet Filter):Unix
- DLPI(Datalink Provider Interface): SVR4
- SOCK_PACKET接口:Linux
libpcap提供跨平台的接口。当进入promiscuous mode时,可以看到本地链路层的所有包,而不仅仅是到主机的包。
Linux: SOCK_PACKET and PF_PACKET
Linux下有两种方法访问链路层
- 创建一个family为SOCK_PACKET的socket
- 创建一个family为PF_PACKET的socket
The newer method, which introduces more filtering and performance features, is to create a socket of family PF_PACKET. When using PF_PACKET sockets, the second argument to socket can be SOCK_DGRAM, for "cooked" packets with the link-layer header removed, or SOCK_RAW, for the complete link-layer packet.
接收所有的包
fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
fd = socket(AF_INET, SOCK_PACKET, htons(ETH_P_ALL));
只接收IPv4
fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP));
fd = socket(AF_INET, SOCK_PACKET, htons(ETH_P_IP));
其它参数如:ETH_P_ARP或ETH_P_IPV6
Specifying a protocol of ETH_P_xxx tells the datalink which frame types to pass to the socket for the frames the datalink receives. If the datalink supports a promiscuous mode
(e.g., an Ethernet), then the device must also be put into a promiscuous mode, if desired. This is done with a PACKET_ADD_MEMBERSHIP socket option, using a packet_mreq structure specifying an interface and an action of PACKET_MR_PROMISC.
PF_PACKET sockets can be linked to a device by calling bind.
libpcap: Packet Capture Library
只支持读操作
libnet: Packet Creation and Injection Library
提供raw socket和datalink access