我想使用dtrace来显示有关tcp连接,接受和数据发送的信息......但我还想显示端口和IP信息。
有没有办法在osx上这样做?我注意到osx没有TCP提供程序(与solaris不同),但还有另一种方法吗?
答案 0 :(得分:2)
OSX 确实拥有TCP提供商。以下是如何确认:
sudo dtrace -l | perl -pe 's/^.*?\S+\s+(\S+?)([0-9]|\s).*/\1/' | sort | uniq
以下DTrace脚本已在macOS 10.13 High Sierra和10.12 Sierra上进行了测试。
像这样调用:
sudo ./tcpsnoop.d 2>/dev/null
#!/usr/sbin/dtrace -s
#pragma D option quiet
#pragma D option switchrate=10hz
dtrace:::BEGIN
{
printf("%6s %20s %15s:%-5s %15s:%-5s %6s %s\n",
"TIME", "CMD", "LADDR", "PORT", "RADDR", "PORT", "BYTES", "FLAGS");
}
tcp:::send
{
this->length = args[2]->ip_plength - args[4]->tcp_offset;
printf("%6d %20s %15s:%-5d -> %15s:%-5d %6d (",
timestamp/1000, execname, args[2]->ip_saddr,
args[4]->tcp_sport, args[2]->ip_daddr, args[4]->tcp_dport,
this->length);
}
tcp:::receive
{
this->length = args[2]->ip_plength - args[4]->tcp_offset;
printf("%6d %20s %15s:%-5d <- %15s:%-5d %6d (",
timestamp/1000, execname, args[2]->ip_daddr,
args[4]->tcp_dport, args[2]->ip_saddr, args[4]->tcp_sport,
this->length);
}
tcp:::send,
tcp:::receive
{
printf("%s", args[4]->tcp_flags & TH_FIN ? "FIN|" : "");
printf("%s", args[4]->tcp_flags & TH_SYN ? "SYN|" : "");
printf("%s", args[4]->tcp_flags & TH_RST ? "RST|" : "");
printf("%s", args[4]->tcp_flags & TH_PUSH ? "PUSH|" : "");
printf("%s", args[4]->tcp_flags & TH_ACK ? "ACK|" : "");
printf("%s", args[4]->tcp_flags & TH_URG ? "URG|" : "");
printf("%s", args[4]->tcp_flags & TH_ECE ? "ECE|" : "");
printf("%s", args[4]->tcp_flags & TH_CWR ? "CWR|" : "");
printf("%s", args[4]->tcp_flags == 0 ? "null " : "");
printf("\b)\n");
}
输出:
TIME CMD LADDR:PORT RADDR:PORT BYTES FLAGS
146791177843 curl 192.168.232.2:56775 -> 151.101.65.69:80 16172 (SYN)
146791206127 curl 192.168.232.2:56775 -> 151.101.65.69:80 35052 (PUSH|ACK)
146791390070 curl 192.168.232.2:56775 -> 151.101.65.69:80 13292 (FIN|ACK)
有关如何扩展它的一些建议:
将过滤器/execname == $1/
添加到三个块tcp:::send
,tcp:::receive
,tcp:::send, tcp:::receive
中的每一个块上。
这允许您按进程名称进行筛选:
sudo ./tcpsnoop.d 2>/dev/null curl
将过滤器/progenyof($target) || pid == $target/
添加到三个块tcp:::send
,tcp:::receive
,tcp:::send, tcp:::receive
中的每一个块上。
这允许您按PID过滤:
pgrep 'pritunl-openvpn' | xargs -n 1 sudo ./tcpsnoop3.d 2>/dev/null -p