This becomes interesting. truss shows an ipv6 address for some processes, like sshd (ipv4 encapsulated in ipv6), although there is no configured ipv6 interface.
909: accept(3, 0x08047A10, 0x08047E78, SOV_DEFAULT) = 4
909: AF_INET6 name = ::ffff:172.31.70.6 port = 64625
When the probe fbt:sockfs:accept:return is fired , af_family is set to 26 (INET6) instead of 2 (INET). The return of an ipv6 address seems to be the reason for the value of 0 of (uint_t)self->sockcont->sin_addr.s_addr . I still have no glue how the struct sin_addr for ipv6 does look like, if and how it differs from the original ipv4 one.
Is there a way to find out the structs getting accessed when a probe is fired?
I've create created a perlscript, which uses IO::Socket::INET to create a listening socket. truss return the address family AF_INET and the ipv4 address.
23523: accept(4, 0x080475E8, 0x08047A00, SOV_DEFAULT) = 5
23523: AF_INET name = 172.31.70.6 port = 64622
With the following D I could catch the source ip and port. You're right, I've to distinguish the endianness. So it won't work on sparc.
What predicate could be used to differentiate between little and big endian?
Do you see a simpler way of the bit operations I'm doing to get the port and ip?
#!/usr/sbin/dtrace -qCs
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
fbt:sockfs:accept:entry
/ execname == "tcps.pl" /
{
self->sockaddr = arg1;
self->socklenp = arg2;
}
fbt:sockfs:accept:return
/ self->socklenp && execname == "tcps.pl" /
{
self->socklen = *(int *)copyin(self->socklenp, 4);
self->sockcont = (struct sockaddr_in *)copyin(self->sockaddr, self->socklen);
self->sockcont_nofamily = (struct sockaddr *)copyin(self->sockaddr, self->socklen);
self->port = self->sockcont->sin_port;
self->portB1 = self->port & 0xFF00;
self->portB1 >>= 8;
self->portB2 = self->port & 0xFF;
self->portB2 <<= 8;
self->portOk = self->portB2 | self->portB1;
self->ip = (uint_t)self->sockcont->sin_addr.s_addr;
oct4 = self->ip >> 24;
oct3 = self->ip >> 16;
oct2 = self->ip >> 8;
oct1 = self->ip;
oct1 &= 255;
oct2 &= 255;
oct3 &= 255;
oct4 &= 255;
printf("Process %s , Pid: %d got request from %d.%d.%d.%d (src Port %d)\n", execname, pid, oct1, oct2, oct3, oct4, self->portOk);
/*
printf("address family const got : %d\n", self->sockcont_nofamily->sa_family);
printf("address family const of ipv6: %d\n", AF_INET6);
printf("len %d\n", self->socklen);
printf("struct size: %d\n", sizeof( self->sockcont));
printf("port: %d ip: %d port1: %d port2: %d portall: %d\n", self->port, self->ip, self->portB1, self->portB2, self->portOk);
printf("socklen: %d \n", self->socklen);
printf("struct addrr: %x \n", self->sockaddr);
printf("struct len: %x\n", self->socklenp);
*/
}
--
This message posted from opensolaris.org