1a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown/*
2a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown * Copyright 2012 Daniel Drown <dan-android@drown.org>
3a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown *
4a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown * Licensed under the Apache License, Version 2.0 (the "License");
5a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown * you may not use this file except in compliance with the License.
6a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown * You may obtain a copy of the License at
7a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown *
8a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown * http://www.apache.org/licenses/LICENSE-2.0
9a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown *
10a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown * Unless required by applicable law or agreed to in writing, software
11a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown * distributed under the License is distributed on an "AS IS" BASIS,
12a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown * See the License for the specific language governing permissions and
14a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown * limitations under the License.
15a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown *
16a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown * netlink_callbacks.c - generic callbacks for netlink responses
17a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown */
18a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown#include <netinet/in.h>
19a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown#include <net/if.h>
20a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown
21a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown#include <linux/rtnetlink.h>
22a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown#include <netlink/handlers.h>
23a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown#include <netlink/msg.h>
24a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown
25a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown/* function: ack_handler
26a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown * generic netlink callback for ack messages
27a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown * msg  - netlink message
28a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown * data - pointer to an int, stores the success code
29a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown */
3056ec161d47856212008f47676577882f30853312Lorenzo Colittistatic int ack_handler(__attribute__((unused)) struct nl_msg *msg, void *data) {
31a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown  int *retval = data;
32a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown  *retval = 0;
33a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown  return NL_OK;
34a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown}
35a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown
36a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown/* function: error_handler
37a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown * generic netlink callback for error messages
38a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown * nla  - error source
39a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown * err  - netlink error message
40a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown * arg  - pointer to an int, stores the error code
41a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown */
4256ec161d47856212008f47676577882f30853312Lorenzo Colittistatic int error_handler(__attribute__((unused)) struct sockaddr_nl *nla,
4356ec161d47856212008f47676577882f30853312Lorenzo Colitti                         struct nlmsgerr *err, void *arg) {
44a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown  int *retval = arg;
45a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown  if(err->error < 0) {
46a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown    *retval = err->error;
47a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown  } else {
48a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown    *retval = 0; // NLMSG_ERROR used as reply type on no error
49a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown  }
50a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown  return NL_OK;
51a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown}
52a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown
53a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown/* function: alloc_ack_callbacks
54a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown * allocates a set of netlink callbacks.  returns NULL on failure.  callbacks will modify retval with <0 meaning failure
55a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown * retval - shared state between caller and callback functions
56a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown */
57a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drownstruct nl_cb *alloc_ack_callbacks(int *retval) {
58a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown  struct nl_cb *callbacks;
59a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown
60a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown  callbacks = nl_cb_alloc(NL_CB_DEFAULT);
61a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown  if(!callbacks) {
62a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown    return NULL;
63a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown  }
64a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown  nl_cb_set(callbacks, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, retval);
65a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown  nl_cb_err(callbacks, NL_CB_CUSTOM, error_handler, retval);
66a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown  return callbacks;
67a45056e35c1af2a0f0a6eed258fd5fdf4846a79fDaniel Drown}
68