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 char buf[256];
00138
00139 fprintf(ofd, "-- Error received: %s\n-- Original message: ",
00140 strerror_r(-e->error, buf, sizeof(buf)));
00141 print_header_content(ofd, &e->msg);
00142 fprintf(ofd, "\n");
00143
00144 return e->error;
00145 }
00146
00147 static int nl_valid_handler_debug(struct nl_msg *msg, void *arg)
00148 {
00149 FILE *ofd = arg ? arg : stderr;
00150
00151 fprintf(ofd, "-- Debug: Unhandled Valid message: ");
00152 print_header_content(ofd, nlmsg_hdr(msg));
00153 fprintf(ofd, "\n");
00154
00155 return NL_OK;
00156 }
00157
00158 static int nl_finish_handler_debug(struct nl_msg *msg, void *arg)
00159 {
00160 FILE *ofd = arg ? arg : stderr;
00161
00162 fprintf(ofd, "-- Debug: End of multipart message block: ");
00163 print_header_content(ofd, nlmsg_hdr(msg));
00164 fprintf(ofd, "\n");
00165
00166 return NL_STOP;
00167 }
00168
00169 static int nl_msg_in_handler_debug(struct nl_msg *msg, void *arg)
00170 {
00171 FILE *ofd = arg ? arg : stderr;
00172
00173 fprintf(ofd, "-- Debug: Received Message:\n");
00174 nl_msg_dump(msg, ofd);
00175
00176 return NL_OK;
00177 }
00178
00179 static int nl_msg_out_handler_debug(struct nl_msg *msg, void *arg)
00180 {
00181 FILE *ofd = arg ? arg : stderr;
00182
00183 fprintf(ofd, "-- Debug: Sent Message:\n");
00184 nl_msg_dump(msg, ofd);
00185
00186 return NL_OK;
00187 }
00188
00189 static int nl_skipped_handler_debug(struct nl_msg *msg, void *arg)
00190 {
00191 FILE *ofd = arg ? arg : stderr;
00192
00193 fprintf(ofd, "-- Debug: Skipped message: ");
00194 print_header_content(ofd, nlmsg_hdr(msg));
00195 fprintf(ofd, "\n");
00196
00197 return NL_SKIP;
00198 }
00199
00200 static int nl_ack_handler_debug(struct nl_msg *msg, void *arg)
00201 {
00202 FILE *ofd = arg ? arg : stderr;
00203
00204 fprintf(ofd, "-- Debug: ACK: ");
00205 print_header_content(ofd, nlmsg_hdr(msg));
00206 fprintf(ofd, "\n");
00207
00208 return NL_STOP;
00209 }
00210
00211 static nl_recvmsg_msg_cb_t cb_def[NL_CB_TYPE_MAX+1][NL_CB_KIND_MAX+1] = {
00212 [NL_CB_VALID] = {
00213 [NL_CB_VERBOSE] = nl_valid_handler_verbose,
00214 [NL_CB_DEBUG] = nl_valid_handler_debug,
00215 },
00216 [NL_CB_FINISH] = {
00217 [NL_CB_DEBUG] = nl_finish_handler_debug,
00218 },
00219 [NL_CB_INVALID] = {
00220 [NL_CB_VERBOSE] = nl_invalid_handler_verbose,
00221 [NL_CB_DEBUG] = nl_invalid_handler_verbose,
00222 },
00223 [NL_CB_MSG_IN] = {
00224 [NL_CB_DEBUG] = nl_msg_in_handler_debug,
00225 },
00226 [NL_CB_MSG_OUT] = {
00227 [NL_CB_DEBUG] = nl_msg_out_handler_debug,
00228 },
00229 [NL_CB_OVERRUN] = {
00230 [NL_CB_VERBOSE] = nl_overrun_handler_verbose,
00231 [NL_CB_DEBUG] = nl_overrun_handler_verbose,
00232 },
00233 [NL_CB_SKIPPED] = {
00234 [NL_CB_DEBUG] = nl_skipped_handler_debug,
00235 },
00236 [NL_CB_ACK] = {
00237 [NL_CB_DEBUG] = nl_ack_handler_debug,
00238 },
00239 };
00240
00241 static nl_recvmsg_err_cb_t cb_err_def[NL_CB_KIND_MAX+1] = {
00242 [NL_CB_VERBOSE] = nl_error_handler_verbose,
00243 [NL_CB_DEBUG] = nl_error_handler_verbose,
00244 };
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256 struct nl_cb *nl_cb_alloc(enum nl_cb_kind kind)
00257 {
00258 int i;
00259 struct nl_cb *cb;
00260
00261 if (kind < 0 || kind > NL_CB_KIND_MAX)
00262 return NULL;
00263
00264 cb = calloc(1, sizeof(*cb));
00265 if (!cb) {
00266 nl_errno(ENOMEM);
00267 return NULL;
00268 }
00269
00270 cb->cb_refcnt = 1;
00271
00272 for (i = 0; i <= NL_CB_TYPE_MAX; i++)
00273 nl_cb_set(cb, i, kind, NULL, NULL);
00274
00275 nl_cb_err(cb, kind, NULL, NULL);
00276
00277 return cb;
00278 }
00279
00280
00281
00282
00283
00284
00285
00286 struct nl_cb *nl_cb_clone(struct nl_cb *orig)
00287 {
00288 struct nl_cb *cb;
00289
00290 cb = nl_cb_alloc(NL_CB_DEFAULT);
00291 if (!cb)
00292 return NULL;
00293
00294 memcpy(cb, orig, sizeof(*orig));
00295 cb->cb_refcnt = 1;
00296
00297 return cb;
00298 }
00299
00300 struct nl_cb *nl_cb_get(struct nl_cb *cb)
00301 {
00302 cb->cb_refcnt++;
00303
00304 return cb;
00305 }
00306
00307 void nl_cb_put(struct nl_cb *cb)
00308 {
00309 if (!cb)
00310 return;
00311
00312 cb->cb_refcnt--;
00313
00314 if (cb->cb_refcnt < 0)
00315 BUG();
00316
00317 if (cb->cb_refcnt <= 0)
00318 free(cb);
00319 }
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338 int nl_cb_set(struct nl_cb *cb, enum nl_cb_type type, enum nl_cb_kind kind,
00339 nl_recvmsg_msg_cb_t func, void *arg)
00340 {
00341 if (type < 0 || type > NL_CB_TYPE_MAX)
00342 return nl_error(ERANGE, "Callback type out of range");
00343
00344 if (kind < 0 || kind > NL_CB_KIND_MAX)
00345 return nl_error(ERANGE, "Callback kind out of range");
00346
00347 if (kind == NL_CB_CUSTOM) {
00348 cb->cb_set[type] = func;
00349 cb->cb_args[type] = arg;
00350 } else {
00351 cb->cb_set[type] = cb_def[type][kind];
00352 cb->cb_args[type] = arg;
00353 }
00354
00355 return 0;
00356 }
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367 int nl_cb_set_all(struct nl_cb *cb, enum nl_cb_kind kind,
00368 nl_recvmsg_msg_cb_t func, void *arg)
00369 {
00370 int i, err;
00371
00372 for (i = 0; i <= NL_CB_TYPE_MAX; i++) {
00373 err = nl_cb_set(cb, i, kind, func, arg);
00374 if (err < 0)
00375 return err;
00376 }
00377
00378 return 0;
00379 }
00380
00381
00382
00383
00384
00385
00386
00387
00388 int nl_cb_err(struct nl_cb *cb, enum nl_cb_kind kind,
00389 nl_recvmsg_err_cb_t func, void *arg)
00390 {
00391 if (kind < 0 || kind > NL_CB_KIND_MAX)
00392 return nl_error(ERANGE, "Callback kind out of range");
00393
00394 if (kind == NL_CB_CUSTOM) {
00395 cb->cb_err = func;
00396 cb->cb_err_arg = arg;
00397 } else {
00398 cb->cb_err = cb_err_def[kind];
00399 cb->cb_err_arg = arg;
00400 }
00401
00402 return 0;
00403 }
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416
00417 void nl_cb_overwrite_recvmsgs(struct nl_cb *cb,
00418 int (*func)(struct nl_handle *, struct nl_cb *))
00419 {
00420 cb->cb_recvmsgs_ow = func;
00421 }
00422
00423
00424
00425
00426
00427
00428 void nl_cb_overwrite_recv(struct nl_cb *cb,
00429 int (*func)(struct nl_handle *, struct sockaddr_nl *,
00430 unsigned char **, struct ucred **))
00431 {
00432 cb->cb_recv_ow = func;
00433 }
00434
00435
00436
00437
00438
00439
00440 void nl_cb_overwrite_send(struct nl_cb *cb,
00441 int (*func)(struct nl_handle *, struct nl_msg *))
00442 {
00443 cb->cb_send_ow = func;
00444 }
00445
00446
00447
00448