1 /**
2  * @file net.c  Networking code.
3  *
4  * Copyright (C) 2010 Creytiv.com
5  */
6 #define _BSD_SOURCE 1
7 #define _DEFAULT_SOURCE 1
8 #include <stdlib.h>
9 #include <string.h>
10 #if !defined(WIN32)
11 #define __USE_BSD 1  /**< Use BSD code */
12 #include <unistd.h>
13 #include <netdb.h>
14 #endif
15 #include <re_types.h>
16 #include <re_fmt.h>
17 #include <re_mbuf.h>
18 #include <re_sa.h>
19 #include <re_net.h>
20 
21 
22 #define DEBUG_MODULE "net"
23 #define DEBUG_LEVEL 5
24 #include <re_dbg.h>
25 
26 
27 /**
28  * Get the IP address of the host
29  *
30  * @param af  Address Family
31  * @param ip  Returned IP address
32  *
33  * @return 0 if success, otherwise errorcode
34  */
net_hostaddr(int af,struct sa * ip)35 int net_hostaddr(int af, struct sa *ip)
36 {
37 	char hostname[256];
38 	struct in_addr in;
39 	struct hostent *he;
40 
41 	if (-1 == gethostname(hostname, sizeof(hostname)))
42 		return errno;
43 
44 	he = gethostbyname(hostname);
45 	if (!he)
46 		return ENOENT;
47 
48 	if (af != he->h_addrtype)
49 		return EAFNOSUPPORT;
50 
51 	/* Get the first entry */
52 	memcpy(&in, he->h_addr_list[0], sizeof(in));
53 	sa_set_in(ip, ntohl(in.s_addr), 0);
54 
55 	return 0;
56 }
57 
58 
59 /**
60  * Get the default source IP address
61  *
62  * @param af  Address Family
63  * @param ip  Returned IP address
64  *
65  * @return 0 if success, otherwise errorcode
66  */
net_default_source_addr_get(int af,struct sa * ip)67 int net_default_source_addr_get(int af, struct sa *ip)
68 {
69 #if defined(WIN32)
70 	return net_hostaddr(af, ip);
71 #else
72 	char ifname[64] = "";
73 
74 #ifdef HAVE_ROUTE_LIST
75 	/* Get interface with default route */
76 	(void)net_rt_default_get(af, ifname, sizeof(ifname));
77 #endif
78 
79 	/* First try with default interface */
80 	if (0 == net_if_getaddr(ifname, af, ip))
81 		return 0;
82 
83 	/* Then try first real IP */
84 	if (0 == net_if_getaddr(NULL, af, ip))
85 		return 0;
86 
87 	return net_if_getaddr4(ifname, af, ip);
88 #endif
89 }
90 
91 
92 /**
93  * Get a list of all network interfaces including name and IP address.
94  * Both IPv4 and IPv6 are supported
95  *
96  * @param ifh Interface handler, called once per network interface
97  * @param arg Handler argument
98  *
99  * @return 0 if success, otherwise errorcode
100  */
net_if_apply(net_ifaddr_h * ifh,void * arg)101 int net_if_apply(net_ifaddr_h *ifh, void *arg)
102 {
103 #ifdef HAVE_GETIFADDRS
104 	return net_getifaddrs(ifh, arg);
105 #else
106 	return net_if_list(ifh, arg);
107 #endif
108 }
109 
110 
net_rt_handler(const char * ifname,const struct sa * dst,int dstlen,const struct sa * gw,void * arg)111 static bool net_rt_handler(const char *ifname, const struct sa *dst,
112 			   int dstlen, const struct sa *gw, void *arg)
113 {
114 	void **argv = arg;
115 	struct sa *ip = argv[1];
116 	(void)dst;
117 	(void)dstlen;
118 
119 	if (0 == str_cmp(ifname, argv[0])) {
120 		*ip = *gw;
121 		return true;
122 	}
123 
124 	return false;
125 }
126 
127 
128 /**
129  * Get the IP-address of the default gateway
130  *
131  * @param af  Address Family
132  * @param gw  Returned Gateway address
133  *
134  * @return 0 if success, otherwise errorcode
135  */
net_default_gateway_get(int af,struct sa * gw)136 int net_default_gateway_get(int af, struct sa *gw)
137 {
138 	char ifname[64];
139 	void *argv[2];
140 	int err;
141 
142 	if (!af || !gw)
143 		return EINVAL;
144 
145 	err = net_rt_default_get(af, ifname, sizeof(ifname));
146 	if (err)
147 		return err;
148 
149 	argv[0] = ifname;
150 	argv[1] = gw;
151 
152 	err = net_rt_list(net_rt_handler, argv);
153 	if (err)
154 		return err;
155 
156 	return 0;
157 }
158