DTrace действительно работает в области ядра и практически не жрет ресурсов. Это что-то наподобие интеловского VTune, встроенное в операционную систему. Он позволяет отслеживать события операционной системы и перехватывать параметры этих событий.
Существует программа для организации туннеля, в котором трафик жмется и шифруется. Требуется померять, сколько данных вошло в туннель, в какое количество трафика они превратились при передаче по сети и то же самое - в обратную сторону. Эти 4 числа выдаются на стандарный вывод каждые 20 минут.
192.168.1.2 - IP точки туннеля на машине, где запущен скрипт
10.0.10.32 - IP машины, где запущен скрипт
10.0.10.33 - IP машины, где находится вторая точка туннеля
11111 - это TCP-порт, по которому передаются данные, завернутые в туннель
#!/usr/sbin/dtrace -s
#pragma D option quiet
#pragma D option switchrate=10hz
dtrace:::BEGIN
{
tun0in=0;
tun0out=0;
bge0in=0;
bge0out=0;
}
profile:::tick-20min{
printf("%d\t%d\t%d\t%d\t\n",
tun0in,tun0out,bge0in,bge0out);
tun0in=0;
tun0out=0;
bge0in=0;
bge0out=0;
}
ip:::send
/args[2]->ip_saddr=="192.168.1.2"/
{
tun0in+=args[4]->ipv4_length;
}
ip:::send
/args[2]->ip_saddr=="10.0.10.32" && args[2]->ip_daddr=="10.0.10.33" && args[4]->ipv4_protocol==6 && (unsigned int)(*(((char*)args[4]->ipv4_hdr)+22))*256+(unsigned int)(*(((char*)args[4]->ipv4_hdr)+23))==11111/
{
bge0in+=args[4]->ipv4_length;
}
ip:::receive
/args[2]->ip_daddr=="192.168.1.2"/
{
tun0out+=args[4]->ipv4_length;
}
ip:::receive
/args[2]->ip_daddr=="10.0.10.32" && args[2]->ip_saddr=="10.0.10.33" && args[4]->ipv4_protocol==6 && (unsigned int)(*(((char*)args[4]->ipv4_hdr)+20))*256+(unsigned int)(*(((char*)args[4]->ipv4_hdr)+21))==11111/
{
bge0out+=args[4]->ipv4_length;
}
Более подробное описание применения DTrace для сбора сетевой статистики
http://sunhelp.ru/archives/200-DTrace_ip_Provider_budet_vkljuchen_v_Solaris_Express.html#extendedСпособ определения порта - чтение TCP-заголовка. В snv_94 работает. Не знаю, будет ли он работать в следующих версиях.