X-Git-Url: http://git.onelab.eu/?p=libnl.git;a=blobdiff_plain;f=lib%2Fhandlers.c;fp=lib%2Fhandlers.c;h=0000000000000000000000000000000000000000;hp=c433230a6d7352282bac4316e11aa4d0fc79d48d;hb=332c8b7561dcac7ac95cc0d07328b1cb22d780a6;hpb=eabdd897b75ecc1fac5e255229a899126085e57a diff --git a/lib/handlers.c b/lib/handlers.c deleted file mode 100644 index c433230..0000000 --- a/lib/handlers.c +++ /dev/null @@ -1,581 +0,0 @@ -/* - * lib/handlers.c default netlink message handlers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation version 2.1 - * of the License. - * - * Copyright (c) 2003-2006 Thomas Graf - */ - -/** - * @ingroup nl - * @defgroup cb Callbacks/Customization - * - * Customization via callbacks. - * @{ - */ - -#include -#include -#include -#include -#include - -static void print_header_content(FILE *ofd, struct nlmsghdr *n) -{ - char flags[128]; - char type[32]; - - fprintf(ofd, "type=%s length=%u flags=<%s> sequence-nr=%u pid=%u", - nl_nlmsgtype2str(n->nlmsg_type, type, sizeof(type)), - n->nlmsg_len, nl_nlmsg_flags2str(n->nlmsg_flags, flags, - sizeof(flags)), n->nlmsg_seq, n->nlmsg_pid); -} - -static inline void dump_hex(FILE *ofd, char *start, int len) -{ - int i, a, c, limit; - char ascii[21] = {0}; - - limit = 18; - fprintf(ofd, " "); - - for (i = 0, a = 0, c = 0; i < len; i++) { - int v = *(uint8_t *) (start + i); - - fprintf(ofd, "%02x ", v); - ascii[a++] = isprint(v) ? v : '.'; - - if (c == limit-1) { - fprintf(ofd, "%s\n", ascii); - if (i < (len - 1)) - fprintf(ofd, " "); - a = c = 0; - memset(ascii, 0, sizeof(ascii)); - } else - c++; - } - - if (c != 0) { - for (i = 0; i < (limit - c); i++) - fprintf(ofd, " "); - fprintf(ofd, "%s\n", ascii); - } -} - -static void print_hdr(FILE *ofd, struct nl_msg *msg) -{ - struct nlmsghdr *nlh = nlmsg_hdr(msg); - struct nl_cache_ops *ops; - char buf[128]; - - fprintf(ofd, " .nlmsg_len = %d\n", nlh->nlmsg_len); - - ops = nl_cache_mngt_associate(nlmsg_get_proto(msg), nlh->nlmsg_type); - - fprintf(ofd, " .nlmsg_type = %d <%s>\n", nlh->nlmsg_type, - ops ? nl_cache_mngt_type2name(ops, nlh->nlmsg_type, - buf, sizeof(buf)) - : nl_nlmsgtype2str(nlh->nlmsg_type, buf, sizeof(buf))); - fprintf(ofd, " .nlmsg_flags = %d <%s>\n", nlh->nlmsg_flags, - nl_nlmsg_flags2str(nlh->nlmsg_flags, buf, sizeof(buf))); - fprintf(ofd, " .nlmsg_seq = %d\n", nlh->nlmsg_seq); - fprintf(ofd, " .nlmsg_pid = %d\n", nlh->nlmsg_pid); - -} - -static void raw_dump_msg(FILE *ofd, struct nl_msg *msg) -{ - struct nlmsghdr *hdr = nlmsg_hdr(msg); - - fprintf(ofd, - "-------------------------- BEGIN NETLINK MESSAGE " - "---------------------------\n"); - - fprintf(ofd, " [HEADER] %Zu octets\n", sizeof(struct nlmsghdr)); - print_hdr(ofd, msg); - - if (hdr->nlmsg_type == NLMSG_ERROR && - hdr->nlmsg_len >= nlmsg_msg_size(sizeof(struct nlmsgerr))) { - struct nl_msg *errmsg; - struct nlmsgerr *err = nlmsg_data(hdr); - - fprintf(ofd, " [ERRORMSG] %Zu octets\n", sizeof(*err)); - fprintf(ofd, " .error = %d \"%s\"\n", err->error, - strerror(-err->error)); - fprintf(ofd, " [ORIGINAL MESSAGE] %Zu octets\n", sizeof(*hdr)); - - errmsg = nlmsg_build(&err->msg); - print_hdr(ofd, errmsg); - nlmsg_free(msg); - } else if (nlmsg_len(hdr) > 0) { - struct nl_cache_ops *ops; - int payloadlen = nlmsg_len(hdr); - int attrlen = 0; - - ops = nl_cache_mngt_associate(nlmsg_get_proto(msg), - hdr->nlmsg_type); - if (ops) { - attrlen = nlmsg_attrlen(hdr, ops->co_hdrsize); - payloadlen -= attrlen; - } - - fprintf(ofd, " [PAYLOAD] %d octets\n", payloadlen); - dump_hex(ofd, nlmsg_data(hdr), payloadlen); - - if (attrlen) { - int rem, padlen; - struct nlattr *nla; - - nlmsg_for_each_attr(nla, hdr, ops->co_hdrsize, rem) { - int alen = nla_len(nla); - - fprintf(ofd, " [ATTR %02d] %d octets\n", - nla->nla_type, alen); - dump_hex(ofd, nla_data(nla), alen); - - padlen = nla_padlen(alen); - if (padlen > 0) { - fprintf(ofd, " [PADDING] %d octets\n", - padlen); - dump_hex(ofd, nla_data(nla) + alen, - padlen); - } - } - } - } - - fprintf(ofd, - "--------------------------- END NETLINK MESSAGE " - "---------------------------\n"); -} - -static int nl_valid_handler_default(struct nl_msg *msg, void *arg) -{ - return NL_PROCEED; -} - -static int nl_finish_handler_default(struct nl_msg *msg, void *arg) -{ - return NL_EXIT; -} - -static int nl_invalid_handler_default(struct nl_msg *msg, void *arg) -{ - return NL_EXIT; -} - -static int nl_msg_in_handler_default(struct nl_msg *msg, void *arg) -{ - return NL_PROCEED; -} - -static int nl_msg_out_handler_default(struct nl_msg *msg, void *arg) -{ - return NL_PROCEED; -} - -static int nl_overrun_handler_default(struct nl_msg *msg, void *arg) -{ - return NL_EXIT; -} - -static int nl_skipped_handler_default(struct nl_msg *msg, void *arg) -{ - return NL_SKIP; -} - -static int nl_ack_handler_default(struct nl_msg *msg, void *arg) -{ - return NL_EXIT; -} - -static int nl_error_handler_default(struct sockaddr_nl *who, - struct nlmsgerr *e, void *arg) -{ - return NL_EXIT; -} - -static int nl_valid_handler_verbose(struct nl_msg *msg, void *arg) -{ - FILE *ofd = arg ? arg : stdout; - - fprintf(ofd, "-- Warning: unhandled valid message: "); - print_header_content(ofd, nlmsg_hdr(msg)); - fprintf(ofd, "\n"); - - return NL_PROCEED; -} - -static int nl_finish_handler_verbose(struct nl_msg *msg, void *arg) -{ - return NL_EXIT; -} - -static int nl_msg_in_handler_verbose(struct nl_msg *msg, void *arg) -{ - return NL_PROCEED; -} - -static int nl_invalid_handler_verbose(struct nl_msg *msg, void *arg) -{ - FILE *ofd = arg ? arg : stderr; - - fprintf(ofd, "-- Error: Invalid message: "); - print_header_content(ofd, nlmsg_hdr(msg)); - fprintf(ofd, "\n"); - - return NL_EXIT; -} - -static int nl_msg_out_handler_verbose(struct nl_msg *msg, void *arg) -{ - return NL_PROCEED; -} - -static int nl_overrun_handler_verbose(struct nl_msg *msg, void *arg) -{ - FILE *ofd = arg ? arg : stderr; - - fprintf(ofd, "-- Error: Netlink Overrun: "); - print_header_content(ofd, nlmsg_hdr(msg)); - fprintf(ofd, "\n"); - - return NL_EXIT; -} - -static int nl_ack_handler_verbose(struct nl_msg *msg, void *arg) -{ - return NL_EXIT; -} - -static int nl_skipped_handler_verbose(struct nl_msg *msg, void *arg) -{ - return NL_SKIP; -} - -static int nl_error_handler_verbose(struct sockaddr_nl *who, - struct nlmsgerr *e, void *arg) -{ - FILE *ofd = arg ? arg : stderr; - - fprintf(ofd, "-- Error received: %s\n-- Original message: ", - strerror(-e->error)); - print_header_content(ofd, &e->msg); - fprintf(ofd, "\n"); - - return NL_EXIT; -} - -static int nl_valid_handler_debug(struct nl_msg *msg, void *arg) -{ - FILE *ofd = arg ? arg : stderr; - - fprintf(ofd, "-- Debug: Valid message: "); - print_header_content(ofd, nlmsg_hdr(msg)); - fprintf(ofd, "\n"); - - return NL_PROCEED; -} - -static int nl_finish_handler_debug(struct nl_msg *msg, void *arg) -{ - FILE *ofd = arg ? arg : stderr; - - fprintf(ofd, "-- Debug: End of multipart message block: "); - print_header_content(ofd, nlmsg_hdr(msg)); - fprintf(ofd, "\n"); - - return NL_EXIT; -} - -static int nl_invalid_handler_debug(struct nl_msg *msg, void *arg) -{ - return nl_invalid_handler_verbose(msg, arg); -} - -static int nl_msg_in_handler_debug(struct nl_msg *msg, void *arg) -{ - FILE *ofd = arg ? arg : stderr; - - fprintf(ofd, "-- Debug: Received Message:\n"); - raw_dump_msg(ofd, msg); - - return NL_PROCEED; -} - -static int nl_msg_out_handler_debug(struct nl_msg *msg, void *arg) -{ - FILE *ofd = arg ? arg : stderr; - - fprintf(ofd, "-- Debug: Sent Message:\n"); - raw_dump_msg(ofd, msg); - - return NL_PROCEED; -} - -static int nl_overrun_handler_debug(struct nl_msg *msg, void *arg) -{ - return nl_overrun_handler_verbose(msg, arg); -} - -static int nl_skipped_handler_debug(struct nl_msg *msg, void *arg) -{ - FILE *ofd = arg ? arg : stderr; - - fprintf(ofd, "-- Debug: Skipped message: "); - print_header_content(ofd, nlmsg_hdr(msg)); - fprintf(ofd, "\n"); - - return NL_SKIP; -} - -static int nl_ack_handler_debug(struct nl_msg *msg, void *arg) -{ - FILE *ofd = arg ? arg : stderr; - - fprintf(ofd, "-- Debug: ACK: "); - print_header_content(ofd, nlmsg_hdr(msg)); - fprintf(ofd, "\n"); - - return NL_EXIT; -} - -static int nl_error_handler_debug(struct sockaddr_nl *who, - struct nlmsgerr *e, void *arg) -{ - return nl_error_handler_verbose(who, e, arg); -} - -static nl_recvmsg_msg_cb_t cb_def[NL_CB_TYPE_MAX+1][NL_CB_KIND_MAX+1] = { - [NL_CB_VALID] = { - [NL_CB_DEFAULT] = nl_valid_handler_default, - [NL_CB_VERBOSE] = nl_valid_handler_verbose, - [NL_CB_DEBUG] = nl_valid_handler_debug, - }, - [NL_CB_FINISH] = { - [NL_CB_DEFAULT] = nl_finish_handler_default, - [NL_CB_VERBOSE] = nl_finish_handler_verbose, - [NL_CB_DEBUG] = nl_finish_handler_debug, - }, - [NL_CB_INVALID] = { - [NL_CB_DEFAULT] = nl_invalid_handler_default, - [NL_CB_VERBOSE] = nl_invalid_handler_verbose, - [NL_CB_DEBUG] = nl_invalid_handler_debug, - }, - [NL_CB_MSG_IN] = { - [NL_CB_DEFAULT] = nl_msg_in_handler_default, - [NL_CB_VERBOSE] = nl_msg_in_handler_verbose, - [NL_CB_DEBUG] = nl_msg_in_handler_debug, - }, - [NL_CB_MSG_OUT] = { - [NL_CB_DEFAULT] = nl_msg_out_handler_default, - [NL_CB_VERBOSE] = nl_msg_out_handler_verbose, - [NL_CB_DEBUG] = nl_msg_out_handler_debug, - }, - [NL_CB_OVERRUN] = { - [NL_CB_DEFAULT] = nl_overrun_handler_default, - [NL_CB_VERBOSE] = nl_overrun_handler_verbose, - [NL_CB_DEBUG] = nl_overrun_handler_debug, - }, - [NL_CB_SKIPPED] = { - [NL_CB_DEFAULT] = nl_skipped_handler_default, - [NL_CB_VERBOSE] = nl_skipped_handler_verbose, - [NL_CB_DEBUG] = nl_skipped_handler_debug, - }, - [NL_CB_ACK] = { - [NL_CB_DEFAULT] = nl_ack_handler_default, - [NL_CB_VERBOSE] = nl_ack_handler_verbose, - [NL_CB_DEBUG] = nl_ack_handler_debug, - }, -}; - -static nl_recvmsg_err_cb_t cb_err_def[NL_CB_KIND_MAX+1] = { - [NL_CB_DEFAULT] = nl_error_handler_default, - [NL_CB_VERBOSE] = nl_error_handler_verbose, - [NL_CB_DEBUG] = nl_error_handler_debug, -}; - -/** - * @name Callback Handle Management - * @{ - */ - -/** - * Allocate a new callback handle - * @arg kind callback kind to be used for initialization - * @return Newly allocated callback handle or NULL - */ -struct nl_cb *nl_cb_new(enum nl_cb_kind kind) -{ - int i; - struct nl_cb *cb; - - if (kind < 0 || kind > NL_CB_KIND_MAX) - return NULL; - - cb = calloc(1, sizeof(*cb)); - if (!cb) { - nl_errno(ENOMEM); - return NULL; - } - - for (i = 0; i <= NL_CB_TYPE_MAX; i++) - nl_cb_set(cb, i, kind, NULL, NULL); - - nl_cb_err(cb, kind, NULL, NULL); - - return cb; -} - -/** - * Destroy a callback handle - * @arg cb callback handle - */ -void nl_cb_destroy(struct nl_cb *cb) -{ - free(cb); -} - -/** - * Clone an existing callback handle - * @arg orig original callback handle - * @return Newly allocated callback handle being a duplicate of - * orig or NULL - */ -struct nl_cb *nl_cb_clone(struct nl_cb *orig) -{ - struct nl_cb *cb; - - cb = nl_cb_new(NL_CB_DEFAULT); - if (!cb) - return NULL; - - memcpy(cb, orig, sizeof(*orig)); - - return cb; -} - -/** @} */ - -/** - * @name Callback Setup - * @{ - */ - -/** - * Set up a callback - * @arg cb callback configuration - * @arg type which type callback to set - * @arg kind kind of callback - * @arg func callback function - * @arg arg argument to be passwd to callback function - * - * @return 0 on success or a negative error code - */ -int 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) -{ - if (type < 0 || type > NL_CB_TYPE_MAX) - return nl_error(ERANGE, "Callback type out of range"); - - if (kind < 0 || kind > NL_CB_KIND_MAX) - return nl_error(ERANGE, "Callback kind out of range"); - - if (kind == NL_CB_CUSTOM) { - cb->cb_set[type] = func; - cb->cb_args[type] = arg; - } else { - cb->cb_set[type] = cb_def[type][kind]; - cb->cb_args[type] = arg; - } - - return 0; -} - -/** - * Set up a all callbacks - * @arg cb callback configuration - * @arg kind kind of callback - * @arg func callback function - * @arg arg argument to be passwd to callback function - * - * @return 0 on success or a negative error code - */ -int nl_cb_set_all(struct nl_cb *cb, enum nl_cb_kind kind, - nl_recvmsg_msg_cb_t func, void *arg) -{ - int i, err; - - for (i = 0; i <= NL_CB_TYPE_MAX; i++) { - err = nl_cb_set(cb, i, kind, func, arg); - if (err < 0) - return err; - } - - return 0; -} - -/** - * Set up an error callback - * @arg cb callback configuration - * @arg kind kind of callback - * @arg func callback function - * @arg arg argument to be passed to callback function - */ -int nl_cb_err(struct nl_cb *cb, enum nl_cb_kind kind, - nl_recvmsg_err_cb_t func, void *arg) -{ - if (kind < 0 || kind > NL_CB_KIND_MAX) - return nl_error(ERANGE, "Callback kind out of range"); - - if (kind == NL_CB_CUSTOM) { - cb->cb_err = func; - cb->cb_err_arg = arg; - } else { - cb->cb_err = cb_err_def[kind]; - cb->cb_err_arg = arg; - } - - return 0; -} - -/** - * Overwrite internal calls to nl_recvmsgs() - * @arg cb callback configuration - * @arg func replacement callback for nl_recvmsgs() - */ -void nl_cb_overwrite_recvmsgs(struct nl_cb *cb, - int (*func)(struct nl_handle *, struct nl_cb *)) -{ - cb->cb_recvmsgs_ow = func; -} - -/** - * Overwrite internal calls to nl_recv() - * @arg cb callback configuration - * @arg func replacement callback for nl_recv() - */ -void nl_cb_overwrite_recv(struct nl_cb *cb, - int (*func)(struct nl_handle *, struct sockaddr_nl *, - unsigned char **, struct ucred **)) -{ - cb->cb_recv_ow = func; -} - -/** - * Overwrite internal calls to nl_send() - * @arg cb callback configuration - * @arg func replacement callback for nl_send() - */ -void nl_cb_overwrite_send(struct nl_cb *cb, - int (*func)(struct nl_handle *, struct nl_msg *)) -{ - cb->cb_send_ow = func; -} - -/** @} */ - -/** @} */