Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

How can I generate from this INPUT in "general"

INPUT (/proc/net/ip_conntrack)

udp      17 0 src=192.168.1.128 dst=91.120.112.125 sport=29249 dport=39802 packets=3 bytes=408 [UNREPLIED] src=91.120.112.125 dst=79.132.235.112 sport=39802 dport=29249 packets=0 bytes=0 mark=0 use=2
udp      17 146 src=192.168.1.128 dst=98.196.37.3 sport=56932 dport=43645 packets=924 bytes=406167 src=98.196.37.3 dst=79.132.235.112 sport=43645 dport=56932 packets=1042 bytes=546092 [ASSURED] mark=0 use=2
tcp      6 118 SYN_SENT src=192.168.1.129 dst=89.132.51.110 sport=2518 dport=47385 packets=2 bytes=104 [UNREPLIED] src=80.132.51.190 dst=79.132.235.112 sport=47385 dport=2518 packets=0 bytes=0 mark=0 use=2
udp      17 147 src=192.168.1.128 dst=98.196.37.7 sport=56937 dport=43647 packets=924 bytes=406167 src=98.196.37.7 dst=80.132.235.117 sport=43647 dport=56937 packets=1042 bytes=546092 [ASSURED] mark=0 use=2
tcp      6 119 SYN_SENT src=192.168.1.129 dst=89.132.51.110 sport=2514 dport=47384 packets=2 bytes=104 [UNREPLIED] src=80.132.51.194 dst=80.132.235.114 sport=47384 dport=2514 packets=0 bytes=0 mark=0 use=2
udp      17 163 src=192.168.1.111 dst=192.168.1.201 sport=67 dport=68 packets=29 bytes=9512 src=192.168.1.201 dst=192.168.1.1 sport=68 dport=67 packets=27 bytes=8856 [ASSURED] mark=0 use=2
tcp      6 1 TIME_WAIT src=192.168.1.201 dst=67.201.31.15 sport=55479 dport=80 packets=7 bytes=725 src=67.201.31.35 dst=79.132.235.112 sport=80 dport=55479 packets=5 bytes=1963 [ASSURED] mark=0 use=2

to this output?

OUTPUT

udp 192.168.1.128   3
tcp 192.168.1.129   2
udp 192.168.1.111   1
tcp 192.168.1.201   1

So that from the INPUT datas the OUTPUT would be 3 columns:

protocoll   src-ip-address  count-connection-numbers

So that the IP with the most number of connections would be at top.

share|improve this question

5 Answers 5

Using sed, uniq, sort, awk and column:

sed -n -r 's/^(udp|tcp)\s*[^=]*=([0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}).*$/\1 \2/p' infile \
  | sort | uniq -c | sort -nr | awk '{print $2" "$3" "$1'} | column -t > outfile
share|improve this answer

You can use perl one-liner to get it done, it's very easy!

perl -lane 'print "$F[0] $1" if /src=(.*?)\s/' /proc/net/ip_conntrack | sort | uniq -c | sort -rn -k 1
share|improve this answer

There are two steps: extract the protocol and source addresses, and collect and sort. You already know how to do the second, so let's see how to do the first.

You already had a way to extract the source addresses:

sed -ne 's/^.*src=\([^ ]*\).*/\1/p'

That extracts the last src= field though; here we want to extract the first. It's a bit inconvenient in sed, but can be done.

sed -n -e 's/\(src=[^ ]*\).*/\1/' -e 's/^.*src=\([^ ]*\).*/\1/p'

To retain the first field, just apply the last replacement to the part after the first space.

sed -n -e 's/\(src=[^ ]*\).*/\1/' -e 's/ .*src=\([^ ]*\).*/ \1/p'

This is terse and not very clear. Here's an about equally terse, but clearer way to get the same output with awk. Call match to find the extent of the first src= field, then print out the corresponding part of the line.

awk 'match($0, / src=[^ ]*/) {print $1 substr($0, RSTART, RLENGTH)}'

Finally, pipe into the second stage (sort, obtain counts, and sort by count).

awk 'match($0, / src=[^ ]*/) {print $1 substr($0, RSTART, RLENGTH)}' |
sort | uniq -c | sort -nr
share|improve this answer
    
s/ .*src= makes a greedy grab and returns the 2nd src= ip.. One alternative is 's/ [^=]*= –  Peter.O Jun 23 '11 at 19:20
    
@fred I shouldn't post so late at night, I hadn't even noticed the second src= field. s/ [^=]*=\([^ ]*\)/\1/p would work, but it would rely on src= being the first field with an equal sign, and that feels too inflexible. (P.S. I forget, do you do Perl? You may be interested in this text replacement benchmark.) –  Gilles Jun 23 '11 at 20:22
    
I too hadn't noticed the second src= until after I had +1'd your answer, based on a visual 'test', and then thought I'd better give it a 'real' test... Re. perl: I look on in awe :) –  Peter.O Jun 23 '11 at 22:25

Using awk and sort:

/usr/bin/awk -F" " '
{
  proto = $1
  for(i = 2; i <= NF; ++i) 
  {
    if ($i ~ /^src=/) 
    { 
      scrip = $i
      srcip = sub(/^src=/, "", scrip)
      key = proto SUBSEP scrip
      a[key]+=1
    }
  }
}
END {
  for (var in a)
  {
    split(var, subkey, SUBSEP)
    printf "%-5s %-18s %-8s\n", subkey[1], subkey[2], a[var]
  }
}
' infile | sort -rn -k3,3
share|improve this answer
    
Your output prints both instances (per line) of src=... The sample output requires only the first instance... –  Peter.O Jun 23 '11 at 19:42
#!/usr/bin/perl
use strict;
use warnings;

my %count;

# extract protocol and source-ip-address, count rows with same values
while(<>) {
  if (/^([^ ]+).*src=([0-9.]+)/) {
    $count{"$1 $2"}++;
  }
}

# sort by count
for my $p_src (sort {$count{$b} <=> $count{$a}} keys %count) {
  print "$p_src\t$count{$p_src}\n";
}

Example (your data isn't very interesting)

$ eg.pl eg.txt
tcp 67.201.31.35        1
tcp 80.132.51.190       1
tcp 80.132.51.194       1
udp 192.168.1.201       1
udp 91.120.112.125      1
udp 98.196.37.3 1
udp 98.196.37.7 1
share|improve this answer
    
Based on the sample output provided, only the first instance (per line) of src= ip should be printed... –  Peter.O Jun 23 '11 at 19:49

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.