tcpv4connect.php 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. <?php
  2. $bpf_text = <<<EOT
  3. #include <uapi/linux/ptrace.h>
  4. #include <net/sock.h>
  5. #include <bcc/proto.h>
  6. BPF_HASH(currsock, u32, struct sock *);
  7. int kprobe__tcp_v4_connect(struct pt_regs *ctx, struct sock *sk)
  8. {
  9. u32 pid = bpf_get_current_pid_tgid();
  10. // stash the sock ptr for lookup on return
  11. currsock.update(&pid, &sk);
  12. return 0;
  13. };
  14. int kretprobe__tcp_v4_connect(struct pt_regs *ctx)
  15. {
  16. int ret = PT_REGS_RC(ctx);
  17. u32 pid = bpf_get_current_pid_tgid();
  18. struct sock **skpp;
  19. skpp = currsock.lookup(&pid);
  20. if (skpp == 0) {
  21. return 0; // missed entry
  22. }
  23. if (ret != 0) {
  24. // failed to send SYNC packet, may not have populated
  25. // socket __sk_common.{skc_rcv_saddr, ...}
  26. currsock.delete(&pid);
  27. return 0;
  28. }
  29. // pull in details
  30. struct sock *skp = *skpp;
  31. u32 saddr = skp->__sk_common.skc_rcv_saddr;
  32. u32 daddr = skp->__sk_common.skc_daddr;
  33. u16 dport = skp->__sk_common.skc_dport;
  34. // output
  35. bpf_trace_printk("trace_tcp4connect %x %x %d\\n", saddr, daddr, ntohs(dport));
  36. currsock.delete(&pid);
  37. return 0;
  38. }
  39. EOT;
  40. $ebpf = new Ebpf($bpf_text);
  41. # header
  42. printf("%-6s %-12s %-16s %-16s %-4s\n", "PID", "COMM", "SADDR", "DADDR","DPORT");
  43. # format output
  44. while (true) {
  45. try {
  46. list($task, $pid, $cpu, $flags, $ts, $msg) =$ebpf->trace_fields();
  47. list($tag, $saddr_hs, $daddr_hs, $dport_s) = explode(" ", $msg, 4);
  48. printf("%-6d %-12.12s %-16s %-16s %-4s\n",
  49. $pid,
  50. $task,
  51. long2ip(unpack('V', pack('H*', $saddr_hs))[1]),
  52. long2ip(unpack('V', pack('H*', $daddr_hs))[1]),
  53. $dport_s
  54. );
  55. flush();
  56. } catch (Exception $e) {
  57. continue;
  58. }
  59. }