]> git.ozlabs.org Git - petitboot/blobdiff - lib/pb-config/storage-powerpc-nvram.c
network: handle DNS config
[petitboot] / lib / pb-config / storage-powerpc-nvram.c
index 4e4d29ae8effccff7f2a44f0140adc676d545457..3ed3c46dbd1b716ec0643381f137698f880cfd97 100644 (file)
@@ -12,7 +12,6 @@
 #include "storage.h"
 
 static const char *partition = "common";
 #include "storage.h"
 
 static const char *partition = "common";
-static const char *prefix = "petitboot,";
 
 struct param {
        char                    *name;
 
 struct param {
        char                    *name;
@@ -26,12 +25,33 @@ struct powerpc_nvram_storage {
        struct list             params;
 };
 
        struct list             params;
 };
 
+static const char *known_params[] = {
+       "auto-boot?",
+       "petitboot,network",
+       NULL,
+};
+
 #define to_powerpc_nvram_storage(s) \
        container_of(s, struct powerpc_nvram_storage, storage)
 
 /* a partition max a max size of 64k * 16bytes = 1M */
 static const int max_partition_size = 64 * 1024 * 16;
 
 #define to_powerpc_nvram_storage(s) \
        container_of(s, struct powerpc_nvram_storage, storage)
 
 /* a partition max a max size of 64k * 16bytes = 1M */
 static const int max_partition_size = 64 * 1024 * 16;
 
+static bool param_is_known(const char *param, unsigned int len)
+{
+       const char *known_param;
+       unsigned int i;
+
+       for (i = 0; known_params[i]; i++) {
+               known_param = known_params[i];
+               if (len == strlen(known_param) &&
+                               !strncmp(param, known_param, len))
+                       return true;
+       }
+
+       return false;
+}
+
 static int parse_nvram_params(struct powerpc_nvram_storage *nv,
                char *buf, int len)
 {
 static int parse_nvram_params(struct powerpc_nvram_storage *nv,
                char *buf, int len)
 {
@@ -58,9 +78,16 @@ static int parse_nvram_params(struct powerpc_nvram_storage *nv,
                return -1;
        }
 
                return -1;
        }
 
-       for (pos = buf + i; pos < buf + len; pos += paramlen) {
+       for (pos = buf + i; pos < buf + len; pos += paramlen + 1) {
                unsigned int namelen;
                struct param *param;
                unsigned int namelen;
                struct param *param;
+               char *newline;
+
+               newline = strchr(pos, '\n');
+               if (!newline)
+                       break;
+
+               *newline = '\0';
 
                paramlen = strlen(pos);
 
 
                paramlen = strlen(pos);
 
@@ -69,14 +96,13 @@ static int parse_nvram_params(struct powerpc_nvram_storage *nv,
                if (!value)
                        continue;
 
                if (!value)
                        continue;
 
-               namelen = name - value;
-               if (namelen <= strlen(prefix))
+               namelen = value - name;
+               if (namelen == 0)
                        continue;
 
                        continue;
 
-               if (strncmp(name, prefix, strlen(prefix)))
+               if (!param_is_known(name, namelen))
                        continue;
 
                        continue;
 
-               name += strlen(prefix);
                value++;
 
                param = talloc(nv, struct param);
                value++;
 
                param = talloc(nv, struct param);
@@ -162,7 +188,7 @@ static const char *get_param(struct powerpc_nvram_storage *nv,
        return NULL;
 }
 
        return NULL;
 }
 
-static int parse_hwaddr(struct network_config *config, char *str)
+static int parse_hwaddr(struct interface_config *ifconf, char *str)
 {
        int i;
 
 {
        int i;
 
@@ -181,62 +207,89 @@ static int parse_hwaddr(struct network_config *config, char *str)
                if (endp != byte + 2)
                        return -1;
 
                if (endp != byte + 2)
                        return -1;
 
-               config->hwaddr[i] = x & 0xff;
+               ifconf->hwaddr[i] = x & 0xff;
        }
 
        return 0;
 }
 
        }
 
        return 0;
 }
 
-static int parse_one_network_config(struct network_config *config,
+static int parse_one_interface_config(struct config *config,
                char *confstr)
 {
                char *confstr)
 {
+       struct interface_config *ifconf;
        char *tok, *saveptr;
 
        char *tok, *saveptr;
 
+       ifconf = talloc(config, struct interface_config);
+
        if (!confstr || !strlen(confstr))
        if (!confstr || !strlen(confstr))
-               return -1;
+               goto out_err;
 
        /* first token should be the mac address */
        tok = strtok_r(confstr, ",", &saveptr);
        if (!tok)
 
        /* first token should be the mac address */
        tok = strtok_r(confstr, ",", &saveptr);
        if (!tok)
-               return -1;
+               goto out_err;
 
 
-       if (parse_hwaddr(config, tok))
-               return -1;
+       if (parse_hwaddr(ifconf, tok))
+               goto out_err;
 
        /* second token is the method */
        tok = strtok_r(NULL, ",", &saveptr);
        if (!tok || !strlen(tok) || !strcmp(tok, "ignore")) {
 
        /* second token is the method */
        tok = strtok_r(NULL, ",", &saveptr);
        if (!tok || !strlen(tok) || !strcmp(tok, "ignore")) {
-               config->ignore = true;
-               return 0;
-       }
+               ifconf->ignore = true;
 
 
-       if (!strcmp(tok, "dhcp")) {
-               config->method = CONFIG_METHOD_DHCP;
+       } else if (!strcmp(tok, "dhcp")) {
+               ifconf->method = CONFIG_METHOD_DHCP;
 
        } else if (!strcmp(tok, "static")) {
 
        } else if (!strcmp(tok, "static")) {
-               config->method = CONFIG_METHOD_STATIC;
+               ifconf->method = CONFIG_METHOD_STATIC;
 
 
-               /* ip/mask, [optional] gateway, [optional] dns */
+               /* ip/mask, [optional] gateway */
                tok = strtok_r(NULL, ",", &saveptr);
                if (!tok)
                tok = strtok_r(NULL, ",", &saveptr);
                if (!tok)
-                       return -1;
-               config->static_config.address =
-                       talloc_strdup(config, tok);
+                       goto out_err;
+               ifconf->static_config.address =
+                       talloc_strdup(ifconf, tok);
 
                tok = strtok_r(NULL, ",", &saveptr);
                if (tok) {
 
                tok = strtok_r(NULL, ",", &saveptr);
                if (tok) {
-                       config->static_config.gateway =
-                               talloc_strdup(config, tok);
-                       tok = strtok_r(NULL, ",", &saveptr);
+                       ifconf->static_config.gateway =
+                               talloc_strdup(ifconf, tok);
                }
 
                }
 
-               if (tok) {
-                       config->static_config.dns =
-                               talloc_strdup(config, tok);
-               }
        } else {
                pb_log("Unknown network configuration method %s\n", tok);
        } else {
                pb_log("Unknown network configuration method %s\n", tok);
-               return -1;
+               goto out_err;
+       }
+
+       config->network.interfaces = talloc_realloc(config,
+                       config->network.interfaces,
+                       struct interface_config *,
+                       ++config->network.n_interfaces);
+
+       config->network.interfaces[config->network.n_interfaces - 1] = ifconf;
+
+       return 0;
+out_err:
+       talloc_free(ifconf);
+       return -1;
+}
+
+static int parse_one_dns_config(struct config *config,
+               char *confstr)
+{
+       char *tok, *saveptr;
+
+       for (tok = strtok_r(confstr, ",", &saveptr); tok;
+                       tok = strtok_r(NULL, ",", &saveptr)) {
+
+               char *server = talloc_strdup(config, tok);
+
+               config->network.dns_servers = talloc_realloc(config,
+                               config->network.dns_servers, const char *,
+                               ++config->network.n_dns_servers);
+
+               config->network.dns_servers[config->network.n_dns_servers - 1]
+                               = server;
        }
 
        return 0;
        }
 
        return 0;
@@ -249,36 +302,24 @@ static void populate_network_config(struct powerpc_nvram_storage *nv,
        char *val;
        int i;
 
        char *val;
        int i;
 
-       cval = get_param(nv, "network");
+       cval = get_param(nv, "petitboot,network");
        if (!cval || !strlen(cval))
                return;
 
        val = talloc_strdup(config, cval);
 
        for (i = 0; ; i++) {
        if (!cval || !strlen(cval))
                return;
 
        val = talloc_strdup(config, cval);
 
        for (i = 0; ; i++) {
-               struct network_config *netconf;
                char *tok, *saveptr;
                char *tok, *saveptr;
-               int rc;
 
                tok = strtok_r(i == 0 ? val : NULL, " ", &saveptr);
                if (!tok)
                        break;
 
 
                tok = strtok_r(i == 0 ? val : NULL, " ", &saveptr);
                if (!tok)
                        break;
 
-               netconf = talloc(nv, struct network_config);
-
-               rc = parse_one_network_config(netconf, tok);
-               if (rc) {
-                       talloc_free(netconf);
-                       continue;
-               }
-
-               config->network_configs = talloc_realloc(nv,
-                                               config->network_configs,
-                                               struct network_config *,
-                                               ++config->n_network_configs);
+               if (!strncasecmp(tok, "dns,", strlen("dns,")))
+                       parse_one_dns_config(config, tok + strlen("dns,"));
+               else
+                       parse_one_interface_config(config, tok);
 
 
-               config->network_configs[config->n_network_configs - 1] =
-                                               netconf;
        }
 
        talloc_free(val);
        }
 
        talloc_free(val);