2011-12-22 15 views
3

セカンダリインターフェイスtap0のipv6アドレスにバインドするUDPサーバー用の次のCコードがあります。 セカンダリインターフェイスでUDP/IPv6パケットを受信できません

tap0  Link encap:Ethernet HWaddr ce:23:fc:81:7f:65 
      inet6 addr: fe80::cc23:fcff:fe81:7f65/64 Scope:Link 
      inet6 addr: aaaa::1/64 Scope:Global 

は、私は次のコマンドを使用して上記のコードを実行します:

context_t * 
new_context(const struct sockaddr *listen_addr, size_t addr_size) { 
    context_t *c = malloc(sizeof(context_t)); 
    time_t now; 
    int reuse = 1; 

    if (!listen_addr) { 
    fprintf(stderr, "no listen address specified\n"); 
    return NULL; 
    } 

    srand(getpid()^time(&now)); 

    if (!c) { 
    perror("init: malloc:"); 
    return NULL; 
    } 

    memset(c, 0, sizeof(context_t)); 

    c->sockfd = socket(listen_addr->sa_family, SOCK_DGRAM, 0); 
    if (c->sockfd < 0) { 
    perror("new_context: socket"); 
    goto onerror; 
    } 

    if (setsockopt(c->sockfd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0) 
    perror("setsockopt SO_REUSEADDR"); 

    if (bind (c->sockfd, listen_addr, addr_size) < 0) { 
    perror("new_context: bind"); 
    goto onerror; 
    } 

    return c; 

onerror: 
    if (c->sockfd >= 0) 
    close (c->sockfd); 
    free(c); 
    return NULL; 
} 



context_t * 
get_context(const char *ipaddress, const char *port, unsigned int scopeId) { 
    int s; 
    context_t* ctx; 
    struct addrinfo hints; 
    struct addrinfo *result, *rp; 

    memset(&hints, 0, sizeof(struct addrinfo)); 
    hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ 
    hints.ai_socktype = SOCK_DGRAM; /* Coap uses UDP */ 
    hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST | AI_NUMERICSERV | AI_ALL; 

    s = getaddrinfo(ipaddress, port, &hints, &result); 
    if (s != 0) { 
    fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(s)); 
    return NULL; 
    } 

    /* iterate through results until success */ 
    for (rp = result; rp != NULL; rp = rp->ai_next) { 
    ctx = new_context(rp->ai_addr, rp->ai_addrlen); 
    if (ctx) { 
     if (rp->ai_family == PF_INET6) { 
     struct sockaddr_in6* pSadrIn6 = (struct sockaddr_in6*) rp->ai_addr; 
     if (pSadrIn6->sin6_scope_id == 0) { 
      pSadrIn6->sin6_scope_id = scopeId; 
     } /* End IF the scope ID wasn't set. */ 
     } 
     goto finish; 
    } 
    } 

    fprintf(stderr, "no context available for interface '%s'\n", node); 

finish: 
    freeaddrinfo(result); 
    return ctx; 
} 

デバイスTAP0は、次の詳細がある

./server -A aaaa::1 

をしかし、それはアドレスに来たメッセージを聞くことができませんtap0のaaaa :: 1。 tap0インターフェイスでwiresharkダンプのパケットを見ることができます。面白いことに、サーバーは上記のコマンドから実行され、コードはlocalhostを介してメッセージを受け取ることができます。したがって、次のコマンドを実行すると、サーバーはメッセージを受信します。

nc -6 -vvv -u aaaa::1 61616 < /tmp/send_to_node_raw 

上記のコマンドの送受信はlocalhostを介して行われます。 セカンダリインターフェイスでUDP/IPv6メッセージをプログラムで受信する方法はありますか?

+0

設定している「scopeId」とは何ですか?万一それが「1」ですか? –

+0

これは本当に1つのインターフェイスです。 bind(2)はインターフェースではなくアドレスに "バインド"することができます。すなわち、dst addr aaaa :: 1を持つパケットは最大でも受信されます。 –

+0

@ニコライ:scopeIdをtap0に設定しています。 –

答えて

0

問題は別の場所にある必要があります。上記のコードを使用すると、ローカルアドレスとリモートアドレスとしてそれぞれaaaa :: 1/64とaaaa :: 2/64を使用して、別のノードからパケットを正常に受信できます。

::にバインドして、そのように動作するかどうかを確認してください。また、netcat6を使ってaaaa :: 1にバインドし、別のnetcat6インスタンスから受信しようとします。

関連する問題