Как увеличить необработанный кольцевой буфер сокетов до более 4 Гб в Centos и Red Hat? - PullRequest
0 голосов
/ 25 апреля 2020

Использование сырых сокетов для перехвата пакетов в 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);    }
...