
POE::Filter::Log::IPTables - filter for processing IPTables logs

use POE::Filter::Log::IPTables; $filter = POE::Filter::Log::IPTables->new(Syslog => 1); $arrayref_of_hashrefs = $filter->get($arrayref_of_raw_chunks_from_driver);

The Log::IPTables filter translates iptables log lines into hashrefs.

new() creates and initializes a new POE::Filter::Log::IPTables filter. You can pass it "Syslog => 1" if you would like it to attempt to remove syslog timestamps from the log lines. You can pass it "Debug => 1" to turn debugging on.
get() translates iptables log lines into hashrefs.
In the top level of the hashref:
The interface a packet came in on.
The interface a packet went out on.
Any part of the iptables log line that couldn't be parsed.
The entire (unmodified) iptables log line.
The source address of the IP packet.
The destination address of the IP packet.
The length of the IP packet.
The Type of Service of the IP packet.
The Precedence of the IP packet.
The time to live of the IP packet.
The id of the IP packet.
An arrayref. Can have "CE" (congestion), "DF" (don't fragment), or "MF" (more fragments are coming).
The name/number of the protocol that the IP packet encapsulates. This will be 'tcp', 'udp', 'icmp', or a number corresponding to the protocol in /etc/protocols.
The source port of the tcp packet.
The destination port of the tcp packet.
The length of the TCP window.
The reserved bits.
An arrayref. Can be any combination of "CWR" (Congestion Window Reduced), "ECE" (Explicit Congestion Notification Echo), "URG" (Urgent), "ACK" (Acknowledgement), "PSH" (Push), "RST" (Reset), "SYN" (Synchronize), or "FIN" (Finished)
The urgent pointer.
The numeric type of the ICMP packet.
The numeric code of the ICMP packet.
Some types of ICMP - 3 (destination unreachable), 4 (source quench), and 11 (time exceeded) - contain the IP and protocol headers that generated the ICMP packet. We parse this recursively, so if the type is one of those numbers, error_header is a hashref that starts again with the top level of the data structure. It may make more sense if you look at a YAML dump, which can be found below...
The id of the ICMP echo packet.
The sequence number of the ICMP echo packet.

in_int: eth1
leftover: ~
line: >-
Nov 28 19:52:19 malloc kernel: in: IN=eth1 OUT= MAC= SRC=192.168.1.31 DST=192.168.0.54 LEN=100 TOS=0x00 PREC=0x00 TTL=63 ID=38565 DF PROTO=TCP SPT=25 DPT=1071 WINDOW=57352 RES=0x00 ACK PSH URGP=0
mac: ~
out_int: ~
ip:
dst_addr: 192.168.0.54
fragment_flags:
- DF
id: 38565
len: 100
prec: 0x00
src_addr: 192.168.1.31
tos: 0x00
ttl: 63
type: tcp
tcp:
dst_port: 1071
flags:
- ACK
- PSH
res: 0x00
src_port: 25
urgp: 0
window: 57352
in_int: eth1
leftover: ~
line: >-
Nov 29 10:52:11 malloc kernel: in: IN=eth1 OUT= MAC= SRC=10.9.8.46 DST=192.168.0.208 LEN=801 TOS=0x00 PREC=0x00 TTL=115 ID=3391 PROTO=UDP SPT=31466 DPT=1026 LEN=781
mac: ~
out_int: ~
ip:
dst_addr: 192.168.0.208
id: 3391
len: 801
prec: 0x00
src_addr: 10.9.8.46
tos: 0x00
ttl: 115
type: udp
udp:
dst_port: 1026
len: 781
src_port: 31466
in_int: ppp0
leftover: ~
line: >-
Nov 30 09:54:51 malloc kernel: in: IN=ppp0 OUT= MAC= SRC=10.0.0.34 DST=192.168.143.41 LEN=37 TOS=0x00 PREC=0x00 TTL=115 ID=61772 PROTO=ICMP TYPE=8 CODE=0 ID=256 SEQ=8403
mac: ~
out_int: ~
ip:
dst_addr: 192.168.143.41
id: 61772
len: 37
prec: 0x00
src_addr: 10.0.0.34
tos: 0x00
ttl: 115
type: icmp
icmp:
code: 0
id: 256
seq: 8403
type: 8
in_int: ppp0
leftover: ~
line: >-
Nov 28 11:17:33 malloc kernel: in: IN=ppp0 OUT= MAC= SRC=192.168.2.113 DST=192.168.0.223 LEN=492 TOS=0x00 PREC=0x00 TTL=240 ID=39184 PROTO=ICMP TYPE=3 CODE=3 [SRC=192.168.0.223 DST=192.168.2.113 LEN=464 TOS=0x00 PREC=0x00 TTL=52 ID=58665 DF PROTO=TCP SPT=34373 DPT=80 WINDOW=63712 RES=0x00 ACK PSH FIN URGP=0 ]
mac: ~
out_int: ~>
ip:
dst_addr: 192.168.0.223
id: 39184
len: 492
prec: 0x00
src_addr: 192.168.2.113
tos: 0x00
ttl: 240
type: icmp
icmp:
code: 3
type: 3
error_header:
leftover: ~
line: >-
SRC=192.168.0.223 DST=192.168.2.113 LEN=464 TOS=0x00 PREC=0x00 TTL=52 ID=58665 DF PROTO=TCP SPT=34373 DPT=80 WINDOW=63712 RES=0x00 ACK PSH FIN URGP=0
ip:
dst_addr: 192.168.2.113
fragment_flags:
- DF
id: 58665
len: 464
prec: 0x00
src_addr: 192.168.0.223
tos: 0x00
ttl: 52
type: tcp
tcp:
dst_port: 80
flags:
- ACK
- PSH
- FIN
res: 0x00
src_port: 34373
urgp: 0
window: 63712


There are probably some corner cases that this module can't parse correctly. I haven't tested, in particular, AH, ESP, other non-tcp/udp/icmp protocols, ICMP packets of type 11 (parameter problem), 5 (redirect), and 4 (source quench). It also has some problems with logs from bridging firewalls. I haven't tested ebtables logs at all.
It doesn't even pretend to support IPv6. It shouldn't be too hard to do, but I don't have any IPv6 networks to test with. All the code is in /usr/src/linux/net/ipv6/netfilter/ip6t_LOG.c, though. Patches welcome.
Doesn't support --log-tcp-sequence, --log-tcp-options, or --log-ip-options. It won't throw the whole line out, though, it'll do the best it can and hand you the leftovers in the 'leftover' field of the hashref.
Doesn't support get_one(), get_one_start(), or get_pending(). This means switching from this filter to another filter probably won't work, but I haven't tried it.
Doesn't support put(), though it would be cool to be able to take iptables logs and write the iptables commands used to generate them.

Paul Visscher, <paulv@cpan.org>

Copyright (C) 2004-2005 by Paul Visscher
This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.8.4 or, at your option, any later version of Perl 5 you may have available.