utils.c: Add ip address validation
[project/netifd.git] / utils.c
diff --git a/utils.c b/utils.c
index d202505..e01b633 100644 (file)
--- a/utils.c
+++ b/utils.c
@@ -17,6 +17,7 @@
 
 #include <arpa/inet.h>
 #include <netinet/in.h>
+#include <sys/socket.h>
 
 #ifdef __APPLE__
 #include <libproc.h>
@@ -118,6 +119,7 @@ int
 parse_ip_and_netmask(int af, const char *str, void *addr, unsigned int *netmask)
 {
        char *astr = alloca(strlen(str) + 1);
+       int ret = 0;
 
        strcpy(astr, str);
        if (!split_netmask(astr, netmask, af == AF_INET6))
@@ -131,7 +133,23 @@ parse_ip_and_netmask(int af, const char *str, void *addr, unsigned int *netmask)
                        return 0;
        }
 
-       return inet_pton(af, astr, addr);
+       ret = inet_pton(af, astr, addr);
+       if (ret > 0) {
+               if (af == AF_INET) {
+                       struct in_addr *ip4_addr = (struct in_addr *)addr;
+                       uint32_t host_addr = ntohl(ip4_addr->s_addr);
+
+                       if (IN_EXPERIMENTAL(host_addr)) {
+                               return 0;
+                       }
+               }
+               else if (af == AF_INET6) {
+                       if (IN6_IS_ADDR_MULTICAST((struct in6_addr *)addr)) {
+                               return 0;
+                       }
+               }
+       }
+       return ret;
 }
 
 char *
@@ -195,3 +213,22 @@ bool check_pid_path(int pid, const char *exe)
 
        return !memcmp(exe, proc_exe_buf, exe_len);
 }
+
+static const char * const uci_validate_name[__BLOBMSG_TYPE_LAST] = {
+       [BLOBMSG_TYPE_STRING] = "string",
+       [BLOBMSG_TYPE_ARRAY] = "list(string)",
+       [BLOBMSG_TYPE_INT32] = "uinteger",
+       [BLOBMSG_TYPE_BOOL] = "bool",
+};
+
+const char*
+uci_get_validate_string(const struct uci_blob_param_list *p, int i)
+{
+       if (p->validate[i])
+               return p->validate[i];
+
+       else if (uci_validate_name[p->params[i].type])
+               return uci_validate_name[p->params[i].type];
+
+       return p->validate[BLOBMSG_TYPE_STRING];
+}