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