1 /* libnfnetlink.c: generic library for communication with netfilter
3 * (C) 2002-2006 by Harald Welte <laforge@gnumonks.org>
4 * (C) 2006-2011 by Pablo Neira Ayuso <pablo@netfilter.org>
6 * Based on some original ideas from Jay Schulist <jschlst@samba.org>
8 * Development of this code funded by Astaro AG (http://www.astaro.com)
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.
14 * 2005-09-14 Pablo Neira Ayuso <pablo@netfilter.org>:
15 * Define structure nfnlhdr
16 * Added __be64_to_cpu function
17 * Use NFA_TYPE macro to get the attribute type
19 * 2006-01-14 Harald Welte <laforge@netfilter.org>:
20 * introduce nfnl_subsys_handle
22 * 2006-01-15 Pablo Neira Ayuso <pablo@netfilter.org>:
23 * set missing subsys_id in nfnl_subsys_open
24 * set missing nfnlh->local.nl_pid in nfnl_open
26 * 2006-01-26 Harald Welte <laforge@netfilter.org>:
27 * remove bogus nfnlh->local.nl_pid from nfnl_open ;)
28 * add 16bit attribute functions
30 * 2006-07-03 Pablo Neira Ayuso <pablo@netfilter.org>:
32 * add replacements for nfnl_listen and nfnl_talk
45 #include <netinet/in.h>
47 #include <linux/types.h>
48 #include <sys/socket.h>
51 #include <linux/netlink.h>
53 #include <libnfnetlink/libnfnetlink.h>
55 #ifndef NETLINK_ADD_MEMBERSHIP
56 #define NETLINK_ADD_MEMBERSHIP 1
60 #define SOL_NETLINK 270
64 #define nfnl_error(format, args...) \
65 fprintf(stderr, "%s: " format "\n", __FUNCTION__, ## args)
68 #define nfnl_debug_dump_packet nfnl_dump_packet
70 #define nfnl_debug_dump_packet(a, b, ...)
73 struct nfnl_subsys_handle
{
74 struct nfnl_handle
*nfnlh
;
75 u_int32_t subscriptions
;
78 struct nfnl_callback
*cb
; /* array of callbacks */
81 #define NFNL_MAX_SUBSYS 16 /* enough for now */
83 #define NFNL_F_SEQTRACK_ENABLED (1 << 0)
87 struct sockaddr_nl local
;
88 struct sockaddr_nl peer
;
89 u_int32_t subscriptions
;
92 u_int32_t rcv_buffer_size
; /* for nfnl_catch */
94 struct nlmsghdr
*last_nlhdr
;
95 struct nfnl_subsys_handle subsys
[NFNL_MAX_SUBSYS
+1];
98 void nfnl_dump_packet(struct nlmsghdr
*nlh
, int received_len
, char *desc
)
100 void *nlmsg_data
= NLMSG_DATA(nlh
);
101 struct nfattr
*nfa
= NFM_NFA(NLMSG_DATA(nlh
));
102 int len
= NFM_PAYLOAD(nlh
);
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
);
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
);
123 * nfnl_fd - returns the descriptor that identifies the socket
124 * @nfnlh: nfnetlink handler
126 * Use this function if you need to interact with the socket. Common
127 * scenarios are the use of poll()/select() to achieve multiplexation.
129 int nfnl_fd(struct nfnl_handle
*h
)
136 * nfnl_portid - returns the Netlink port ID of this socket
137 * @h: nfnetlink handler
139 unsigned int nfnl_portid(const struct nfnl_handle
*h
)
142 return h
->local
.nl_pid
;
145 static int recalc_rebind_subscriptions(struct nfnl_handle
*nfnlh
)
148 u_int32_t new_subscriptions
= nfnlh
->subscriptions
;
150 for (i
= 0; i
< NFNL_MAX_SUBSYS
; i
++)
151 new_subscriptions
|= nfnlh
->subsys
[i
].subscriptions
;
153 nfnlh
->local
.nl_groups
= new_subscriptions
;
154 err
= bind(nfnlh
->fd
, (struct sockaddr
*)&nfnlh
->local
,
155 sizeof(nfnlh
->local
));
159 nfnlh
->subscriptions
= new_subscriptions
;
165 * nfnl_open - open a nfnetlink handler
167 * This function creates a nfnetlink handler, this is required to establish
168 * a communication between the userspace and the nfnetlink system.
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.
173 struct nfnl_handle
*nfnl_open(void)
175 struct nfnl_handle
*nfnlh
;
176 unsigned int addr_len
;
178 nfnlh
= malloc(sizeof(*nfnlh
));
182 memset(nfnlh
, 0, sizeof(*nfnlh
));
183 nfnlh
->fd
= socket(AF_NETLINK
, SOCK_RAW
, NETLINK_NETFILTER
);
187 nfnlh
->local
.nl_family
= AF_NETLINK
;
188 nfnlh
->peer
.nl_family
= AF_NETLINK
;
190 addr_len
= sizeof(nfnlh
->local
);
191 getsockname(nfnlh
->fd
, (struct sockaddr
*)&nfnlh
->local
, &addr_len
);
192 if (addr_len
!= sizeof(nfnlh
->local
)) {
196 if (nfnlh
->local
.nl_family
!= AF_NETLINK
) {
200 nfnlh
->seq
= time(NULL
);
201 nfnlh
->rcv_buffer_size
= NFNL_BUFFSIZE
;
203 /* don't set pid here, only first socket of process has real pid !!!
204 * binding to pid '0' will default */
206 /* let us do the initial bind */
207 if (recalc_rebind_subscriptions(nfnlh
) < 0)
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
)) {
217 /* sequence tracking enabled by default */
218 nfnlh
->flags
|= NFNL_F_SEQTRACK_ENABLED
;
230 * nfnl_set_sequence_tracking - set netlink sequence tracking
231 * @h: nfnetlink handler
233 void nfnl_set_sequence_tracking(struct nfnl_handle
*h
)
235 h
->flags
|= NFNL_F_SEQTRACK_ENABLED
;
239 * nfnl_unset_sequence_tracking - set netlink sequence tracking
240 * @h: nfnetlink handler
242 void nfnl_unset_sequence_tracking(struct nfnl_handle
*h
)
244 h
->flags
&= ~NFNL_F_SEQTRACK_ENABLED
;
248 * nfnl_set_rcv_buffer_size - set the size of the receive buffer
249 * @h: libnfnetlink handler
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.
255 void nfnl_set_rcv_buffer_size(struct nfnl_handle
*h
, unsigned int size
)
257 h
->rcv_buffer_size
= size
;
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
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().
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.
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
)
279 struct nfnl_subsys_handle
*ssh
;
283 if (subsys_id
> NFNL_MAX_SUBSYS
) {
288 ssh
= &nfnlh
->subsys
[subsys_id
];
294 ssh
->cb
= calloc(cb_count
, sizeof(*(ssh
->cb
)));
299 ssh
->cb_count
= cb_count
;
300 ssh
->subscriptions
= subscriptions
;
301 ssh
->subsys_id
= subsys_id
;
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) {
315 * nfnl_subsys_close - close a nfnetlink subsys handler
316 * @ssh: nfnetlink subsystem handler
318 * Release all the callbacks registered in a subsystem handler.
320 void nfnl_subsys_close(struct nfnl_subsys_handle
*ssh
)
324 ssh
->subscriptions
= 0;
333 * nfnl_close - close a nfnetlink handler
334 * @nfnlh: nfnetlink handler
336 * This function closes the nfnetlink handler. On success, 0 is returned.
337 * On error, -1 is returned and errno is set appropiately.
339 int nfnl_close(struct nfnl_handle
*nfnlh
)
345 for (i
= 0; i
< NFNL_MAX_SUBSYS
; i
++)
346 nfnl_subsys_close(&nfnlh
->subsys
[i
]);
348 ret
= close(nfnlh
->fd
);
358 * nfnl_join - join a nfnetlink multicast group
359 * @nfnlh: nfnetlink handler
360 * @group: group we want to join
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.
366 * On success, 0 is returned. On error, -1 is returned and errno is set
369 int nfnl_join(const struct nfnl_handle
*nfnlh
, unsigned int group
)
372 return setsockopt(nfnlh
->fd
, SOL_NETLINK
, NETLINK_ADD_MEMBERSHIP
,
373 &group
, sizeof(group
));
377 * nfnl_send - send a nfnetlink message through netlink socket
378 * @nfnlh: nfnetlink handler
379 * @n: netlink message
381 * On success, the number of bytes is returned. On error, -1 is returned
382 * and errno is set appropiately.
384 int nfnl_send(struct nfnl_handle
*nfnlh
, struct nlmsghdr
*n
)
389 nfnl_debug_dump_packet(n
, n
->nlmsg_len
+sizeof(*n
), "nfnl_send");
391 return sendto(nfnlh
->fd
, n
, n
->nlmsg_len
, 0,
392 (struct sockaddr
*)&nfnlh
->peer
, sizeof(nfnlh
->peer
));
395 int nfnl_sendmsg(const struct nfnl_handle
*nfnlh
, const struct msghdr
*msg
,
401 return sendmsg(nfnlh
->fd
, msg
, flags
);
404 int nfnl_sendiov(const struct nfnl_handle
*nfnlh
, const struct iovec
*iov
,
405 unsigned int num
, unsigned int flags
)
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;
419 return nfnl_sendmsg(nfnlh
, &msg
, flags
);
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
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.
436 void nfnl_fill_hdr(struct nfnl_subsys_handle
*ssh
,
437 struct nlmsghdr
*nlh
, unsigned int len
,
446 struct nfgenmsg
*nfg
= (void *)nlh
+ sizeof(*nlh
);
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
;
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
);
459 /* unset sequence number, ignore it */
463 nfg
->nfgen_family
= family
;
464 nfg
->version
= NFNETLINK_V0
;
465 nfg
->res_id
= htons(res_id
);
469 nfnl_parse_hdr(const struct nfnl_handle
*nfnlh
,
470 const struct nlmsghdr
*nlh
,
471 struct nfgenmsg
**genmsg
)
473 if (nlh
->nlmsg_len
< NLMSG_LENGTH(sizeof(struct nfgenmsg
)))
476 if (nlh
->nlmsg_len
== NLMSG_LENGTH(sizeof(struct nfgenmsg
))) {
478 *genmsg
= (void *)nlh
+ sizeof(*nlh
);
483 *genmsg
= (void *)nlh
+ sizeof(*nlh
);
485 return (void *)nlh
+ NLMSG_LENGTH(sizeof(struct nfgenmsg
));
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
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
498 * On success, 0 is returned. On error, -1 is returned and errno is set
501 * Note that ENOBUFS is returned in case that nfnetlink is exhausted. In
502 * that case is possible that the information requested is incomplete.
505 nfnl_recv(const struct nfnl_handle
*h
, unsigned char *buf
, size_t len
)
509 struct sockaddr_nl peer
;
515 if (len
< sizeof(struct nlmsgerr
)
516 || len
< sizeof(struct nlmsghdr
)) {
521 addrlen
= sizeof(h
->peer
);
522 status
= recvfrom(h
->fd
, buf
, len
, 0, (struct sockaddr
*)&peer
,
527 if (addrlen
!= sizeof(peer
)) {
532 if (peer
.nl_pid
!= 0) {
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
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().
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.
562 int nfnl_listen(struct nfnl_handle
*nfnlh
,
563 int (*handler
)(struct sockaddr_nl
*, struct nlmsghdr
*n
,
566 struct sockaddr_nl nladdr
;
567 char buf
[NFNL_BUFFSIZE
] __attribute__ ((aligned
));
571 struct nlmsgerr
*msgerr
;
574 struct msghdr msg
= {
576 .msg_namelen
= sizeof(nladdr
),
581 memset(&nladdr
, 0, sizeof(nladdr
));
582 nladdr
.nl_family
= AF_NETLINK
;
584 iov
.iov_len
= sizeof(buf
);
587 remain
= recvmsg(nfnlh
->fd
, &msg
, 0);
591 /* Bad file descriptor */
592 else if (errno
== EBADF
)
594 else if (errno
== EAGAIN
)
596 nfnl_error("recvmsg overrun: %s", strerror(errno
));
600 nfnl_error("EOF on netlink");
603 if (msg
.msg_namelen
!= sizeof(nladdr
)) {
604 nfnl_error("Bad sender address len (%d)",
609 for (h
= (struct nlmsghdr
*)buf
; remain
>= sizeof(*h
);) {
611 int len
= h
->nlmsg_len
;
612 int l
= len
- sizeof(*h
);
614 if (l
< 0 || len
> remain
) {
615 if (msg
.msg_flags
& MSG_TRUNC
) {
616 nfnl_error("MSG_TRUNC");
619 nfnl_error("Malformed msg (len=%d)", len
);
623 /* end of messages reached, let's return */
624 if (h
->nlmsg_type
== NLMSG_DONE
)
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
;
634 err
= handler(&nladdr
, h
, jarg
);
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
));
644 if (msg
.msg_flags
& MSG_TRUNC
) {
645 nfnl_error("MSG_TRUNC");
649 nfnl_error("remnant size %d", remain
);
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
662 * @groups: netlink groups
663 * @junk: callback called if out-of-sequence messages were received
664 * @jarg: data for the junk callback
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.
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 *),
676 char buf
[NFNL_BUFFSIZE
] __attribute__ ((aligned
));
677 struct sockaddr_nl nladdr
;
684 struct msghdr msg
= {
686 .msg_namelen
= sizeof(nladdr
),
691 memset(&nladdr
, 0, sizeof(nladdr
));
692 nladdr
.nl_family
= AF_NETLINK
;
693 nladdr
.nl_pid
= peer
;
694 nladdr
.nl_groups
= groups
;
696 n
->nlmsg_seq
= seq
= ++nfnlh
->seq
;
699 n
->nlmsg_flags
|= NLM_F_ACK
;
701 status
= sendmsg(nfnlh
->fd
, &msg
, 0);
703 nfnl_error("sendmsg(netlink) %s", strerror(errno
));
707 iov
.iov_len
= sizeof(buf
);
710 status
= recvmsg(nfnlh
->fd
, &msg
, 0);
714 nfnl_error("recvmsg over-run");
718 nfnl_error("EOF on netlink");
721 if (msg
.msg_namelen
!= sizeof(nladdr
)) {
722 nfnl_error("Bad sender address len %d",
727 for (h
= (struct nlmsghdr
*)buf
; status
>= sizeof(*h
); ) {
728 int len
= h
->nlmsg_len
;
729 int l
= len
- sizeof(*h
);
732 if (l
< 0 || len
> status
) {
733 if (msg
.msg_flags
& MSG_TRUNC
) {
734 nfnl_error("Truncated message\n");
737 nfnl_error("Malformed message: len=%d\n", len
);
738 return -1; /* FIXME: libnetlink exits here */
741 if (h
->nlmsg_pid
!= nfnlh
->local
.nl_pid
||
742 h
->nlmsg_seq
!= seq
) {
744 err
= junk(&nladdr
, h
, jarg
);
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");
759 memcpy(answer
, h
, h
->nlmsg_len
);
762 perror("NFNETLINK answers");
767 memcpy(answer
, h
, h
->nlmsg_len
);
771 nfnl_error("Unexpected reply!\n");
773 status
-= NLMSG_ALIGN(len
);
774 h
= (struct nlmsghdr
*)((char *)h
+ NLMSG_ALIGN(len
));
776 if (msg
.msg_flags
& MSG_TRUNC
) {
777 nfnl_error("Messages truncated\n");
781 nfnl_error("Remnant of size %d\n", status
);
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
793 int nfnl_addattr_l(struct nlmsghdr
*n
, int maxlen
, int type
, const void *data
,
796 int len
= NFA_LENGTH(alen
);
803 if ((NLMSG_ALIGN(n
->nlmsg_len
) + len
) > maxlen
) {
809 nfa
->nfa_type
= type
;
811 memcpy(NFA_DATA(nfa
), data
, alen
);
812 n
->nlmsg_len
= (NLMSG_ALIGN(n
->nlmsg_len
) + NFA_ALIGN(len
));
817 * nfnl_nfa_addattr_l - Add variable length attribute to struct nfattr
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
826 int nfnl_nfa_addattr_l(struct nfattr
*nfa
, int maxlen
, int type
,
827 const void *data
, int alen
)
829 struct nfattr
*subnfa
;
830 int len
= NFA_LENGTH(alen
);
836 if (NFA_ALIGN(nfa
->nfa_len
) + len
> maxlen
) {
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
;
851 * nfnl_addattr8 - Add u_int8_t attribute to nlmsghdr
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
858 int nfnl_addattr8(struct nlmsghdr
*n
, int maxlen
, int type
, u_int8_t data
)
864 return nfnl_addattr_l(n
, maxlen
, type
, &data
, sizeof(data
));
868 * nfnl_nfa_addattr16 - Add u_int16_t attribute to struct nfattr
870 * @nfa: struct nfattr
871 * @maxlen: maximal length of nfattr buffer
872 * @type: type for new attribute
873 * @data: content of new attribute
876 int nfnl_nfa_addattr16(struct nfattr
*nfa
, int maxlen
, int type
,
883 return nfnl_nfa_addattr_l(nfa
, maxlen
, type
, &data
, sizeof(data
));
887 * nfnl_addattr16 - Add u_int16_t attribute to nlmsghdr
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
895 int nfnl_addattr16(struct nlmsghdr
*n
, int maxlen
, int type
,
902 return nfnl_addattr_l(n
, maxlen
, type
, &data
, sizeof(data
));
906 * nfnl_nfa_addattr32 - Add u_int32_t attribute to struct nfattr
908 * @nfa: struct nfattr
909 * @maxlen: maximal length of nfattr buffer
910 * @type: type for new attribute
911 * @data: content of new attribute
914 int nfnl_nfa_addattr32(struct nfattr
*nfa
, int maxlen
, int type
,
921 return nfnl_nfa_addattr_l(nfa
, maxlen
, type
, &data
, sizeof(data
));
925 * nfnl_addattr32 - Add u_int32_t attribute to nlmsghdr
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
933 int nfnl_addattr32(struct nlmsghdr
*n
, int maxlen
, int type
,
940 return nfnl_addattr_l(n
, maxlen
, type
, &data
, sizeof(data
));
944 * nfnl_parse_attr - Parse a list of nfattrs into a pointer array
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'
951 * The returned value is equal to the number of remaining bytes of the netlink
952 * message that cannot be parsed.
954 int nfnl_parse_attr(struct nfattr
*tb
[], int max
, struct nfattr
*nfa
, int len
)
960 memset(tb
, 0, sizeof(struct nfattr
*) * max
);
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
);
972 * nfnl_build_nfa_iovec - Build two iovec's from tag, length and value
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'
981 void nfnl_build_nfa_iovec(struct iovec
*iov
, struct nfattr
*nfa
,
982 u_int16_t type
, u_int32_t len
, unsigned char *val
)
987 /* Set the attribut values */
988 nfa
->nfa_len
= sizeof(struct nfattr
) + len
;
989 nfa
->nfa_type
= type
;
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
);
997 #ifndef SO_RCVBUFFORCE
998 #define SO_RCVBUFFORCE (33)
1002 * nfnl_rcvbufsiz - set the socket buffer size
1003 * @h: nfnetlink handler
1004 * @size: size of the buffer we want to set
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
1010 * This function returns the new size of the socket buffer.
1012 unsigned int nfnl_rcvbufsiz(const struct nfnl_handle
*h
, unsigned int size
)
1015 socklen_t socklen
= sizeof(size
);
1016 unsigned int read_size
= 0;
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
1023 status
= setsockopt(h
->fd
, SOL_SOCKET
, SO_RCVBUFFORCE
, &size
, socklen
);
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
);
1029 getsockopt(h
->fd
, SOL_SOCKET
, SO_RCVBUF
, &read_size
, &socklen
);
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
1040 * This function returns a pointer to the first netlink message contained
1041 * in the chunk of data received from certain nfnetlink subsystem.
1043 * On success, a valid address that points to the netlink message is returned.
1044 * On error, NULL is returned.
1046 struct nlmsghdr
*nfnl_get_msg_first(struct nfnl_handle
*h
,
1047 const unsigned char *buf
,
1050 struct nlmsghdr
*nlh
;
1056 /* first message in buffer */
1057 nlh
= (struct nlmsghdr
*)buf
;
1058 if (!NLMSG_OK(nlh
, len
))
1060 h
->last_nlhdr
= nlh
;
1065 struct nlmsghdr
*nfnl_get_msg_next(struct nfnl_handle
*h
,
1066 const unsigned char *buf
,
1069 struct nlmsghdr
*nlh
;
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
;
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
;
1094 remain_len
= (len
- ((unsigned char *)h
->last_nlhdr
- buf
));
1095 nlh
= NLMSG_NEXT(h
->last_nlhdr
, remain_len
);
1097 if (!NLMSG_OK(nlh
, remain_len
)) {
1098 h
->last_nlhdr
= NULL
;
1102 h
->last_nlhdr
= nlh
;
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
1113 * On success, 0 is returned. On error, -1 is returned and errno is set
1116 int nfnl_callback_register(struct nfnl_subsys_handle
*ssh
,
1117 u_int8_t type
, struct nfnl_callback
*cb
)
1122 if (type
>= ssh
->cb_count
) {
1127 memcpy(&ssh
->cb
[type
], cb
, sizeof(*cb
));
1133 * nfnl_callback_unregister - unregister a certain callback
1134 * @ssh: nfnetlink subsys handler
1135 * @type: subsys call
1137 * On sucess, 0 is returned. On error, -1 is returned and errno is
1140 int nfnl_callback_unregister(struct nfnl_subsys_handle
*ssh
, u_int8_t type
)
1144 if (type
>= ssh
->cb_count
) {
1149 ssh
->cb
[type
].call
= NULL
;
1154 int nfnl_check_attributes(const struct nfnl_handle
*h
,
1155 const struct nlmsghdr
*nlh
,
1156 struct nfattr
*nfa
[])
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
;
1168 if (subsys_id
> NFNL_MAX_SUBSYS
)
1171 ssh
= &h
->subsys
[subsys_id
];
1172 cb
= &ssh
->cb
[type
];
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
)
1180 min_len
= NLMSG_SPACE(sizeof(struct nfgenmsg
));
1181 if (nlh
->nlmsg_len
< min_len
)
1184 memset(nfa
, 0, sizeof(struct nfattr
*) * cb
->attr_count
);
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
);
1190 while (NFA_OK(attr
, attrlen
)) {
1191 unsigned int flavor
= NFA_TYPE(attr
);
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
);
1201 nfa
[flavor
- 1] = attr
;
1203 attr
= NFA_NEXT(attr
, attrlen
);
1210 static int __nfnl_handle_msg(struct nfnl_handle
*h
, struct nlmsghdr
*nlh
,
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
);
1218 if (subsys_id
> NFNL_MAX_SUBSYS
)
1221 ssh
= &h
->subsys
[subsys_id
];
1223 if (nlh
->nlmsg_len
< NLMSG_LENGTH(NLMSG_ALIGN(sizeof(struct nfgenmsg
))))
1226 if (type
>= ssh
->cb_count
)
1229 if (ssh
->cb
[type
].attr_count
) {
1230 struct nfattr
*nfa
[ssh
->cb
[type
].attr_count
];
1232 err
= nfnl_check_attributes(h
, nlh
, nfa
);
1235 if (ssh
->cb
[type
].call
)
1236 return ssh
->cb
[type
].call(nlh
, nfa
, ssh
->cb
[type
].data
);
1241 int nfnl_handle_packet(struct nfnl_handle
*h
, char *buf
, int len
)
1244 while (len
>= NLMSG_SPACE(0)) {
1246 struct nlmsghdr
*nlh
= (struct nlmsghdr
*)buf
;
1248 if (nlh
->nlmsg_len
< sizeof(struct nlmsghdr
)
1249 || len
< nlh
->nlmsg_len
)
1252 rlen
= NLMSG_ALIGN(nlh
->nlmsg_len
);
1256 if (__nfnl_handle_msg(h
, nlh
, rlen
) < 0)
1265 static int nfnl_is_error(struct nfnl_handle
*h
, struct nlmsghdr
*nlh
)
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
))) {
1275 errno
= -(*((int *)NLMSG_DATA(nlh
)));
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
)
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
);
1290 /* Is this an error message? */
1291 if (nfnl_is_error(h
, nlh
)) {
1292 /* This is an ACK */
1295 /* This an error message */
1299 /* nfnetlink sanity checks: check for nfgenmsg size */
1300 if (nlh
->nlmsg_len
< NLMSG_SPACE(sizeof(struct nfgenmsg
))) {
1305 if (subsys_id
> NFNL_MAX_SUBSYS
) {
1310 ssh
= &h
->subsys
[subsys_id
];
1316 if (type
>= ssh
->cb_count
) {
1321 if (ssh
->cb
[type
].attr_count
) {
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
);
1328 err
= nfnl_parse_attr(tb
, ssh
->cb
[type
].attr_count
, attr
, len
);
1332 if (ssh
->cb
[type
].call
) {
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
1340 return ssh
->cb
[type
].call(nlh
,
1342 ssh
->cb
[type
].data
);
1345 /* no callback set, continue data processing */
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)
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().
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
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.
1369 int nfnl_process(struct nfnl_handle
*h
, const unsigned char *buf
, size_t len
)
1372 struct nlmsghdr
*nlh
= (struct nlmsghdr
*)buf
;
1378 /* check for out of sequence message */
1379 if (nlh
->nlmsg_seq
&& nlh
->nlmsg_seq
!= h
->seq
) {
1383 while (len
>= NLMSG_SPACE(0) && NLMSG_OK(nlh
, len
)) {
1385 ret
= nfnl_step(h
, nlh
);
1386 if (ret
<= NFNL_CB_STOP
)
1389 nlh
= NLMSG_NEXT(nlh
, len
);
1395 * New parsing functions based on iterators
1398 struct nfnl_iterator
{
1399 struct nlmsghdr
*nlh
;
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)
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.
1413 * On success, a valid address is returned. On error, NULL is returned
1414 * and errno is set to the appropiate value.
1416 struct nfnl_iterator
*
1417 nfnl_iterator_create(const struct nfnl_handle
*h
,
1421 struct nlmsghdr
*nlh
;
1422 struct nfnl_iterator
*it
;
1428 it
= malloc(sizeof(struct nfnl_iterator
));
1434 /* first message in buffer */
1435 nlh
= (struct nlmsghdr
*)buf
;
1436 if (len
< NLMSG_SPACE(0) || !NLMSG_OK(nlh
, len
)) {
1448 * nfnl_iterator_destroy - destroy a nfnetlink iterator
1449 * @it: nfnetlink iterator
1451 * This function destroys a certain iterator. Nothing is returned.
1453 void nfnl_iterator_destroy(struct nfnl_iterator
*it
)
1460 * nfnl_iterator_process - process a nfnetlink message
1461 * @h: nfnetlink handler
1462 * @it: nfnetlink iterator that contains the current message to be proccesed
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.
1468 int nfnl_iterator_process(struct nfnl_handle
*h
, struct nfnl_iterator
*it
)
1473 /* check for out of sequence message */
1474 if (it
->nlh
->nlmsg_seq
&& it
->nlh
->nlmsg_seq
!= h
->seq
) {
1478 if (it
->len
< NLMSG_SPACE(0) || !NLMSG_OK(it
->nlh
, it
->len
)) {
1482 return nfnl_step(h
, it
->nlh
);
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
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.
1494 int nfnl_iterator_next(const struct nfnl_handle
*h
, struct nfnl_iterator
*it
)
1499 it
->nlh
= NLMSG_NEXT(it
->nlh
, it
->len
);
1506 * nfnl_catch - get responses from the nfnetlink system and process them
1507 * @h: nfnetlink handler
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.
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
1518 * Note that ENOBUFS is returned in case that nfnetlink is exhausted. In
1519 * that case is possible that the information requested is incomplete.
1521 int nfnl_catch(struct nfnl_handle
*h
)
1528 unsigned char buf
[h
->rcv_buffer_size
]
1529 __attribute__ ((aligned
));
1531 ret
= nfnl_recv(h
, buf
, sizeof(buf
));
1533 /* interrupted syscall must retry */
1539 ret
= nfnl_process(h
, buf
, ret
);
1540 if (ret
<= NFNL_CB_STOP
)
1548 * nfnl_query - request/response communication challenge
1549 * @h: nfnetlink handler
1550 * @nlh: nfnetlink message to be sent
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.
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.
1561 * Note that ENOBUFS is returned in case that nfnetlink is exhausted. In
1562 * that case is possible that the information requested is incomplete.
1564 int nfnl_query(struct nfnl_handle
*h
, struct nlmsghdr
*nlh
)
1569 if (nfnl_send(h
, nlh
) == -1)
1572 return nfnl_catch(h
);