Использование сырых сокетов для перехвата пакетов в Centos и Red Hat. Невозможно запросить кольцевой буфер размером более 4 ГБ. Как это можно сделать? Доступно ли изменение конфигурации, чтобы обойти это ограничение? Все ли версии Linux имеют это ограничение?
Использование Centos 7.7.1988. Использование packet_mmap. c GPL версии 2.0. Приведенный ниже код работает, когда blocknum равен <= 127. </p>
Когда blocknum равен> = 128, получите указанную ниже ошибку от setsockopt ().
Интерфейс сниффинга enp0s3 с использованием 128 блоков. Размер блока составляет 33554432, а максимальный размер пакета равен 16384. привязка кольцевого буфера setsockopt: неверный аргумент
static int setup_socket(struct ring *ring, char *netdev) {
int err, i, fd, v = TPACKET_V3;
struct sockaddr_ll ll;
unsigned int blocksiz = 1 << 25, framesiz = 1 << 14; // 1 << 14 is 16384, 2^25 is 33554432
unsigned int blocknum = 127;
printf("Sniffing interface %s using %d blocks. Block size is %d and max packet size is %d.\n", netdev, blocknum, blocksiz, framesiz);
fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
if (fd < 0) {
perror("socket");
exit(1); }
err = setsockopt(fd, SOL_PACKET, PACKET_VERSION, &v, sizeof(v));
if (err < 0) {
perror("setsockopt packet version");
exit(1); }
// Switch to PROMISC mode
struct packet_mreq sock_params;
memset(&sock_params, 0, sizeof(sock_params));
sock_params.mr_type = PACKET_MR_PROMISC;
sock_params.mr_ifindex = if_nametoindex(netdev);
int set_promisc = setsockopt(fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, (void *)&sock_params, sizeof(sock_params));
if (set_promisc == -1) {
printf("Can't enable promisc mode\n");
return -1; }
memset(&ring->req, 0, sizeof(ring->req));
ring->req.tp_block_size = blocksiz;
ring->req.tp_frame_size = framesiz;
ring->req.tp_block_nr = blocknum;
ring->req.tp_frame_nr = (blocksiz * blocknum) / framesiz;
ring->req.tp_retire_blk_tov = 60;
ring->req.tp_feature_req_word = TP_FT_REQ_FILL_RXHASH;
err = setsockopt(fd, SOL_PACKET, PACKET_RX_RING, &ring->req, sizeof(ring->req));
if (err < 0) {
perror("setsockopt ring buffer bind");
exit(1); }