1 /*
2 * Copyright 2006-2024, Haiku, Inc. All Rights Reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 * Oliver Ruiz Dorantes, oliver.ruiz.dorantes_at_gmail.com
7 */
8
9
10 #include <net_datalink.h>
11
12 #include <ByteOrder.h>
13 #include <KernelExport.h>
14
15 #include <NetUtilities.h>
16
17 #include <memory.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20
21 #include <bluetooth/bdaddrUtils.h>
22 #include <bluetooth/L2CAP/btL2CAP.h>
23
24
25 static status_t
l2cap_copy_address(const sockaddr * from,sockaddr ** to,bool replaceWithZeros=false,const sockaddr * mask=NULL)26 l2cap_copy_address(const sockaddr *from, sockaddr **to,
27 bool replaceWithZeros = false, const sockaddr *mask = NULL)
28 {
29 if (replaceWithZeros) {
30 *to = (sockaddr *)malloc(sizeof(sockaddr_in));
31 if (*to == NULL)
32 return B_NO_MEMORY;
33
34 memset(*to, 0, sizeof(sockaddr_l2cap));
35 (*to)->sa_family = AF_BLUETOOTH;
36 (*to)->sa_len = sizeof(sockaddr_l2cap);
37 } else {
38 if (from == NULL)
39 return B_OK;
40 if (from->sa_family != AF_BLUETOOTH)
41 return B_MISMATCHED_VALUES;
42
43 *to = (sockaddr *)malloc(sizeof(sockaddr_in));
44 if (*to == NULL)
45 return B_NO_MEMORY;
46
47 memcpy(*to, from, sizeof(sockaddr_l2cap));
48
49 }
50 return B_OK;
51 }
52
53
54 static bool
l2cap_is_empty_address(const sockaddr * address,bool checkPort)55 l2cap_is_empty_address(const sockaddr *address, bool checkPort)
56 {
57 if (address == NULL || address->sa_len == 0
58 || address->sa_family == AF_UNSPEC)
59 return true;
60
61 return ((bdaddrUtils::Compare(
62 ((const sockaddr_l2cap *)address)->l2cap_bdaddr, BDADDR_NULL))
63 && (!checkPort || ((sockaddr_l2cap *)address)->l2cap_psm == 0));
64 }
65
66
67 static bool
l2cap_is_same_family(const sockaddr * address)68 l2cap_is_same_family(const sockaddr *address)
69 {
70 if (address == NULL)
71 return false;
72
73 return address->sa_family == AF_BLUETOOTH;
74 }
75
76
77 static bool
l2cap_equal_addresses(const sockaddr * a,const sockaddr * b)78 l2cap_equal_addresses(const sockaddr *a, const sockaddr *b)
79 {
80 if (a == NULL && b == NULL)
81 return true;
82 if (a != NULL && b == NULL)
83 return l2cap_is_empty_address(a, false);
84 if (a == NULL && b != NULL)
85 return l2cap_is_empty_address(b, false);
86
87 return bdaddrUtils::Compare(((const sockaddr_l2cap*)a)->l2cap_bdaddr,
88 ((sockaddr_l2cap*)b)->l2cap_bdaddr);
89 }
90
91
92 static bool
l2cap_equal_ports(const sockaddr * a,const sockaddr * b)93 l2cap_equal_ports(const sockaddr *a, const sockaddr *b)
94 {
95 uint16 portA = a ? ((sockaddr_l2cap *)a)->l2cap_psm : 0;
96 uint16 portB = b ? ((sockaddr_l2cap *)b)->l2cap_psm : 0;
97 return portA == portB;
98 }
99
100
101 static bool
l2cap_equal_addresses_and_ports(const sockaddr * a,const sockaddr * b)102 l2cap_equal_addresses_and_ports(const sockaddr *a, const sockaddr *b)
103 {
104 if (a == NULL && b == NULL)
105 return true;
106 if (a != NULL && b == NULL)
107 return l2cap_is_empty_address(a, true);
108 if (a == NULL && b != NULL)
109 return l2cap_is_empty_address(b, true);
110
111 return (bdaddrUtils::Compare(((const sockaddr_l2cap *)a)->l2cap_bdaddr,
112 ((const sockaddr_l2cap *)b)->l2cap_bdaddr))
113 && ((sockaddr_l2cap *)a)->l2cap_psm == ((sockaddr_l2cap *)b)->l2cap_psm;
114 }
115
116
117 static bool
l2cap_equal_masked_addresses(const sockaddr * a,const sockaddr * b,const sockaddr * mask)118 l2cap_equal_masked_addresses(const sockaddr *a, const sockaddr *b,
119 const sockaddr *mask)
120 {
121 // no masks
122 return l2cap_equal_addresses(a, b);
123 }
124
125
126 static int32
l2cap_first_mask_bit(const sockaddr * _mask)127 l2cap_first_mask_bit(const sockaddr *_mask)
128 {
129 return 0;
130 }
131
132
133 static bool
l2cap_check_mask(const sockaddr * _mask)134 l2cap_check_mask(const sockaddr *_mask)
135 {
136 return false;
137 }
138
139
140 static status_t
l2cap_print_address_buffer(const sockaddr * _address,char * buffer,size_t bufferSize,bool printPort)141 l2cap_print_address_buffer(const sockaddr *_address, char *buffer,
142 size_t bufferSize, bool printPort)
143 {
144 if (buffer == NULL)
145 return B_BAD_VALUE;
146
147 const sockaddr_l2cap *address = (const sockaddr_l2cap *)_address;
148 if (address == NULL) {
149 strlcpy(buffer, "<none>", bufferSize);
150 } else {
151 bdaddr_t addr = address->l2cap_bdaddr;
152 if (printPort) {
153 snprintf(buffer, bufferSize,
154 "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X|%u", addr.b[0],
155 addr.b[1],addr.b[2],addr.b[3],addr.b[4],addr.b[5],
156 address->l2cap_psm);
157 } else {
158 snprintf(buffer, bufferSize,
159 "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",addr.b[0],
160 addr.b[1],addr.b[2],addr.b[3],addr.b[4],addr.b[5]);
161 }
162 }
163
164 return B_OK;
165 }
166
167
168 static status_t
l2cap_print_address(const sockaddr * _address,char ** _buffer,bool printPort)169 l2cap_print_address(const sockaddr *_address, char **_buffer, bool printPort)
170 {
171 if (_buffer == NULL)
172 return B_BAD_VALUE;
173
174 char tmp[32];
175 l2cap_print_address_buffer(_address, tmp, sizeof(tmp), printPort);
176
177 *_buffer = strdup(tmp);
178 if (*_buffer == NULL)
179 return B_NO_MEMORY;
180
181 return B_OK;
182 }
183
184
185 static uint16
l2cap_get_port(const sockaddr * address)186 l2cap_get_port(const sockaddr *address)
187 {
188 if (address == NULL)
189 return 0;
190
191 return ((sockaddr_l2cap *)address)->l2cap_psm;
192 }
193
194
195 static status_t
l2cap_set_port(sockaddr * address,uint16 port)196 l2cap_set_port(sockaddr *address, uint16 port)
197 {
198 if (address == NULL)
199 return B_BAD_VALUE;
200
201 ((sockaddr_l2cap *)address)->l2cap_psm = port;
202 return B_OK;
203 }
204
205
206 static status_t
l2cap_set_to(sockaddr * address,const sockaddr * from)207 l2cap_set_to(sockaddr *address, const sockaddr *from)
208 {
209 if (address == NULL || from == NULL)
210 return B_BAD_VALUE;
211
212 if (from->sa_family != AF_BLUETOOTH)
213 return B_MISMATCHED_VALUES;
214
215 memcpy(address, from, sizeof(sockaddr_l2cap));
216 return B_OK;
217 }
218
219
220 static status_t
l2cap_mask_address(const sockaddr * address,const sockaddr * mask,sockaddr * result)221 l2cap_mask_address(const sockaddr *address, const sockaddr *mask,
222 sockaddr *result)
223 {
224 // no masks
225 return l2cap_set_to(result, address);
226 }
227
228
229 static status_t
l2cap_update_to(sockaddr * _address,const sockaddr * _from)230 l2cap_update_to(sockaddr *_address, const sockaddr *_from)
231 {
232 sockaddr_l2cap *address = (sockaddr_l2cap *)_address;
233 const sockaddr_l2cap *from = (const sockaddr_l2cap *)_from;
234
235 if (address == NULL || from == NULL)
236 return B_BAD_VALUE;
237
238 if (from->l2cap_family != AF_BLUETOOTH)
239 return B_BAD_VALUE;
240
241 address->l2cap_family = AF_BLUETOOTH;
242 address->l2cap_len = sizeof(sockaddr_l2cap);
243
244 if (bdaddrUtils::Compare(address->l2cap_bdaddr, BDADDR_NULL))
245 address->l2cap_bdaddr = from->l2cap_bdaddr;
246
247 if (address->l2cap_psm == 0)
248 address->l2cap_psm = from->l2cap_psm;
249
250 return B_OK;
251 }
252
253
254 static status_t
l2cap_set_to_empty_address(sockaddr * address)255 l2cap_set_to_empty_address(sockaddr *address)
256 {
257 if (address == NULL)
258 return B_BAD_VALUE;
259
260 memset(address, 0, sizeof(sockaddr_l2cap));
261 address->sa_len = sizeof(sockaddr_l2cap);
262 address->sa_family = AF_BLUETOOTH;
263 return B_OK;
264 }
265
266
267 static status_t
l2cap_set_to_defaults(sockaddr * _defaultMask,sockaddr * _defaultBroadcast,const sockaddr * _address,const sockaddr * _mask)268 l2cap_set_to_defaults(sockaddr *_defaultMask, sockaddr *_defaultBroadcast,
269 const sockaddr *_address, const sockaddr *_mask)
270 {
271 if (_address == NULL)
272 return B_BAD_VALUE;
273
274 status_t error = B_OK;
275 if (_defaultMask != NULL)
276 error = l2cap_set_to_empty_address(_defaultMask);
277 if (error == B_OK && _defaultBroadcast != NULL)
278 error = l2cap_set_to_empty_address(_defaultBroadcast);
279
280 return error;
281 }
282
283
284 static uint32
l2cap_hash_address(const struct sockaddr * _address,bool includePort)285 l2cap_hash_address(const struct sockaddr* _address, bool includePort)
286 {
287 const sockaddr_l2cap* address = (const sockaddr_l2cap*)_address;
288 if (address == NULL || address->l2cap_len == 0)
289 return 0;
290
291 uint32 hash = 0;
292 for (size_t i = 0; i < sizeof(address->l2cap_bdaddr.b); i++)
293 hash += address->l2cap_bdaddr.b[i] << (i * 2);
294
295 if (includePort)
296 hash += address->l2cap_psm;
297 return hash;
298 }
299
300
301 static uint32
l2cap_hash_address_pair(const sockaddr * ourAddress,const sockaddr * peerAddress)302 l2cap_hash_address_pair(const sockaddr *ourAddress, const sockaddr *peerAddress)
303 {
304 return l2cap_hash_address(ourAddress, true) * 17
305 + l2cap_hash_address(peerAddress, true);
306 }
307
308
309 static status_t
l2cap_checksum_address(struct Checksum * checksum,const sockaddr * address)310 l2cap_checksum_address(struct Checksum *checksum, const sockaddr *address)
311 {
312 if (checksum == NULL || address == NULL)
313 return B_BAD_VALUE;
314
315 for (uint i = 0; i < sizeof(bdaddr_t); i++)
316 (*checksum) << ((sockaddr_l2cap*)address)->l2cap_bdaddr.b[i];
317
318 return B_OK;
319 }
320
321
322 net_address_module_info gL2capAddressModule = {
323 {
324 NULL,
325 0,
326 NULL
327 },
328 NET_ADDRESS_MODULE_FLAG_BROADCAST_ADDRESS,
329 l2cap_copy_address,
330 l2cap_mask_address,
331 l2cap_equal_addresses,
332 l2cap_equal_ports,
333 l2cap_equal_addresses_and_ports,
334 l2cap_equal_masked_addresses,
335 l2cap_is_empty_address,
336 l2cap_is_same_family,
337 l2cap_first_mask_bit,
338 l2cap_check_mask,
339 l2cap_print_address,
340 l2cap_print_address_buffer,
341 l2cap_get_port,
342 l2cap_set_port,
343 l2cap_set_to,
344 l2cap_set_to_empty_address,
345 l2cap_set_to_defaults,
346 l2cap_update_to,
347 l2cap_hash_address,
348 l2cap_hash_address_pair,
349 l2cap_checksum_address,
350 NULL // get_loopback_address
351 };
352