Вы используете интерфейс сокета.Таким образом, вы получаете пакет 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.