1 /* libnfnetlink.c: generic library for communication with netfilter 2 * 3 * (C) 2002-2006 by Harald Welte <laforge (at) gnumonks.org> 4 * (C) 2006-2011 by Pablo Neira Ayuso <pablo (at) netfilter.org> 5 * 6 * Based on some original ideas from Jay Schulist <jschlst (at) samba.org> 7 * 8 * Development of this code funded by Astaro AG (http://www.astaro.com) 9 * 10 * This program is free software; you can redistribute it and/or modify it 11 * under the terms of the GNU General Public License version 2 as published 12 * by the Free Software Foundation. 13 * 14 * 2005-09-14 Pablo Neira Ayuso <pablo (at) netfilter.org>: 15 * Define structure nfnlhdr 16 * Added __be64_to_cpu function 17 * Use NFA_TYPE macro to get the attribute type 18 * 19 * 2006-01-14 Harald Welte <laforge (at) netfilter.org>: 20 * introduce nfnl_subsys_handle 21 * 22 * 2006-01-15 Pablo Neira Ayuso <pablo (at) netfilter.org>: 23 * set missing subsys_id in nfnl_subsys_open 24 * set missing nfnlh->local.nl_pid in nfnl_open 25 * 26 * 2006-01-26 Harald Welte <laforge (at) netfilter.org>: 27 * remove bogus nfnlh->local.nl_pid from nfnl_open ;) 28 * add 16bit attribute functions 29 * 30 * 2006-07-03 Pablo Neira Ayuso <pablo (at) netfilter.org>: 31 * add iterator API 32 * add replacements for nfnl_listen and nfnl_talk 33 * fix error handling 34 * add assertions 35 * add documentation 36 * minor cleanups 37 */ 38 39 #include <stdlib.h> 40 #include <stdio.h> 41 #include <unistd.h> 42 #include <errno.h> 43 #include <string.h> 44 #include <time.h> 45 #include <netinet/in.h> 46 #include <assert.h> 47 #include <linux/types.h> 48 #include <sys/socket.h> 49 #include <sys/uio.h> 50 51 #include <linux/netlink.h> 52 53 #include <libnfnetlink/libnfnetlink.h> 54 55 #ifndef NETLINK_ADD_MEMBERSHIP 56 #define NETLINK_ADD_MEMBERSHIP 1 57 #endif 58 59 #ifndef SOL_NETLINK 60 #define SOL_NETLINK 270 61 #endif 62 63 64 #define nfnl_error(format, args...) \ 65 fprintf(stderr, "%s: " format "\n", __FUNCTION__, ## args) 66 67 #ifdef _NFNL_DEBUG 68 #define nfnl_debug_dump_packet nfnl_dump_packet 69 #else 70 #define nfnl_debug_dump_packet(a, b, ...) 71 #endif 72 73 struct nfnl_subsys_handle { 74 struct nfnl_handle *nfnlh; 75 u_int32_t subscriptions; 76 u_int8_t subsys_id; 77 u_int8_t cb_count; 78 struct nfnl_callback *cb; /* array of callbacks */ 79 }; 80 81 #define NFNL_MAX_SUBSYS 16 /* enough for now */ 82 83 #define NFNL_F_SEQTRACK_ENABLED (1 << 0) 84 85 struct nfnl_handle { 86 int fd; 87 struct sockaddr_nl local; 88 struct sockaddr_nl peer; 89 u_int32_t subscriptions; 90 u_int32_t seq; 91 u_int32_t dump; 92 u_int32_t rcv_buffer_size; /* for nfnl_catch */ 93 u_int32_t flags; 94 struct nlmsghdr *last_nlhdr; 95 struct nfnl_subsys_handle subsys[NFNL_MAX_SUBSYS+1]; 96 }; 97 98 void nfnl_dump_packet(struct nlmsghdr *nlh, int received_len, char *desc) 99 { 100 void *nlmsg_data = NLMSG_DATA(nlh); 101 struct nfattr *nfa = NFM_NFA(NLMSG_DATA(nlh)); 102 int len = NFM_PAYLOAD(nlh); 103 104 printf("%s called from %s\n", __FUNCTION__, desc); 105 printf(" nlmsghdr = %p, received_len = %u\n", nlh, received_len); 106 printf(" NLMSG_DATA(nlh) = %p (+%td bytes)\n", nlmsg_data, 107 (nlmsg_data - (void *)nlh)); 108 printf(" NFM_NFA(NLMSG_DATA(nlh)) = %p (+%td bytes)\n", 109 nfa, ((void *)nfa - (void *)nlh)); 110 printf(" NFM_PAYLOAD(nlh) = %u\n", len); 111 printf(" nlmsg_type = %u, nlmsg_len = %u, nlmsg_seq = %u " 112 "nlmsg_flags = 0x%x\n", nlh->nlmsg_type, nlh->nlmsg_len, 113 nlh->nlmsg_seq, nlh->nlmsg_flags); 114 115 while (NFA_OK(nfa, len)) { 116 printf(" nfa@%p: nfa_type=%u, nfa_len=%u\n", 117 nfa, NFA_TYPE(nfa), nfa->nfa_len); 118 nfa = NFA_NEXT(nfa,len); 119 } 120 } 121 122 /** 123 * nfnl_fd - returns the descriptor that identifies the socket 124 * @nfnlh: nfnetlink handler 125 * 126 * Use this function if you need to interact with the socket. Common 127 * scenarios are the use of poll()/select() to achieve multiplexation. 128 */ 129 int nfnl_fd(struct nfnl_handle *h) 130 { 131 assert(h); 132 return h->fd; 133 } 134 135 /** 136 * nfnl_portid - returns the Netlink port ID of this socket 137 * @h: nfnetlink handler 138 */ 139 unsigned int nfnl_portid(const struct nfnl_handle *h) 140 { 141 assert(h); 142 return h->local.nl_pid; 143 } 144 145 static int recalc_rebind_subscriptions(struct nfnl_handle *nfnlh) 146 { 147 int i, err; 148 u_int32_t new_subscriptions = nfnlh->subscriptions; 149 150 for (i = 0; i < NFNL_MAX_SUBSYS; i++) 151 new_subscriptions |= nfnlh->subsys[i].subscriptions; 152 153 nfnlh->local.nl_groups = new_subscriptions; 154 err = bind(nfnlh->fd, (struct sockaddr *)&nfnlh->local, 155 sizeof(nfnlh->local)); 156 if (err == -1) 157 return -1; 158 159 nfnlh->subscriptions = new_subscriptions; 160 161 return 0; 162 } 163 164 static void recalc_subscriptions(struct nfnl_handle *nfnlh) 165 { 166 int i; 167 u_int32_t new_subscriptions = nfnlh->subscriptions; 168 169 for (i = 0; i < NFNL_MAX_SUBSYS; i++) 170 new_subscriptions |= nfnlh->subsys[i].subscriptions; 171 172 nfnlh->local.nl_groups = new_subscriptions; 173 nfnlh->subscriptions = new_subscriptions; 174 } 175 176 /** 177 * nfnl_open - open a nfnetlink handler 178 * 179 * This function creates a nfnetlink handler, this is required to establish 180 * a communication between the userspace and the nfnetlink system. 181 * 182 * On success, a valid address that points to a nfnl_handle structure 183 * is returned. On error, NULL is returned and errno is set approapiately. 184 */ 185 struct nfnl_handle *nfnl_open(void) 186 { 187 struct nfnl_handle *nfnlh; 188 int fd; 189 190 fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_NETFILTER); 191 if (fd == -1) 192 return NULL; 193 nfnlh = nfnl_open2(fd, true); 194 if (nfnlh == NULL) 195 close(fd); 196 return nfnlh; 197 } 198 199 /** 200 * nfnl_open2 - open a nfnetlink handler 201 * @fd: passing file descriptor 202 * @bind: indicate the passing fd needs to be binded or not 203 * 204 * This function creates a nfnetlink handler, this is required to establish 205 * a communication between the userspace and the nfnetlink system. 206 * 207 * On success, a valid address that points to a nfnl_handle structure 208 * is returned. On error, NULL is returned and errno is set approapiately. 209 */ 210 struct nfnl_handle *nfnl_open2(int fd, bool bind) 211 { 212 struct nfnl_handle *nfnlh; 213 unsigned int addr_len; 214 215 if (fd < 0) 216 goto err; 217 218 nfnlh = malloc(sizeof(*nfnlh)); 219 if (!nfnlh) 220 return NULL; 221 222 memset(nfnlh, 0, sizeof(*nfnlh)); 223 nfnlh->fd = fd; 224 225 nfnlh->local.nl_family = AF_NETLINK; 226 nfnlh->peer.nl_family = AF_NETLINK; 227 228 addr_len = sizeof(nfnlh->local); 229 getsockname(nfnlh->fd, (struct sockaddr *)&nfnlh->local, &addr_len); 230 if (addr_len != sizeof(nfnlh->local)) { 231 errno = EINVAL; 232 goto err_free; 233 } 234 if (nfnlh->local.nl_family != AF_NETLINK) { 235 errno = EINVAL; 236 goto err_free; 237 } 238 nfnlh->seq = time(NULL); 239 nfnlh->rcv_buffer_size = NFNL_BUFFSIZE; 240 241 /* don't set pid here, only first socket of process has real pid !!! 242 * binding to pid '0' will default */ 243 244 /* let us do the initial bind */ 245 if (bind) { 246 if (recalc_rebind_subscriptions(nfnlh) < 0) 247 goto err_free; 248 } else { 249 recalc_subscriptions(nfnlh); 250 } 251 252 /* use getsockname to get the netlink pid that the kernel assigned us */ 253 addr_len = sizeof(nfnlh->local); 254 getsockname(nfnlh->fd, (struct sockaddr *)&nfnlh->local, &addr_len); 255 if (addr_len != sizeof(nfnlh->local)) { 256 errno = EINVAL; 257 goto err_free; 258 } 259 /* sequence tracking enabled by default */ 260 nfnlh->flags |= NFNL_F_SEQTRACK_ENABLED; 261 262 return nfnlh; 263 264 err_free: 265 free(nfnlh); 266 err: 267 return NULL; 268 } 269 270 /** 271 * nfnl_set_sequence_tracking - set netlink sequence tracking 272 * @h: nfnetlink handler 273 */ 274 void nfnl_set_sequence_tracking(struct nfnl_handle *h) 275 { 276 h->flags |= NFNL_F_SEQTRACK_ENABLED; 277 } 278 279 /** 280 * nfnl_unset_sequence_tracking - set netlink sequence tracking 281 * @h: nfnetlink handler 282 */ 283 void nfnl_unset_sequence_tracking(struct nfnl_handle *h) 284 { 285 h->flags &= ~NFNL_F_SEQTRACK_ENABLED; 286 } 287 288 /** 289 * nfnl_set_rcv_buffer_size - set the size of the receive buffer 290 * @h: libnfnetlink handler 291 * @size: buffer size 292 * 293 * This function sets the size of the receive buffer size, i.e. the size 294 * of the buffer used by nfnl_recv. Default value is 4096 bytes. 295 */ 296 void nfnl_set_rcv_buffer_size(struct nfnl_handle *h, unsigned int size) 297 { 298 h->rcv_buffer_size = size; 299 } 300 301 /** 302 * nfnl_subsys_open - open a netlink subsystem 303 * @nfnlh: libnfnetlink handle 304 * @subsys_id: which nfnetlink subsystem we are interested in 305 * @cb_count: number of callbacks that are used maximum. 306 * @subscriptions: netlink groups we want to be subscribed to 307 * 308 * This function creates a subsystem handler that contains the set of 309 * callbacks that handle certain types of messages coming from a netfilter 310 * subsystem. Initially the callback set is empty, you can register callbacks 311 * via nfnl_callback_register(). 312 * 313 * On error, NULL is returned and errno is set appropiately. On success, 314 * a valid address that points to a nfnl_subsys_handle structure is returned. 315 */ 316 struct nfnl_subsys_handle * 317 nfnl_subsys_open(struct nfnl_handle *nfnlh, u_int8_t subsys_id, 318 u_int8_t cb_count, u_int32_t subscriptions) 319 { 320 return nfnl_subsys_open2 (nfnlh, subsys_id, cb_count, subscriptions, true); 321 } 322 323 /** 324 * nfnl_subsys_open2 - open a netlink subsystem 325 * @nfnlh: libnfnetlink handle 326 * @subsys_id: which nfnetlink subsystem we are interested in 327 * @cb_count: number of callbacks that are used maximum. 328 * @subscriptions: netlink groups we want to be subscribed to 329 * @bind: indicate the passing fd needs to be binded or not 330 * 331 * This function creates a subsystem handler that contains the set of 332 * callbacks that handle certain types of messages coming from a netfilter 333 * subsystem. Initially the callback set is empty, you can register callbacks 334 * via nfnl_callback_register(). 335 * 336 * On error, NULL is returned and errno is set appropiately. On success, 337 * a valid address that points to a nfnl_subsys_handle structure is returned. 338 */ 339 struct nfnl_subsys_handle * 340 nfnl_subsys_open2(struct nfnl_handle *nfnlh, u_int8_t subsys_id, 341 u_int8_t cb_count, u_int32_t subscriptions, bool bind) 342 { 343 struct nfnl_subsys_handle *ssh; 344 int err = 0; 345 346 assert(nfnlh); 347 348 if (subsys_id > NFNL_MAX_SUBSYS) { 349 errno = ENOENT; 350 return NULL; 351 } 352 353 ssh = &nfnlh->subsys[subsys_id]; 354 if (ssh->cb) { 355 errno = EBUSY; 356 return NULL; 357 } 358 359 ssh->cb = calloc(cb_count, sizeof(*(ssh->cb))); 360 if (!ssh->cb) 361 return NULL; 362 363 ssh->nfnlh = nfnlh; 364 ssh->cb_count = cb_count; 365 ssh->subscriptions = subscriptions; 366 ssh->subsys_id = subsys_id; 367 368 /* although now we have nfnl_join to subscribe to certain 369 * groups, just keep this to ensure compatibility */ 370 if (bind) 371 err = recalc_rebind_subscriptions(nfnlh); 372 else 373 recalc_subscriptions(nfnlh); 374 if (err < 0) { 375 free(ssh->cb); 376 ssh->cb = NULL; 377 return NULL; 378 } 379 return ssh; 380 } 381 382 /** 383 * nfnl_subsys_close - close a nfnetlink subsys handler 384 * @ssh: nfnetlink subsystem handler 385 * 386 * Release all the callbacks registered in a subsystem handler. 387 */ 388 void nfnl_subsys_close(struct nfnl_subsys_handle *ssh) 389 { 390 assert(ssh); 391 392 ssh->subscriptions = 0; 393 ssh->cb_count = 0; 394 if (ssh->cb) { 395 free(ssh->cb); 396 ssh->cb = NULL; 397 } 398 } 399 400 /** 401 * nfnl_close - close a nfnetlink handler 402 * @nfnlh: nfnetlink handler 403 * 404 * This function closes the nfnetlink handler. On success, 0 is returned. 405 * On error, -1 is returned and errno is set appropiately. 406 */ 407 int nfnl_close(struct nfnl_handle *nfnlh) 408 { 409 int ret; 410 411 assert(nfnlh); 412 ret = close(nfnlh->fd); 413 if (ret < 0) 414 return ret; 415 return nfnl_close2(nfnlh); 416 } 417 418 /** 419 * nfnl_close2 - close a nfnetlink handler but keep fd 420 * @nfnlh: nfnetlink handler 421 * 422 * This function closes the nfnetlink handler. On success, 0 is returned. 423 * On error, -1 is returned and errno is set appropiately. 424 */ 425 int nfnl_close2(struct nfnl_handle *nfnlh) 426 { 427 int i; 428 429 assert(nfnlh); 430 431 for (i = 0; i < NFNL_MAX_SUBSYS; i++) 432 nfnl_subsys_close(&nfnlh->subsys[i]); 433 434 free(nfnlh); 435 436 return 0; 437 } 438 439 /** 440 * nfnl_join - join a nfnetlink multicast group 441 * @nfnlh: nfnetlink handler 442 * @group: group we want to join 443 * 444 * This function is used to join a certain multicast group. It must be 445 * called once the nfnetlink handler has been created. If any doubt, 446 * just use it if you have to listen to nfnetlink events. 447 * 448 * On success, 0 is returned. On error, -1 is returned and errno is set 449 * approapiately. 450 */ 451 int nfnl_join(const struct nfnl_handle *nfnlh, unsigned int group) 452 { 453 assert(nfnlh); 454 return setsockopt(nfnlh->fd, SOL_NETLINK, NETLINK_ADD_MEMBERSHIP, 455 &group, sizeof(group)); 456 } 457 458 /** 459 * nfnl_send - send a nfnetlink message through netlink socket 460 * @nfnlh: nfnetlink handler 461 * @n: netlink message 462 * 463 * On success, the number of bytes is returned. On error, -1 is returned 464 * and errno is set appropiately. 465 */ 466 int nfnl_send(struct nfnl_handle *nfnlh, struct nlmsghdr *n) 467 { 468 assert(nfnlh); 469 assert(n); 470 471 nfnl_debug_dump_packet(n, n->nlmsg_len+sizeof(*n), "nfnl_send"); 472 473 return sendto(nfnlh->fd, n, n->nlmsg_len, 0, 474 (struct sockaddr *)&nfnlh->peer, sizeof(nfnlh->peer)); 475 } 476 477 int nfnl_sendmsg(const struct nfnl_handle *nfnlh, const struct msghdr *msg, 478 unsigned int flags) 479 { 480 assert(nfnlh); 481 assert(msg); 482 483 return sendmsg(nfnlh->fd, msg, flags); 484 } 485 486 int nfnl_sendiov(const struct nfnl_handle *nfnlh, const struct iovec *iov, 487 unsigned int num, unsigned int flags) 488 { 489 struct msghdr msg; 490 491 assert(nfnlh); 492 493 msg.msg_name = (struct sockaddr *) &nfnlh->peer; 494 msg.msg_namelen = sizeof(nfnlh->peer); 495 msg.msg_iov = (struct iovec *) iov; 496 msg.msg_iovlen = num; 497 msg.msg_control = NULL; 498 msg.msg_controllen = 0; 499 msg.msg_flags = 0; 500 501 return nfnl_sendmsg(nfnlh, &msg, flags); 502 } 503 504 /** 505 * nfnl_fill_hdr - fill in netlink and nfnetlink header 506 * @nfnlh: nfnetlink handle 507 * @nlh: netlink message to be filled in 508 * @len: length of _payload_ bytes (not including nfgenmsg) 509 * @family: AF_INET / ... 510 * @res_id: resource id 511 * @msg_type: nfnetlink message type (without subsystem) 512 * @msg_flags: netlink message flags 513 * 514 * This function sets up appropiately the nfnetlink header. See that the 515 * pointer to the netlink message passed must point to a memory region of 516 * at least the size of struct nlmsghdr + struct nfgenmsg. 517 */ 518 void nfnl_fill_hdr(struct nfnl_subsys_handle *ssh, 519 struct nlmsghdr *nlh, unsigned int len, 520 u_int8_t family, 521 u_int16_t res_id, 522 u_int16_t msg_type, 523 u_int16_t msg_flags) 524 { 525 assert(ssh); 526 assert(nlh); 527 528 struct nfgenmsg *nfg = (void *)nlh + sizeof(*nlh); 529 530 nlh->nlmsg_len = NLMSG_LENGTH(len+sizeof(*nfg)); 531 nlh->nlmsg_type = (ssh->subsys_id<<8)|msg_type; 532 nlh->nlmsg_flags = msg_flags; 533 nlh->nlmsg_pid = 0; 534 535 if (ssh->nfnlh->flags & NFNL_F_SEQTRACK_ENABLED) { 536 nlh->nlmsg_seq = ++ssh->nfnlh->seq; 537 /* kernel uses sequence number zero for events */ 538 if (!ssh->nfnlh->seq) 539 nlh->nlmsg_seq = ssh->nfnlh->seq = time(NULL); 540 } else { 541 /* unset sequence number, ignore it */ 542 nlh->nlmsg_seq = 0; 543 } 544 545 nfg->nfgen_family = family; 546 nfg->version = NFNETLINK_V0; 547 nfg->res_id = htons(res_id); 548 } 549 550 struct nfattr * 551 nfnl_parse_hdr(const struct nfnl_handle *nfnlh, 552 const struct nlmsghdr *nlh, 553 struct nfgenmsg **genmsg) 554 { 555 if (nlh->nlmsg_len < NLMSG_LENGTH(sizeof(struct nfgenmsg))) 556 return NULL; 557 558 if (nlh->nlmsg_len == NLMSG_LENGTH(sizeof(struct nfgenmsg))) { 559 if (genmsg) 560 *genmsg = (void *)nlh + sizeof(*nlh); 561 return NULL; 562 } 563 564 if (genmsg) 565 *genmsg = (void *)nlh + sizeof(*nlh); 566 567 return (void *)nlh + NLMSG_LENGTH(sizeof(struct nfgenmsg)); 568 } 569 570 /** 571 * nfnl_recv - receive data from a nfnetlink subsystem 572 * @h: nfnetlink handler 573 * @buf: buffer where the data will be stored 574 * @len: size of the buffer 575 * 576 * This function doesn't perform any sanity checking. So do no expect 577 * that the data is well-formed. Such checkings are done by the parsing 578 * functions. 579 * 580 * On success, 0 is returned. On error, -1 is returned and errno is set 581 * appropiately. 582 * 583 * Note that ENOBUFS is returned in case that nfnetlink is exhausted. In 584 * that case is possible that the information requested is incomplete. 585 */ 586 ssize_t 587 nfnl_recv(const struct nfnl_handle *h, unsigned char *buf, size_t len) 588 { 589 socklen_t addrlen; 590 int status; 591 struct sockaddr_nl peer; 592 593 assert(h); 594 assert(buf); 595 assert(len > 0); 596 597 if (len < sizeof(struct nlmsgerr) 598 || len < sizeof(struct nlmsghdr)) { 599 errno = EBADMSG; 600 return -1; 601 } 602 603 addrlen = sizeof(h->peer); 604 status = recvfrom(h->fd, buf, len, 0, (struct sockaddr *)&peer, 605 &addrlen); 606 if (status <= 0) 607 return status; 608 609 if (addrlen != sizeof(peer)) { 610 errno = EINVAL; 611 return -1; 612 } 613 614 if (peer.nl_pid != 0) { 615 errno = ENOMSG; 616 return -1; 617 } 618 619 return status; 620 } 621 /** 622 * nfnl_listen: listen for one or more netlink messages 623 * @nfnhl: libnfnetlink handle 624 * @handler: callback function to be called for every netlink message 625 * - the callback handler should normally return 0 626 * - but may return a negative error code which will cause 627 * nfnl_listen to return immediately with the same error code 628 * - or return a postivie error code which will cause 629 * nfnl_listen to return after it has finished processing all 630 * the netlink messages in the current packet 631 * Thus a positive error code will terminate nfnl_listen "soon" 632 * without any loss of data, a negative error code will terminate 633 * nfnl_listen "very soon" and throw away data already read from 634 * the netlink socket. 635 * @jarg: opaque argument passed on to callback 636 * 637 * This function is used to receive and process messages coming from an open 638 * nfnetlink handler like events or information request via nfnl_send(). 639 * 640 * On error, -1 is returned, unfortunately errno is not always set 641 * appropiately. For that reason, the use of this function is DEPRECATED. 642 * Please, use nfnl_receive_process() instead. 643 */ 644 int nfnl_listen(struct nfnl_handle *nfnlh, 645 int (*handler)(struct sockaddr_nl *, struct nlmsghdr *n, 646 void *), void *jarg) 647 { 648 struct sockaddr_nl nladdr; 649 char buf[NFNL_BUFFSIZE] __attribute__ ((aligned)); 650 struct iovec iov; 651 int remain; 652 struct nlmsghdr *h; 653 struct nlmsgerr *msgerr; 654 int quit=0; 655 656 struct msghdr msg = { 657 .msg_name = &nladdr, 658 .msg_namelen = sizeof(nladdr), 659 .msg_iov = &iov, 660 .msg_iovlen = 1, 661 }; 662 663 memset(&nladdr, 0, sizeof(nladdr)); 664 nladdr.nl_family = AF_NETLINK; 665 iov.iov_base = buf; 666 iov.iov_len = sizeof(buf); 667 668 while (! quit) { 669 remain = recvmsg(nfnlh->fd, &msg, 0); 670 if (remain < 0) { 671 if (errno == EINTR) 672 continue; 673 /* Bad file descriptor */ 674 else if (errno == EBADF) 675 break; 676 else if (errno == EAGAIN) 677 break; 678 nfnl_error("recvmsg overrun: %s", strerror(errno)); 679 continue; 680 } 681 if (remain == 0) { 682 nfnl_error("EOF on netlink"); 683 return -1; 684 } 685 if (msg.msg_namelen != sizeof(nladdr)) { 686 nfnl_error("Bad sender address len (%d)", 687 msg.msg_namelen); 688 return -1; 689 } 690 691 for (h = (struct nlmsghdr *)buf; remain >= sizeof(*h);) { 692 int err; 693 int len = h->nlmsg_len; 694 int l = len - sizeof(*h); 695 696 if (l < 0 || len > remain) { 697 if (msg.msg_flags & MSG_TRUNC) { 698 nfnl_error("MSG_TRUNC"); 699 return -1; 700 } 701 nfnl_error("Malformed msg (len=%d)", len); 702 return -1; 703 } 704 705 /* end of messages reached, let's return */ 706 if (h->nlmsg_type == NLMSG_DONE) 707 return 0; 708 709 /* Break the loop if success is explicitely 710 * reported via NLM_F_ACK flag set */ 711 if (h->nlmsg_type == NLMSG_ERROR) { 712 msgerr = NLMSG_DATA(h); 713 return msgerr->error; 714 } 715 716 err = handler(&nladdr, h, jarg); 717 if (err < 0) 718 return err; 719 quit |= err; 720 721 /* FIXME: why not _NEXT macros, etc.? */ 722 //h = NLMSG_NEXT(h, remain); 723 remain -= NLMSG_ALIGN(len); 724 h = (struct nlmsghdr *)((char *)h + NLMSG_ALIGN(len)); 725 } 726 if (msg.msg_flags & MSG_TRUNC) { 727 nfnl_error("MSG_TRUNC"); 728 continue; 729 } 730 if (remain) { 731 nfnl_error("remnant size %d", remain); 732 return -1; 733 } 734 } 735 736 return quit; 737 } 738 739 /** 740 * nfnl_talk - send a request and then receive and process messages returned 741 * @nfnlh: nfnetelink handler 742 * @n: netlink message that contains the request 743 * @peer: peer PID 744 * @groups: netlink groups 745 * @junk: callback called if out-of-sequence messages were received 746 * @jarg: data for the junk callback 747 * 748 * This function is used to request an action that does not returns any 749 * information. On error, a negative value is returned, errno could be 750 * set appropiately. For that reason, the use of this function is DEPRECATED. 751 * Please, use nfnl_query() instead. 752 */ 753 int nfnl_talk(struct nfnl_handle *nfnlh, struct nlmsghdr *n, pid_t peer, 754 unsigned groups, struct nlmsghdr *answer, 755 int (*junk)(struct sockaddr_nl *, struct nlmsghdr *n, void *), 756 void *jarg) 757 { 758 char buf[NFNL_BUFFSIZE] __attribute__ ((aligned)); 759 struct sockaddr_nl nladdr; 760 struct nlmsghdr *h; 761 unsigned int seq; 762 int status; 763 struct iovec iov = { 764 n, n->nlmsg_len 765 }; 766 struct msghdr msg = { 767 .msg_name = &nladdr, 768 .msg_namelen = sizeof(nladdr), 769 .msg_iov = &iov, 770 .msg_iovlen = 1, 771 }; 772 773 memset(&nladdr, 0, sizeof(nladdr)); 774 nladdr.nl_family = AF_NETLINK; 775 nladdr.nl_pid = peer; 776 nladdr.nl_groups = groups; 777 778 n->nlmsg_seq = seq = ++nfnlh->seq; 779 /* FIXME: why ? */ 780 if (!answer) 781 n->nlmsg_flags |= NLM_F_ACK; 782 783 status = sendmsg(nfnlh->fd, &msg, 0); 784 if (status < 0) { 785 nfnl_error("sendmsg(netlink) %s", strerror(errno)); 786 return -1; 787 } 788 iov.iov_base = buf; 789 iov.iov_len = sizeof(buf); 790 791 while (1) { 792 status = recvmsg(nfnlh->fd, &msg, 0); 793 if (status < 0) { 794 if (errno == EINTR) 795 continue; 796 nfnl_error("recvmsg over-run"); 797 continue; 798 } 799 if (status == 0) { 800 nfnl_error("EOF on netlink"); 801 return -1; 802 } 803 if (msg.msg_namelen != sizeof(nladdr)) { 804 nfnl_error("Bad sender address len %d", 805 msg.msg_namelen); 806 return -1; 807 } 808 809 for (h = (struct nlmsghdr *)buf; status >= sizeof(*h); ) { 810 int len = h->nlmsg_len; 811 int l = len - sizeof(*h); 812 int err; 813 814 if (l < 0 || len > status) { 815 if (msg.msg_flags & MSG_TRUNC) { 816 nfnl_error("Truncated message\n"); 817 return -1; 818 } 819 nfnl_error("Malformed message: len=%d\n", len); 820 return -1; /* FIXME: libnetlink exits here */ 821 } 822 823 if (h->nlmsg_pid != nfnlh->local.nl_pid || 824 h->nlmsg_seq != seq) { 825 if (junk) { 826 err = junk(&nladdr, h, jarg); 827 if (err < 0) 828 return err; 829 } 830 goto cont; 831 } 832 833 if (h->nlmsg_type == NLMSG_ERROR) { 834 struct nlmsgerr *err = NLMSG_DATA(h); 835 if (l < sizeof(struct nlmsgerr)) 836 nfnl_error("ERROR truncated\n"); 837 else { 838 errno = -err->error; 839 if (errno == 0) { 840 if (answer) 841 memcpy(answer, h, h->nlmsg_len); 842 return 0; 843 } 844 perror("NFNETLINK answers"); 845 } 846 return err->error; 847 } 848 if (answer) { 849 memcpy(answer, h, h->nlmsg_len); 850 return 0; 851 } 852 853 nfnl_error("Unexpected reply!\n"); 854 cont: 855 status -= NLMSG_ALIGN(len); 856 h = (struct nlmsghdr *)((char *)h + NLMSG_ALIGN(len)); 857 } 858 if (msg.msg_flags & MSG_TRUNC) { 859 nfnl_error("Messages truncated\n"); 860 continue; 861 } 862 if (status) 863 nfnl_error("Remnant of size %d\n", status); 864 } 865 } 866 867 /** 868 * nfnl_addattr_l - Add variable length attribute to nlmsghdr 869 * @n: netlink message header to which attribute is to be added 870 * @maxlen: maximum length of netlink message header 871 * @type: type of new attribute 872 * @data: content of new attribute 873 * @len: attribute length 874 */ 875 int nfnl_addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data, 876 int alen) 877 { 878 int len = NFA_LENGTH(alen); 879 struct nfattr *nfa; 880 881 assert(n); 882 assert(maxlen > 0); 883 assert(type >= 0); 884 885 if ((NLMSG_ALIGN(n->nlmsg_len) + len) > maxlen) { 886 errno = ENOSPC; 887 return -1; 888 } 889 890 nfa = NLMSG_TAIL(n); 891 nfa->nfa_type = type; 892 nfa->nfa_len = len; 893 memcpy(NFA_DATA(nfa), data, alen); 894 n->nlmsg_len = (NLMSG_ALIGN(n->nlmsg_len) + NFA_ALIGN(len)); 895 return 0; 896 } 897 898 /** 899 * nfnl_nfa_addattr_l - Add variable length attribute to struct nfattr 900 * 901 * @nfa: struct nfattr 902 * @maxlen: maximal length of nfattr buffer 903 * @type: type for new attribute 904 * @data: content of new attribute 905 * @alen: length of new attribute 906 * 907 */ 908 int nfnl_nfa_addattr_l(struct nfattr *nfa, int maxlen, int type, 909 const void *data, int alen) 910 { 911 struct nfattr *subnfa; 912 int len = NFA_LENGTH(alen); 913 914 assert(nfa); 915 assert(maxlen > 0); 916 assert(type >= 0); 917 918 if (NFA_ALIGN(nfa->nfa_len) + len > maxlen) { 919 errno = ENOSPC; 920 return -1; 921 } 922 923 subnfa = (struct nfattr *)(((char *)nfa) + NFA_ALIGN(nfa->nfa_len)); 924 subnfa->nfa_type = type; 925 subnfa->nfa_len = len; 926 memcpy(NFA_DATA(subnfa), data, alen); 927 nfa->nfa_len = NFA_ALIGN(nfa->nfa_len) + len; 928 929 return 0; 930 } 931 932 /** 933 * nfnl_addattr8 - Add u_int8_t attribute to nlmsghdr 934 * 935 * @n: netlink message header to which attribute is to be added 936 * @maxlen: maximum length of netlink message header 937 * @type: type of new attribute 938 * @data: content of new attribute 939 */ 940 int nfnl_addattr8(struct nlmsghdr *n, int maxlen, int type, u_int8_t data) 941 { 942 assert(n); 943 assert(maxlen > 0); 944 assert(type >= 0); 945 946 return nfnl_addattr_l(n, maxlen, type, &data, sizeof(data)); 947 } 948 949 /** 950 * nfnl_nfa_addattr16 - Add u_int16_t attribute to struct nfattr 951 * 952 * @nfa: struct nfattr 953 * @maxlen: maximal length of nfattr buffer 954 * @type: type for new attribute 955 * @data: content of new attribute 956 * 957 */ 958 int nfnl_nfa_addattr16(struct nfattr *nfa, int maxlen, int type, 959 u_int16_t data) 960 { 961 assert(nfa); 962 assert(maxlen > 0); 963 assert(type >= 0); 964 965 return nfnl_nfa_addattr_l(nfa, maxlen, type, &data, sizeof(data)); 966 } 967 968 /** 969 * nfnl_addattr16 - Add u_int16_t attribute to nlmsghdr 970 * 971 * @n: netlink message header to which attribute is to be added 972 * @maxlen: maximum length of netlink message header 973 * @type: type of new attribute 974 * @data: content of new attribute 975 * 976 */ 977 int nfnl_addattr16(struct nlmsghdr *n, int maxlen, int type, 978 u_int16_t data) 979 { 980 assert(n); 981 assert(maxlen > 0); 982 assert(type >= 0); 983 984 return nfnl_addattr_l(n, maxlen, type, &data, sizeof(data)); 985 } 986 987 /** 988 * nfnl_nfa_addattr32 - Add u_int32_t attribute to struct nfattr 989 * 990 * @nfa: struct nfattr 991 * @maxlen: maximal length of nfattr buffer 992 * @type: type for new attribute 993 * @data: content of new attribute 994 * 995 */ 996 int nfnl_nfa_addattr32(struct nfattr *nfa, int maxlen, int type, 997 u_int32_t data) 998 { 999 assert(nfa); 1000 assert(maxlen > 0); 1001 assert(type >= 0); 1002 1003 return nfnl_nfa_addattr_l(nfa, maxlen, type, &data, sizeof(data)); 1004 } 1005 1006 /** 1007 * nfnl_addattr32 - Add u_int32_t attribute to nlmsghdr 1008 * 1009 * @n: netlink message header to which attribute is to be added 1010 * @maxlen: maximum length of netlink message header 1011 * @type: type of new attribute 1012 * @data: content of new attribute 1013 * 1014 */ 1015 int nfnl_addattr32(struct nlmsghdr *n, int maxlen, int type, 1016 u_int32_t data) 1017 { 1018 assert(n); 1019 assert(maxlen > 0); 1020 assert(type >= 0); 1021 1022 return nfnl_addattr_l(n, maxlen, type, &data, sizeof(data)); 1023 } 1024 1025 /** 1026 * nfnl_parse_attr - Parse a list of nfattrs into a pointer array 1027 * 1028 * @tb: pointer array, will be filled in (output) 1029 * @max: size of pointer array 1030 * @nfa: pointer to list of nfattrs 1031 * @len: length of 'nfa' 1032 * 1033 * The returned value is equal to the number of remaining bytes of the netlink 1034 * message that cannot be parsed. 1035 */ 1036 int nfnl_parse_attr(struct nfattr *tb[], int max, struct nfattr *nfa, int len) 1037 { 1038 assert(tb); 1039 assert(max > 0); 1040 assert(nfa); 1041 1042 memset(tb, 0, sizeof(struct nfattr *) * max); 1043 1044 while (NFA_OK(nfa, len)) { 1045 if (NFA_TYPE(nfa) <= max) 1046 tb[NFA_TYPE(nfa)-1] = nfa; 1047 nfa = NFA_NEXT(nfa,len); 1048 } 1049 1050 return len; 1051 } 1052 1053 /** 1054 * nfnl_build_nfa_iovec - Build two iovec's from tag, length and value 1055 * 1056 * @iov: pointer to array of two 'struct iovec' (caller-allocated) 1057 * @nfa: pointer to 'struct nfattr' (caller-allocated) 1058 * @type: type (tag) of attribute 1059 * @len: length of value 1060 * @val: pointer to buffer containing 'value' 1061 * 1062 */ 1063 void nfnl_build_nfa_iovec(struct iovec *iov, struct nfattr *nfa, 1064 u_int16_t type, u_int32_t len, unsigned char *val) 1065 { 1066 assert(iov); 1067 assert(nfa); 1068 1069 /* Set the attribut values */ 1070 nfa->nfa_len = sizeof(struct nfattr) + len; 1071 nfa->nfa_type = type; 1072 1073 iov[0].iov_base = nfa; 1074 iov[0].iov_len = sizeof(*nfa); 1075 iov[1].iov_base = val; 1076 iov[1].iov_len = NFA_ALIGN(len); 1077 } 1078 1079 #ifndef SO_RCVBUFFORCE 1080 #define SO_RCVBUFFORCE (33) 1081 #endif 1082 1083 /** 1084 * nfnl_rcvbufsiz - set the socket buffer size 1085 * @h: nfnetlink handler 1086 * @size: size of the buffer we want to set 1087 * 1088 * This function sets the new size of the socket buffer. Use this setting 1089 * to increase the socket buffer size if your system is reporting ENOBUFS 1090 * errors. 1091 * 1092 * This function returns the new size of the socket buffer. 1093 */ 1094 unsigned int nfnl_rcvbufsiz(const struct nfnl_handle *h, unsigned int size) 1095 { 1096 int status; 1097 socklen_t socklen = sizeof(size); 1098 unsigned int read_size = 0; 1099 1100 assert(h); 1101 1102 /* first we try the FORCE option, which is introduced in kernel 1103 * 2.6.14 to give "root" the ability to override the system wide 1104 * maximum */ 1105 status = setsockopt(h->fd, SOL_SOCKET, SO_RCVBUFFORCE, &size, socklen); 1106 if (status < 0) { 1107 /* if this didn't work, we try at least to get the system 1108 * wide maximum (or whatever the user requested) */ 1109 setsockopt(h->fd, SOL_SOCKET, SO_RCVBUF, &size, socklen); 1110 } 1111 getsockopt(h->fd, SOL_SOCKET, SO_RCVBUF, &read_size, &socklen); 1112 1113 return read_size; 1114 } 1115 1116 /** 1117 * nfnl_get_msg_first - get the first message of a multipart netlink message 1118 * @h: nfnetlink handle 1119 * @buf: data received that we want to process 1120 * @len: size of the data received 1121 * 1122 * This function returns a pointer to the first netlink message contained 1123 * in the chunk of data received from certain nfnetlink subsystem. 1124 * 1125 * On success, a valid address that points to the netlink message is returned. 1126 * On error, NULL is returned. 1127 */ 1128 struct nlmsghdr *nfnl_get_msg_first(struct nfnl_handle *h, 1129 const unsigned char *buf, 1130 size_t len) 1131 { 1132 struct nlmsghdr *nlh; 1133 1134 assert(h); 1135 assert(buf); 1136 assert(len > 0); 1137 1138 /* first message in buffer */ 1139 nlh = (struct nlmsghdr *)buf; 1140 if (!NLMSG_OK(nlh, len)) 1141 return NULL; 1142 h->last_nlhdr = nlh; 1143 1144 return nlh; 1145 } 1146 1147 struct nlmsghdr *nfnl_get_msg_next(struct nfnl_handle *h, 1148 const unsigned char *buf, 1149 size_t len) 1150 { 1151 struct nlmsghdr *nlh; 1152 size_t remain_len; 1153 1154 assert(h); 1155 assert(buf); 1156 assert(len > 0); 1157 1158 /* if last header in handle not inside this buffer, 1159 * drop reference to last header */ 1160 if (!h->last_nlhdr || 1161 (unsigned char *)h->last_nlhdr >= (buf + len) || 1162 (unsigned char *)h->last_nlhdr < buf) { 1163 h->last_nlhdr = NULL; 1164 return NULL; 1165 } 1166 1167 /* n-th part of multipart message */ 1168 if (h->last_nlhdr->nlmsg_type == NLMSG_DONE || 1169 h->last_nlhdr->nlmsg_flags & NLM_F_MULTI) { 1170 /* if last part in multipart message or no 1171 * multipart message at all, return */ 1172 h->last_nlhdr = NULL; 1173 return NULL; 1174 } 1175 1176 remain_len = (len - ((unsigned char *)h->last_nlhdr - buf)); 1177 nlh = NLMSG_NEXT(h->last_nlhdr, remain_len); 1178 1179 if (!NLMSG_OK(nlh, remain_len)) { 1180 h->last_nlhdr = NULL; 1181 return NULL; 1182 } 1183 1184 h->last_nlhdr = nlh; 1185 1186 return nlh; 1187 } 1188 1189 /** 1190 * nfnl_callback_register - register a callback for a certain message type 1191 * @ssh: nfnetlink subsys handler 1192 * @type: subsys call 1193 * @cb: nfnetlink callback to be registered 1194 * 1195 * On success, 0 is returned. On error, -1 is returned and errno is set 1196 * appropiately. 1197 */ 1198 int nfnl_callback_register(struct nfnl_subsys_handle *ssh, 1199 u_int8_t type, struct nfnl_callback *cb) 1200 { 1201 assert(ssh); 1202 assert(cb); 1203 1204 if (type >= ssh->cb_count) { 1205 errno = EINVAL; 1206 return -1; 1207 } 1208 1209 memcpy(&ssh->cb[type], cb, sizeof(*cb)); 1210 1211 return 0; 1212 } 1213 1214 /** 1215 * nfnl_callback_unregister - unregister a certain callback 1216 * @ssh: nfnetlink subsys handler 1217 * @type: subsys call 1218 * 1219 * On sucess, 0 is returned. On error, -1 is returned and errno is 1220 * set appropiately. 1221 */ 1222 int nfnl_callback_unregister(struct nfnl_subsys_handle *ssh, u_int8_t type) 1223 { 1224 assert(ssh); 1225 1226 if (type >= ssh->cb_count) { 1227 errno = EINVAL; 1228 return -1; 1229 } 1230 1231 ssh->cb[type].call = NULL; 1232 1233 return 0; 1234 } 1235 1236 int nfnl_check_attributes(const struct nfnl_handle *h, 1237 const struct nlmsghdr *nlh, 1238 struct nfattr *nfa[]) 1239 { 1240 assert(h); 1241 assert(nlh); 1242 assert(nfa); 1243 1244 int min_len; 1245 u_int8_t type = NFNL_MSG_TYPE(nlh->nlmsg_type); 1246 u_int8_t subsys_id = NFNL_SUBSYS_ID(nlh->nlmsg_type); 1247 const struct nfnl_subsys_handle *ssh; 1248 struct nfnl_callback *cb; 1249 1250 if (subsys_id > NFNL_MAX_SUBSYS) 1251 return -EINVAL; 1252 1253 ssh = &h->subsys[subsys_id]; 1254 cb = &ssh->cb[type]; 1255 1256 #if 1 1257 /* checks need to be enabled as soon as this is called from 1258 * somebody else than __nfnl_handle_msg */ 1259 if (type >= ssh->cb_count) 1260 return -EINVAL; 1261 1262 min_len = NLMSG_SPACE(sizeof(struct nfgenmsg)); 1263 if (nlh->nlmsg_len < min_len) 1264 return -EINVAL; 1265 #endif 1266 memset(nfa, 0, sizeof(struct nfattr *) * cb->attr_count); 1267 1268 if (nlh->nlmsg_len > min_len) { 1269 struct nfattr *attr = NFM_NFA(NLMSG_DATA(nlh)); 1270 int attrlen = nlh->nlmsg_len - NLMSG_ALIGN(min_len); 1271 1272 while (NFA_OK(attr, attrlen)) { 1273 unsigned int flavor = NFA_TYPE(attr); 1274 if (flavor) { 1275 if (flavor > cb->attr_count) { 1276 /* we have received an attribute from 1277 * the kernel which we don't understand 1278 * yet. We have to silently ignore this 1279 * for the sake of future compatibility */ 1280 attr = NFA_NEXT(attr, attrlen); 1281 continue; 1282 } 1283 nfa[flavor - 1] = attr; 1284 } 1285 attr = NFA_NEXT(attr, attrlen); 1286 } 1287 } 1288 1289 return 0; 1290 } 1291 1292 static int __nfnl_handle_msg(struct nfnl_handle *h, struct nlmsghdr *nlh, 1293 int len) 1294 { 1295 struct nfnl_subsys_handle *ssh; 1296 u_int8_t type = NFNL_MSG_TYPE(nlh->nlmsg_type); 1297 u_int8_t subsys_id = NFNL_SUBSYS_ID(nlh->nlmsg_type); 1298 int err = 0; 1299 1300 if (subsys_id > NFNL_MAX_SUBSYS) 1301 return -1; 1302 1303 ssh = &h->subsys[subsys_id]; 1304 1305 if (nlh->nlmsg_len < NLMSG_LENGTH(NLMSG_ALIGN(sizeof(struct nfgenmsg)))) 1306 return -1; 1307 1308 if (type >= ssh->cb_count) 1309 return -1; 1310 1311 if (ssh->cb[type].attr_count) { 1312 struct nfattr *nfa[ssh->cb[type].attr_count]; 1313 1314 err = nfnl_check_attributes(h, nlh, nfa); 1315 if (err < 0) 1316 return err; 1317 if (ssh->cb[type].call) 1318 return ssh->cb[type].call(nlh, nfa, ssh->cb[type].data); 1319 } 1320 return 0; 1321 } 1322 1323 int nfnl_handle_packet(struct nfnl_handle *h, char *buf, int len) 1324 { 1325 1326 while (len >= NLMSG_SPACE(0)) { 1327 u_int32_t rlen; 1328 struct nlmsghdr *nlh = (struct nlmsghdr *)buf; 1329 1330 if (nlh->nlmsg_len < sizeof(struct nlmsghdr) 1331 || len < nlh->nlmsg_len) 1332 return -1; 1333 1334 rlen = NLMSG_ALIGN(nlh->nlmsg_len); 1335 if (rlen > len) 1336 rlen = len; 1337 1338 if (__nfnl_handle_msg(h, nlh, rlen) < 0) 1339 return -1; 1340 1341 len -= rlen; 1342 buf += rlen; 1343 } 1344 return 0; 1345 } 1346 1347 static int nfnl_is_error(struct nfnl_handle *h, struct nlmsghdr *nlh) 1348 { 1349 /* This message is an ACK or a DONE */ 1350 if (nlh->nlmsg_type == NLMSG_ERROR || 1351 (nlh->nlmsg_type == NLMSG_DONE && 1352 nlh->nlmsg_flags & NLM_F_MULTI)) { 1353 if (nlh->nlmsg_len < NLMSG_ALIGN(sizeof(struct nlmsgerr))) { 1354 errno = EBADMSG; 1355 return 1; 1356 } 1357 errno = -(*((int *)NLMSG_DATA(nlh))); 1358 return 1; 1359 } 1360 return 0; 1361 } 1362 1363 /* On error, -1 is returned and errno is set appropiately. On success, 1364 * 0 is returned if there is no more data to process, >0 if there is 1365 * more data to process */ 1366 static int nfnl_step(struct nfnl_handle *h, struct nlmsghdr *nlh) 1367 { 1368 struct nfnl_subsys_handle *ssh; 1369 u_int8_t type = NFNL_MSG_TYPE(nlh->nlmsg_type); 1370 u_int8_t subsys_id = NFNL_SUBSYS_ID(nlh->nlmsg_type); 1371 1372 /* Is this an error message? */ 1373 if (nfnl_is_error(h, nlh)) { 1374 /* This is an ACK */ 1375 if (errno == 0) 1376 return 0; 1377 /* This an error message */ 1378 return -1; 1379 } 1380 1381 /* nfnetlink sanity checks: check for nfgenmsg size */ 1382 if (nlh->nlmsg_len < NLMSG_SPACE(sizeof(struct nfgenmsg))) { 1383 errno = ENOSPC; 1384 return -1; 1385 } 1386 1387 if (subsys_id > NFNL_MAX_SUBSYS) { 1388 errno = ENOENT; 1389 return -1; 1390 } 1391 1392 ssh = &h->subsys[subsys_id]; 1393 if (!ssh) { 1394 errno = ENOENT; 1395 return -1; 1396 } 1397 1398 if (type >= ssh->cb_count) { 1399 errno = ENOENT; 1400 return -1; 1401 } 1402 1403 if (ssh->cb[type].attr_count) { 1404 int err; 1405 struct nfattr *tb[ssh->cb[type].attr_count]; 1406 struct nfattr *attr = NFM_NFA(NLMSG_DATA(nlh)); 1407 int min_len = NLMSG_SPACE(sizeof(struct nfgenmsg)); 1408 int len = nlh->nlmsg_len - NLMSG_ALIGN(min_len); 1409 1410 err = nfnl_parse_attr(tb, ssh->cb[type].attr_count, attr, len); 1411 if (err == -1) 1412 return -1; 1413 1414 if (ssh->cb[type].call) { 1415 /* 1416 * On error, the callback returns NFNL_CB_FAILURE and 1417 * errno must be explicitely set. On success, 1418 * NFNL_CB_STOP is returned and we're done, otherwise 1419 * NFNL_CB_CONTINUE means that we want to continue 1420 * data processing. 1421 */ 1422 return ssh->cb[type].call(nlh, 1423 tb, 1424 ssh->cb[type].data); 1425 } 1426 } 1427 /* no callback set, continue data processing */ 1428 return 1; 1429 } 1430 1431 /** 1432 * nfnl_process - process data coming from a nfnetlink system 1433 * @h: nfnetlink handler 1434 * @buf: buffer that contains the netlink message 1435 * @len: size of the data contained in the buffer (not the buffer size) 1436 * 1437 * This function processes all the nfnetlink messages contained inside a 1438 * buffer. It performs the appropiate sanity checks and passes the message 1439 * to a certain handler that is registered via register_callback(). 1440 * 1441 * On success, NFNL_CB_STOP is returned if the data processing has finished. 1442 * If a value NFNL_CB_CONTINUE is returned, then there is more data to 1443 * process. On error, NFNL_CB_CONTINUE is returned and errno is set to the 1444 * appropiate value. 1445 * 1446 * In case that the callback returns NFNL_CB_FAILURE, errno may be set by 1447 * the library client. If your callback decides not to process data anymore 1448 * for any reason, then it must return NFNL_CB_STOP. Otherwise, if the 1449 * callback continues the processing NFNL_CB_CONTINUE is returned. 1450 */ 1451 int nfnl_process(struct nfnl_handle *h, const unsigned char *buf, size_t len) 1452 { 1453 int ret = 0; 1454 struct nlmsghdr *nlh = (struct nlmsghdr *)buf; 1455 1456 assert(h); 1457 assert(buf); 1458 assert(len > 0); 1459 1460 /* check for out of sequence message */ 1461 if (nlh->nlmsg_seq && nlh->nlmsg_seq != h->seq) { 1462 errno = EILSEQ; 1463 return -1; 1464 } 1465 while (len >= NLMSG_SPACE(0) && NLMSG_OK(nlh, len)) { 1466 1467 ret = nfnl_step(h, nlh); 1468 if (ret <= NFNL_CB_STOP) 1469 break; 1470 1471 nlh = NLMSG_NEXT(nlh, len); 1472 } 1473 return ret; 1474 } 1475 1476 /* 1477 * New parsing functions based on iterators 1478 */ 1479 1480 struct nfnl_iterator { 1481 struct nlmsghdr *nlh; 1482 unsigned int len; 1483 }; 1484 1485 /** 1486 * nfnl_iterator_create: create an nfnetlink iterator 1487 * @h: nfnetlink handler 1488 * @buf: buffer that contains data received from a nfnetlink system 1489 * @len: size of the data contained in the buffer (not the buffer size) 1490 * 1491 * This function creates an iterator that can be used to parse nfnetlink 1492 * message one by one. The iterator gives more control to the programmer 1493 * in the messages processing. 1494 * 1495 * On success, a valid address is returned. On error, NULL is returned 1496 * and errno is set to the appropiate value. 1497 */ 1498 struct nfnl_iterator * 1499 nfnl_iterator_create(const struct nfnl_handle *h, 1500 const char *buf, 1501 size_t len) 1502 { 1503 struct nlmsghdr *nlh; 1504 struct nfnl_iterator *it; 1505 1506 assert(h); 1507 assert(buf); 1508 assert(len > 0); 1509 1510 it = malloc(sizeof(struct nfnl_iterator)); 1511 if (!it) { 1512 errno = ENOMEM; 1513 return NULL; 1514 } 1515 1516 /* first message in buffer */ 1517 nlh = (struct nlmsghdr *)buf; 1518 if (len < NLMSG_SPACE(0) || !NLMSG_OK(nlh, len)) { 1519 free(it); 1520 errno = EBADMSG; 1521 return NULL; 1522 } 1523 it->nlh = nlh; 1524 it->len = len; 1525 1526 return it; 1527 } 1528 1529 /** 1530 * nfnl_iterator_destroy - destroy a nfnetlink iterator 1531 * @it: nfnetlink iterator 1532 * 1533 * This function destroys a certain iterator. Nothing is returned. 1534 */ 1535 void nfnl_iterator_destroy(struct nfnl_iterator *it) 1536 { 1537 assert(it); 1538 free(it); 1539 } 1540 1541 /** 1542 * nfnl_iterator_process - process a nfnetlink message 1543 * @h: nfnetlink handler 1544 * @it: nfnetlink iterator that contains the current message to be proccesed 1545 * 1546 * This function process just the current message selected by the iterator. 1547 * On success, a value greater or equal to zero is returned. On error, 1548 * -1 is returned and errno is appropiately set. 1549 */ 1550 int nfnl_iterator_process(struct nfnl_handle *h, struct nfnl_iterator *it) 1551 { 1552 assert(h); 1553 assert(it->nlh); 1554 1555 /* check for out of sequence message */ 1556 if (it->nlh->nlmsg_seq && it->nlh->nlmsg_seq != h->seq) { 1557 errno = EILSEQ; 1558 return -1; 1559 } 1560 if (it->len < NLMSG_SPACE(0) || !NLMSG_OK(it->nlh, it->len)) { 1561 errno = EBADMSG; 1562 return -1; 1563 } 1564 return nfnl_step(h, it->nlh); 1565 } 1566 1567 /** 1568 * nfnl_iterator_next - get the next message hold by the iterator 1569 * @h: nfnetlink handler 1570 * @it: nfnetlink iterator that contains the current message processed 1571 * 1572 * This function update the current message to be processed pointer. 1573 * It returns NFNL_CB_CONTINUE if there is still more messages to be 1574 * processed, otherwise NFNL_CB_STOP is returned. 1575 */ 1576 int nfnl_iterator_next(const struct nfnl_handle *h, struct nfnl_iterator *it) 1577 { 1578 assert(h); 1579 assert(it); 1580 1581 it->nlh = NLMSG_NEXT(it->nlh, it->len); 1582 if (!it->nlh) 1583 return 0; 1584 return 1; 1585 } 1586 1587 /** 1588 * nfnl_catch - get responses from the nfnetlink system and process them 1589 * @h: nfnetlink handler 1590 * 1591 * This function handles the data received from the nfnetlink system. 1592 * For example, events generated by one of the subsystems. The message 1593 * is passed to the callback registered via callback_register(). Note that 1594 * this a replacement of nfnl_listen and its use is recommended. 1595 * 1596 * On success, 0 is returned. On error, a -1 is returned. If you do not 1597 * want to listen to events anymore, then your callback must return 1598 * NFNL_CB_STOP. 1599 * 1600 * Note that ENOBUFS is returned in case that nfnetlink is exhausted. In 1601 * that case is possible that the information requested is incomplete. 1602 */ 1603 int nfnl_catch(struct nfnl_handle *h) 1604 { 1605 int ret; 1606 1607 assert(h); 1608 1609 while (1) { 1610 unsigned char buf[h->rcv_buffer_size] 1611 __attribute__ ((aligned)); 1612 1613 ret = nfnl_recv(h, buf, sizeof(buf)); 1614 if (ret == -1) { 1615 /* interrupted syscall must retry */ 1616 if (errno == EINTR) 1617 continue; 1618 break; 1619 } 1620 1621 ret = nfnl_process(h, buf, ret); 1622 if (ret <= NFNL_CB_STOP) 1623 break; 1624 } 1625 1626 return ret; 1627 } 1628 1629 /** 1630 * nfnl_query - request/response communication challenge 1631 * @h: nfnetlink handler 1632 * @nlh: nfnetlink message to be sent 1633 * 1634 * This function sends a nfnetlink message to a certain subsystem and 1635 * receives the response messages associated, such messages are passed to 1636 * the callback registered via register_callback(). Note that this function 1637 * is a replacement for nfnl_talk, its use is recommended. 1638 * 1639 * On success, 0 is returned. On error, a negative is returned. If your 1640 * does not want to listen to events anymore, then your callback must 1641 * return NFNL_CB_STOP. 1642 * 1643 * Note that ENOBUFS is returned in case that nfnetlink is exhausted. In 1644 * that case is possible that the information requested is incomplete. 1645 */ 1646 int nfnl_query(struct nfnl_handle *h, struct nlmsghdr *nlh) 1647 { 1648 assert(h); 1649 assert(nlh); 1650 1651 if (nfnl_send(h, nlh) == -1) 1652 return -1; 1653 1654 return nfnl_catch(h); 1655 } 1656