KevinOrr

tcpdump filter by opt. src + dest ip, & disp freqs per proto

Oct 13th, 2014
245
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 3.44 KB | None | 0 0
  1. #!/usr/bin/python
  2. import sys
  3. import re
  4. import os.path
  5.  
  6. USAGE = 'Usage: {} [src_ip [dest_ip]] file'.format(sys.argv[0])
  7.  
  8. """Basically, this script takes a csv-like file, and gives a count of how many adjacent (e.g. line 44 and line 45) duplicate lines it finds.
  9. Additionally, it will filter based on optional src_ip and dest_ip arguments."""
  10.  
  11. IP_PATTERN = re.compile(r'^(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.'
  12.                        +r'(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.'
  13.                        +r'(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.'
  14.                        +r'(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])$')
  15.  
  16. def check_ips(*ip_name_pairs):
  17.     # Check for valid ips. If not valid, error and exit
  18.     for ip, name in ip_name_pairs:
  19.         if IP_PATTERN.match(ip) is None:
  20.             # print ip + ' is not a valid IPv4 address'
  21.             print 'Invalid ' + name + ' IP'
  22.             sys.exit()
  23.  
  24. filename = os.path.abspath(sys.argv[-1])
  25.  
  26. def get_packets(filename):
  27.     # if a valid file, return unfiltered lines
  28.     # else, error and exit
  29.     if not os.path. exists(filename) or not os.path.isfile(filename):
  30.         print 'File ' + sys.argv[-1] + ' does not exist'
  31.         sys.exit()
  32.     with open(filename) as f:
  33.         return [','.join(line.strip().replace('"', '').split(',')[2:5]) for line in f]
  34.  
  35.  
  36. # Begin filtering packets based on sys.argv
  37. if len(sys.argv) == 2:
  38.     lines = get_packets(filename)
  39. elif len(sys.argv) == 3:
  40.     check_ips((sys.argv[1], 'Source'))
  41.     lines = [line for line in get_packets(filename) if sys.argv[1] in line.split(',')[0]]
  42. elif len(sys.argv) == 4 and sys.argv[2] == '-s':
  43.     check_ips((sys.argv[2], 'Source'))
  44.     lines = [line for line in get_packets(filename) if sys.argv[2] in line.split(',')[0]]
  45. elif len(sys.argv) == 4 and sys.argv[2] == '-d':
  46.     check_ips((sys.argv[2], 'Destination'))
  47.     lines = [line for line in get_packets(filename) if sys.argv[2] in line.split(',')[1]]
  48. elif len(sys.argv) == 4:
  49.     check_ips((sys.argv[1], 'Source'), (sys.argv[2], 'Destination'))
  50.     lines = [line for line in get_packets(filename) if sys.argv[1] in line.split(',')[0] and sys.argv[2] in line.split(',')[1]]
  51. else:
  52.     # user must have entered either no arguments, or more than 3. Error and exit
  53.     print USAGE
  54.     sys.exit()
  55.  
  56. # Now actually count the frequencies
  57. counts = {}
  58. for line in lines:
  59.     if line in counts:
  60.         counts[line] += 1
  61.     else:
  62.         counts[line] = 1
  63.  
  64. # Print output header
  65. print "%20s %20s %15s %15s" % ("Source IP", "Destination IP", "Protocol", "Count")
  66.  
  67. last = ['', '', '']
  68. for line in sorted(counts.keys()):
  69.     line = line.split(',')
  70.     if [last[0], last[1]] == line[0:2]:
  71.          # if same src ip and dest ip as the last line,
  72.          # then only print the protocols, and their frequencies
  73.      print ('{:>57} {:>15}'
  74.         .format(line[2], counts[','.join(line)]))
  75.     elif last[0] == line[0]:
  76.          # if only same src ip as the last line,
  77.          # then start a new line, and print dest ip, protocols, and their frequencies
  78.      print ('\n{:>41} {:>15} {:>15}'
  79.         .format(line[1], line[2], counts[','.join(line)]))
  80.     else:
  81.          # if both src ip and dest ip are different from the line before,
  82.          # then begin a new line, and print everything
  83.          print ('\n{:>20} {:>20} {:>15} {count:>15}'    
  84.             .format(*line, count = counts[','.join(line)]))
  85.     last = line
  86.  
  87. # print the total count
  88. print '\n{:<40} Total: {:>14}'.format('', sum(counts.values()))
Add Comment
Please, Sign In to add comment