1. tcpdump is a good tool for tracking the system behavior of processes in the local machine. in the debugging of network problems, tcpdump is an indispensable tool, like most excellent linux tools, it features simplicity and power. By default, tcpdump does not capture packets for internal communication on the local machine. According to the network Association
I,Tcpdump
Strace is a good tool for tracking system behavior calls of processes in the local machine. in network debugging, tcpdump is an essential tool, like most excellent linux tools, it features simplicity and power.
By default, tcpdump does not capture packets for internal communication on the local machine. According to the network protocol stack, for packets, even if the destination is a local machine, it also needs to go through the network protocol layer of the local machine. Therefore, the local communication must enter the kernel through APIs, the route selection is completed.
II. how packet capture works in linux
In linux, packet capture is used to complete the processing of network packets (accurate to network devices) by registering a virtual underlying network protocol. After a network packet is received, the network adapter traverses all registered network protocols in the system, such as the Ethernet protocol and the x25 protocol processing module, to try to parse the packets, this is similar to the mounting of Some file systems, that is, to allow all registered file systems in the system to try mounting. if any one thinks they can handle it, the mounting will be completed.
When the packet capture module disguise itself as a network protocol, the system will give the pseudo protocol a chance to process the packets received by the network adapter when receiving the packets, in this case, the module will take the opportunity to snoop the packet, that is, to completely copy the packet, pretend to be the packet received by itself, and report it to the packet capture module.
Let's take a look at how the network layer processes received packets.
Static int process_backlog (struct net_device * backlog_dev, int * budget) --- netif_receive_skb
List_for_each_entry_rcu (ptype, & ptype_all, list ){
If (! Ptype-> dev | ptype-> dev = skb-> dev ){
If (pt_prev)
Ret = deliver_skb (skb, pt_prev, orig_dev );
Pt_prev = ptype;
}
}
III. protocol family registration
This protocol can only be registered when necessary, because it increases the processing speed of system packets and consumes a large amount of system skb. At the beginning of packet capture, it will create a corresponding network set interface, which is of the af_packet type. Related implementation:
Linux-2.6.21 \ net \ packet \ af_packet.c
Static int packet_create (struct socket * sock, int protocol)
Sk-> sk_family = PF_PACKET;
Po-> num = proto;
......
Po-> prot_hook.func = packet_rcv;
......
If (proto ){
Po-> prot_hook.type = proto;
Dev_add_pack (& po-> prot_hook); this interface registers the prot_hook to the ptype_all queue shown above.
Sock_hold (sk );
Po-> running = 1;
}
When a packet arrives, it will call the packet_rcv function registered here.
......
Res = run_filter (skb, sk, snaplen); if the filter fails to be filtered, it means that the packet capture does not care about is directly released. if the returned value is non-zero, the packet does not care.
If (! Res)
Goto drop_n_restore;
......
If (skb_shared (skb )){
Struct sk_buff * nskb = skb_clone (skb, GFP_ATOMIC); copy it by yourself.
If (nskb = NULL)
Gotodrop_n_acct;
If (skb_head! = Skb-> data ){
Skb-> data = skb_head;
Skb-> len = skb_len;
}
Kfree_skb (skb );
Skb = nskb;
}
4. filter execution
Run_filter ---> sk_run_filter
......
/*
* Process array of filterinstructions.
*/
For (pc = 0; pc <flen; pc ++ ){
Fentry = & filter [pc];
Switch (fentry-> code ){
CaseBPF_ALU | BPF_ADD | BPF_X:
A + = X;
Continue;
CaseBPF_ALU | BPF_ADD | BPF_K:
A + = fentry-> k;
Continue;
......
/*
* Handle ancillarydata, which are impossible
* (Or very difficult) to get parsing packet contents.
*/
Switch (k-SKF_AD_OFF ){
Case SKF_AD_PROTOCOL:
A = ntohs (skb-> protocol );
Continue;
Case SKF_AD_PKTTYPE:
A = skb-> pkt_type;
Continue;
Case SKF_AD_IFINDEX:
A = skb-> dev-> ifindex;
Continue;
Default:
Return0;
}
This function executes a defined instruction set and. You can use sockopt to register this command. the kernel executes these commands in kernel mode to complete the matching, including loading of certain fields of the message, conditional jump, addition, subtraction, multiplication, division, and return. After receiving the packet, the packet package interface executes this virtual program until it encounters a ret command as its return value. Tcpdump-d can be used to display the commands generated after Compilation. Below is a test output
[Root @ Harry bash-4.1] # tcpdump-d host 1.2.3.4
Tcpdump: WARNING: eth0: no IPv4 address assigned
(000) ldh [12]
(001) jeq #0x800 jt 2 jf 6
(002) ld [26] loads an int type starting from the first 26th bytes of the received message,
(003) if jeq #0x1020304 jt12 jf 4 is equal to 0x1234, jump to the 12-hop command and wait until the fourth command is continued.
(004) ld [30]
(005) jeq #0x1020304 jt12 jf 13
(006) jeq #0x806 jt 8 jf 7
(007) jeq #0x8035 jt8 jf 13
(008) ld [28]
(009) jeq #0x1020304 jt12 jf 10
(010) ld [38]
(011) jeq #0x1020304 jt12 jf 13
(012) ret #65535
(013) ret #0
[Root @ Harry bash-4.1] #
V. processing of tcpdump
For tcpdump, parameters other than options in command line input are processed as a syntax file. Libcap defines its own lexical analyzer and syntax analyzer. The lexical analyzer is composer. l, and the syntax analysis file is composer. l. It can be seen that the language definition uses the help of common bison and flex. However, if these tools are used, it means that a configuration file can be very complex to write, such as syslog-ng configuration, ld connection configuration script, bash script, and other syntaxes.