1 /* vim: set expandtab ts=4 sw=4: */
2 /*
3 * You may redistribute this program and/or modify it under the terms of
4 * the GNU General Public License as published by the Free Software Foundation,
5 * either version 3 of the License, or (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <https://www.gnu.org/licenses/>.
14 */
15 #ifndef Sockaddr_H
16 #define Sockaddr_H
17
18 #include "memory/Allocator.h"
19 #include "util/Endian.h"
20 #include "util/Linker.h"
21 Linker_require("util/platform/Sockaddr.c")
22
23 #include <stdint.h>
24
25 struct Sockaddr
26 {
27 /** the length of this sockaddr, this field is included in the length. */
28 uint16_t addrLen;
29
30 #define Sockaddr_flags_BCAST 1
31 #define Sockaddr_flags_PREFIX (1<<1)
32 uint8_t flags;
33
34 #define Sockaddr_PLATFORM 0
35 #define Sockaddr_HANDLE 1
36 uint8_t type;
37
38 /** Only applies if flags & Sockaddr_flags_PREFIX is true. */
39 uint8_t prefix;
40
41 uint8_t pad1;
42 uint16_t pad2;
43 };
44
45 /** The number of bytes of space taken for representing the addrLen at the beginning. */
46 #define Sockaddr_OVERHEAD 8
47
48 /** The maximum possible size for the native sockaddr (not including Sockaddr_OVERHEAD) */
49 #define Sockaddr_MAXSIZE 128
50 struct Sockaddr_storage
51 {
52 struct Sockaddr addr;
53 uint64_t nativeAddr[Sockaddr_MAXSIZE / 8];
54 };
55
56 /** 127.0.0.1 and ::1 addresses for building from. */
57 extern const struct Sockaddr* const Sockaddr_LOOPBACK_be;
58 extern const struct Sockaddr* const Sockaddr_LOOPBACK_le;
59 #define Sockaddr_LOOPBACK (Endian_isBigEndian() ? Sockaddr_LOOPBACK_be : Sockaddr_LOOPBACK_le)
60
61 extern const struct Sockaddr* const Sockaddr_LOOPBACK6;
62
63 /**
64 * Parse an internal form of Sockaddr which is used to represent a uint32_t handle.
65 * If the length of the address is not equal to sizeof(struct Sockaddr) or the type is not
66 * Sockaddr_HANDLE then this returns Sockaddr_addrHandle_INVALID.
67 */
68 #define Sockaddr_addrHandle_INVALID 0xffffffffu
69 uint32_t Sockaddr_addrHandle(const struct Sockaddr* addr);
70
71 /**
72 * Create a handle sockaddr from a numeric handle, if handle is equal to
73 * Sockaddr_addrHandle_INVALID then this will trigger an assertion.
74 */
75 void Sockaddr_addrFromHandle(struct Sockaddr* addr, uint32_t handle);
76
77
78 int Sockaddr_getPrefix(struct Sockaddr* addr);
79
80 /**
81 * Parse a sockaddr from a string, may be IP4 or IP6.
82 *
83 * @param str a string representation of the sockaddr.
84 * @param output a sockaddr_storage to populate, if null then the validity of the string will be
85 * checked only.
86 * @return 0 if all goes well, -1 if there is an error.
87 */
88 int Sockaddr_parse(const char* str, struct Sockaddr_storage* out);
89
90 /**
91 * Convert a sockaddr to a printable string.
92 */
93 char* Sockaddr_print(struct Sockaddr* addr, struct Allocator* alloc);
94
95 /**
96 * Get the port from a sockaddr if applicable.
97 *
98 * @param a sockaddr.
99 * @return the port number or -1 if not applicable to this sockaddr.
100 */
101 int Sockaddr_getPort(struct Sockaddr* sa);
102
103 /**
104 * Set the port for a sockaddr if applicable.
105 *
106 * @param sa a sockaddr.
107 * @param port the port number to set.
108 * @return 0 if all goes well, -1 if not applicable to this sockaddr.
109 */
110 int Sockaddr_setPort(struct Sockaddr* sa, uint16_t port);
111
112 /**
113 * Get the address family for the address.
114 *
115 * @param a sockaddr.
116 * @return the AF number for this sockaddr.
117 */
118 extern const int Sockaddr_AF_INET;
119 extern const int Sockaddr_AF_INET6;
120 int Sockaddr_getFamily(struct Sockaddr* sa);
121
122 /**
123 * Get the address stored in a sockaddr.
124 *
125 * @param sa a sockaddr.
126 * @param addrPtr a pointer which will be set to the actual address component of the sockaddr.
127 * If NULL, the length will be returned only.
128 * @return the length of the address component in bytes, -1 if failed to parse.
129 */
130 int Sockaddr_getAddress(struct Sockaddr* sa, void* addrPtr);
131
132 /**
133 * Get a new sockaddr from the native form, IE: sockaddr_in or sockaddr_in6.
134 */
135 struct Sockaddr* Sockaddr_fromNative(const void* ss, int addrLen, struct Allocator* alloc);
136
137 /**
138 * Output the native form of a sockaddr.
139 */
Sockaddr_asNative(struct Sockaddr * sa)140 static inline void* Sockaddr_asNative(struct Sockaddr* sa)
141 {
142 return (void*)(&sa[1]);
143 }
Sockaddr_asNativeConst(const struct Sockaddr * sa)144 static inline const void* Sockaddr_asNativeConst(const struct Sockaddr* sa)
145 {
146 return (const void*)(&sa[1]);
147 }
148
149 /**
150 * Contrast with Sockaddr_fromNative(), Sockaddr_fromBytes() takes
151 * input as the bytes of the address eg: Sockaddr_fromBytes({127,0,0,1}, Sockaddr_AF_INET, alloc)
152 */
153 struct Sockaddr* Sockaddr_fromBytes(const uint8_t* bytes, int addrFamily, struct Allocator* alloc);
154
155 /**
156 * Clone the sockaddr, the clone will use only as much memory as the type of sockaddr requires.
157 */
158 struct Sockaddr* Sockaddr_clone(const struct Sockaddr* addr, struct Allocator* alloc);
159
160 /**
161 * Normalize inconsistent native sockaddr implementations
162 */
163 void Sockaddr_normalizeNative(void* nativeSockaddr);
164
165 /**
166 * Get a hash for hashtable lookup.
167 */
168 uint32_t Sockaddr_hash(const struct Sockaddr* addr);
169
170 /**
171 * Compare two sockaddrs for sorting, comparison does not put them in any specific order.
172 */
173 int Sockaddr_compare(const struct Sockaddr* a, const struct Sockaddr* b);
174
175 #endif
176