The Fork
http://the.fork.pl/code/saker/
 the.fork.pl
 Site
 Credits
 Contact
 Powered by
 The Story of Fork
 Words
 Sermon on the Hill
 Antybiografia
 Angel
 Devil
 Powrót z...
 Simon T.
 Favourite poems
 Roam
 Sounds
 The Lost Faith
 Atari Reloaded
 Players
 Code
 Saker
 Moon phase
 KB24
 Attic
 PLC
 33doi
 DemoScene
 Atari
 Logrus
 Cryogen
 Crew
 History
 Stuph
 Pictures
 Ascii Art
 Set One
 Set Two
 Set Three

Saker - Bandwidth stats per MAC

Introduction

This is little utility that gathers statistics for network bandwith. Tested on FreeBSD, probably won't work on Linux without changes. Needs FreeBSD 4.6 or later (because of poll(2) behavior on BPF devs).

Features

  • Layer 2 oriented
  • monitoring multiple interfaces
  • configurable output
  • DNS resolving (off by default)
  • pcap-style filter expressions

Download

download saker.cc 22.1K

Compile

 

Example output

# saker -iem0 -iem1 -iem2 -iem3 -b -n0 -c -t5 -p -m10 -l -X

saker v1.41
Listening on: em0 em1 em2 em3

Interfaces: em0 em1 em2 em3
Total packets: 22.29 KPkt (4.45 KPkts/s)
Total size: 15.07 MB (3.01 MB/s, 24.11 MBits/s)
SRC stats:
    4.07 MB  27.0 %   ckul-xchg
    3.47 MB  23.1 % * 00:0e:0c:59:77:72
    2.84 MB  18.9 % * xchg-3
    2.35 MB  15.6 %   shodan
    1.18 MB   7.8 % * xchg-2
  535.00 KB   3.5 %   k-antczak1
  201.57 KB   1.3 %   kolos
  129.90 KB   0.8 %   root
   82.76 KB   0.5 %   b203-asus
   68.38 KB   0.4 %   ping
DST stats:
    4.07 MB  27.0 % * 00:0e:0c:59:77:72
    3.47 MB  23.1 %   ckul-xchg
    2.75 MB  18.3 %   shodan
    2.42 MB  16.1 % * xchg-3
  849.05 KB   5.5 % * xchg-2
  758.70 KB   4.9 %   k-antczak1
  218.02 KB   1.4 %   k-rodak-1
  214.83 KB   1.4 %   root
  211.20 KB   1.4 % * xchg
   98.14 KB   0.6 %   ping
 

The code

  1. /**
  2. * Saker, local net (layer 2) stats for bsd
  3. * written by Jan Pustelnik, Marcin Gryszkalis
  4. * no license, grab the code and run.
  5. *
  6. * Requires FreeBSD 4.6 or later (because of poll(2) behavior on BPF devs)
  7. *
  8. * Compile with
  9. * $ c++ -o saker -lpcap saker.cc
  10. *
  11. * $Id: saker.cc,v 1.42 2006/04/19 22:15:02 mg Exp $
  12. */
  13.  
  14. // system and C includes
  15. #include <pcap.h>
  16. #include <cstdio>
  17.  
  18. #include <sys/types.h>
  19. #include <sys/sysctl.h>
  20. #include <unistd.h>
  21. #include <sys/socket.h>
  22. #include <ifaddrs.h>
  23. #include <stdio.h>
  24. #include <netdb.h>
  25. #include <net/if_dl.h>
  26. #include <net/route.h>
  27. #include <net/if_types.h>
  28. #include <netinet/in.h>
  29. #include <netinet/if_ether.h>
  30. #include <arpa/inet.h>
  31. #include <signal.h>
  32. #include <time.h>
  33. #include <poll.h>
  34. #include <errno.h>
  35.  
  36. #define SAKER_INT unsigned long long
  37.  
  38. // C++ includes
  39. #include <string>
  40. #include <iostream>
  41. #include <set>
  42. #include <map>
  43. #include <algorithm>
  44. #include <iterator>
  45. // container that keeps pairs (MAC, count) representing src
  46. // addresses of packets ordered by MAC adress
  47. // same for dst addresses
  48. // container that keeps pairs (MAC, count)
  49. // representing src addresses of packets
  50. // ordered by count of packets (or count of bytes)
  51. // same for dst addresses
  52. // keeps list of own macs (for -r/-l handling)
  53. // on by dafault!
  54. #define MAX_IFACES (16)
  55. #define PCAP_MAX_PKT_PER_DISPATCH (256)
  56.  
  57. #define DEFAULT_PKT_CNT (100)
  58. #define DEFAULT_DELAY (10)
  59. // number of packets actually grabbed
  60. // PCAP callback function, grabs the packet
  61. "%02x:", pkt[i + 6]);
  62.     buf[17] = '\0';
  63.  
  64.     string s1(buf);
  65.     mit=src.find(s1);   // find element of src having MAC equal to s1
  66. // not found, create
  67. // found, increase count
  68. "%02x:", pkt[i]);
  69.     buf[17] = '\0';
  70.  
  71.     string s2(buf);
  72.     mit=dst.find(s2);   // same for dst
  73. //    if (g_debug)
  74. //        cout << s1 << " ->> " << s2 << endl;
  75. }
  76.  
  77.  
  78. // resolver stuff
  79. // trim hostname
  80. '.''\0'#define ROUNDUP(a) \
  81. /* Retrieve routing table */"Error: route-sysctl-estimate failed""Error: malloc failed""Error: retrieval of routing table failed"// check if already in the cache
  82. // save to cache
  83. "MAC: "" -> ""Resolve MAC: " << mac << endl;
  84.  
  85.     string h;
  86.     hit = resolver.find(mac);   // find in the cache
  87. // not found, rebuild cache
  88. // still not found
  89. "Resolve MAC (done): ""DEBUG uncount: " << x.first << " " << *cnt_var << endl;
  90.         }
  91.     }
  92. };
  93.  
  94. // utility for printing pairs to output stream
  95. //    bool g_mac_cnt;
  96. /*        if (mc != DEFAULT_MAC_CNT)
  97.             g_mac_cnt = true;
  98.         else
  99.             g_mac_cnt = false; */"DEBUG: erased: "//cerr << "((" << g_mac_cnt << ":" << _mac_cnt << ":" << (_mac_cnt==0) << "))" << endl;
  100. "%10sB""%10sPkt", f1);
  101.         }
  102.  
  103.         os <<  f << " "" %4.1f ""%"" * ""   "// resolve_ip is checked inside
  104. // utility for reverting pairs
  105. // input:  pair (A, B)
  106. // output: pair (B, A)
  107. // Converts a size to a human readable format.
  108. "%llu  ""%llu.%02llu K""%llu.%02llu M""%llu.%02llu G", number, reminder);
  109.                 }
  110.             }
  111.         }
  112.     }
  113.  
  114. // cerr << "!" << size << "!" << number << "!" << output << "!" << endl;
  115. //  strNumber.Replace(".00", "");
  116. // container that keeps pairs (MAC, count)
  117. // representing src addresses of packets
  118. // ordered by count of packets
  119. // same for dst addresses
  120. // count the packets-per-second
  121. "Interfaces: "" ""Total packets: " << hpkt << "Pkt (" << hpps << "Pkts/s)""Total size: " << hsize << "B (" << hbps << "B/s, " << hbbps << "Bits/s)" << endl;
  122. //    cout << "Macs: " << mac_cnt << endl;
  123. "SRC stats:"// we have first to copy all stats from src, which is ordered by MAC to src_score
  124.         // which is ordered by count, making possible printing stats ordered by count
  125. // and now we simply print stats by count :)
  126. "DST stats:"// same for dst
  127. "saker: shutdown"// show usage
  128. "$Revision: 1.42 $"'\0'// skip prefix
  129. "saker v""i:n:m:t:clapbhvorsdxXf:VD"'i'"Error: too many interfaces specified"'n''m''t''a''p''b''h''v''r''l''o''x''X''c''d'"Error: You cannot have both -d and -s."'s'"Error: You cannot have both -d and -s."'f''V''D''?'"Error: Unknown command line option.""Error: Interface(s) not specified.""Usage: saker [-apbrmvhVD] [-n num] [-m num] [-s|-d] [-c -t num] [-f 'expr'] -i <if> [-i <if2> ... ]" << endl
  130.             << "  -i <if>   network interface (many interfaces can be specified)" << endl
  131.             << "  -h        show this info" << endl
  132.             << "  -n num    number of packets to capture (default "", -1 for unlimited)" << endl
  133.             << "  -a        ascending sort (default descending)" << endl
  134.             << "  -m num    number of MACs to display in summary (all by default)" << endl
  135.             << "  -p        show percentage" << endl
  136.             << "  -b        count bytes (instead of packets)" << endl
  137.             << "  -r        count only remote ends (exclude own MACs)" << endl
  138.             << "  -l        mark local MACs with asterisk (see also -r)" << endl
  139.             << "  -s        show only source stats" << endl
  140.             << "  -d        show only destination stats" << endl
  141.             << "  -x        resolve MACs to IPs" << endl
  142.             << "  -X        resolve IPs to hostnames (implies -x)" << endl
  143.             << "  -c        continuous mode" << endl
  144.             << "  -o        turn off promiscuous mode" << endl
  145.             << "  -t num    time delay for continuous mode in seconds (default "")" << endl
  146.             << "  -f 'expr' expr is a pcap-style BPF expression (man tcpdump)" << endl
  147.             << "  -v        be verbose (e.g. output each packet)" << endl
  148.             << "  -V        print version and exit" << endl
  149.             << "  -D        enable debug output (you are not supposed to understand it)""Listening on: "" "// get own mac's
  150. "..:..:..:..:..:.."; // 6*2+5+1
  151. "Error: getifaddrs failed: ""Own MAC adresses:""%c%02x", ':'"%02x"" ("")""!\n"//initialize pcap
  152. "PCAP init for ""Error: pcap_lookupnet failed: ""Error: cannot open pcap live: ""Error: cannot set nonblocking mode: ""Error: cannot compile BPF filter expression ("
  153.                             << pcap_geterr(dv[i].pcap)
  154.                             << ")""Error: cannot install BPF filter ("
  155.                             << pcap_geterr(dv[i].pcap)
  156.                             << ")"// init for poll(2)
  157. "Error: pcap_get_selectable_fd failed""pcap_selectable_fd: " << dv[i].device << "=" << dv[i].pfd.fd << endl;
  158.  
  159.         dv[i].pfd.events = POLLRDNORM;
  160.         pollfdtab[i] = dv[i].pfd;
  161.     }
  162.  
  163.     // the main loop
  164. "Error: poll failed"//                cerr << "POLL(" << pollret << ")" << endl;
  165. "Error: error during pcap dispatch ("
  166.                                 << pcap_geterr(dv[i].pcap)
  167.                                 << ")"
Last modified: 2006-11-04 01:40:44 (v423)   Valid XHTML 1.0

(c) 2009 Marcin Gryszkalis