Binding an IPv6 address to an AF_INET socket? - Networking

This is a discussion on Binding an IPv6 address to an AF_INET socket? - Networking ; The code below attempts to bind an IPv6 address to an AF_INET socket. I belive this should fail, yet when compiled and run on our RedHat AS-3 and AS-4 boxes, it prints "bind worked". Does this make sense? On Solaris-8, ...

+ Reply to Thread
Results 1 to 6 of 6

Thread: Binding an IPv6 address to an AF_INET socket?

  1. Binding an IPv6 address to an AF_INET socket?

    The code below attempts to bind an IPv6 address to an AF_INET socket. I
    belive this should fail, yet when compiled and run on our RedHat AS-3 and
    AS-4 boxes, it prints "bind worked". Does this make sense?

    On Solaris-8, it prints "bind failed: Address family not supported by
    protocol family", which is about what I would have expected.

    Before anybody asks, "Why do you want to do that?", the answer is, "I
    don't". It came up during some unit tests, where (at a higher level in
    some C++ code), we attempt to do this and expect it to throw an exception.


    #include
    #include
    #include
    #include
    #include

    int main (int argc, char* argv[]) {
    * * int s = socket(PF_INET, SOCK_STREAM, 0);
    * * printf ("s = %d\n", s);

    * * struct in6_addr anyaddr = IN6ADDR_ANY_INIT;
    * * struct sockaddr_in6 sa;

    * * sa.sin6_family = AF_INET6;
    * * sa.sin6_port = 0;
    * * sa.sin6_flowinfo = 0;
    * * sa.sin6_addr = anyaddr;
    * * sa.sin6_scope_id = 0;

    * * int retval = bind(s, (struct sockaddr*) &sa, sizeof (sa));
    * * if (retval == 0) {
    * * * * printf ("bind worked\n");
    * * } else {
    * * * * perror ("bind failed");
    * * }
    }

  2. Re: Binding an IPv6 address to an AF_INET socket?

    Roy Smith wrote:
    > The code below attempts to bind an IPv6 address to an AF_INET socket.
    > I belive this should fail, yet when compiled and run on our RedHat
    > AS-3 and AS-4 boxes, it prints "bind worked". Does this make sense?


    It makes sense and if the underlying OS supports IPv6 then the bind should
    work. The behavior of bind() under IPv6 is described in RFC 3493.

    Why do you believe the bind should fail?

    > #include
    > #include
    > #include
    > #include
    > #include
    >
    > int main (int argc, char* argv[]) {
    > * * int s = socket(PF_INET, SOCK_STREAM, 0);
    > * * printf ("s = %d\n", s);
    >
    > * * struct in6_addr anyaddr = IN6ADDR_ANY_INIT;
    > * * struct sockaddr_in6 sa;
    >
    > * * sa.sin6_family = AF_INET6;
    > * * sa.sin6_port = 0;
    > * * sa.sin6_flowinfo = 0;
    > * * sa.sin6_addr = anyaddr;
    > * * sa.sin6_scope_id = 0;
    >
    > * * int retval = bind(s, (struct sockaddr*) &sa, sizeof (sa));
    > * * if (retval == 0) {
    > * * * * printf ("bind worked\n");
    > * * } else {
    > * * * * perror ("bind failed");
    > * * }
    > }


  3. Re: Binding an IPv6 address to an AF_INET socket?

    In article ,
    Jim Logajan wrote:

    > Roy Smith wrote:
    > > The code below attempts to bind an IPv6 address to an AF_INET socket.
    > > I belive this should fail, yet when compiled and run on our RedHat
    > > AS-3 and AS-4 boxes, it prints "bind worked". Does this make sense?

    >
    > It makes sense and if the underlying OS supports IPv6 then the bind should
    > work. The behavior of bind() under IPv6 is described in RFC 3493.
    >
    > Why do you believe the bind should fail?


    Because I'm trying to bind an AF_INET6 address to a PF_INET socket. I
    don't see anything in 3493 that explicitly says this will fail, but it
    seems logical. This isn't something which "3.7 Compatibility with IPv4
    Nodes" talks about.





    >
    > > #include
    > > #include
    > > #include
    > > #include
    > > #include
    > >
    > > int main (int argc, char* argv[]) {
    > > * * int s = socket(PF_INET, SOCK_STREAM, 0);
    > > * * printf ("s = %d\n", s);
    > >
    > > * * struct in6_addr anyaddr = IN6ADDR_ANY_INIT;
    > > * * struct sockaddr_in6 sa;
    > >
    > > * * sa.sin6_family = AF_INET6;
    > > * * sa.sin6_port = 0;
    > > * * sa.sin6_flowinfo = 0;
    > > * * sa.sin6_addr = anyaddr;
    > > * * sa.sin6_scope_id = 0;
    > >
    > > * * int retval = bind(s, (struct sockaddr*) &sa, sizeof (sa));
    > > * * if (retval == 0) {
    > > * * * * printf ("bind worked\n");
    > > * * } else {
    > > * * * * perror ("bind failed");
    > > * * }
    > > }


  4. Re: Binding an IPv6 address to an AF_INET socket?

    Roy Smith writes:

    > In article ,
    > Jim Logajan wrote:
    >
    > > Roy Smith wrote:
    > > > The code below attempts to bind an IPv6 address to an AF_INET socket.
    > > > I belive this should fail, yet when compiled and run on our RedHat
    > > > AS-3 and AS-4 boxes, it prints "bind worked". Does this make sense?

    > >
    > > It makes sense and if the underlying OS supports IPv6 then the bind should
    > > work. The behavior of bind() under IPv6 is described in RFC 3493.
    > >
    > > Why do you believe the bind should fail?

    >
    > Because I'm trying to bind an AF_INET6 address to a PF_INET socket. I
    > don't see anything in 3493 that explicitly says this will fail, but it
    > seems logical. This isn't something which "3.7 Compatibility with IPv4
    > Nodes" talks about.


    Yes. This is logical, because RFC 3493 defines new protocol family PF_INET6.

    | 3.1 IPv6 Address Family and Protocol Family
    |
    | A new address family name, AF_INET6, is defined in .
    | The AF_INET6 definition distinguishes between the original
    | sockaddr_in address data structure, and the new sockaddr_in6 data
    | structure.
    |
    | A new protocol family name, PF_INET6, is defined in .
    | Like most of the other protocol family names, this will usually be
    | defined to have the same value as the corresponding address family
    | name:
    |
    | #define PF_INET6 AF_INET6
    |
    | The AF_INET6 is used in the first argument to the socket() function
    | to indicate that an IPv6 socket is being created.



    > > > #include
    > > > #include
    > > > #include
    > > > #include
    > > > #include
    > > >
    > > > int main (int argc, char* argv[]) {
    > > > * * int s = socket(PF_INET, SOCK_STREAM, 0);
    > > > * * printf ("s = %d\n", s);
    > > >
    > > > * * struct in6_addr anyaddr = IN6ADDR_ANY_INIT;
    > > > * * struct sockaddr_in6 sa;
    > > >
    > > > * * sa.sin6_family = AF_INET6;
    > > > * * sa.sin6_port = 0;
    > > > * * sa.sin6_flowinfo = 0;
    > > > * * sa.sin6_addr = anyaddr;
    > > > * * sa.sin6_scope_id = 0;
    > > >
    > > > * * int retval = bind(s, (struct sockaddr*) &sa, sizeof (sa));
    > > > * * if (retval == 0) {
    > > > * * * * printf ("bind worked\n");
    > > > * * } else {
    > > > * * * * perror ("bind failed");
    > > > * * }
    > > > }


  5. Re: Binding an IPv6 address to an AF_INET socket?

    In article <5dzm48iuog.fsf@Hurtta06k.keh.iki.fi>,
    Kari Hurtta wrote:

    > Roy Smith writes:
    >
    > > In article ,
    > > Jim Logajan wrote:
    > >
    > > > Roy Smith wrote:
    > > > > The code below attempts to bind an IPv6 address to an AF_INET socket.
    > > > > I belive this should fail, yet when compiled and run on our RedHat
    > > > > AS-3 and AS-4 boxes, it prints "bind worked". Does this make sense?
    > > >
    > > > It makes sense and if the underlying OS supports IPv6 then the bind
    > > > should
    > > > work. The behavior of bind() under IPv6 is described in RFC 3493.
    > > >
    > > > Why do you believe the bind should fail?

    > >
    > > Because I'm trying to bind an AF_INET6 address to a PF_INET socket. I
    > > don't see anything in 3493 that explicitly says this will fail, but it
    > > seems logical. This isn't something which "3.7 Compatibility with IPv4
    > > Nodes" talks about.

    >
    > Yes. This is logical, because RFC 3493 defines new protocol family PF_INET6.


    I'm very confused. I know that it defines PF_INET6. But, when I created
    the socket, I created it with PF_INET. I don't understand why or how you
    can bind an AF_INET6 address to a PF_INET socket.

  6. Re: Binding an IPv6 address to an AF_INET socket?

    Roy Smith wrote:
    > I'm very confused. I know that it defines PF_INET6. But, when I
    > created the socket, I created it with PF_INET. I don't understand why
    > or how you can bind an AF_INET6 address to a PF_INET socket.


    I can think of two possible explanations (these do not exclude other
    possibilities of course!):

    (1) The underlying OSs are not doing proper cross-validation of the
    socket's address family with the type of address that is actually being
    requested.

    (2) The underlying OSs are supporting dual-stack mode and allowing IPv4 or
    IPv6 addresses to be bound to any socket created under either address
    family. On these machines the socket() call can treat the PF_INET and
    PF_INET6 as synonymous. So how then does the bind() call know whether the
    address being provided is an IPv4 or IPv6 address? It figures it out by
    examining the first two bytes of the address being supplied - not by
    examining which address family the socket was created for. In this case
    when your code did this assignment:

    sa.sin6_family = AF_INET6;

    it was all the bind() function needed to know that the rest of the contents
    at the address pointed to by &sa was an IPv6 address. If you had messed up
    and did AF_INET (or PF_INET) instead it would have treated the contents at
    &sa as an IPv4 address structure. (ALL the address structure types on dual-
    stack machines typically set aside the first 2 bytes of the structures to
    hold the address family.)

    I believe that explanation (2) is the reason your code is working.

+ Reply to Thread