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
_______________________________________________
dtrace-discuss mailing list
dtrace-discuss@opensolaris.org

Reply via email to