# cd /usr/src/linux
# make menuconfig (生成了.config)
# tar -jxvf patch-o-matic-20050519.tar.bz2
# cd patch-o-matic-20050519
# export KERNEL_DIR=/usr/src/linux
# export IPTABLES_DIR=/usr/src/iptables
# ./runme time
# cd /usr/src/linux
# make menuconfig (加上TIME MATCH)
# make
# make modules_install
# cp arch/i386/boot/bzImage /boot/kernel-2.6.11.10-time
# cd /usr/src/iptables
# make KERNEL_DIR=/usr/src/linux
# make install
重新启动系统后可以看到:
ip_tables: (C) 2000-2002 Netfilter core team
ipt_time loading
登录进入系统清空所有iptables规则,然后执行:
iptables -A INPUT -p icmp -m time --timestart 14:20 --timestop 14:21 -j REJECT
终于找到原因了:
/usr/src/linux/net/ipv4/netfilter/ipt_time.c 中
[code:1]
long int tm_gmtoff; /* we don't care, we count from GMT */
const char *tm_zone; /* we don't care, we count from GMT */
[/code:1]
[code:1]
/* we use the kerneltime if we are in forward or output */
info->kerneltime = 1;
if (hook_mask & ~((1 << NF_IP_FORWARD) | (1 << NF_IP_LOCAL_OUT)))
/* we use the skb time */
info->kerneltime = 0;
[/code:1]
在规则匹配函数match()中:
[code:1]
/* if kerneltime=1, we don't read the skb->timestamp but kernel time instead */
if (info->kerneltime)
{
do_gettimeofday(&kerneltimeval);
packet_local_time = kerneltimeval.tv_sec;
}
else
packet_local_time = skb->stamp.tv_sec;
[/code:1]
而skb->stamp是在什么时候生成的呢?找了很久,终于在/usr/src/linux/net/core/dev.c中找到答案:
[code:1]
/**
* netif_rx - post buffer to the network code
* @skb: buffer to post
*
* This function receives a packet from a device driver and queues it for
* the upper (protocol) levels to process. It always succeeds. The buffer
* may be dropped during processing for congestion control or by the
* protocol layers.
*
* return values:
* NET_RX_SUCCESS (no congestion)
* NET_RX_CN_LOW (low congestion)
* NET_RX_CN_MOD (moderate congestion)
* NET_RX_CN_HIGH (high congestion)
* NET_RX_DROP (packet was dropped)
*
*/
int netif_rx(struct sk_buff *skb)
{
int this_cpu;
struct softnet_data *queue;
unsigned long flags;
看来netstamp_needed默认为0,那么skb->stamp.tv_sec就等于0,所以在ipt_time用于的INPUT chain时时间老是不对,看来在ipt_time.c上动手改造最方便了,将/usr/src/linux/net/ipv4/netfilter/ipt_time.c中的:
[code:1]
/* we use the kerneltime if we are in forward or output */
info->kerneltime = 1;
if (hook_mask & ~((1 << NF_IP_FORWARD) | (1 << NF_IP_LOCAL_OUT)))
/* we use the skb time */
info->kerneltime = 0;
[/code:1]
改成:
[code:1]
/* we use the kerneltime if we are in forward or output */
info->kerneltime = 1;
[/code:1]
现在ipt_time将对所有的chain使用kerneltime,重新编译内核,如果现在再测试用于INPUT链的time匹配就可以正常工作了。