iplib: Add a helper for finding the IP router
authorBarret Rhoden <brho@cs.berkeley.edu>
Thu, 22 Dec 2016 18:56:42 +0000 (13:56 -0500)
committerBarret Rhoden <brho@cs.berkeley.edu>
Tue, 10 Jan 2017 00:01:40 +0000 (19:01 -0500)
This will return a full IP address (v4 or v6).  To get a binary v4 address
(suitable for packet copies), use v6tov4() on the result.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
user/iplib/include/iplib/iplib.h
user/iplib/myipaddr.c

index 3dad453..5ee67ca 100644 (file)
@@ -191,6 +191,7 @@ char*       v4parseip(uint8_t*, char*);
 char*  v4parsecidr(uint8_t*, uint8_t*, char*);
 int    parseether(uint8_t*, char*);
 int    myipaddr(uint8_t*, char*);
+int my_router_addr(uint8_t *addr, char *net);
 int    myetheraddr(uint8_t*, char*);
 int    equivip4(uint8_t*, uint8_t*);
 int    equivip6(uint8_t*, uint8_t*);
index edbdec5..ff3ffb9 100644 (file)
@@ -6,6 +6,7 @@
  * modified, propagated, or distributed except according to the terms contained
  * in the LICENSE file.
  */
+#define _GNU_SOURCE
 #include <stdlib.h>
 
 #include <iplib/iplib.h>
@@ -30,3 +31,61 @@ int myipaddr(uint8_t *ip, char *net)
        free_ipifc(ifc);
        return 0;
 }
+
+/* Finds the default router from net/iproute, stores the full IP address
+ * (IPaddrlen) in addr.  Returns 0 on success. */
+int my_router_addr(uint8_t *addr, char *net)
+{
+       char *line = NULL;
+       size_t len = 0;
+       ssize_t read;
+       FILE *fp;
+       char *p, *str;
+       uint8_t ipaddr[IPaddrlen];
+       uint8_t v4addr[IPaddrlen];
+       char netpath[MAX_PATH_LEN];
+       int ret = -1;
+
+       if (!net)
+               net = "/net";
+       snprintf(netpath, sizeof(netpath), "%s/iproute", net);
+       fp = fopen(netpath, "r");
+       if (!fp)
+               return -1;
+       while ((read = getline(&line, &len, fp)) != -1) {
+               p = strchr(line, ' ');
+               if (!p) {
+                       werrstr("Malformed line, no initial space");
+                       goto out;
+               }
+               *p++ = 0;
+               parseip(ipaddr, line);
+               if (isv4(ipaddr)) {
+                       v6tov4(v4addr, ipaddr);
+                       if (!equivip4(v4addr, IPnoaddr))
+                               continue;
+               } else {
+                       if (!equivip6(ipaddr, IPnoaddr))
+                               continue;
+               }
+               p = strchr(p, ' ');
+               if (!p) {
+                       werrstr("Malformed line, no second space %s", line);
+                       goto out;
+               }
+               p++;
+               str = p;
+               p = strchr(p, ' ');
+               if (!p) {
+                       werrstr("Malformed line, no third space %s", line);
+                       goto out;
+               }
+               *p++ = 0;
+               parseip(addr, str);
+               ret = 0;
+       }
+out:
+       free(line);
+       fclose(fp);
+       return ret;
+}