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 <netinet/in.h>
19  
#include <netinet/in.h>
20  
#include <arpa/inet.h>
20  
#include <arpa/inet.h>
21  
#else
21  
#else
22  
#ifndef WIN32_LEAN_AND_MEAN
22  
#ifndef WIN32_LEAN_AND_MEAN
23  
#define WIN32_LEAN_AND_MEAN
23  
#define WIN32_LEAN_AND_MEAN
24  
#endif
24  
#endif
25  
#ifndef NOMINMAX
25  
#ifndef NOMINMAX
26  
#define NOMINMAX
26  
#define NOMINMAX
27  
#endif
27  
#endif
28  
#include <WinSock2.h>
28  
#include <WinSock2.h>
29  
#include <Ws2tcpip.h>
29  
#include <Ws2tcpip.h>
30  
#endif
30  
#endif
31  

31  

32  
namespace boost::corosio::detail {
32  
namespace boost::corosio::detail {
33  

33  

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

35  

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

49  

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

51  

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

65  

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

67  

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

78  

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

80  

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

91  

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

93  

94  
#endif
94  
#endif