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