Dynamic protocol Tracking Mechanism
For example, the FTP dynamic protocol creates another associated connection through a control connection, while the Linux operating system does not implement this flexibly. The Code is as follows:
- Static struct ip_conntrack_helper FTP [max_ports];
- Static int _ init Init (void)
- {
- Int I, RET;
- Char * tmpname;
- If (ports [0] = 0)
- Ports [0] = ftp_port;
- // When the value of max_ports is 8, you must specify the source port when loading the module.
- For (I = 0; (I <max_ports) & ports [I]; I ++ ){
- FTP [I]. tuple. SRC. U. tcp. Port = htons (ports [I]);
- FTP [I]. tuple. dst. protonum = ipproto_tcp;
- FTP [I]. Mask. SRC. U. tcp. Port = 0 xFFFF;
- FTP [I]. Mask. dst. protonum = 0 xFFFF;
- FTP [I]. max_expected = 1;
- FTP [I]. Timeout = 0;
- FTP [I]. Flags = ip_ct_helper_f_reuse_reset CT;
- FTP [I]. Me = ip_conntrack_ftp;
- FTP [I]. Help = help;
- Tmpname = & ftp_names [I] [0];
- If (ports [I] = ftp_port)
- Sprintf (tmpname, "ftp ");
- Else
- Sprintf (tmpname, "ftp-% d", ports [I]);
- FTP [I]. Name = tmpname;
- Debugp ("ip_ct_ftp: Registering helper for port % d/N ",
- Ports [I]);
- // Register ip_conntrack_helper
- Ret = ip_conntrack_helper_register (& FTP [I]);
- If (RET ){
- Fini ();
- Return ret;
- }
- Ports_c ++;
- }
- Return 0;
- }
In this case, when FTP uses a large number of non-standard ports, the primary connection cannot properly record the corresponding connections. Therefore, there is a work und here, so that no connection can be found for all FTP master connections, register a helper_binding function to the application for identification (a module that determines the connection type based on the data packet content) when the application identifies the current connection as an FTP connection, it calls helper_binding to search by name and then associates the FTP ip_conntrack_helper with the master connection.
Set FTP [I]. mask. SRC. u. TCP. port = 0x0000;, because this assignment will cause all connections to not meet the requirements, so there should be no applications that conflict with this. In the init_conntrack function, the corresponding helper is searched for each primary connection. The Code is as follows:
/* Look up the conntrack helper for Master connections only */
If (! Expected)
Conntrack-> helper = ip_ct_find_helper (& repl_tuple );
In the end, this function will call helper_cmp, so we can modify this function to directly return it.
- Static inline int
- Helper_cmp (const struct ip_nat_helper * helper,
- Const struct ip_conntrack_tuple * tuple)
- {
- // Added judgment code
- If (helper-> mask. SRC. U. tcp. Port = 0 &
- (Helper-> tuple. dst. protonum = ipproto_tcp | helper-> tuple. dst. protonum = ipproto_udp ))
- Return 0;
- Else
- Return ip_ct_tuple_mask_cmp (tuple, & helper-> tuple, & helper-> mask );
- }
After the connection is recognized as FTP by the application, the Help function is called in the corresponding ip_conntrack_in function of the backbread. The Code is as follows:
- /* Netfilter hook itself .*/
- Unsigned int ip_conntrack_in (unsigned int hooknum,
- Struct sk_buff ** pskb,
- Const struct net_device * In,
- Const struct net_device * Out,
- INT (* okfn) (struct sk_buff *))
- {
- Struct ip_conntrack * CT;
- Enum ip_conntrack_info ctinfo;
- Struct ip_conntrack_protocol * proto;
- Int set_reply;
- Int ret;
- //...
- //...
- If (Ret! = Nf_drop & CT-> helper ){
- // Call the help function
- Ret = CT-> helper-> help (* pskb)-> NH. iph, (* pskb)-> Len,
- CT, ctinfo );
- If (ret =-1 ){
- /* Invalid */
- Nf_conntrack_put (* pskb)-> nfct );
- (* Pskb)-> nfct = NULL;
- Return nf_accept;
- }
- }
- If (set_reply)
- Set_bit (ips_seen_reply_bit, & CT-> status );
- Return ret;
- }