diff options
Diffstat (limited to 'getroute.c')
-rw-r--r-- | getroute.c | 144 |
1 files changed, 0 insertions, 144 deletions
diff --git a/getroute.c b/getroute.c deleted file mode 100644 index a615a4f..0000000 --- a/getroute.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright 2012 Daniel Drown - * - * 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. - * - * getroute.c - get an ip route - */ -#include <string.h> -#include <errno.h> - -#include <sys/socket.h> -#include <linux/netlink.h> -#include <linux/rtnetlink.h> -#include <arpa/inet.h> - -#include <netlink/handlers.h> -#include <netlink/msg.h> - -#include "getroute.h" -#include "netlink_callbacks.h" -#include "netlink_msg.h" - -/* function: get_default_route_cb - * finds the default route with the request family and out interface and saves the gateway - * msg - netlink message - * data - (struct default_route_data) requested filters and response storage - */ -static int get_default_route_cb(struct nl_msg *msg, void *data) { - struct rtmsg *rt_p; - struct rtattr *rta_p; - int rta_len; - struct default_route_data *default_route = data; - union anyip *this_gateway = NULL; - ssize_t this_gateway_size; - int this_interface_id = -1; - - if(default_route->reply_found_route) { // we already found our route - return NL_OK; - } - - rt_p = (struct rtmsg *)nlmsg_data(nlmsg_hdr(msg)); - if(rt_p->rtm_dst_len != 0) { // not a default route - return NL_OK; - } - if((rt_p->rtm_family != default_route->request_family) || (rt_p->rtm_table != RT_TABLE_MAIN)) { // not a route we care about - return NL_OK; - } - - rta_p = (struct rtattr *)RTM_RTA(rt_p); - rta_len = RTM_PAYLOAD(nlmsg_hdr(msg)); - for(; RTA_OK(rta_p, rta_len); rta_p = RTA_NEXT(rta_p, rta_len)) { - switch(rta_p->rta_type) { - case RTA_GATEWAY: - this_gateway = RTA_DATA(rta_p); - this_gateway_size = RTA_PAYLOAD(rta_p); - break; - case RTA_OIF: - this_interface_id = *(int *)RTA_DATA(rta_p); - break; - default: - break; - } - } - - if(this_interface_id == default_route->request_interface_id) { - default_route->reply_found_route = 1; - if(this_gateway != NULL) { - memcpy(&default_route->reply_gateway, this_gateway, this_gateway_size); - default_route->reply_has_gateway = 1; - } else { - default_route->reply_has_gateway = 0; - } - } - return NL_OK; -} - -/* function: error_handler - * error callback for get_default_route - * nla - where the message came from - * err - netlink message - * arg - (int *) storage for the error number - */ -static int error_handler(__attribute__((unused)) struct sockaddr_nl *nla, - struct nlmsgerr *err, void *arg) { - int *retval = arg; - if(err->error < 0) { // error_handler called even on no error (NLMSG_ERROR reply type used) - *retval = err->error; - } - return NL_OK; -} - -/* function: get_default_route - * finds the first default route with the given family and interface, returns the gateway (if it exists) in the struct - * default_route - requested family and interface, and response storage - */ -int get_default_route(struct default_route_data *default_route) { - struct rtmsg msg; - struct nl_cb *callbacks = NULL; - struct nl_msg *nlmsg = NULL; - int retval = 0; - - default_route->reply_has_gateway = 0; - default_route->reply_found_route = 0; - - memset(&msg,'\0',sizeof(msg)); - msg.rtm_family = default_route->request_family; - msg.rtm_table = RT_TABLE_MAIN; - msg.rtm_protocol = RTPROT_KERNEL; - msg.rtm_scope = RT_SCOPE_UNIVERSE; - - callbacks = nl_cb_alloc(NL_CB_DEFAULT); - if(!callbacks) { - retval = -ENOMEM; - goto cleanup; - } - // get_default_route_cb sets the response fields in default_route - nl_cb_set(callbacks, NL_CB_VALID, NL_CB_CUSTOM, get_default_route_cb, default_route); - nl_cb_err(callbacks, NL_CB_CUSTOM, error_handler, &retval); - - nlmsg = nlmsg_alloc_rtmsg(RTM_GETROUTE, NLM_F_REQUEST | NLM_F_ROOT, &msg); - if(!nlmsg) { - retval = -ENOMEM; - goto cleanup; - } - send_netlink_msg(nlmsg, callbacks); - -cleanup: - if(callbacks) - nl_cb_put(callbacks); - if(nlmsg) - nlmsg_free(nlmsg); - - return retval; -} |