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