lwip-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lwip-devel] [task #15393] Support scoped literal IPv6 addresses in geta


From: Ashley Duncan
Subject: [lwip-devel] [task #15393] Support scoped literal IPv6 addresses in getaddrinfo
Date: Thu, 19 Sep 2019 01:41:35 -0400 (EDT)
User-agent: Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:69.0) Gecko/20100101 Firefox/69.0

Follow-up Comment #2, task #15393 (project lwip):

Thanks for your reply.

The code used by mbedtls is below.  I know the interface name is correct as I
made the interface myself and it returns the correct index when queried by
name.  It gets as deep down as ip6addr_aton with the scoped address which
returns a correctly decoded IPV6 address but the zone is always set to 0 by
line 187 of ip6_addr.c.  There is no test in this function for the existence
of a % in the address.  

I can bind to a link local address on my interface using the socket bind
function as expected but need to call an lwip function to get the interface id
which is not available through a portable API.

I pass "FE80::2B0:52FF:FEFF:FF05%pl1" as bind_ip and it always results in a
zone (scope_id) of 0.  It should set the correct zone I think if there was
only one interface present (there is a test for this somewhere down the
stack).  But I have two interfaces.

int mbedtls_net_bind( mbedtls_net_context *ctx, const char *bind_ip, const
char *port, int proto )
{
    int ret;
    struct addrinfo hints, *addr_list, *cur;

    if ( ( ret = net_prepare() ) != 0 ) {
        return ( ret );
    }

    /* Bind to IPv6 and/or IPv4, but only in the desired protocol */
    memset( &hints, 0, sizeof( hints ) );
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = proto == MBEDTLS_NET_PROTO_UDP ? SOCK_DGRAM :
SOCK_STREAM;
    hints.ai_protocol = proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP :
IPPROTO_TCP;

    if ( getaddrinfo( bind_ip, port, &hints, &addr_list ) != 0 ) {
        return ( MBEDTLS_ERR_NET_UNKNOWN_HOST );
    }

    /* Try the sockaddrs until a binding succeeds */
    ret = MBEDTLS_ERR_NET_UNKNOWN_HOST;
    for ( cur = addr_list; cur != NULL; cur = cur->ai_next ) {
        int fd = socket( cur->ai_family, cur->ai_socktype, cur->ai_protocol
);
        if ( fd < 0 ) {
            ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
            continue;
        }

        /*SO_REUSEADDR option dafault is disable in source code(lwip)*/
#if SO_REUSE
        int n = 1;
        if ( setsockopt( fd, SOL_SOCKET, SO_REUSEADDR,
                         (const char *) &n, sizeof( n ) ) != 0 ) {
            close( fd );
            ret = MBEDTLS_ERR_NET_SOCKET_FAILED;
            continue;
        }
#endif
        /*bind interface default don't process the addr is 0xffffffff for TCP
Protocol*/
        struct sockaddr_in *serv_addr = NULL;
        serv_addr = (struct sockaddr_in *)cur->ai_addr;
        serv_addr->sin_addr.s_addr = htonl(INADDR_ANY); /* Any incoming
interface */
        if ( bind( fd, (struct sockaddr *)serv_addr, cur->ai_addrlen ) != 0 )
{
            close( fd );
            ret = MBEDTLS_ERR_NET_BIND_FAILED;
            continue;
        }
...


I use this function I wrote instead to bind to the link local address on my
interface which works perfectly:

#include "lwip/netifapi.h"
int mbedtls_net_bind_ip6_interface(mbedtls_net_context *ctx, const char *
bind_ip, const char * interface, unsigned port, int proto )
{
    int ret;
    struct sockaddr_in6 sa6;
    if ( ( ret = net_prepare() ) != 0 ) {
        return ( ret );
    }
    inet_pton(AF_INET6, bind_ip, &(sa6.sin6_addr));
    sa6.sin6_port = htons(port);
    sa6.sin6_len = sizeof(sa6);
    sa6.sin6_flowinfo = 0;
    sa6.sin6_family = AF_INET6;
    u8_t idx = 0;
    netifapi_netif_name_to_index(interface, &idx);
    sa6.sin6_scope_id = idx;
    
    int fd = socket( sa6.sin6_family, proto == MBEDTLS_NET_PROTO_UDP ?
SOCK_DGRAM : SOCK_STREAM, proto == MBEDTLS_NET_PROTO_UDP ? IPPROTO_UDP :
IPPROTO_TCP);
    if ( fd < 0 ) {
        return MBEDTLS_ERR_NET_SOCKET_FAILED;
    }

    /*SO_REUSEADDR option dafault is disable in source code(lwip)*/
#if SO_REUSE
    int n = 1;
    if ( setsockopt( fd, SOL_SOCKET, SO_REUSEADDR, (const char *) &n, sizeof(
n ) ) != 0 ) {
        close( fd );
        return MBEDTLS_ERR_NET_SOCKET_FAILED;
    }
#endif
    if ( bind( fd, (struct sockaddr *)&sa6, sizeof(sa6) ) != 0 ) {
        close( fd );
        return MBEDTLS_ERR_NET_BIND_FAILED;
    }

...

    _______________________________________________________

Reply to this item at:

  <https://savannah.nongnu.org/task/?15393>

_______________________________________________
  Message sent via Savannah
  https://savannah.nongnu.org/




reply via email to

[Prev in Thread] Current Thread [Next in Thread]