1 /* 2 * lib/socket.c Netlink Socket 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation version 2.1 7 * of the License. 8 * 9 * Copyright (c) 2003-2012 Thomas Graf <tgraf (at) suug.ch> 10 */ 11 12 /** 13 * @ingroup core_types 14 * @defgroup socket Socket 15 * 16 * Representation of a netlink socket 17 * 18 * Related sections in the development guide: 19 * - @core_doc{core_sockets, Netlink Sockets} 20 * 21 * @{ 22 * 23 * Header 24 * ------ 25 * ~~~~{.c} 26 * #include <netlink/socket.h> 27 * ~~~~ 28 */ 29 30 #include "defs.h" 31 32 #include <netlink-private/netlink.h> 33 #include <netlink-private/socket.h> 34 #include <netlink/netlink.h> 35 #include <netlink/utils.h> 36 #include <netlink/handlers.h> 37 #include <netlink/msg.h> 38 #include <netlink/attr.h> 39 40 static int default_cb = NL_CB_DEFAULT; 41 42 static void __init init_default_cb(void) 43 { 44 char *nlcb; 45 46 if ((nlcb = getenv("NLCB"))) { 47 if (!strcasecmp(nlcb, "default")) 48 default_cb = NL_CB_DEFAULT; 49 else if (!strcasecmp(nlcb, "verbose")) 50 default_cb = NL_CB_VERBOSE; 51 else if (!strcasecmp(nlcb, "debug")) 52 default_cb = NL_CB_DEBUG; 53 else { 54 fprintf(stderr, "Unknown value for NLCB, valid values: " 55 "{default | verbose | debug}\n"); 56 } 57 } 58 } 59 60 static uint32_t used_ports_map[32]; 61 static NL_RW_LOCK(port_map_lock); 62 63 static uint32_t generate_local_port(void) 64 { 65 int i, j, n, m; 66 static uint16_t idx_state = 0; 67 uint32_t pid = getpid() & 0x3FFFFF; 68 69 nl_write_lock(&port_map_lock); 70 71 if (idx_state == 0) { 72 uint32_t t = time(NULL); 73 74 /* from time to time (on average each 2^15 calls), the idx_state will 75 * be zero again. No problem, just "seed" anew with time(). */ 76 idx_state = t ^ (t >> 16) ^ 0x3047; 77 } else 78 idx_state = idx_state + 20011; /* add prime number */ 79 80 i = idx_state >> 5; 81 n = idx_state; 82 for (j = 0; j < 32; j++) { 83 /* walk the index somewhat randomized, with always leaving the block 84 * #0 as last. The reason is that libnl-1 will start at block #0, 85 * so just leave the first 32 ports preferably for libnl-1 owned sockets 86 * (this is relevant only if the applications ends up using both versions 87 * of the library and doesn't hurt otherwise). */ 88 if (j == 31) 89 i = 0; 90 else 91 i = (((i-1) + 7) % 31) + 1; 92 93 if (used_ports_map[i] == 0xFFFFFFFF) 94 continue; 95 96 for (m = 0; m < 32; m++) { 97 n = (n + 13) % 32; 98 if (1UL & (used_ports_map[i] >> n)) 99 continue; 100 101 used_ports_map[i] |= (1UL << n); 102 n += (i * 32); 103 104 /* PID_MAX_LIMIT is currently at 2^22, leaving 10 bit 105 * to, i.e. 1024 unique ports per application. */ 106 107 nl_write_unlock(&port_map_lock); 108 109 return pid + (((uint32_t)n) << 22); 110 } 111 } 112 113 nl_write_unlock(&port_map_lock); 114 115 /* Out of sockets in our own PID namespace, what to do? FIXME */ 116 NL_DBG(1, "Warning: Ran out of unique local port namespace\n"); 117 return UINT32_MAX; 118 } 119 120 static void release_local_port(uint32_t port) 121 { 122 int nr; 123 uint32_t mask; 124 125 if (port == UINT32_MAX) 126 return; 127 128 BUG_ON(port == 0); 129 130 nr = port >> 22; 131 mask = 1UL << (nr % 32); 132 nr /= 32; 133 134 nl_write_lock(&port_map_lock); 135 BUG_ON((used_ports_map[nr] & mask) != mask); 136 used_ports_map[nr] &= ~mask; 137 nl_write_unlock(&port_map_lock); 138 } 139 140 /** \cond skip */ 141 void _nl_socket_used_ports_release_all(const uint32_t *used_ports) 142 { 143 int i; 144 145 for (i = 0; i < 32; i++) { 146 if (used_ports[i] != 0) { 147 nl_write_lock(&port_map_lock); 148 for (; i < 32; i++) { 149 BUG_ON((used_ports_map[i] & used_ports[i]) != used_ports[i]); 150 used_ports_map[i] &= ~(used_ports[i]); 151 } 152 nl_write_unlock(&port_map_lock); 153 return; 154 } 155 } 156 } 157 158 void _nl_socket_used_ports_set(uint32_t *used_ports, uint32_t port) 159 { 160 int nr; 161 int32_t mask; 162 163 nr = port >> 22; 164 mask = 1UL << (nr % 32); 165 nr /= 32; 166 167 /* 168 BUG_ON(port == UINT32_MAX || port == 0 || (getpid() & 0x3FFFFF) != (port & 0x3FFFFF)); 169 BUG_ON(used_ports[nr] & mask); 170 */ 171 172 used_ports[nr] |= mask; 173 } 174 /** \endcond */ 175 176 /** 177 * @name Allocation 178 * @{ 179 */ 180 181 static struct nl_sock *__alloc_socket(struct nl_cb *cb) 182 { 183 struct nl_sock *sk; 184 185 sk = calloc(1, sizeof(*sk)); 186 if (!sk) 187 return NULL; 188 189 sk->s_fd = -1; 190 sk->s_cb = nl_cb_get(cb); 191 sk->s_local.nl_family = AF_NETLINK; 192 sk->s_peer.nl_family = AF_NETLINK; 193 sk->s_seq_expect = sk->s_seq_next = time(0); 194 195 /* the port is 0 (unspecified), meaning NL_OWN_PORT */ 196 sk->s_flags = NL_OWN_PORT; 197 198 return sk; 199 } 200 201 /** 202 * Allocate new netlink socket 203 * 204 * @return Newly allocated netlink socket or NULL. 205 */ 206 struct nl_sock *nl_socket_alloc(void) 207 { 208 struct nl_cb *cb; 209 struct nl_sock *sk; 210 211 cb = nl_cb_alloc(default_cb); 212 if (!cb) 213 return NULL; 214 215 /* will increment cb reference count on success */ 216 sk = __alloc_socket(cb); 217 218 nl_cb_put(cb); 219 220 return sk; 221 } 222 223 /** 224 * Allocate new socket with custom callbacks 225 * @arg cb Callback handler 226 * 227 * The reference to the callback handler is taken into account 228 * automatically, it is released again upon calling nl_socket_free(). 229 * 230 *@return Newly allocted socket handle or NULL. 231 */ 232 struct nl_sock *nl_socket_alloc_cb(struct nl_cb *cb) 233 { 234 if (cb == NULL) 235 BUG(); 236 237 return __alloc_socket(cb); 238 } 239 240 /** 241 * Free a netlink socket. 242 * @arg sk Netlink socket. 243 */ 244 void nl_socket_free(struct nl_sock *sk) 245 { 246 if (!sk) 247 return; 248 249 if (sk->s_fd >= 0) 250 close(sk->s_fd); 251 252 if (!(sk->s_flags & NL_OWN_PORT)) 253 release_local_port(sk->s_local.nl_pid); 254 255 nl_cb_put(sk->s_cb); 256 free(sk); 257 } 258 259 /** @} */ 260 261 /** 262 * @name Sequence Numbers 263 * @{ 264 */ 265 266 static int noop_seq_check(struct nl_msg *msg, void *arg) 267 { 268 return NL_OK; 269 } 270 271 272 /** 273 * Disable sequence number checking. 274 * @arg sk Netlink socket. 275 * 276 * Disables checking of sequence numbers on the netlink socket This is 277 * required to allow messages to be processed which were not requested by 278 * a preceding request message, e.g. netlink events. 279 * 280 * @note This function modifies the NL_CB_SEQ_CHECK configuration in 281 * the callback handle associated with the socket. 282 */ 283 void nl_socket_disable_seq_check(struct nl_sock *sk) 284 { 285 nl_cb_set(sk->s_cb, NL_CB_SEQ_CHECK, 286 NL_CB_CUSTOM, noop_seq_check, NULL); 287 } 288 289 /** 290 * Use next sequence number 291 * @arg sk Netlink socket. 292 * 293 * Uses the next available sequence number and increases the counter 294 * by one for subsequent calls. 295 * 296 * @return Unique serial sequence number 297 */ 298 unsigned int nl_socket_use_seq(struct nl_sock *sk) 299 { 300 return sk->s_seq_next++; 301 } 302 303 /** 304 * Disable automatic request for ACK 305 * @arg sk Netlink socket. 306 * 307 * The default behaviour of a socket is to request an ACK for 308 * each message sent to allow for the caller to synchronize to 309 * the completion of the netlink operation. This function 310 * disables this behaviour and will result in requests being 311 * sent which will not have the NLM_F_ACK flag set automatically. 312 * However, it is still possible for the caller to set the 313 * NLM_F_ACK flag explicitely. 314 */ 315 void nl_socket_disable_auto_ack(struct nl_sock *sk) 316 { 317 sk->s_flags |= NL_NO_AUTO_ACK; 318 } 319 320 /** 321 * Enable automatic request for ACK (default) 322 * @arg sk Netlink socket. 323 * @see nl_socket_disable_auto_ack 324 */ 325 void nl_socket_enable_auto_ack(struct nl_sock *sk) 326 { 327 sk->s_flags &= ~NL_NO_AUTO_ACK; 328 } 329 330 /** @} */ 331 332 /** \cond skip */ 333 int _nl_socket_is_local_port_unspecified(struct nl_sock *sk) 334 { 335 return (sk->s_local.nl_pid == 0); 336 } 337 338 uint32_t _nl_socket_generate_local_port_no_release(struct nl_sock *sk) 339 { 340 uint32_t port; 341 342 /* reset the port to generate_local_port(), but do not release 343 * the previously generated port. */ 344 345 port = generate_local_port(); 346 sk->s_flags &= ~NL_OWN_PORT; 347 sk->s_local.nl_pid = port; 348 return port; 349 } 350 /** \endcond */ 351 352 /** 353 * @name Source Idenficiation 354 * @{ 355 */ 356 357 uint32_t nl_socket_get_local_port(const struct nl_sock *sk) 358 { 359 if (sk->s_local.nl_pid == 0) { 360 /* modify the const argument sk. This is justified, because 361 * nobody ever saw the local_port from externally. So, we 362 * initilize it on first use. 363 * 364 * Note that this also means that you cannot call this function 365 * from multiple threads without synchronization. But nl_sock 366 * is not automatically threadsafe anyway, so the user is not 367 * allowed to do that. 368 */ 369 return _nl_socket_generate_local_port_no_release((struct nl_sock *) sk); 370 } 371 return sk->s_local.nl_pid; 372 } 373 374 /** 375 * Set local port of socket 376 * @arg sk Netlink socket. 377 * @arg port Local port identifier 378 * 379 * Assigns a local port identifier to the socket. 380 * 381 * If port is 0, the port is reset to 'unspecified' as it is after newly 382 * calling nl_socket_alloc(). 383 * Unspecified means, that the port will be generated automatically later 384 * on first use (either on nl_socket_get_local_port() or nl_connect()). 385 */ 386 void nl_socket_set_local_port(struct nl_sock *sk, uint32_t port) 387 { 388 if (!(sk->s_flags & NL_OWN_PORT)) 389 release_local_port(sk->s_local.nl_pid); 390 sk->s_flags |= NL_OWN_PORT; 391 sk->s_local.nl_pid = port; 392 } 393 394 /** @} */ 395 396 /** 397 * @name Group Subscriptions 398 * @{ 399 */ 400 401 /** 402 * Join groups 403 * @arg sk Netlink socket 404 * @arg group Group identifier 405 * 406 * Joins the specified groups using the modern socket option which 407 * is available since kernel version 2.6.14. It allows joining an 408 * almost arbitary number of groups without limitation. The list 409 * of groups has to be terminated by 0 (%NFNLGRP_NONE). 410 * 411 * Make sure to use the correct group definitions as the older 412 * bitmask definitions for nl_join_groups() are likely to still 413 * be present for backward compatibility reasons. 414 * 415 * @return 0 on sucess or a negative error code. 416 */ 417 int nl_socket_add_memberships(struct nl_sock *sk, int group, ...) 418 { 419 int err; 420 va_list ap; 421 422 if (sk->s_fd == -1) 423 return -NLE_BAD_SOCK; 424 425 va_start(ap, group); 426 427 while (group != 0) { 428 if (group < 0) { 429 va_end(ap); 430 return -NLE_INVAL; 431 } 432 433 err = setsockopt(sk->s_fd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, 434 &group, sizeof(group)); 435 if (err < 0) { 436 va_end(ap); 437 return -nl_syserr2nlerr(errno); 438 } 439 440 group = va_arg(ap, int); 441 } 442 443 va_end(ap); 444 445 return 0; 446 } 447 448 int nl_socket_add_membership(struct nl_sock *sk, int group) 449 { 450 return nl_socket_add_memberships(sk, group, 0); 451 } 452 453 /** 454 * Leave groups 455 * @arg sk Netlink socket 456 * @arg group Group identifier 457 * 458 * Leaves the specified groups using the modern socket option 459 * which is available since kernel version 2.6.14. The list of groups 460 * has to terminated by 0 (%NFNLGRP_NONE). 461 * 462 * @see nl_socket_add_membership 463 * @return 0 on success or a negative error code. 464 */ 465 int nl_socket_drop_memberships(struct nl_sock *sk, int group, ...) 466 { 467 int err; 468 va_list ap; 469 470 if (sk->s_fd == -1) 471 return -NLE_BAD_SOCK; 472 473 va_start(ap, group); 474 475 while (group != 0) { 476 if (group < 0) { 477 va_end(ap); 478 return -NLE_INVAL; 479 } 480 481 err = setsockopt(sk->s_fd, SOL_NETLINK, NETLINK_DROP_MEMBERSHIP, 482 &group, sizeof(group)); 483 if (err < 0) { 484 va_end(ap); 485 return -nl_syserr2nlerr(errno); 486 } 487 488 group = va_arg(ap, int); 489 } 490 491 va_end(ap); 492 493 return 0; 494 } 495 496 int nl_socket_drop_membership(struct nl_sock *sk, int group) 497 { 498 return nl_socket_drop_memberships(sk, group, 0); 499 } 500 501 502 /** 503 * Join multicast groups (deprecated) 504 * @arg sk Netlink socket. 505 * @arg groups Bitmask of groups to join. 506 * 507 * This function defines the old way of joining multicast group which 508 * has to be done prior to calling nl_connect(). It works on any kernel 509 * version but is very limited as only 32 groups can be joined. 510 */ 511 void nl_join_groups(struct nl_sock *sk, int groups) 512 { 513 sk->s_local.nl_groups |= groups; 514 } 515 516 517 /** @} */ 518 519 /** 520 * @name Peer Identfication 521 * @{ 522 */ 523 524 uint32_t nl_socket_get_peer_port(const struct nl_sock *sk) 525 { 526 return sk->s_peer.nl_pid; 527 } 528 529 void nl_socket_set_peer_port(struct nl_sock *sk, uint32_t port) 530 { 531 sk->s_peer.nl_pid = port; 532 } 533 534 uint32_t nl_socket_get_peer_groups(const struct nl_sock *sk) 535 { 536 return sk->s_peer.nl_groups; 537 } 538 539 void nl_socket_set_peer_groups(struct nl_sock *sk, uint32_t groups) 540 { 541 sk->s_peer.nl_groups = groups; 542 } 543 544 545 546 /** @} */ 547 548 /** 549 * @name File Descriptor 550 * @{ 551 */ 552 553 /** 554 * Return the file descriptor of the backing socket 555 * @arg sk Netlink socket 556 * 557 * Only valid after calling nl_connect() to create and bind the respective 558 * socket. 559 * 560 * @return File descriptor or -1 if not available. 561 */ 562 int nl_socket_get_fd(const struct nl_sock *sk) 563 { 564 return sk->s_fd; 565 } 566 567 /** 568 * Set file descriptor of socket to non-blocking state 569 * @arg sk Netlink socket. 570 * 571 * @return 0 on success or a negative error code. 572 */ 573 int nl_socket_set_nonblocking(const struct nl_sock *sk) 574 { 575 if (sk->s_fd == -1) 576 return -NLE_BAD_SOCK; 577 578 if (fcntl(sk->s_fd, F_SETFL, O_NONBLOCK) < 0) 579 return -nl_syserr2nlerr(errno); 580 581 return 0; 582 } 583 584 /** 585 * Enable use of MSG_PEEK when reading from socket 586 * @arg sk Netlink socket. 587 */ 588 void nl_socket_enable_msg_peek(struct nl_sock *sk) 589 { 590 sk->s_flags |= NL_MSG_PEEK; 591 } 592 593 /** 594 * Disable use of MSG_PEEK when reading from socket 595 * @arg sk Netlink socket. 596 */ 597 void nl_socket_disable_msg_peek(struct nl_sock *sk) 598 { 599 sk->s_flags &= ~NL_MSG_PEEK; 600 } 601 602 /** @} */ 603 604 /** 605 * @name Callback Handler 606 * @{ 607 */ 608 609 struct nl_cb *nl_socket_get_cb(const struct nl_sock *sk) 610 { 611 return nl_cb_get(sk->s_cb); 612 } 613 614 void nl_socket_set_cb(struct nl_sock *sk, struct nl_cb *cb) 615 { 616 if (cb == NULL) 617 BUG(); 618 619 nl_cb_put(sk->s_cb); 620 sk->s_cb = nl_cb_get(cb); 621 } 622 623 /** 624 * Modify the callback handler associated with the socket 625 * @arg sk Netlink socket. 626 * @arg type which type callback to set 627 * @arg kind kind of callback 628 * @arg func callback function 629 * @arg arg argument to be passed to callback function 630 * 631 * @see nl_cb_set 632 */ 633 int nl_socket_modify_cb(struct nl_sock *sk, enum nl_cb_type type, 634 enum nl_cb_kind kind, nl_recvmsg_msg_cb_t func, 635 void *arg) 636 { 637 return nl_cb_set(sk->s_cb, type, kind, func, arg); 638 } 639 640 /** 641 * Modify the error callback handler associated with the socket 642 * @arg sk Netlink socket. 643 * @arg kind kind of callback 644 * @arg func callback function 645 * @arg arg argument to be passed to callback function 646 * 647 * @see nl_cb_err 648 */ 649 int nl_socket_modify_err_cb(struct nl_sock *sk, enum nl_cb_kind kind, 650 nl_recvmsg_err_cb_t func, void *arg) 651 { 652 return nl_cb_err(sk->s_cb, kind, func, arg); 653 } 654 655 /** @} */ 656 657 /** 658 * @name Utilities 659 * @{ 660 */ 661 662 /** 663 * Set socket buffer size of netlink socket. 664 * @arg sk Netlink socket. 665 * @arg rxbuf New receive socket buffer size in bytes. 666 * @arg txbuf New transmit socket buffer size in bytes. 667 * 668 * Sets the socket buffer size of a netlink socket to the specified 669 * values \c rxbuf and \c txbuf. Providing a value of \c 0 assumes a 670 * good default value. 671 * 672 * @note It is not required to call this function prior to nl_connect(). 673 * @return 0 on sucess or a negative error code. 674 */ 675 int nl_socket_set_buffer_size(struct nl_sock *sk, int rxbuf, int txbuf) 676 { 677 int err; 678 679 if (rxbuf <= 0) 680 rxbuf = 32768; 681 682 if (txbuf <= 0) 683 txbuf = 32768; 684 685 if (sk->s_fd == -1) 686 return -NLE_BAD_SOCK; 687 688 err = setsockopt(sk->s_fd, SOL_SOCKET, SO_SNDBUF, 689 &txbuf, sizeof(txbuf)); 690 if (err < 0) 691 return -nl_syserr2nlerr(errno); 692 693 err = setsockopt(sk->s_fd, SOL_SOCKET, SO_RCVBUF, 694 &rxbuf, sizeof(rxbuf)); 695 if (err < 0) 696 return -nl_syserr2nlerr(errno); 697 698 sk->s_flags |= NL_SOCK_BUFSIZE_SET; 699 700 return 0; 701 } 702 703 /** 704 * Set default message buffer size of netlink socket. 705 * @arg sk Netlink socket. 706 * @arg bufsize Default message buffer size in bytes. 707 * 708 * Sets the default message buffer size to the specified length in bytes. 709 * The default message buffer size limits the maximum message size the 710 * socket will be able to receive. It is generally recommneded to specify 711 * a buffer size no less than the size of a memory page. 712 * 713 * @return 0 on success or a negative error code. 714 */ 715 int nl_socket_set_msg_buf_size(struct nl_sock *sk, size_t bufsize) 716 { 717 sk->s_bufsize = bufsize; 718 719 return 0; 720 } 721 722 /** 723 * Get default message buffer size of netlink socket. 724 * @arg sk Netlink socket. 725 * 726 * @return Size of default message buffer. 727 */ 728 size_t nl_socket_get_msg_buf_size(struct nl_sock *sk) 729 { 730 return sk->s_bufsize; 731 } 732 733 /** 734 * Enable/disable credential passing on netlink socket. 735 * @arg sk Netlink socket. 736 * @arg state New state (0 - disabled, 1 - enabled) 737 * 738 * @return 0 on success or a negative error code 739 */ 740 int nl_socket_set_passcred(struct nl_sock *sk, int state) 741 { 742 int err; 743 744 if (sk->s_fd == -1) 745 return -NLE_BAD_SOCK; 746 747 err = setsockopt(sk->s_fd, SOL_SOCKET, SO_PASSCRED, 748 &state, sizeof(state)); 749 if (err < 0) 750 return -nl_syserr2nlerr(errno); 751 752 if (state) 753 sk->s_flags |= NL_SOCK_PASSCRED; 754 else 755 sk->s_flags &= ~NL_SOCK_PASSCRED; 756 757 return 0; 758 } 759 760 /** 761 * Enable/disable receival of additional packet information 762 * @arg sk Netlink socket. 763 * @arg state New state (0 - disabled, 1 - enabled) 764 * 765 * @return 0 on success or a negative error code 766 */ 767 int nl_socket_recv_pktinfo(struct nl_sock *sk, int state) 768 { 769 int err; 770 771 if (sk->s_fd == -1) 772 return -NLE_BAD_SOCK; 773 774 err = setsockopt(sk->s_fd, SOL_NETLINK, NETLINK_PKTINFO, 775 &state, sizeof(state)); 776 if (err < 0) 777 return -nl_syserr2nlerr(errno); 778 779 return 0; 780 } 781 782 /** @} */ 783 784 /** @} */ 785