22#include "nl-default.h"
24#include <netlink/netlink.h>
25#include <netlink/utils.h>
26#include <netlink/msg.h>
27#include <netlink/handlers.h>
30#include "nl-priv-dynamic-core/nl-core.h"
32static void print_header_content(FILE *ofd,
struct nlmsghdr *n)
37 fprintf(ofd,
"type=%s length=%u flags=<%s> sequence-nr=%u pid=%u",
38 nl_nlmsgtype2str(n->nlmsg_type, type,
sizeof(type)),
39 n->nlmsg_len, nl_nlmsg_flags2str(n->nlmsg_flags, flags,
40 sizeof(flags)), n->nlmsg_seq, n->nlmsg_pid);
43static int nl_valid_handler_verbose(
struct nl_msg *msg,
void *arg)
45 FILE *ofd = arg ? arg : stdout;
47 fprintf(ofd,
"-- Warning: unhandled valid message: ");
48 print_header_content(ofd,
nlmsg_hdr(msg));
54static int nl_invalid_handler_verbose(
struct nl_msg *msg,
void *arg)
56 FILE *ofd = arg ? arg : stderr;
58 fprintf(ofd,
"-- Error: Invalid message: ");
59 print_header_content(ofd,
nlmsg_hdr(msg));
65static int nl_overrun_handler_verbose(
struct nl_msg *msg,
void *arg)
67 FILE *ofd = arg ? arg : stderr;
69 fprintf(ofd,
"-- Error: Netlink Overrun: ");
70 print_header_content(ofd,
nlmsg_hdr(msg));
76static int nl_error_handler_verbose(
struct sockaddr_nl *who,
77 struct nlmsgerr *e,
void *arg)
79 FILE *ofd = arg ? arg : stderr;
81 fprintf(ofd,
"-- Error received: %s\n-- Original message: ",
82 nl_strerror_l(-e->error));
83 print_header_content(ofd, &e->msg);
86 return -nl_syserr2nlerr(e->error);
89static int nl_valid_handler_debug(
struct nl_msg *msg,
void *arg)
91 FILE *ofd = arg ? arg : stderr;
93 fprintf(ofd,
"-- Debug: Unhandled Valid message: ");
94 print_header_content(ofd,
nlmsg_hdr(msg));
100static int nl_finish_handler_debug(
struct nl_msg *msg,
void *arg)
102 FILE *ofd = arg ? arg : stderr;
104 fprintf(ofd,
"-- Debug: End of multipart message block: ");
105 print_header_content(ofd,
nlmsg_hdr(msg));
111static int nl_msg_in_handler_debug(
struct nl_msg *msg,
void *arg)
113 FILE *ofd = arg ? arg : stderr;
115 fprintf(ofd,
"-- Debug: Received Message:\n");
121static int nl_msg_out_handler_debug(
struct nl_msg *msg,
void *arg)
123 FILE *ofd = arg ? arg : stderr;
125 fprintf(ofd,
"-- Debug: Sent Message:\n");
131static int nl_skipped_handler_debug(
struct nl_msg *msg,
void *arg)
133 FILE *ofd = arg ? arg : stderr;
135 fprintf(ofd,
"-- Debug: Skipped message: ");
136 print_header_content(ofd,
nlmsg_hdr(msg));
142static int nl_ack_handler_debug(
struct nl_msg *msg,
void *arg)
144 FILE *ofd = arg ? arg : stderr;
146 fprintf(ofd,
"-- Debug: ACK: ");
147 print_header_content(ofd,
nlmsg_hdr(msg));
203 if ((
unsigned int) kind > NL_CB_KIND_MAX)
206 cb = calloc(1,
sizeof(*cb));
213 for (i = 0; i <= NL_CB_TYPE_MAX; i++)
235 memcpy(cb, orig,
sizeof(*orig));
248void nl_cb_put(
struct nl_cb *cb)
255 if (cb->cb_refcnt < 0)
258 if (cb->cb_refcnt <= 0)
293 if ((
unsigned int) type > NL_CB_TYPE_MAX)
296 if ((
unsigned int) kind > NL_CB_KIND_MAX)
300 cb->cb_set[type] = func;
301 cb->cb_args[type] = arg;
303 cb->cb_set[type] = cb_def[type][kind];
304 cb->cb_args[type] = arg;
324 for (i = 0; i <= NL_CB_TYPE_MAX; i++) {
343 if ((
unsigned int) kind > NL_CB_KIND_MAX)
348 cb->cb_err_arg = arg;
350 cb->cb_err = cb_err_def[kind];
351 cb->cb_err_arg = arg;
370 int (*func)(
struct nl_sock *,
struct nl_cb *))
381 int (*func)(
struct nl_sock *,
struct sockaddr_nl *,
382 unsigned char **,
struct ucred **))
393 int (*func)(
struct nl_sock *,
struct nl_msg *))
void nl_cb_overwrite_send(struct nl_cb *cb, int(*func)(struct nl_sock *, struct nl_msg *))
Overwrite internal calls to nl_send()
int(* nl_recvmsg_err_cb_t)(struct sockaddr_nl *nla, struct nlmsgerr *nlerr, void *arg)
nl_recvmsgs() callback for error message processing customization
void nl_cb_overwrite_recv(struct nl_cb *cb, int(*func)(struct nl_sock *, struct sockaddr_nl *, unsigned char **, struct ucred **))
Overwrite internal calls to nl_recv()
nl_cb_type
Callback types.
int(* nl_recvmsg_msg_cb_t)(struct nl_msg *msg, void *arg)
nl_recvmsgs() callback for message processing customization
nl_cb_kind
Callback kinds.
int nl_cb_set(struct nl_cb *cb, enum nl_cb_type type, enum nl_cb_kind kind, nl_recvmsg_msg_cb_t func, void *arg)
Set up a callback.
int nl_cb_set_all(struct nl_cb *cb, enum nl_cb_kind kind, nl_recvmsg_msg_cb_t func, void *arg)
Set up a all callbacks.
struct nl_cb * nl_cb_clone(struct nl_cb *orig)
Clone an existing callback handle.
struct nl_cb * nl_cb_alloc(enum nl_cb_kind kind)
Allocate a new callback handle.
enum nl_cb_type nl_cb_active_type(struct nl_cb *cb)
Obtain type of current active callback.
void nl_cb_overwrite_recvmsgs(struct nl_cb *cb, int(*func)(struct nl_sock *, struct nl_cb *))
Overwrite internal calls to nl_recvmsgs()
int nl_cb_err(struct nl_cb *cb, enum nl_cb_kind kind, nl_recvmsg_err_cb_t func, void *arg)
Set up an error callback.
@ NL_STOP
Stop parsing altogether and discard remaining messages.
@ NL_OK
Proceed with whatever would come next.
@ NL_SKIP
Skip this message.
@ NL_CB_SKIPPED
Message wants to be skipped.
@ NL_CB_FINISH
Last message in a series of multi part messages received.
@ NL_CB_MSG_OUT
Called for every message sent out except for nl_sendto()
@ NL_CB_MSG_IN
Called for every message received.
@ NL_CB_OVERRUN
Report received that data was lost.
@ NL_CB_VALID
Message is valid.
@ NL_CB_ACK
Message is an acknowledgement.
@ NL_CB_INVALID
Message is malformed and invalid.
@ NL_CB_DEFAULT
Default handlers (quiet)
@ NL_CB_CUSTOM
Customized handler specified by the user.
@ NL_CB_VERBOSE
Verbose default handlers (error messages printed)
@ NL_CB_DEBUG
Debug handlers for debugging.
void nl_msg_dump(struct nl_msg *msg, FILE *ofd)
Dump message in human readable format to file descriptor.
struct nlmsghdr * nlmsg_hdr(struct nl_msg *n)
Return actual netlink message.
int(* cb_recvmsgs_ow)(struct nl_sock *, struct nl_cb *)
May be used to replace nl_recvmsgs with your own implementation in all internal calls to nl_recvmsgs.
enum nl_cb_type cb_active
indicates the callback that is currently active
int(* cb_recv_ow)(struct nl_sock *, struct sockaddr_nl *, unsigned char **, struct ucred **)
Overwrite internal calls to nl_recv, must return the number of octets read and allocate a buffer for ...
int(* cb_send_ow)(struct nl_sock *, struct nl_msg *)
Overwrites internal calls to nl_send, must send the netlink message.