trafd on FreeBSD

2006-03-26 23:18

FreeBSD 下有個好用的 network traffic log daemon
在 ports/net-mgmt/trafd
兩年前左右開始架 ftp 後 , 就用它來掌控機器的流量

它會跑一隻 daemon , 去 log 指定 interface 收到封包的資料
預設是記下 packet 的 protocol、src ip、dst ip、src port、dst port、size

同一個 socket 的資料 , 會把 size 往上累加
因此不會說收到多少 packets 就有幾筆資料 ...

用 ports 簡單裝完後
( cd /usr/ports/net-mgmt/trafd ; make install distclean )

到 /etc/rc.conf 加幾行

trafd_enable=”YES”
trafd_ifaces=”fxp0″      # depend on your interface
trafd_flags=”-p”       # don't put interface into promiscuous mode
trafd_log=”/var/log/traffic.log” # daemon log position

然後
cp /usr/local/etc/rc.d/trafd.sh.sample /usr/local/etc/rc.d/trafd.sh
/usr/local/etc/rc.d/trafd.sh start
就會動了
( ps ax | grep trafd 應該會看到 process 在跑 )

在 /usr/local/bin 會有幾隻 traf* 開頭的工具
(/usr/local/share/doc/trafd/README 有說明)
我比較常用的是

trafstat -n -i fxp0 就可以看目前累積的流量狀況

然後為什麼會需要這隻 daemon 呢 ?

首先學術網路上的各校都有流量限制 , 東海的限制是一天 in+out 10G
既然我和計中關係密切 , 就更不能監守自盜惡搞了
於是就要控制自己機器的流量 ...

但是在區分流量的時候 , 要把對校內和對校外的分開來
否則校內隨便抓就破 10G .. 然後停掉service的話外面都不用抓了 :p

於是寫隻 script 放 crontab
去 parse “trafstat -n -i fxp0″ 的結果
把 對校內/非校內 的流量區分開來
當發現對校外的流量達到設定的限制 (8G左右)
就修改 ftp daemon 的 .ftpaccess , 改成限校內 ip 進入

每天凌晨 00:00 , 學校的 netflow 重新計算的時候
也跑 /usr/local/bin/trafsave fxp0 把結果 reset
再把 .ftpaccess 的設定改成全開
這樣就沒什麼問題了 ....

但是前陣子發現怎麼有時還是會爆流量 ...
於是trace了一下 .....
發現有時 trafstat 會噴這樣的結果出來 -
From Port To Port Proto All
140.128.101.156 60272 140.128.194.76 client tcp -2045143144

怎麼合計起來會有 - 的大小咧 !?

查了一下 source , 原來在 trafstat/trafstat.c:171 是這樣寫的

printf(”%-4.4s %9ld %10ld\n”, proto, entries[i].n_bytes, entries[i].n_psize);

首先是 %ld 只能噴 –2,147,483,648 ~ 2,147,483,647 ,
先改一下 ... 改用 %lu ... 馬上現賺一倍 ...

再者 struct definition 長這樣

struct t_entry {
struct in_addr in_ip, out_ip; /* src ip addr and dst ip addr */
u_char ip_protocol;    /* which protocol been used (/etc/protocols)*/
u_char who_srv;     /* who was server flag */
u_short p_port;      /* which port been used (/etc/services) */
u_long n_psize;     /* how many bytes in ip datagrams passed */
u_long n_bytes;     /* how many data bytes passed */
} *entries;

u_long 只能 handle 到 4294967295 ....
設計的人也沒想到同一組 socket 會傳到把 u_long 爆掉吧 :p

有空再來 trace 一下其他部份 ...
看有沒有需要把 u_long (4 bytes) 整個換去 long long (8 bytes) ....
然後 printf 時要用 %llu ...

結論 -

還是 open source 的東西好 , 要改啥自己來 XD


FreeBSD 類別的文章 :
衝 6.16.1 ...

新增留言

*

*

Trackback this post  |  訂閱這則留言的 RSS Feed


各分類文章

最近的 20 篇文章