我有一个原始的ipv6套接字,我从这个套接字中获得这个UDP包。套接字(AF_INET6、SOCK_RAW、IPPROTO_UDP)
我需要验证收到的数据包的udp校验和,并计算伪头,需要找到源ip地址。不确定如何从ipv6原始套接字获取。
对于目标地址,我们有IPV6_RECVPKTINFO套接字选项,但不确定如何从它获取源地址。
发布于 2018-10-26 18:08:31
我对原始套接字和IPv6不感兴趣。如果没有任何代码可供执行,我建议研究一下RFC。请看这里:https://www.ietf.org/rfc/rfc3542.txt。特别要注意Page21 -4到6和6.2。
另请参阅:(ssize_t recvmsg(int socket, struct msghdr *message, int flags);)中的msg_control
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`
}发布于 2018-12-27 02:19:53
您正在使用套接字接口。因此,您使用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);接收UDP数据包。
请注意,对于大多数操作系统(Linux、Unix、Windows等),在收到数据包之前已经检查过循环冗余校验,因此您不需要检查循环冗余校验。
在recvfrom()中,源地址存储在第五个参数所指向的缓冲区的一部分中,即struct sockaddr_in6结构。要分配此缓冲区,您可能更喜欢使用sockaddr_storage结构而不是sockaddr_in6,因为它的大小足以容纳所有支持的特定于协议的地址结构,并且您可以重用此缓冲区来处理其他地址类型。
因此,您可以使用一个用struct in6_addr类型的((struct sockaddr_in6 *) src_addr)->sin6_addr,填充的伪缓冲区来计算CRC。
对于recvmsg(),您在第二个参数中给出了一个指向struct msghdr的指针,源地址存储在msg_name字段指向的缓冲区的一部分中,采用struct sockaddr_in6结构。
因此,您可以使用一个用struct in6_addr类型的((struct sockaddr_in6 *) msg_name)->sin6_addr,填充的伪缓冲区来计算CRC。
最后,请注意,对于OS-X或FreeBSD等基于BSD的系统,即使作用域id存储在struct sockaddr_in6 结构的字段中,它也会作为第二个16位字嵌入到地址本身中。因此,在这种情况下,您不应将这部分地址复制到伪头中,而应将其替换为0。
https://stackoverflow.com/questions/53004716
复制相似问题