Проверка контрольной суммы UDP для ipv6: как извлечь адрес источника ipv6 из вспомогательных данных - PullRequest
0 голосов
/ 26 октября 2018

У меня есть необработанный сокет ipv6, из которого я получаю этот пакет udp. сокет (AF_INET6, SOCK_RAW, IPPROTO_UDP)

Мне нужно проверить контрольную сумму udp на полученном пакете, а для вычисления псевдозаголовка необходимо найти IP-адрес источника. Не уверен, как получить это из сокета ipv6 raw.

Для адреса получателя у нас есть опция сокета IPV6_RECVPKTINFO, но мы не уверены, как получить от нее адрес источника.

Ответы [ 2 ]

0 голосов
/ 26 декабря 2018

Вы используете интерфейс сокета.Таким образом, вы получаете пакет UDP, используя recvfrom(int sockfd, void *buf, size_t len, int flags, struct sockaddr *src_addr, socklen_t addrlen); или recvmsg(int sockfd, struct msghdr *msg, int flags);.

. Обратите внимание, что в большинстве операционных систем (Linux, Unix, Windows, ...) CRC уже был проверен ранее.вы получаете пакет, поэтому вам не нужно проверять CRC.

При recvfrom() адрес источника сохраняется в части буфера, указанного 5-м аргументом, то есть struct sockaddr_in6 структура.Чтобы выделить этот буфер, вы можете предпочесть использовать структуру sockaddr_storage вместо sockaddr_in6, поскольку она достаточно велика, чтобы вместить все поддерживаемые структуры адресов протокола, и вы можете повторно использовать этот буфер для обработки других типов адресов.

Таким образом, вы можете вычислить свой CRC, используя псевдобуфер, заполненный ((struct sockaddr_in6 *) src_addr)->sin6_addr, который имеет тип struct in6_addr.

С recvmsg(), вы даетеуказатель на struct msghdr во втором аргументе, а адрес источника хранится в части буфера, на который указывает поле msg_name, в структуре struct sockaddr_in6.

Таким образом, вы можете вычислить свой CRCиспользуя псевдобуфер, заполненный ((struct sockaddr_in6 *) msg_name)->sin6_addr, который имеет тип struct in6_addr.

Наконец, обратите внимание, что в системах на основе BSD, таких как OS-X или FreeBSD, даже еслиидентификатор области видимости хранится в поле структуры struct sockaddr_in6, он также встроен в сам адрес в качестве второго 16-битного слова.Следовательно, в таком случае не следует копировать эту часть адреса в псевдозаголовок, а заменить ее на 0.

0 голосов
/ 26 октября 2018

Я не то чтобы в RAW сокеты и IPv6.Не имея кода для выполнения, я рекомендую заглянуть в RFC.Смотрите здесь: https://www.ietf.org/rfc/rfc3542.txt. В частности, смотрите страницы 21 - 4 и 6,2.

Также смотрите msg_control in: (ssize_t recvmsg(int socket, struct msghdr *message, int flags);)

struct msghdr {

    void         *msg_name        optional address
    socklen_t     msg_namelen     size of address
    struct iovec *msg_iov         scatter/gather array
    int           msg_iovlen      members in msg_iov
    void         *msg_control     ancillary data, see below
    socklen_t     msg_controllen  ancillary data buffer len
    int           msg_flags       flags on received message`
}
...