#!/usr/sbin/dtrace -CZqs /** Usage: $0 -32 -p $nscd_pid */ #include #define MAXNS 3 /* max # name servers we'll track */ #define MAXDNAME 256 /* maximum domain name */ #define MAXDNSRCH 6 /* max # domains in search path */ #define MAXADDR 10 /* max # addresses to sort by */ struct _res_state { int retrans; /* retransmition time interval */ int retry; /* number of times to retransmit */ long options; /* option flags - see below. */ int nscount; /* number of name servers */ struct sockaddr_in nsaddr_list[MAXNS]; /* address of name server */ #define nsaddr nsaddr_list[0] /* for backward compatibility */ u_short id; /* current packet id */ char defdname[MAXDNAME]; /* default domain */ char *dnsrch[MAXDNSRCH+1]; /* components of domain to search */ int ascount; /* number of addresses */ struct in_addr sort_list[MAXADDR]; /* address sorting list */ }; typedef struct _res_state *res_state; string LINEDELIM; string LINEDELIM2; dtrace:::BEGIN { LINEDELIM = "==============================================================="; LINEDELIM2 = "---------------------------------------------------------------"; } pid$target:libresolv.so.2:res_nsearch:entry { self->track = 1; this->rs = (res_state) copyin(arg0, sizeof(struct _res_state)); printf("\n\n%s\nLookup: %s (timeout:%d attempts:%d nameservers:%d)\n%s\n", LINEDELIM, copyinstr(arg1), this->rs->retrans, this->rs->retry, this->rs->nscount, LINEDELIM2); self->start0 = timestamp; } pid$target:libresolv.so.2:res_nsearch:return /self->track / { self->track = 0; this->to = timestamp - self->start0 + 500000; this->sec = this->to / 1000000000; this->to -= this->sec * 1000000000; this->ms = this->to / 1000000; printf("%s\nOverall time: %6d.%03d s\n", LINEDELIM, this->sec, this->ms); self->start0 = 0; } pid$target:libresolv.so.2:res_nquery:entry /self->track / { printf("Trying %s ...\n", copyinstr(arg1)); self->count = 0; self->start = timestamp; } pid$target:libresolv.so.2:res_nquery:return /self->track / { this->to = timestamp - self->start + 500000; this->sec = this->to / 1000000000; this->to -= this->sec * 1000000000; this->ms = this->to / 1000000; printf("time: %6d.%03d s\n", this->sec, this->ms); self->start = 0; self->count = 0; } pid$target:libresolv.so.2:send_dg:entry /self->track / { self->count++; self->last = timestamp; self->ns = (int) arg6; this->rs = (res_state) copyin(arg0, sizeof(struct _res_state)); self->retrans = this->rs->retrans; self->nscount = this->rs->nscount; self->tries = (int) arg7; } pid$target:libresolv.so.2:send_dg:return /self->track / { this->t = timestamp - self->last + 50000; this->ms = this->t / 1000000; this->t -= this->ms * 1000000; this->b = this->t / 100000; printf("%d. ns%d %5d.%d ms (retrans=%d nscount=%d tries=%d)\n", self->count, self->ns, this->ms, this->b, self->retrans, self->nscount, self->tries); self->retrans = 0; self->nscount = 0; self->tries = 0; self->last = 0; self->ns = 0; }