1  
//
1  
//
2  
// Copyright (c) 2026 Vinnie Falco (vinnie.falco@gmail.com)
2  
// Copyright (c) 2026 Vinnie Falco (vinnie.falco@gmail.com)
3  
//
3  
//
4  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
4  
// Distributed under the Boost Software License, Version 1.0. (See accompanying
5  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
5  
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6  
//
6  
//
7  
// Official repository: https://github.com/cppalliance/corosio
7  
// Official repository: https://github.com/cppalliance/corosio
8  
//
8  
//
9  

9  

10  
#ifndef BOOST_COROSIO_DETAIL_ENDPOINT_CONVERT_HPP
10  
#ifndef BOOST_COROSIO_DETAIL_ENDPOINT_CONVERT_HPP
11  
#define BOOST_COROSIO_DETAIL_ENDPOINT_CONVERT_HPP
11  
#define BOOST_COROSIO_DETAIL_ENDPOINT_CONVERT_HPP
12  

12  

13  
#include <boost/corosio/endpoint.hpp>
13  
#include <boost/corosio/endpoint.hpp>
14  
#include <boost/corosio/detail/platform.hpp>
14  
#include <boost/corosio/detail/platform.hpp>
15  

15  

16  
#include <cstring>
16  
#include <cstring>
17  

17  

18  
#if BOOST_COROSIO_POSIX
18  
#if BOOST_COROSIO_POSIX
19  
#include <sys/socket.h>
19  
#include <sys/socket.h>
20  
#include <netinet/in.h>
20  
#include <netinet/in.h>
21  
#include <arpa/inet.h>
21  
#include <arpa/inet.h>
22  
#else
22  
#else
23  
#ifndef WIN32_LEAN_AND_MEAN
23  
#ifndef WIN32_LEAN_AND_MEAN
24  
#define WIN32_LEAN_AND_MEAN
24  
#define WIN32_LEAN_AND_MEAN
25  
#endif
25  
#endif
26  
#ifndef NOMINMAX
26  
#ifndef NOMINMAX
27  
#define NOMINMAX
27  
#define NOMINMAX
28  
#endif
28  
#endif
29  
#include <WinSock2.h>
29  
#include <WinSock2.h>
30  
#include <Ws2tcpip.h>
30  
#include <Ws2tcpip.h>
31  
#endif
31  
#endif
32  

32  

33  
namespace boost::corosio::detail {
33  
namespace boost::corosio::detail {
34  

34  

35  
/** Convert IPv4 endpoint to sockaddr_in.
35  
/** Convert IPv4 endpoint to sockaddr_in.
36  

36  

37  
    @param ep The endpoint to convert. Must be IPv4 (is_v4() == true).
37  
    @param ep The endpoint to convert. Must be IPv4 (is_v4() == true).
38  
    @return A sockaddr_in structure with fields in network byte order.
38  
    @return A sockaddr_in structure with fields in network byte order.
39  
*/
39  
*/
40  
inline sockaddr_in
40  
inline sockaddr_in
41  
to_sockaddr_in(endpoint const& ep) noexcept
41  
to_sockaddr_in(endpoint const& ep) noexcept
42  
{
42  
{
43  
    sockaddr_in sa{};
43  
    sockaddr_in sa{};
44  
    sa.sin_family = AF_INET;
44  
    sa.sin_family = AF_INET;
45  
    sa.sin_port   = htons(ep.port());
45  
    sa.sin_port   = htons(ep.port());
46  
    auto bytes    = ep.v4_address().to_bytes();
46  
    auto bytes    = ep.v4_address().to_bytes();
47  
    std::memcpy(&sa.sin_addr, bytes.data(), 4);
47  
    std::memcpy(&sa.sin_addr, bytes.data(), 4);
48  
    return sa;
48  
    return sa;
49  
}
49  
}
50  

50  

51  
/** Convert IPv6 endpoint to sockaddr_in6.
51  
/** Convert IPv6 endpoint to sockaddr_in6.
52  

52  

53  
    @param ep The endpoint to convert. Must be IPv6 (is_v6() == true).
53  
    @param ep The endpoint to convert. Must be IPv6 (is_v6() == true).
54  
    @return A sockaddr_in6 structure with fields in network byte order.
54  
    @return A sockaddr_in6 structure with fields in network byte order.
55  
*/
55  
*/
56  
inline sockaddr_in6
56  
inline sockaddr_in6
57  
to_sockaddr_in6(endpoint const& ep) noexcept
57  
to_sockaddr_in6(endpoint const& ep) noexcept
58  
{
58  
{
59  
    sockaddr_in6 sa{};
59  
    sockaddr_in6 sa{};
60  
    sa.sin6_family = AF_INET6;
60  
    sa.sin6_family = AF_INET6;
61  
    sa.sin6_port   = htons(ep.port());
61  
    sa.sin6_port   = htons(ep.port());
62  
    auto bytes     = ep.v6_address().to_bytes();
62  
    auto bytes     = ep.v6_address().to_bytes();
63  
    std::memcpy(&sa.sin6_addr, bytes.data(), 16);
63  
    std::memcpy(&sa.sin6_addr, bytes.data(), 16);
64  
    return sa;
64  
    return sa;
65  
}
65  
}
66  

66  

67  
/** Create endpoint from sockaddr_in.
67  
/** Create endpoint from sockaddr_in.
68  

68  

69  
    @param sa The sockaddr_in structure with fields in network byte order.
69  
    @param sa The sockaddr_in structure with fields in network byte order.
70  
    @return An endpoint with address and port extracted from sa.
70  
    @return An endpoint with address and port extracted from sa.
71  
*/
71  
*/
72  
inline endpoint
72  
inline endpoint
73  
from_sockaddr_in(sockaddr_in const& sa) noexcept
73  
from_sockaddr_in(sockaddr_in const& sa) noexcept
74  
{
74  
{
75  
    ipv4_address::bytes_type bytes;
75  
    ipv4_address::bytes_type bytes;
76  
    std::memcpy(bytes.data(), &sa.sin_addr, 4);
76  
    std::memcpy(bytes.data(), &sa.sin_addr, 4);
77  
    return endpoint(ipv4_address(bytes), ntohs(sa.sin_port));
77  
    return endpoint(ipv4_address(bytes), ntohs(sa.sin_port));
78  
}
78  
}
79  

79  

80  
/** Create endpoint from sockaddr_in6.
80  
/** Create endpoint from sockaddr_in6.
81  

81  

82  
    @param sa The sockaddr_in6 structure with fields in network byte order.
82  
    @param sa The sockaddr_in6 structure with fields in network byte order.
83  
    @return An endpoint with address and port extracted from sa.
83  
    @return An endpoint with address and port extracted from sa.
84  
*/
84  
*/
85  
inline endpoint
85  
inline endpoint
86  
from_sockaddr_in6(sockaddr_in6 const& sa) noexcept
86  
from_sockaddr_in6(sockaddr_in6 const& sa) noexcept
87  
{
87  
{
88  
    ipv6_address::bytes_type bytes;
88  
    ipv6_address::bytes_type bytes;
89  
    std::memcpy(bytes.data(), &sa.sin6_addr, 16);
89  
    std::memcpy(bytes.data(), &sa.sin6_addr, 16);
90  
    return endpoint(ipv6_address(bytes), ntohs(sa.sin6_port));
90  
    return endpoint(ipv6_address(bytes), ntohs(sa.sin6_port));
91  
}
91  
}
92  

92  

93  
} // namespace boost::corosio::detail
93  
} // namespace boost::corosio::detail
94  

94  

95  
#endif
95  
#endif