00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 #include <netlink-local.h>
00084 #include <netlink/netlink.h>
00085 #include <netlink/utils.h>
00086 #include <netlink/msg.h>
00087 #include <netlink/handlers.h>
00088
00089 static void print_header_content(FILE *ofd, struct nlmsghdr *n)
00090 {
00091 char flags[128];
00092 char type[32];
00093
00094 fprintf(ofd, "type=%s length=%u flags=<%s> sequence-nr=%u pid=%u",
00095 nl_nlmsgtype2str(n->nlmsg_type, type, sizeof(type)),
00096 n->nlmsg_len, nl_nlmsg_flags2str(n->nlmsg_flags, flags,
00097 sizeof(flags)), n->nlmsg_seq, n->nlmsg_pid);
00098 }
00099
00100 static int nl_valid_handler_verbose(struct nl_msg *msg, void *arg)
00101 {
00102 FILE *ofd = arg ? arg : stdout;
00103
00104 fprintf(ofd, "-- Warning: unhandled valid message: ");
00105 print_header_content(ofd, nlmsg_hdr(msg));
00106 fprintf(ofd, "\n");
00107
00108 return NL_OK;
00109 }
00110
00111 static int nl_invalid_handler_verbose(struct nl_msg *msg, void *arg)
00112 {
00113 FILE *ofd = arg ? arg : stderr;
00114
00115 fprintf(ofd, "-- Error: Invalid message: ");
00116 print_header_content(ofd, nlmsg_hdr(msg));
00117 fprintf(ofd, "\n");
00118
00119 return NL_STOP;
00120 }
00121
00122 static int nl_overrun_handler_verbose(struct nl_msg *msg, void *arg)
00123 {
00124 FILE *ofd = arg ? arg : stderr;
00125
00126 fprintf(ofd, "-- Error: Netlink Overrun: ");
00127 print_header_content(ofd, nlmsg_hdr(msg));
00128 fprintf(ofd, "\n");
00129
00130 return NL_STOP;
00131 }
00132
00133 static int nl_error_handler_verbose(struct sockaddr_nl *who,
00134 struct nlmsgerr *e, void *arg)
00135 {
00136 FILE *ofd = arg ? arg : stderr;
00137
00138 fprintf(ofd, "-- Error received: %s\n-- Original message: ",
00139 strerror(-e->error));
00140 print_header_content(ofd, &e->msg);
00141 fprintf(ofd, "\n");
00142
00143 return e->error;
00144 }
00145
00146 static int nl_valid_handler_debug(struct nl_msg *msg, void *arg)
00147 {
00148 FILE *ofd = arg ? arg : stderr;
00149
00150 fprintf(ofd, "-- Debug: Unhandled Valid message: ");
00151 print_header_content(ofd, nlmsg_hdr(msg));
00152 fprintf(ofd, "\n");
00153
00154 return NL_OK;
00155 }
00156
00157 static int nl_finish_handler_debug(struct nl_msg *msg, void *arg)
00158 {
00159 FILE *ofd = arg ? arg : stderr;
00160
00161 fprintf(ofd, "-- Debug: End of multipart message block: ");
00162 print_header_content(ofd, nlmsg_hdr(msg));
00163 fprintf(ofd, "\n");
00164
00165 return NL_STOP;
00166 }
00167
00168 static int nl_msg_in_handler_debug(struct nl_msg *msg, void *arg)
00169 {
00170 FILE *ofd = arg ? arg : stderr;
00171
00172 fprintf(ofd, "-- Debug: Received Message:\n");
00173 nl_msg_dump(msg, ofd);
00174
00175 return NL_OK;
00176 }
00177
00178 static int nl_msg_out_handler_debug(struct nl_msg *msg, void *arg)
00179 {
00180 FILE *ofd = arg ? arg : stderr;
00181
00182 fprintf(ofd, "-- Debug: Sent Message:\n");
00183 nl_msg_dump(msg, ofd);
00184
00185 return NL_OK;
00186 }
00187
00188 static int nl_skipped_handler_debug(struct nl_msg *msg, void *arg)
00189 {
00190 FILE *ofd = arg ? arg : stderr;
00191
00192 fprintf(ofd, "-- Debug: Skipped message: ");
00193 print_header_content(ofd, nlmsg_hdr(msg));
00194 fprintf(ofd, "\n");
00195
00196 return NL_SKIP;
00197 }
00198
00199 static int nl_ack_handler_debug(struct nl_msg *msg, void *arg)
00200 {
00201 FILE *ofd = arg ? arg : stderr;
00202
00203 fprintf(ofd, "-- Debug: ACK: ");
00204 print_header_content(ofd, nlmsg_hdr(msg));
00205 fprintf(ofd, "\n");
00206
00207 return NL_STOP;
00208 }
00209
00210 static nl_recvmsg_msg_cb_t cb_def[NL_CB_TYPE_MAX+1][NL_CB_KIND_MAX+1] = {
00211 [NL_CB_VALID] = {
00212 [NL_CB_VERBOSE] = nl_valid_handler_verbose,
00213 [NL_CB_DEBUG] = nl_valid_handler_debug,
00214 },
00215 [NL_CB_FINISH] = {
00216 [NL_CB_DEBUG] = nl_finish_handler_debug,
00217 },
00218 [NL_CB_INVALID] = {
00219 [NL_CB_VERBOSE] = nl_invalid_handler_verbose,
00220 [NL_CB_DEBUG] = nl_invalid_handler_verbose,
00221 },
00222 [NL_CB_MSG_IN] = {
00223 [NL_CB_DEBUG] = nl_msg_in_handler_debug,
00224 },
00225 [NL_CB_MSG_OUT] = {
00226 [NL_CB_DEBUG] = nl_msg_out_handler_debug,
00227 },
00228 [NL_CB_OVERRUN] = {
00229 [NL_CB_VERBOSE] = nl_overrun_handler_verbose,
00230 [NL_CB_DEBUG] = nl_overrun_handler_verbose,
00231 },
00232 [NL_CB_SKIPPED] = {
00233 [NL_CB_DEBUG] = nl_skipped_handler_debug,
00234 },
00235 [NL_CB_ACK] = {
00236 [NL_CB_DEBUG] = nl_ack_handler_debug,
00237 },
00238 };
00239
00240 static nl_recvmsg_err_cb_t cb_err_def[NL_CB_KIND_MAX+1] = {
00241 [NL_CB_VERBOSE] = nl_error_handler_verbose,
00242 [NL_CB_DEBUG] = nl_error_handler_verbose,
00243 };
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255 struct nl_cb *nl_cb_alloc(enum nl_cb_kind kind)
00256 {
00257 int i;
00258 struct nl_cb *cb;
00259
00260 if (kind < 0 || kind > NL_CB_KIND_MAX)
00261 return NULL;
00262
00263 cb = calloc(1, sizeof(*cb));
00264 if (!cb) {
00265 nl_errno(ENOMEM);
00266 return NULL;
00267 }
00268
00269 cb->cb_refcnt = 1;
00270
00271 for (i = 0; i <= NL_CB_TYPE_MAX; i++)
00272 nl_cb_set(cb, i, kind, NULL, NULL);
00273
00274 nl_cb_err(cb, kind, NULL, NULL);
00275
00276 return cb;
00277 }
00278
00279
00280
00281
00282
00283
00284
00285 struct nl_cb *nl_cb_clone(struct nl_cb *orig)
00286 {
00287 struct nl_cb *cb;
00288
00289 cb = nl_cb_alloc(NL_CB_DEFAULT);
00290 if (!cb)
00291 return NULL;
00292
00293 memcpy(cb, orig, sizeof(*orig));
00294 cb->cb_refcnt = 1;
00295
00296 return cb;
00297 }
00298
00299 struct nl_cb *nl_cb_get(struct nl_cb *cb)
00300 {
00301 cb->cb_refcnt++;
00302
00303 return cb;
00304 }
00305
00306 void nl_cb_put(struct nl_cb *cb)
00307 {
00308 if (!cb)
00309 return;
00310
00311 cb->cb_refcnt--;
00312
00313 if (cb->cb_refcnt < 0)
00314 BUG();
00315
00316 if (cb->cb_refcnt <= 0)
00317 free(cb);
00318 }
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337 int nl_cb_set(struct nl_cb *cb, enum nl_cb_type type, enum nl_cb_kind kind,
00338 nl_recvmsg_msg_cb_t func, void *arg)
00339 {
00340 if (type < 0 || type > NL_CB_TYPE_MAX)
00341 return nl_error(ERANGE, "Callback type out of range");
00342
00343 if (kind < 0 || kind > NL_CB_KIND_MAX)
00344 return nl_error(ERANGE, "Callback kind out of range");
00345
00346 if (kind == NL_CB_CUSTOM) {
00347 cb->cb_set[type] = func;
00348 cb->cb_args[type] = arg;
00349 } else {
00350 cb->cb_set[type] = cb_def[type][kind];
00351 cb->cb_args[type] = arg;
00352 }
00353
00354 return 0;
00355 }
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366 int nl_cb_set_all(struct nl_cb *cb, enum nl_cb_kind kind,
00367 nl_recvmsg_msg_cb_t func, void *arg)
00368 {
00369 int i, err;
00370
00371 for (i = 0; i <= NL_CB_TYPE_MAX; i++) {
00372 err = nl_cb_set(cb, i, kind, func, arg);
00373 if (err < 0)
00374 return err;
00375 }
00376
00377 return 0;
00378 }
00379
00380
00381
00382
00383
00384
00385
00386
00387 int nl_cb_err(struct nl_cb *cb, enum nl_cb_kind kind,
00388 nl_recvmsg_err_cb_t func, void *arg)
00389 {
00390 if (kind < 0 || kind > NL_CB_KIND_MAX)
00391 return nl_error(ERANGE, "Callback kind out of range");
00392
00393 if (kind == NL_CB_CUSTOM) {
00394 cb->cb_err = func;
00395 cb->cb_err_arg = arg;
00396 } else {
00397 cb->cb_err = cb_err_def[kind];
00398 cb->cb_err_arg = arg;
00399 }
00400
00401 return 0;
00402 }
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416 void nl_cb_overwrite_recvmsgs(struct nl_cb *cb,
00417 int (*func)(struct nl_handle *, struct nl_cb *))
00418 {
00419 cb->cb_recvmsgs_ow = func;
00420 }
00421
00422
00423
00424
00425
00426
00427 void nl_cb_overwrite_recv(struct nl_cb *cb,
00428 int (*func)(struct nl_handle *, struct sockaddr_nl *,
00429 unsigned char **, struct ucred **))
00430 {
00431 cb->cb_recv_ow = func;
00432 }
00433
00434
00435
00436
00437
00438
00439 void nl_cb_overwrite_send(struct nl_cb *cb,
00440 int (*func)(struct nl_handle *, struct nl_msg *))
00441 {
00442 cb->cb_send_ow = func;
00443 }
00444
00445
00446
00447