3

I want to understand meaning of records in /proc/net/xt_recent/ip_list file (which is created by recent extension of iptables), e.g:

src=127.0.0.1 ttl: 128 last_seen: 4298627364 oldest_pkt: 3 4298623492, 4298625777, 4298627364

All fields look pretty obvious and last_look look like timestamp. But it isn't timestamp in UNIX-time format. Being converted as UNIX-time is equal 03/21/2106 18:19:24. Evidently it isn't a "last seen" time.

How can I extract correct value from last_seen time?

Thank you.

UPDATE

Just to avoid misconception:

$ date 
Mon Jun 15 14:14:00 MSK 2015
shau-kote
  • 135
  • 1
  • 8
  • http://forums.fedoraforum.org/showpost.php?p=1235507&postcount=2 – Dan Jun 15 '15 at 15:15
  • I struggled with for a while before I found this utility on github https://github.com/peppelinux/iptables_xt_recent_parser that is exactly what I needed. – Josiah DeWitt Dec 01 '17 at 21:46

3 Answers3

4

I wrote this:

https://github.com/peppelinux/xt_recent_parser

output is like this:

python3 xt_recent_parser.py 
XT_RECENT python parser
<giuseppe.demarco@unical.it>


114.241.108.160, last seen: 2017-03-25 18:21:42 after 13 Connections 
46.165.210.17, last seen: 2017-03-25 13:07:54 after 10 Connections 
61.53.219.162, last seen: 2017-03-25 17:39:17 after 20 Connections 
179.37.141.232, last seen: 2017-03-25 18:08:23 after 2 Connections 
114.42.117.39, last seen: 2017-03-25 13:22:14 after 18 Connections 
177.12.84.234, last seen: 2017-03-25 16:22:14 after 17 Connections 
2

That's a number of jiffies, which is an internal kernel variable incremented every 1/HZ seconds. As shown by Maxiko, you can get the current jiffies value from /proc/timer_list. You can generally get HZ from /boot/config.<kernel-version>, so you should be able to post-process that data with something like:

#! /usr/bin/perl
use Time::HiRes qw(gettimeofday);
use POSIX;

my $kernel = (uname())[2];

open CONFIG, "<", "/boot/config-$kernel" or
  die "Can't find kernel config file: $!";

my $hz;
while (<CONFIG>) {
  if (/^CONFIG_HZ=(\d+)/) {
    $hz = $1;
    last;
  }
}
close CONFIG;

die "Can't determine HZ" unless $hz;

open TIMERS, "<", "/proc/timer_list" or
  die "Can't open /proc/timer_list: $!";

my $jiffies;
while (<TIMERS>) {
  if (/^jiffies: (\d+)/) {
    $jiffies = $1;
    last;
  }
}
close TIMERS;

die "Can't determine jiffies" unless $jiffies;

my ($seconds, $microseconds) = gettimeofday;
$seconds += $microseconds / 1e6;

while (<>) {
  s{(?<=last_seen: )\d+|\d+(?=,|$)}{
    my $t = $seconds + ($& - $jiffies) / $hz;
    $& . strftime(" [%F %T", localtime($t)) .
      sprintf(".%03d]", ($t * 1000 + 0.5) % 1000);
  }ge;
  print;
}

Which on your sample and on my system (so with a different jiffies as on yours) gives:

src=127.0.0.1 ttl: 128 last_seen: 4298627364 [2016-08-16 17:21:00.882] oldest_pkt: 3 4298623492 [2016-08-16 17:20:45.394], 4298625777 [2016-08-16 17:20:54.534], 4298627364 [2016-08-16 17:21:00.882]
sch
  • 560
  • 4
  • 13
1

This should works:

FILE=iplist #This is file name of recent module output. It may vary on your system (like iplist)
TICKS=$(grep CONFIG_HZ= /boot/config-$(uname -r)|awk -F= '{print $2}') # Get current ticks per sec

printit()
{
    Len=`echo $1|wc -c`
    Date=$DATE
    Dot="."
    Loop=`echo 50-$Len|bc`
    loop=0
    while [ $loop -le $Loop ]
    do
        loop=`echo $loop+1|bc`
        Dot=`echo $Dot.`
    done
    echo "$1$Dot$DATE"
}
cat $FILE|while read LINE
do
    IP=`echo $LINE|awk '{print $1}'|awk -F= {'print $2'}`
    DATE=$(date -d@$(date +'%s'-$(echo \($(cat /proc/timer_list|grep -m1 -E '^jiffies'|cut -d" " -f2)-$(awk '{print $5}' $FILE)\)/$TICKS|bc)|bc))
    printit $IP $DATE
done

And there is an output of your example:

127.0.0.1..........................................Пн. мая 18 14:24:40 OMST 2015

Timezone may differ from you regional settings

Also you can check https://stackoverflow.com/questions/2731463/converting-jiffies-to-milli-seconds

Alexis Wilke
  • 2,210
  • 1
  • 20
  • 37
Maxiko
  • 474
  • 2
  • 8
  • It just interpret `last_seen` value as POSIX-timestamp and print it in human-readable format -- I again see datetime in distant 2106 year. :( – shau-kote Jun 15 '15 at 11:12
  • I've edited answer, check please – Maxiko Jun 15 '15 at 11:18
  • I don't know Bash so well, but unfortunately it looks like your script just output current datetime -- I ran it three times and got three sequential datetimes close to current datetime (but `ip_list` didn't change). Do you wish to tell `last_seen` value is stored in jiffies? – shau-kote Jun 15 '15 at 11:47
  • Yes, in jiffies since boot. I fixed code, so now it work normal – Maxiko Jun 15 '15 at 13:02
  • Yeah, it works! But there is not `/boot/config*` on my system (Arch). I think it is better to take HZ from `/proc/config.gz`. I did it this way. – shau-kote Jun 15 '15 at 18:03