2014-11-06 39 views
2

我想了解sin6_scope_id如何在UNIX C编程中用于IPv6地址。具体来说,我写了这个程序,试图绑定到::1%2(等接口2环回地址,如果我得到这个权利),即使我回送地址实际上是对接口1当:: 1在接口1上时,为什么我可以将此套接字绑定到:: 1%2?

我预计这将失败。但它成功绑定。为什么?

这里是由ifconfig -a返回的第一个3个接口:

$ 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); 
} 
+1

也许它的操作系统特定 - 你在哪个操作系统上运行? – nos 2015-10-07 19:47:18

+0

这是在Linux上,如果我记得正确(抱歉在我的答复延迟)。 – conradkdotcom 2015-11-04 17:06:44

回答

1

根据你的unix版本可能是%2被忽略。

在某些IBM systems,文档说:

上述IPv6的文本形式可以包括一个附加的区域指示符(如果之前有一个%字符)和/或一个附加的前缀长度(如果之前有一个/字符)。在这些情况下,%或/ 将被视为与空终止符相同。

相关问题