在内核模块中,给定初始化为struct sockaddr
的sa_family
,如何可靠地确定它是AF_UNSPEC
还是struct sockaddr_in
?在Linux 3.16.0-4-686-pae(x86)上。
struct sockaddr {
unsigned short sa_family; // AF_UNSPEC
char sa_data[14]; // ?
};
struct sockaddr_in {
unsigned short sin_family;
unsigned short sin_port;
struct in_addr sin_addr;
char sin_zero[8];
};
struct sockaddr_in6 {
unsigned short sin6_family;
unsigned short sin6_port;
unsigned int sin6_flowinfo;
struct in6_addr sin6_addr;
unsigned int sin6_scope_id;
};
最佳答案
通常,当某些东西调用内核并给出struct sockaddr
时,它还必须给出struct sockaddr
的长度。例如,请参见:
ssize_t sendto (int sockfd, const void *buf, size_t buflen, int flags,
const struct sockaddr *addr, socklen_t addrlen);
使用缓冲区的大小,您应该能够很好地猜测需要使用哪种类型的
sendto()
:if (addr.sa_family == AF_UNSPEC) {
switch (addrlen) {
case sizeof (struct sockaddr_in): {
addr.sa_family = AF_INET;
break;
}
case sizeof (struct sockaddr_in6): {
addr.sa_family = AF_INET6;
break;
}
default: {
// handle error
break;
}
}
}
在理想的情况下,
sockaddr
将被设置为seithersa_family
(IPv4)或AF_INET
(IPv6),但不幸的是,这里似乎不是这样。关于c - 确定ipv4或ipv6数据结构,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31232771/