summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2009-12-20 12:46:50 -0800
committerMarcel Holtmann <marcel@holtmann.org>2009-12-20 12:46:50 -0800
commit5b1c118c543bb2bde58878cadb509558c28acbb8 (patch)
tree2e960cf2dbd3336865dff2dd775442db00e087af /src
parentcf18e1cca44857e17d5c7b476d09fe38c7212b9c (diff)
downloadconnman-5b1c118c543bb2bde58878cadb509558c28acbb8.tar.gz
connman-5b1c118c543bb2bde58878cadb509558c28acbb8.tar.bz2
connman-5b1c118c543bb2bde58878cadb509558c28acbb8.zip
Add D-Bus interface for configuring IP addresses
Diffstat (limited to 'src')
-rw-r--r--src/connman.h8
-rw-r--r--src/ipconfig.c148
-rw-r--r--src/service.c23
3 files changed, 165 insertions, 14 deletions
diff --git a/src/connman.h b/src/connman.h
index 889cc6d9..c4020b1e 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -129,9 +129,11 @@ const char *__connman_ipconfig_method2string(enum connman_ipconfig_method method
enum connman_ipconfig_method __connman_ipconfig_string2method(const char *method);
void __connman_ipconfig_append_ipv4(struct connman_ipconfig *ipconfig,
- DBusMessageIter *iter);
-int __connman_ipconfig_set_ipv4(struct connman_ipconfig *ipconfig,
- const char *key, DBusMessageIter *value);
+ DBusMessageIter *iter);
+void __connman_ipconfig_append_ipv4config(struct connman_ipconfig *ipconfig,
+ DBusMessageIter *iter);
+int __connman_ipconfig_set_ipv4config(struct connman_ipconfig *ipconfig,
+ DBusMessageIter *value);
int __connman_ipconfig_append_ethernet(struct connman_ipconfig *ipconfig,
DBusMessageIter *iter);
diff --git a/src/ipconfig.c b/src/ipconfig.c
index 7d2ae9d6..df023c2c 100644
--- a/src/ipconfig.c
+++ b/src/ipconfig.c
@@ -91,6 +91,37 @@ void connman_ipaddress_free(struct connman_ipaddress *ipaddress)
g_free(ipaddress);
}
+static unsigned char netmask2prefixlen(const char *netmask)
+{
+ unsigned char bits = 0;
+ in_addr_t mask = inet_network(netmask);
+ in_addr_t host = ~mask;
+
+ /* a valid netmask must be 2^n - 1 */
+ if ((host & (host + 1)) != 0)
+ return -1;
+
+ for (; mask; mask <<= 1)
+ ++bits;
+
+ return bits;
+}
+
+void connman_ipaddress_set(struct connman_ipaddress *ipaddress,
+ const char *address, const char *netmask)
+{
+ if (ipaddress == NULL)
+ return;
+
+ if (netmask != NULL)
+ ipaddress->prefixlen = netmask2prefixlen(netmask);
+ else
+ ipaddress->prefixlen = 32;
+
+ g_free(ipaddress->local);
+ ipaddress->local = g_strdup(address);
+}
+
void connman_ipaddress_clear(struct connman_ipaddress *ipaddress)
{
if (ipaddress == NULL)
@@ -920,7 +951,7 @@ enum connman_ipconfig_method __connman_ipconfig_string2method(const char *method
}
void __connman_ipconfig_append_ipv4(struct connman_ipconfig *ipconfig,
- DBusMessageIter *iter)
+ DBusMessageIter *iter)
{
const char *str;
@@ -949,25 +980,120 @@ void __connman_ipconfig_append_ipv4(struct connman_ipconfig *ipconfig,
}
}
-int __connman_ipconfig_set_ipv4(struct connman_ipconfig *ipconfig,
- const char *key, DBusMessageIter *value)
+void __connman_ipconfig_append_ipv4config(struct connman_ipconfig *ipconfig,
+ DBusMessageIter *iter)
+{
+ const char *str;
+
+ str = __connman_ipconfig_method2string(ipconfig->method);
+ if (str == NULL)
+ return;
+
+ connman_dbus_dict_append_basic(iter, "Method", DBUS_TYPE_STRING, &str);
+
+ switch (ipconfig->method) {
+ case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
+ case CONNMAN_IPCONFIG_METHOD_OFF:
+ case CONNMAN_IPCONFIG_METHOD_DHCP:
+ return;
+ case CONNMAN_IPCONFIG_METHOD_MANUAL:
+ break;
+ }
+
+ if (ipconfig->address == NULL)
+ return;
+
+ if (ipconfig->address->local != NULL) {
+ in_addr_t addr;
+ struct in_addr netmask;
+ char *mask;
+
+ connman_dbus_dict_append_basic(iter, "Address",
+ DBUS_TYPE_STRING, &ipconfig->address->local);
+
+ addr = 0xffffffff << (32 - ipconfig->address->prefixlen);
+ netmask.s_addr = htonl(addr);
+ mask = inet_ntoa(netmask);
+ connman_dbus_dict_append_basic(iter, "Netmask",
+ DBUS_TYPE_STRING, &mask);
+ }
+}
+
+int __connman_ipconfig_set_ipv4config(struct connman_ipconfig *ipconfig,
+ DBusMessageIter *array)
{
- int type = dbus_message_iter_get_arg_type(value);
+ enum connman_ipconfig_method method = CONNMAN_IPCONFIG_METHOD_UNKNOWN;
+ const char *address = NULL, *netmask = NULL;
+ DBusMessageIter dict;
+
+ DBG("ipconfig %p", ipconfig);
+
+ if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY)
+ return -EINVAL;
- DBG("ipconfig %p key %s type %d", ipconfig, key, type);
+ dbus_message_iter_recurse(array, &dict);
- if (g_strcmp0(key, "Method") == 0) {
- const char *method;
+ while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
+ DBusMessageIter entry;
+ const char *key;
+ int type;
- if (type != DBUS_TYPE_STRING)
+ dbus_message_iter_recurse(&dict, &entry);
+
+ if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING)
return -EINVAL;
- dbus_message_iter_get_basic(value, &method);
+ dbus_message_iter_get_basic(&entry, &key);
+ dbus_message_iter_next(&entry);
+
+ type = dbus_message_iter_get_arg_type(&entry);
+
+ if (g_str_equal(key, "Method") == TRUE) {
+ const char *str;
+
+ if (type != DBUS_TYPE_STRING)
+ return -EINVAL;
+
+ dbus_message_iter_get_basic(&entry, &str);
+ method = __connman_ipconfig_string2method(str);
+ } else if (g_str_equal(key, "Address") == TRUE) {
+ if (type != DBUS_TYPE_STRING)
+ return -EINVAL;
- ipconfig->method = __connman_ipconfig_string2method(method);
- } else
+ dbus_message_iter_get_basic(&entry, &address);
+ } else if (g_str_equal(key, "Netmask") == TRUE) {
+ if (type != DBUS_TYPE_STRING)
+ return -EINVAL;
+
+ dbus_message_iter_get_basic(&entry, &netmask);
+ }
+
+ dbus_message_iter_next(&dict);
+ }
+
+ DBG("method %d address %s netmask %s", method, address, netmask);
+
+ switch (method) {
+ case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
+ case CONNMAN_IPCONFIG_METHOD_OFF:
return -EINVAL;
+ case CONNMAN_IPCONFIG_METHOD_MANUAL:
+ if (address == NULL)
+ return -EINVAL;
+
+ ipconfig->method = method;
+ connman_ipaddress_set(ipconfig->address, address, netmask);
+ break;
+
+ case CONNMAN_IPCONFIG_METHOD_DHCP:
+ if (ipconfig->method == method)
+ return 0;
+
+ ipconfig->method = method;
+ break;
+ }
+
return 0;
}
diff --git a/src/service.c b/src/service.c
index 21aaba44..dec86224 100644
--- a/src/service.c
+++ b/src/service.c
@@ -423,6 +423,14 @@ static void append_ipv4(DBusMessageIter *iter, void *user_data)
__connman_ipconfig_append_ipv4(service->ipconfig, iter);
}
+static void append_ipv4config(DBusMessageIter *iter, void *user_data)
+{
+ struct connman_service *service = user_data;
+
+ if (service->ipconfig != NULL)
+ __connman_ipconfig_append_ipv4config(service->ipconfig, iter);
+}
+
static void settings_changed(struct connman_service *service)
{
connman_dbus_property_changed_dict(service->path,
@@ -565,6 +573,9 @@ static DBusMessage *get_properties(DBusConnection *conn,
connman_dbus_dict_append_dict(&dict, "IPv4", append_ipv4, service);
+ connman_dbus_dict_append_dict(&dict, "IPv4.Configuration",
+ append_ipv4config, service);
+
connman_dbus_dict_close(&array, &dict);
return reply;
@@ -693,6 +704,18 @@ static DBusMessage *set_property(DBusConnection *conn,
"Cellular.Password", service->password);
__connman_storage_save_service(service);
+ } else if (g_str_equal(name, "IPv4.Configuration") == TRUE) {
+ int err;
+
+ if (service->ipconfig == NULL)
+ return __connman_error_invalid_property(msg);
+
+ err = __connman_ipconfig_set_ipv4config(service->ipconfig,
+ &value);
+ if (err < 0)
+ return __connman_error_failed(msg, -err);
+
+ __connman_storage_save_service(service);
} else
return __connman_error_invalid_property(msg);