179 lines
3.3 KiB
C
179 lines
3.3 KiB
C
/**
|
|
* @file net/if.c Network interface code
|
|
*
|
|
* Copyright (C) 2010 Creytiv.com
|
|
*/
|
|
#include <re_types.h>
|
|
#include <re_fmt.h>
|
|
#include <re_mbuf.h>
|
|
#include <re_sa.h>
|
|
#include <re_net.h>
|
|
|
|
|
|
#define DEBUG_MODULE "netif"
|
|
#define DEBUG_LEVEL 5
|
|
#include <re_dbg.h>
|
|
|
|
|
|
/** Interface address entry */
|
|
struct ifentry {
|
|
int af; /**< Address family */
|
|
char *ifname; /**< Interface name */
|
|
struct sa *ip; /**< IP address */
|
|
size_t sz; /**< Size of buffer */
|
|
bool found; /**< Found flag */
|
|
};
|
|
|
|
|
|
static bool if_getname_handler(const char *ifname, const struct sa *sa,
|
|
void *arg)
|
|
{
|
|
struct ifentry *ife = arg;
|
|
|
|
if (ife->af != sa_af(sa))
|
|
return false;
|
|
|
|
if (0 == sa_cmp(sa, ife->ip, SA_ADDR)) {
|
|
str_ncpy(ife->ifname, ifname, ife->sz);
|
|
ife->found = true;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
/**
|
|
* Get the name of the interface for a given IP address
|
|
*
|
|
* @param ifname Buffer for returned network interface name
|
|
* @param sz Size of buffer
|
|
* @param af Address Family
|
|
* @param ip Given IP address
|
|
*
|
|
* @return 0 if success, otherwise errorcode
|
|
*/
|
|
int net_if_getname(char *ifname, size_t sz, int af, const struct sa *ip)
|
|
{
|
|
struct ifentry ife;
|
|
int err;
|
|
|
|
if (!ifname || !sz || !ip)
|
|
return EINVAL;
|
|
|
|
ife.af = af;
|
|
ife.ifname = ifname;
|
|
ife.ip = (struct sa *)ip;
|
|
ife.sz = sz;
|
|
ife.found = false;
|
|
|
|
err = net_if_list(if_getname_handler, &ife);
|
|
|
|
return ife.found ? err : ENODEV;
|
|
}
|
|
|
|
|
|
static bool if_getaddr_handler(const char *ifname,
|
|
const struct sa *sa, void *arg)
|
|
{
|
|
struct ifentry *ife = arg;
|
|
struct pl in = PL_INIT;
|
|
|
|
/* Match name of interface? */
|
|
pl_set_str(&in, ife->ifname);
|
|
if (pl_isset(&in) && 0 != pl_strcmp(&in, ifname))
|
|
return false;
|
|
|
|
if (!sa)
|
|
return false;
|
|
|
|
#if 1
|
|
/* skip loopback and link-local IP */
|
|
if (sa_is_loopback(sa) || sa_is_linklocal(sa))
|
|
return false;
|
|
#endif
|
|
|
|
/* Match address family */
|
|
if (ife->af != sa_af(sa))
|
|
return false;
|
|
|
|
/* Match - copy address */
|
|
sa_cpy(ife->ip, sa);
|
|
ife->found = true;
|
|
|
|
return ife->found;
|
|
}
|
|
|
|
|
|
/**
|
|
* Get IP address for a given network interface
|
|
*
|
|
* @param ifname Network interface name (optional)
|
|
* @param af Address Family
|
|
* @param ip Returned IP address
|
|
*
|
|
* @return 0 if success, otherwise errorcode
|
|
*
|
|
* @deprecated Works for IPv4 only
|
|
*/
|
|
int net_if_getaddr(const char *ifname, int af, struct sa *ip)
|
|
{
|
|
struct ifentry ife;
|
|
int err;
|
|
|
|
if (!ip)
|
|
return EINVAL;
|
|
|
|
ife.af = af;
|
|
ife.ifname = (char *)ifname;
|
|
ife.ip = ip;
|
|
ife.sz = 0;
|
|
ife.found = false;
|
|
|
|
#ifdef HAVE_GETIFADDRS
|
|
err = net_getifaddrs(if_getaddr_handler, &ife);
|
|
#else
|
|
err = net_if_list(if_getaddr_handler, &ife);
|
|
#endif
|
|
|
|
return ife.found ? err : ENODEV;
|
|
}
|
|
|
|
|
|
#ifndef __SYMBIAN32__
|
|
static bool if_debug_handler(const char *ifname, const struct sa *sa,
|
|
void *arg)
|
|
{
|
|
struct re_printf *pf = arg;
|
|
|
|
(void)re_hprintf(pf, " %10s: %j\n", ifname, sa);
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
/**
|
|
* Debug network interfaces
|
|
*
|
|
* @param pf Print handler for debug output
|
|
* @param unused Unused parameter
|
|
*
|
|
* @return 0 if success, otherwise errorcode
|
|
*/
|
|
int net_if_debug(struct re_printf *pf, void *unused)
|
|
{
|
|
int err;
|
|
|
|
(void)unused;
|
|
|
|
err = re_hprintf(pf, "net interfaces:\n");
|
|
|
|
#ifdef HAVE_GETIFADDRS
|
|
err |= net_getifaddrs(if_debug_handler, pf);
|
|
#else
|
|
err |= net_if_list(if_debug_handler, pf);
|
|
#endif
|
|
|
|
return err;
|
|
}
|
|
#endif
|