web-dev-qa-db-ja.com

rawソケットでドロップされたパケットの数を調べる

私は、rawソケット(AF_PACKET、SOCK_RAW)を使用してネットワークパケットをスニッフィングし、何らかの方法でそれらを処理するプログラムを開発しています。

プログラムが十分に高速に実行され、ソケット上のすべてのパケットをキャプチャすることに成功したかどうかはわかりません。このソケットの受信バッファが(トラフィックバーストのために)ときどきいっぱいになり、一部のパケットがドロップされるのではないかと心配しています。

ソケットの受信バッファのスペースが不足しているためにパケットがドロップされたかどうかを確認するにはどうすればよいですか?

ss -f link -nlpを実行してみました。

これは、そのソケットのリビジョンバッファに現在格納されているバイト数を出力しますが、パケットがドロップされたかどうかはわかりません。

私はbuntu 14.04.2 LTS(GNU/Linux 3.13.0-52-generic x86_64)を使用しています。

3
gabi

ドロップされたパケットは、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 controlnet.core.rmem_maxを介してシステム全体の最大値を増やしてください

NICレイヤーでは、バーストトラフィックを処理するためにリングバッファを増やすこともできます(ethtool -gで設定を確認してください)

2
VenkatC

packet(7) のマンページで説明されているように、PACKET_STATISTICSソケットオプションを使用して、プログラムで受信したパケットの総数とドロップしたパケットの数を取得できます。

#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" );
}
0
Matt