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