2014-11-05 108 views
1

man 7 ipv6,我们可以看到,IPv6地址在内部这样表示:为什么sin6_family需要IPv6地址?

struct sockaddr_in6 { 
     sa_family_t  sin6_family; /* AF_INET6 */ 
     in_port_t  sin6_port;  /* port number */ 
     uint32_t  sin6_flowinfo; /* IPv6 flow information */ 
     struct in6_addr sin6_addr;  /* IPv6 address */ 
     uint32_t  sin6_scope_id; /* Scope ID (new in 2.4) */ 
}; 

而且还认为:

sin6_family总是被设置为AF_INET6

为什么sin6_family如果它总是一样的话,那么这是必需的吗?这是否意味着将IPv4转换为IPv6更简单,因为struct的布局相似?

回答

2

为了在C sockets API中提供一种穷人的多态性,C sockets函数只需要一个指向struct sockaddr *的指针,它将接受可能有许多不同系列的地址。

这依赖于C中的保证,即结构的第一个成员的地址与结构的地址相同。由于每个sockaddr_*类型的第一个成员都是地址族,因此内部代码可以检查族是否回到正确的地址结构。

因此,这允许通话推断出您已经通过IPv6地址,即使在投射到sockaddr *并相应地处理它。

1

the bind man-page

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen); 

[...]
被传为addr参数将取决于地址族的实际结构。
sockaddr结构被定义为是这样的:

struct sockaddr { 
     sa_family_t sa_family; 
     char  sa_data[14]; 
    } 

这种结构的唯一目的是投在addr传递的结构的指针,以避免编译器警告。
[...]

所以你看,sa_family是一个隐含的扩展tagged-union标志着结构为一体的专业化的IPv6版本的标签,而不是一般的未知,IPv4或又一个。