7fb53b4eeefe5dba27002c644c9029b75a9749a6
[openwrt.git] / package / libnl-tiny / src / include / netlink / handlers.h
1 /*
2  * netlink/handlers.c   default netlink message handlers
3  *
4  *      This library is free software; you can redistribute it and/or
5  *      modify it under the terms of the GNU Lesser General Public
6  *      License as published by the Free Software Foundation version 2.1
7  *      of the License.
8  *
9  * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
10  */
11
12 #ifndef NETLINK_HANDLERS_H_
13 #define NETLINK_HANDLERS_H_
14
15 #include <stdio.h>
16 #include <stdint.h>
17 #include <sys/types.h>
18 #include <netlink/netlink-compat.h>
19 #include <netlink/netlink-kernel.h>
20 #include <netlink/types.h>
21
22 #ifdef __cplusplus
23 extern "C" {
24 #endif
25
26 struct nl_sock;
27 struct nl_msg;
28 struct nl_cb;
29 /**
30  * @name Callback Typedefs
31  * @{
32  */
33
34 /**
35  * nl_recvmsgs() callback for message processing customization
36  * @ingroup cb
37  * @arg msg             netlink message being processed
38  * @arg arg             argument passwd on through caller
39  */
40 typedef int (*nl_recvmsg_msg_cb_t)(struct nl_msg *msg, void *arg);
41
42 /**
43  * nl_recvmsgs() callback for error message processing customization
44  * @ingroup cb
45  * @arg nla             netlink address of the peer
46  * @arg nlerr           netlink error message being processed
47  * @arg arg             argument passed on through caller
48  */
49 typedef int (*nl_recvmsg_err_cb_t)(struct sockaddr_nl *nla,
50                                    struct nlmsgerr *nlerr, void *arg);
51
52 /** @} */
53
54 /**
55  * Callback actions
56  * @ingroup cb
57  */
58 enum nl_cb_action {
59         /** Proceed with wathever would come next */
60         NL_OK,
61         /** Skip this message */
62         NL_SKIP,
63         /** Stop parsing altogether and discard remaining messages */
64         NL_STOP,
65 };
66
67 /**
68  * Callback kinds
69  * @ingroup cb
70  */
71 enum nl_cb_kind {
72         /** Default handlers (quiet) */
73         NL_CB_DEFAULT,
74         /** Verbose default handlers (error messages printed) */
75         NL_CB_VERBOSE,
76         /** Debug handlers for debugging */
77         NL_CB_DEBUG,
78         /** Customized handler specified by the user */
79         NL_CB_CUSTOM,
80         __NL_CB_KIND_MAX,
81 };
82
83 #define NL_CB_KIND_MAX (__NL_CB_KIND_MAX - 1)
84
85 /**
86  * Callback types
87  * @ingroup cb
88  */
89 enum nl_cb_type {
90         /** Message is valid */
91         NL_CB_VALID,
92         /** Last message in a series of multi part messages received */
93         NL_CB_FINISH,
94         /** Report received that data was lost */
95         NL_CB_OVERRUN,
96         /** Message wants to be skipped */
97         NL_CB_SKIPPED,
98         /** Message is an acknowledge */
99         NL_CB_ACK,
100         /** Called for every message received */
101         NL_CB_MSG_IN,
102         /** Called for every message sent out except for nl_sendto() */
103         NL_CB_MSG_OUT,
104         /** Message is malformed and invalid */
105         NL_CB_INVALID,
106         /** Called instead of internal sequence number checking */
107         NL_CB_SEQ_CHECK,
108         /** Sending of an acknowledge message has been requested */
109         NL_CB_SEND_ACK,
110         __NL_CB_TYPE_MAX,
111 };
112
113 #define NL_CB_TYPE_MAX (__NL_CB_TYPE_MAX - 1)
114
115 struct nl_cb
116 {
117         nl_recvmsg_msg_cb_t     cb_set[NL_CB_TYPE_MAX+1];
118         void *                  cb_args[NL_CB_TYPE_MAX+1];
119         
120         nl_recvmsg_err_cb_t     cb_err;
121         void *                  cb_err_arg;
122
123         /** May be used to replace nl_recvmsgs with your own implementation
124          * in all internal calls to nl_recvmsgs. */
125         int                     (*cb_recvmsgs_ow)(struct nl_sock *,
126                                                   struct nl_cb *);
127
128         /** Overwrite internal calls to nl_recv, must return the number of
129          * octets read and allocate a buffer for the received data. */
130         int                     (*cb_recv_ow)(struct nl_sock *,
131                                               struct sockaddr_nl *,
132                                               unsigned char **,
133                                               struct ucred **);
134
135         /** Overwrites internal calls to nl_send, must send the netlink
136          * message. */
137         int                     (*cb_send_ow)(struct nl_sock *,
138                                               struct nl_msg *);
139
140         int                     cb_refcnt;
141 };
142
143
144 extern struct nl_cb *   nl_cb_alloc(enum nl_cb_kind);
145 extern struct nl_cb *   nl_cb_clone(struct nl_cb *);
146 extern void             nl_cb_put(struct nl_cb *);
147
148 extern int  nl_cb_set(struct nl_cb *, enum nl_cb_type, enum nl_cb_kind,
149                       nl_recvmsg_msg_cb_t, void *);
150 extern int  nl_cb_err(struct nl_cb *, enum nl_cb_kind, nl_recvmsg_err_cb_t,
151                       void *);
152
153 static inline struct nl_cb *nl_cb_get(struct nl_cb *cb)
154 {
155         cb->cb_refcnt++;
156
157         return cb;
158 }
159
160 /**
161  * Set up a all callbacks
162  * @arg cb              callback set
163  * @arg kind            kind of callback
164  * @arg func            callback function
165  * @arg arg             argument to be passwd to callback function
166  *
167  * @return 0 on success or a negative error code
168  */
169 static inline int nl_cb_set_all(struct nl_cb *cb, enum nl_cb_kind kind,
170                   nl_recvmsg_msg_cb_t func, void *arg)
171 {
172         int i, err;
173
174         for (i = 0; i <= NL_CB_TYPE_MAX; i++) {
175                 err = nl_cb_set(cb,(enum nl_cb_type)i, kind, func, arg);
176                 if (err < 0)
177                         return err;
178         }
179
180         return 0;
181 }
182
183
184 /**
185  * @name Overwriting
186  * @{
187  */
188
189 /**
190  * Overwrite internal calls to nl_recvmsgs()
191  * @arg cb              callback set
192  * @arg func            replacement callback for nl_recvmsgs()
193  */
194 static inline void nl_cb_overwrite_recvmsgs(struct nl_cb *cb,
195                               int (*func)(struct nl_sock *, struct nl_cb *))
196 {
197         cb->cb_recvmsgs_ow = func;
198 }
199
200 /**
201  * Overwrite internal calls to nl_recv()
202  * @arg cb              callback set
203  * @arg func            replacement callback for nl_recv()
204  */
205 static inline void nl_cb_overwrite_recv(struct nl_cb *cb,
206                           int (*func)(struct nl_sock *, struct sockaddr_nl *,
207                                       unsigned char **, struct ucred **))
208 {
209         cb->cb_recv_ow = func;
210 }
211
212 /**
213  * Overwrite internal calls to nl_send()
214  * @arg cb              callback set
215  * @arg func            replacement callback for nl_send()
216  */
217 static inline void nl_cb_overwrite_send(struct nl_cb *cb,
218                           int (*func)(struct nl_sock *, struct nl_msg *))
219 {
220         cb->cb_send_ow = func;
221 }
222
223 /** @} */
224
225
226 #ifdef __cplusplus
227 }
228 #endif
229
230 #endif