summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--proto-static.c2
-rw-r--r--proto.c67
-rw-r--r--proto.h1
3 files changed, 69 insertions, 1 deletions
diff --git a/proto-static.c b/proto-static.c
index 86f2f20..833b6b8 100644
--- a/proto-static.c
+++ b/proto-static.c
@@ -33,7 +33,7 @@ struct static_proto_state {
static bool
static_proto_setup(struct static_proto_state *state)
{
- return proto_apply_ip_settings(state->proto.iface, state->config, false) == 0;
+ return proto_apply_static_ip_settings(state->proto.iface, state->config) == 0;
}
static int
diff --git a/proto.c b/proto.c
index d41e796..a395187 100644
--- a/proto.c
+++ b/proto.c
@@ -203,6 +203,73 @@ parse_gateway_option(struct interface *iface, struct blob_attr *attr, bool v6)
}
int
+proto_apply_static_ip_settings(struct interface *iface, struct blob_attr *attr)
+{
+ struct blob_attr *tb[__OPT_MAX];
+ struct blob_attr *cur;
+ const char *error;
+ unsigned int netmask = 32;
+ int n_v4 = 0, n_v6 = 0;
+ struct in_addr bcast = {};
+
+ blobmsg_parse(proto_ip_attributes, __OPT_MAX, tb, blob_data(attr), blob_len(attr));
+
+ if ((cur = tb[OPT_NETMASK])) {
+ netmask = parse_netmask_string(blobmsg_data(cur), false);
+ if (netmask > 32) {
+ error = "INVALID_NETMASK";
+ goto error;
+ }
+ }
+
+ if ((cur = tb[OPT_BROADCAST])) {
+ if (!inet_pton(AF_INET, blobmsg_data(cur), &bcast)) {
+ error = "INVALID_BROADCAST";
+ goto error;
+ }
+ }
+
+ if ((cur = tb[OPT_IPADDR]))
+ n_v4 = parse_address_option(iface, cur, false,
+ netmask, false, bcast.s_addr);
+
+ if ((cur = tb[OPT_IP6ADDR]))
+ n_v6 = parse_address_option(iface, cur, true,
+ netmask, false, 0);
+
+ if (!n_v4 && !n_v6) {
+ error = "NO_ADDRESS";
+ goto error;
+ }
+
+ if (n_v4 < 0 || n_v6 < 0)
+ goto out;
+
+ if ((cur = tb[OPT_GATEWAY])) {
+ if (n_v4 && !parse_gateway_option(iface, cur, false))
+ goto out;
+ }
+
+ if ((cur = tb[OPT_IP6GW])) {
+ if (n_v6 && !parse_gateway_option(iface, cur, true))
+ goto out;
+ }
+
+ if ((cur = tb[OPT_DNS]))
+ interface_add_dns_server_list(&iface->proto_ip, cur);
+
+ if ((cur = tb[OPT_DNS_SEARCH]))
+ interface_add_dns_search_list(&iface->proto_ip, cur);
+
+ return 0;
+
+error:
+ interface_add_error(iface, "proto", error, NULL, 0);
+out:
+ return -1;
+}
+
+int
proto_apply_ip_settings(struct interface *iface, struct blob_attr *attr, bool ext)
{
struct blob_attr *tb[__OPT_MAX];
diff --git a/proto.h b/proto.h
index e86a8a3..12653cd 100644
--- a/proto.h
+++ b/proto.h
@@ -70,6 +70,7 @@ int interface_proto_event(struct interface_proto_state *proto,
enum interface_proto_cmd cmd, bool force);
unsigned int parse_netmask_string(const char *str, bool v6);
+int proto_apply_static_ip_settings(struct interface *iface, struct blob_attr *attr);
int proto_apply_ip_settings(struct interface *iface, struct blob_attr *attr, bool ext);