/*
Copyright (C) 2005-2009, Parrot Foundation.
$Id: test.in 49532 2010-10-14 00:47:36Z jkeenan $

*/

#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <errno.h>

int main(int c,char**v) {
    int x = socket( PF_INET6, SOCK_DGRAM, 0 );
    if ( x < 0 ) {
        perror("Not OK - socket failed");
        return 2;
    }

    /*
    By now we have (a) PF_INET6 defined, and (b) in-principle kernel
    support for v6; however we don't yet know if we have any v6
    interfaces.
    */

    struct in6_addr A = IN6ADDR_LOOPBACK_INIT;  /* IN6ADDR_ANY_INIT; */
    struct sockaddr_in6 S = { AF_INET6 };  /* family is always first field in sockaddr_* */
    S.sin6_addr = A;
    S.sin6_port = 32760;  /* a pseudorandom 15-bit number */

    /*
    By now we have struct in6_addr, struct sockaddr_in6 and AF_INET6 and
    IN6ADDR_LOOPBACK_INIT. But we still don't know about interfaces.
    */

    #ifdef linux  /* might not be supported elsewhere */
    S.sin6_flowinfo = 0;
    S.sin6_scope_id = 0;
    #endif

    /*
    Set the SO_REUSEADDR option so as not to interfere with anyone else
    using the port, including running this test again within the
    re-use timeout period.
    */
    int reuse_address = 1;
    if ( setsockopt(x, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) < 0 ) {
        perror("Not OK - setsockopt failed");
        return 1;
    }

    if ( bind( x, (void*) &S, sizeof(S) ) < 0 && errno != EADDRINUSE ) {
        perror("Not OK - bind failed");
        return 1;
    }

    /*
    By now we know we can bind to "::1", which means we truly do have
    IPv6 support. Of course, we might not have any useful routes off
    this host, but that wasn't the question.
    */
    puts("OK");
    close(x);
    return 0;
}

/*
 * Local variables:
 *   c-file-style: "parrot"
 * End:
 * vim: expandtab shiftwidth=4:
 */
