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