Index: uspace/app/inetcfg/inetcfg.c
===================================================================
--- uspace/app/inetcfg/inetcfg.c	(revision 3b3c689ff125151df11825f53e0b224b082b7157)
+++ uspace/app/inetcfg/inetcfg.c	(revision 8bf672df361c98c8f5273d51034e67574914aaf3)
@@ -51,4 +51,6 @@
 	printf("\t" NAME " create <addr>/<width> <link-name> <addr-name>\n");
 	printf("\t" NAME " delete <link-name> <addr-name>\n");
+	printf("\t" NAME " add-sr <dest-addr>/<width> <router-addr> <route-name>\n");
+	printf("\t" NAME " del-sr <route-name>\n");
 }
 
@@ -82,8 +84,35 @@
 	}
 
-	if (bits < 1 || bits > 31)
+	if (bits > 31)
 		return EINVAL;
 
 	naddr->bits = bits;
+	return EOK;
+}
+
+static int addr_parse(const char *text, inet_addr_t *addr)
+{
+	unsigned long a[4];
+	char *cp = (char *)text;
+	int i;
+
+	for (i = 0; i < 3; i++) {
+		a[i] = strtoul(cp, &cp, 10);
+		if (*cp != '.')
+			return EINVAL;
+		++cp;
+	}
+
+	a[3] = strtoul(cp, &cp, 10);
+	if (*cp != '\0')
+		return EINVAL;
+
+	addr->ipv4 = 0;
+	for (i = 0; i < 4; i++) {
+		if (a[i] > 255)
+			return EINVAL;
+		addr->ipv4 = (addr->ipv4 << 8) | a[i];
+	}
+
 	return EOK;
 }
@@ -103,4 +132,18 @@
 }
 
+static int addr_format(inet_addr_t *addr, char **bufp)
+{
+	int rc;
+
+	rc = asprintf(bufp, "%d.%d.%d.%d", addr->ipv4 >> 24,
+	    (addr->ipv4 >> 16) & 0xff, (addr->ipv4 >> 8) & 0xff,
+	    addr->ipv4 & 0xff);
+
+	if (rc < 0)
+		return ENOMEM;
+
+	return EOK;
+}
+
 static int addr_create_static(int argc, char *argv[])
 {
@@ -138,5 +181,6 @@
 	rc = naddr_parse(addr_spec, &naddr);
 	if (rc != EOK) {
-		printf(NAME ": Invalid address format '%s'.\n", addr_spec);
+		printf(NAME ": Invalid network address format '%s'.\n",
+		    addr_spec);
 		return EINVAL;
 	}
@@ -197,4 +241,91 @@
 }
 
+static int sroute_create(int argc, char *argv[])
+{
+	char *dest_str;
+	char *router_str;
+	char *route_name;
+
+	inet_naddr_t dest;
+	inet_addr_t router;
+	sysarg_t sroute_id;
+	int rc;
+
+	if (argc < 3) {
+		printf(NAME ": Missing arguments.\n");
+		print_syntax();
+		return EINVAL;
+	}
+
+	if (argc > 3) {
+		printf(NAME ": Too many arguments.\n");
+		print_syntax();
+		return EINVAL;
+	}
+
+	dest_str   = argv[0];
+	router_str = argv[1];
+	route_name = argv[2];
+
+	rc = naddr_parse(dest_str, &dest);
+	if (rc != EOK) {
+		printf(NAME ": Invalid network address format '%s'.\n",
+		    dest_str);
+		return EINVAL;
+	}
+
+	rc = addr_parse(router_str, &router);
+	if (rc != EOK) {
+		printf(NAME ": Invalid address format '%s'.\n", router_str);
+		return EINVAL;
+	}
+
+	rc = inetcfg_sroute_create(route_name, &dest, &router, &sroute_id);
+	if (rc != EOK) {
+		printf(NAME ": Failed creating static route '%s' (%d)\n",
+		    route_name, rc);
+		return EIO;
+	}
+
+	return EOK;
+}
+
+static int sroute_delete(int argc, char *argv[])
+{
+	char *route_name;
+	sysarg_t sroute_id;
+	int rc;
+
+	if (argc < 1) {
+		printf(NAME ": Missing arguments.\n");
+		print_syntax();
+		return EINVAL;
+	}
+
+	if (argc > 1) {
+		printf(NAME ": Too many arguments.\n");
+		print_syntax();
+		return EINVAL;
+	}
+
+	route_name = argv[0];
+
+	rc = inetcfg_sroute_get_id(route_name, &sroute_id);
+	if (rc != EOK) {
+		printf(NAME ": Static route '%s' not found (%d).\n",
+		    route_name, rc);
+		return ENOENT;
+	}
+
+	rc = inetcfg_sroute_delete(sroute_id);
+	if (rc != EOK) {
+		printf(NAME ": Failed deleting static route '%s' (%d)\n",
+		    route_name, rc);
+		return EIO;
+	}
+
+	return EOK;
+}
+
 static int addr_list(void)
 {
@@ -213,4 +344,8 @@
 		return rc;
 	}
+
+	printf("Configured addresses:\n");
+
+	ainfo.name = linfo.name = astr = NULL;
 
 	for (i = 0; i < count; i++) {
@@ -219,4 +354,5 @@
 			printf("Failed getting properties of address %zu.\n",
 			    (size_t)addr_list[i]);
+			ainfo.name = NULL;
 			continue;
 		}
@@ -226,4 +362,5 @@
 			printf("Failed getting properties of link %zu.\n",
 			    (size_t)ainfo.ilink);
+			linfo.name = NULL;
 			continue;
 		}
@@ -232,16 +369,97 @@
 		if (rc != EOK) {
 			printf("Memory allocation failed.\n");
+			astr = NULL;
 			goto out;
 		}
 
-		printf("%s %s %s\n", astr, linfo.name,
+		printf("    %s %s %s\n", astr, linfo.name,
 		    ainfo.name);
 
-		free(astr);
 		free(ainfo.name);
 		free(linfo.name);
-	}
+		free(astr);
+
+		ainfo.name = linfo.name = astr = NULL;
+	}
+
+	if (count == 0)
+		printf("    None\n");
 out:
+	if (ainfo.name != NULL)
+		free(ainfo.name);
+	if (linfo.name != NULL)
+		free(linfo.name);
+	if (astr != NULL)
+		free(astr);
+
 	free(addr_list);
+
+	return EOK;
+}
+
+static int sroute_list(void)
+{
+	sysarg_t *sroute_list;
+	inet_sroute_info_t srinfo;
+
+	size_t count;
+	size_t i;
+	int rc;
+	char *dest_str;
+	char *router_str;
+
+	rc = inetcfg_get_sroute_list(&sroute_list, &count);
+	if (rc != EOK) {
+		printf(NAME ": Failed getting address list.\n");
+		return rc;
+	}
+
+	printf("Static routes:\n");
+
+	srinfo.name = dest_str = router_str = NULL;
+
+	for (i = 0; i < count; i++) {
+		rc = inetcfg_sroute_get(sroute_list[i], &srinfo);
+		if (rc != EOK) {
+			printf("Failed getting properties of static route %zu.\n",
+			    (size_t)sroute_list[i]);
+			srinfo.name = NULL;
+			continue;
+		}
+
+		rc = naddr_format(&srinfo.dest, &dest_str);
+		if (rc != EOK) {
+			printf("Memory allocation failed.\n");
+			dest_str = NULL;
+			goto out;
+		}
+
+		rc = addr_format(&srinfo.router, &router_str);
+		if (rc != EOK) {
+			printf("Memory allocation failed.\n");
+			router_str = NULL;
+			goto out;
+		}
+
+		printf("    %s %s %s\n", dest_str, router_str, srinfo.name);
+
+		free(srinfo.name);
+		free(dest_str);
+		free(router_str);
+
+		router_str = srinfo.name = dest_str = NULL;
+	}
+
+	if (count == 0)
+		printf("    None\n");
+out:
+	if (srinfo.name != NULL)
+		free(srinfo.name);
+	if (dest_str != NULL)
+		free(dest_str);
+	if (router_str != NULL)
+		free(router_str);
+
+	free(sroute_list);
 
 	return EOK;
@@ -261,4 +479,7 @@
 	if (argc < 2) {
 		rc = addr_list();
+		if (rc != EOK)
+			return 1;
+		rc = sroute_list();
 		if (rc != EOK)
 			return 1;
@@ -274,4 +495,12 @@
 		if (rc != EOK)
 			return 1;
+	} else if (str_cmp(argv[1], "add-sr") == 0) {
+		rc = sroute_create(argc - 2, argv + 2);
+		if (rc != EOK)
+			return 1;
+	} else if (str_cmp(argv[1], "del-sr") == 0) {
+		rc = sroute_delete(argc - 2, argv + 2);
+		if (rc != EOK)
+			return 1;
 	} else {
 		printf(NAME ": Unknown command '%s'.\n", argv[1]);
