[meego-packaging] 4945: Changes to MeeGo:1.0:Core:Update:Testing/connman

Martin Xu martin.xu at intel.com
Sun Jun 27 23:54:10 PDT 2010


Hi,
I have made the following changes to connman in project MeeGo:1.0:Core:Update:Testing. Please review and accept ASAP.

Thank You,
Martin Xu 

[This message was auto-generated]

---

Request #4945:

  submit:   home:martin:branches:MeeGo:1.0:Core:Update:Testing/connman(r3)(cleanup) -> MeeGo:1.0:Core:Update:Testing/connman


Message:
    Fix MBC #3420

State:   new          2010-06-27T18:50:55 martin
Comment: None



changes files:
--------------
--- connman.changes
+++ connman.changes
@@ -1,3 +1,3 @@
-* Fri Jun 18 2010 Martin Xu <martin.xu at intel.com> - 0.52
-- add patch 0001-Remove-supplicant-and-device-scanning-state.patch
-- to fix bug #1848
+* Tue Jun 22 2010 Martin Xu <martin.xu at intel.com> - 0.54
+- Upgrade to 0.54
+- to fix MBC #3420 
@@ -5,11 +5,3 @@
-* Tue May 11 2010 Martin Xu <martin.xu at intel.com> - 0.52
-- add patch 0001-Check-ssid_len-before-set-WiFi.SSID-of-network.patch
-- to fix bug #1814
-
-* Sun May 09 2010 Martin Xu <martin.xu at intel.com> - 0.52
-- add patch 0001-Export-Gateway-from-service-properties-ipv4.patch
-- to fix bug #1851
-
-* Thu May 06 2010 Martin Xu <martin.xu at intel.com> - 0.52
-- add patch 0001-call-__connman_notifier_connect-only-when-state-is.patch 
-- to fix bug #1466
+* Fri Jun 11 2010 Martin Xu <martin.xu at intel.com> - 0.53
+- upgrade to 0.53
+- add portal support
@@ -22,3 +13,0 @@
-
-* Mon May 3 2010 Arjan van de Ven <arjan at linux.intel.com> - 0.52
-- stop some logspam (BMC 1573)

old:
----
  0001-Check-error-before-call-dbus_message_get_args-to-acq.patch
  0001-Check-ssid_len-before-set-WiFi.SSID-of-network.patch
  0001-Export-Gateway-from-service-properties-ipv4.patch
  0001-Remove-supplicant-and-device-scanning-state.patch
  0001-Set-network-associating-as-FALSE-at-function-pan_dis.patch
  0001-call-__connman_notifier_connect-only-when-state-is.patch
  connman-0.52.tar.bz2

new:
----
  connman-0.54.tar.bz2

spec files:
-----------
--- connman.spec
+++ connman.spec
@@ -7,7 +7,7 @@
 
 Name:       connman
 Summary:    Connection Manager
-Version:    0.52
+Version:    0.54
 Release:    1
 Group:      System/Networking
 License:    GPLv2
@@ -15,12 +15,6 @@
 Source0:    http://www.kernel.org/pub/linux/network/connman/connman-%{version}.tar.bz2
 Source100:  connman.yaml
 Patch0:     no-logspam.patch
-Patch1:     0001-Set-network-associating-as-FALSE-at-function-pan_dis.patch
-Patch2:     0001-Check-error-before-call-dbus_message_get_args-to-acq.patch
-Patch3:     0001-call-__connman_notifier_connect-only-when-state-is.patch
-Patch4:     0001-Export-Gateway-from-service-properties-ipv4.patch
-Patch5:     0001-Check-ssid_len-before-set-WiFi.SSID-of-network.patch
-Patch6:     0001-Remove-supplicant-and-device-scanning-state.patch
 Requires:   dbus
 Requires:   dhclient >= 3.0.2
 Requires:   wpa_supplicant >= 0.6.9
@@ -74,18 +68,6 @@
 
 # no-logspam.patch
 %patch0 -p1
-# 0001-Set-network-associating-as-FALSE-at-function-pan_dis.patch
-%patch1 -p1
-# 0001-Check-error-before-call-dbus_message_get_args-to-acq.patch
-%patch2 -p1
-# 0001-call-__connman_notifier_connect-only-when-state-is.patch
-%patch3 -p1
-# 0001-Export-Gateway-from-service-properties-ipv4.patch
-%patch4 -p1
-# 0001-Check-ssid_len-before-set-WiFi.SSID-of-network.patch
-%patch5 -p1
-# 0001-Remove-supplicant-and-device-scanning-state.patch
-%patch6 -p1
 # >> setup
 # << setup
 
@@ -101,6 +83,7 @@
     --enable-bluetooth=builtin \
     --enable-loopback=builtin \
     --enable-dnsproxy=builtin \
+    --enable-portal=builtin \
     --enable-meego=builtin \
     --enable-openconnect=builtin \
 %ifarch %{ix86}

other changes:
--------------

++++++ connman-0.52.tar.bz2 -> connman-0.54.tar.bz2
--- AUTHORS
+++ AUTHORS
@@ -6,3 +6,6 @@
 Gustavo Sverzut Barbieri <barbieri at profusion.mobi>
 Martin Xu <martin.xu at intel.com>
 Sam Leffler <sleffler at google.com>
+Daniel Wagner <daniel.wagner at bmw-carit.de>
+Forest Bond <forest at alittletooquiet.net>
+Kalle Valo <kalle.valo at canonical.com>
--- ChangeLog
+++ ChangeLog
@@ -1,3 +1,29 @@
+ver 0.54:
+	Fix issue with root requests and EDNS0 OPT records.
+	Fix issue with default gateway when route deletion fails.
+	Fix issue with group identifiers for cellular networks.
+	Fix issue with fixed IP settings from cellular networks.
+	Fix issue with nameserver settings and manual configuration.
+	Add support for cellular network name changes.
+	Add support for cellular signal strength changes.
+	Add support for actively scanning for hidden networks.
+	Add support for ASCII based WEP keys.
+	Add support for NTP timeserver updates.
+	Add support for PPP default route settings.
+
+ver 0.53:
+	Fix issue with supplicant and device scanning state cleaning.
+	Fix issue with Bluetooth PAN networks stay in connected state.
+	Fix issue with reference counting and connected state.
+	Fix issue with technology disabling on device removal.
+	Fix issue with two default gateways when using VPN.
+	Fix issue with static IPv4 configuration and signals.
+	Add support for splitting DHCP provided nameserver results.
+	Add support multiple nameservers in /etc/resolv.conf.
+	Add support for setting manual DNS server configuration.
+	Add support for exporting IPv4 gateway information.
+	Add support for newer versions of oFono API.
+
 ver 0.52:
 	Fix issue with new "connected" states.
 	Fix issue with hidden networks and PSK.
--- Makefile.am
+++ Makefile.am
@@ -116,8 +116,8 @@
 
 if TOOLS
 noinst_PROGRAMS += tools/wifi-scan tools/supplicant-test tools/dbus-test \
-			tools/addr-test tools/tap-test tools/polkit-test \
-							tools/portal-test
+			tools/addr-test tools/tap-test tools/resolv-test \
+					tools/polkit-test tools/portal-test
 
 tools_wifi_scan_LDADD = @GLIB_LIBS@ @NETLINK_LIBS@
 
@@ -129,6 +129,8 @@
 tools_dbus_test_SOURCES = $(gdbus_sources) tools/dbus-test.c
 tools_dbus_test_LDADD = @GLIB_LIBS@ @DBUS_LIBS@
 
+tools_resolv_test_LDADD = -lresolv
+
 tools_polkit_test_LDADD = @DBUS_LIBS@
 
 tools_portal_test_LDADD = @GLIB_LIBS@
@@ -142,7 +144,9 @@
 		test/simple-agent test/show-introspection test/test-compat \
 		test/test-manager test/test-connman test/monitor-connman \
 		test/connect-vpn test/disconnect-vpn test/list-providers \
-		test/monitor-manager test/test-counter test/set-ip-method
+		test/monitor-manager test/test-counter test/set-ip-method \
+		test/set-nameservers test/set-domains test/find-service \
+		test/get-services
 
 if TEST
 testdir = $(pkglibdir)/test
@@ -182,6 +186,7 @@
 				--enable-client \
 				--enable-portal \
 				--enable-hh2serial-gps \
+				--enable-ntpd \
 				--enable-tools
 
 DISTCLEANFILES = $(pkgconfig_DATA)
@@ -222,5 +227,5 @@
 	$(AM_V_at)$(MKDIR_P) include/connman
 	$(AM_V_GEN)$(LN_S) $(abs_top_srcdir)/$< $@
 
-clean-local: include/connman
-	@$(RM) -r $<
+clean-local:
+	@$(RM) -rf include/connman
--- Makefile.in
+++ Makefile.in
@@ -129,10 +129,15 @@
 @OPENCONNECT_TRUE at am__append_76 = scripts/openconnect-script
 @DHCLIENT_TRUE at am__append_77 = scripts/dhclient.conf
 @DHCLIENT_TRUE at am__append_78 = scripts/dhclient-script
- at CLIENT_TRUE@am__append_79 = client/cm
- at TOOLS_TRUE@am__append_80 = tools/wifi-scan tools/supplicant-test tools/dbus-test \
- at TOOLS_TRUE@			tools/addr-test tools/tap-test tools/polkit-test \
- at TOOLS_TRUE@							tools/portal-test
+ at NTPD_BUILTIN_TRUE@@NTPD_TRUE at am__append_79 = ntpd
+ at NTPD_BUILTIN_TRUE@@NTPD_TRUE at am__append_80 = plugins/ntpd.c
+ at NTPD_BUILTIN_TRUE@@NTPD_TRUE at am__append_81 = -DNTPD=\"@NTPD@\"
+ at NTPD_BUILTIN_FALSE@@NTPD_TRUE at am__append_82 = plugins/ntpd.la
+ at NTPD_BUILTIN_FALSE@@NTPD_TRUE at am__append_83 = $(plugins_ntpd_la_OBJECTS)
+ at CLIENT_TRUE@am__append_84 = client/cm
+ at TOOLS_TRUE@am__append_85 = tools/wifi-scan tools/supplicant-test tools/dbus-test \
+ at TOOLS_TRUE@			tools/addr-test tools/tap-test tools/resolv-test \
+ at TOOLS_TRUE@					tools/polkit-test tools/portal-test
 
 subdir = .
 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
@@ -282,6 +287,15 @@
 	$(plugins_meego_la_LDFLAGS) $(LDFLAGS) -o $@
 @MEEGO_BUILTIN_FALSE@@MEEGO_TRUE at am_plugins_meego_la_rpath = -rpath \
 @MEEGO_BUILTIN_FALSE@@MEEGO_TRUE@	$(plugindir)
+plugins_ntpd_la_LIBADD =
+plugins_ntpd_la_SOURCES = plugins/ntpd.c
+plugins_ntpd_la_OBJECTS = plugins/plugins_ntpd_la-ntpd.lo
+plugins_ntpd_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC \
+	$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CCLD) \
+	$(plugins_ntpd_la_CFLAGS) $(CFLAGS) $(plugins_ntpd_la_LDFLAGS) \
+	$(LDFLAGS) -o $@
+ at NTPD_BUILTIN_FALSE@@NTPD_TRUE at am_plugins_ntpd_la_rpath = -rpath \
+ at NTPD_BUILTIN_FALSE@@NTPD_TRUE@	$(plugindir)
 plugins_ofono_la_LIBADD =
 plugins_ofono_la_SOURCES = plugins/ofono.c
 plugins_ofono_la_OBJECTS = plugins/plugins_ofono_la-ofono.lo
@@ -358,7 +372,8 @@
 @TOOLS_TRUE at am__EXEEXT_2 = tools/wifi-scan$(EXEEXT) \
 @TOOLS_TRUE@	tools/supplicant-test$(EXEEXT) \
 @TOOLS_TRUE@	tools/dbus-test$(EXEEXT) tools/addr-test$(EXEEXT) \
- at TOOLS_TRUE@	tools/tap-test$(EXEEXT) tools/polkit-test$(EXEEXT) \
+ at TOOLS_TRUE@	tools/tap-test$(EXEEXT) tools/resolv-test$(EXEEXT) \
+ at TOOLS_TRUE@	tools/polkit-test$(EXEEXT) \
 @TOOLS_TRUE@	tools/portal-test$(EXEEXT)
 @UDHCP_TRUE at am__EXEEXT_3 = scripts/udhcpc-script$(EXEEXT)
 @OPENCONNECT_TRUE at am__EXEEXT_4 = scripts/openconnect-script$(EXEEXT)
@@ -386,8 +401,8 @@
 	plugins/task.h plugins/task.c plugins/dhclient.c \
 	plugins/resolvconf.c plugins/openconnect.c plugins/portal.c \
 	plugins/dnsproxy.c plugins/google.c plugins/meego.c \
-	plugins/polkit.c src/main.c src/connman.h src/log.c \
-	src/selftest.c src/error.c src/plugin.c src/task.c \
+	plugins/polkit.c plugins/ntpd.c src/main.c src/connman.h \
+	src/log.c src/selftest.c src/error.c src/plugin.c src/task.c \
 	src/element.c src/device.c src/network.c src/connection.c \
 	src/manager.c src/profile.c src/service.c src/agent.c \
 	src/notifier.c src/provider.c src/security.c src/resolver.c \
@@ -421,14 +436,16 @@
 @MEEGO_BUILTIN_TRUE@@MEEGO_TRUE@	plugins/meego.$(OBJEXT)
 @POLKIT_BUILTIN_TRUE@@POLKIT_TRUE at am__objects_16 =  \
 @POLKIT_BUILTIN_TRUE@@POLKIT_TRUE@	plugins/polkit.$(OBJEXT)
-am__objects_17 = $(am__objects_2) $(am__objects_3) $(am__objects_4) \
+ at NTPD_BUILTIN_TRUE@@NTPD_TRUE at am__objects_17 = plugins/ntpd.$(OBJEXT)
+am__objects_18 = $(am__objects_2) $(am__objects_3) $(am__objects_4) \
 	$(am__objects_5) $(am__objects_6) $(am__objects_7) \
 	$(am__objects_8) $(am__objects_9) $(am__objects_10) \
 	$(am__objects_11) $(am__objects_12) $(am__objects_13) \
-	$(am__objects_14) $(am__objects_15) $(am__objects_16)
- at UDEV_TRUE@am__objects_18 = src/udev.$(OBJEXT)
- at UDEV_FALSE@am__objects_19 = src/udev-compat.$(OBJEXT)
-am_src_connmand_OBJECTS = $(am__objects_1) $(am__objects_17) \
+	$(am__objects_14) $(am__objects_15) $(am__objects_16) \
+	$(am__objects_17)
+ at UDEV_TRUE@am__objects_19 = src/udev.$(OBJEXT)
+ at UDEV_FALSE@am__objects_20 = src/udev-compat.$(OBJEXT)
+am_src_connmand_OBJECTS = $(am__objects_1) $(am__objects_18) \
 	src/main.$(OBJEXT) src/log.$(OBJEXT) src/selftest.$(OBJEXT) \
 	src/error.$(OBJEXT) src/plugin.$(OBJEXT) src/task.$(OBJEXT) \
 	src/element.$(OBJEXT) src/device.$(OBJEXT) \
@@ -443,7 +460,7 @@
 	src/wifi.$(OBJEXT) src/storage.$(OBJEXT) src/dbus.$(OBJEXT) \
 	src/config.$(OBJEXT) src/technology.$(OBJEXT) \
 	src/counter.$(OBJEXT) src/location.$(OBJEXT) \
-	src/session.$(OBJEXT) $(am__objects_18) $(am__objects_19)
+	src/session.$(OBJEXT) $(am__objects_19) $(am__objects_20)
 src_connmand_OBJECTS = $(am_src_connmand_OBJECTS)
 am__DEPENDENCIES_1 =
 am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1)
@@ -465,6 +482,9 @@
 tools_portal_test_SOURCES = tools/portal-test.c
 tools_portal_test_OBJECTS = tools/portal-test.$(OBJEXT)
 tools_portal_test_DEPENDENCIES =
+tools_resolv_test_SOURCES = tools/resolv-test.c
+tools_resolv_test_OBJECTS = tools/resolv-test.$(OBJEXT)
+tools_resolv_test_DEPENDENCIES =
 am__tools_supplicant_test_SOURCES_DIST = gdbus/gdbus.h \
 	gdbus/mainloop.c gdbus/object.c gdbus/watch.c \
 	tools/supplicant-test.c tools/supplicant-dbus.h \
@@ -512,29 +532,31 @@
 	plugins/ethernet.c plugins/fake.c plugins/google.c \
 	plugins/hh2serial-gps.c plugins/iospm.c \
 	$(plugins_iwmxsdk_la_SOURCES) plugins/loopback.c \
-	plugins/meego.c plugins/ofono.c plugins/openconnect.c \
-	plugins/polkit.c plugins/portal.c plugins/resolvconf.c \
-	$(plugins_udhcp_la_SOURCES) $(plugins_wifi_la_SOURCES) \
-	$(client_cm_SOURCES) scripts/dhclient-script.c \
-	scripts/openconnect-script.c scripts/udhcpc-script.c \
-	$(src_connmand_SOURCES) tools/addr-test.c \
-	$(tools_dbus_test_SOURCES) tools/polkit-test.c \
-	tools/portal-test.c $(tools_supplicant_test_SOURCES) \
-	tools/tap-test.c tools/wifi-scan.c
+	plugins/meego.c plugins/ntpd.c plugins/ofono.c \
+	plugins/openconnect.c plugins/polkit.c plugins/portal.c \
+	plugins/resolvconf.c $(plugins_udhcp_la_SOURCES) \
+	$(plugins_wifi_la_SOURCES) $(client_cm_SOURCES) \
+	scripts/dhclient-script.c scripts/openconnect-script.c \
+	scripts/udhcpc-script.c $(src_connmand_SOURCES) \
+	tools/addr-test.c $(tools_dbus_test_SOURCES) \
+	tools/polkit-test.c tools/portal-test.c tools/resolv-test.c \
+	$(tools_supplicant_test_SOURCES) tools/tap-test.c \
+	tools/wifi-scan.c
 DIST_SOURCES = plugins/bluetooth.c plugins/dhclient.c \
 	plugins/dnsproxy.c plugins/ethernet.c plugins/fake.c \
 	plugins/google.c plugins/hh2serial-gps.c plugins/iospm.c \
 	$(am__plugins_iwmxsdk_la_SOURCES_DIST) plugins/loopback.c \
-	plugins/meego.c plugins/ofono.c plugins/openconnect.c \
-	plugins/polkit.c plugins/portal.c plugins/resolvconf.c \
-	$(am__plugins_udhcp_la_SOURCES_DIST) \
+	plugins/meego.c plugins/ntpd.c plugins/ofono.c \
+	plugins/openconnect.c plugins/polkit.c plugins/portal.c \
+	plugins/resolvconf.c $(am__plugins_udhcp_la_SOURCES_DIST) \
 	$(am__plugins_wifi_la_SOURCES_DIST) \
 	$(am__client_cm_SOURCES_DIST) scripts/dhclient-script.c \
 	scripts/openconnect-script.c scripts/udhcpc-script.c \
 	$(am__src_connmand_SOURCES_DIST) tools/addr-test.c \
 	$(am__tools_dbus_test_SOURCES_DIST) tools/polkit-test.c \
-	tools/portal-test.c $(am__tools_supplicant_test_SOURCES_DIST) \
-	tools/tap-test.c tools/wifi-scan.c
+	tools/portal-test.c tools/resolv-test.c \
+	$(am__tools_supplicant_test_SOURCES_DIST) tools/tap-test.c \
+	tools/wifi-scan.c
 DATA = $(dbus_DATA) $(pkgconfig_DATA) $(policy_DATA) $(script_DATA)
 HEADERS = $(include_HEADERS) $(nodist_include_HEADERS) \
 	$(noinst_HEADERS)
@@ -610,6 +632,7 @@
 NETLINK_LIBS = @NETLINK_LIBS@
 NM = @NM@
 NMEDIT = @NMEDIT@
+NTPD = @NTPD@
 OBJDUMP = @OBJDUMP@
 OBJEXT = @OBJEXT@
 OPENCONNECT = @OPENCONNECT@
@@ -716,26 +739,30 @@
 	$(am__append_30) $(am__append_35) $(am__append_40) \
 	$(am__append_45) $(am__append_49) $(am__append_53) \
 	$(am__append_57) $(am__append_61) $(am__append_67) \
-	$(am__append_69) $(am__append_71) $(am__append_73)
+	$(am__append_69) $(am__append_71) $(am__append_73) \
+	$(am__append_82)
 plugin_objects = $(am__append_6) $(am__append_10) $(am__append_14) \
 	$(am__append_18) $(am__append_22) $(am__append_26) \
 	$(am__append_31) $(am__append_36) $(am__append_41) \
 	$(am__append_46) $(am__append_50) $(am__append_54) \
 	$(am__append_58) $(am__append_62) $(am__append_68) \
-	$(am__append_70) $(am__append_72) $(am__append_74)
+	$(am__append_70) $(am__append_72) $(am__append_74) \
+	$(am__append_83)
 builtin_modules = $(am__append_3) $(am__append_7) $(am__append_11) \
 	$(am__append_15) $(am__append_19) $(am__append_23) \
 	$(am__append_27) $(am__append_32) $(am__append_37) \
 	$(am__append_42) $(am__append_47) $(am__append_51) \
-	$(am__append_55) $(am__append_59) $(am__append_63)
+	$(am__append_55) $(am__append_59) $(am__append_63) \
+	$(am__append_79)
 builtin_sources = $(am__append_4) $(am__append_8) $(am__append_12) \
 	$(am__append_16) $(am__append_20) $(am__append_24) \
 	$(am__append_28) $(am__append_33) $(am__append_38) \
 	$(am__append_43) $(am__append_48) $(am__append_52) \
-	$(am__append_56) $(am__append_60) $(am__append_64)
+	$(am__append_56) $(am__append_60) $(am__append_64) \
+	$(am__append_80)
 builtin_libadd = $(am__append_65)
 builtin_cflags = $(am__append_29) $(am__append_34) $(am__append_39) \
-	$(am__append_44) $(am__append_66)
+	$(am__append_44) $(am__append_66) $(am__append_81)
 src_connmand_SOURCES = $(gdbus_sources) $(builtin_sources) src/main.c \
 	src/connman.h src/log.c src/selftest.c src/error.c \
 	src/plugin.c src/task.c src/element.c src/device.c \
@@ -842,6 +869,8 @@
 @UDHCP_TRUE at scripts_udhcpc_script_LDADD = @DBUS_LIBS@
 @OPENCONNECT_TRUE at scripts_openconnect_script_LDADD = @DBUS_LIBS@
 @DHCLIENT_TRUE at scripts_dhclient_script_LDADD = @DBUS_LIBS@
+ at NTPD_BUILTIN_FALSE@@NTPD_TRUE at plugins_ntpd_la_CFLAGS = $(plugin_cflags) -DNTPD=\"@NTPD@\"
+ at NTPD_BUILTIN_FALSE@@NTPD_TRUE at plugins_ntpd_la_LDFLAGS = $(plugin_ldflags)
 @CLIENT_TRUE at client_cm_SOURCES = client/main.c
 @CLIENT_TRUE at client_cm_LDADD = @DBUS_LIBS@
 @TOOLS_TRUE at tools_wifi_scan_LDADD = @GLIB_LIBS@ @NETLINK_LIBS@
@@ -852,6 +881,7 @@
 @TOOLS_TRUE at tools_supplicant_test_LDADD = @GLIB_LIBS@ @DBUS_LIBS@
 @TOOLS_TRUE at tools_dbus_test_SOURCES = $(gdbus_sources) tools/dbus-test.c
 @TOOLS_TRUE at tools_dbus_test_LDADD = @GLIB_LIBS@ @DBUS_LIBS@
+ at TOOLS_TRUE@tools_resolv_test_LDADD = -lresolv
 @TOOLS_TRUE at tools_polkit_test_LDADD = @DBUS_LIBS@
 @TOOLS_TRUE at tools_portal_test_LDADD = @GLIB_LIBS@
 test_scripts = test/get-state test/list-profiles test/list-services \
@@ -862,7 +892,9 @@
 		test/simple-agent test/show-introspection test/test-compat \
 		test/test-manager test/test-connman test/monitor-connman \
 		test/connect-vpn test/disconnect-vpn test/list-providers \
-		test/monitor-manager test/test-counter test/set-ip-method
+		test/monitor-manager test/test-counter test/set-ip-method \
+		test/set-nameservers test/set-domains test/find-service \
+		test/get-services
 
 @TEST_TRUE at testdir = $(pkglibdir)/test
 @TEST_TRUE at test_SCRIPTS = $(test_scripts)
@@ -885,6 +917,7 @@
 				--enable-client \
 				--enable-portal \
 				--enable-hh2serial-gps \
+				--enable-ntpd \
 				--enable-tools
 
 DISTCLEANFILES = $(pkgconfig_DATA)
@@ -1072,6 +1105,10 @@
 	plugins/$(DEPDIR)/$(am__dirstamp)
 plugins/meego.la: $(plugins_meego_la_OBJECTS) $(plugins_meego_la_DEPENDENCIES) plugins/$(am__dirstamp)
 	$(AM_V_CCLD)$(plugins_meego_la_LINK) $(am_plugins_meego_la_rpath) $(plugins_meego_la_OBJECTS) $(plugins_meego_la_LIBADD) $(LIBS)
+plugins/plugins_ntpd_la-ntpd.lo: plugins/$(am__dirstamp) \
+	plugins/$(DEPDIR)/$(am__dirstamp)
+plugins/ntpd.la: $(plugins_ntpd_la_OBJECTS) $(plugins_ntpd_la_DEPENDENCIES) plugins/$(am__dirstamp)
+	$(AM_V_CCLD)$(plugins_ntpd_la_LINK) $(am_plugins_ntpd_la_rpath) $(plugins_ntpd_la_OBJECTS) $(plugins_ntpd_la_LIBADD) $(LIBS)
 plugins/plugins_ofono_la-ofono.lo: plugins/$(am__dirstamp) \
 	plugins/$(DEPDIR)/$(am__dirstamp)
 plugins/ofono.la: $(plugins_ofono_la_OBJECTS) $(plugins_ofono_la_DEPENDENCIES) plugins/$(am__dirstamp)
@@ -1277,6 +1314,8 @@
 	plugins/$(DEPDIR)/$(am__dirstamp)
 plugins/polkit.$(OBJEXT): plugins/$(am__dirstamp) \
 	plugins/$(DEPDIR)/$(am__dirstamp)
+plugins/ntpd.$(OBJEXT): plugins/$(am__dirstamp) \
+	plugins/$(DEPDIR)/$(am__dirstamp)
 src/$(am__dirstamp):
 	@$(MKDIR_P) src
 	@: > src/$(am__dirstamp)
@@ -1372,6 +1411,11 @@
 tools/portal-test$(EXEEXT): $(tools_portal_test_OBJECTS) $(tools_portal_test_DEPENDENCIES) tools/$(am__dirstamp)
 	@rm -f tools/portal-test$(EXEEXT)
 	$(AM_V_CCLD)$(LINK) $(tools_portal_test_OBJECTS) $(tools_portal_test_LDADD) $(LIBS)
+tools/resolv-test.$(OBJEXT): tools/$(am__dirstamp) \
+	tools/$(DEPDIR)/$(am__dirstamp)
+tools/resolv-test$(EXEEXT): $(tools_resolv_test_OBJECTS) $(tools_resolv_test_DEPENDENCIES) tools/$(am__dirstamp)
+	@rm -f tools/resolv-test$(EXEEXT)
+	$(AM_V_CCLD)$(LINK) $(tools_resolv_test_OBJECTS) $(tools_resolv_test_LDADD) $(LIBS)
 tools/supplicant-test.$(OBJEXT): tools/$(am__dirstamp) \
 	tools/$(DEPDIR)/$(am__dirstamp)
 tools/supplicant-dbus.$(OBJEXT): tools/$(am__dirstamp) \
@@ -1440,6 +1484,7 @@
 	-rm -f plugins/hh2serial-gps.$(OBJEXT)
 	-rm -f plugins/loopback.$(OBJEXT)
 	-rm -f plugins/meego.$(OBJEXT)
+	-rm -f plugins/ntpd.$(OBJEXT)
 	-rm -f plugins/ofono.$(OBJEXT)
 	-rm -f plugins/openconnect.$(OBJEXT)
 	-rm -f plugins/plugins_bluetooth_la-bluetooth.$(OBJEXT)
@@ -1466,6 +1511,8 @@
 	-rm -f plugins/plugins_loopback_la-loopback.lo
 	-rm -f plugins/plugins_meego_la-meego.$(OBJEXT)
 	-rm -f plugins/plugins_meego_la-meego.lo
+	-rm -f plugins/plugins_ntpd_la-ntpd.$(OBJEXT)
+	-rm -f plugins/plugins_ntpd_la-ntpd.lo
 	-rm -f plugins/plugins_ofono_la-ofono.$(OBJEXT)
 	-rm -f plugins/plugins_ofono_la-ofono.lo
 	-rm -f plugins/plugins_openconnect_la-openconnect.$(OBJEXT)
@@ -1534,6 +1581,7 @@
 	-rm -f tools/dbus-test.$(OBJEXT)
 	-rm -f tools/polkit-test.$(OBJEXT)
 	-rm -f tools/portal-test.$(OBJEXT)
+	-rm -f tools/resolv-test.$(OBJEXT)
 	-rm -f tools/supplicant-dbus.$(OBJEXT)
 	-rm -f tools/supplicant-test.$(OBJEXT)
 	-rm -f tools/supplicant.$(OBJEXT)
@@ -1555,6 +1603,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote at plugins/$(DEPDIR)/hh2serial-gps.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at plugins/$(DEPDIR)/loopback.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at plugins/$(DEPDIR)/meego.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at plugins/$(DEPDIR)/ntpd.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at plugins/$(DEPDIR)/ofono.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at plugins/$(DEPDIR)/openconnect.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at plugins/$(DEPDIR)/plugins_bluetooth_la-bluetooth.Plo at am__quote@
@@ -1569,6 +1618,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote at plugins/$(DEPDIR)/plugins_iwmxsdk_la-iwmxsdk.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at plugins/$(DEPDIR)/plugins_loopback_la-loopback.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at plugins/$(DEPDIR)/plugins_meego_la-meego.Plo at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at plugins/$(DEPDIR)/plugins_ntpd_la-ntpd.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at plugins/$(DEPDIR)/plugins_ofono_la-ofono.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at plugins/$(DEPDIR)/plugins_openconnect_la-openconnect.Plo at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at plugins/$(DEPDIR)/plugins_polkit_la-polkit.Plo at am__quote@
@@ -1628,6 +1678,7 @@
 @AMDEP_TRUE@@am__include@ @am__quote at tools/$(DEPDIR)/dbus-test.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at tools/$(DEPDIR)/polkit-test.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at tools/$(DEPDIR)/portal-test.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at tools/$(DEPDIR)/resolv-test.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at tools/$(DEPDIR)/supplicant-dbus.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at tools/$(DEPDIR)/supplicant-test.Po at am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote at tools/$(DEPDIR)/supplicant.Po at am__quote@
@@ -1757,6 +1808,14 @@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@	$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(plugins_meego_la_CFLAGS) $(CFLAGS) -c -o plugins/plugins_meego_la-meego.lo `test -f 'plugins/meego.c' || echo '$(srcdir)/'`plugins/meego.c
 
+plugins/plugins_ntpd_la-ntpd.lo: plugins/ntpd.c
+ at am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(plugins_ntpd_la_CFLAGS) $(CFLAGS) -MT plugins/plugins_ntpd_la-ntpd.lo -MD -MP -MF plugins/$(DEPDIR)/plugins_ntpd_la-ntpd.Tpo -c -o plugins/plugins_ntpd_la-ntpd.lo `test -f 'plugins/ntpd.c' || echo '$(srcdir)/'`plugins/ntpd.c
+ at am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) plugins/$(DEPDIR)/plugins_ntpd_la-ntpd.Tpo plugins/$(DEPDIR)/plugins_ntpd_la-ntpd.Plo
+ at am__fastdepCC_FALSE@	$(AM_V_CC) @AM_BACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	source='plugins/ntpd.c' object='plugins/plugins_ntpd_la-ntpd.lo' libtool=yes @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCC_FALSE@	$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(plugins_ntpd_la_CFLAGS) $(CFLAGS) -c -o plugins/plugins_ntpd_la-ntpd.lo `test -f 'plugins/ntpd.c' || echo '$(srcdir)/'`plugins/ntpd.c
+
 plugins/plugins_ofono_la-ofono.lo: plugins/ofono.c
 @am__fastdepCC_TRUE@	$(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(plugins_ofono_la_CFLAGS) $(CFLAGS) -MT plugins/plugins_ofono_la-ofono.lo -MD -MP -MF plugins/$(DEPDIR)/plugins_ofono_la-ofono.Tpo -c -o plugins/plugins_ofono_la-ofono.lo `test -f 'plugins/ofono.c' || echo '$(srcdir)/'`plugins/ofono.c
 @am__fastdepCC_TRUE@	$(AM_V_at)$(am__mv) plugins/$(DEPDIR)/plugins_ofono_la-ofono.Tpo plugins/$(DEPDIR)/plugins_ofono_la-ofono.Plo
@@ -2356,8 +2415,8 @@
 	$(AM_V_at)$(MKDIR_P) include/connman
 	$(AM_V_GEN)$(LN_S) $(abs_top_srcdir)/$< $@
 
-clean-local: include/connman
-	@$(RM) -r $<
+clean-local:
+	@$(RM) -rf include/connman
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
--- Makefile.plugins
+++ Makefile.plugins
@@ -249,6 +249,18 @@
 scripts_dhclient_script_LDADD = @DBUS_LIBS@
 endif
 
+if NTPD
+if NTPD_BUILTIN
+builtin_modules += ntpd
+builtin_sources += plugins/ntpd.c
+builtin_cflags += -DNTPD=\"@NTPD@\"
+else
+plugin_LTLIBRARIES += plugins/ntpd.la
+plugin_objects += $(plugins_ntpd_la_OBJECTS)
+plugins_ntpd_la_CFLAGS = $(plugin_cflags) -DNTPD=\"@NTPD@\"
+plugins_ntpd_la_LDFLAGS = $(plugin_ldflags)
+endif
+endif
 
 EXTRA_DIST += plugins/polkit.policy scripts/dhclient.conf
 
--- TODO
+++ TODO
@@ -1,32 +1,10 @@
 
-  o Support for WPA/WPA2 Enterprise WiFi authentication
-
-	With wpa_supplicant the support for WPA/WPA2 Enterprise is already
-	present, but it needs properly hooked up. This involves a correct
-	security architecture since it uses personalized credentials.
-
   o Support for WPS based WiFi authentication
 
 	Newer versions of wpa_supplicant contain support for WPS. For full
 	integration of WPS support, the agent concept needs to be extended.
 
-  o Support for multiple profiles
-
-	Currently only one active profile (the default profile) is supported.
-
-  o Support for static IPv4 configuration
-
-	This is in theory possible, but no D-Bus API has been defined on how
-	to configure it.
-
   o Support for interface statistics
 
 	Information about carrier speed etc. should be exported.
 
-  o Support for handling RFKILL events
-
-	The RFKILL events are received via the udev infrastructure, but not
-	acted upon. Current problem is to assign the event to the correct
-	physical device. In case of platform RFKILL switches this is a real
-	problem and not solved yet.
-
--- client/main.c
+++ client/main.c
@@ -35,7 +35,13 @@
 #define CONNMAN_MANAGER_INTERFACE	CONNMAN_SERVICE ".Manager"
 #define CONNMAN_MANAGER_PATH		"/"
 
-static DBusMessage *get_properties(DBusConnection *connection)
+struct service_data {
+	const char *path;
+	const char *name;
+	dbus_bool_t favorite;
+};
+
+static DBusMessage *get_services(DBusConnection *connection)
 {
 	DBusMessage *message, *reply;
 	DBusError error;
@@ -43,7 +49,7 @@
 	message = dbus_message_new_method_call(CONNMAN_SERVICE,
 						CONNMAN_MANAGER_PATH,
 						CONNMAN_MANAGER_INTERFACE,
-							"GetProperties");
+							"GetServices");
 	if (message == NULL)
 		return NULL;
 
@@ -66,18 +72,49 @@
 	return reply;
 }
 
-static const char *extract_state(DBusMessage *message)
+static DBusMessage *lookup_service(DBusConnection *connection,
+							const char *pattern)
 {
-	DBusMessageIter array, dict;
+	DBusMessage *message, *reply;
+	DBusError error;
+
+	message = dbus_message_new_method_call(CONNMAN_SERVICE,
+						CONNMAN_MANAGER_PATH,
+						CONNMAN_MANAGER_INTERFACE,
+							"LookupService");
+	if (message == NULL)
+		return NULL;
+
+	dbus_message_append_args(message, DBUS_TYPE_STRING, &pattern,
+							DBUS_TYPE_INVALID);
+
+	dbus_error_init(&error);
+
+	reply = dbus_connection_send_with_reply_and_block(connection,
+							message, -1, &error);
+	if (reply == NULL) {
+		if (dbus_error_is_set(&error) == TRUE) {
+			fprintf(stderr, "%s\n", error.message);
+			dbus_error_free(&error);
+		} else
+			fprintf(stderr, "Failed to get properties\n");
+		dbus_message_unref(message);
+		return NULL;
+	}
 
-	dbus_message_iter_init(message, &array);
-	dbus_message_iter_recurse(&array, &dict);
+	dbus_message_unref(message);
+
+	return reply;
+}
 
-	while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
+static void extract_properties(DBusMessageIter *dict,
+					struct service_data *service)
+{
+	while (dbus_message_iter_get_arg_type(dict) == DBUS_TYPE_DICT_ENTRY) {
 		DBusMessageIter entry, value;
 		const char *key;
 
-		dbus_message_iter_recurse(&dict, &entry);
+		dbus_message_iter_recurse(dict, &entry);
 		dbus_message_iter_get_basic(&entry, &key);
 
 		dbus_message_iter_next(&entry);
@@ -87,94 +124,73 @@
 		//type = dbus_message_iter_get_arg_type(&value);
 		//dbus_message_iter_get_basic(&value, &val);
 
-		if (strcmp(key, "State") == 0) {
-			const char *val;
-			dbus_message_iter_get_basic(&value, &val);
-			return val;
-		}
+		if (strcmp(key, "Name") == 0)
+			dbus_message_iter_get_basic(&value, &service->name);
+		else if (strcmp(key, "Favorite") == 0)
+			dbus_message_iter_get_basic(&value, &service->favorite);
 
-		dbus_message_iter_next(&dict);
+		dbus_message_iter_next(dict);
 	}
-
-	return NULL;
 }
 
-static void print_objects(DBusMessageIter *array)
+static void extract_services(DBusMessage *message)
 {
-	DBusMessageIter value;
-
-	if (dbus_message_iter_get_arg_type(array) != DBUS_TYPE_ARRAY)
-		return;
+	DBusMessageIter iter, array;
 
-	dbus_message_iter_recurse(array, &value);
+	dbus_message_iter_init(message, &iter);
+	dbus_message_iter_recurse(&iter, &array);
 
-	while (dbus_message_iter_get_arg_type(&value) == DBUS_TYPE_OBJECT_PATH) {
+	while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_STRUCT) {
+		DBusMessageIter entry, dict;
+		struct service_data service;
 		const char *path;
 
-		dbus_message_iter_get_basic(&value, &path);
-
-		printf("%s\n", path);
-
-		dbus_message_iter_next(&value);
-	}
-}
-
-static void extract_devices(DBusMessage *message)
-{
-	DBusMessageIter array, dict;
+		dbus_message_iter_recurse(&array, &entry);
+		dbus_message_iter_get_basic(&entry, &path);
 
-	dbus_message_iter_init(message, &array);
-	dbus_message_iter_recurse(&array, &dict);
-
-	while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
-		DBusMessageIter entry, value;
-		const char *key;
-
-		dbus_message_iter_recurse(&dict, &entry);
-		dbus_message_iter_get_basic(&entry, &key);
+		service.path = strrchr(path, '/') + 1;
 
 		dbus_message_iter_next(&entry);
 
-		dbus_message_iter_recurse(&entry, &value);
+		dbus_message_iter_recurse(&entry, &dict);
+		extract_properties(&dict, &service);
 
-		//type = dbus_message_iter_get_arg_type(&value);
-		//dbus_message_iter_get_basic(&value, &val);
+		printf("%c %-20s { %-50s }\n",
+				service.favorite == TRUE ? '*' : ' ',
+						service.name, service.path);
 
-		if (strcmp(key, "Devices") == 0) {
-			print_objects(&value);
-			return;
-		}
-
-		dbus_message_iter_next(&dict);
+		dbus_message_iter_next(&array);
 	}
 }
 
-static int cmd_status(DBusConnection *connection)
+static int cmd_list_services(DBusConnection *connection)
 {
 	DBusMessage *message;
-	const char *state;
 
-	message = get_properties(connection);
+	message = get_services(connection);
+	if (message == NULL)
+		return -1;
 
-	state = extract_state(message);
+	extract_services(message);
 
 	dbus_message_unref(message);
 
-	if (state == NULL)
-		return -EINVAL;
-
-	printf("System is %s\n", state);
-
 	return 0;
 }
 
-static int cmd_devices(DBusConnection *connection)
+static int cmd_show_service(DBusConnection *connection, const char *pattern)
 {
 	DBusMessage *message;
+	const char *path;
+
+	message = lookup_service(connection, pattern);
+	if (message == NULL)
+		return -1;
 
-	message = get_properties(connection);
+	dbus_message_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &path,
+							DBUS_TYPE_INVALID);
 
-	extract_devices(message);
+	printf("Service: %s\n", path);
 
 	dbus_message_unref(message);
 
@@ -186,11 +202,12 @@
 	printf("ConnMan utility ver %s\n\n", VERSION);
 
 	printf("Usage:\n"
-		"\t%s <command>\n\n", program);
+		"\t%s <command> [options]\n\n", program);
 
 	printf("Commands:\n"
 		"\thelp\n"
-		"\tdev\n"
+		"\tlist\n"
+		"\tshow <service>\n"
 		"\n");
 }
 
@@ -210,10 +227,16 @@
 	}
 
 	if (argc > 1) {
-		if (strcmp(argv[1], "dev") == 0)
-			cmd_devices(conn);
+		if (strcmp(argv[1], "list") == 0)
+			cmd_list_services(conn);
+		else if (strcmp(argv[1], "show") == 0) {
+			if (argc > 2)
+				cmd_show_service(conn, argv[2]);
+			else
+				usage(argv[0]);
+		}
 	} else
-		cmd_status(conn);
+		usage(argv[0]);
 
 	dbus_connection_unref(conn);
 
--- config.h.in
+++ config.h.in
@@ -3,6 +3,9 @@
 /* Define to 1 if you have capabilities library. */
 #undef HAVE_CAPNG
 
+/* Define to 1 if you have dhclient hostname support. */
+#undef HAVE_DHCLIENT_HOSTNAME
+
 /* Define to 1 if you have the <dlfcn.h> header file. */
 #undef HAVE_DLFCN_H
 
@@ -15,6 +18,9 @@
 /* Define to 1 if you have the <memory.h> header file. */
 #undef HAVE_MEMORY_H
 
+/* Define to 1 if you have the <resolv.h> header file. */
+#undef HAVE_RESOLV_H
+
 /* Define to 1 if you have the <stdint.h> header file. */
 #undef HAVE_STDINT_H
 
--- configure
+++ configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.63 for connman 0.52.
+# Generated by GNU Autoconf 2.63 for connman 0.54.
 #
 # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
 # 2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
@@ -743,8 +743,8 @@
 # Identity of this package.
 PACKAGE_NAME='connman'
 PACKAGE_TARNAME='connman'
-PACKAGE_VERSION='0.52'
-PACKAGE_STRING='connman 0.52'
+PACKAGE_VERSION='0.54'
+PACKAGE_STRING='connman 0.54'
 PACKAGE_BUGREPORT=''
 
 ac_default_prefix=/usr/local
@@ -821,6 +821,11 @@
 GTHREAD_CFLAGS
 GLIB_LIBS
 GLIB_CFLAGS
+NTPD_BUILTIN_FALSE
+NTPD_BUILTIN_TRUE
+NTPD_FALSE
+NTPD_TRUE
+NTPD
 IOSPM_FALSE
 IOSPM_TRUE
 IWMX_FALSE
@@ -1045,6 +1050,8 @@
 with_iwmxsdk
 enable_iwmx
 enable_iospm
+with_ntpd
+enable_ntpd
 with_dbusconf
 enable_polkit
 enable_client
@@ -1633,7 +1640,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures connman 0.52 to adapt to many kinds of systems.
+\`configure' configures connman 0.54 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1703,7 +1710,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of connman 0.52:";;
+     short | recursive ) echo "Configuration of connman 0.54:";;
    esac
   cat <<\_ACEOF
 
@@ -1743,6 +1750,7 @@
   --enable-meego          enable MeeGo features support
   --enable-iwmx           enable Intel WiMAX support
   --enable-iospm          enable Intel OSPM support
+  --enable-ntpd           enable ntpd support
   --enable-polkit         enable PolicyKit support
   --enable-client         enable command line client
   --enable-tools          enable testing tools
@@ -1766,6 +1774,7 @@
   --with-openconnect=PROGRAM
                           specify location of openconnect binary
   --with-iwmxsdk=PATH     path to Intel WiMAX SDK
+  --with-=PROGRAM         specify ntpd binary location
   --with-dbusconf=PATH    path to D-Bus config directory
 
 Some influential environment variables:
@@ -1868,7 +1877,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-connman configure 0.52
+connman configure 0.54
 generated by GNU Autoconf 2.63
 
 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1882,7 +1891,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by connman $as_me 0.52, which was
+It was created by connman $as_me 0.54, which was
 generated by GNU Autoconf 2.63.  Invocation command line was
 
   $ $0 $@
@@ -2732,7 +2741,7 @@
 
 # Define the identity of the package.
  PACKAGE='connman'
- VERSION='0.52'
+ VERSION='0.54'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -5178,13 +5187,13 @@
 else
   lt_cv_nm_interface="BSD nm"
   echo "int some_variable = 0;" > conftest.$ac_ext
-  (eval echo "\"\$as_me:5181: $ac_compile\"" >&5)
+  (eval echo "\"\$as_me:5190: $ac_compile\"" >&5)
   (eval "$ac_compile" 2>conftest.err)
   cat conftest.err >&5
-  (eval echo "\"\$as_me:5184: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+  (eval echo "\"\$as_me:5193: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
   (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
   cat conftest.err >&5
-  (eval echo "\"\$as_me:5187: output\"" >&5)
+  (eval echo "\"\$as_me:5196: output\"" >&5)
   cat conftest.out >&5
   if $GREP 'External.*some_variable' conftest.out > /dev/null; then
     lt_cv_nm_interface="MS dumpbin"
@@ -6390,7 +6399,7 @@
   ;;
 *-*-irix6*)
   # Find out which ABI we are using.
-  echo '#line 6393 "configure"' > conftest.$ac_ext
+  echo '#line 6402 "configure"' > conftest.$ac_ext
   if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
@@ -8213,11 +8222,11 @@
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:8216: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:8225: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:8220: \$? = $ac_status" >&5
+   echo "$as_me:8229: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -8552,11 +8561,11 @@
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:8555: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:8564: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:8559: \$? = $ac_status" >&5
+   echo "$as_me:8568: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -8657,11 +8666,11 @@
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:8660: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:8669: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:8664: \$? = $ac_status" >&5
+   echo "$as_me:8673: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -8712,11 +8721,11 @@
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:8715: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:8724: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:8719: \$? = $ac_status" >&5
+   echo "$as_me:8728: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -11515,7 +11524,7 @@
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11518 "configure"
+#line 11527 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -11611,7 +11620,7 @@
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 11614 "configure"
+#line 11623 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -12009,13 +12018,13 @@
 else
   lt_cv_nm_interface="BSD nm"
   echo "int some_variable = 0;" > conftest.$ac_ext
-  (eval echo "\"\$as_me:12012: $ac_compile\"" >&5)
+  (eval echo "\"\$as_me:12021: $ac_compile\"" >&5)
   (eval "$ac_compile" 2>conftest.err)
   cat conftest.err >&5
-  (eval echo "\"\$as_me:12015: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
+  (eval echo "\"\$as_me:12024: $NM \\\"conftest.$ac_objext\\\"\"" >&5)
   (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out)
   cat conftest.err >&5
-  (eval echo "\"\$as_me:12018: output\"" >&5)
+  (eval echo "\"\$as_me:12027: output\"" >&5)
   cat conftest.out >&5
   if $GREP 'External.*some_variable' conftest.out > /dev/null; then
     lt_cv_nm_interface="MS dumpbin"
@@ -12474,6 +12483,18 @@
 		DHCLIENT="${path_dhclient}"
 
 	fi
+	{ $as_echo "$as_me:$LINENO: checking dhclient major version" >&5
+$as_echo_n "checking dhclient major version... " >&6; }
+	version_dhclient=`${DHCLIENT} --version 2>&1 | sed '/^isc-dhclient-*/!d; s///; s/\..*//;q'`
+	{ $as_echo "$as_me:$LINENO: result: ${version_dhclient}" >&5
+$as_echo "${version_dhclient}" >&6; }
+	if (test "${version_dhclient}" = "4"); then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_DHCLIENT_HOSTNAME 1
+_ACEOF
+
+	fi
 fi
  if test "${enable_dhclient}" != "no"; then
   DHCLIENT_TRUE=
@@ -12586,8 +12607,8 @@
 fi
 
 if (test "${enable_openconnect}" != "no"); then
-        if (test -z "${path_openconnect}"); then
-                # Extract the first word of "openconnect", so it can be a program name with args.
+	if (test -z "${path_openconnect}"); then
+		# Extract the first word of "openconnect", so it can be a program name with args.
 set dummy openconnect; ac_word=$2
 { $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
 $as_echo_n "checking for $ac_word... " >&6; }
@@ -12628,10 +12649,10 @@
 fi
 
 
-        else
-                OPENCONNECT="${path_openconnect}"
+	else
+		OPENCONNECT="${path_openconnect}"
 
-        fi
+	fi
 fi
  if test "${enable_openconnect}" != "no"; then
   OPENCONNECT_TRUE=
@@ -12931,6 +12952,231 @@
   enable_dnsproxy="no"
 fi
 
+if (test "${enable_dnsproxy}" != "no"); then
+
+for ac_header in resolv.h
+do
+as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  { $as_echo "$as_me:$LINENO: checking for $ac_header" >&5
+$as_echo_n "checking for $ac_header... " >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  $as_echo_n "(cached) " >&6
+fi
+ac_res=`eval 'as_val=${'$as_ac_Header'}
+		 $as_echo "$as_val"'`
+	       { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ $as_echo "$as_me:$LINENO: checking $ac_header usability" >&5
+$as_echo_n "checking $ac_header usability... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_header_compiler=yes
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:$LINENO: checking $ac_header presence" >&5
+$as_echo_n "checking $ac_header presence... " >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null && {
+	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       }; then
+  ac_header_preproc=yes
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ $as_echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { $as_echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { $as_echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { $as_echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { $as_echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { $as_echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { $as_echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+$as_echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { $as_echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+$as_echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+
+    ;;
+esac
+{ $as_echo "$as_me:$LINENO: checking for $ac_header" >&5
+$as_echo_n "checking for $ac_header... " >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  $as_echo_n "(cached) " >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+ac_res=`eval 'as_val=${'$as_ac_Header'}
+		 $as_echo "$as_val"'`
+	       { $as_echo "$as_me:$LINENO: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+
+fi
+as_val=`eval 'as_val=${'$as_ac_Header'}
+		 $as_echo "$as_val"'`
+   if test "x$as_val" = x""yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+ dummy=yes
+else
+  { { $as_echo "$as_me:$LINENO: error: resolver header files are required" >&5
+$as_echo "$as_me: error: resolver header files are required" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+done
+
+	{ $as_echo "$as_me:$LINENO: checking for ns_initparse in -lresolv" >&5
+$as_echo_n "checking for ns_initparse in -lresolv... " >&6; }
+if test "${ac_cv_lib_resolv_ns_initparse+set}" = set; then
+  $as_echo_n "(cached) " >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lresolv  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char ns_initparse ();
+int
+main ()
+{
+return ns_initparse ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:$LINENO: $ac_try_echo\""
+$as_echo "$ac_try_echo") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  $as_echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+	 test -z "$ac_c_werror_flag" ||
+	 test ! -s conftest.err
+       } && test -s conftest$ac_exeext && {
+	 test "$cross_compiling" = yes ||
+	 $as_test_x conftest$ac_exeext
+       }; then
+  ac_cv_lib_resolv_ns_initparse=yes
+else
+  $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+	ac_cv_lib_resolv_ns_initparse=no
+fi
+
+rm -rf conftest.dSYM
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ $as_echo "$as_me:$LINENO: result: $ac_cv_lib_resolv_ns_initparse" >&5
+$as_echo "$ac_cv_lib_resolv_ns_initparse" >&6; }
+if test "x$ac_cv_lib_resolv_ns_initparse" = x""yes; then
+  dummy=yes
+else
+  { { $as_echo "$as_me:$LINENO: error: resolver library support is required" >&5
+$as_echo "$as_me: error: resolver library support is required" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+fi
  if test "${enable_dnsproxy}" != "no"; then
   DNSPROXY_TRUE=
   DNSPROXY_FALSE='#'
@@ -13679,6 +13925,86 @@
 
 
 
+# Check whether --with-ntpd was given.
+if test "${with_ntpd+set}" = set; then
+  withval=$with_ntpd; path_ntpd=${withval}
+fi
+
+
+# Check whether --enable-ntpd was given.
+if test "${enable_ntpd+set}" = set; then
+  enableval=$enable_ntpd; enable_ntpd=${enableval}
+else
+  enable_ntpd="no"
+fi
+
+
+if (test "${enable_ntpd}" != "no"); then
+	if (test -z "${path_ntpd}"); then
+		# Extract the first word of "ntpd", so it can be a program name with args.
+set dummy ntpd; ac_word=$2
+{ $as_echo "$as_me:$LINENO: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if test "${ac_cv_path_NTPD+set}" = set; then
+  $as_echo_n "(cached) " >&6
+else
+  case $NTPD in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_NTPD="$NTPD" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_dummy="$PATH:/sbin:/usr/sbin"
+for as_dir in $as_dummy
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_NTPD="$as_dir/$ac_word$ac_exec_ext"
+    $as_echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+NTPD=$ac_cv_path_NTPD
+if test -n "$NTPD"; then
+  { $as_echo "$as_me:$LINENO: result: $NTPD" >&5
+$as_echo "$NTPD" >&6; }
+else
+  { $as_echo "$as_me:$LINENO: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+	else
+		NTPD="${path_ntpd}"
+
+	fi
+fi
+ if test "${enable_ntpd}" != "no"; then
+  NTPD_TRUE=
+  NTPD_FALSE='#'
+else
+  NTPD_TRUE='#'
+  NTPD_FALSE=
+fi
+
+ if test "${enable_ntpd}" = "builtin"; then
+  NTPD_BUILTIN_TRUE=
+  NTPD_BUILTIN_FALSE='#'
+else
+  NTPD_BUILTIN_TRUE='#'
+  NTPD_BUILTIN_FALSE=
+fi
+
+
+
 pkg_failed=no
 { $as_echo "$as_me:$LINENO: checking for GLIB" >&5
 $as_echo_n "checking for GLIB... " >&6; }
@@ -14778,6 +15104,20 @@
 Usually this means the macro was only invoked conditionally." >&2;}
    { (exit 1); exit 1; }; }
 fi
+if test -z "${NTPD_TRUE}" && test -z "${NTPD_FALSE}"; then
+  { { $as_echo "$as_me:$LINENO: error: conditional \"NTPD\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+$as_echo "$as_me: error: conditional \"NTPD\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "${NTPD_BUILTIN_TRUE}" && test -z "${NTPD_BUILTIN_FALSE}"; then
+  { { $as_echo "$as_me:$LINENO: error: conditional \"NTPD_BUILTIN\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+$as_echo "$as_me: error: conditional \"NTPD_BUILTIN\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
 if test -z "${POLKIT_TRUE}" && test -z "${POLKIT_FALSE}"; then
   { { $as_echo "$as_me:$LINENO: error: conditional \"POLKIT\" was never defined.
 Usually this means the macro was only invoked conditionally." >&5
@@ -15156,7 +15496,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by connman $as_me 0.52, which was
+This file was extended by connman $as_me 0.54, which was
 generated by GNU Autoconf 2.63.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -15219,7 +15559,7 @@
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_version="\\
-connman config.status 0.52
+connman config.status 0.54
 configured by $0, generated by GNU Autoconf 2.63,
   with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
 
--- configure.ac
+++ configure.ac
@@ -1,5 +1,5 @@
 AC_PREREQ(2.60)
-AC_INIT(connman, 0.52)
+AC_INIT(connman, 0.54)
 
 AM_INIT_AUTOMAKE([foreign subdir-objects])
 AM_CONFIG_HEADER(config.h)
@@ -87,8 +87,8 @@
 AM_CONDITIONAL(BLUETOOTH_BUILTIN, test "${enable_bluetooth}" = "builtin")
 
 AC_ARG_ENABLE(hh2serial-gps,
-        AC_HELP_STRING([--enable-hh2serial-gps], [enable hh2serial GPS support]),
-                        [enable_hh2serial_gps=${enableval}], [enable_hh2serial_gps="no"])
+	AC_HELP_STRING([--enable-hh2serial-gps], [enable hh2serial GPS support]),
+			[enable_hh2serial_gps=${enableval}], [enable_hh2serial_gps="no"])
 AM_CONDITIONAL(HH2SERIAL_GPS, test "${enable_hh2serial_gps}" != "no")
 AM_CONDITIONAL(HH2SERIAL_GPS_BUILTIN, test "${enable_hh2serial_gps}" = "builtin")
 
@@ -128,6 +128,12 @@
 		DHCLIENT="${path_dhclient}"
 		AC_SUBST(DHCLIENT)
 	fi
+	AC_MSG_CHECKING(dhclient major version)
+	version_dhclient=`${DHCLIENT} --version 2>&1 | sed '/^isc-dhclient-*/!d; s///; s/\..*//;q'`
+	AC_MSG_RESULT(${version_dhclient})
+	if (test "${version_dhclient}" = "4"); then
+		AC_DEFINE(HAVE_DHCLIENT_HOSTNAME, 1, [Define to 1 if you have dhclient hostname support.])
+	fi
 fi
 AM_CONDITIONAL(DHCLIENT, test "${enable_dhclient}" != "no")
 AM_CONDITIONAL(DHCLIENT_BUILTIN, test "${enable_dhclient}" = "builtin")
@@ -153,22 +159,22 @@
         [specify location of openconnect binary]), [path_openconnect=${withval}])
 
 AC_ARG_ENABLE(openconnect,
-        AC_HELP_STRING([--enable-openconnect], [enable openconnect support]),
-                        [enable_openconnect=${enableval}], [enable_openconnect="no"])
+	AC_HELP_STRING([--enable-openconnect], [enable openconnect support]),
+			[enable_openconnect=${enableval}], [enable_openconnect="no"])
 if (test "${enable_openconnect}" != "no"); then
-        if (test -z "${path_openconnect}"); then
-                AC_PATH_PROG(OPENCONNECT, [openconnect], [], $PATH:/sbin:/usr/sbin)
-        else
-                OPENCONNECT="${path_openconnect}"
-                AC_SUBST(OPENCONNECT)
-        fi
+	if (test -z "${path_openconnect}"); then
+		AC_PATH_PROG(OPENCONNECT, [openconnect], [], $PATH:/sbin:/usr/sbin)
+	else
+		OPENCONNECT="${path_openconnect}"
+		AC_SUBST(OPENCONNECT)
+	fi
 fi
 AM_CONDITIONAL(OPENCONNECT, test "${enable_openconnect}" != "no")
 AM_CONDITIONAL(OPENCONNECT_BUILTIN, test "${enable_openconnect}" = "builtin")
 
 AC_ARG_ENABLE(portal,
-        AC_HELP_STRING([--enable-portal], [enable portal detection support]),
-                        [enable_portal=${enableval}], [enable_portal="no"])
+	AC_HELP_STRING([--enable-portal], [enable portal detection support]),
+			[enable_portal=${enableval}], [enable_portal="no"])
 AM_CONDITIONAL(PORTAL, test "${enable_portal}" != "no")
 AM_CONDITIONAL(PORTAL_BUILTIN, test "${enable_portal}" = "builtin")
 
@@ -188,6 +194,12 @@
 AC_ARG_ENABLE(dnsproxy,
 	AC_HELP_STRING([--enable-dnsproxy], [enable DNS proxy support]),
 			[enable_dnsproxy=${enableval}], [enable_dnsproxy="no"])
+if (test "${enable_dnsproxy}" != "no"); then
+	AC_CHECK_HEADERS(resolv.h, dummy=yes,
+			AC_MSG_ERROR(resolver header files are required))
+	AC_CHECK_LIB(resolv, ns_initparse, dummy=yes,
+			AC_MSG_ERROR(resolver library support is required))
+fi
 AM_CONDITIONAL(DNSPROXY, test "${enable_dnsproxy}" != "no")
 AM_CONDITIONAL(DNSPROXY_BUILTIN, test "${enable_dnsproxy}" = "builtin")
 
@@ -268,6 +280,24 @@
 		[enable Intel OSPM support]), [enable_iospm=${enableval}])
 AM_CONDITIONAL(IOSPM, test "${enable_iospm}" = "yes")
 
+AC_ARG_WITH(ntpd, AC_HELP_STRING([--with-=PROGRAM],
+	[specify ntpd binary location]), [path_ntpd=${withval}])
+
+AC_ARG_ENABLE(ntpd,
+	AC_HELP_STRING([--enable-ntpd], [enable ntpd support]),
+			[enable_ntpd=${enableval}], [enable_ntpd="no"])
+
+if (test "${enable_ntpd}" != "no"); then
+	if (test -z "${path_ntpd}"); then
+		AC_PATH_PROG(NTPD, [ntpd], [], $PATH:/sbin:/usr/sbin)
+	else
+		NTPD="${path_ntpd}"
+		AC_SUBST(NTPD)
+	fi
+fi
+AM_CONDITIONAL(NTPD, test "${enable_ntpd}" != "no")
+AM_CONDITIONAL(NTPD_BUILTIN, test "${enable_ntpd}" = "builtin")
+
 PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.16, dummy=yes,
 				AC_MSG_ERROR(GLib >= 2.16 is required))
 AC_SUBST(GLIB_CFLAGS)
--- doc/config-format.txt
+++ doc/config-format.txt
@@ -3,7 +3,8 @@
 
 Connman uses configuration files to provision existing services. Connman will
 be looking for its configuration files at STORAGEDIR which by default points
-to /var/lib/connman/.
+to /var/lib/connman/. Configuration file names should follow the *.config
+pattern.
 Those configuration files are text files with a simple format and we typically
 have one file per provisioned network.
 
@@ -39,6 +40,7 @@
 to fsid.
 - Identity: Identity string for EAP.
 - Phase2: Phase2 (inner authentication with TLS tunnel) parameters.
+- Passphrase: RSN/WPA/WPA2 Passphrase
 
 
 Example
@@ -46,8 +48,10 @@
 
 This is a configuration file for a network providing both EAP-TLS and
 EAP-PEAP services.
-The respective SSIDs are tls_ssid and peap_ssid.
+The respective SSIDs are tls_ssid and peap_ssid and the file name is
+example.config.
 
+example at example:[~]$ cat /var/lib/connman/example.config
 [global]
 Name = Example
 Description = Example network configuration
--- doc/manager-api.txt
+++ doc/manager-api.txt
@@ -69,6 +69,30 @@
 
 			Possible Errors: [service].Error.InvalidArguments
 
+		arracy{object,dict} GetServices()
+
+			Returns a sorted list of tuples with service
+			object path and dictionary of service properties.
+
+			This list will not contain sensitive information
+			like passphrases etc.
+
+			Possible Errors: [service].Error.InvalidArguments
+
+		object LookupService(string pattern)
+
+			Lookup a service matching the specific pattern.
+
+			Examples are interface names like "eth0", "wlan0"
+			etc. or service names like "hotspot" etc.
+
+			In case of multiple services match the the pattern
+			an error is returned.
+
+			Possible Errors: [service].Error.InvalidArguments
+			                 [service].Error.NotUnique
+			                 [service].Error.NotFound
+
 		object ConnectService(dict network)
 
 			Connect to a network specified by the given
--- doc/service-api.txt
+++ doc/service-api.txt
@@ -271,13 +271,45 @@
 			indicates connections to a foreign provider when
 			traveling abroad.
 
-		array{string} Nameservers [readwrite]
+		array{string} Nameservers [readonly]
+
+			The list of currently active nameservers for this
+			service. If the server is not in READY, LOGIN or
+			ONLINE state than this list will be empty.
+
+			Global nameservers are automatically added to this
+			list. The array represents a sorted list of the
+			current nameservers. The first one has the highest
+			priority and is used by default.
+
+			When using DHCP this array represents the nameservers
+			provided by the network. In case of manual settings,
+			the ones from Nameservers.Configuration are used.
+
+		array{string} Nameservers.Configuration [readwrite]
 
 			The list of manually configured domain name
 			servers. Some 3G networks don't provide correct
 			name servers and this allows for an override.
 
-		array{string} Domains [readwrite]
+			This array is sorted by priority and the first
+			entry in the list represents the nameserver with
+			the highest priority.
+
+			When using manual configuration and no global
+			nameservers are configured, then it is useful
+			to configure this setting.
+
+			Changes to the domain name servers can be done
+			at any time. It will not cause a disconnect of
+			the service. However there might be small window
+			where name resolution might fail.
+
+		array{string} Domains [readonly]
+
+			The list of currently used search domains.
+
+		array{string} Domains.Configuration [readwrite]
 
 			The list of manually configured search domains.
 
@@ -288,6 +320,10 @@
 				Possible values are "dhcp", "manual"
 				and "off".
 
+				The value "fixed" indicates an IP address
+				that can not be modified. For example
+				cellular networks return fixed information.
+
 			string Address [readonly]
 
 				The current configured IPv4 address.
@@ -306,6 +342,11 @@
 			the actual system configuration while this allows
 			user configuration.
 
+			Changing these settings will cause a state change
+			of the service. The service will become unavailable
+			until the new configuration has been successfully
+			installed.
+
 		dict Proxy [readonly]
 
 			string Method [readonly]
--- gdbus/object.c
+++ gdbus/object.c
@@ -308,8 +308,10 @@
 		goto done;
 
 	if (!dbus_connection_get_object_path_data(conn, parent_path,
-							(void *) &data))
+							(void *) &data)) {
+		invalidate_parent_data(conn, parent_path);
 		goto done;
+	}
 
 	if (!data)
 		goto done;
@@ -514,8 +516,10 @@
 	if (data == NULL)
 		return FALSE;
 
-	if (find_interface(data->interfaces, name))
+	if (find_interface(data->interfaces, name)) {
+		object_path_unref(connection, path);
 		return FALSE;
+	}
 
 	add_interface(data, name, methods, signals,
 			properties, user_data, destroy);
--- include/device.h
+++ include/device.h
@@ -79,7 +79,6 @@
 						connman_bool_t powered);
 int connman_device_set_scanning(struct connman_device *device,
 						connman_bool_t scanning);
-void connman_device_cleanup_scanning(struct connman_device *device);
 
 int connman_device_set_disconnected(struct connman_device *device,
 						connman_bool_t disconnected);
--- include/element.h
+++ include/element.h
@@ -139,6 +139,8 @@
 					struct connman_element *parent);
 void connman_element_unregister(struct connman_element *element);
 void connman_element_unregister_children(struct connman_element *element);
+void connman_element_unregister_children_type(struct connman_element *element,
+						enum connman_element_type type);
 void connman_element_update(struct connman_element *element);
 
 int connman_element_set_enabled(struct connman_element *element,
--- include/inet.h
+++ include/inet.h
@@ -50,6 +50,7 @@
 int connman_inet_set_gateway_address(int index, const char *gateway);
 int connman_inet_clear_gateway_address(int index, const char *gateway);
 int connman_inet_set_gateway_interface(int index);
+int connman_inet_clear_gateway_interface(int index);
 
 #ifdef __cplusplus
 }
--- include/network.h
+++ include/network.h
@@ -132,6 +132,8 @@
 void *connman_network_get_data(struct connman_network *network);
 void connman_network_set_data(struct connman_network *network, void *data);
 
+void connman_network_update(struct connman_network *network);
+
 struct connman_network_driver {
 	const char *name;
 	enum connman_network_type type;
--- include/timeserver.h
+++ include/timeserver.h
@@ -34,12 +34,14 @@
 
 int connman_timeserver_append(const char *server);
 int connman_timeserver_remove(const char *server);
+void connman_timeserver_sync(void);
 
 struct connman_timeserver_driver {
 	const char *name;
 	int priority;
 	int (*append) (const char *server);
 	int (*remove) (const char *server);
+	void (*sync) (void);
 };
 
 int connman_timeserver_driver_register(struct connman_timeserver_driver *driver);
--- include/utsname.h
+++ include/utsname.h
@@ -32,9 +32,12 @@
  * @short_description: Functions for handling utsname
  */
 
+const char *connman_utsname_get_hostname(void);
+
 struct connman_utsname_driver {
 	const char *name;
 	int priority;
+	const char * (*get_hostname) (void);
 	int (*set_hostname) (const char *hostname);
 	int (*set_domainname) (const char *domainname);
 };
--- include/wifi.h
+++ include/wifi.h
@@ -31,6 +31,8 @@
 							const char *mode,
 							const char *security);
 
+char **connman_wifi_load_ssid(void);
+
 #ifdef __cplusplus
 }
 #endif
--- plugins/bluetooth.c
+++ plugins/bluetooth.c
@@ -62,6 +62,7 @@
 static DBusConnection *connection;
 
 static GHashTable *bluetooth_devices = NULL;
+static GHashTable *bluetooth_networks = NULL;
 
 static int pan_probe(struct connman_network *network)
 {
@@ -89,6 +90,12 @@
 
 	dbus_error_init(&error);
 
+	if (dbus_set_error_from_message(&error, reply) == TRUE) {
+		connman_error("%s", error.message);
+		dbus_error_free(&error);
+		goto done;
+	}
+
 	if (dbus_message_get_args(reply, &error,
 					DBUS_TYPE_STRING, &interface,
 						DBUS_TYPE_INVALID) == FALSE) {
@@ -171,6 +178,12 @@
 
 	dbus_error_init(&error);
 
+	if (dbus_set_error_from_message(&error, reply) == TRUE) {
+		connman_error("%s", error.message);
+		dbus_error_free(&error);
+		goto done;
+	}
+
 	if (dbus_message_get_args(reply, &error, DBUS_TYPE_INVALID) == FALSE) {
 		if (dbus_error_is_set(&error) == TRUE) {
 			connman_error("%s", error.message);
@@ -225,6 +238,8 @@
 
 	connman_network_ref(network);
 
+	connman_network_set_associating(network, FALSE);
+
 	dbus_pending_call_set_notify(call, disconnect_reply, network, NULL);
 
 	dbus_message_unref(message);
@@ -241,6 +256,43 @@
 	.disconnect	= pan_disconnect,
 };
 
+static gboolean network_changed(DBusConnection *connection,
+				DBusMessage *message, void *user_data)
+{
+	const char *path = dbus_message_get_path(message);
+	struct connman_network *network;
+	DBusMessageIter iter, value;
+	const char *key;
+
+	DBG("path %s", path);
+
+	network = g_hash_table_lookup(bluetooth_networks, path);
+	if (network == NULL)
+		return TRUE;
+
+	if (dbus_message_iter_init(message, &iter) == FALSE)
+		return TRUE;
+
+	dbus_message_iter_get_basic(&iter, &key);
+
+	dbus_message_iter_next(&iter);
+	dbus_message_iter_recurse(&iter, &value);
+
+	if (g_str_equal(key, "Connected") == TRUE) {
+		dbus_bool_t connected;
+
+		dbus_message_iter_get_basic(&value, &connected);
+
+		if (connected == TRUE)
+			return TRUE;
+
+		connman_network_set_associating(network, FALSE);
+		connman_network_set_connected(network, FALSE);
+	}
+
+	return TRUE;
+}
+
 static void extract_properties(DBusMessage *reply, const char **parent,
 						const char **address,
 						const char **name,
@@ -381,6 +433,8 @@
 
 	connman_network_set_group(network, ident);
 
+	g_hash_table_insert(bluetooth_networks, g_strdup(path), network);
+
 done:
 	dbus_message_unref(reply);
 
@@ -625,6 +679,12 @@
 
 	dbus_error_init(&error);
 
+	if (dbus_set_error_from_message(&error, reply) == TRUE) {
+		connman_error("%s", error.message);
+		dbus_error_free(&error);
+		goto done;
+	}
+
 	if (dbus_message_get_args(reply, &error,
 				DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH,
 						&adapters, &num_adapters,
@@ -668,6 +728,9 @@
 	bluetooth_devices = g_hash_table_new_full(g_str_hash, g_str_equal,
 						g_free, unregister_device);
 
+	bluetooth_networks = g_hash_table_new_full(g_str_hash, g_str_equal,
+						g_free, NULL);
+
 	message = dbus_message_new_method_call(BLUEZ_SERVICE, "/",
 				BLUEZ_MANAGER_INTERFACE, LIST_ADAPTERS);
 	if (message == NULL)
@@ -699,6 +762,7 @@
 	if (bluetooth_devices == NULL)
 		return;
 
+	g_hash_table_destroy(bluetooth_networks);
 	g_hash_table_destroy(bluetooth_devices);
 	bluetooth_devices = NULL;
 }
@@ -717,14 +781,24 @@
 
 static void powered_reply(DBusPendingCall *call, void *user_data)
 {
+	DBusError error;
 	DBusMessage *reply;
 
 	DBG("");
 
 	reply = dbus_pending_call_steal_reply(call);
 
-	dbus_message_unref(reply);
+	dbus_error_init(&error);
 
+	if (dbus_set_error_from_message(&error, reply) == TRUE) {
+		connman_error("%s", error.message);
+		dbus_error_free(&error);
+		dbus_message_unref(reply);
+		dbus_pending_call_unref(call);
+		return;
+	}
+
+	dbus_message_unref(reply);
 	dbus_pending_call_unref(call);
 
 	add_adapter(connection, user_data);
@@ -805,6 +879,7 @@
 static guint added_watch;
 static guint removed_watch;
 static guint adapter_watch;
+static guint network_watch;
 
 static int bluetooth_init(void)
 {
@@ -832,8 +907,13 @@
 						PROPERTY_CHANGED, adapter_changed,
 						NULL, NULL);
 
+	network_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
+						BLUEZ_NETWORK_INTERFACE,
+						PROPERTY_CHANGED, network_changed,
+						NULL, NULL);
+
 	if (watch == 0 || added_watch == 0 || removed_watch == 0
-			|| adapter_watch == 0) {
+			|| adapter_watch == 0 || network_watch == 0) {
 		err = -EIO;
 		goto remove;
 	}
@@ -855,6 +935,7 @@
 	g_dbus_remove_watch(connection, added_watch);
 	g_dbus_remove_watch(connection, removed_watch);
 	g_dbus_remove_watch(connection, adapter_watch);
+	g_dbus_remove_watch(connection, network_watch);
 
 	dbus_connection_unref(connection);
 
@@ -867,6 +948,7 @@
 	g_dbus_remove_watch(connection, added_watch);
 	g_dbus_remove_watch(connection, removed_watch);
 	g_dbus_remove_watch(connection, adapter_watch);
+	g_dbus_remove_watch(connection, network_watch);
 
 	bluetooth_disconnect(connection, NULL);
 
--- plugins/dhclient.c
+++ plugins/dhclient.c
@@ -32,6 +32,7 @@
 
 #define CONNMAN_API_SUBJECT_TO_CHANGE
 #include <connman/plugin.h>
+#include <connman/utsname.h>
 #include <connman/dhcp.h>
 #include <connman/task.h>
 #include <connman/log.h>
@@ -129,6 +130,7 @@
 static void dhclient_setup(struct connman_task *task, const char *ifname)
 {
 	const char *path, *intf = "org.moblin.connman.Task";
+	const char *hostname;
 
 	path = connman_task_get_path(task);
 
@@ -143,6 +145,13 @@
 							STATEDIR, ifname);
 	connman_task_add_argument(task, "-cf", "%s/dhclient.conf", SCRIPTDIR);
 	connman_task_add_argument(task, "-sf", "%s/dhclient-script", SCRIPTDIR);
+
+	hostname = connman_utsname_get_hostname();
+#ifdef HAVE_DHCLIENT_HOSTNAME
+	if (hostname != NULL)
+		connman_task_add_argument(task, "-H", hostname);
+#endif
+
 	connman_task_add_argument(task, ifname, NULL);
 	connman_task_add_argument(task, "-n", NULL);
 }
--- plugins/dnsproxy.c
+++ plugins/dnsproxy.c
@@ -401,6 +401,8 @@
 	.offline_mode		= dnsproxy_offline_mode,
 };
 
+static unsigned char opt_edns0_type[2] = { 0x00, 0x29 };
+
 static int parse_request(unsigned char *buf, int len,
 					char *name, unsigned int size)
 {
@@ -409,7 +411,6 @@
 	uint16_t arcount = ntohs(hdr->arcount);
 	unsigned char *ptr;
 	char *last_label = NULL;
-	int label_count = 0;
 	unsigned int remain, used = 0;
 
 	if (len < 12)
@@ -424,20 +425,17 @@
 
 	memset(name, 0, size);
 
-	ptr = buf + 12;
-	remain = len - 12;
+	ptr = buf + sizeof(struct domain_hdr);
+	remain = len - sizeof(struct domain_hdr);
 
 	while (remain > 0) {
 		uint8_t len = *ptr;
 
 		if (len == 0x00) {
-			if (label_count > 0)
-				last_label = (char *) (ptr + 1);
+			last_label = (char *) (ptr + 1);
 			break;
 		}
 
-		label_count++;
-
 		if (used + len + 1 > size)
 			return -ENOBUFS;
 
@@ -450,8 +448,8 @@
 		remain -= len + 1;
 	}
 
-	if (arcount && remain >= 9 && last_label[4] == 0 &&
-				last_label[5] == 0 && last_label[6] == 0x29) {
+	if (last_label && arcount && remain >= 9 && last_label[4] == 0 &&
+				!memcmp(last_label + 5, opt_edns0_type, 2)) {
 		uint16_t edns0_bufsize;
 
 		edns0_bufsize = last_label[7] << 8 | last_label[8];
@@ -472,7 +470,7 @@
 		}
 	}
 
-	DBG("query %s (%d labels)", name, label_count);
+	DBG("query %s", name);
 
 	return 0;
 }
--- plugins/loopback.c
+++ plugins/loopback.c
@@ -43,6 +43,8 @@
 static in_addr_t loopback_address;
 static in_addr_t loopback_netmask;
 
+static char system_hostname[HOST_NAME_MAX + 1];
+
 #if 0
 static GIOChannel *inotify_channel = NULL;
 
@@ -146,21 +148,24 @@
 
 	if (sethostname(name, strlen(name)) < 0)
 		connman_error("Failed to set hostname to %s", name);
+
+	strncpy(system_hostname, name, HOST_NAME_MAX);
 }
 
 static int setup_hostname(void)
 {
 	char name[HOST_NAME_MAX + 1];
 
-	memset(name, 0, sizeof(name));
+	memset(system_hostname, 0, sizeof(system_hostname));
 
-	if (gethostname(name, HOST_NAME_MAX) < 0) {
+	if (gethostname(system_hostname, HOST_NAME_MAX) < 0) {
 		connman_error("Failed to get current hostname");
 		return -EIO;
 	}
 
-	if (strlen(name) > 0 && strcmp(name, "(none)") != 0)
-		connman_info("System hostname is %s", name);
+	if (strlen(system_hostname) > 0 &&
+				strcmp(system_hostname, "(none)") != 0)
+		connman_info("System hostname is %s", system_hostname);
 	else
 		create_hostname();
 
@@ -279,10 +284,18 @@
 	return err;
 }
 
+static const char *loopback_get_hostname(void)
+{
+	return system_hostname;
+}
+
 static int loopback_set_hostname(const char *hostname)
 {
 	int err;
 
+	if (g_strcmp0(hostname, "<hostname>") == 0)
+		return 0;
+
 	if (sethostname(hostname, strlen(hostname)) < 0) {
 		err = -errno;
 		connman_error("Failed to set hostname to %s", hostname);
@@ -311,6 +324,7 @@
 
 static struct connman_utsname_driver loopback_driver = {
 	.name		= "loopback",
+	.get_hostname	= loopback_get_hostname,
 	.set_hostname	= loopback_set_hostname,
 	.set_domainname	= loopback_set_domainname,
 };
--- plugins/meego.c
+++ plugins/meego.c
@@ -24,15 +24,19 @@
 #endif
 
 #define CONNMAN_API_SUBJECT_TO_CHANGE
+#include <connman/timeserver.h>
 #include <connman/plugin.h>
 
+#define MEEGO_NTP_SERVER "ntp.meego.com"
+
 static int meego_init(void)
 {
-	return 0;
+	return connman_timeserver_append(MEEGO_NTP_SERVER);
 }
 
 static void meego_exit(void)
 {
+	connman_timeserver_remove(MEEGO_NTP_SERVER);
 }
 
 CONNMAN_PLUGIN_DEFINE(meego, "MeeGo features plugin", VERSION,
--- plugins/ntpd.c
+++ plugins/ntpd.c
+/*
+ *
+ *  Connection Manager
+ *
+ *  Copyright (C) 2007-2010  Intel Corporation. All rights reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <arpa/inet.h>
+
+#define CONNMAN_API_SUBJECT_TO_CHANGE
+#include <connman/plugin.h>
+#include <connman/task.h>
+#include <connman/timeserver.h>
+#include <connman/driver.h>
+#include <connman/log.h>
+
+/*
+ * The peers list are the peers currently added to a running ntpd,
+ * while pending_peers are the one appended but not used by ntpd yet.
+ */
+static GList *peers = NULL;
+static GList *pending_peers = NULL;
+
+#define NTPD_PORT 123
+
+struct ntpd_peer {
+	char *server;
+	gint refcount;
+};
+
+struct ntpdate_task {
+	struct connman_task *task;
+	gint conf_fd;
+	char *conf_path;
+};
+
+static struct ntpd_peer *find_peer(GList *peer_list, const char* server)
+{
+	GList *list;
+	struct ntpd_peer *peer;
+
+	for (list = peer_list; list; list = list->next) {
+		peer = list->data;
+
+		if (g_str_equal(peer->server, server))
+			return peer;
+	}
+
+	return NULL;
+}
+
+static void remove_peer(GList *peer_list, struct ntpd_peer *peer)
+{
+	if (!g_atomic_int_dec_and_test(&peer->refcount))
+		return;
+
+	g_free(peer->server);
+	g_free(peer);
+	peer_list = g_list_remove(peer_list, peer);
+}
+
+static connman_bool_t ntpd_running(void)
+{
+	int sock;
+	connman_bool_t ret;
+	struct sockaddr_in server_addr;
+
+	if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
+		return FALSE;
+
+	server_addr.sin_family = AF_INET;
+        server_addr.sin_port = htons(NTPD_PORT);
+        server_addr.sin_addr.s_addr = INADDR_ANY;
+        memset(&(server_addr.sin_zero), 0, 8);
+
+	if (bind(sock, (struct sockaddr *)&server_addr,
+			sizeof(struct sockaddr)) == -1) {
+		if (errno == EADDRINUSE)
+			ret = TRUE;
+		else
+			ret = FALSE;
+        }
+
+	close(sock);
+
+	return ret;
+}
+
+static void ntpdate_died(struct connman_task *task, void *user_data)
+{
+	struct ntpdate_task *ntpdate = user_data;
+
+	DBG("");
+
+	unlink(ntpdate->conf_path);
+	g_free(ntpdate->conf_path);
+	connman_task_destroy(ntpdate->task);
+}
+
+static void ntpdate_add_peer(struct ntpdate_task *ntpdate, char *peer)
+{
+	FILE *conf_file;
+
+	DBG("%s", peer);
+
+	conf_file = fdopen(ntpdate->conf_fd, "a+");
+	if (conf_file == NULL) {
+		connman_error("fdopen failed");
+		return;
+	}
+
+	fprintf(conf_file, "server %s iburst\n", peer);
+
+	fclose(conf_file);
+}
+
+static int ntpdate(void)
+{
+	int err;
+	GError *g_err;
+	GList *list;
+	struct ntpd_peer *peer;
+	struct ntpdate_task *ntpdate;
+
+	DBG("");
+
+	ntpdate = g_try_new0(struct ntpdate_task, 1);
+	if (ntpdate == NULL)
+		return -ENOMEM;
+
+	/* ntpdate is deprecated, we use ntpd -q instead */
+	ntpdate->task = connman_task_create(NTPD);
+	if (ntpdate->task == NULL) {
+		err = -ENOMEM;
+		goto error_task;
+	}
+
+	connman_task_add_argument(ntpdate->task, "-q", NULL);
+
+	/* The servers are added through a temp configuration file */
+	ntpdate->conf_fd = g_file_open_tmp("connman.ntp.conf_XXXXXX",
+						&ntpdate->conf_path, &g_err);
+	if  (ntpdate->conf_fd == -1) {
+		err = g_err->code;
+		g_free(g_err);
+		goto error_open;
+	}
+
+	connman_task_add_argument(ntpdate->task, "-c", ntpdate->conf_path);
+
+	DBG("conf path %s", ntpdate->conf_path);
+
+	for (list = pending_peers; list; list = list->next) {
+		peer = list->data;
+
+		ntpdate_add_peer(ntpdate, peer->server);
+	}
+
+	for (list = peers; list; list = list->next) {
+		peer = list->data;
+
+		ntpdate_add_peer(ntpdate, peer->server);
+	}
+
+	close(ntpdate->conf_fd);
+
+	return connman_task_run(ntpdate->task, ntpdate_died, ntpdate,
+						NULL, NULL, NULL);
+error_open:
+	connman_task_destroy(ntpdate->task);
+
+error_task:
+	g_free(ntpdate);
+
+	return err;
+}
+
+static int ntpd_add_peer(char *peer)
+{
+	DBG("%s", peer);
+
+	return 0;
+}
+
+static void ntpd_sync(void)
+{
+	int err;
+	GList *list;
+
+	DBG("");
+
+	if (g_list_length(pending_peers) == 0 &&
+			g_list_length(peers) == 0)
+		return;
+
+	if (!ntpd_running()) {
+		ntpdate();
+		return;
+	}
+
+	/* TODO Grab ntp keys path */
+
+	list = g_list_first(pending_peers);
+	while(list) {
+		struct ntpd_peer *peer = list->data;
+
+		err = ntpd_add_peer(peer->server);
+		if (err)
+			continue;
+
+		peers = g_list_prepend(peers, peer);
+
+		list = g_list_next(list);
+
+		pending_peers = g_list_remove(pending_peers, peer);
+	};
+}
+
+static int ntpd_append(const char *server)
+{
+	struct ntpd_peer *peer;
+
+	DBG("");
+
+	if (server == NULL)
+		return 0;
+
+	if ((peer = find_peer(pending_peers, server)) ||
+			(peer = find_peer(peers, server))) {
+		g_atomic_int_inc(&peer->refcount);
+		return 0;
+	}
+
+	peer = g_try_new0(struct ntpd_peer, 1);
+	if (peer == NULL)
+		return -ENOMEM;
+
+	peer->server = g_strdup(server);
+	if (peer->server == NULL) {
+		g_free(peer);
+		return -ENOMEM;
+	}
+
+	peer->refcount = 1;
+
+	pending_peers = g_list_prepend(pending_peers, peer);
+
+	return 0;
+}
+
+static int ntpd_remove(const char *server)
+{
+	struct ntpd_peer *peer;
+
+	DBG("");
+
+	if (server == NULL)
+		return 0;
+
+	peer = find_peer(peers, server);
+	if (peer == NULL)
+		goto remove;
+
+	remove_peer(peers, peer);
+
+remove:
+	/* TODO: send ntpd remove command */
+
+	peer = find_peer(pending_peers, server);
+	if (peer == NULL)
+		return 0;
+
+	remove_peer(pending_peers, peer);
+
+	return 0;
+}
+
+static struct connman_timeserver_driver ntpd_driver = {
+	.name		= "ntpd",
+	.priority	= CONNMAN_DRIVER_PRIORITY_DEFAULT,
+	.append		= ntpd_append,
+	.remove		= ntpd_remove,
+	.sync		= ntpd_sync,
+};
+
+static int ntpd_init(void)
+{
+	return connman_timeserver_driver_register(&ntpd_driver);
+}
+
+static void ntpd_exit(void)
+{
+	connman_timeserver_driver_unregister(&ntpd_driver);
+}
+
+CONNMAN_PLUGIN_DEFINE(ntpd, "ntpd plugin", VERSION,
+		CONNMAN_PLUGIN_PRIORITY_DEFAULT, ntpd_init, ntpd_exit)
--- plugins/ofono.c
+++ plugins/ofono.c
@@ -170,19 +170,16 @@
 
 static char *get_ident(const char *path)
 {
-	char *ident, *pos;
+	char *pos;
 
 	if (*path != '/')
 		return NULL;
 
-	ident = g_strdup(path + 1);
-
-	pos = ident;
-
-	while ((pos = strchr(pos, '/')) != NULL)
-		*pos = '_';
+	pos = strrchr(path, '/');
+	if (pos == NULL)
+		return NULL;
 
-	return ident;
+	return g_strdup(pos + 1);
 }
 
 static void create_service(struct connman_network *network)
@@ -229,7 +226,12 @@
 		dbus_message_iter_next(&entry);
 		dbus_message_iter_recurse(&entry, &value);
 
-		if (g_str_equal(key, "Operator") == TRUE) {
+		/*
+		 * 'Operator' is deprecated since version 0.20, but
+		 * keep it here for backward compatibility reasons.
+		 */
+		if (g_str_equal(key, "Operator") == TRUE ||
+				g_str_equal(key, "Name") == TRUE) {
 			const char *name;
 
 			dbus_message_iter_get_basic(&value, &name);
@@ -373,9 +375,59 @@
 	dbus_message_unref(message);
 }
 
+static gboolean registration_changed(DBusConnection *connection,
+					DBusMessage *message, void *user_data)
+{
+	const char *path = dbus_message_get_path(message);
+	struct connman_network *network = user_data;
+	DBusMessageIter iter, value;
+	const char *key;
+
+	DBG("path %s", path);
+
+	if (dbus_message_iter_init(message, &iter) == FALSE)
+		return TRUE;
+
+	dbus_message_iter_get_basic(&iter, &key);
+
+	DBG("key %s", key);
+
+	dbus_message_iter_next(&iter);
+	dbus_message_iter_recurse(&iter, &value);
+
+	if (g_strcmp0(key, "Name") == 0 ||
+			g_strcmp0(key, "Operator") == 0) {
+		const char *name;
+
+		dbus_message_iter_get_basic(&value, &name);
+		DBG("name %s", name);
+		connman_network_set_name(network, name);
+		create_service(network);
+	} else if (g_strcmp0(key, "Strength") == 0) {
+		connman_uint8_t strength;
+
+		dbus_message_iter_get_basic(&value, &strength);
+		connman_network_set_strength(network, strength);
+		connman_network_update(network);
+	}
+
+	return TRUE;
+}
+
 static int network_probe(struct connman_network *network)
 {
 	const char *path;
+	guint reg_watch;
+
+	reg_watch = g_dbus_add_signal_watch(connection, NULL, NULL,
+						OFONO_REGISTRATION_INTERFACE,
+						PROPERTY_CHANGED,
+						registration_changed,
+						network, NULL);
+	if (reg_watch == 0)
+		return -EIO;
+
+	connman_network_set_data(network, GUINT_TO_POINTER(reg_watch));
 
 	path = connman_network_get_string(network, "Path");
 
@@ -585,7 +637,12 @@
 
 static void network_remove(struct connman_network *network)
 {
+	guint reg_watch;
+
 	DBG("network %p", network);
+
+	reg_watch = GPOINTER_TO_UINT(connman_network_get_data(network));
+	g_dbus_remove_watch(connection, reg_watch);
 }
 
 static int network_setup(struct connman_network *network, const char *key)
@@ -611,8 +668,9 @@
 static void add_network(struct connman_device *device, const char *path)
 {
 	struct connman_network *network;
-	char *ident, *mcc, *mnc;
-	const char *mcc_mnc;
+	char *ident;
+	const char *mcc;
+	const char *mnc;
 
 	DBG("device %p path %s", device, path);
 
@@ -633,16 +691,13 @@
 	connman_network_set_available(network, TRUE);
 	connman_network_set_index(network, -1);
 
-	mcc_mnc = connman_device_get_string(device, "MCC_MNC");
-	if (mcc_mnc != NULL) {
-		mcc = g_strndup(mcc_mnc, 3);
+	mcc = connman_device_get_string(device, "MCC");
+	if (mcc != NULL)
 		connman_network_set_string(network, "Cellular.MCC", mcc);
-		g_free(mcc);
 
-		mnc = g_strdup(mcc_mnc + 3);
+	mnc = connman_device_get_string(device, "MNC");
+	if (mnc != NULL)
 		connman_network_set_string(network, "Cellular.MNC", mnc);
-		g_free(mnc);
-	}
 
 	connman_device_add_network(device, network);
 }
@@ -777,11 +832,6 @@
 			contexts = value;
 			add_default_context(&contexts, path,
 					CONTEXT_NAME, CONTEXT_TYPE);
-		} else if (g_str_equal(key, "Status") == TRUE) {
-			const char *status;
-
-			dbus_message_iter_get_basic(&value, &status);
-			/* FIXME: add roaming support */
 		} else if (g_str_equal(key, "Powered") == TRUE) {
 			dbus_bool_t powered;
 
@@ -843,13 +893,12 @@
 }
 
 static void add_device(const char *path, const char *imsi,
-					unsigned char mnc_length)
+				const char *mcc, const char *mnc)
 {
 	struct modem_data *modem;
 	struct connman_device *device;
-	char *mcc_mnc;
 
-	DBG("path %s imsi %s mnc_length %d", path, imsi, mnc_length);
+	DBG("path %s imsi %s", path, imsi);
 
 	if (path == NULL)
 		return;
@@ -870,12 +919,10 @@
 	connman_device_set_mode(device, CONNMAN_DEVICE_MODE_NETWORK_MULTIPLE);
 
 	connman_device_set_string(device, "Path", path);
-
-	if (mnc_length == 2 || mnc_length == 3) {
-		mcc_mnc = g_strndup(imsi, mnc_length + 3);
-		connman_device_set_string(device, "MCC_MNC", mcc_mnc);
-		g_free(mcc_mnc);
-	}
+	if (mcc != NULL)
+		connman_device_set_string(device, "MCC", mcc);
+	if (mnc != NULL)
+		connman_device_set_string(device, "MNC", mnc);
 
 	if (connman_device_register(device) < 0) {
 		connman_device_unref(device);
@@ -891,6 +938,8 @@
 {
 	const char *path = user_data;
 	const char *imsi;
+	char *mcc = NULL;
+	char *mnc = NULL;
 	/* If MobileNetworkCodeLength is not provided, mnc_length is 0 */
 	unsigned char mnc_length = 0;
 	DBusMessage *reply;
@@ -920,14 +969,34 @@
 
 		if (g_str_equal(key, "SubscriberIdentity") == TRUE)
 			dbus_message_iter_get_basic(&value, &imsi);
+		/*
+		 * 'MobileNetworkCodeLength' is deprecated since version 0.20, but
+		 * keep it here for backward compatibility reasons.
+		 */
 		else if (g_str_equal(key, "MobileNetworkCodeLength") == TRUE)
 			dbus_message_iter_get_basic(&value,
 						(void *) &mnc_length);
+		else if (g_str_equal(key, "MobileCountryCode") == TRUE)
+			dbus_message_iter_get_basic(&value,
+						(void *) &mcc);
+		else if (g_str_equal(key, "MobileNetworkCode") == TRUE)
+			dbus_message_iter_get_basic(&value,
+						(void *) &mnc);
 
 		dbus_message_iter_next(&dict);
 	}
 
-	add_device(path, imsi, mnc_length);
+	if (mnc_length == 2 || mnc_length == 3) {
+		mcc = g_strndup(imsi, 3);
+		mnc = g_strndup(imsi + 3, mnc_length);
+	}
+
+	add_device(path, imsi, mcc, mnc);
+
+	if (mnc_length == 2 || mnc_length == 3) {
+		g_free(mcc);
+		g_free(mnc);
+	}
 
 done:
 	dbus_message_unref(reply);
@@ -1377,13 +1446,6 @@
 		else if (modem->device != NULL)
 			connman_device_remove_all_networks(modem->device);
 
-	} else if (g_str_equal(key, "Status") == TRUE) {
-		const char *status;
-		dbus_message_iter_get_basic(&value, &status);
-
-		DBG("status %s", status);
-
-		/* FIXME: add roaming support */
 	} else if (g_str_equal(key, "PrimaryContexts") == TRUE) {
 		check_networks(modem);
 	} else if (g_str_equal(key, "Powered") == TRUE) {
@@ -1567,42 +1629,12 @@
 				struct connman_element *parent,
 					connman_bool_t connected)
 {
-	if (connected == TRUE) {
-		struct connman_element *element;
-
-		if (parent->ipv4.address == NULL)
-			goto failed;
-
-		if (parent->ipv4.netmask == NULL)
-			goto failed;
-
-		element = connman_element_create(NULL);
-		if (element == NULL) {
-			connman_error("Can not create connman_element");
-			return -ENOMEM;
-		}
-
-		element->type = CONNMAN_ELEMENT_TYPE_IPV4;
-		element->index = parent->index;
-
-		if (connman_element_register(element, parent) < 0) {
-			connman_element_unref(element);
-			goto failed;
-		}
-	} else
+	if (connected == FALSE)
 		cleanup_ipconfig(parent);
 
 	connman_network_set_connected(pending_network, connected);
 
 	return 0;
-
-failed:
-	connman_network_set_error(pending_network,
-		CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL);
-
-	cleanup_ipconfig(parent);
-
-	return -EINVAL;
 }
 
 static gboolean pri_context_changed(DBusConnection *connection,
--- plugins/portal.c
+++ plugins/portal.c
@@ -167,6 +167,7 @@
 		return FALSE;
 
 	if (condition & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
+		connman_error("TCP event error %d", condition);
 		remove_timeout(data);
 		data->watch = 0;
 		if (data->get_page)
@@ -257,12 +258,16 @@
 	int ret;
 	char *ip = NULL;
 
+	DBG("");
+
 	data = connman_location_get_data(location);
 	data->connection_ready = 0;
 	data->sock = create_socket();
 	if (data->sock < 0)
 		goto error;
 
+	DBG("proxy %s port %d", data->proxy, data->proxy_port);
+
 	if (strlen(data->proxy) > 0)
 		ip = get_ip_from_host(data->proxy);
 	else {
@@ -341,15 +346,19 @@
 	str = g_strrstr(lines[0], "200 OK");
 	if (str != NULL) {
 		for (i = 0; lines[i] != NULL && i < 12; i++) {
+			DBG("%s", lines[i]);
 			str = g_strstr_len(lines[i], 12, "Set-Cookie");
 			if (str != NULL) {
 				g_strfreev(lines);
+				DBG("success");
 				return GET_PAGE_SUCCESS;
 			}
 		}
 	}
 	g_strfreev(lines);
 
+	DBG("redirection");
+
 	return GET_PAGE_REDIRECTED;
 }
 
@@ -366,6 +375,8 @@
 	else
 		ret = status;
 
+	DBG("status %d", status);
+
 	switch (ret) {
 	case GET_PAGE_SUCCESS:
 		connman_location_report_result(location,
@@ -399,9 +410,22 @@
 	enum connman_service_type service_type;
 
 	service_type = connman_location_get_type(location);
-	if (service_type != CONNMAN_SERVICE_TYPE_WIFI &&
-		service_type != CONNMAN_SERVICE_TYPE_ETHERNET)
-		return 0;
+
+	DBG("service type %d", service_type);
+
+	switch (service_type) {
+	case CONNMAN_SERVICE_TYPE_ETHERNET:
+	case CONNMAN_SERVICE_TYPE_WIFI:
+	case CONNMAN_SERVICE_TYPE_WIMAX:
+	case CONNMAN_SERVICE_TYPE_BLUETOOTH:
+	case CONNMAN_SERVICE_TYPE_CELLULAR:
+		break;
+	case CONNMAN_SERVICE_TYPE_UNKNOWN:
+	case CONNMAN_SERVICE_TYPE_SYSTEM:
+	case CONNMAN_SERVICE_TYPE_GPS:
+	case CONNMAN_SERVICE_TYPE_VPN:
+		return -EOPNOTSUPP;
+	}
 
 	data = g_try_new0(struct server_data, 1);
 	if (data == NULL)
--- plugins/supplicant.c
+++ plugins/supplicant.c
@@ -41,6 +41,7 @@
 #include <connman/option.h>
 #include <connman/inet.h>
 #include <connman/dbus.h>
+#include <connman/wifi.h>
 #include <connman/log.h>
 
 #include "supplicant.h"
@@ -174,6 +175,13 @@
 	dbus_int32_t maxrate;
 };
 
+struct supplicant_block {
+	unsigned char *ssid;
+	char *netpath;
+	gboolean enabled;
+	int num_scans;
+};
+
 struct supplicant_task {
 	int ifindex;
 	char *ifname;
@@ -183,6 +191,8 @@
 	struct connman_network *pending_network;
 	char *path;
 	char *netpath;
+	gboolean hidden_found;
+	GHashTable *hidden_blocks;
 	gboolean created;
 	enum supplicant_state state;
 	gboolean scanning;
@@ -206,6 +216,16 @@
 	g_free(task);
 }
 
+static void remove_block(gpointer user_data)
+{
+	struct supplicant_block *block = user_data;
+
+	DBG("");
+
+	g_free(block->ssid);
+	g_free(block->netpath);
+}
+
 static struct supplicant_task *find_task_by_index(int index)
 {
 	GSList *list;
@@ -303,12 +323,266 @@
 	return 0;
 }
 
+static int enable_network(struct supplicant_task *task, const char *netpath,
+			  connman_bool_t enable)
+{
+	DBusMessage *message, *reply;
+	DBusError error;
+	char *enable_string;
+
+	DBG("enable %d", enable);
+
+	enable_string = enable ? "enable" : "disable";
+
+	message = dbus_message_new_method_call(SUPPLICANT_NAME, netpath,
+				SUPPLICANT_INTF ".Network", enable_string);
+	if (message == NULL)
+		return -ENOMEM;
+
+	dbus_message_set_auto_start(message, FALSE);
+
+	dbus_error_init(&error);
+
+	reply = dbus_connection_send_with_reply_and_block(connection,
+							message, -1, &error);
+	if (reply == NULL) {
+		if (dbus_error_is_set(&error) == TRUE) {
+			connman_error("%s", error.message);
+			dbus_error_free(&error);
+		} else
+			connman_error("Failed to select network");
+		dbus_message_unref(message);
+		return -EIO;
+	}
+
+	dbus_message_unref(reply);
+
+	dbus_message_unref(message);
+
+	return 0;
+}
+
+static int set_hidden_network(struct supplicant_task *task, const char *netpath,
+				const unsigned char *ssid, int ssid_len)
+{
+	DBusMessage *message, *reply;
+	DBusMessageIter array, dict;
+	DBusError error;
+	dbus_uint32_t scan_ssid = 1;
+	const char *invalid_address = "ff:ff:ff:ff:ff:ff";
+
+	message = dbus_message_new_method_call(SUPPLICANT_NAME, netpath,
+					SUPPLICANT_INTF ".Network", "set");
+	if (message == NULL)
+		return -ENOMEM;
+
+	dbus_message_set_auto_start(message, FALSE);
+
+	dbus_message_iter_init_append(message, &array);
+
+	connman_dbus_dict_open(&array, &dict);
+
+	connman_dbus_dict_append_basic(&dict, "scan_ssid",
+					 DBUS_TYPE_UINT32, &scan_ssid);
+
+	connman_dbus_dict_append_fixed_array(&dict, "ssid",
+					DBUS_TYPE_BYTE, &ssid, ssid_len);
+
+	/*
+	 * We're setting an invalid BSSID to prevent wpa_s from associating
+	 * automatically to this block once it's found.
+	 */
+	connman_dbus_dict_append_basic(&dict, "bssid",
+					DBUS_TYPE_STRING, &invalid_address);
+
+	connman_dbus_dict_close(&array, &dict);
+
+	dbus_error_init(&error);
+
+	reply = dbus_connection_send_with_reply_and_block(connection,
+							message, -1, &error);
+	if (reply == NULL) {
+		if (dbus_error_is_set(&error) == TRUE) {
+			connman_error("%s", error.message);
+			dbus_error_free(&error);
+		} else
+			connman_error("Failed to set network options");
+		dbus_message_unref(message);
+		return -EIO;
+	}
+
+	dbus_message_unref(reply);
+
+	dbus_message_unref(message);
+
+	return 0;
+}
+
+static void block_reset(gpointer key, gpointer value, gpointer user_data)
+{
+	struct supplicant_block *block = value;
+	struct supplicant_task *task = user_data;
+
+	block->num_scans = 0;
+	if (block->enabled)
+		enable_network(task, block->netpath, FALSE);
+
+	block->enabled = FALSE;
+}
+
+#define MAX_BLOCK_SCANS 2
+static void hidden_block_enable(struct supplicant_task *task)
+{
+	GHashTableIter iter;
+	gpointer key, value;
+	struct supplicant_block *block;
+
+	DBG("network %p", task->network);
+
+	if (g_hash_table_size(task->hidden_blocks) == 0)
+		return;
+
+	/*
+	 * If we're associated or associating, we no longer need to
+	 * look for hidden networks.
+	 */
+	if (task->network)
+		return;
+
+	/*
+	 * We go through the block list and:
+	 * - If we scanned it more than twice, we disable it and move
+	 *   on to the next block.
+	 * - If the next block is not enabled, we enable it, start
+	 *   the scan counter, and return. This routine will be called
+	 *   again when the next scan results are available.
+	 * - If we're done with all the blocks there, we just reset them.
+	 */
+	g_hash_table_iter_init(&iter, task->hidden_blocks);
+	while (g_hash_table_iter_next(&iter, &key, &value)) {
+		block = value;
+
+		DBG("%s num of scans %d enabled %d",
+			block->ssid, block->num_scans, block->enabled);
+
+		if (block->num_scans > MAX_BLOCK_SCANS) {
+			if (block->enabled == FALSE)
+				continue;
+
+			enable_network(task, block->netpath, FALSE);
+			block->enabled = FALSE;
+			continue;
+		}
+
+		if (block->enabled == FALSE) {
+			enable_network(task, block->netpath, TRUE);
+			block->enabled = TRUE;
+		}
+
+		block->num_scans++;
+
+		return;
+	}
+
+	g_hash_table_foreach(task->hidden_blocks, block_reset, task);
+}
+
+static int add_hidden_network(struct supplicant_task *task,
+				const unsigned char *ssid, int ssid_len)
+{
+	DBusMessage *message, *reply;
+	DBusError error;
+	const char *path;
+	struct supplicant_block *block;
+	char *netpath = NULL;
+	int ret, i;
+
+	DBG("task %p", task);
+
+	message = dbus_message_new_method_call(SUPPLICANT_NAME, task->path,
+				SUPPLICANT_INTF ".Interface", "addNetwork");
+	if (message == NULL)
+		return -ENOMEM;
+
+	dbus_message_set_auto_start(message, FALSE);
+
+	dbus_error_init(&error);
+
+	reply = dbus_connection_send_with_reply_and_block(connection,
+							message, -1, &error);
+	if (reply == NULL) {
+		if (dbus_error_is_set(&error) == TRUE) {
+			connman_error("%s", error.message);
+			dbus_error_free(&error);
+		} else
+			connman_error("Failed to add network");
+		dbus_message_unref(message);
+		return -EIO;
+	}
+
+	dbus_error_init(&error);
+
+	if (dbus_message_get_args(reply, &error, DBUS_TYPE_OBJECT_PATH, &path,
+						DBUS_TYPE_INVALID) == FALSE) {
+		if (dbus_error_is_set(&error) == TRUE) {
+			connman_error("%s", error.message);
+			dbus_error_free(&error);
+		} else
+			connman_error("Wrong arguments for network");
+		dbus_message_unref(reply);
+		return -EIO;
+	}
+
+	netpath = g_strdup(path);
+
+	ret = set_hidden_network(task, netpath, ssid, ssid_len);
+	if (ret < 0)
+		goto done;
+
+	block = g_try_new0(struct supplicant_block, 1);
+	if (block == NULL)
+		goto done;
+
+	block->ssid = g_try_malloc0(ssid_len + 1);
+	if (block->ssid == NULL) {
+		g_free(block);
+		goto done;
+	}
+
+	for (i = 0; i < ssid_len; i++) {
+		if (g_ascii_isprint(ssid[i]))
+			block->ssid[i] = ssid[i];
+		else
+			block->ssid[i] = ' ';
+	}
+
+	block->netpath = netpath;
+	block->enabled = FALSE;
+	block->num_scans = 0;
+
+	DBG("path %s ssid %s", block->netpath, block->ssid);
+
+	g_hash_table_replace(task->hidden_blocks, block->ssid, block);
+
+	return 0;
+done:
+	g_free(netpath);
+
+	dbus_message_unref(reply);
+
+	dbus_message_unref(message);
+
+	return ret;
+}
+
 static void add_interface_reply(DBusPendingCall *call, void *user_data)
 {
 	struct supplicant_task *task = user_data;
 	DBusMessage *reply;
 	DBusError error;
 	const char *path;
+	char **hex_ssids, *hex_ssid;
+	int i;
 
 	DBG("task %p", task);
 
@@ -336,6 +610,31 @@
 
 	connman_device_set_powered(task->device, TRUE);
 
+	hex_ssids = connman_wifi_load_ssid();
+
+	for (i = 0; hex_ssids[i]; i++) {
+		unsigned char *ssid;
+		unsigned int j, k = 0, hex;
+		size_t hex_ssid_len;
+
+		hex_ssid = hex_ssids[i];
+		hex_ssid_len = strlen(hex_ssid);
+
+		ssid = g_try_malloc0(hex_ssid_len / 2 + 1);
+		if (ssid == NULL)
+			break;
+
+		for (j = 0, k = 0; j < hex_ssid_len; j += 2) {
+			sscanf(hex_ssid + j, "%02x", &hex);
+			ssid[k++] = hex;
+		}
+
+		if (add_hidden_network(task, ssid, hex_ssid_len / 2) < 0)
+			break;
+	}
+
+	g_strfreev(hex_ssids);
+
 	dbus_message_unref(reply);
 
 	dbus_pending_call_unref(call);
@@ -1021,6 +1320,17 @@
 						"wep_key0", DBUS_TYPE_BYTE,
 							&key, size / 2);
 				free(key);
+			} else if (size == 5 || size == 13) {
+				unsigned char *key = malloc(13);
+				int i;
+				if (key == NULL)
+					size = 0;
+				for (i = 0; i < size; i++)
+					key[i] = (unsigned char) passphrase[i];
+				connman_dbus_dict_append_fixed_array(&dict,
+						"wep_key0", DBUS_TYPE_BYTE,
+								&key, size);
+				free(key);
 			} else
 				connman_dbus_dict_append_basic(&dict,
 						"wep_key0", DBUS_TYPE_STRING,
@@ -1426,6 +1736,7 @@
 {
 	struct supplicant_task *task = user_data;
 	struct supplicant_result result;
+	struct supplicant_block *block;
 	struct connman_network *network;
 	DBusMessage *reply;
 	DBusMessageIter array, dict;
@@ -1517,6 +1828,17 @@
 	if (result.path[0] == '\0')
 		goto done;
 
+	if (result.name) {
+		block = g_hash_table_lookup(task->hidden_blocks, result.name);
+		if (block) {
+			enable_network(task, block->netpath, FALSE);
+			g_hash_table_remove(task->hidden_blocks, block->ssid);
+		}
+	}
+
+	if (result.ssid == NULL)
+		task->hidden_found = TRUE;
+
 	if (result.frequency > 0 && result.frequency < 14)
 		result.frequency = 2407 + (5 * result.frequency);
 	else if (result.frequency == 14)
@@ -1576,7 +1898,8 @@
 	if (result.name != NULL && result.name[0] != '\0')
 		connman_network_set_name(network, result.name);
 
-	connman_network_set_blob(network, "WiFi.SSID",
+	if (result.ssid_len != 0)
+		connman_network_set_blob(network, "WiFi.SSID",
 						result.ssid, result.ssid_len);
 
 	connman_network_set_string(network, "WiFi.Mode", mode);
@@ -1617,8 +1940,17 @@
 	char *path;
 
 	path = g_slist_nth_data(task->scan_results, 0);
-	if (path == NULL)
+	if (path == NULL) {
+		if (task->hidden_found == TRUE) {
+			/*
+			 * We're done with regular scanning, let's enable
+			 * the missing network blocks if there are hidden
+			 * SSIDs around.
+			 */
+			hidden_block_enable(task);
+		}
 		goto noscan;
+	}
 
 	message = dbus_message_new_method_call(SUPPLICANT_NAME, path,
 						SUPPLICANT_INTF ".BSSID",
@@ -1701,6 +2033,8 @@
 		task->scan_results = g_slist_append(task->scan_results, path);
 	}
 
+	task->hidden_found = FALSE;
+
 	g_strfreev(results);
 
 	dbus_message_unref(reply);
@@ -1791,6 +2125,8 @@
 	unsigned int ssid_len;
 	int err;
 
+	g_hash_table_foreach(task->hidden_blocks, block_reset, task);
+
 	connman_inet_ifup(task->ifindex);
 
 	address = connman_network_get_string(task->network, "Address");
@@ -1876,11 +2212,6 @@
 	if (state == WPA_INVALID)
 		return;
 
-	if (task->scanning == TRUE && state != WPA_SCANNING) {
-		connman_device_cleanup_scanning(task->device);
-		task->scanning = FALSE;
-	}
-
 	prevstate = task->state;
 	task->state = state;
 
@@ -2029,7 +2360,8 @@
 	task->state = WPA_INVALID;
 	task->disconnecting = FALSE;
 	task->pending_network = NULL;
-
+	task->hidden_blocks = g_hash_table_new_full(g_str_hash, g_str_equal,
+							NULL, remove_block);
 	task_list = g_slist_append(task_list, task);
 
 	return create_interface(task);
@@ -2056,6 +2388,7 @@
 	g_free(task->range);
 
 	task_list = g_slist_remove(task_list, task);
+	g_hash_table_destroy(task->hidden_blocks);
 
 	if (task->scan_call != NULL) {
 		dbus_pending_call_cancel(task->scan_call);
--- plugins/wifi.c
+++ plugins/wifi.c
@@ -99,12 +99,9 @@
 
 	if ((wifi->flags & IFF_UP) != (flags & IFF_UP)) {
 		if (flags & IFF_UP) {
-			DBG("power on");
-			connman_device_set_powered(device, TRUE);
-			supplicant_scan(device);
+			DBG("interface up");
 		} else {
-			connman_device_set_powered(device, FALSE);
-			DBG("power off");
+			DBG("interface down");
 		}
 	}
 
--- scripts/dhclient.conf
+++ scripts/dhclient.conf
@@ -1,4 +1,3 @@
-send host-name "<hostname>";
 option proxy-auto-config code 252 = text;
 request subnet-mask, broadcast-address, routers, host-name,
 	domain-search, domain-name, domain-name-servers,
--- src/config.c
+++ src/config.c
@@ -44,6 +44,7 @@
 	char *private_key_passphrase;
 	char *private_key_passphrase_type;
 	char *phase2;
+	char *passphrase;
 };
 
 struct connman_config {
@@ -87,6 +88,7 @@
 	g_free(service->private_key_passphrase);
 	g_free(service->private_key_passphrase_type);
 	g_free(service->phase2);
+	g_free(service->passphrase);
 	g_free(service);
 }
 
@@ -211,6 +213,12 @@
 		service->phase2 = str;
 	}
 
+	str = g_key_file_get_string(keyfile, group, "Passphrase", NULL);
+	if (str != NULL) {
+		g_free(service->passphrase);
+		service->passphrase = str;
+	}
+
 	g_hash_table_replace(config->service_table, service->ident, service);
 
 	connman_info("Adding service configuration %s", service->ident);
@@ -440,6 +448,9 @@
 
 	if (config->phase2 != NULL)
 		__connman_service_set_string(service, "Phase2", config->phase2);
+
+	if (config->passphrase != NULL)
+		__connman_service_set_string(service, "Passphrase", config->passphrase);
 }
 
 int __connman_config_provision_service(struct connman_service *service)
--- src/connection.c
+++ src/connection.c
@@ -38,6 +38,7 @@
 	/* VPN extra data */
 	gboolean vpn;
 	char *vpn_ip;
+	int vpn_phy_index;
 };
 
 static GSList *gateway_list = NULL;
@@ -65,16 +66,19 @@
 
 static int del_routes(struct gateway_data *data)
 {
-	const char *address;
-
-	connman_inet_del_host_route(data->index, data->gateway);
-
-	if (data->vpn)
-		address = data->vpn_ip;
-	else
-		address = data->gateway;
-
-	return connman_inet_clear_gateway_address(data->index, address);
+	if (data->vpn) {
+		if (data->vpn_phy_index >= 0)
+			connman_inet_del_host_route(data->vpn_phy_index,
+							data->gateway);
+		return connman_inet_clear_gateway_address(data->index,
+							data->vpn_ip);
+	} else if (g_strcmp0(data->gateway, "0.0.0.0") == 0) {
+		return connman_inet_clear_gateway_interface(data->index);
+	} else {
+		connman_inet_del_host_route(data->index, data->gateway);
+		return connman_inet_clear_gateway_address(data->index,
+							data->gateway);
+	}
 }
 
 static void find_element(struct connman_element *element, gpointer user_data)
@@ -107,6 +111,7 @@
 	data->element = NULL;
 	data->vpn_ip = NULL;
 	data->vpn = FALSE;
+	data->vpn_phy_index = -1;
 
 	__connman_element_foreach(NULL, CONNMAN_ELEMENT_TYPE_CONNECTION,
 							find_element, data);
@@ -136,23 +141,17 @@
 {
 	struct connman_element *element = data->element;
 	struct connman_service *service = NULL;
-	short int ifflags;
 
 	DBG("gateway %s", data->gateway);
 
 	if (data->vpn == TRUE) {
 		connman_inet_set_gateway_address(data->index, data->vpn_ip);
+		data->active = TRUE;
 		/* vpn gateway going away no changes in services */
 		return;
 	}
 
-	ifflags = connman_inet_ifflags(element->index);
-	if (ifflags < 0) {
-		connman_error("Fail to get network interface flags");
-		return;
-	}
-
-	if (ifflags & IFF_POINTOPOINT) {
+	if (g_strcmp0(data->gateway, "0.0.0.0") == 0) {
 		if (connman_inet_set_gateway_interface(element->index) < 0)
 			return;
 		goto done;
@@ -186,18 +185,24 @@
 	return found;
 }
 
-static void remove_gateway(struct gateway_data *data)
+static int remove_gateway(struct gateway_data *data)
 {
+	int err;
+
 	DBG("gateway %s", data->gateway);
 
 	gateway_list = g_slist_remove(gateway_list, data);
 
 	if (data->active == TRUE)
-		del_routes(data);
+		err = del_routes(data);
+	else
+		err = 0;
 
 	g_free(data->gateway);
 	g_free(data->vpn_ip);
 	g_free(data);
+
+	return err;
 }
 
 static void connection_delgateway(int index, const char *gateway)
@@ -229,6 +234,7 @@
 
 	for (list = gateway_list; list; list = list->next) {
 		struct gateway_data *data = list->data;
+
 		if (data->active == TRUE)
 			return data;
 	}
@@ -261,15 +267,21 @@
 
 	DBG("gateway %s", gateway);
 
+	/*
+	 * If gateway is NULL, it's a point to point link and the default
+	 * gateway is 0.0.0.0, meaning the interface.
+	 */
+	if (gateway == NULL) {
+		gateway = "0.0.0.0";
+		element->ipv4.gateway = g_strdup(gateway);
+	}
+
 	service = __connman_element_get_service(element);
 	__connman_service_indicate_state(service,
 					CONNMAN_SERVICE_STATE_READY);
 
 	connman_element_set_enabled(element, TRUE);
 
-	if (gateway == NULL)
-		return 0;
-
 	active_gateway = find_active_gateway();
 	new_gateway = add_gateway(element->index, gateway);
 
@@ -278,6 +290,8 @@
 		new_gateway->vpn_ip = g_strdup(vpn_ip);
 		/* make sure vpn gateway are at higher priority */
 		new_gateway->order = 10;
+		if (active_gateway)
+			new_gateway->vpn_phy_index = active_gateway->index;
 	} else
 		new_gateway->vpn = FALSE;
 
@@ -290,9 +304,6 @@
 		connman_inet_add_host_route_vpn(active_gateway->index,
 						active_gateway->gateway,
 						new_gateway->gateway);
-
-		connman_inet_set_gateway_address(new_gateway->index,
-							new_gateway->gateway);
 	}
 
 	if (new_gateway->order >= active_gateway->order) {
@@ -309,6 +320,7 @@
 	const char *gateway = NULL;
 	struct gateway_data *data = NULL;
 	gboolean set_default = FALSE;
+	int err;
 
 	DBG("element %p name %s", element, element->name);
 
@@ -332,16 +344,17 @@
 
 	set_default = data->vpn;
 
-	if (data->vpn == TRUE)
-		connman_inet_del_host_route(data->index, data->gateway);
+	if (data->vpn == TRUE && data->vpn_phy_index >= 0)
+		connman_inet_del_host_route(data->vpn_phy_index, data->gateway);
 
-	remove_gateway(data);
+	err = remove_gateway(data);
 
 	/* with vpn this will be called after the network was deleted,
 	 * we need to call set_default here because we will not recieve any
 	 * gateway delete notification.
+	 * We hit the same issue if remove_gateway() fails.
 	 */
-	if (set_default) {
+	if (set_default || err < 0) {
 		data = find_default_gateway();
 		if (data != NULL)
 			set_default_gateway(data);
--- src/connman.h
+++ src/connman.h
@@ -37,6 +37,7 @@
 DBusMessage *__connman_error_permission_denied(DBusMessage *msg);
 DBusMessage *__connman_error_passphrase_required(DBusMessage *msg);
 DBusMessage *__connman_error_not_registered(DBusMessage *msg);
+DBusMessage *__connman_error_not_unique(DBusMessage *msg);
 DBusMessage *__connman_error_not_supported(DBusMessage *msg);
 DBusMessage *__connman_error_not_implemented(DBusMessage *msg);
 DBusMessage *__connman_error_not_found(DBusMessage *msg);
@@ -252,6 +253,9 @@
 
 #include <connman/timeserver.h>
 
+int __connman_timeserver_init(void);
+void __connman_timeserver_cleanup(void);
+
 #include <connman/dhcp.h>
 
 int __connman_dhcp_init(void);
@@ -338,6 +342,10 @@
 
 int __connman_network_connect(struct connman_network *network);
 int __connman_network_disconnect(struct connman_network *network);
+int __connman_network_clear_ipconfig(struct connman_network *network,
+					struct connman_ipconfig *ipconfig);
+int __connman_network_set_ipconfig(struct connman_network *network,
+					struct connman_ipconfig *ipconfig);
 
 connman_bool_t __connman_network_has_driver(struct connman_network *network);
 
@@ -383,6 +391,7 @@
 void __connman_service_cleanup(void);
 
 void __connman_service_list(DBusMessageIter *iter, void *user_data);
+void __connman_service_list_struct(DBusMessageIter *iter);
 const char *__connman_service_default(void);
 
 void __connman_service_put(struct connman_service *service);
@@ -412,6 +421,7 @@
 					enum connman_service_error error);
 int __connman_service_indicate_default(struct connman_service *service);
 
+int __connman_service_lookup(const char *pattern, const char **path);
 int __connman_service_connect(struct connman_service *service);
 int __connman_service_disconnect(struct connman_service *service);
 int __connman_service_create_and_connect(DBusMessage *msg);
@@ -420,6 +430,11 @@
 
 const char *__connman_service_type2string(enum connman_service_type type);
 
+void __connman_service_append_nameserver(struct connman_service *service,
+						const char *nameserver);
+void __connman_service_remove_nameserver(struct connman_service *service,
+						const char *nameserver);
+
 #include <connman/location.h>
 
 int __connman_location_init(void);
@@ -464,6 +479,7 @@
 void __connman_notifier_offlinemode(connman_bool_t enabled);
 void __connman_notifier_default_changed(struct connman_service *service);
 
+connman_bool_t __connman_notifier_is_registered(enum connman_service_type type);
 connman_bool_t __connman_notifier_is_enabled(enum connman_service_type type);
 unsigned int __connman_notifier_count_connected(void);
 const char *__connman_notifier_get_state(void);
--- src/device.c
+++ src/device.c
@@ -1184,24 +1184,6 @@
 					DBUS_TYPE_BOOLEAN, &device->scanning);
 }
 
-static void mark_network_available(gpointer key, gpointer value,
-						gpointer user_data)
-{
-	struct connman_network *network = value;
-
-	connman_network_set_available(network, TRUE);
-}
-
-void connman_device_cleanup_scanning(struct connman_device *device)
-{
-	device->scanning = FALSE;
-
-	scanning_changed(device);
-
-	g_hash_table_foreach(device->networks,
-				mark_network_available, NULL);
-}
-
 /**
  * connman_device_set_scanning:
  * @device: device structure
--- src/dhcp.c
+++ src/dhcp.c
@@ -96,6 +96,8 @@
 void connman_dhcp_set_value(struct connman_dhcp *dhcp,
 					const char *key, const char *value)
 {
+	char **nameservers;
+
 	if (g_strcmp0(key, "Address") == 0) {
 		g_free(dhcp->element->ipv4.address);
 		dhcp->element->ipv4.address = g_strdup(value);
@@ -113,7 +115,14 @@
 		dhcp->element->ipv4.broadcast = g_strdup(value);
 	} else if (g_strcmp0(key, "Nameserver") == 0) {
 		g_free(dhcp->element->ipv4.nameserver);
-		dhcp->element->ipv4.nameserver = g_strdup(value);
+		nameservers = g_strsplit_set(value, " ", 0);
+		/* FIXME: The ipv4 structure can only hold one nameserver, so
+		 * we are only able to pass along the first nameserver sent by
+		 * the DHCP server.  If this situation changes, we should
+		 * retain all of them.
+		 */
+		dhcp->element->ipv4.nameserver = g_strdup(nameservers[0]);
+		g_strfreev(nameservers);
 	} else if (g_strcmp0(key, "Domainname") == 0) {
 		__connman_utsname_set_domainname(value);
 	} else if (g_strcmp0(key, "Hostname") == 0) {
--- src/element.c
+++ src/element.c
@@ -1120,6 +1120,45 @@
 	return FALSE;
 }
 
+struct unregister_type {
+	struct connman_element *root;
+	enum connman_element_type type;
+};
+
+static gboolean remove_element_type(GNode *node, gpointer user_data)
+{
+	struct unregister_type *children_type = user_data;
+	struct connman_element *root = children_type->root;
+	struct connman_element *element = node->data;
+	enum connman_element_type type = children_type->type;
+
+	DBG("element %p name %s", element, element->name);
+
+	if (element == root)
+		return FALSE;
+
+	if(element->type != type)
+		return FALSE;
+
+	if (node != NULL)
+		g_node_unlink(node);
+
+	if (element->driver) {
+		if (element->driver->remove)
+			element->driver->remove(element);
+
+		element->driver = NULL;
+	}
+
+	if (node != NULL)
+		g_node_destroy(node);
+
+	connman_element_unref(element);
+
+	return FALSE;
+}
+
+
 void connman_element_unregister(struct connman_element *element)
 {
 	GNode *node;
@@ -1146,6 +1185,25 @@
 				G_TRAVERSE_ALL, -1, remove_element, element);
 }
 
+void connman_element_unregister_children_type(struct connman_element *element, enum connman_element_type type)
+{
+	GNode *node;
+
+	DBG("element %p name %s", element, element->name);
+
+	node = g_node_find(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, element);
+
+	if (node != NULL) {
+		struct unregister_type children_type;
+
+		children_type.root = element;
+		children_type.type = type;
+		g_node_traverse(node, G_POST_ORDER,
+				G_TRAVERSE_ALL, -1, remove_element_type, &children_type);
+	}
+}
+
+
 static gboolean update_element(GNode *node, gpointer user_data)
 {
 	struct connman_element *element = node->data;
--- src/error.c
+++ src/error.c
@@ -49,6 +49,8 @@
 		return __connman_error_not_implemented(msg);
 	case ENOLINK:
 		return __connman_error_no_carrier(msg);
+	case ENOTUNIQ:
+		return __connman_error_not_unique(msg);
 	case EOPNOTSUPP:
 		return __connman_error_not_supported(msg);
 	case ECONNABORTED:
@@ -93,6 +95,12 @@
 					".NotRegistered", "Not registered");
 }
 
+DBusMessage *__connman_error_not_unique(DBusMessage *msg)
+{
+	return g_dbus_create_error(msg, CONNMAN_ERROR_INTERFACE
+					".NotUnique", "Not unique");
+}
+
 DBusMessage *__connman_error_not_supported(DBusMessage *msg)
 {
 	return g_dbus_create_error(msg, CONNMAN_ERROR_INTERFACE
--- src/inet.c
+++ src/inet.c
@@ -899,3 +899,48 @@
 
 	return err;
 }
+
+int connman_inet_clear_gateway_interface(int index)
+{
+	struct ifreq ifr;
+	struct rtentry rt;
+	struct sockaddr_in addr;
+	int sk, err;
+
+	DBG("");
+
+	sk = socket(PF_INET, SOCK_DGRAM, 0);
+	if (sk < 0)
+		return -1;
+
+	memset(&ifr, 0, sizeof(ifr));
+	ifr.ifr_ifindex = index;
+
+	if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
+		close(sk);
+		return -1;
+	}
+
+	DBG("ifname %s", ifr.ifr_name);
+
+	memset(&rt, 0, sizeof(rt));
+	rt.rt_flags = RTF_UP;
+
+	memset(&addr, 0, sizeof(addr));
+	addr.sin_family = AF_INET;
+	addr.sin_addr.s_addr = INADDR_ANY;
+
+	memcpy(&rt.rt_genmask, &addr, sizeof(rt.rt_genmask));
+	memcpy(&rt.rt_dst, &addr, sizeof(rt.rt_dst));
+	memcpy(&rt.rt_gateway, &addr, sizeof(rt.rt_gateway));
+
+	rt.rt_dev = ifr.ifr_name;
+
+	err = ioctl(sk, SIOCDELRT, &rt);
+	if (err < 0)
+		connman_error("Removing default interface route failed (%s)",
+							strerror(errno));
+	close(sk);
+
+	return err;
+}
--- src/ipconfig.c
+++ src/ipconfig.c
@@ -381,7 +381,6 @@
 	GString *str;
 	gboolean up = FALSE, down = FALSE;
 	gboolean lower_up = FALSE, lower_down = FALSE;
-	char *ifname;
 
 	DBG("index %d", index);
 
@@ -392,22 +391,12 @@
 	if (ipdevice != NULL)
 		goto update;
 
-	ifname = connman_inet_ifname(index);
-
-	if (__connman_element_device_isfiltered(ifname) == TRUE) {
-		connman_info("Ignoring interface %s (filtered)", ifname);
-		g_free(ifname);
-		return;
-	}
-
 	ipdevice = g_try_new0(struct connman_ipdevice, 1);
-	if (ipdevice == NULL) {
-		g_free(ifname);
+	if (ipdevice == NULL)
 		return;
-	}
 
 	ipdevice->index = index;
-	ipdevice->ifname = ifname;
+	ipdevice->ifname = connman_inet_ifname(index);
 	ipdevice->type = type;
 
 	ipdevice->address = g_strdup(address);
@@ -634,8 +623,23 @@
 		return;
 
 	if (scope == 0 && g_strcmp0(dst, "0.0.0.0") == 0) {
+		GSList *list;
+
 		g_free(ipdevice->gateway);
 		ipdevice->gateway = g_strdup(gateway);
+
+		if (ipdevice->config != NULL &&
+					ipdevice->config->system != NULL) {
+			g_free(ipdevice->config->system->gateway);
+			ipdevice->config->system->gateway = g_strdup(gateway);
+		}
+
+		for (list = ipdevice->address_list; list; list = list->next) {
+			struct connman_ipaddress *ipaddress = list->data;
+
+			g_free(ipaddress->gateway);
+			ipaddress->gateway = g_strdup(gateway);
+		}
 	}
 
 	connman_info("%s {add} route %s gw %s scope %u <%s>",
@@ -655,8 +659,23 @@
 		return;
 
 	if (scope == 0 && g_strcmp0(dst, "0.0.0.0") == 0) {
+		GSList *list;
+
 		g_free(ipdevice->gateway);
 		ipdevice->gateway = NULL;
+
+		if (ipdevice->config != NULL &&
+					ipdevice->config->system != NULL) {
+			g_free(ipdevice->config->system->gateway);
+			ipdevice->config->system->gateway = NULL;
+		}
+
+		for (list = ipdevice->address_list; list; list = list->next) {
+			struct connman_ipaddress *ipaddress = list->data;
+
+			g_free(ipaddress->gateway);
+			ipaddress->gateway = NULL;
+		}
 	}
 
 	connman_info("%s {del} route %s gw %s scope %u <%s>",
@@ -848,6 +867,9 @@
  */
 int connman_ipconfig_get_index(struct connman_ipconfig *ipconfig)
 {
+	if (ipconfig == NULL)
+		return -1;
+
 	if (ipconfig->origin != NULL)
 		return ipconfig->origin->index;
 
@@ -864,6 +886,9 @@
 {
 	struct connman_ipdevice *ipdevice;
 
+	if (ipconfig == NULL)
+		return NULL;
+
 	if (ipconfig->index < 0)
 		return NULL;
 
@@ -903,8 +928,7 @@
 	return 0;
 }
 
-enum connman_ipconfig_method __connman_ipconfig_get_method(
-				struct connman_ipconfig *ipconfig)
+enum connman_ipconfig_method __connman_ipconfig_get_method(struct connman_ipconfig *ipconfig)
 {
 	if (ipconfig == NULL)
 		return CONNMAN_IPCONFIG_METHOD_UNKNOWN;
@@ -1109,6 +1133,10 @@
 		connman_dbus_dict_append_basic(iter, "Netmask",
 						DBUS_TYPE_STRING, &mask);
 	}
+
+	if (ipconfig->system->gateway != NULL)
+		connman_dbus_dict_append_basic(iter, "Gateway",
+				DBUS_TYPE_STRING, &ipconfig->system->gateway);
 }
 
 void __connman_ipconfig_append_ipv4config(struct connman_ipconfig *ipconfig,
@@ -1149,6 +1177,10 @@
 		connman_dbus_dict_append_basic(iter, "Netmask",
 						DBUS_TYPE_STRING, &mask);
 	}
+
+	if (ipconfig->address->gateway != NULL)
+		connman_dbus_dict_append_basic(iter, "Gateway",
+				DBUS_TYPE_STRING, &ipconfig->address->gateway);
 }
 
 int __connman_ipconfig_set_ipv4config(struct connman_ipconfig *ipconfig,
--- src/ipv4.c
+++ src/ipv4.c
@@ -40,8 +40,7 @@
 	struct in_addr broadcast;
 };
 
-static int set_ipv4(struct connman_element *element,
-			struct connman_ipv4 *ipv4, const char *nameserver)
+static int set_ipv4(struct connman_element *element, struct connman_ipv4 *ipv4)
 {
 	struct ifreq ifr;
 	struct sockaddr_in addr;
@@ -95,11 +94,6 @@
 
 	close(sk);
 
-	if (nameserver == NULL)
-		connman_error("No nameserver for %s defined", ifr.ifr_name);
-	else
-		connman_resolver_append(ifr.ifr_name, NULL, nameserver);
-
 	return 0;
 }
 
@@ -125,8 +119,6 @@
 
 	DBG("ifname %s", ifr.ifr_name);
 
-	connman_resolver_remove_all(ifr.ifr_name);
-
 	memset(&addr, 0, sizeof(addr));
 	addr.sin_family = AF_INET;
 	addr.sin_addr.s_addr = INADDR_ANY;
@@ -175,7 +167,8 @@
 	struct connman_element *connection;
 	struct connman_ipv4 ipv4;
 	const char *address = NULL, *netmask = NULL, *broadcast = NULL;
-	const char *nameserver = NULL, *timeserver = NULL;
+	const char *nameserver = NULL;
+	char *timeserver = NULL;
 
 	DBG("element %p name %s", element, element->name);
 
@@ -207,7 +200,14 @@
 		ipv4.broadcast.s_addr = ipv4.address.s_addr |
 						~ipv4.netmask.s_addr;
 
-	set_ipv4(element, &ipv4, nameserver);
+	set_ipv4(element, &ipv4);
+
+	if (nameserver != NULL) {
+		struct connman_service *service;
+
+		service = __connman_element_get_service(element);
+		__connman_service_append_nameserver(service, nameserver);
+	}
 
 	connman_timeserver_append(timeserver);
 
@@ -225,15 +225,25 @@
 
 static void ipv4_remove(struct connman_element *element)
 {
-	const char *timeserver = NULL;
+	const char *nameserver = NULL;
+	char *timeserver = NULL;
 
 	DBG("element %p name %s", element, element->name);
 
 	connman_element_get_value(element,
+			CONNMAN_PROPERTY_ID_IPV4_NAMESERVER, &nameserver);
+	connman_element_get_value(element,
 			CONNMAN_PROPERTY_ID_IPV4_TIMESERVER, &timeserver);
 
 	connman_timeserver_remove(timeserver);
 
+	if (nameserver != NULL) {
+		struct connman_service *service;
+
+		service = __connman_element_get_service(element);
+		__connman_service_remove_nameserver(service, nameserver);
+	}
+
 	clear_ipv4(element);
 }
 
--- src/main.c
+++ src/main.c
@@ -67,8 +67,20 @@
 static gboolean option_selftest = FALSE;
 static gboolean option_version = FALSE;
 
+static gboolean parse_debug(const char *key, const char *value,
+					gpointer user_data, GError **error)
+{
+	if (value)
+		option_debug = g_strdup(value);
+	else
+		option_debug = g_strdup("*");
+
+	return TRUE;
+}
+
 static GOptionEntry options[] = {
-	{ "debug", 'd', 0, G_OPTION_ARG_STRING, &option_debug,
+	{ "debug", 'd', G_OPTION_FLAG_OPTIONAL_ARG,
+				G_OPTION_ARG_CALLBACK, parse_debug,
 				"Specify debug options to enable", "DEBUG" },
 	{ "device", 'i', 0, G_OPTION_ARG_STRING, &option_device,
 			"Specify networking device or interface", "DEV" },
@@ -218,6 +230,7 @@
 	__connman_udev_init();
 	__connman_task_init();
 	__connman_session_init();
+	__connman_timeserver_init();
 
 	__connman_plugin_init(option_plugin, option_noplugin);
 
@@ -239,6 +252,7 @@
 
 	__connman_plugin_cleanup();
 
+	__connman_timeserver_cleanup();
 	__connman_session_cleanup();
 	__connman_task_cleanup();
 	__connman_udev_cleanup();
--- src/manager.c
+++ src/manager.c
@@ -345,6 +345,9 @@
 	else
 		return __connman_error_invalid_arguments(msg);
 
+	if (__connman_notifier_is_registered(type) == FALSE)
+		return __connman_error_not_registered(msg);
+
 	if (__connman_notifier_is_enabled(type) == TRUE)
 		return __connman_error_already_enabled(msg);
 
@@ -390,6 +393,9 @@
 	else
 		return __connman_error_invalid_arguments(msg);
 
+	if (__connman_notifier_is_registered(type) == FALSE)
+		return __connman_error_not_registered(msg);
+
 	if (__connman_notifier_is_enabled(type) == FALSE)
 		return __connman_error_already_disabled(msg);
 
@@ -407,6 +413,54 @@
 	return NULL;
 }
 
+static DBusMessage *get_services(DBusConnection *conn,
+					DBusMessage *msg, void *data)
+{
+	DBusMessage *reply;
+	DBusMessageIter iter, array;
+
+	reply = dbus_message_new_method_return(msg);
+	if (reply == NULL)
+		return NULL;
+
+	dbus_message_iter_init_append(reply, &iter);
+
+	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
+			DBUS_STRUCT_BEGIN_CHAR_AS_STRING
+			DBUS_TYPE_OBJECT_PATH_AS_STRING
+			DBUS_TYPE_ARRAY_AS_STRING
+				DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+					DBUS_TYPE_STRING_AS_STRING
+					DBUS_TYPE_VARIANT_AS_STRING
+				DBUS_DICT_ENTRY_END_CHAR_AS_STRING
+			DBUS_STRUCT_END_CHAR_AS_STRING, &array);
+
+	__connman_service_list_struct(&array);
+
+	dbus_message_iter_close_container(&iter, &array);
+
+	return reply;
+}
+
+static DBusMessage *lookup_service(DBusConnection *conn,
+					DBusMessage *msg, void *data)
+{
+	const char *pattern, *path;
+	int err;
+
+	DBG("conn %p", conn);
+
+	dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &pattern,
+							DBUS_TYPE_INVALID);
+
+	err = __connman_service_lookup(pattern, &path);
+	if (err < 0)
+		return __connman_error_failed(msg, -err);
+
+	return g_dbus_create_reply(msg, DBUS_TYPE_OBJECT_PATH, &path,
+							DBUS_TYPE_INVALID);
+}
+
 static DBusMessage *connect_service(DBusConnection *conn,
 					DBusMessage *msg, void *data)
 {
@@ -433,7 +487,7 @@
 
 
 static DBusMessage *connect_provider(DBusConnection *conn,
-				     DBusMessage *msg, void *data)
+					DBusMessage *msg, void *data)
 {
 	int err;
 
@@ -590,6 +644,8 @@
 						G_DBUS_METHOD_FLAG_ASYNC },
 	{ "DisableTechnology", "s",     "",      disable_technology,
 						G_DBUS_METHOD_FLAG_ASYNC },
+	{ "GetServices",       "",      "a(oa{sv})", get_services   },
+	{ "LookupService",     "s",     "o",     lookup_service,    },
 	{ "ConnectService",    "a{sv}", "o",     connect_service,
 						G_DBUS_METHOD_FLAG_ASYNC },
 	{ "ConnectProvider",   "a{sv}", "o",     connect_provider,
--- src/network.c
+++ src/network.c
@@ -741,10 +741,51 @@
 					CONNMAN_SERVICE_STATE_CONFIGURATION);
 }
 
+static int set_connected_fixed(struct connman_network *network)
+{
+	struct connman_service *service;
+	struct connman_element *parent, *element;
+
+	DBG("");
+
+	service = __connman_service_lookup_from_network(network);
+
+	parent = connman_network_get_element(network);
+
+	set_configuration(network);
+
+	if (parent->ipv4.address == NULL)
+		return -EINVAL;
+
+	if (parent->ipv4.netmask == NULL)
+		return -EINVAL;
+
+	element = connman_element_create(NULL);
+	if (element == NULL) {
+		connman_error("Can not create connman_element");
+		return -ENOMEM;
+	}
+
+	element->type = CONNMAN_ELEMENT_TYPE_IPV4;
+	element->index = parent->index;
+
+	if (connman_element_register(element, parent) < 0) {
+		connman_error("Can not register connman_element");
+		return -EINVAL;
+	}
+
+	network->connecting = FALSE;
+
+	connman_network_set_associating(network, FALSE);
+
+	return 0;
+}
+
 static void set_connected_manual(struct connman_network *network)
 {
 	struct connman_service *service;
 	struct connman_ipconfig *ipconfig;
+	const char *nameserver = NULL;
 	int err;
 
 	DBG("network %p", network);
@@ -762,6 +803,11 @@
 		return;
 	}
 
+	connman_element_get_value(&network->element,
+			CONNMAN_PROPERTY_ID_IPV4_NAMESERVER, &nameserver);
+	if (nameserver != NULL)
+		__connman_service_append_nameserver(service, nameserver);
+
 	__connman_ipconfig_set_gateway(ipconfig, &network->element);
 
 	network->connecting = FALSE;
@@ -819,8 +865,14 @@
 		case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
 		case CONNMAN_IPCONFIG_METHOD_OFF:
 			return FALSE;
-		case CONNMAN_IPCONFIG_METHOD_MANUAL:
 		case CONNMAN_IPCONFIG_METHOD_FIXED:
+			if (set_connected_fixed(network) < 0) {
+				connman_network_set_error(network,
+					CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL);
+				return FALSE;
+			}
+			return TRUE;
+		case CONNMAN_IPCONFIG_METHOD_MANUAL:
 			set_connected_manual(network);
 			return TRUE;
 		case CONNMAN_IPCONFIG_METHOD_DHCP:
@@ -993,6 +1045,122 @@
 	return err;
 }
 
+static int dhcp_start(struct connman_network *network)
+{
+	struct connman_element *element;
+	int error;
+
+	if (network->protocol != CONNMAN_NETWORK_PROTOCOL_IP)
+		return -EINVAL;
+
+	element = connman_element_create(NULL);
+	if (element == NULL)
+		return -ENOMEM;
+
+	element->type  = CONNMAN_ELEMENT_TYPE_DHCP;
+	element->index = network->element.index;
+
+	error = connman_element_register(element, &network->element);
+	if (error < 0) {
+		connman_element_unref(element);
+		return error;
+	}
+
+	return 0;
+}
+
+static int dhcp_stop(struct connman_network *network)
+{
+	if (network->protocol != CONNMAN_NETWORK_PROTOCOL_IP)
+		return -EINVAL;
+
+	connman_element_unregister_children_type(&network->element,
+					CONNMAN_ELEMENT_TYPE_CONNECTION);
+	connman_element_unregister_children_type(&network->element,
+						CONNMAN_ELEMENT_TYPE_IPV4);
+	connman_element_unregister_children_type(&network->element,
+						CONNMAN_ELEMENT_TYPE_DHCP);
+
+	return 0;
+}
+
+static int manual_ipv4_set(struct connman_network *network,
+				struct connman_ipconfig *ipconfig)
+{
+	struct connman_service *service;
+	int err;
+
+	service = __connman_service_lookup_from_network(network);
+	if (service == NULL)
+		return -EINVAL;
+
+	err = __connman_ipconfig_set_address(ipconfig);
+	if (err < 0) {
+		connman_network_set_error(network,
+			CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL);
+		return err;
+	}
+
+	__connman_ipconfig_set_gateway(ipconfig, &network->element);
+
+	__connman_service_indicate_state(service, CONNMAN_SERVICE_STATE_READY);
+
+	return 0;
+}
+
+int __connman_network_clear_ipconfig(struct connman_network *network,
+					struct connman_ipconfig *ipconfig)
+{
+	struct connman_service *service;
+	enum connman_ipconfig_method method;
+
+	service = __connman_service_lookup_from_network(network);
+	if (service == NULL)
+		return -EINVAL;
+
+	method = __connman_ipconfig_get_method(ipconfig);
+
+	switch (method) {
+	case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
+	case CONNMAN_IPCONFIG_METHOD_OFF:
+	case CONNMAN_IPCONFIG_METHOD_FIXED:
+		return -EINVAL;
+	case CONNMAN_IPCONFIG_METHOD_MANUAL:
+		connman_element_unregister_children_type(&network->element,
+					CONNMAN_ELEMENT_TYPE_CONNECTION);
+		__connman_ipconfig_clear_address(ipconfig);
+		break;
+	case CONNMAN_IPCONFIG_METHOD_DHCP:
+		dhcp_stop(network);
+		break;
+	}
+
+	__connman_service_indicate_state(service,
+					CONNMAN_SERVICE_STATE_CONFIGURATION);
+
+	return 0;
+}
+
+int __connman_network_set_ipconfig(struct connman_network *network, struct connman_ipconfig *ipconfig)
+{
+	enum connman_ipconfig_method method;
+
+	method = __connman_ipconfig_get_method(ipconfig);
+
+	switch (method) {
+	case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
+	case CONNMAN_IPCONFIG_METHOD_OFF:
+	case CONNMAN_IPCONFIG_METHOD_FIXED:
+		return -EINVAL;
+	case CONNMAN_IPCONFIG_METHOD_MANUAL:
+		return manual_ipv4_set(network, ipconfig);
+	case CONNMAN_IPCONFIG_METHOD_DHCP:
+		return dhcp_start(network);
+	}
+
+	return 0;
+}
+
 /**
  * connman_network_set_address:
  * @network: network structure
@@ -1397,6 +1565,27 @@
 	network->driver_data = data;
 }
 
+void connman_network_update(struct connman_network *network)
+{
+	switch (network->type) {
+	case CONNMAN_NETWORK_TYPE_UNKNOWN:
+	case CONNMAN_NETWORK_TYPE_VENDOR:
+		return;
+	case CONNMAN_NETWORK_TYPE_ETHERNET:
+	case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
+	case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
+	case CONNMAN_NETWORK_TYPE_CELLULAR:
+	case CONNMAN_NETWORK_TYPE_WIFI:
+	case CONNMAN_NETWORK_TYPE_WIMAX:
+		break;
+	}
+
+	if (network->group != NULL)
+		__connman_service_update_from_network(network);
+
+	return;
+}
+
 static gboolean match_driver(struct connman_network *network,
 					struct connman_network_driver *driver)
 {
--- src/notifier.c
+++ src/notifier.c
@@ -401,10 +401,8 @@
 	}
 }
 
-connman_bool_t __connman_notifier_is_enabled(enum connman_service_type type)
+static connman_bool_t technology_supported(enum connman_service_type type)
 {
-	DBG("type %d", type);
-
 	switch (type) {
 	case CONNMAN_SERVICE_TYPE_UNKNOWN:
 	case CONNMAN_SERVICE_TYPE_SYSTEM:
@@ -419,6 +417,29 @@
 		break;
 	}
 
+	return TRUE;
+}
+
+connman_bool_t __connman_notifier_is_registered(enum connman_service_type type)
+{
+	DBG("type %d", type);
+
+	if (technology_supported(type) == FALSE)
+		return FALSE;
+
+	if (g_atomic_int_get(&registered[type]) > 0)
+		return TRUE;
+
+	return FALSE;
+}
+
+connman_bool_t __connman_notifier_is_enabled(enum connman_service_type type)
+{
+	DBG("type %d", type);
+
+	if (technology_supported(type) == FALSE)
+		return FALSE;
+
 	if (g_atomic_int_get(&enabled[type]) > 0)
 		return TRUE;
 
--- src/resolver.c
+++ src/resolver.c
@@ -29,6 +29,7 @@
 #include <unistd.h>
 #include <string.h>
 #include <sys/stat.h>
+#include <resolv.h>
 
 #include "connman.h"
 
@@ -333,17 +334,56 @@
 	return 0;
 }
 
-static int resolvfile_append(const char *interface, const char *domain,
-							const char *server)
+struct resolvfile_entry {
+	char *interface;
+	char *domain;
+	char *server;
+};
+
+static GList *resolvfile_list = NULL;
+
+static void resolvfile_remove_entries(GList *entries)
+{
+	GList *list;
+
+	for (list = entries; list; list = list->next) {
+		struct resolvfile_entry *entry = list->data;
+
+		resolvfile_list = g_list_remove(resolvfile_list, entry);
+
+		g_free(entry->server);
+		g_free(entry->domain);
+		g_free(entry->interface);
+		g_free(entry);
+	}
+
+	g_list_free(entries);
+}
+
+static int resolvfile_export(void)
 {
-	char *cmd;
-	int fd, len, err;
+	GList *list;
+	GString *content;
+	int fd, err;
+	unsigned int count;
 	mode_t old_umask;
 
-	DBG("interface %s server %s", interface, server);
+	content = g_string_new("# Generated by Connection Manager\n"
+						"options edns0\n");
 
-	if (interface == NULL)
-		return -ENOENT;
+	/*
+	 * Nameservers are added in reverse so that the most recently
+	 * appended entry is the primary nameserver. No more than MAXNS
+	 * nameservers are used.
+	 */
+	for (count = 0, list = g_list_last(resolvfile_list);
+						list && (count < MAXNS);
+						list = g_list_previous(list)) {
+		struct resolvfile_entry *entry = list->data;
+		g_string_append_printf(content, "nameserver %s\n",
+								entry->server);
+		count++;
+	}
 
 	old_umask = umask(022);
 
@@ -361,31 +401,68 @@
 
 	err = 0;
 
-	cmd = g_strdup_printf("# Generated by Connection Manager\n"
-						"options edns0\n"
-						"nameserver %s\n", server);
-
-	len = write(fd, cmd, strlen(cmd));
-	if (len < 0)
+	if (write(fd, content->str, content->len) < 0)
 		err = -errno;
 
-	g_free(cmd);
-
 failed:
 	close(fd);
 
 done:
+	g_string_free(content, TRUE);
 	umask(old_umask);
 
 	return err;
 }
 
+static int resolvfile_append(const char *interface, const char *domain,
+							const char *server)
+{
+	struct resolvfile_entry *entry;
+
+	DBG("interface %s server %s", interface, server);
+
+	if (interface == NULL)
+		return -ENOENT;
+
+	entry = g_try_new0(struct resolvfile_entry, 1);
+	if (entry == NULL)
+		return -ENOMEM;
+
+	entry->interface = g_strdup(interface);
+	entry->domain = g_strdup(domain);
+	entry->server = g_strdup(server);
+
+	resolvfile_list = g_list_append(resolvfile_list, entry);
+
+	return resolvfile_export();
+}
+
 static int resolvfile_remove(const char *interface, const char *domain,
 							const char *server)
 {
+	GList *list, *matches = NULL;
+
 	DBG("interface %s server %s", interface, server);
 
-	return 0;
+	for (list = resolvfile_list; list; list = g_list_next(list)) {
+		struct resolvfile_entry *entry = list->data;
+
+		if (interface != NULL &&
+				g_strcmp0(entry->interface, interface) != 0)
+			continue;
+
+		if (domain != NULL && g_strcmp0(entry->domain, domain) != 0)
+			continue;
+
+		if (g_strcmp0(entry->server, server) != 0)
+			continue;
+
+		matches = g_list_append(matches, entry);
+	}
+
+	resolvfile_remove_entries(matches);
+
+	return resolvfile_export();
 }
 
 static struct connman_resolver resolvfile_resolver = {
--- src/rtnl.c
+++ src/rtnl.c
@@ -485,7 +485,12 @@
 
 	__connman_ipconfig_newroute(index, scope, dststr, gatewaystr);
 
-	if (scope != RT_SCOPE_UNIVERSE || dst.s_addr != INADDR_ANY)
+	/* skip host specific routes */
+	if (scope != RT_SCOPE_UNIVERSE &&
+			!(scope == RT_SCOPE_LINK && dst.s_addr == INADDR_ANY))
+		return;
+
+	if (dst.s_addr != INADDR_ANY)
 		return;
 
 	for (list = rtnl_list; list; list = list->next) {
@@ -514,7 +519,12 @@
 
 	__connman_ipconfig_delroute(index, scope, dststr, gatewaystr);
 
-	if (scope != RT_SCOPE_UNIVERSE || dst.s_addr != INADDR_ANY)
+	/* skip host specific routes */
+	if (scope != RT_SCOPE_UNIVERSE &&
+			!(scope == RT_SCOPE_LINK && dst.s_addr == INADDR_ANY))
+		return;
+
+	if (dst.s_addr != INADDR_ANY)
 		return;
 
 	for (list = rtnl_list; list; list = list->next) {
@@ -783,15 +793,29 @@
 	}
 }
 
+static connman_bool_t is_route_rtmsg(struct rtmsg *msg)
+{
+
+	if (msg->rtm_table != RT_TABLE_MAIN)
+		return FALSE;
+
+	if (msg->rtm_protocol != RTPROT_BOOT &&
+			msg->rtm_protocol != RTPROT_KERNEL)
+		return FALSE;
+
+	if (msg->rtm_type != RTN_UNICAST)
+		return FALSE;
+
+	return TRUE;
+}
+
 static void rtnl_newroute(struct nlmsghdr *hdr)
 {
 	struct rtmsg *msg = (struct rtmsg *) NLMSG_DATA(hdr);
 
 	rtnl_route(hdr);
 
-	if (msg->rtm_table == RT_TABLE_MAIN &&
-				msg->rtm_protocol == RTPROT_BOOT &&
-						msg->rtm_type == RTN_UNICAST)
+	if (is_route_rtmsg(msg))
 		process_newroute(msg->rtm_family, msg->rtm_scope,
 						msg, RTM_PAYLOAD(hdr));
 }
@@ -802,9 +826,7 @@
 
 	rtnl_route(hdr);
 
-	if (msg->rtm_table == RT_TABLE_MAIN &&
-				msg->rtm_protocol == RTPROT_BOOT &&
-						msg->rtm_type == RTN_UNICAST)
+	if (is_route_rtmsg(msg))
 		process_delroute(msg->rtm_family, msg->rtm_scope,
 						msg, RTM_PAYLOAD(hdr));
 }
--- src/service.c
+++ src/service.c
@@ -65,6 +65,9 @@
 	connman_bool_t roaming;
 	struct connman_ipconfig *ipconfig;
 	struct connman_network *network;
+	char **nameservers;
+	char *nameserver;
+	char **domains;
 	/* 802.1x settings from the config files */
 	char *eap;
 	char *identity;
@@ -283,6 +286,69 @@
 	return FALSE;
 }
 
+static void update_nameservers(struct connman_service *service)
+{
+	const char *ifname = connman_ipconfig_get_ifname(service->ipconfig);
+
+	if (ifname == NULL)
+		return;
+
+	switch (service->state) {
+	case CONNMAN_SERVICE_STATE_UNKNOWN:
+	case CONNMAN_SERVICE_STATE_IDLE:
+	case CONNMAN_SERVICE_STATE_ASSOCIATION:
+	case CONNMAN_SERVICE_STATE_CONFIGURATION:
+		return;
+	case CONNMAN_SERVICE_STATE_FAILURE:
+	case CONNMAN_SERVICE_STATE_DISCONNECT:
+		connman_resolver_remove_all(ifname);
+		return;
+	case CONNMAN_SERVICE_STATE_READY:
+	case CONNMAN_SERVICE_STATE_LOGIN:
+	case CONNMAN_SERVICE_STATE_ONLINE:
+		break;
+	}
+
+	connman_resolver_remove_all(ifname);
+
+	if (service->nameservers != NULL) {
+		int i;
+
+		for (i = 0; service->nameservers[i]; i++)
+			connman_resolver_append(ifname, NULL,
+						service->nameservers[i]);
+	} else if (service->nameserver != NULL)
+		connman_resolver_append(ifname, NULL, service->nameserver);
+}
+
+void __connman_service_append_nameserver(struct connman_service *service,
+						const char *nameserver)
+{
+	DBG("service %p nameserver %s", service, nameserver);
+
+	if (nameserver == NULL)
+		return;
+
+	g_free(service->nameserver);
+	service->nameserver = g_strdup(nameserver);
+
+	update_nameservers(service);
+}
+
+void __connman_service_remove_nameserver(struct connman_service *service,
+						const char *nameserver)
+{
+	DBG("service %p nameserver %s", service, nameserver);
+
+	if (nameserver == NULL)
+		return;
+
+	g_free(service->nameserver);
+	service->nameserver = NULL;
+
+	update_nameservers(service);
+}
+
 static struct connman_service *get_default(void)
 {
 	struct connman_service *service;
@@ -490,6 +556,64 @@
 		__connman_ipconfig_append_ipv4config(service->ipconfig, iter);
 }
 
+static void append_dns(DBusMessageIter *iter, void *user_data)
+{
+	struct connman_service *service = user_data;
+
+	if (is_connected(service) == FALSE)
+		return;
+
+	if (service->nameservers != NULL) {
+		int i;
+
+		for (i = 0; service->nameservers[i]; i++)
+			dbus_message_iter_append_basic(iter,
+				DBUS_TYPE_STRING, &service->nameservers[i]);
+
+		return;
+	}
+
+	if (service->nameserver == NULL)
+		return;
+
+	dbus_message_iter_append_basic(iter,
+				DBUS_TYPE_STRING, &service->nameserver);
+}
+
+static void append_dnsconfig(DBusMessageIter *iter, void *user_data)
+{
+	struct connman_service *service = user_data;
+	int i;
+
+	if (service->nameservers == NULL)
+		return;
+
+	for (i = 0; service->nameservers[i]; i++)
+		dbus_message_iter_append_basic(iter,
+				DBUS_TYPE_STRING, &service->nameservers[i]);
+}
+
+static void append_domain(DBusMessageIter *iter, void *user_data)
+{
+	struct connman_service *service = user_data;
+
+	if (is_connected(service) == FALSE)
+		return;
+}
+
+static void append_domainconfig(DBusMessageIter *iter, void *user_data)
+{
+	struct connman_service *service = user_data;
+	int i;
+
+	if (service->domains == NULL)
+		return;
+
+	for (i = 0; service->domains[i]; i++)
+		dbus_message_iter_append_basic(iter,
+				DBUS_TYPE_STRING, &service->domains[i]);
+}
+
 static void append_proxy(DBusMessageIter *iter, void *user_data)
 {
 	struct connman_service *service = user_data;
@@ -517,69 +641,84 @@
 							service);
 }
 
-static DBusMessage *get_properties(DBusConnection *conn,
-					DBusMessage *msg, void *user_data)
+static void dns_changed(struct connman_service *service)
 {
-	struct connman_service *service = user_data;
-	DBusMessage *reply;
-	DBusMessageIter array, dict;
-	dbus_bool_t required;
-	const char *str;
+	if (is_connected(service) == FALSE)
+		return;
 
-	DBG("service %p", service);
+	connman_dbus_property_changed_array(service->path,
+				CONNMAN_SERVICE_INTERFACE, "Nameservers",
+					DBUS_TYPE_STRING, append_dns, service);
+}
 
-	reply = dbus_message_new_method_return(msg);
-	if (reply == NULL)
-		return NULL;
+static void dns_configuration_changed(struct connman_service *service)
+{
+	connman_dbus_property_changed_array(service->path,
+				CONNMAN_SERVICE_INTERFACE,
+				"Nameservers.Configuration",
+				DBUS_TYPE_STRING, append_dnsconfig, service);
 
-	dbus_message_iter_init_append(reply, &array);
+	dns_changed(service);
+}
 
-	connman_dbus_dict_open(&array, &dict);
+static void domain_configuration_changed(struct connman_service *service)
+{
+	connman_dbus_property_changed_array(service->path,
+				CONNMAN_SERVICE_INTERFACE,
+				"Domains.Configuration",
+				DBUS_TYPE_STRING, append_domainconfig, service);
+}
+
+static void append_properties(DBusMessageIter *dict, dbus_bool_t limited,
+					struct connman_service *service)
+{
+	dbus_bool_t required;
+	const char *str;
 
 	str = __connman_service_type2string(service->type);
 	if (str != NULL)
-		connman_dbus_dict_append_basic(&dict, "Type",
+		connman_dbus_dict_append_basic(dict, "Type",
 						DBUS_TYPE_STRING, &str);
 
 	str = mode2string(service->mode);
 	if (str != NULL)
-		connman_dbus_dict_append_basic(&dict, "Mode",
+		connman_dbus_dict_append_basic(dict, "Mode",
 						DBUS_TYPE_STRING, &str);
 
 	str = security2string(service->security);
 	if (str != NULL)
-		connman_dbus_dict_append_basic(&dict, "Security",
+		connman_dbus_dict_append_basic(dict, "Security",
 						DBUS_TYPE_STRING, &str);
 
 	str = state2string(service->state);
 	if (str != NULL)
-		connman_dbus_dict_append_basic(&dict, "State",
+		connman_dbus_dict_append_basic(dict, "State",
 						DBUS_TYPE_STRING, &str);
 
 	str = error2string(service->error);
 	if (str != NULL)
-		connman_dbus_dict_append_basic(&dict, "Error",
+		connman_dbus_dict_append_basic(dict, "Error",
 						DBUS_TYPE_STRING, &str);
 
 	if (service->strength > 0)
-		connman_dbus_dict_append_basic(&dict, "Strength",
+		connman_dbus_dict_append_basic(dict, "Strength",
 					DBUS_TYPE_BYTE, &service->strength);
 
-	connman_dbus_dict_append_basic(&dict, "Favorite",
+	connman_dbus_dict_append_basic(dict, "Favorite",
 					DBUS_TYPE_BOOLEAN, &service->favorite);
 
-	connman_dbus_dict_append_basic(&dict, "Immutable",
+	connman_dbus_dict_append_basic(dict, "Immutable",
 					DBUS_TYPE_BOOLEAN, &service->immutable);
 
 	if (service->favorite == TRUE)
-		connman_dbus_dict_append_basic(&dict, "AutoConnect",
+		connman_dbus_dict_append_basic(dict, "AutoConnect",
 				DBUS_TYPE_BOOLEAN, &service->autoconnect);
 	else
-		connman_dbus_dict_append_basic(&dict, "AutoConnect",
+		connman_dbus_dict_append_basic(dict, "AutoConnect",
 					DBUS_TYPE_BOOLEAN, &service->favorite);
 
 	if (service->name != NULL)
-		connman_dbus_dict_append_basic(&dict, "Name",
+		connman_dbus_dict_append_basic(dict, "Name",
 					DBUS_TYPE_STRING, &service->name);
 
 	switch (service->type) {
@@ -589,27 +728,27 @@
 	case CONNMAN_SERVICE_TYPE_VPN:
 		break;
 	case CONNMAN_SERVICE_TYPE_CELLULAR:
-		connman_dbus_dict_append_basic(&dict, "Roaming",
+		connman_dbus_dict_append_basic(dict, "Roaming",
 					DBUS_TYPE_BOOLEAN, &service->roaming);
 
 		if (service->mcc != NULL && service->mnc != NULL) {
-			connman_dbus_dict_append_basic(&dict, "MCC",
+			connman_dbus_dict_append_basic(dict, "MCC",
 					DBUS_TYPE_STRING, &service->mcc);
-			connman_dbus_dict_append_basic(&dict, "MNC",
+			connman_dbus_dict_append_basic(dict, "MNC",
 					DBUS_TYPE_STRING, &service->mnc);
 		}
 
 		if (service->apn != NULL) {
-			connman_dbus_dict_append_basic(&dict, "APN",
+			connman_dbus_dict_append_basic(dict, "APN",
 					DBUS_TYPE_STRING, &service->apn);
 
 			if (service->username != NULL)
-				connman_dbus_dict_append_basic(&dict,
+				connman_dbus_dict_append_basic(dict,
 					"Username", DBUS_TYPE_STRING,
 							&service->username);
 
 			if (service->password != NULL)
-				connman_dbus_dict_append_basic(&dict,
+				connman_dbus_dict_append_basic(dict,
 					"Password", DBUS_TYPE_STRING,
 							&service->password);
 
@@ -617,14 +756,14 @@
 		} else
 			required = TRUE;
 
-		connman_dbus_dict_append_basic(&dict, "SetupRequired",
+		connman_dbus_dict_append_basic(dict, "SetupRequired",
 						DBUS_TYPE_BOOLEAN, &required);
+		connman_dbus_dict_append_dict(dict, "Ethernet",
+						append_ethernet, service);
 		break;
 	case CONNMAN_SERVICE_TYPE_WIFI:
-		if (service->passphrase != NULL &&
-				__connman_security_check_privilege(msg,
-					CONNMAN_SECURITY_PRIVILEGE_SECRET) == 0)
-			connman_dbus_dict_append_basic(&dict, "Passphrase",
+		if (service->passphrase != NULL && limited == FALSE)
+			connman_dbus_dict_append_basic(dict, "Passphrase",
 				DBUS_TYPE_STRING, &service->passphrase);
 
 		required = FALSE;
@@ -644,24 +783,85 @@
 			break;
 		}
 
-		connman_dbus_dict_append_basic(&dict, "PassphraseRequired",
+		connman_dbus_dict_append_basic(dict, "PassphraseRequired",
 						DBUS_TYPE_BOOLEAN, &required);
 		/* fall through */
 	case CONNMAN_SERVICE_TYPE_ETHERNET:
 	case CONNMAN_SERVICE_TYPE_WIMAX:
 	case CONNMAN_SERVICE_TYPE_BLUETOOTH:
-		connman_dbus_dict_append_dict(&dict, "Ethernet",
+		connman_dbus_dict_append_dict(dict, "Ethernet",
 						append_ethernet, service);
 		break;
 	}
 
-	connman_dbus_dict_append_dict(&dict, "IPv4", append_ipv4, service);
+	connman_dbus_dict_append_dict(dict, "IPv4", append_ipv4, service);
 
-	connman_dbus_dict_append_dict(&dict, "IPv4.Configuration",
+	connman_dbus_dict_append_dict(dict, "IPv4.Configuration",
 						append_ipv4config, service);
 
-	connman_dbus_dict_append_dict(&dict, "Proxy", append_proxy, service);
+	connman_dbus_dict_append_array(dict, "Nameservers",
+				DBUS_TYPE_STRING, append_dns, service);
+
+	connman_dbus_dict_append_array(dict, "Nameservers.Configuration",
+				DBUS_TYPE_STRING, append_dnsconfig, service);
+
+	connman_dbus_dict_append_array(dict, "Domains",
+				DBUS_TYPE_STRING, append_domain, service);
+
+	connman_dbus_dict_append_array(dict, "Domains.Configuration",
+				DBUS_TYPE_STRING, append_domainconfig, service);
+
+	connman_dbus_dict_append_dict(dict, "Proxy", append_proxy, service);
+}
+
+static void append_struct(gpointer value, gpointer user_data)
+{
+	struct connman_service *service = value;
+	DBusMessageIter *iter = user_data;
+	DBusMessageIter entry, dict;
+
+	if (service->path == NULL || service->hidden == TRUE)
+		return;
+
+	dbus_message_iter_open_container(iter, DBUS_TYPE_STRUCT, NULL, &entry);
+
+	dbus_message_iter_append_basic(&entry, DBUS_TYPE_OBJECT_PATH,
+							&service->path);
+
+	connman_dbus_dict_open(&entry, &dict);
+	append_properties(&dict, TRUE, service);
+	connman_dbus_dict_close(&entry, &dict);
+
+	dbus_message_iter_close_container(iter, &entry);
+}
+
+void __connman_service_list_struct(DBusMessageIter *iter)
+{
+	g_sequence_foreach(service_list, append_struct, iter);
+}
 
+static DBusMessage *get_properties(DBusConnection *conn,
+					DBusMessage *msg, void *user_data)
+{
+	struct connman_service *service = user_data;
+	DBusMessage *reply;
+	DBusMessageIter array, dict;
+	dbus_bool_t limited = TRUE;
+
+	DBG("service %p", service);
+
+	if (__connman_security_check_privilege(msg,
+				CONNMAN_SECURITY_PRIVILEGE_SECRET) == 0)
+		limited = FALSE;
+
+	reply = dbus_message_new_method_return(msg);
+	if (reply == NULL)
+		return NULL;
+
+	dbus_message_iter_init_append(reply, &array);
+
+	connman_dbus_dict_open(&array, &dict);
+	append_properties(&dict, limited, service);
 	connman_dbus_dict_close(&array, &dict);
 
 	return reply;
@@ -715,6 +915,9 @@
 		if (type != DBUS_TYPE_STRING)
 			return __connman_error_invalid_arguments(msg);
 
+		if (service->immutable == TRUE)
+			return __connman_error_not_supported(msg);
+
 		if (__connman_security_check_privilege(msg,
 					CONNMAN_SECURITY_PRIVILEGE_SECRET) < 0)
 			return __connman_error_permission_denied(msg);
@@ -737,6 +940,9 @@
 		if (type != DBUS_TYPE_STRING)
 			return __connman_error_invalid_arguments(msg);
 
+		if (service->immutable == TRUE)
+			return __connman_error_not_supported(msg);
+
 		if (service->type != CONNMAN_SERVICE_TYPE_CELLULAR)
 			return __connman_error_invalid_service(msg);
 
@@ -758,6 +964,9 @@
 		if (type != DBUS_TYPE_STRING)
 			return __connman_error_invalid_arguments(msg);
 
+		if (service->immutable == TRUE)
+			return __connman_error_not_supported(msg);
+
 		if (service->type != CONNMAN_SERVICE_TYPE_CELLULAR)
 			return __connman_error_invalid_service(msg);
 
@@ -777,6 +986,9 @@
 		if (type != DBUS_TYPE_STRING)
 			return __connman_error_invalid_arguments(msg);
 
+		if (service->immutable == TRUE)
+			return __connman_error_not_supported(msg);
+
 		if (service->type != CONNMAN_SERVICE_TYPE_CELLULAR)
 			return __connman_error_invalid_service(msg);
 
@@ -790,19 +1002,107 @@
 					"Cellular.Password", service->password);
 
 		__connman_storage_save_service(service);
+	} else if (g_str_equal(name, "Nameservers.Configuration") == TRUE) {
+		DBusMessageIter entry;
+		GString *str;
+
+		if (type != DBUS_TYPE_ARRAY)
+			return __connman_error_invalid_arguments(msg);
+
+		str = g_string_new(NULL);
+		if (str == NULL)
+			return __connman_error_invalid_arguments(msg);
+
+		dbus_message_iter_recurse(&value, &entry);
+
+		while (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_STRING) {
+			const char *val;
+			dbus_message_iter_get_basic(&entry, &val);
+			dbus_message_iter_next(&entry);
+			if (str->len > 0)
+				g_string_append_printf(str, " %s", val);
+			else
+				g_string_append(str, val);
+		}
+
+		g_strfreev(service->nameservers);
+
+		if (str->len > 0)
+			service->nameservers = g_strsplit_set(str->str, " ", 0);
+		else
+			service->nameservers = NULL;
+
+		g_string_free(str, TRUE);
+
+		update_nameservers(service);
+		dns_configuration_changed(service);
+
+		__connman_storage_save_service(service);
+	} else if (g_str_equal(name, "Domains.Configuration") == TRUE) {
+		DBusMessageIter entry;
+		GString *str;
+
+		if (type != DBUS_TYPE_ARRAY)
+			return __connman_error_invalid_arguments(msg);
+
+		str = g_string_new(NULL);
+		if (str == NULL)
+			return __connman_error_invalid_arguments(msg);
+
+		dbus_message_iter_recurse(&value, &entry);
+
+		while (dbus_message_iter_get_arg_type(&entry) == DBUS_TYPE_STRING) {
+			const char *val;
+			dbus_message_iter_get_basic(&entry, &val);
+			dbus_message_iter_next(&entry);
+			if (str->len > 0)
+				g_string_append_printf(str, " %s", val);
+			else
+				g_string_append(str, val);
+		}
+
+		g_strfreev(service->domains);
+
+		if (str->len > 0)
+			service->domains = g_strsplit_set(str->str, " ", 0);
+		else
+			service->domains = NULL;
+
+		g_string_free(str, TRUE);
+
+		//update_domains(service);
+		domain_configuration_changed(service);
+
+		__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);
 
+		if (is_connecting(service) ||
+				is_connected(service))
+			__connman_network_clear_ipconfig(service->network,
+							service->ipconfig);
+
 		err = __connman_ipconfig_set_ipv4config(service->ipconfig,
 								&value);
-		if (err < 0)
+		if (err < 0) {
+			if (is_connected(service) ||
+					is_connecting(service))
+				__connman_network_set_ipconfig(service->network,
+							service->ipconfig);
+
 			return __connman_error_failed(msg, -err);
+		}
 
 		ipv4_configuration_changed(service);
 
+		if (is_connecting(service) ||
+				is_connected(service))
+			__connman_network_set_ipconfig(service->network,
+							service->ipconfig);
+
 		__connman_storage_save_service(service);
 	} else
 		return __connman_error_invalid_property(msg);
@@ -838,6 +1138,9 @@
 		g_get_current_time(&service->modified);
 		__connman_storage_save_service(service);
 	} else if (g_str_equal(name, "Passphrase") == TRUE) {
+		if (service->immutable == TRUE)
+			return __connman_error_not_supported(msg);
+
 		g_free(service->passphrase);
 		service->passphrase = NULL;
 
@@ -1145,6 +1448,9 @@
 	if (service->type == CONNMAN_SERVICE_TYPE_ETHERNET)
 		return __connman_error_not_supported(msg);
 
+	if (service->immutable == TRUE)
+		return __connman_error_not_supported(msg);
+
 	if (service->favorite == FALSE &&
 			service->state != CONNMAN_SERVICE_STATE_FAILURE)
 		return __connman_error_not_supported(msg);
@@ -1280,6 +1586,10 @@
 	if (service->location != NULL)
 		connman_location_unref(service->location);
 
+	g_strfreev(service->nameservers);
+	g_strfreev(service->domains);
+
+	g_free(service->nameserver);
 	g_free(service->mcc);
 	g_free(service->mnc);
 	g_free(service->apn);
@@ -1494,8 +1804,7 @@
 	return service->network;
 }
 
-struct connman_ipconfig *
-__connman_service_get_ipconfig(struct connman_service *service)
+struct connman_ipconfig *__connman_service_get_ipconfig(struct connman_service *service)
 {
 	if (service == NULL)
 		return NULL;
@@ -1610,6 +1919,9 @@
 	service->state = state;
 	state_changed(service);
 
+	if (state == CONNMAN_SERVICE_STATE_ONLINE)
+		connman_timeserver_sync();
+
 	if (state == CONNMAN_SERVICE_STATE_IDLE) {
 		connman_bool_t reconnect;
 
@@ -1618,8 +1930,7 @@
 			__connman_service_auto_connect();
 	}
 
-	if (state == CONNMAN_SERVICE_STATE_READY ||
-			state == CONNMAN_SERVICE_STATE_ONLINE) {
+	if (state == CONNMAN_SERVICE_STATE_READY) {
 		set_reconnect_state(service, TRUE);
 
 		__connman_service_set_favorite(service, TRUE);
@@ -1631,15 +1942,20 @@
 		g_get_current_time(&service->modified);
 		__connman_storage_save_service(service);
 
+		update_nameservers(service);
+		dns_changed(service);
+
 		__connman_notifier_connect(service->type);
 
 		default_changed();
-
 	} else if (state == CONNMAN_SERVICE_STATE_DISCONNECT) {
 		__connman_location_finish(service);
 
 		default_changed();
 
+		update_nameservers(service);
+		dns_changed(service);
+
 		__connman_notifier_disconnect(service->type);
 	}
 
@@ -1873,11 +2189,39 @@
 
 /**
  * __connman_service_lookup:
+ * @pattern: search pattern
+ * @path: return object path
+ *
+ * Look up a service path from a search pattern
+ */
+int __connman_service_lookup(const char *pattern, const char **path)
+{
+	GHashTableIter iter;
+	gpointer key, value;
+
+	g_hash_table_iter_init(&iter, service_hash);
+
+	while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) {
+		GSequenceIter *iter = value;
+		struct connman_service *service = g_sequence_get(iter);
+
+		if (g_strcmp0(service->identifier, pattern) == 0 ||
+				g_strcmp0(service->name, pattern) == 0) {
+			*path = (const char *) service->path;
+			return 0;
+		}
+	}
+
+	return -ENXIO;
+}
+
+/**
+ * lookup_by_identifier:
  * @identifier: service identifier
  *
  * Look up a service by identifier (reference count will not be increased)
  */
-static struct connman_service *__connman_service_lookup(const char *identifier)
+static struct connman_service *lookup_by_identifier(const char *identifier)
 {
 	GSequenceIter *iter;
 
@@ -2033,7 +2377,7 @@
 
 	name = g_strdup_printf("%s_%s_%s", type, ident, group);
 
-	service = __connman_service_lookup(name);
+	service = lookup_by_identifier(name);
 
 	if (service != NULL)
 		goto done;
@@ -2044,7 +2388,7 @@
 		created = TRUE;
 	}
 
-	service = __connman_service_lookup(name);
+	service = lookup_by_identifier(name);
 
 done:
 	g_free(name);
@@ -2270,7 +2614,7 @@
 
 	name = g_strdup_printf("%s_%s_%s",
 			__connman_network_get_type(network), ident, group);
-	service = __connman_service_lookup(name);
+	service = lookup_by_identifier(name);
 	g_free(name);
 
 	return service;
@@ -2530,6 +2874,7 @@
 	connman_uint8_t strength, value;
 	connman_bool_t roaming;
 	GSequenceIter *iter;
+	const char *name;
 
 	DBG("network %p", network);
 
@@ -2540,6 +2885,15 @@
 	if (service->network == NULL)
 		return;
 
+	name = connman_network_get_string(service->network, "Name");
+	if (g_strcmp0(service->name, name) != 0) {
+		g_free(service->name);
+		service->name = g_strdup(name);
+		connman_dbus_property_changed_basic(service->path,
+				CONNMAN_SERVICE_INTERFACE, "Name",
+				DBUS_TYPE_STRING, &service->name);
+	}
+
 	strength = connman_network_get_uint8(service->network, "Strength");
 	if (strength == service->strength)
 		goto roaming;
@@ -2693,7 +3047,7 @@
 		service->username = g_key_file_get_string(keyfile,
 					service->identifier, "Username", NULL);
 
-		service->username = g_key_file_get_string(keyfile,
+		service->password = g_key_file_get_string(keyfile,
 					service->identifier, "Password", NULL);
 
 		service->favorite = g_key_file_get_boolean(keyfile,
@@ -2732,6 +3086,20 @@
 		__connman_ipconfig_load(service->ipconfig, keyfile,
 					service->identifier, "IPv4.");
 
+	service->nameservers = g_key_file_get_string_list(keyfile,
+			service->identifier, "Nameservers", &length, NULL);
+	if (service->nameservers != NULL && length == 0) {
+		g_strfreev(service->nameservers);
+		service->nameservers = NULL;
+	}
+
+	service->domains = g_key_file_get_string_list(keyfile,
+			service->identifier, "Domains", &length, NULL);
+	if (service->domains != NULL && length == 0) {
+		g_strfreev(service->domains);
+		service->domains = NULL;
+	}
+
 done:
 	g_key_file_free(keyfile);
 
@@ -2865,6 +3233,26 @@
 		__connman_ipconfig_save(service->ipconfig, keyfile,
 					service->identifier, "IPv4.");
 
+	if (service->nameservers != NULL) {
+		guint len = g_strv_length(service->nameservers);
+
+		g_key_file_set_string_list(keyfile, service->identifier,
+								"Nameservers",
+				(const gchar **) service->nameservers, len);
+	} else
+		g_key_file_remove_key(keyfile, service->identifier,
+							"Nameservers", NULL);
+
+	if (service->domains != NULL) {
+		guint len = g_strv_length(service->domains);
+
+		g_key_file_set_string_list(keyfile, service->identifier,
+								"Domains",
+				(const gchar **) service->domains, len);
+	} else
+		g_key_file_remove_key(keyfile, service->identifier,
+							"Domains", NULL);
+
 	data = g_key_file_to_data(keyfile, &length, NULL);
 
 	if (g_file_set_contents(pathname, data, length, NULL) == FALSE)
--- src/technology.c
+++ src/technology.c
@@ -345,6 +345,7 @@
 	DBG("device %p", device);
 
 	type = __connman_device_get_service_type(device);
+	__connman_notifier_disable(type);
 	__connman_notifier_unregister(type);
 
 	technology = g_hash_table_lookup(device_table, device);
--- src/timeserver.c
+++ src/timeserver.c
@@ -28,6 +28,7 @@
 #include "connman.h"
 
 static GSList *driver_list = NULL;
+static GHashTable *server_hash = NULL;
 
 static gint compare_priority(gconstpointer a, gconstpointer b)
 {
@@ -76,14 +77,35 @@
  */
 int connman_timeserver_append(const char *server)
 {
+	GSList *list;
+
 	DBG("server %s", server);
 
 	if (server == NULL)
 		return -EINVAL;
 
-	connman_info("Adding time server %s", server);
+	/* This server is already handled by a driver */
+	if (g_hash_table_lookup(server_hash, server))
+		return 0;
+
+	for (list = driver_list; list; list = list->next) {
+		struct connman_timeserver_driver *driver = list->data;
+		char *new_server;
+
+		if (driver->append == NULL)
+			continue;
+
+		new_server = g_strdup(server);
+		if (new_server == NULL)
+			return -ENOMEM;
+
+		if (driver->append(server) == 0) {
+			g_hash_table_insert(server_hash, new_server, driver);
+			return 0;
+		}
+	}
 
-	return 0;
+	return -ENOENT;
 }
 
 /**
@@ -94,12 +116,54 @@
  */
 int connman_timeserver_remove(const char *server)
 {
+	struct connman_timeserver_driver *driver;
+
 	DBG("server %s", server);
 
 	if (server == NULL)
 		return -EINVAL;
 
-	connman_info("Removing time server %s", server);
+	driver = g_hash_table_lookup(server_hash, server);
+	if (driver == NULL)
+		return -EINVAL;
+
+	g_hash_table_remove(server_hash, server);
+
+	if (driver->remove == NULL)
+		return -ENOENT;
+
+	return driver->remove(server);
+}
+
+void connman_timeserver_sync(void)
+{
+	GSList *list;
+
+	DBG("");
+
+	for (list = driver_list; list; list = list->next) {
+		struct connman_timeserver_driver *driver = list->data;
+
+		if (driver->sync == NULL)
+			continue;
+
+		driver->sync();
+	}
+}
+
+int __connman_timeserver_init(void)
+{
+	DBG("");
+
+	server_hash = g_hash_table_new_full(g_str_hash, g_str_equal,
+						g_free, NULL);
 
 	return 0;
 }
+
+void __connman_timeserver_cleanup(void)
+{
+	DBG("");
+
+	g_hash_table_destroy(server_hash);
+}
--- src/utsname.c
+++ src/utsname.c
@@ -68,6 +68,34 @@
 	driver_list = g_slist_remove(driver_list, driver);
 }
 
+/**
+ * connman_utsname_get_hostname:
+ *
+ * Returns current hostname
+ */
+const char *connman_utsname_get_hostname(void)
+{
+	GSList *list;
+
+	DBG("");
+
+	for (list = driver_list; list; list = list->next) {
+		struct connman_utsname_driver *driver = list->data;
+		const char *hostname;
+
+		DBG("driver %p name %s", driver, driver->name);
+
+		if (driver->get_hostname == NULL)
+			continue;
+
+		hostname = driver->get_hostname();
+		if (hostname != NULL)
+			return hostname;
+	}
+
+	return NULL;
+}
+
 int __connman_utsname_set_hostname(const char *hostname)
 {
 	GSList *list;
--- src/wifi.c
+++ src/wifi.c
@@ -23,6 +23,9 @@
 #include <config.h>
 #endif
 
+#include <stdio.h>
+#include <string.h>
+
 #include <glib.h>
 
 #include "connman.h"
@@ -48,3 +51,51 @@
 
 	return g_string_free(str, FALSE);
 }
+
+char **connman_wifi_load_ssid(void)
+{
+	GKeyFile *key_file;
+	const char * profile;
+	gchar **groups, *group;
+	gsize num_groups;
+	char **hex_ssids;
+	int i, j;
+
+	profile = __connman_profile_active_ident();
+
+	key_file = __connman_storage_open_profile(profile);
+	if (key_file == NULL)
+		return NULL;
+
+	groups = g_key_file_get_groups(key_file, &num_groups);
+	if (groups == NULL) {
+		hex_ssids = NULL;
+		goto done;
+	}
+
+	hex_ssids = g_try_malloc0(sizeof(*hex_ssids) * num_groups);
+
+	for (i = 0, j = 0; groups[i]; i++) {
+		gchar *hex_ssid;
+		gboolean favorite;
+
+		group = groups[i];
+
+		favorite = g_key_file_get_boolean(key_file, group,
+							"Favorite", NULL);
+		if (favorite == FALSE)
+			continue;
+
+		hex_ssid = g_key_file_get_string(key_file, group,
+							"SSID", NULL);
+		if (hex_ssid == NULL)
+			continue;
+
+		hex_ssids[j++] = hex_ssid;
+	}
+
+done:
+	__connman_storage_close_profile(profile, key_file, FALSE);
+
+	return hex_ssids;
+}
--- test/find-service
+++ test/find-service
+#!/usr/bin/python
+
+import sys
+import dbus
+
+if (len(sys.argv) < 2):
+	print "Usage: %s <pattern>" % (sys.argv[0])
+	sys.exit(1)
+
+bus = dbus.SystemBus()
+
+manager = dbus.Interface(bus.get_object('org.moblin.connman', '/'),
+					'org.moblin.connman.Manager')
+
+path = manager.LookupService(sys.argv[1])
+
+print "Service is %s" % (path)
--- test/get-services
+++ test/get-services
+#!/usr/bin/python
+
+import dbus
+
+def extract_values(values):
+	val = "{"
+	for key in values.keys():
+		val += " " + key + "="
+		val += str(values[key])
+	val += " }"
+	return val
+
+def extract_list(list):
+	val = "["
+	for i in list:
+		val += " " + str(i)
+	val += " ]"
+	return val
+
+bus = dbus.SystemBus()
+
+manager = dbus.Interface(bus.get_object('org.moblin.connman', '/'),
+					'org.moblin.connman.Manager')
+
+services = manager.GetServices()
+
+for entry in services:
+	path = entry[0]
+	properties = entry[1]
+
+	print "[ %s ]" % (path)
+
+	for key in properties.keys():
+		if key in ["IPv4", "IPv4.Configuration", "Proxy", "Ethernet"]:
+			val = extract_values(properties[key])
+		elif key in ["Nameservers", "Nameservers.Configuration",
+					"Domains", "Domains.Configuration"]:
+			val = extract_list(properties[key])
+		elif key in ["Favorite", "Immutable", "AutoConnect",
+				"SetupRequired", "PassphraseRequired"]:
+			if properties[key] == dbus.Boolean(1):
+				val = "true"
+			else:
+				val = "false"
+		elif key in ["Strength"]:
+			val = int(properties[key])
+		else:
+			val = str(properties[key])
+		print "    %s = %s" % (key, val)
+
+	print
--- test/list-services
+++ test/list-services
@@ -10,6 +10,13 @@
 	val += " }"
 	return val
 
+def extract_list(list):
+	val = "["
+	for i in list:
+		val += " " + str(i)
+	val += " ]"
+	return val
+
 bus = dbus.SystemBus()
 
 manager = dbus.Interface(bus.get_object("org.moblin.connman", "/"),
@@ -28,6 +35,9 @@
 	for key in properties.keys():
 		if key in ["IPv4", "IPv4.Configuration", "Proxy", "Ethernet"]:
 			val = extract_values(properties[key])
+		elif key in ["Nameservers", "Nameservers.Configuration",
+					"Domains", "Domains.Configuration"]:
+			val = extract_list(properties[key])
 		elif key in ["Favorite", "Immutable", "AutoConnect",
 				"SetupRequired", "PassphraseRequired"]:
 			if properties[key] == dbus.Boolean(1):
--- test/monitor-services
+++ test/monitor-services
@@ -13,6 +13,13 @@
 	val += " }"
 	return val
 
+def extract_list(list):
+	val = "["
+	for i in list:
+		val += " " + str(i)
+	val += " ]"
+	return val
+
 def property_changed(name, value, path):
 	service = path[path.rfind("/") + 1:]
 	if name in ["Profiles", "Services", "Providers", "Technologies",
@@ -23,6 +30,9 @@
 		val = val + " ]"
 	elif name in ["IPv4", "IPv4.Configuration", "Proxy", "Ethernet"]:
 		val = extract_values(value)
+	elif name in ["Nameservers", "Nameservers.Configuration",
+					"Domains", "Domains.Configuration"]:
+		val = extract_list(value)
 	elif name in ["Strength", "Priority"]:
 		val = int(value)
 	else:
--- test/set-domains
+++ test/set-domains
+#!/usr/bin/python
+
+import sys
+import dbus
+
+if (len(sys.argv) < 2):
+	print "Usage: %s <service> [domain*]" % (sys.argv[0])
+	sys.exit(1)
+
+bus = dbus.SystemBus()
+path = "/profile/default/" + sys.argv[1]
+service = dbus.Interface(bus.get_object('org.moblin.connman', path),
+					'org.moblin.connman.Service')
+
+properties = service.GetProperties()
+
+print "Setting domains to %s" % (sys.argv[2:])
+
+service.SetProperty("Domains.Configuration", 
+	dbus.Array(sys.argv[2:], signature=dbus.Signature('s')))
--- test/set-nameservers
+++ test/set-nameservers
+#!/usr/bin/python
+
+import sys
+import dbus
+
+if (len(sys.argv) < 2):
+	print "Usage: %s <service> [nameserver*]" % (sys.argv[0])
+	sys.exit(1)
+
+bus = dbus.SystemBus()
+path = "/profile/default/" + sys.argv[1]
+service = dbus.Interface(bus.get_object('org.moblin.connman', path),
+					'org.moblin.connman.Service')
+
+properties = service.GetProperties()
+
+print "Setting nameserver to %s" % (sys.argv[2:])
+
+service.SetProperty("Nameservers.Configuration", 
+	dbus.Array(sys.argv[2:], signature=dbus.Signature('s')))
--- tools/resolv-test.c
+++ tools/resolv-test.c
+/*
+ *
+ *  Connection Manager
+ *
+ *  Copyright (C) 2007-2010  Intel Corporation. All rights reserved.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 2 as
+ *  published by the Free Software Foundation.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <unistd.h>
+#include <string.h>
+#include <resolv.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <arpa/nameser.h>
+
+static int do_connect(const char *server)
+{
+	struct sockaddr_in sin;
+	int sk;
+
+	sk = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+	//sk = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+	if (sk < 0)
+		return -1;
+
+	memset(&sin, 0, sizeof(sin));
+	sin.sin_family = AF_INET;
+	sin.sin_port = htons(53);
+	sin.sin_addr.s_addr = inet_addr(server);
+
+	if (connect(sk, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
+		close(sk);
+		return -1;
+	}
+
+	return sk;
+}
+
+int main(int argc, char *argv[])
+{
+	ns_msg msg;
+	ns_rr rr;
+	int rcode;
+	const char *nameserver;
+	unsigned char buf[4096];
+	int i, sk, err, len, off = 0;
+
+	if (argc < 2) {
+		printf("missing argument\n");
+		return 1;
+	}
+
+	if (argc > 2)
+		nameserver = argv[2];
+	else
+		nameserver = "127.0.0.1";
+
+	sk = do_connect(nameserver);
+	if (sk < 0) {
+		printf("Can't connect\n");
+		return 1;
+	}
+
+	len = res_mkquery(ns_o_query, argv[1], ns_c_in, ns_t_a,
+				NULL, 0, NULL, buf + off, sizeof(buf) - off);
+	printf("query len: %d\n", len);
+
+	if (off > 0) {
+		buf[0] = len >> 8;
+		buf[1] = len & 0xff;
+	}
+
+	//for (i = 0; i < len + off; i++)
+	//	printf("%02x ", buf[i]);
+	//printf("\n");
+
+	err = send(sk, buf, len + off, 0);
+	printf("send result: %d\n", err);
+
+	len = recv(sk, buf, sizeof(buf), 0);
+	printf("answer len: %d\n", len);
+
+	//for (i = 0; i < len + off; i++)
+	//	printf("%02x ", buf[i]);
+	//printf("\n");
+
+	close(sk);
+
+	ns_initparse(buf + off, len - off, &msg);
+
+	rcode = ns_msg_getflag(msg, ns_f_rcode);
+
+	printf("msg id: 0x%04x\n", ns_msg_id(msg));
+	printf("msg rcode: %d\n", rcode);
+	printf("msg count: %d\n", ns_msg_count(msg, ns_s_an));
+
+	for (i = 0; i < ns_msg_count(msg, ns_s_an); i++) {
+		char result[100];
+
+		ns_parserr(&msg, ns_s_an, i, &rr);
+
+		if (ns_rr_class(rr) != ns_c_in)
+			continue;
+
+		if (ns_rr_type(rr) != ns_t_a)
+			continue;
+
+		if (ns_rr_rdlen(rr) != NS_INADDRSZ)
+			continue;
+
+		inet_ntop(AF_INET, ns_rr_rdata(rr), result, sizeof(result));
+
+		printf("result: %s\n", result);
+	}
+
+	return 0;
+}

++++++ connman.yaml
--- connman.yaml
+++ connman.yaml
@@ -1,6 +1,6 @@
 Name: connman
 Summary: Connection Manager
-Version: 0.52
+Version: 0.54
 Release: 1
 Group: System/Networking
 License: GPLv2
@@ -10,7 +10,8 @@
 Description: |
     Connection Manager provides a daemon for managing Internet connections
     within embedded devices running the Linux operating system.
-
+Patches:
+    - no-logspam.patch
 Requires:
     - dbus
     - dhclient >= 3.0.2
@@ -26,14 +27,6 @@
     - dbus-1
     - libudev >= 145
 Configure: configure
-Patches:
-    - no-logspam.patch
-    - 0001-Set-network-associating-as-FALSE-at-function-pan_dis.patch
-    - 0001-Check-error-before-call-dbus_message_get_args-to-acq.patch
-    - 0001-call-__connman_notifier_connect-only-when-state-is.patch
-    - 0001-Export-Gateway-from-service-properties-ipv4.patch
-    - 0001-Check-ssid_len-before-set-WiFi.SSID-of-network.patch
-    - 0001-Remove-supplicant-and-device-scanning-state.patch
 ConfigOptions:
     - --enable-ethernet=builtin
     - --enable-wifi=builtin
@@ -42,6 +35,7 @@
     - --enable-bluetooth=builtin
     - --enable-loopback=builtin
     - --enable-dnsproxy=builtin
+    - --enable-portal=builtin
     - --enable-meego=builtin
     - --enable-openconnect=builtin
     - ix86:--enable-iwmx

++++++ deleted files:
--- 0001-Check-error-before-call-dbus_message_get_args-to-acq.patch
--- 0001-Check-ssid_len-before-set-WiFi.SSID-of-network.patch
--- 0001-Export-Gateway-from-service-properties-ipv4.patch
--- 0001-Remove-supplicant-and-device-scanning-state.patch
--- 0001-Set-network-associating-as-FALSE-at-function-pan_dis.patch
--- 0001-call-__connman_notifier_connect-only-when-state-is.patch


More information about the Meego-packaging mailing list