背景
机器上面不清楚有什么程序一直对外发包,需要抓取到这个行为,是谁发起的
通过普通的netstat或者ss进行判断,然后进行抓取,这个方式无法满足发送又马上释放了的情况
抓取方法
编写一个脚本udp_count.bt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| #!/usr/bin/env bpftrace
BEGIN { printf("=== UDP统计开始,每分钟输出一次快照 ===\n"); }
kprobe:udp_sendmsg { $sk = (struct sock *)arg0; $msg = (struct msghdr *)arg1;
/* * sendto()/sendmsg() * 优先从 msg_name 获取本次发送的真实目标地址 */ if ($msg->msg_name != 0) { $sa = (struct sockaddr *)$msg->msg_name;
/* * AF_INET = 2 * 当前只统计 IPv4 UDP */ if ($sa->sa_family == 2) { $sin = (struct sockaddr_in *)$msg->msg_name;
$daddr = ntop($sin->sin_addr.s_addr); $dport = bswap($sin->sin_port);
@udp_count[comm, pid, $daddr, $dport] = count(); } } else { /* * connect() 后的 UDP send()/sendmsg() * 从 socket 获取目标地址 */ $daddr_raw = $sk->__sk_common.skc_daddr; $dport_raw = $sk->__sk_common.skc_dport;
if ($daddr_raw != 0 && $dport_raw != 0) { $daddr = ntop($daddr_raw); $dport = bswap($dport_raw);
@udp_count[comm, pid, $daddr, $dport] = count(); } } }
/* * 每 60 秒输出一次 */ interval:s:60 { printf("\n=== UDP统计快照 (%s) ===\n", strftime("%Y-%m-%d %H:%M:%S", nsecs));
print(@udp_count);
/* * 清零,因此统计的是“最近一分钟” */ clear(@udp_count); }
END { printf("\n=== 最终统计 ===\n"); print(@udp_count); }
|
运行抓取
效果
1 2
| === UDP统计快照 (2026-08-19 10:32:57) === @udp_count[ping, 2678, 192.168.0.1, 33531]: 1
|
这样就可以摘取到发送的行为了,可以根据自己的需要对脚本进行调整