locked
GetAddrInfoW works with both IPv4 and IPv6 at the same time? RRS feed

  • Question

  • There is an example of this link: https://docs.microsoft.com/en-us/windows/win32/api/ws2tcpip/nf-ws2tcpip-getaddrinfow

    In this example, IPv4 and IPv6 work the same when using ptr->ai_addr:
    sockaddr_ip = ptr->ai_addr;
    sockaddr_ip = (LPSOCKADDR) ptr->ai_addr;
    But the "sockaddr" structure has 16 bytes. How can I write 28 bytes to it?

    If you use the method with the "WSAAddressToString" api-function to work with IPv6, then only 16 bytes will be used, and the remaining 12 bytes will be outside and will not be used?

    How do I explain this discrepancy?




    • Edited by MSDN Member Tuesday, March 17, 2020 7:34 PM
    Tuesday, March 17, 2020 9:25 AM

Answers

  • Starting from the very basics, a pointer just contains an address. So struct sockaddr * and struct sockaddr_in * are pretty much the same. They both just store an address. Only relevant difference is how compiler treats their objects.

    So when you pass (LPSOCKADDR)ptr->ai_addr, you are just passing the start address of the buffer, and then the dwAddressLength specifies the length of the buffer.

    Best Regards,

    Drake


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by MSDN Member Wednesday, March 18, 2020 4:21 AM
    Wednesday, March 18, 2020 3:23 AM

All replies

  • There is an example of this link: https://docs.microsoft.com/en-us/windows/win32/api/ws2tcpip/nf-ws2tcpip-getaddrinfow

    In this example, IPv4 and IPv6 work the same when using ptr->ai_addr:
    sockaddr_ip = ptr->ai_addr;
    sockaddr_ipv6 = (struct sockaddr_in6 *) ptr->ai_addr;
    But the structures: "sockaddr" and "sockaddr_in6" have different lengths: "sockaddr" has 16 bytes and "sockaddr_in6" has 28 bytes.

    If you use the method with the "WSAAddressToString" api-function to work with IPv6, then only 16 bytes will be used, and the remaining 12 bytes will be outside and will not be used?

    How do I explain this discrepancy?


    Note that the second parameter to WSAAddressToString takes the buffer length contained in the ADDRINFOW structure (ptr->ai_addrlen in the sample code).
    Tuesday, March 17, 2020 10:40 AM
  • RLWA32, I don 't think your answer is an answer.
    GetaddrinfoW writes information to RAM. This information takes up a certain number of bytes (or something else - I don't understand it).
    In one case, fewer bytes are used, and in the other, more. Inconsistency.
    Tuesday, March 17, 2020 10:50 AM
  • RLWA32, I don 't think your answer is an answer.
    GetaddrinfoW writes information to RAM. This information takes up a certain number of bytes (or something else - I don't understand it).
    In one case, fewer bytes are used, and in the other, more. Inconsistency.

    I'm not going to debate with you.

    Step through the sample code in the debugger line by line and study how the information returned by GetAddrInfoW is used.

    Tuesday, March 17, 2020 11:00 AM
  • RLWA32, thank you for your participation. Something began to turn out.

    How do 28 bytes get written to a "sockaddr" structure that has 16 bytes?

    • Edited by MSDN Member Tuesday, March 17, 2020 7:12 PM
    Tuesday, March 17, 2020 7:05 PM
  • They don't.  If you're doing an IPv4 query, you will set ai_addrlen to 16.  If you're doing an IPv6 query, you will set ai_addrlen to 28.  The API will adjust its behavior accordingly.

    Tim Roberts | Driver MVP Emeritus | Providenza & Boekelheide, Inc.

    Tuesday, March 17, 2020 7:23 PM
  • I got it wrong in the first message. I wrote the wrong question.

    I fixed it now.

    I'm still confused myself. Because there are a lot of structures and api functions. I don't remember why I asked the question like that at first.

    • Edited by MSDN Member Tuesday, March 17, 2020 7:36 PM
    Tuesday, March 17, 2020 7:33 PM
  • Hi, 

    Thanks for posting here.

    According to the sockaddr document:

    • Winsock functions using sockaddr are not strictly interpreted to be pointers to a sockaddr structure. The structure is interpreted differently in the context of different address families. The only requirements are that the first u_short is the address family and the total size of the memory buffer in bytes is namelen(ai_addrlen).

    So the struct is "variable-sized",  GetAddrInfoW will first determine the address family, and then return different buffers according to different families.

    How do 28 bytes get written to a "sockaddr" structure that has 16 bytes?

    sockaddr_ip = (LPSOCKADDR)ptr->ai_addr;

    If you mean how this line convert from 28 bytes to 16 bytes, whether it stack overflow?
    This is just copying a pointer to the data buffer, there is no data written.

    If you use the method with the "WSAAddressToString" api-function to work with IPv6, then only 16 bytes will be used, and the remaining 12 bytes will be outside and will not be used?

    As comments of RLWA32 and Roberts, The WSAAddressToString function judges the address family and the data buffer size of the sockaddr pointer according to the parameter dwAddressLength.

    And note that the size of data buffer which these apis used is not equal to the size of struct, when the address family is IPv6.

    Best Regards,

    Drake


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, March 18, 2020 3:11 AM
  • Starting from the very basics, a pointer just contains an address. So struct sockaddr * and struct sockaddr_in * are pretty much the same. They both just store an address. Only relevant difference is how compiler treats their objects.

    So when you pass (LPSOCKADDR)ptr->ai_addr, you are just passing the start address of the buffer, and then the dwAddressLength specifies the length of the buffer.

    Best Regards,

    Drake


    MSDN Community Support Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by MSDN Member Wednesday, March 18, 2020 4:21 AM
    Wednesday, March 18, 2020 3:23 AM
  • thanks
    Wednesday, March 18, 2020 4:21 AM