summaryrefslogtreecommitdiffstats
path: root/getroute.c
diff options
context:
space:
mode:
Diffstat (limited to 'getroute.c')
-rw-r--r--getroute.c144
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;
-}