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