| /** |
| * @file net.c Networking code. |
| * |
| * Copyright (C) 2010 Creytiv.com |
| */ |
| #define _BSD_SOURCE 1 |
| #define _DEFAULT_SOURCE 1 |
| #include <stdlib.h> |
| #include <string.h> |
| #if !defined(WIN32) |
| #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) |
| 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; |
| } |