Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

sysconfig: add missing network API bits

  • Loading branch information...
commit 850889d61c1427c53ed5b527c44e087f70a7596e 1 parent f89125c
Sébastien Bourdeauducq authored May 07, 2011

Showing 1 changed file with 116 additions and 22 deletions. Show diff stats Hide diff stats

  1. 138  src/sysconfig.c
138  src/sysconfig.c
@@ -15,6 +15,11 @@
15 15
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 16
  */
17 17
 
  18
+#include <rtems.h>
  19
+#include <rtems/rtems_bsdnet.h>
  20
+#include <rtems/dhcp.h>
  21
+#include <rtems/bspcmdline.h>
  22
+#include <rtems/bsdnet/servers.h>
18 23
 #include <stdio.h>
19 24
 #include <stdlib.h>
20 25
 #include <string.h>
@@ -24,10 +29,7 @@
24 29
 #include <sys/sockio.h>
25 30
 #include <arpa/inet.h>
26 31
 #include <net/if.h>
27  
-#include <rtems.h>
28  
-#include <rtems/rtems_bsdnet.h>
29  
-#include <rtems/dhcp.h>
30  
-#include <rtems/bspcmdline.h>
  32
+#include <net/route.h>
31 33
 #include <bsp.h>
32 34
 #include <mtklib.h>
33 35
 
@@ -63,7 +65,7 @@ struct rtems_bsdnet_config rtems_bsdnet_config = {
63 65
 	"local", /* domainname */
64 66
 	NULL, /* gateway */
65 67
 	NULL, /* log_host */
66  
-	{ NULL }, /* name_server[3] */
  68
+	{ NULL, NULL, NULL }, /* name_server[3] */
67 69
 	{ NULL }, /* ntp_server[3] */
68 70
 	0,
69 71
 	0,
@@ -140,6 +142,9 @@ static struct sysconfig sysconfig = {
140 142
 
141 143
 static char ip_fmt[FMT_IP_LEN];
142 144
 static char netmask_fmt[FMT_IP_LEN];
  145
+static char gateway_fmt[FMT_IP_LEN];
  146
+static char dns1_fmt[FMT_IP_LEN];
  147
+static char dns2_fmt[FMT_IP_LEN];
143 148
 
144 149
 static void format_ip(unsigned int ip, char *out)
145 150
 {
@@ -185,19 +190,28 @@ void sysconfig_load()
185 190
 
186 191
 	if(sysconfig.dhcp_enable)
187 192
 		rtems_bsdnet_config.bootp = my_dhcp;
188  
-	else
189  
-		rtems_bsdnet_config.bootp = NULL;
190  
-	if(sysconfig.ip && !sysconfig.dhcp_enable) {
191  
-		format_ip(sysconfig.ip, ip_fmt);
192  
-		netdriver_config.ip_address = ip_fmt;
193  
-	} else
194  
-		netdriver_config.ip_address = NULL;
195  
-	if(sysconfig.netmask && !sysconfig.dhcp_enable) {
196  
-		format_ip(sysconfig.netmask, netmask_fmt);
197  
-		netdriver_config.ip_netmask = netmask_fmt;
198  
-	} else
199  
-		netdriver_config.ip_netmask = NULL;
200  
-	/* TODO: gateway, DNS */
  193
+	else {
  194
+		if(sysconfig.ip) {
  195
+			format_ip(sysconfig.ip, ip_fmt);
  196
+			netdriver_config.ip_address = ip_fmt;
  197
+		}
  198
+		if(sysconfig.netmask) {
  199
+			format_ip(sysconfig.netmask, netmask_fmt);
  200
+			netdriver_config.ip_netmask = netmask_fmt;
  201
+		}
  202
+		if(sysconfig.gateway) {
  203
+			format_ip(sysconfig.gateway, gateway_fmt);
  204
+			rtems_bsdnet_config.gateway = gateway_fmt;
  205
+		}
  206
+		if(sysconfig.dns1) {
  207
+			format_ip(sysconfig.dns1, dns1_fmt);
  208
+			rtems_bsdnet_config.name_server[0] = dns1_fmt;
  209
+		}
  210
+		if(sysconfig.dns2) {
  211
+			format_ip(sysconfig.dns2, dns2_fmt);
  212
+			rtems_bsdnet_config.name_server[1] = dns2_fmt;
  213
+		}
  214
+	}
201 215
 }
202 216
 
203 217
 void sysconfig_save()
@@ -234,6 +248,76 @@ static void ifconfig_set_ip(uint32_t cmd, unsigned int ip)
234 248
 	rtems_bsdnet_ifconfig(NETWORK_INTERFACE, cmd, &ipaddr);
235 249
 }
236 250
 
  251
+/* HACK: we are not meant to use those from the application,
  252
+ * but RTEMS provides no other way to read the routing table.
  253
+ * (In its defense, the BSD API is about as crappy)
  254
+ */
  255
+extern struct radix_node_head *rt_tables[AF_MAX+1];
  256
+void rtems_bsdnet_semaphore_obtain(void);
  257
+void rtems_bsdnet_semaphore_release(void);
  258
+
  259
+static int retrieve_gateway(struct radix_node *rn, void *vw)
  260
+{
  261
+	unsigned int *r = (unsigned int *)vw;
  262
+	struct rtentry *rt = (struct rtentry *)rn;
  263
+	struct sockaddr_in *dst;
  264
+	struct sockaddr_in *gateway;
  265
+	
  266
+	dst = (struct sockaddr_in *)rt_key(rt);
  267
+	gateway = (struct sockaddr_in *)rt->rt_gateway;
  268
+	if((dst != NULL) && (dst->sin_addr.s_addr == INADDR_ANY)
  269
+	  && (rt->rt_flags & RTF_GATEWAY) && (gateway != NULL))
  270
+		*r = gateway->sin_addr.s_addr;
  271
+	
  272
+	return 0;
  273
+}
  274
+
  275
+static unsigned int route_get_gateway()
  276
+{
  277
+	struct radix_node_head *rnh;
  278
+	int error;
  279
+	unsigned int r;
  280
+	
  281
+	rnh = rt_tables[AF_INET];
  282
+	if(!rnh)
  283
+		return 0;
  284
+	r = 0;
  285
+	rtems_bsdnet_semaphore_obtain();
  286
+	error = rnh->rnh_walktree(rnh, retrieve_gateway, &r);
  287
+	rtems_bsdnet_semaphore_release();
  288
+	if(error)
  289
+		return 0;
  290
+	return r;
  291
+}
  292
+
  293
+static void route_set_gateway(unsigned int ip)
  294
+{
  295
+	struct sockaddr_in dst;
  296
+	struct sockaddr_in gw;
  297
+	struct sockaddr_in netmask;
  298
+
  299
+	dst.sin_len = sizeof(dst);
  300
+	dst.sin_family = AF_INET;
  301
+	dst.sin_addr.s_addr = 0;
  302
+
  303
+	gw.sin_len = sizeof(gw);
  304
+	gw.sin_family = AF_INET;
  305
+	gw.sin_addr.s_addr = ip;
  306
+
  307
+	netmask.sin_len = sizeof(netmask);
  308
+	netmask.sin_family = AF_INET;
  309
+	netmask.sin_addr.s_addr = 0xffffff00;
  310
+
  311
+	rtems_bsdnet_rtrequest(
  312
+		RTM_ADD,
  313
+		(struct sockaddr *)&dst,
  314
+		(struct sockaddr *)&gw,
  315
+		(struct sockaddr *)&netmask,
  316
+		RTF_STATIC | RTF_GATEWAY,
  317
+		NULL
  318
+	);
  319
+}
  320
+
237 321
 /* get */
238 322
 
239 323
 int sysconfig_get_resolution()
@@ -265,11 +349,11 @@ void sysconfig_get_ipconfig(int *dhcp_enable, unsigned int *ip, unsigned int *ne
265 349
 	if(netmask != NULL)
266 350
 		*netmask = ifconfig_get_ip(SIOCGIFNETMASK);
267 351
 	if(gateway != NULL)
268  
-		*gateway = 0; /* TODO */
  352
+		*gateway = route_get_gateway();
269 353
 	if(dns1 != NULL)
270  
-		*dns1 = 0; /* TODO */
  354
+		*dns1 = rtems_bsdnet_nameserver_count > 0 ? rtems_bsdnet_nameserver[0].s_addr : 0;
271 355
 	if(dns2 != NULL)
272  
-		*dns2 = 0; /* TODO */
  356
+		*dns2 = rtems_bsdnet_nameserver_count > 1 ? rtems_bsdnet_nameserver[1].s_addr : 0;
273 357
 }
274 358
 
275 359
 void sysconfig_get_credentials(char *login, char *password)
@@ -379,7 +463,17 @@ void sysconfig_set_ipconfig(int dhcp_enable, unsigned int ip, unsigned int netma
379 463
 				ifconfig_set_ip(SIOCSIFADDR, ip);
380 464
 			if(netmask != 0)
381 465
 				ifconfig_set_ip(SIOCSIFNETMASK, netmask);
382  
-			/* TODO: gateway, DNS */
  466
+			if(gateway != 0)
  467
+				route_set_gateway(gateway);
  468
+			if(dns1 != 0) {
  469
+				rtems_bsdnet_nameserver_count = 1;
  470
+				rtems_bsdnet_nameserver[0].s_addr = dns1;
  471
+				if(dns2 != 0) {
  472
+					rtems_bsdnet_nameserver_count = 2;
  473
+					rtems_bsdnet_nameserver[1].s_addr = dns2;
  474
+				}
  475
+			}
  476
+			/* TODO: run res_init() ? */
383 477
 		} else if(!sysconfig.dhcp_enable) {
384 478
 			ifconfig_set_ip(SIOCSIFADDR, 0);
385 479
 			ifconfig_set_ip(SIOCSIFNETMASK, 0);

0 notes on commit 850889d

Please sign in to comment.
Something went wrong with that request. Please try again.