Linux UDP recvfrom: Что я получу в начале моего буфера? - PullRequest
2 голосов
/ 26 февраля 2020

Что я получу в начале буфера, если мой вызов recvfrom вернёт правильное количество байтов (например, 1400)?

Получу ли я ethhdr? Например, этот код не работает, хотя я должен получать UDP-пакеты:

void read_packets(struct config *cfg) {

    int64_t read_bytes = recvfrom(cfg->socket_fd, buffer, BUFFER_SIZE, 0, NULL, NULL);
    if(read_bytes == -1) {
        return;
    }

    cfg->stats.amnt_of_packets += 1;
    cfg->stats.amnt_of_bytes += read_bytes;

    struct ethhdr *eth = (struct ethhdr*)(buffer);
    if(ntohs(eth->h_proto) == ETH_P_IP) {
        struct iphdr *iph = (struct iphdr*)(buffer + sizeof(struct ethhdr));
        if(iph->protocol == IPPROTO_UDP) {
            /* doesn't work */
        }
    }
}

socket_fd был создан как:

cfg->socket_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

1 Ответ

4 голосов
/ 26 февраля 2020

Использование recvfrom на сокете UDP вернет только полезную нагрузку пакета UDP, то есть то, что передающая сторона передала sendto. Вы не увидите заголовок ethe rnet, заголовок IP или заголовок UDP как часть этого.

Однако вы передали значения NULL для двух последних аргументов. Их можно использовать для заполнения структуры struct sockaddr_in, которая будет содержать IP-адрес и порт UDP отправляющей стороны.

Также, если вы используете recvmsg, у вас есть возможность получить значения некоторых поля из заголовка IP, такие как IP-адрес назначения (полезно, если сокет принимает многоадресные пакеты), поле TOS / DSCP или различные параметры IP, которые могут быть установлены.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...