File Coverage

libnet-sockaddr/src/panda/net/sockaddr.h
Criterion Covered Total %
statement 3 3 100.0
branch n/a
condition n/a
subroutine n/a
pod n/a
total 3 3 100.0


line stmt bran cond sub pod time code
1             #pragma once
2             #include
3             #include
4             #include
5             #ifdef _WIN32
6             #include
7             #include
8             #else
9             #include
10             #include
11             #include
12             #endif
13              
14             namespace panda { namespace net {
15              
16             using sa_family_t = decltype(std::declval().sa_family);
17              
18             struct SockAddr {
19             struct Inet4;
20             struct Inet6;
21              
22             static const size_t IP4_MAX_ADDRSTRLEN = 16;
23             static const size_t IP6_MAX_ADDRSTRLEN = 46;
24             static const size_t BASE_LEN = offsetof(sockaddr, sa_data);
25              
26 38           SockAddr () { sa.sa_family = AF_UNSPEC; }
27              
28             SockAddr (const sockaddr* sa, size_t length);
29             SockAddr (const sockaddr_in* sa) : sa4(*sa) {}
30             SockAddr (const sockaddr_in6* sa) : sa6(*sa) {}
31              
32 36           SockAddr (const SockAddr& oth) { operator=(oth); }
33              
34             SockAddr& operator= (const SockAddr& oth);
35              
36 146           sa_family_t family () const { return sa.sa_family; }
37              
38             bool is_inet4 () const { return family() == AF_INET; }
39             bool is_inet6 () const { return family() == AF_INET6; }
40              
41             const Inet4& inet4 () const { return *((const Inet4*)this); }
42             const Inet6& inet6 () const { return *((const Inet6*)this); }
43             Inet4& inet4 () { return *((Inet4*)this); }
44             Inet6& inet6 () { return *((Inet6*)this); }
45              
46             const sockaddr* get () const { return &sa; }
47             sockaddr* get () { return &sa; }
48              
49             bool operator== (const SockAddr& oth) const;
50             bool operator!= (const SockAddr& oth) const { return !operator==(oth); }
51              
52             explicit
53             operator bool () const { return sa.sa_family != AF_UNSPEC; }
54              
55             string ip () const;
56             uint16_t port () const;
57             size_t length () const;
58              
59             template
60             void assign_foreign (Function&& fn) {
61             size_t length = sizeof(SockAddr); // max size
62             bool success = fn(&sa, &length);
63             if (success) {
64             // length is the actual size
65             validate(&sa, length);
66             #ifndef _WIN32
67             if (sa.sa_family == AF_UNIX) fix_unix_path(length);
68             #endif
69             }
70             }
71              
72             #ifndef _WIN32
73             static const size_t PATH_OFFSET = offsetof(sockaddr_un, sun_path);
74             struct Unix;
75              
76             SockAddr (const sockaddr_un* sa, size_t length) : SockAddr((const sockaddr*)sa, length) {}
77              
78             bool is_unix () const { return family() == AF_UNIX; }
79              
80             Unix& unix () const { return *((Unix*)this); }
81             #endif
82              
83             protected:
84             union {
85             sockaddr sa;
86             sockaddr_in sa4;
87             sockaddr_in6 sa6;
88             #ifndef _WIN32
89             sockaddr_un sau;
90             #endif
91             };
92              
93             private:
94             void validate (const sockaddr*, size_t len);
95              
96             #ifndef _WIN32
97             void fix_unix_path (size_t length) noexcept;
98             #endif
99             };
100              
101             std::ostream& operator<< (std::ostream&, const SockAddr&);
102              
103             struct SockAddr::Inet4 : SockAddr {
104             static const in_addr addr_any;
105             static const in_addr addr_loopback;
106             static const in_addr addr_broadcast;
107             static const in_addr addr_none;
108             static const Inet4 sockaddr_any;
109             static const Inet4 sockaddr_loopback;
110              
111             Inet4 (const sockaddr_in* sa) : SockAddr(sa) {}
112             Inet4 (const Inet4& oth) : SockAddr(oth.get()) {}
113              
114             Inet4 (const string_view& ip, uint16_t port);
115             Inet4 (const in_addr& addr, uint16_t port);
116              
117             const in_addr& addr () const { return sa4.sin_addr; }
118             in_addr& addr () { return sa4.sin_addr; }
119              
120             const sockaddr_in* get () const { return &sa4; }
121             sockaddr_in* get () { return &sa4; }
122              
123             uint16_t port () const { return ntohs(sa4.sin_port); }
124             string ip () const;
125             };
126              
127             struct SockAddr::Inet6 : SockAddr {
128             static const in6_addr addr_any;
129             static const in6_addr addr_loopback;
130             static const Inet6 sockaddr_any;
131             static const Inet6 sockaddr_loopback;
132              
133             Inet6 (const sockaddr_in6* sa) : SockAddr(sa) {}
134             Inet6 (const Inet6& oth) : SockAddr(oth.get()) {}
135              
136             Inet6 (const string_view& ip, uint16_t port, uint32_t scope_id = 0, uint32_t flowinfo = 0);
137             Inet6 (const in6_addr& addr, uint16_t port, uint32_t scope_id = 0, uint32_t flowinfo = 0);
138              
139             const in6_addr& addr () const { return sa6.sin6_addr; }
140             in6_addr& addr () { return sa6.sin6_addr; }
141              
142             const sockaddr_in6* get () const { return &sa6; }
143             sockaddr_in6* get () { return &sa6; }
144              
145             string ip () const;
146             uint16_t port () const { return ntohs(sa6.sin6_port); }
147             uint32_t scope_id () const { return sa6.sin6_scope_id; }
148             uint32_t flowinfo () const { return ntohl(sa6.sin6_flowinfo); }
149             };
150              
151             #ifndef _WIN32
152              
153             struct SockAddr::Unix : SockAddr {
154             Unix (const sockaddr_un* sa, size_t length) : SockAddr(sa, length) {}
155             Unix (const Unix& oth) : SockAddr(oth) {}
156              
157             Unix (const string_view& path);
158              
159             string_view path () const { return (char*)sau.sun_path; }
160              
161             const sockaddr_un* get () const { return &sau; }
162             sockaddr_un* get () { return &sau; }
163             };
164              
165             #endif
166              
167             }}