저는 원시 소켓을 사용하여 네트워크 패킷을 스니핑하는 프로그램을 개발 중입니다(AF_PACKET, SOCK_RAW) 어떤 방식으로든 처리하세요.
내 프로그램이 충분히 빠르게 실행되고 소켓의 모든 패킷을 성공적으로 캡처하는지 잘 모르겠습니다. 이 소켓의 수신 버퍼가 때때로 가득 차서(트래픽 버스트로 인해) 일부 패킷이 삭제되는 것이 걱정됩니다.
소켓 수신 버퍼 공간이 부족하여 패킷이 삭제되었는지 어떻게 알 수 있나요?
나는 달리기를 시도했다 ss -f link -nlp
.
이는 해당 소켓에 대한 장치 버퍼에 현재 저장된 바이트 수를 출력하지만 패킷이 삭제되었는지 알 수 없습니다.
나는 사용하고있다우분투 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" );
}