| /* |
| * Copyright 2012 Daniel Drown <dan-android@drown.org> |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| * netlink_callbacks.c - generic callbacks for netlink responses |
| */ |
| #include <net/if.h> |
| #include <netinet/in.h> |
| |
| #include <linux/rtnetlink.h> |
| #include <netlink/handlers.h> |
| #include <netlink/msg.h> |
| |
| /* function: ack_handler |
| * generic netlink callback for ack messages |
| * msg - netlink message |
| * data - pointer to an int, stores the success code |
| */ |
| static int ack_handler(__attribute__((unused)) struct nl_msg *msg, void *data) { |
| int *retval = data; |
| *retval = 0; |
| return NL_OK; |
| } |
| |
| /* function: error_handler |
| * generic netlink callback for error messages |
| * nla - error source |
| * err - netlink error message |
| * arg - pointer to an int, stores the error code |
| */ |
| static int error_handler(__attribute__((unused)) struct sockaddr_nl *nla, struct nlmsgerr *err, |
| void *arg) { |
| int *retval = arg; |
| if (err->error < 0) { |
| *retval = err->error; |
| } else { |
| *retval = 0; // NLMSG_ERROR used as reply type on no error |
| } |
| return NL_OK; |
| } |
| |
| /* function: alloc_ack_callbacks |
| * allocates a set of netlink callbacks. returns NULL on failure. callbacks will modify retval |
| * with <0 meaning failure retval - shared state between caller and callback functions |
| */ |
| struct nl_cb *alloc_ack_callbacks(int *retval) { |
| struct nl_cb *callbacks; |
| |
| callbacks = nl_cb_alloc(NL_CB_DEFAULT); |
| if (!callbacks) { |
| return NULL; |
| } |
| nl_cb_set(callbacks, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, retval); |
| nl_cb_err(callbacks, NL_CB_CUSTOM, error_handler, retval); |
| return callbacks; |
| } |