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 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 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 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 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 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 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 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 127 l2cap_first_mask_bit(const sockaddr *_mask) 128 { 129 return 0; 130 } 131 132 133 static bool 134 l2cap_check_mask(const sockaddr *_mask) 135 { 136 return false; 137 } 138 139 140 static status_t 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 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 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 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 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 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 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 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 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 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 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 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