我试图了解sin6_scope_id
UNIX C套接字编程中IPv6地址的工作方式。具体来说,我编写了此程序尝试绑定::1%2
(即使我的环回地址实际上位于接口1上,因此也要绑定到接口2的环回地址)。
我希望这会失败。但是它绑定成功。为什么?
以下是传回的前3个介面ifconfig -a
:
$ ifconfig -a
lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384
options=3<RXCSUM,TXCSUM>
inet6 ::1 prefixlen 128
inet 127.0.0.1 netmask 0xff000000
inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1
nd6 options=1<PERFORMNUD>
gif0: flags=8010<POINTOPOINT,MULTICAST> mtu 1280
stf0: flags=0<> mtu 1280
您可以使用以下命令编译该程序:
cc -Wall -Wextra main.c
这是评论源:
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main() {
// Allow any IP address on the interface with scope ID of 2.
const char *hostname = "::1%2";
// Say we want to bind on port 80 (for http).
const char *servname = "1337";
// Store some information about the IP address wanted.
struct addrinfo hints;
// Save addresses in here.
struct addrinfo *addr_list_item = NULL;
// Tell `getaddrinfo` that we want an address for IPv6 TCP.
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_INET6;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
if (getaddrinfo(hostname, servname, &hints, &addr_list_item) != 0) {
printf("Could not read addresses.\n");
exit(1);
}
// Create a socket and bind it to the address we found before. This should fail
// but for some reason I don't understand it doesn't.
if (addr_list_item) {
int sock = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);
if (sock != -1) {
if (bind(sock, addr_list_item->ai_addr, addr_list_item->ai_addrlen) != -1) {
printf("Binded succesfully!\n");
} else {
perror(NULL);
}
close(sock);
}
}
// Release memory.
freeaddrinfo(addr_list_item);
return (0);
}
根据您的Unix版本,%2
可能会被忽略。
在某些IBM系统上,文档说:
上面的IPv6文本格式可以包括一个附加的区域指示符(如果以%字符开头)和/或一个附加的前缀长度(如果以/字符开头)。在这些情况下,%或/将被视为空终止符。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句