net_monitor.php 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. <?php
  2. if ($argc !== 2) {
  3. echo "Usage: php {$argv[0]} <net_interface>\n";
  4. echo "Example: php {$argv[0]} eno1\n";
  5. exit(1);
  6. }
  7. $INTERFACE = $argv[1];
  8. define("OUTPUT_INTERVAL", 1);
  9. $bpf_text = <<<EOT
  10. #include <uapi/linux/ptrace.h>
  11. #include <net/sock.h>
  12. #include <bcc/proto.h>
  13. #include <linux/bpf.h>
  14. #define IP_TCP 6
  15. #define IP_UDP 17
  16. #define IP_ICMP 1
  17. #define ETH_HLEN 14
  18. BPF_PERF_OUTPUT(skb_events);
  19. BPF_HASH(packet_cnt, u64, long, 256);
  20. int packet_monitor(struct __sk_buff *skb) {
  21. u8 *cursor = 0;
  22. u32 saddr, daddr;
  23. long* count = 0;
  24. long one = 1;
  25. u64 pass_value = 0;
  26. struct ethernet_t *ethernet = cursor_advance(cursor, sizeof(*ethernet));
  27. struct ip_t *ip = cursor_advance(cursor, sizeof(*ip));
  28. if (ip->ver != 4)
  29. return 0;
  30. if (ip->nextp != IP_TCP)
  31. {
  32. if (ip -> nextp != IP_UDP)
  33. {
  34. if (ip -> nextp != IP_ICMP)
  35. return 0;
  36. }
  37. }
  38. saddr = ip -> src;
  39. daddr = ip -> dst;
  40. pass_value = saddr;
  41. pass_value = pass_value << 32;
  42. pass_value = pass_value + daddr;
  43. count = packet_cnt.lookup(&pass_value);
  44. if (count) // check if this map exists
  45. *count += 1;
  46. else // if the map for the key doesn't exist, create one
  47. {
  48. packet_cnt.update(&pass_value, &one);
  49. }
  50. return -1;
  51. }
  52. EOT;
  53. $b = new Bpf(["text" => $bpf_text]);
  54. $func = $b->load_func("packet_monitor", Bpf::SOCKET_FILTER);
  55. $b->attach_raw_socket($func, $INTERFACE);
  56. $packet_cnt = $b->get_table("packet_cnt");
  57. function decimal_to_ip($int) {
  58. return long2ip($int);
  59. }
  60. while (true) {
  61. sleep(OUTPUT_INTERVAL);
  62. $items = $packet_cnt->values();
  63. $time = date("Y-m-d H:i:s");
  64. if (count($items) > 0) {
  65. echo "\nCurrent packet stats:\n";
  66. }
  67. foreach ($items as $entry) {
  68. $key = unpack("Q", $entry["key"])[1];
  69. $val = unpack("l", $entry["value"])[1];
  70. $src = ($key >> 32) & 0xFFFFFFFF;
  71. $dst = $key & 0xFFFFFFFF;
  72. echo sprintf(
  73. "source: %s -> destination: %s count: %d time: %s\n",
  74. decimal_to_ip($src),
  75. decimal_to_ip($dst),
  76. $val,
  77. $time
  78. );
  79. }
  80. $packet_cnt->clear();
  81. }