私はrawソケットを使用してネットワークパケットをスニッフィングするプログラムを開発しています(AF_PACKET、SOCK_RAW)何らかの方法で処理してください。
私のプログラムが十分速く実行され、ソケットのすべてのパケットを正常にキャプチャするかどうかはわかりません。このソケットの受信バッファが時々いっぱいになる(トラフィックバーストのため)、いくつかのパケットが破棄されることが心配されます。
ソケット受信バッファスペースが不足してパケットがドロップされたかどうかはどうすればわかりますか?
私は走ろうとしましたss -f link -nlp
。
これは、そのソケットのデバイスバッファに現在格納されているバイト数を出力しますが、パケットが破棄されたかどうかはわかりません。
使っていますUbuntu 14.04.2 LTS (GNU/Linux 3.13.0-52-一般 x86_64)。
答え1
ドロップされたパケットは、netstat、ethtool出力で見ることができます。 UDPパケット損失の場合は、'netstat -us'
パケットがNIC層自体からも破棄されていることを確認してください。'ethtool -S <device_name>'
出力例:
$ netstat -us
IcmpMsg:
InType3: 44
InType8: 5
InType13: 1
InType17: 3
InType37: 1
OutType0: 5
OutType3: 599
OutType8: 4
OutType14: 1
Udp:
86942 packets received
209 packets to unknown port received.
**0 packet receive errors** <== This indicates packets dropped due to socket buffer full
213901 packets sent
UdpLite:
IpExt:
InOctets: 38683476091
OutOctets: 959938111
より大きなバッファスペース(SO_RCVBUF)を使用し、sysctl制御net.core.rmem_maxを介してシステム全体の最大値を増やします。
NIC層では、バーストトラフィックを処理するためにリングバッファを増やすこともできます(設定を確認ethtool -g
)。
答え2
次のように、PACKET_STATISTICSソケットオプションを使用して、プログラムが受信したパケットの総数と破棄されたパケットの数を取得できます。パッケージ(7)マンページ。
#include <linux/if_packet.h>
#include <sys/socket.h>
#include <sys/types.h>
...
struct tpacket_stats lStats = {};
socklen_t lStatsLength = sizeof( lStats );
if ( getsockopt( mRawSocket, SOL_PACKET, PACKET_STATISTICS, &lStats, &lStatsLength ) == 0 )
{
printf( "Total Packets: %u\nDropped Packets: %u\n", lStats.tp_packets, lStats.tp_drops );
}
else
{
perror( "Failed to get network receive statistics" );
}