xref: /aosp_15_r20/external/libnl/lib/handlers.c (revision 4dc78e53d49367fa8e61b07018507c90983a077d)
1*4dc78e53SAndroid Build Coastguard Worker /* SPDX-License-Identifier: LGPL-2.1-only */
2*4dc78e53SAndroid Build Coastguard Worker /*
3*4dc78e53SAndroid Build Coastguard Worker  * Copyright (c) 2003-2008 Thomas Graf <[email protected]>
4*4dc78e53SAndroid Build Coastguard Worker  */
5*4dc78e53SAndroid Build Coastguard Worker 
6*4dc78e53SAndroid Build Coastguard Worker /**
7*4dc78e53SAndroid Build Coastguard Worker  * @ingroup core
8*4dc78e53SAndroid Build Coastguard Worker  * @defgroup cb Callbacks/Customization
9*4dc78e53SAndroid Build Coastguard Worker  *
10*4dc78e53SAndroid Build Coastguard Worker  * Related sections in the development guide:
11*4dc78e53SAndroid Build Coastguard Worker  * - @core_doc{core_cb, Callback Configuration}
12*4dc78e53SAndroid Build Coastguard Worker  *
13*4dc78e53SAndroid Build Coastguard Worker  * @{
14*4dc78e53SAndroid Build Coastguard Worker  *
15*4dc78e53SAndroid Build Coastguard Worker  * Header
16*4dc78e53SAndroid Build Coastguard Worker  * ------
17*4dc78e53SAndroid Build Coastguard Worker  * ~~~~{.c}
18*4dc78e53SAndroid Build Coastguard Worker  * #include <netlink/handlers.h>
19*4dc78e53SAndroid Build Coastguard Worker  * ~~~~
20*4dc78e53SAndroid Build Coastguard Worker  */
21*4dc78e53SAndroid Build Coastguard Worker 
22*4dc78e53SAndroid Build Coastguard Worker #include "nl-default.h"
23*4dc78e53SAndroid Build Coastguard Worker 
24*4dc78e53SAndroid Build Coastguard Worker #include <netlink/netlink.h>
25*4dc78e53SAndroid Build Coastguard Worker #include <netlink/utils.h>
26*4dc78e53SAndroid Build Coastguard Worker #include <netlink/msg.h>
27*4dc78e53SAndroid Build Coastguard Worker #include <netlink/handlers.h>
28*4dc78e53SAndroid Build Coastguard Worker 
29*4dc78e53SAndroid Build Coastguard Worker #include "nl-core.h"
30*4dc78e53SAndroid Build Coastguard Worker #include "nl-priv-dynamic-core/nl-core.h"
31*4dc78e53SAndroid Build Coastguard Worker 
print_header_content(FILE * ofd,struct nlmsghdr * n)32*4dc78e53SAndroid Build Coastguard Worker static void print_header_content(FILE *ofd, struct nlmsghdr *n)
33*4dc78e53SAndroid Build Coastguard Worker {
34*4dc78e53SAndroid Build Coastguard Worker 	char flags[128];
35*4dc78e53SAndroid Build Coastguard Worker 	char type[32];
36*4dc78e53SAndroid Build Coastguard Worker 
37*4dc78e53SAndroid Build Coastguard Worker 	fprintf(ofd, "type=%s length=%u flags=<%s> sequence-nr=%u pid=%u",
38*4dc78e53SAndroid Build Coastguard Worker 		nl_nlmsgtype2str(n->nlmsg_type, type, sizeof(type)),
39*4dc78e53SAndroid Build Coastguard Worker 		n->nlmsg_len, nl_nlmsg_flags2str(n->nlmsg_flags, flags,
40*4dc78e53SAndroid Build Coastguard Worker 		sizeof(flags)), n->nlmsg_seq, n->nlmsg_pid);
41*4dc78e53SAndroid Build Coastguard Worker }
42*4dc78e53SAndroid Build Coastguard Worker 
nl_valid_handler_verbose(struct nl_msg * msg,void * arg)43*4dc78e53SAndroid Build Coastguard Worker static int nl_valid_handler_verbose(struct nl_msg *msg, void *arg)
44*4dc78e53SAndroid Build Coastguard Worker {
45*4dc78e53SAndroid Build Coastguard Worker 	FILE *ofd = arg ? arg : stdout;
46*4dc78e53SAndroid Build Coastguard Worker 
47*4dc78e53SAndroid Build Coastguard Worker 	fprintf(ofd, "-- Warning: unhandled valid message: ");
48*4dc78e53SAndroid Build Coastguard Worker 	print_header_content(ofd, nlmsg_hdr(msg));
49*4dc78e53SAndroid Build Coastguard Worker 	fprintf(ofd, "\n");
50*4dc78e53SAndroid Build Coastguard Worker 
51*4dc78e53SAndroid Build Coastguard Worker 	return NL_OK;
52*4dc78e53SAndroid Build Coastguard Worker }
53*4dc78e53SAndroid Build Coastguard Worker 
nl_invalid_handler_verbose(struct nl_msg * msg,void * arg)54*4dc78e53SAndroid Build Coastguard Worker static int nl_invalid_handler_verbose(struct nl_msg *msg, void *arg)
55*4dc78e53SAndroid Build Coastguard Worker {
56*4dc78e53SAndroid Build Coastguard Worker 	FILE *ofd = arg ? arg : stderr;
57*4dc78e53SAndroid Build Coastguard Worker 
58*4dc78e53SAndroid Build Coastguard Worker 	fprintf(ofd, "-- Error: Invalid message: ");
59*4dc78e53SAndroid Build Coastguard Worker 	print_header_content(ofd, nlmsg_hdr(msg));
60*4dc78e53SAndroid Build Coastguard Worker 	fprintf(ofd, "\n");
61*4dc78e53SAndroid Build Coastguard Worker 
62*4dc78e53SAndroid Build Coastguard Worker 	return NL_STOP;
63*4dc78e53SAndroid Build Coastguard Worker }
64*4dc78e53SAndroid Build Coastguard Worker 
nl_overrun_handler_verbose(struct nl_msg * msg,void * arg)65*4dc78e53SAndroid Build Coastguard Worker static int nl_overrun_handler_verbose(struct nl_msg *msg, void *arg)
66*4dc78e53SAndroid Build Coastguard Worker {
67*4dc78e53SAndroid Build Coastguard Worker 	FILE *ofd = arg ? arg : stderr;
68*4dc78e53SAndroid Build Coastguard Worker 
69*4dc78e53SAndroid Build Coastguard Worker 	fprintf(ofd, "-- Error: Netlink Overrun: ");
70*4dc78e53SAndroid Build Coastguard Worker 	print_header_content(ofd, nlmsg_hdr(msg));
71*4dc78e53SAndroid Build Coastguard Worker 	fprintf(ofd, "\n");
72*4dc78e53SAndroid Build Coastguard Worker 
73*4dc78e53SAndroid Build Coastguard Worker 	return NL_STOP;
74*4dc78e53SAndroid Build Coastguard Worker }
75*4dc78e53SAndroid Build Coastguard Worker 
nl_error_handler_verbose(struct sockaddr_nl * who,struct nlmsgerr * e,void * arg)76*4dc78e53SAndroid Build Coastguard Worker static int nl_error_handler_verbose(struct sockaddr_nl *who,
77*4dc78e53SAndroid Build Coastguard Worker 				    struct nlmsgerr *e, void *arg)
78*4dc78e53SAndroid Build Coastguard Worker {
79*4dc78e53SAndroid Build Coastguard Worker 	FILE *ofd = arg ? arg : stderr;
80*4dc78e53SAndroid Build Coastguard Worker 
81*4dc78e53SAndroid Build Coastguard Worker 	fprintf(ofd, "-- Error received: %s\n-- Original message: ",
82*4dc78e53SAndroid Build Coastguard Worker 		nl_strerror_l(-e->error));
83*4dc78e53SAndroid Build Coastguard Worker 	print_header_content(ofd, &e->msg);
84*4dc78e53SAndroid Build Coastguard Worker 	fprintf(ofd, "\n");
85*4dc78e53SAndroid Build Coastguard Worker 
86*4dc78e53SAndroid Build Coastguard Worker 	return -nl_syserr2nlerr(e->error);
87*4dc78e53SAndroid Build Coastguard Worker }
88*4dc78e53SAndroid Build Coastguard Worker 
nl_valid_handler_debug(struct nl_msg * msg,void * arg)89*4dc78e53SAndroid Build Coastguard Worker static int nl_valid_handler_debug(struct nl_msg *msg, void *arg)
90*4dc78e53SAndroid Build Coastguard Worker {
91*4dc78e53SAndroid Build Coastguard Worker 	FILE *ofd = arg ? arg : stderr;
92*4dc78e53SAndroid Build Coastguard Worker 
93*4dc78e53SAndroid Build Coastguard Worker 	fprintf(ofd, "-- Debug: Unhandled Valid message: ");
94*4dc78e53SAndroid Build Coastguard Worker 	print_header_content(ofd, nlmsg_hdr(msg));
95*4dc78e53SAndroid Build Coastguard Worker 	fprintf(ofd, "\n");
96*4dc78e53SAndroid Build Coastguard Worker 
97*4dc78e53SAndroid Build Coastguard Worker 	return NL_OK;
98*4dc78e53SAndroid Build Coastguard Worker }
99*4dc78e53SAndroid Build Coastguard Worker 
nl_finish_handler_debug(struct nl_msg * msg,void * arg)100*4dc78e53SAndroid Build Coastguard Worker static int nl_finish_handler_debug(struct nl_msg *msg, void *arg)
101*4dc78e53SAndroid Build Coastguard Worker {
102*4dc78e53SAndroid Build Coastguard Worker 	FILE *ofd = arg ? arg : stderr;
103*4dc78e53SAndroid Build Coastguard Worker 
104*4dc78e53SAndroid Build Coastguard Worker 	fprintf(ofd, "-- Debug: End of multipart message block: ");
105*4dc78e53SAndroid Build Coastguard Worker 	print_header_content(ofd, nlmsg_hdr(msg));
106*4dc78e53SAndroid Build Coastguard Worker 	fprintf(ofd, "\n");
107*4dc78e53SAndroid Build Coastguard Worker 
108*4dc78e53SAndroid Build Coastguard Worker 	return NL_STOP;
109*4dc78e53SAndroid Build Coastguard Worker }
110*4dc78e53SAndroid Build Coastguard Worker 
nl_msg_in_handler_debug(struct nl_msg * msg,void * arg)111*4dc78e53SAndroid Build Coastguard Worker static int nl_msg_in_handler_debug(struct nl_msg *msg, void *arg)
112*4dc78e53SAndroid Build Coastguard Worker {
113*4dc78e53SAndroid Build Coastguard Worker 	FILE *ofd = arg ? arg : stderr;
114*4dc78e53SAndroid Build Coastguard Worker 
115*4dc78e53SAndroid Build Coastguard Worker 	fprintf(ofd, "-- Debug: Received Message:\n");
116*4dc78e53SAndroid Build Coastguard Worker 	nl_msg_dump(msg, ofd);
117*4dc78e53SAndroid Build Coastguard Worker 
118*4dc78e53SAndroid Build Coastguard Worker 	return NL_OK;
119*4dc78e53SAndroid Build Coastguard Worker }
120*4dc78e53SAndroid Build Coastguard Worker 
nl_msg_out_handler_debug(struct nl_msg * msg,void * arg)121*4dc78e53SAndroid Build Coastguard Worker static int nl_msg_out_handler_debug(struct nl_msg *msg, void *arg)
122*4dc78e53SAndroid Build Coastguard Worker {
123*4dc78e53SAndroid Build Coastguard Worker 	FILE *ofd = arg ? arg : stderr;
124*4dc78e53SAndroid Build Coastguard Worker 
125*4dc78e53SAndroid Build Coastguard Worker 	fprintf(ofd, "-- Debug: Sent Message:\n");
126*4dc78e53SAndroid Build Coastguard Worker 	nl_msg_dump(msg, ofd);
127*4dc78e53SAndroid Build Coastguard Worker 
128*4dc78e53SAndroid Build Coastguard Worker 	return NL_OK;
129*4dc78e53SAndroid Build Coastguard Worker }
130*4dc78e53SAndroid Build Coastguard Worker 
nl_skipped_handler_debug(struct nl_msg * msg,void * arg)131*4dc78e53SAndroid Build Coastguard Worker static int nl_skipped_handler_debug(struct nl_msg *msg, void *arg)
132*4dc78e53SAndroid Build Coastguard Worker {
133*4dc78e53SAndroid Build Coastguard Worker 	FILE *ofd = arg ? arg : stderr;
134*4dc78e53SAndroid Build Coastguard Worker 
135*4dc78e53SAndroid Build Coastguard Worker 	fprintf(ofd, "-- Debug: Skipped message: ");
136*4dc78e53SAndroid Build Coastguard Worker 	print_header_content(ofd, nlmsg_hdr(msg));
137*4dc78e53SAndroid Build Coastguard Worker 	fprintf(ofd, "\n");
138*4dc78e53SAndroid Build Coastguard Worker 
139*4dc78e53SAndroid Build Coastguard Worker 	return NL_SKIP;
140*4dc78e53SAndroid Build Coastguard Worker }
141*4dc78e53SAndroid Build Coastguard Worker 
nl_ack_handler_debug(struct nl_msg * msg,void * arg)142*4dc78e53SAndroid Build Coastguard Worker static int nl_ack_handler_debug(struct nl_msg *msg, void *arg)
143*4dc78e53SAndroid Build Coastguard Worker {
144*4dc78e53SAndroid Build Coastguard Worker 	FILE *ofd = arg ? arg : stderr;
145*4dc78e53SAndroid Build Coastguard Worker 
146*4dc78e53SAndroid Build Coastguard Worker 	fprintf(ofd, "-- Debug: ACK: ");
147*4dc78e53SAndroid Build Coastguard Worker 	print_header_content(ofd, nlmsg_hdr(msg));
148*4dc78e53SAndroid Build Coastguard Worker 	fprintf(ofd, "\n");
149*4dc78e53SAndroid Build Coastguard Worker 
150*4dc78e53SAndroid Build Coastguard Worker 	return NL_STOP;
151*4dc78e53SAndroid Build Coastguard Worker }
152*4dc78e53SAndroid Build Coastguard Worker 
153*4dc78e53SAndroid Build Coastguard Worker static nl_recvmsg_msg_cb_t cb_def[NL_CB_TYPE_MAX+1][NL_CB_KIND_MAX+1] = {
154*4dc78e53SAndroid Build Coastguard Worker 	[NL_CB_VALID] = {
155*4dc78e53SAndroid Build Coastguard Worker 		[NL_CB_VERBOSE]	= nl_valid_handler_verbose,
156*4dc78e53SAndroid Build Coastguard Worker 		[NL_CB_DEBUG]	= nl_valid_handler_debug,
157*4dc78e53SAndroid Build Coastguard Worker 	},
158*4dc78e53SAndroid Build Coastguard Worker 	[NL_CB_FINISH] = {
159*4dc78e53SAndroid Build Coastguard Worker 		[NL_CB_DEBUG]	= nl_finish_handler_debug,
160*4dc78e53SAndroid Build Coastguard Worker 	},
161*4dc78e53SAndroid Build Coastguard Worker 	[NL_CB_INVALID] = {
162*4dc78e53SAndroid Build Coastguard Worker 		[NL_CB_VERBOSE]	= nl_invalid_handler_verbose,
163*4dc78e53SAndroid Build Coastguard Worker 		[NL_CB_DEBUG]	= nl_invalid_handler_verbose,
164*4dc78e53SAndroid Build Coastguard Worker 	},
165*4dc78e53SAndroid Build Coastguard Worker 	[NL_CB_MSG_IN] = {
166*4dc78e53SAndroid Build Coastguard Worker 		[NL_CB_DEBUG]	= nl_msg_in_handler_debug,
167*4dc78e53SAndroid Build Coastguard Worker 	},
168*4dc78e53SAndroid Build Coastguard Worker 	[NL_CB_MSG_OUT] = {
169*4dc78e53SAndroid Build Coastguard Worker 		[NL_CB_DEBUG]	= nl_msg_out_handler_debug,
170*4dc78e53SAndroid Build Coastguard Worker 	},
171*4dc78e53SAndroid Build Coastguard Worker 	[NL_CB_OVERRUN] = {
172*4dc78e53SAndroid Build Coastguard Worker 		[NL_CB_VERBOSE]	= nl_overrun_handler_verbose,
173*4dc78e53SAndroid Build Coastguard Worker 		[NL_CB_DEBUG]	= nl_overrun_handler_verbose,
174*4dc78e53SAndroid Build Coastguard Worker 	},
175*4dc78e53SAndroid Build Coastguard Worker 	[NL_CB_SKIPPED] = {
176*4dc78e53SAndroid Build Coastguard Worker 		[NL_CB_DEBUG]	= nl_skipped_handler_debug,
177*4dc78e53SAndroid Build Coastguard Worker 	},
178*4dc78e53SAndroid Build Coastguard Worker 	[NL_CB_ACK] = {
179*4dc78e53SAndroid Build Coastguard Worker 		[NL_CB_DEBUG]	= nl_ack_handler_debug,
180*4dc78e53SAndroid Build Coastguard Worker 	},
181*4dc78e53SAndroid Build Coastguard Worker };
182*4dc78e53SAndroid Build Coastguard Worker 
183*4dc78e53SAndroid Build Coastguard Worker static nl_recvmsg_err_cb_t cb_err_def[NL_CB_KIND_MAX+1] = {
184*4dc78e53SAndroid Build Coastguard Worker 	[NL_CB_VERBOSE]	= nl_error_handler_verbose,
185*4dc78e53SAndroid Build Coastguard Worker 	[NL_CB_DEBUG]	= nl_error_handler_verbose,
186*4dc78e53SAndroid Build Coastguard Worker };
187*4dc78e53SAndroid Build Coastguard Worker 
188*4dc78e53SAndroid Build Coastguard Worker /**
189*4dc78e53SAndroid Build Coastguard Worker  * @name Callback Handle Management
190*4dc78e53SAndroid Build Coastguard Worker  * @{
191*4dc78e53SAndroid Build Coastguard Worker  */
192*4dc78e53SAndroid Build Coastguard Worker 
193*4dc78e53SAndroid Build Coastguard Worker /**
194*4dc78e53SAndroid Build Coastguard Worker  * Allocate a new callback handle
195*4dc78e53SAndroid Build Coastguard Worker  * @arg kind		callback kind to be used for initialization
196*4dc78e53SAndroid Build Coastguard Worker  * @return Newly allocated callback handle or NULL
197*4dc78e53SAndroid Build Coastguard Worker  */
nl_cb_alloc(enum nl_cb_kind kind)198*4dc78e53SAndroid Build Coastguard Worker struct nl_cb *nl_cb_alloc(enum nl_cb_kind kind)
199*4dc78e53SAndroid Build Coastguard Worker {
200*4dc78e53SAndroid Build Coastguard Worker 	int i;
201*4dc78e53SAndroid Build Coastguard Worker 	struct nl_cb *cb;
202*4dc78e53SAndroid Build Coastguard Worker 
203*4dc78e53SAndroid Build Coastguard Worker 	if ((unsigned int) kind > NL_CB_KIND_MAX)
204*4dc78e53SAndroid Build Coastguard Worker 		return NULL;
205*4dc78e53SAndroid Build Coastguard Worker 
206*4dc78e53SAndroid Build Coastguard Worker 	cb = calloc(1, sizeof(*cb));
207*4dc78e53SAndroid Build Coastguard Worker 	if (!cb)
208*4dc78e53SAndroid Build Coastguard Worker 		return NULL;
209*4dc78e53SAndroid Build Coastguard Worker 
210*4dc78e53SAndroid Build Coastguard Worker 	cb->cb_refcnt = 1;
211*4dc78e53SAndroid Build Coastguard Worker 	cb->cb_active = NL_CB_TYPE_MAX + 1;
212*4dc78e53SAndroid Build Coastguard Worker 
213*4dc78e53SAndroid Build Coastguard Worker 	for (i = 0; i <= NL_CB_TYPE_MAX; i++)
214*4dc78e53SAndroid Build Coastguard Worker 		nl_cb_set(cb, i, kind, NULL, NULL);
215*4dc78e53SAndroid Build Coastguard Worker 
216*4dc78e53SAndroid Build Coastguard Worker 	nl_cb_err(cb, kind, NULL, NULL);
217*4dc78e53SAndroid Build Coastguard Worker 
218*4dc78e53SAndroid Build Coastguard Worker 	return cb;
219*4dc78e53SAndroid Build Coastguard Worker }
220*4dc78e53SAndroid Build Coastguard Worker 
221*4dc78e53SAndroid Build Coastguard Worker /**
222*4dc78e53SAndroid Build Coastguard Worker  * Clone an existing callback handle
223*4dc78e53SAndroid Build Coastguard Worker  * @arg orig		original callback handle
224*4dc78e53SAndroid Build Coastguard Worker  * @return Newly allocated callback handle being a duplicate of
225*4dc78e53SAndroid Build Coastguard Worker  *         orig or NULL
226*4dc78e53SAndroid Build Coastguard Worker  */
nl_cb_clone(struct nl_cb * orig)227*4dc78e53SAndroid Build Coastguard Worker struct nl_cb *nl_cb_clone(struct nl_cb *orig)
228*4dc78e53SAndroid Build Coastguard Worker {
229*4dc78e53SAndroid Build Coastguard Worker 	struct nl_cb *cb;
230*4dc78e53SAndroid Build Coastguard Worker 
231*4dc78e53SAndroid Build Coastguard Worker 	cb = nl_cb_alloc(NL_CB_DEFAULT);
232*4dc78e53SAndroid Build Coastguard Worker 	if (!cb)
233*4dc78e53SAndroid Build Coastguard Worker 		return NULL;
234*4dc78e53SAndroid Build Coastguard Worker 
235*4dc78e53SAndroid Build Coastguard Worker 	memcpy(cb, orig, sizeof(*orig));
236*4dc78e53SAndroid Build Coastguard Worker 	cb->cb_refcnt = 1;
237*4dc78e53SAndroid Build Coastguard Worker 
238*4dc78e53SAndroid Build Coastguard Worker 	return cb;
239*4dc78e53SAndroid Build Coastguard Worker }
240*4dc78e53SAndroid Build Coastguard Worker 
nl_cb_get(struct nl_cb * cb)241*4dc78e53SAndroid Build Coastguard Worker struct nl_cb *nl_cb_get(struct nl_cb *cb)
242*4dc78e53SAndroid Build Coastguard Worker {
243*4dc78e53SAndroid Build Coastguard Worker 	cb->cb_refcnt++;
244*4dc78e53SAndroid Build Coastguard Worker 
245*4dc78e53SAndroid Build Coastguard Worker 	return cb;
246*4dc78e53SAndroid Build Coastguard Worker }
247*4dc78e53SAndroid Build Coastguard Worker 
nl_cb_put(struct nl_cb * cb)248*4dc78e53SAndroid Build Coastguard Worker void nl_cb_put(struct nl_cb *cb)
249*4dc78e53SAndroid Build Coastguard Worker {
250*4dc78e53SAndroid Build Coastguard Worker 	if (!cb)
251*4dc78e53SAndroid Build Coastguard Worker 		return;
252*4dc78e53SAndroid Build Coastguard Worker 
253*4dc78e53SAndroid Build Coastguard Worker 	cb->cb_refcnt--;
254*4dc78e53SAndroid Build Coastguard Worker 
255*4dc78e53SAndroid Build Coastguard Worker 	if (cb->cb_refcnt < 0)
256*4dc78e53SAndroid Build Coastguard Worker 		BUG();
257*4dc78e53SAndroid Build Coastguard Worker 
258*4dc78e53SAndroid Build Coastguard Worker 	if (cb->cb_refcnt <= 0)
259*4dc78e53SAndroid Build Coastguard Worker 		free(cb);
260*4dc78e53SAndroid Build Coastguard Worker }
261*4dc78e53SAndroid Build Coastguard Worker 
262*4dc78e53SAndroid Build Coastguard Worker /**
263*4dc78e53SAndroid Build Coastguard Worker  * Obtain type of current active callback
264*4dc78e53SAndroid Build Coastguard Worker  * @arg cb		callback to query
265*4dc78e53SAndroid Build Coastguard Worker  *
266*4dc78e53SAndroid Build Coastguard Worker  * @return type or __NL_CB_TYPE_MAX if none active
267*4dc78e53SAndroid Build Coastguard Worker  */
nl_cb_active_type(struct nl_cb * cb)268*4dc78e53SAndroid Build Coastguard Worker enum nl_cb_type nl_cb_active_type(struct nl_cb *cb)
269*4dc78e53SAndroid Build Coastguard Worker {
270*4dc78e53SAndroid Build Coastguard Worker 	return cb->cb_active;
271*4dc78e53SAndroid Build Coastguard Worker }
272*4dc78e53SAndroid Build Coastguard Worker 
273*4dc78e53SAndroid Build Coastguard Worker /** @} */
274*4dc78e53SAndroid Build Coastguard Worker 
275*4dc78e53SAndroid Build Coastguard Worker /**
276*4dc78e53SAndroid Build Coastguard Worker  * @name Callback Setup
277*4dc78e53SAndroid Build Coastguard Worker  * @{
278*4dc78e53SAndroid Build Coastguard Worker  */
279*4dc78e53SAndroid Build Coastguard Worker 
280*4dc78e53SAndroid Build Coastguard Worker /**
281*4dc78e53SAndroid Build Coastguard Worker  * Set up a callback
282*4dc78e53SAndroid Build Coastguard Worker  * @arg cb		callback set
283*4dc78e53SAndroid Build Coastguard Worker  * @arg type		callback to modify
284*4dc78e53SAndroid Build Coastguard Worker  * @arg kind		kind of implementation
285*4dc78e53SAndroid Build Coastguard Worker  * @arg func		callback function (NL_CB_CUSTOM)
286*4dc78e53SAndroid Build Coastguard Worker  * @arg arg		argument passed to callback
287*4dc78e53SAndroid Build Coastguard Worker  *
288*4dc78e53SAndroid Build Coastguard Worker  * @return 0 on success or a negative error code
289*4dc78e53SAndroid Build Coastguard Worker  */
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)290*4dc78e53SAndroid Build Coastguard Worker int nl_cb_set(struct nl_cb *cb, enum nl_cb_type type, enum nl_cb_kind kind,
291*4dc78e53SAndroid Build Coastguard Worker 	      nl_recvmsg_msg_cb_t func, void *arg)
292*4dc78e53SAndroid Build Coastguard Worker {
293*4dc78e53SAndroid Build Coastguard Worker 	if ((unsigned int) type > NL_CB_TYPE_MAX)
294*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_RANGE;
295*4dc78e53SAndroid Build Coastguard Worker 
296*4dc78e53SAndroid Build Coastguard Worker 	if ((unsigned int) kind > NL_CB_KIND_MAX)
297*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_RANGE;
298*4dc78e53SAndroid Build Coastguard Worker 
299*4dc78e53SAndroid Build Coastguard Worker 	if (kind == NL_CB_CUSTOM) {
300*4dc78e53SAndroid Build Coastguard Worker 		cb->cb_set[type] = func;
301*4dc78e53SAndroid Build Coastguard Worker 		cb->cb_args[type] = arg;
302*4dc78e53SAndroid Build Coastguard Worker 	} else {
303*4dc78e53SAndroid Build Coastguard Worker 		cb->cb_set[type] = cb_def[type][kind];
304*4dc78e53SAndroid Build Coastguard Worker 		cb->cb_args[type] = arg;
305*4dc78e53SAndroid Build Coastguard Worker 	}
306*4dc78e53SAndroid Build Coastguard Worker 
307*4dc78e53SAndroid Build Coastguard Worker 	return 0;
308*4dc78e53SAndroid Build Coastguard Worker }
309*4dc78e53SAndroid Build Coastguard Worker 
310*4dc78e53SAndroid Build Coastguard Worker /**
311*4dc78e53SAndroid Build Coastguard Worker  * Set up a all callbacks
312*4dc78e53SAndroid Build Coastguard Worker  * @arg cb		callback set
313*4dc78e53SAndroid Build Coastguard Worker  * @arg kind		kind of callback
314*4dc78e53SAndroid Build Coastguard Worker  * @arg func		callback function
315*4dc78e53SAndroid Build Coastguard Worker  * @arg arg		argument to be passwd to callback function
316*4dc78e53SAndroid Build Coastguard Worker  *
317*4dc78e53SAndroid Build Coastguard Worker  * @return 0 on success or a negative error code
318*4dc78e53SAndroid Build Coastguard Worker  */
nl_cb_set_all(struct nl_cb * cb,enum nl_cb_kind kind,nl_recvmsg_msg_cb_t func,void * arg)319*4dc78e53SAndroid Build Coastguard Worker int nl_cb_set_all(struct nl_cb *cb, enum nl_cb_kind kind,
320*4dc78e53SAndroid Build Coastguard Worker 		  nl_recvmsg_msg_cb_t func, void *arg)
321*4dc78e53SAndroid Build Coastguard Worker {
322*4dc78e53SAndroid Build Coastguard Worker 	int i, err;
323*4dc78e53SAndroid Build Coastguard Worker 
324*4dc78e53SAndroid Build Coastguard Worker 	for (i = 0; i <= NL_CB_TYPE_MAX; i++) {
325*4dc78e53SAndroid Build Coastguard Worker 		err = nl_cb_set(cb, i, kind, func, arg);
326*4dc78e53SAndroid Build Coastguard Worker 		if (err < 0)
327*4dc78e53SAndroid Build Coastguard Worker 			return err;
328*4dc78e53SAndroid Build Coastguard Worker 	}
329*4dc78e53SAndroid Build Coastguard Worker 
330*4dc78e53SAndroid Build Coastguard Worker 	return 0;
331*4dc78e53SAndroid Build Coastguard Worker }
332*4dc78e53SAndroid Build Coastguard Worker 
333*4dc78e53SAndroid Build Coastguard Worker /**
334*4dc78e53SAndroid Build Coastguard Worker  * Set up an error callback
335*4dc78e53SAndroid Build Coastguard Worker  * @arg cb		callback set
336*4dc78e53SAndroid Build Coastguard Worker  * @arg kind		kind of callback
337*4dc78e53SAndroid Build Coastguard Worker  * @arg func		callback function
338*4dc78e53SAndroid Build Coastguard Worker  * @arg arg		argument to be passed to callback function
339*4dc78e53SAndroid Build Coastguard Worker  */
nl_cb_err(struct nl_cb * cb,enum nl_cb_kind kind,nl_recvmsg_err_cb_t func,void * arg)340*4dc78e53SAndroid Build Coastguard Worker int nl_cb_err(struct nl_cb *cb, enum nl_cb_kind kind,
341*4dc78e53SAndroid Build Coastguard Worker 	      nl_recvmsg_err_cb_t func, void *arg)
342*4dc78e53SAndroid Build Coastguard Worker {
343*4dc78e53SAndroid Build Coastguard Worker 	if ((unsigned int) kind > NL_CB_KIND_MAX)
344*4dc78e53SAndroid Build Coastguard Worker 		return -NLE_RANGE;
345*4dc78e53SAndroid Build Coastguard Worker 
346*4dc78e53SAndroid Build Coastguard Worker 	if (kind == NL_CB_CUSTOM) {
347*4dc78e53SAndroid Build Coastguard Worker 		cb->cb_err = func;
348*4dc78e53SAndroid Build Coastguard Worker 		cb->cb_err_arg = arg;
349*4dc78e53SAndroid Build Coastguard Worker 	} else {
350*4dc78e53SAndroid Build Coastguard Worker 		cb->cb_err = cb_err_def[kind];
351*4dc78e53SAndroid Build Coastguard Worker 		cb->cb_err_arg = arg;
352*4dc78e53SAndroid Build Coastguard Worker 	}
353*4dc78e53SAndroid Build Coastguard Worker 
354*4dc78e53SAndroid Build Coastguard Worker 	return 0;
355*4dc78e53SAndroid Build Coastguard Worker }
356*4dc78e53SAndroid Build Coastguard Worker 
357*4dc78e53SAndroid Build Coastguard Worker /** @} */
358*4dc78e53SAndroid Build Coastguard Worker 
359*4dc78e53SAndroid Build Coastguard Worker /**
360*4dc78e53SAndroid Build Coastguard Worker  * @name Overwriting
361*4dc78e53SAndroid Build Coastguard Worker  * @{
362*4dc78e53SAndroid Build Coastguard Worker  */
363*4dc78e53SAndroid Build Coastguard Worker 
364*4dc78e53SAndroid Build Coastguard Worker /**
365*4dc78e53SAndroid Build Coastguard Worker  * Overwrite internal calls to nl_recvmsgs()
366*4dc78e53SAndroid Build Coastguard Worker  * @arg cb		callback set
367*4dc78e53SAndroid Build Coastguard Worker  * @arg func		replacement callback for nl_recvmsgs()
368*4dc78e53SAndroid Build Coastguard Worker  */
nl_cb_overwrite_recvmsgs(struct nl_cb * cb,int (* func)(struct nl_sock *,struct nl_cb *))369*4dc78e53SAndroid Build Coastguard Worker void nl_cb_overwrite_recvmsgs(struct nl_cb *cb,
370*4dc78e53SAndroid Build Coastguard Worker 			      int (*func)(struct nl_sock *, struct nl_cb *))
371*4dc78e53SAndroid Build Coastguard Worker {
372*4dc78e53SAndroid Build Coastguard Worker 	cb->cb_recvmsgs_ow = func;
373*4dc78e53SAndroid Build Coastguard Worker }
374*4dc78e53SAndroid Build Coastguard Worker 
375*4dc78e53SAndroid Build Coastguard Worker /**
376*4dc78e53SAndroid Build Coastguard Worker  * Overwrite internal calls to nl_recv()
377*4dc78e53SAndroid Build Coastguard Worker  * @arg cb		callback set
378*4dc78e53SAndroid Build Coastguard Worker  * @arg func		replacement callback for nl_recv()
379*4dc78e53SAndroid Build Coastguard Worker  */
nl_cb_overwrite_recv(struct nl_cb * cb,int (* func)(struct nl_sock *,struct sockaddr_nl *,unsigned char **,struct ucred **))380*4dc78e53SAndroid Build Coastguard Worker void nl_cb_overwrite_recv(struct nl_cb *cb,
381*4dc78e53SAndroid Build Coastguard Worker 			  int (*func)(struct nl_sock *, struct sockaddr_nl *,
382*4dc78e53SAndroid Build Coastguard Worker 				      unsigned char **, struct ucred **))
383*4dc78e53SAndroid Build Coastguard Worker {
384*4dc78e53SAndroid Build Coastguard Worker 	cb->cb_recv_ow = func;
385*4dc78e53SAndroid Build Coastguard Worker }
386*4dc78e53SAndroid Build Coastguard Worker 
387*4dc78e53SAndroid Build Coastguard Worker /**
388*4dc78e53SAndroid Build Coastguard Worker  * Overwrite internal calls to nl_send()
389*4dc78e53SAndroid Build Coastguard Worker  * @arg cb		callback set
390*4dc78e53SAndroid Build Coastguard Worker  * @arg func		replacement callback for nl_send()
391*4dc78e53SAndroid Build Coastguard Worker  */
nl_cb_overwrite_send(struct nl_cb * cb,int (* func)(struct nl_sock *,struct nl_msg *))392*4dc78e53SAndroid Build Coastguard Worker void nl_cb_overwrite_send(struct nl_cb *cb,
393*4dc78e53SAndroid Build Coastguard Worker 			  int (*func)(struct nl_sock *, struct nl_msg *))
394*4dc78e53SAndroid Build Coastguard Worker {
395*4dc78e53SAndroid Build Coastguard Worker 	cb->cb_send_ow = func;
396*4dc78e53SAndroid Build Coastguard Worker }
397*4dc78e53SAndroid Build Coastguard Worker 
398*4dc78e53SAndroid Build Coastguard Worker /** @} */
399*4dc78e53SAndroid Build Coastguard Worker 
400*4dc78e53SAndroid Build Coastguard Worker /** @} */
401