英文:
What does the 28 bytes mean in ai_addr->sa_data?
问题
第一个 6 字节和最后一个 6 字节有什么用?
英文:
I tested with "::1" and the ip address of a domain. It seems like the ipv6 address has an addrlen of 28. The first 6 was blank (I know the first two bytes of ipv4 is the 16bit port but I'm stumped here) and the last 6 bytes is blank. The middle 16bytes is the 128bit ipv6 address
What is the first 6 bytes and last 6 bytes used for?
答案1
得分: 0
sa_data
字段的内容取决于sa_family
字段中指定的地址族。
当ai_addr->sa_family
为AF_INET
时,ai_addr
指向一个sockaddr_in
结构体:
struct sockaddr_in {
sa_family_t sin_family; /* 地址族:AF_INET */
in_port_t sin_port; /* 端口(网络字节顺序) */
struct in_addr sin_addr; /* 互联网地址 */
};
/* 互联网地址 */
struct in_addr {
uint32_t s_addr; /* 网络字节顺序中的地址 */
};
因此,ai_addr->sa_data
包含了sin_port
和sin_addr
字段的数据(6个字节)。sockaddr_in
的总大小为8个字节。
当ai_addr->sa_family
为AF_INET6
时,ai_addr
指向一个sockaddr_in6
结构体:
struct sockaddr_in6 {
sa_family_t sin6_family; /* AF_INET6 */
in_port_t sin6_port; /* 端口号 */
uint32_t sin6_flowinfo; /* IPv6流信息 */
struct in6_addr sin6_addr; /* IPv6地址 */
uint32_t sin6_scope_id; /* 作用域ID(2.4版引入) */
};
struct in6_addr {
unsigned char s6_addr[16]; /* IPv6地址 */
};
因此,ai_addr->sa_data
包含了sin6_port
到sin6_scope_id
字段的数据(26个字节)。sockaddr_in6
的总大小为28个字节(在不包含sin6_scope_id
的系统上除外)。
因此,您需要查看ai_addr->sa_family
字段,然后对ai_addr
进行类型转换(或使用memcpy()
)以正确访问其他字段,例如:
struct addrinfo hints, *addrs;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
...
int res = getaddrinfo(..., &hints, &addrs);
if (res != 0) ...
for (struct addrinfo *addr = addrs; addr != NULL; addr = addr->ai_next) {
switch (addr->ai_addr->sa_family) {
case AF_INET: {
struct sockaddr_in *ip4 = (struct sockaddr_in *) addr->ai_addr;
/* 或者:
struct sockaddr_in ip4;
memcpy(&ip4, addr->ai_addr, sizeof(ip4));
*/
// 根据需要使用ip4...
break;
}
case AF_INET6: {
struct sockaddr_in6 *ip6 = (struct sockaddr_in6 *) addr->ai_addr;
/* 或者:
struct sockaddr_in6 ip6;
memcpy(&ip6, addr->ai_addr, sizeof(ip6));
*/
// 根据需要使用ip6...
break;
}
}
}
freeaddrinfo(addrs);
英文:
The contents of the sa_data
field are dependent on the address family specified in the sa_family
field.
When ai_addr->sa_family
is AF_INET
, ai_addr
is pointing at a sockaddr_in
struct:
struct sockaddr_in {
sa_family_t sin_family; /* address family: AF_INET */
in_port_t sin_port; /* port in network byte order */
struct in_addr sin_addr; /* internet address */
};
/* Internet address */
struct in_addr {
uint32_t s_addr; /* address in network byte order */
};
Thus, ai_addr->sa_data
contains the data for the sin_port
and sin_addr
fields (6 bytes). The total size of sockaddr_in
is 8 bytes.
When ai_addr->sa_family
is AF_INET6
, ai_addr
is pointing at a sockaddr_in6
struct instead:
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) */
};
struct in6_addr {
unsigned char s6_addr[16]; /* IPv6 address */
};
Thus, ai_addr->sa_data
contains the data for the sin6_port
..sin6_scope_id
fields (26 bytes). The total size of sockaddr_in6
is 28 bytes (except on systems where sin6_scope_id
is not present).
So, you need to look at the ai_addr->sa_family
field and then type-cast ai_addr
(or memcpy()
it) to access the other fields correctly, eg:
struct addrinfo hints, *addrs;
memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC;
...
int res = getaddrinfo(..., &hints, &addrs);
if (res != 0) ...
for(struct addrinfo *addr = addrs; addr != NULL; addr = addr->ai_next) {
switch (addr->ai_addr->sa_family) {
case AF_INET: {
struct sockaddr_in *ip4 = (struct sockaddr_in *) addr->ai_addr;
/* alternatively:
struct sockaddr_in ip4;
memcpy(&ip4, addr->ai_addr, sizeof(ip4));
*/
// use ip4 as needed...
break;
}
case AF_INET6: {
struct sockaddr_in6 *ip6 = (struct sockaddr_in6 *) addr->ai_addr;
/* alternatively:
struct sockaddr_in6 ip6;
memcpy(&ip6, addr->ai_addr, sizeof(ip6));
*/
// use ip6 as needed...
break;
}
}
}
freeaddrinfo(addrs);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论