re/src/net/rt.c

158 lines
2.9 KiB
C
Raw Normal View History

2010-11-03 11:34:14 +00:00
/**
* @file net/rt.c Generic routing table code
*
* Copyright (C) 2010 Creytiv.com
*/
2012-06-11 05:38:38 +00:00
#define _BSD_SOURCE 1
2010-11-03 11:34:14 +00:00
#include <re_types.h>
#include <re_fmt.h>
#include <re_mbuf.h>
#include <re_sa.h>
#include <re_net.h>
struct net_rt {
int af;
char *ifname;
size_t size;
int prefix;
};
static bool rt_debug_handler(const char *ifname, const struct sa *dst,
int dstlen, const struct sa *gw, void *arg)
{
char addr[64];
struct re_printf *pf = arg;
int err = 0;
(void)re_snprintf(addr, sizeof(addr), "%j/%d", dst, dstlen);
err |= re_hprintf(pf, " %-44s", addr);
err |= re_hprintf(pf, "%-40j", gw);
err |= re_hprintf(pf, " %-15s ", ifname);
#ifdef HAVE_INET6
if (AF_INET6 == sa_af(dst)) {
const struct sockaddr_in6 *sin6 = &dst->u.in6;
const struct in6_addr *in6 = &sin6->sin6_addr;
if (IN6_IS_ADDR_MULTICAST(in6))
err |= re_hprintf(pf, " MULTICAST");
if (IN6_IS_ADDR_LINKLOCAL(in6))
err |= re_hprintf(pf, " LINKLOCAL");
if (IN6_IS_ADDR_SITELOCAL(in6))
err |= re_hprintf(pf, " SITELOCAL");
}
#endif
err |= re_hprintf(pf, "\n");
return 0 != err;
}
/**
* Dump the routing table
*
* @param pf Print function for output
* @param unused Unused parameter
*
* @return 0 if success, otherwise errorcode
*/
int net_rt_debug(struct re_printf *pf, void *unused)
{
int err = 0;
(void)unused;
err |= re_hprintf(pf, "net routes:\n");
err |= re_hprintf(pf, " Destination "
"Next Hop"
" Iface "
"Type\n");
err |= net_rt_list(rt_debug_handler, pf);
return err;
}
static bool rt_default_get_handler(const char *_ifname, const struct sa *dst,
int dstlen, const struct sa *gw, void *arg)
{
struct net_rt *rt = arg;
(void)dstlen;
(void)gw;
if (sa_af(dst) != rt->af)
return false;
switch (rt->af) {
case AF_INET:
if (0 == sa_in(dst)) {
str_ncpy(rt->ifname, _ifname, rt->size);
return true;
}
break;
#ifdef HAVE_INET6
case AF_INET6:
if (IN6_IS_ADDR_MULTICAST(&dst->u.in6.sin6_addr))
return false;
if (IN6_IS_ADDR_LINKLOCAL(&dst->u.in6.sin6_addr))
return false;
if (dstlen < rt->prefix) {
rt->prefix = dstlen;
str_ncpy(rt->ifname, _ifname, rt->size);
return false;
}
break;
#endif
}
return false;
}
/**
* Get the interface name of the default route
*
* @param af Address family
* @param ifname Buffer for returned interface name
* @param size Size of buffer
*
* @return 0 if success, otherwise errorcode
*/
int net_rt_default_get(int af, char *ifname, size_t size)
{
struct net_rt rt;
int err;
rt.af = af;
rt.ifname = ifname;
rt.size = size;
rt.prefix = 256;
err = net_rt_list(rt_default_get_handler, &rt);
if (err)
return err;
return '\0' != ifname[0] ? 0 : EINVAL;
}
#ifndef HAVE_ROUTE_LIST
/* We must provide a stub */
int net_rt_list(net_rt_h *rth, void *arg)
{
(void)rth;
(void)arg;
return ENOSYS;
}
#endif