btrfs: Attempt to fix GCC2 build.
[haiku.git] / src / add-ons / kernel / network / protocols / unix / UnixAddress.cpp
blob12fcb3a81e0406b47ba16a7b0dd71a38aa93d39c
1 /*
2 * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
6 #include "UnixAddress.h"
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
12 #include <util/StringHash.h>
14 #include <net_datalink.h>
15 #include <NetUtilities.h>
17 #include "unix.h"
20 static const sockaddr_un kEmptyAddress = {
21 4, // sun_len
22 AF_UNIX, // sun_family
23 { '\0', '\0' } // sun_path
27 char*
28 UnixAddress::ToString(char *buffer, size_t bufferSize) const
30 if (!IsValid())
31 strlcpy(buffer, "<empty>", bufferSize);
32 else if (IsInternalAddress())
33 snprintf(buffer, bufferSize, "<%05" B_PRIx32 ">", fInternalID);
34 else {
35 snprintf(buffer, bufferSize, "<%" B_PRIdDEV ", %" B_PRIdINO ">",
36 fVolumeID, fNodeID);
39 return buffer;
43 // #pragma mark -
46 static status_t
47 unix_copy_address(const sockaddr *from, sockaddr **to, bool replaceWithZeros,
48 const sockaddr *mask)
50 if (replaceWithZeros) {
51 sockaddr_un* newAddress = (sockaddr_un*)malloc(kEmptyAddress.sun_len);
52 if (newAddress == NULL)
53 return B_NO_MEMORY;
55 memcpy(newAddress, &kEmptyAddress, kEmptyAddress.sun_len);
57 *to = (sockaddr*)newAddress;
58 return B_OK;
59 } else {
60 if (from->sa_family != AF_UNIX)
61 return B_MISMATCHED_VALUES;
63 *to = (sockaddr*)malloc(from->sa_len);
64 if (*to == NULL)
65 return B_NO_MEMORY;
67 memcpy(*to, from, from->sa_len);
69 return B_OK;
74 static bool
75 unix_equal_addresses(const sockaddr *a, const sockaddr *b)
77 // NOTE: We compare syntactically only. The real check would involve
78 // looking up the node, if for FS addresses.
79 if (a->sa_len != b->sa_len)
80 return false;
82 return memcmp(a, b, a->sa_len) == 0;
86 static bool
87 unix_equal_ports(const sockaddr *a, const sockaddr *b)
89 // no ports
90 return true;
94 static bool
95 unix_equal_addresses_and_ports(const sockaddr *a, const sockaddr *b)
97 return unix_equal_addresses(a, b);
101 static bool
102 unix_equal_masked_addresses(const sockaddr *a, const sockaddr *b,
103 const sockaddr *mask)
105 // no masks
106 return unix_equal_addresses(a, b);
110 static bool
111 unix_is_empty_address(const sockaddr *address, bool checkPort)
113 return address == NULL || address->sa_len == 0
114 || address->sa_family == AF_UNSPEC
115 || (address->sa_len >= kEmptyAddress.sun_len
116 && memcmp(address, &kEmptyAddress, kEmptyAddress.sun_len) == 0);
120 static bool
121 unix_is_same_family(const sockaddr *address)
123 if (address == NULL)
124 return false;
126 return address->sa_family == AF_UNIX;
130 static int32
131 unix_first_mask_bit(const sockaddr *mask)
133 return 0;
137 static bool
138 unix_check_mask(const sockaddr *address)
140 return false;
144 static status_t
145 unix_print_address_buffer(const sockaddr *_address, char *buffer,
146 size_t bufferSize, bool printPort)
148 if (!buffer)
149 return B_BAD_VALUE;
151 sockaddr_un* address = (sockaddr_un*)_address;
153 if (address == NULL)
154 strlcpy(buffer, "<none>", bufferSize);
155 else if (address->sun_path[0] != '\0')
156 strlcpy(buffer, address->sun_path, bufferSize);
157 else if (address->sun_path[1] != '\0')
158 snprintf(buffer, bufferSize, "<%.5s>", address->sun_path + 1);
159 else
160 strlcpy(buffer, "<empty>", bufferSize);
162 return B_OK;
166 static status_t
167 unix_print_address(const sockaddr *address, char **_buffer, bool printPort)
169 char buffer[128];
170 status_t error = unix_print_address_buffer(address, buffer, sizeof(buffer),
171 printPort);
172 if (error != B_OK)
173 return error;
175 *_buffer = strdup(buffer);
176 return *_buffer != NULL ? B_OK : B_NO_MEMORY;
180 static uint16
181 unix_get_port(const sockaddr *address)
183 return 0;
187 static status_t
188 unix_set_port(sockaddr *address, uint16 port)
190 return B_BAD_VALUE;
194 static status_t
195 unix_set_to(sockaddr *address, const sockaddr *from)
197 if (address == NULL || from == NULL)
198 return B_BAD_VALUE;
200 if (from->sa_family != AF_UNIX)
201 return B_MISMATCHED_VALUES;
203 memcpy(address, from, from->sa_len);
204 return B_OK;
208 static status_t
209 unix_set_to_empty_address(sockaddr *address)
211 return unix_set_to(address, (sockaddr*)&kEmptyAddress);
215 static status_t
216 unix_mask_address(const sockaddr *address, const sockaddr *mask,
217 sockaddr *result)
219 // no masks
220 return unix_set_to(result, address);
224 static status_t
225 unix_set_to_defaults(sockaddr *defaultMask, sockaddr *defaultBroadcast,
226 const sockaddr *address, const sockaddr *netmask)
228 if (address == NULL)
229 return B_BAD_VALUE;
231 status_t error = B_OK;
232 if (defaultMask != NULL)
233 error = unix_set_to_empty_address(defaultMask);
234 if (error == B_OK && defaultBroadcast != NULL)
235 error = unix_set_to_empty_address(defaultBroadcast);
237 return error;
241 static status_t
242 unix_update_to(sockaddr *address, const sockaddr *from)
244 if (address == NULL || from == NULL)
245 return B_BAD_VALUE;
247 if (unix_is_empty_address(from, false))
248 return B_OK;
250 return unix_set_to(address, from);
254 static uint32
255 unix_hash_address(const sockaddr* _address, bool includePort)
257 sockaddr_un* address = (sockaddr_un*)_address;
258 if (address == NULL)
259 return 0;
261 if (address->sun_path[0] == '\0') {
262 char buffer[6];
263 strlcpy(buffer, address->sun_path + 1, 6);
264 return hash_hash_string(buffer);
267 return hash_hash_string(address->sun_path);
271 static uint32
272 unix_hash_address_pair(const sockaddr *ourAddress, const sockaddr *peerAddress)
274 return unix_hash_address(ourAddress, false) * 17
275 + unix_hash_address(peerAddress, false);
279 static status_t
280 unix_checksum_address(struct Checksum *checksum, const sockaddr *_address)
282 if (checksum == NULL || _address == NULL)
283 return B_BAD_VALUE;
285 sockaddr_un* address = (sockaddr_un*)_address;
286 int len = (char*)address + address->sun_len - address->sun_path;
287 for (int i = 0; i < len; i++)
288 (*checksum) << (uint8)address->sun_path[i];
290 return B_OK;
294 net_address_module_info gAddressModule = {
296 NULL,
298 NULL
300 NET_ADDRESS_MODULE_FLAG_BROADCAST_ADDRESS,
301 unix_copy_address,
302 unix_mask_address,
303 unix_equal_addresses,
304 unix_equal_ports,
305 unix_equal_addresses_and_ports,
306 unix_equal_masked_addresses,
307 unix_is_empty_address,
308 unix_is_same_family,
309 unix_first_mask_bit,
310 unix_check_mask,
311 unix_print_address,
312 unix_print_address_buffer,
313 unix_get_port,
314 unix_set_port,
315 unix_set_to,
316 unix_set_to_empty_address,
317 unix_set_to_defaults,
318 unix_update_to,
319 unix_hash_address,
320 unix_hash_address_pair,
321 unix_checksum_address,
322 NULL // get_loopback_address