My first dtrace script...
I had a misbehaving application (I believed it was connecting to the wrong port based on a preference setting), so I figured I’d give dtrace a try and see if I could capture the connect() system call. After a fair amount of tweaking, I was finally able to capture what I was looking for. Here’s the script:
#pragma D option quiet
typedef uint32_t in_addr_t;
typedef uint8_t sa_family_t;
typedef uint16_t in_port_t;
struct in_addr {
in_addr_t s_addr;
};
struct sockaddr_in {
uint8_t sin_len;
sa_family_t sin_family;
in_port_t sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
dtrace:::BEGIN
{
/* print header */
printf("%5s %5s %-12s %4s %5s %s\n",
"UID", "PID", "CMD", "TYPE", "PORT", "IP_SOURCE");
}
syscall::connect:entry
/arg1/
{
sa = (struct sockaddr_in *) copyin(
arg1, sizeof(struct sockaddr_in));
printf("%5d %5d %-12s %4s %5d %d.%d.%d.%d\n",
uid, pid, execname, "tcp",
((sa->sin_port >> 8) | (sa->sin_port << 8)) & 0xFFFF,
sa->sin_addr.s_addr & 0xFF,
(sa->sin_addr.s_addr >> 8) & 0xFF,
(sa->sin_addr.s_addr >> 16) & 0xFF,
sa->sin_addr.s_addr >> 24);
}
And here’s sample output from loading the Slashdot page in Safari:
:: sudo dtrace -C -s snoop-connections.d
UID PID CMD TYPE PORT IP_SOURCE
501 83317 Safari tcp 80 66.35.250.150
501 83317 Safari tcp 80 66.35.250.150
501 83317 Safari tcp 80 66.35.250.55
501 83317 Safari tcp 80 66.35.250.55
501 83317 Safari tcp 80 66.35.250.55