1 /* 2 * Copyright 2006-2010, 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 #define L2CAP_CHECKSUM(address) \ 26 (address.b[0] + address.b[1] + address.b[2] + address.b[3] \ 27 + address.b[4] + address.b[5]) 28 29 30 /*! Routing utility function: copies address \a from into a new address 31 that is put into \a to. 32 If \a replaceWithZeros is set \a from will be replaced by an empty 33 address. 34 If a \a mask is given it is applied to \a from (such that \a to is the 35 result of \a from & \a mask). 36 \return B_OK if the address could be copied 37 \return B_NO_MEMORY if the new address could not be allocated 38 \return B_MISMATCHED_VALUES if \a address does not match family AF_BLUETOOTH 39 */ 40 static status_t 41 l2cap_copy_address(const sockaddr *from, sockaddr **to, 42 bool replaceWithZeros = false, const sockaddr *mask = NULL) 43 { 44 if (replaceWithZeros) { 45 *to = (sockaddr *)malloc(sizeof(sockaddr_in)); 46 if (*to == NULL) 47 return B_NO_MEMORY; 48 49 memset(*to, 0, sizeof(sockaddr_l2cap)); 50 (*to)->sa_family = AF_BLUETOOTH; 51 (*to)->sa_len = sizeof(sockaddr_l2cap); 52 } else { 53 if (from == NULL) 54 return B_OK; 55 if (from->sa_family != AF_BLUETOOTH) 56 return B_MISMATCHED_VALUES; 57 58 *to = (sockaddr *)malloc(sizeof(sockaddr_in)); 59 if (*to == NULL) 60 return B_NO_MEMORY; 61 62 memcpy(*to, from, sizeof(sockaddr_l2cap)); 63 64 } 65 return B_OK; 66 } 67 68 69 /*! Routing utility function: applies \a mask to given \a address and puts 70 the resulting address into \a result. 71 \return B_OK if the mask has been applied 72 \return B_BAD_VALUE if \a address or \a mask is NULL 73 */ 74 static status_t 75 l2cap_mask_address(const sockaddr *address, const sockaddr *mask, 76 sockaddr *result) 77 { 78 if (address == NULL || result == NULL) 79 return B_BAD_VALUE; 80 81 return B_OK; 82 } 83 84 85 /*! Checks if the given \a address is the empty address. By default, the port 86 is checked, too, but you can avoid that by passing \a checkPort = false. 87 \return true if \a address is NULL, uninitialized or the empty address, 88 false if not 89 */ 90 static bool 91 l2cap_is_empty_address(const sockaddr *address, bool checkPort) 92 { 93 if (address == NULL || address->sa_len == 0 94 || address->sa_family == AF_UNSPEC) 95 return true; 96 97 return ((bdaddrUtils::Compare( 98 ((const sockaddr_l2cap *)address)->l2cap_bdaddr, BDADDR_NULL)==0) 99 && (!checkPort || ((sockaddr_l2cap *)address)->l2cap_psm == 0)); 100 } 101 102 103 /*! Checks if the given \a address is L2CAP address. 104 \return false if \a address is NULL, or with family different from 105 AF_BLUETOOTH true if it has AF_BLUETOOTH address family 106 */ 107 static bool 108 l2cap_is_same_family(const sockaddr *address) 109 { 110 if (address == NULL) 111 return false; 112 113 return address->sa_family == AF_BLUETOOTH; 114 } 115 116 117 /*! Compares the IP-addresses of the two given address structures \a a and \a b. 118 \return true if IP-addresses of \a a and \a b are equal, false if not 119 */ 120 static bool 121 l2cap_equal_addresses(const sockaddr *a, const sockaddr *b) 122 { 123 if (a == NULL && b == NULL) 124 return true; 125 if (a != NULL && b == NULL) 126 return l2cap_is_empty_address(a, false); 127 if (a == NULL && b != NULL) 128 return l2cap_is_empty_address(b, false); 129 130 return bdaddrUtils::Compare(((const sockaddr_l2cap*)a)->l2cap_bdaddr, 131 ((sockaddr_l2cap*)b)->l2cap_bdaddr); 132 } 133 134 135 /*! Compares the ports of the two given address structures \a a and \a b. 136 \return true if ports of \a a and \a b are equal, false if not 137 */ 138 static bool 139 l2cap_equal_ports(const sockaddr *a, const sockaddr *b) 140 { 141 uint16 portA = a ? ((sockaddr_l2cap *)a)->l2cap_psm : 0; 142 uint16 portB = b ? ((sockaddr_l2cap *)b)->l2cap_psm : 0; 143 return portA == portB; 144 } 145 146 147 /*! Compares the IP-addresses and ports of the two given address structures 148 \a a and \a b. 149 \return true if IP-addresses and ports of \a a and \a b are equal, false if 150 not. 151 */ 152 static bool 153 l2cap_equal_addresses_and_ports(const sockaddr *a, const sockaddr *b) 154 { 155 if (a == NULL && b == NULL) 156 return true; 157 if (a != NULL && b == NULL) 158 return l2cap_is_empty_address(a, true); 159 if (a == NULL && b != NULL) 160 return l2cap_is_empty_address(b, true); 161 162 return (bdaddrUtils::Compare(((const sockaddr_l2cap *)a)->l2cap_bdaddr, 163 ((const sockaddr_l2cap *)b)->l2cap_bdaddr)) 164 && ((sockaddr_l2cap *)a)->l2cap_psm == ((sockaddr_l2cap *)b)->l2cap_psm; 165 } 166 167 168 /*! Applies the given \a mask two \a a and \a b and then checks whether 169 the masked addresses match. 170 \return true if \a a matches \a b after masking both, false if not 171 */ 172 static bool 173 l2cap_equal_masked_addresses(const sockaddr *a, const sockaddr *b, 174 const sockaddr *mask) 175 { 176 if (a == NULL && b == NULL) 177 return true; 178 179 return false; 180 } 181 182 183 /*! Routing utility function: determines the least significant bit that is set 184 in the given \a mask. 185 \return the number of the first bit that is set (0-32, where 32 means 186 that there's no bit set in the mask). 187 */ 188 static int32 189 l2cap_first_mask_bit(const sockaddr *_mask) 190 { 191 if (_mask == NULL) 192 return 0; 193 194 return 0; 195 } 196 197 198 /*! Routing utility function: checks the given \a mask for correctness (which 199 means that (starting with LSB) consists zero or more unset bits, followed 200 by bits that are all set). 201 \return true if \a mask is ok, false if not 202 */ 203 static bool 204 l2cap_check_mask(const sockaddr *_mask) 205 { 206 207 return true; 208 } 209 210 211 /*! Creates a buffer for the given \a address and prints the address into 212 it (hexadecimal representation in host byte order or '<none>'). 213 If \a printPort is set, the port is printed, too. 214 \return B_OK if the address could be printed, \a buffer will point to 215 the resulting string 216 \return B_BAD_VALUE if no buffer has been given 217 \return B_NO_MEMORY if the buffer could not be allocated 218 */ 219 static status_t 220 l2cap_print_address_buffer(const sockaddr *_address, char *buffer, 221 size_t bufferSize, bool printPort) 222 { 223 const sockaddr_l2cap *address = (const sockaddr_l2cap *)_address; 224 225 if (buffer == NULL) 226 return B_BAD_VALUE; 227 228 if (address == NULL) 229 strlcpy(buffer, "<none>", bufferSize); 230 else { 231 bdaddr_t addr = address->l2cap_bdaddr; 232 if (printPort) { 233 snprintf(buffer, bufferSize, 234 "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X|%u", addr.b[0], 235 addr.b[1],addr.b[2],addr.b[3],addr.b[4],addr.b[5], 236 address->l2cap_psm); 237 } 238 else { 239 snprintf(buffer, bufferSize, 240 "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",addr.b[0], 241 addr.b[1],addr.b[2],addr.b[3],addr.b[4],addr.b[5]); 242 } 243 } 244 245 return B_OK; 246 } 247 248 249 static status_t 250 l2cap_print_address(const sockaddr *_address, char **_buffer, bool printPort) 251 { 252 if (_buffer == NULL) 253 return B_BAD_VALUE; 254 255 char tmp[32]; 256 l2cap_print_address_buffer(_address, tmp, sizeof(tmp), printPort); 257 258 *_buffer = strdup(tmp); 259 if (*_buffer == NULL) 260 return B_NO_MEMORY; 261 262 return B_OK; 263 } 264 265 266 /*! Determines the port of the given \a address. 267 \return uint16 representing the port-nr 268 */ 269 static uint16 270 l2cap_get_port(const sockaddr *address) 271 { 272 if (address == NULL) 273 return 0; 274 275 return ((sockaddr_l2cap *)address)->l2cap_psm; 276 } 277 278 279 /*! Sets the port of the given \a address to \a port. 280 \return B_OK if the port has been set 281 \return B_BAD_VALUE if \a address is NULL 282 */ 283 static status_t 284 l2cap_set_port(sockaddr *address, uint16 port) 285 { 286 if (address == NULL) 287 return B_BAD_VALUE; 288 289 ((sockaddr_l2cap *)address)->l2cap_psm = port; 290 return B_OK; 291 } 292 293 294 /*! Sets \a address to \a from. 295 \return B_OK if \a from has been copied into \a address 296 \return B_BAD_VALUE if either \a address or \a from is NULL 297 \return B_MISMATCHED_VALUES if from is not of family AF_BLUETOOTH 298 */ 299 static status_t 300 l2cap_set_to(sockaddr *address, const sockaddr *from) 301 { 302 if (address == NULL || from == NULL) 303 return B_BAD_VALUE; 304 305 if (from->sa_family != AF_BLUETOOTH) 306 return B_MISMATCHED_VALUES; 307 308 memcpy(address, from, sizeof(sockaddr_l2cap)); 309 address->sa_len = sizeof(sockaddr_l2cap); 310 return B_OK; 311 } 312 313 314 static status_t 315 l2cap_update_to(sockaddr *_address, const sockaddr *_from) 316 { 317 sockaddr_l2cap *address = (sockaddr_l2cap *)_address; 318 const sockaddr_l2cap *from = (const sockaddr_l2cap *)_from; 319 320 if (address == NULL || from == NULL) 321 return B_BAD_VALUE; 322 323 if (from->l2cap_family != AF_BLUETOOTH) 324 return B_BAD_VALUE; 325 326 address->l2cap_family = AF_BLUETOOTH; 327 address->l2cap_len = sizeof(sockaddr_l2cap); 328 329 if (address->l2cap_psm == 0) 330 address->l2cap_psm = from->l2cap_psm; 331 332 if (bdaddrUtils::Compare(address->l2cap_bdaddr, BDADDR_BROADCAST)) 333 address->l2cap_bdaddr = from->l2cap_bdaddr; 334 335 return B_OK; 336 } 337 338 339 /*! Sets \a address to the empty address. 340 \return B_OK if \a address has been set 341 \return B_BAD_VALUE if \a address is NULL 342 */ 343 static status_t 344 l2cap_set_to_empty_address(sockaddr *address) 345 { 346 if (address == NULL) 347 return B_BAD_VALUE; 348 349 memset(address, 0, sizeof(sockaddr_l2cap)); 350 address->sa_len = sizeof(sockaddr_l2cap); 351 address->sa_family = AF_BLUETOOTH; 352 return B_OK; 353 } 354 355 356 static status_t 357 l2cap_set_to_defaults(sockaddr *_defaultMask, sockaddr *_defaultBroadcast, 358 const sockaddr *_address, const sockaddr *_mask) 359 { 360 // TODO: not implemented 361 return B_ERROR; 362 } 363 364 365 /*! Computes a hash value of the given \a address. 366 \return uint32 representing the hash value 367 */ 368 static uint32 369 l2cap_hash_address(const struct sockaddr* _address, bool includePort) 370 { 371 const sockaddr_l2cap* address = (const sockaddr_l2cap*)_address; 372 if (address == NULL || address->l2cap_len == 0) 373 return 0; 374 375 return address->l2cap_psm ^ L2CAP_CHECKSUM(address->l2cap_bdaddr); 376 } 377 378 379 /*! Computes a hash-value of the given addresses \a ourAddress 380 and \a peerAddress. 381 \return uint32 representing the hash-value 382 */ 383 static uint32 384 l2cap_hash_address_pair(const sockaddr *ourAddress, const sockaddr *peerAddress) 385 { 386 const sockaddr_l2cap *our = (const sockaddr_l2cap *)ourAddress; 387 const sockaddr_l2cap *peer = (const sockaddr_l2cap *)peerAddress; 388 389 return ((our ? our->l2cap_psm : 0) | ((peer ? peer->l2cap_psm : 0) << 16)) 390 ^ (our ? L2CAP_CHECKSUM(our->l2cap_bdaddr) : 0) 391 ^ (peer ? L2CAP_CHECKSUM(peer->l2cap_bdaddr) : 0); 392 } 393 394 395 /*! Adds the given \a address to the IP-checksum \a checksum. 396 \return B_OK if \a address has been added to the checksum 397 \return B_BAD_VALUE if either \a address or \a checksum is NULL 398 */ 399 static status_t 400 l2cap_checksum_address(struct Checksum *checksum, const sockaddr *address) 401 { 402 if (checksum == NULL || address == NULL) 403 return B_BAD_VALUE; 404 405 for (uint i = 0; i < sizeof(bdaddr_t); i++) 406 (*checksum) << ((sockaddr_l2cap*)address)->l2cap_bdaddr.b[i]; 407 408 return B_OK; 409 } 410 411 412 net_address_module_info gL2cap4AddressModule = { 413 { 414 NULL, 415 0, 416 NULL 417 }, 418 NET_ADDRESS_MODULE_FLAG_BROADCAST_ADDRESS, 419 l2cap_copy_address, 420 l2cap_mask_address, 421 l2cap_equal_addresses, 422 l2cap_equal_ports, 423 l2cap_equal_addresses_and_ports, 424 l2cap_equal_masked_addresses, 425 l2cap_is_empty_address, 426 l2cap_is_same_family, 427 l2cap_first_mask_bit, 428 l2cap_check_mask, 429 l2cap_print_address, 430 l2cap_print_address_buffer, 431 l2cap_get_port, 432 l2cap_set_port, 433 l2cap_set_to, 434 l2cap_set_to_empty_address, 435 l2cap_set_to_defaults, 436 l2cap_update_to, 437 l2cap_hash_address, 438 l2cap_hash_address_pair, 439 l2cap_checksum_address, 440 NULL // get_loopback_address 441 }; 442