The BSD packet filter (BPF) is a software device used to filter the data flow of a network interface by adding a switch to the network interface. Application process Open/dev/bpf0,
/dev/bpf1 and so on, you can read the BPF device, and each application process can only open one BPF device at a time.
With several IOCTL commands, you can configure a BPF device, correlate it with a network interface, and install a filtering program to selectively receive input groupings.
When the BPF device is turned on, the application process receives the packet through the read-write device, or the packet is placed in the network interface queue.
The BPF device works on the premise that the network interface must be able to support BPF. The previously mentioned drivers for the Ethernet and loopback interfaces have called Bpfattach, which is used to configure
Reads the interface of the BPF device.
1.BPF_IF Structure BPF maintains a list of all network interfaces that support BPF, each with a BPF_IF structure description, a global pointer bpf_iflist to the first structure in the table, and a BPF interface structure.
Bif_next points to the next BPF interface structure in the list. Bif_dlist points to another linked list, including all of the BPF devices that have been opened and configured. If a network interface has a BPF device configured, the switch is added, Bif_driverp is empty. When you configure a BPF device for a network interface, the *BIF_DRIVERP points to the BIF_IF structure, which tells the interface to start passing groupings to the BPF. The interface type is saved in the BIF_DLT. Lists the constant values that correspond to several interfaces.
The additional BPF_HDR structures in each input grouping are given.
Bh_tstamp records the time that the packet was captured. Bh_caplen equals the number of bytes saved by the BPF, and Bh_datalen equals the number of bytes in the original packet. Bh_headlen equals the size of BPF_HDR plus the length of the required padding bytes. It is used to interpret packets read from the BPF device and should be equivalent to the Bif_hdrlen of the receiving interface.
All groupings received by BPF have an additional BPF header. Bif_hdrlen equals the first size, and finally, bif_ifp points to the ifnet structure of the corresponding interface. The BPF_IF structure is given to establish a connection with the ifnet structure.
Note: Bif_driverp points to the IF_BPF and SC_BPF pointers of the network interface, not the interface structure.
Initializes the link type and the header length member variable for 3 interfaces, according to the information given when each interface driver calls Bpfattach. The BPF interface structure chain list is built when each device driver initializes the call to Bpfattach. The approximate processing flow for this function is as follows: 1. Create a space for bpf_if. 2. Initialize the BPF_IF structure. 3. Calculate the BPF header size. The overall structure of the BPF groupings captured on the above 3 interfaces is listed.
4. Initialize the Bpf_dtab table. 5. Print the console information.
2.dpf_d structure in order to selectively receive input messages, the application first opens a BPF device, invoking several ICTL commands that dictate the conditions of the BPF filter, indicating the interface, the read cache size, and the time-out period. Each BPF device has a related bpf_d structure, as shown in.
If multiple BPF devices are configured on the same network interface, the corresponding BPF_D structure will form a linked list. Bd_next points to the next structure in the list. Packet caching: Each BPF_D structure has two packet caches, the input groupings are usually saved in the cache corresponding to the BD_SBUF (storage cache), and the other cache corresponds to BD_FBUF (free cache), which means the cache is empty or corresponds to BD_HBUF (persistence cache). means that there are packets waiting for the application process to read in the cache, Bd_slen and Bd_hlen respectively, the number of bytes saved in the storage cache and the persistence cache. If the storage cache is full, it will be connected to Bd_hbuf, and the free cache will be connected to BD_SBUF. When the persistence cache is emptied, it is connected to the BD_FBUF. Bd_bufsize records the size of the two caches connected to the device, with a default value of 4096 bytes. The bd_bif points to the BPF_IF structure corresponding to the BPF device. Bd_rtout is the number of ticks that are deferred while waiting for grouping. Bd_filter the filter program code that points to the BPF device. Two statistical values, the application process can be read through biogstats, respectively, stored in Bd_rcount and Bd_dcount. The Bd_promisc is set by the Biocpromisc command, which makes the interface work in a promiscuous state. Bd_state not used. Bd_immediate is set by the Biocimmediate command, prompting the driver to return after the packet is received, not waiting for the persistence cache to fill. Bd_pad fills the bpf_d structure so that it aligns with the long-byte boundary. Bd_sel a saved selinfo structure that can be used for select system calls.
2.1.bpfopen function Application process calls open, when the view opens a BPF device, the call is transferred to Bpfopen, which is used to assign the BPF_D structure.
After the 2.2.BPFIOCTL function device is turned on, it can be configured with the IOCTL command, summarizing the IOCTL commands associated with the BPF device.
The state of each structure variable that opens a second BPF device and connects to the same Ethernet network interface is given.
BPF devices connected to the Ethernet interface:
Two BPF devices connected to the Ethernet interface:
When the second BPF device is turned on, a new dpf_d structure is allocated in the Bpf_dtab table.
The 2.3.bpf_setif function Bpf_setif function, which is responsible for establishing the connection between the BPF descriptor and the network interface, the approximate flow is as follows:
1. Look for a matching ifnet structure.
2. Connect the BPF_D structure.
The 2.4.BPF_ATTACHD function establishes the corresponding relationship between the BPF descriptor and the BPF device and the network interface.
3.BPF input Once the BPF device is open and configured, the application process receives the packet from the interface via the read system call. The BPF filter replicates input groupings and therefore does not
interfere with normal network processing. The input grouping is saved in the storage cache and persistence cache attached to the BPF device.
The 3.1.BPF_TAP function below lists the code that Lance device driver calls Bpf_tap:
Bpf_tap (LE->SC_IF.IF_BPF, buf, len + sizeof (struct ether_header));
In this function, the for loop iterates through the BPF device chain list connected to the network interface. For each device, the grouping is submitted to Bpf_filter. If the filter program accepts the
Grouping, which returns the number of bytes captured and calls the Catchpacket replication group. If the filter rejects the grouping, the length is equal to 0, and the loop continues.
3.2.catchpacket function The approximate processing flow of this function is as follows:
1. Determine if the grouping is placed in the cache. If the free cache is available, the cache is rotated and all applications waiting for input data are awakened through Bpf_wakeup.
2. Immediate processing. If the device is in an immediate manner, all waiting processes are awakened to handle the incoming packet-the cache in the kernel that does not have a grouping.
3. Add the BPF header.
The 3.3.bpfread function core handles read transfer of the BPF device to Bpfread. The approximate processing flow for this function is as follows:
1. Wait for the data. Because multiple application processes can read data from the same BPF device, if a process has read the data first, the while loop will force the read
Operation continues. If there is data in the persistence cache, the loop is skipped. This filters the same network interface with two application processes through two different BPF devices
is different.
2. Immediate manner. If the device is in an immediate fashion and there is data in the storage cache, the cycle cache, while loop is terminated.
3. No groupings are available. If the device is not in immediate mode, or there is no data in the storage cache, the application goes into hibernation until a signal arrives.
4. View the persistence cache. If the timer times out and there is data in the persistence cache, the loop terminates.
5. View the storage cache. If the timer times out and there is no data in the storage cache, read returns 0. This situation must be taken into account when the application process executes a time-limited read.
If the timer times out and there is data in the storage cache, the storage cache is transferred to the persistence cache and the loop terminates.
6. Groups are available. Remove the corresponding bytes from the persistence cache, hand it over to the application, transfer the persistence cache to the free cache, clear the cache counter, and return the function.
"TCP/IP Detailed Volume 2: implementation" Note--BPF:BSD packet filter program