re/src/net/net.c
2015-07-01 07:34:05 +00:00

156 lines
2.8 KiB
C

/**
* @file net.c Networking code.
*
* Copyright (C) 2010 Creytiv.com
*/
#define _BSD_SOURCE 1
#include <stdlib.h>
#include <string.h>
#if !defined(WIN32) && !defined(CYGWIN)
#define __USE_BSD 1 /**< Use BSD code */
#include <unistd.h>
#include <netdb.h>
#endif
#include <re_types.h>
#include <re_fmt.h>
#include <re_mbuf.h>
#include <re_sa.h>
#include <re_net.h>
#define DEBUG_MODULE "net"
#define DEBUG_LEVEL 5
#include <re_dbg.h>
/**
* Get the IP address of the host
*
* @param af Address Family
* @param ip Returned IP address
*
* @return 0 if success, otherwise errorcode
*/
int net_hostaddr(int af, struct sa *ip)
{
char hostname[256];
struct in_addr in;
struct hostent *he;
if (-1 == gethostname(hostname, sizeof(hostname)))
return errno;
he = gethostbyname(hostname);
if (!he)
return ENOENT;
if (af != he->h_addrtype)
return EAFNOSUPPORT;
/* Get the first entry */
memcpy(&in, he->h_addr_list[0], sizeof(in));
sa_set_in(ip, ntohl(in.s_addr), 0);
return 0;
}
/**
* Get the default source IP address
*
* @param af Address Family
* @param ip Returned IP address
*
* @return 0 if success, otherwise errorcode
*/
int net_default_source_addr_get(int af, struct sa *ip)
{
#if defined(WIN32) || defined(CYGWIN)
return net_hostaddr(af, ip);
#else
char ifname[64] = "";
#ifdef HAVE_ROUTE_LIST
/* Get interface with default route */
(void)net_rt_default_get(af, ifname, sizeof(ifname));
#endif
/* First try with default interface */
if (0 == net_if_getaddr(ifname, af, ip))
return 0;
/* Then try first real IP */
if (0 == net_if_getaddr(NULL, af, ip))
return 0;
return net_if_getaddr4(ifname, af, ip);
#endif
}
/**
* Get a list of all network interfaces including name and IP address.
* Both IPv4 and IPv6 are supported
*
* @param ifh Interface handler, called once per network interface
* @param arg Handler argument
*
* @return 0 if success, otherwise errorcode
*/
int net_if_apply(net_ifaddr_h *ifh, void *arg)
{
#ifdef HAVE_GETIFADDRS
return net_getifaddrs(ifh, arg);
#else
return net_if_list(ifh, arg);
#endif
}
static bool net_rt_handler(const char *ifname, const struct sa *dst,
int dstlen, const struct sa *gw, void *arg)
{
void **argv = arg;
struct sa *ip = argv[1];
(void)dst;
(void)dstlen;
if (0 == str_cmp(ifname, argv[0])) {
*ip = *gw;
return true;
}
return false;
}
/**
* Get the IP-address of the default gateway
*
* @param af Address Family
* @param gw Returned Gateway address
*
* @return 0 if success, otherwise errorcode
*/
int net_default_gateway_get(int af, struct sa *gw)
{
char ifname[64];
void *argv[2];
int err;
if (!af || !gw)
return EINVAL;
err = net_rt_default_get(af, ifname, sizeof(ifname));
if (err)
return err;
argv[0] = ifname;
argv[1] = gw;
err = net_rt_list(net_rt_handler, argv);
if (err)
return err;
return 0;
}