Linux/NetworkPacketMonitoringWithAwk: icmp-monitor.awk

File icmp-monitor.awk, 3.2 KB (added by tj, 9 years ago)

Monitors ICMP traffic and reports packet loss

Line 
1#!/usr/bin/awk -f
2# icmp-monitor.awk
3# Copyright 2008 TJ <linux@tjworld.net>
4# Licensed under the GNU GPL v3
5#
6# Monitors live tcpdump ICMP ping request/reply packet reports, looking for packet loss.
7# Designed for use with a SPAN (Switched Port ANalyser) or on a regular host. The combination
8# of tcpdump and this script enables multiple ping sessions to be dynamically recognised and
9# monitored.
10
11# Usage:
12#
13# INTERFACE=eth0
14# DEBUG=1
15# sudo tcpdump -i $INTERFACE  -n -l -O icmp | awk -v debug=$DEBUG -f icmp-monitor.awk
16#
17# When setting a debug level, the recognised values are: 0-4
18#   0 = no debug output
19#   1 = new sessions
20#   2 = + function names
21#   3 = + summary for every packet
22#   4 = + raw tcpdump output
23#
24# To stop the monitor cleanly send SIGINT to the tcpdump process. If you use Ctrl+C at the
25# terminal it will also interrrupt awk, which will prevent it printing the final summary
26# statistics.
27# e.g. sudo kill -s INT $(pidof tcpdump)
28#
29BEGIN {
30 session_count=0;
31}
32
33function get_current_session(source, destination) {
34 if(debug>=2) print "get_current_session(",source,",",destination,") session count=" session_count;
35
36 session=0;
37
38 # quick way to conditionally remove any trailing colon
39 split(source, source_address, ":");
40 split(destination, destination_address, ":");
41
42 if(session_count > 0) {
43  # do we already know of this host address?
44  for(i=1; i <= session_count; i++) {
45   if(sources[i] == source_address[1] && destinations[i] == destination_address[1] ) {       
46    session=i;
47    break;
48   }
49  }
50 }
51
52 if(session == 0) {
53  # not known, so add to known list
54  session = ++session_count;
55  sources[session]=source_address[1];
56  destinations[session]=destination_address[1];
57  # reset the counters for this session
58  packets_sent[session]=0;
59  packets_received[session]=0;
60  packets_dropped[session]=0;
61  if (debug>=1) {
62   print "Adding session #", session, "@", sources[session], ">", destinations[session];
63  }
64 }
65 return session;
66}
67
68function get_clean(value) {
69 split(value, parts, ",");
70 return parts[1];
71}
72
73function report(session, append) {
74 print timestamps[session], "session #" session, "(" sources[session],">", destinations[session] ")", "requests=" packets_sent[session], "reqst-ID=" request[session], "reply-ID=" reply[session], "dropped=" packets_dropped[session], append;
75}
76
77{
78 if(debug>=4) print $0;
79}
80
81$0 ~ /echo request/ {
82 current_session=get_current_session($3, $5);
83
84 if(current_session > 0) {
85  # check whether the previous packet was dropped
86  if(reply[current_session] == -1 && request[current_session] != NULL) {
87   packets_dropped[current_session]++;
88   report(current_session, "[dropped]");
89  }
90
91  request[current_session]=get_clean($12);
92  reply[current_session]="-1";
93  packets_sent[current_session]++;
94  timestamps[current_session]=$1;
95 }
96}
97
98$0 ~ /echo reply/ {
99 current_session=get_current_session($5, $3);
100 reply[current_session]=get_clean($12);
101 packets_received[current_session]++;
102}
103
104{
105 if(debug>=3) report(current_session, "[debug]");
106}
107
108END {
109 for(i=1; i <= session_count; i++) {
110  drop = packets_dropped[i] / (packets_sent[i] / 100);
111  print "Session #" i, "(" sources[i],">", destinations[i] ")", "requests", packets_sent[i], "dropped", drop "%";
112 }
113}