Re: help returning a value on a line...
From: John W. Krahn (someone_at_example.com)
Date: 04/21/05
- Next message: mystiq_at_risp.pl: "Retrieve an element from an array"
- Previous message: Stephane CHAZELAS: "Re: Can Ctrl chars be passed as arguments?"
- In reply to: Stachu 'Dozzie' K.: "Re: help returning a value on a line..."
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Thu, 21 Apr 2005 20:05:05 GMT
Stachu 'Dozzie' K. wrote:
> On 21.04.2005, matt_left_coast <Not@given.org> wrote:
>
>>Ok, this just may be something where I have read right past the answer but
>>here it goes...
>>
>>I am trying to write a script to track destination ports of packets that are
>>dropped by iptables in linux. It seems like it would be an easy task with
>>something like awk or sed and I have searched for an answer. I can replace
>>the value with sed and I have a way of printing the value with awk but it
>>is cumbersome because the value is not in the same place for each line.
>>
>>Basically this is what I want to do...
>>
>>Take a line from the /var/log/messages file like
>>
>>Apr 20 21:22:48 bear kernel: Shorewall:net2all:DROP:IN=eth0 OUT= \
>>MAC=00:01:29:ff:f0:a4:00:11:5d:c3:70:8c:08:00 SRC=207.162.252.35 \
>>DST=64.121.65.132 LEN=908 TOS=0x00 PREC=0x00 TTL=119 ID=486 PROTO=UDP \
>>SPT=2612 DPT=1026 LEN=888
>>
>>I want to pick out "SRC=" and the "DPT=" The place on the line for SRC= is
>>the same so it is easy to pick out using awk '{print $5}' but the "DPT="
>>can be at $16, $17, $18, or $19. What I would like to find is a way to find
>>(but not replace) the numeric position (16, 17 18 or 19) of "DPT" so I can
>>cut it out of the line -or- better yet, that would just return "DPT=nnn".
>
>
> I'm using Perl script (very ugly, but I have no time for fixing it) for
> such task:
>
> #v+
> #!/usr/bin/perl -nw
>
> use Sys::Hostname;
>
> BEGIN {
> print "date time in out src IP SPT dest IP DPT Protocol([type]code)\n";
> $host = hostname;
> chomp $host;
> }
>
> # XXX: I'm using -j LOG --log-prefix 'firewall ', so I can `grep -v'
> # non-firewall lines
> next unless /firewall/;
>
> @fields = split;
>
> # time of event
> if (/$host/o) {
> printf "%-3.3s %-2.2s %-8.8s ", $fields[0], $fields[1], $fields[2];
> } else {
> print "--- -- -------- ";
> }
>
> # in/out interfaces
> printf "%-4s ", ($_[1])?$_[1]:"----"
> if ( @_ = split(/=/, join('=', grep(/^IN/, @fields))) );
> printf "%-4s ", ($_[1])?$_[1]:"----"
> if ( @_ = split(/=/, join('=', grep(/^OUT/, @fields))) );
>
> # source IP and port
> printf "%-15s ", ($_[1])?$_[1]:"----"
> if ( @_ = split(/=/, join('=', grep(/^SRC/, @fields))) );
> if ( @_ = split(/=/, join('=', grep(/^SPT/, @fields))) ) {
> printf "%-5s ", ($_[1])?$_[1]:"----";
> } else {
> print " ";
> }
>
> # destination IP and port
> printf "%-15s ", ($_[1])?$_[1]:"----"
> if ( @_ = split(/=/, join('=', grep(/^DST/, @fields))) );
> if ( @_ = split(/=/, join('=', grep(/^DPT/, @fields))) ) {
> printf "%-5s ", ($_[1])?$_[1]:"----";
> } else {
> print " ";
> }
>
> # protocol name
> print( ($_[1])?$_[1]:"----" )
> if ( @_ = split(/=/, join('=', grep(/^PROTO/, @fields))) );
> # second protocol (for ICMP unreachable)
> print "|$_[3]" if ($_[3]);
>
> if ($_[1] eq 'ICMP' || (@_ >= 3 && $_[3] eq 'ICMP')) {
> @_ = split(/=/, join('=', grep(/^TYPE/, @fields)));
> print "([$_[1]]";
> @_ = split(/=/, join('=', grep(/^CODE/, @fields)));
> print "$_[1])";
> }
>
> print "\n";
> #v-
You can pretty it up a bit by using a hash for the fields:
#!/usr/bin/perl -nw
use Sys::Hostname;
BEGIN {
print "date time in out src IP SPT dest IP
DPT Protocol([type]code)\n";
$host = hostname;
}
# XXX: I'm using -j LOG --log-prefix 'firewall ', so I can `grep -v'
# non-firewall lines
next unless /firewall/;
%fields = map /([^=]+)=(\S+)/, split;
# time of event
if (/\b$host\b/o) {
printf "%-3.3s %-2.2s %-8.8s ", /^(\S+)\s+(\S+)\s+(\S+)/;
} else {
print "--- -- -------- ";
}
# in/out interfaces
printf '%-4s ', $fields{IN} || '----';
printf '%-4s ', $fields{OUT} || '----';
# source IP and port
printf '%-15s ', $fields{SRC} || '----';
printf '%-5s ', $fields{SRC} ? $fields{SPT} ? $fields{SPT} : '----' : ' ';
# destination IP and port
printf '%-15s ', $fields{DST} || '----';
printf '%-5s ', $fields{DST} ? $fields{DPT} ? $fields{DPT} : '----' : ' ';
# protocol name
print $fields{PROTO} || '----';
# second protocol (for ICMP unreachable)
#print "|$_[3]" if $_[3]; # Not sure which field this is??
if ( /\bICMP\b/ ) {
print "([$fields{TYPE}]$fields{CODE})";
}
print "\n";
John
-- use Perl; program fulfillment
- Next message: mystiq_at_risp.pl: "Retrieve an element from an array"
- Previous message: Stephane CHAZELAS: "Re: Can Ctrl chars be passed as arguments?"
- In reply to: Stachu 'Dozzie' K.: "Re: help returning a value on a line..."
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|