1e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan/* 2e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan * dhcpcd - DHCP client daemon 3e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan * Copyright (c) 2006-2015 Roy Marples <roy@marples.name> 4e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan * All rights reserved 5e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 6e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan * Redistribution and use in source and binary forms, with or without 7e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan * modification, are permitted provided that the following conditions 8e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan * are met: 9e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan * 1. Redistributions of source code must retain the above copyright 10e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan * notice, this list of conditions and the following disclaimer. 11e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan * 2. Redistributions in binary form must reproduce the above copyright 12e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan * notice, this list of conditions and the following disclaimer in the 13e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan * documentation and/or other materials provided with the distribution. 14e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan * 15e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan * SUCH DAMAGE. 26e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan */ 27e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 28e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan#include <errno.h> 29e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan#include <poll.h> 30e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan#include <signal.h> 31e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan#include <stdio.h> 32e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan#include <stdlib.h> 33e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan#include <string.h> 34e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan#include <syslog.h> 35e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan#include <unistd.h> 36e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 37e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan#include <dbus/dbus.h> 38e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 39e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan#include "../config.h" 40e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan#include "../eloop.h" 41e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan#include "../dhcp.h" 428e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan#ifdef INET6 438e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan#include "../dhcp6.h" 448e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan#endif 45e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan#include "../rpc-interface.h" 46e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan#include "dbus-dict.h" 47e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 48e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan#define SERVICE_NAME "org.chromium.dhcpcd" 49e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan#define SERVICE_PATH "/org/chromium/dhcpcd" 50e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan#define S_EINVAL SERVICE_NAME ".InvalidArgument" 51e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan#define S_ARGS "Not enough arguments" 52e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 53e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tanstatic DBusConnection *connection; 54e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tanstatic struct dhcpcd_ctx *dhcpcd_ctx; 55e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 56e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tanstatic const char dhcpcd_introspection_xml[] = 57e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan " <method name=\"GetVersion\">\n" 58e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan " <arg name=\"version\" direction=\"out\" type=\"s\"/>\n" 59e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan " </method>\n" 60e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan " <method name=\"Rebind\">\n" 61e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan " <arg name=\"interface\" direction=\"in\" type=\"s\"/>\n" 62e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan " </method>\n" 63e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan " <method name=\"Release\">\n" 64e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan " <arg name=\"interface\" direction=\"in\" type=\"s\"/>\n" 65e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan " </method>\n" 66e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan " <method name=\"Stop\">\n" 67e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan " <arg name=\"interface\" direction=\"in\" type=\"s\"/>\n" 68e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan " </method>\n" 69e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan " <signal name=\"Event\">\n" 70e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan " <arg name=\"configuration\" type=\"usa{sv}\"/>\n" 71e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan " </signal>\n" 72e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan " <signal name=\"StatusChanged\">\n" 73e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan " <arg name=\"status\" type=\"us\"/>\n" 74e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan " </signal>\n"; 75e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 76e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tanstatic const char service_watch_rule[] = "interface=" DBUS_INTERFACE_DBUS 77e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan ",type=signal,member=NameOwnerChanged"; 78e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 79e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tanstatic const char introspection_header_xml[] = 80e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "<!DOCTYPE node PUBLIC \"-//freedesktop//" 81e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "DTD D-BUS Object Introspection 1.0//EN\"\n" 82e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "\"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n" 83e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "<node name=\"" SERVICE_PATH "\">\n" 84e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan " <interface name=\"org.freedesktop.DBus.Introspectable\">\n" 85e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan " <method name=\"Introspect\">\n" 86e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan " <arg name=\"data\" direction=\"out\" type=\"s\"/>\n" 87e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan " </method>\n" 88e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan " </interface>\n" 89e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan " <interface name=\"" SERVICE_NAME "\">\n"; 90e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 91e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tanstatic const char introspection_footer_xml[] = 92e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan " </interface>\n" 93e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "</node>\n"; 94e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 95e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tanstatic const struct o_dbus dhos[] = { 96e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "ip_address=", DBUS_TYPE_UINT32, 0, "IPAddress" }, 97e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "server_name=", DBUS_TYPE_STRING, 0, "ServerName"}, 98e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "subnet_mask=", DBUS_TYPE_UINT32, 0, "SubnetMask" }, 99e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "subnet_cidr=", DBUS_TYPE_BYTE, 0, "SubnetCIDR" }, 100e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "network_number=", DBUS_TYPE_UINT32, 0, "NetworkNumber" }, 101e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "classless_static_routes=", DBUS_TYPE_STRING, 0, 102e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "ClasslessStaticRoutes" }, 103e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "ms_classless_static_routes=", DBUS_TYPE_STRING, 0, 104e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "MSClasslessStaticRoutes" }, 105e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "static_routes=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, 106e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "StaticRoutes"} , 107e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "routers=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, "Routers" }, 108e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "time_offset=", DBUS_TYPE_UINT32, 0, "TimeOffset" }, 109e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "time_servers=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, "TimeServers" }, 110e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "ien116_name_servers=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, 111e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "IEN116NameServers" }, 112e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "domain_name_servers=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, 113e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "DomainNameServers" }, 114e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "log_servers=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, "LogServers" }, 115e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "cookie_servers=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, 116e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "CookieServers" }, 117e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "lpr_servers=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, "LPRServers" }, 118e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "impress_servers=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, 119e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "ImpressServers" }, 120e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "resource_location_servers=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, 121e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "ResourceLocationServers" }, 122e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "host_name=", DBUS_TYPE_STRING, 0, "Hostname" }, 123e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "boot_size=", DBUS_TYPE_UINT16, 0, "BootSize" }, 124e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "merit_dump=", DBUS_TYPE_STRING, 0, "MeritDump" }, 125e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "domain_name=", DBUS_TYPE_STRING, 0, "DomainName" }, 126e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "swap_server=", DBUS_TYPE_UINT32, 0, "SwapServer" }, 127e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "root_path=", DBUS_TYPE_STRING, 0, "RootPath" }, 128e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "extensions_path=", DBUS_TYPE_STRING, 0, "ExtensionsPath" }, 129e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "ip_forwarding=", DBUS_TYPE_BOOLEAN, 0, "IPForwarding" }, 130e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "non_local_source_routing=", DBUS_TYPE_BOOLEAN, 0, 131e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "NonLocalSourceRouting" }, 132e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "policy_filter=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, 133e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "PolicyFilter" }, 134e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "max_dgram_reassembly=", DBUS_TYPE_INT16, 0, 135e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "MaxDatagramReassembly" }, 136e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "default_ip_ttl=", DBUS_TYPE_UINT16, 0, "DefaultIPTTL" }, 137e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "path_mtu_aging_timeout=", DBUS_TYPE_UINT32, 0, 138e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "PathMTUAgingTimeout" }, 139e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "path_mtu_plateau_table=" ,DBUS_TYPE_ARRAY, DBUS_TYPE_UINT16, 140e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "PolicyFilter"} , 141e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "interface_mtu=", DBUS_TYPE_UINT16, 0, "InterfaceMTU" }, 142e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "all_subnets_local=", DBUS_TYPE_BOOLEAN, 0, "AllSubnetsLocal" }, 143e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "broadcast_address=", DBUS_TYPE_UINT32, 0, "BroadcastAddress" }, 144e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "perform_mask_discovery=", DBUS_TYPE_BOOLEAN, 0, 145e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "PerformMaskDiscovery" }, 146e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "mask_supplier=", DBUS_TYPE_BOOLEAN, 0, "MaskSupplier" }, 147e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "router_discovery=", DBUS_TYPE_BOOLEAN, 0, "RouterDiscovery" }, 148e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "router_solicitiation_address=", DBUS_TYPE_UINT32, 0, 149e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "RouterSolicationAddress" }, 150e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "trailer_encapsulation=", DBUS_TYPE_BOOLEAN, 0, 151e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "TrailerEncapsulation" }, 152e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "arp_cache_timeout=", DBUS_TYPE_UINT32, 0, "ARPCacheTimeout" }, 153e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "ieee802_3_encapsulation=", DBUS_TYPE_UINT16, 0, 154e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "IEEE8023Encapsulation" }, 155e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "default_tcp_ttl=", DBUS_TYPE_BYTE, 0, "DefaultTCPTTL" }, 156e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "tcp_keepalive_interval=", DBUS_TYPE_UINT32, 0, 157e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "TCPKeepAliveInterval" }, 158e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "tcp_keepalive_garbage=", DBUS_TYPE_BOOLEAN, 0, 159e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "TCPKeepAliveGarbage" }, 160e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "nis_domain=", DBUS_TYPE_STRING, 0, "NISDomain" }, 161e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "nis_servers=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, "NISServers" }, 162e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "ntp_servers=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, "NTPServers" }, 1639c993df942bba4476200aace0e69590bdf9a6a88Victor Dodon { "vendor_encapsulated_options=", DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, 164e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "VendorEncapsulatedOptions" }, 165e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "netbios_name_servers=" ,DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, 166e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "NetBIOSNameServers" }, 167e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "netbios_dd_server=", DBUS_TYPE_UINT32, 0, "NetBIOSDDServer" }, 168e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "netbios_node_type=", DBUS_TYPE_BYTE, 0, "NetBIOSNodeType" }, 169e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "netbios_scope=", DBUS_TYPE_STRING, 0, "NetBIOSScope" }, 170e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "font_servers=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, "FontServers" }, 171e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "x_display_manager=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, 172e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "XDisplayManager" }, 173e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "dhcp_requested_address=", DBUS_TYPE_UINT32, 0, 174e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "DHCPRequestedAddress" }, 175e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "dhcp_lease_time=", DBUS_TYPE_UINT32, 0, "DHCPLeaseTime" }, 176e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "dhcp_option_overload=", DBUS_TYPE_BOOLEAN, 0, 177e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "DHCPOptionOverload" }, 178e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "dhcp_message_type=", DBUS_TYPE_BYTE, 0, "DHCPMessageType" }, 179e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "dhcp_server_identifier=", DBUS_TYPE_UINT32, 0, 180e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "DHCPServerIdentifier" }, 181e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "dhcp_message=", DBUS_TYPE_STRING, 0, "DHCPMessage" }, 182e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "dhcp_max_message_size=", DBUS_TYPE_UINT16, 0, 183e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "DHCPMaxMessageSize" }, 184e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "dhcp_renewal_time=", DBUS_TYPE_UINT32, 0, "DHCPRenewalTime" }, 185e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "dhcp_rebinding_time=", DBUS_TYPE_UINT32, 0, "DHCPRebindingTime" }, 186e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "nisplus_domain=", DBUS_TYPE_STRING, 0, "NISPlusDomain" }, 187e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "nisplus_servers=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, 188e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "NISPlusServers" }, 189e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "tftp_server_name=", DBUS_TYPE_STRING, 0, "TFTPServerName" }, 190e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "bootfile_name=", DBUS_TYPE_STRING, 0, "BootFileName" }, 191e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "mobile_ip_home_agent=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, 192e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "MobileIPHomeAgent" }, 193e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "smtp_server=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, "SMTPServer" }, 194e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "pop_server=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, "POPServer" }, 195e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "nntp_server=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, "NNTPServer" }, 196e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "www_server=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, "WWWServer" }, 197e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "finger_server=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, 198e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "FingerServer" }, 199e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "irc_server=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, "IRCServer" }, 200e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "streettalk_server=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, 201e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "StreetTalkServer" }, 202e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "streettalk_directory_assistance_server=", DBUS_TYPE_ARRAY, 203e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan DBUS_TYPE_UINT32, "StreetTalkDirectoryAssistanceServer" }, 204e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "user_class=", DBUS_TYPE_STRING, 0, "UserClass" }, 205e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "new_fqdn_name=", DBUS_TYPE_STRING, 0, "FQDNName" }, 206e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "nds_servers=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, "NDSServers" }, 207e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "nds_tree_name=", DBUS_TYPE_STRING, 0, "NDSTreeName" }, 208e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "nds_context=", DBUS_TYPE_STRING, 0, "NDSContext" }, 209e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "bcms_controller_names=", DBUS_TYPE_STRING, 0, 210e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "BCMSControllerNames" }, 211e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "client_last_transaction_time=", DBUS_TYPE_UINT32, 0, 212e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "ClientLastTransactionTime" }, 213e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "associated_ip=", DBUS_TYPE_UINT32, 0, "AssociatedIP" }, 214e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "uap_servers=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, "UAPServers" }, 215e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "netinfo_server_address=", DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, 216e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "NetinfoServerAddress" }, 217e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "netinfo_server_tag=", DBUS_TYPE_STRING, 0, "NetinfoServerTag" }, 218e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "default_url=", DBUS_TYPE_STRING, 0, "DefaultURL" }, 219e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "subnet_selection=", DBUS_TYPE_UINT32, 0, "SubnetSelection" }, 220e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "domain_search=", DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, 221e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "DomainSearch" }, 222e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { "wpad_url=", DBUS_TYPE_STRING, 0, "WebProxyAutoDiscoveryUrl" }, 2238e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan#ifdef INET6 2248e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan { "dhcp6_server_id=", DBUS_TYPE_STRING, 0, 2258e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan "DHCPv6ServerIdentifier" }, 2268e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan { "dhcp6_ia_na1_ia_addr1=", DBUS_TYPE_STRING, 0, "DHCPv6Address" }, 2278e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan { "dhcp6_ia_na1_ia_addr1_vltime=", DBUS_TYPE_UINT32, 0, 2288e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan "DHCPv6AddressLeaseTime" }, 2298e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan { "dhcp6_name_servers=", DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, 2308e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan "DHCPv6NameServers" }, 2318e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan { "dhcp6_domain_search=", DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, 2328e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan "DHCPv6DomainSearch" }, 2338e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan { "dhcp6_ia_pd1_prefix1=", DBUS_TYPE_STRING, 0, 2348e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan "DHCPv6DelegatedPrefix" }, 2358e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan { "dhcp6_ia_pd1_prefix1_length=", DBUS_TYPE_UINT32, 0, 2368e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan "DHCPv6DelegatedPrefixLength" }, 2378e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan { "dhcp6_ia_pd1_prefix1_vltime=", DBUS_TYPE_UINT32, 0, 2388e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan "DHCPv6DelegatedPrefixLeaseTime" }, 2398e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan#endif 240e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { NULL, 0, 0, NULL } 241e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan}; 242e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 243e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tanstatic int 244e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tanappend_config(DBusMessageIter *iter, 245e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan const char *prefix, char **env, ssize_t elen) 246e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan{ 247e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan char **eenv, *p; 248e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan const struct o_dbus *dhop; 249e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan size_t l, lp; 250e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan int retval; 251e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 252e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan retval = 0; 253e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan lp = strlen(prefix); 254e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan for (eenv = env + elen; env < eenv; env++) { 255e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan p = env[0]; 256e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan for (dhop = dhos; dhop->var; dhop++) { 257e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan l = strlen(dhop->var); 258e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan if (strncmp(p, dhop->var, l) == 0) { 259e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan retval = dict_append_config_item(iter, 260e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan dhop, p + l); 261e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan break; 262e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan } 263e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan if (strncmp(p, prefix, lp) == 0 && 264e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan strncmp(p + lp, dhop->var, l) == 0) 265e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { 266e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan retval = dict_append_config_item(iter, 267e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan dhop, p + l + lp); 268e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan break; 269e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan } 270e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan } 271e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan if (retval == -1) 272e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan break; 273e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan } 274e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan return retval; 275e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan} 276e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 277e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tanstatic DBusHandlerResult 278e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tanget_dbus_error(DBusConnection *con, DBusMessage *msg, 279e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan const char *name, const char *fmt, ...) 280e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan{ 281e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan char buffer[1024]; 282e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan DBusMessage *reply; 283e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan va_list args; 284e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 285e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan va_start(args, fmt); 286e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan vsnprintf(buffer, sizeof(buffer), fmt, args); 287e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan va_end(args); 288e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan reply = dbus_message_new_error(msg, name, buffer); 289e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan dbus_connection_send(con, reply, NULL); 290e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan dbus_message_unref(reply); 291e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan return DBUS_HANDLER_RESULT_HANDLED; 292e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan} 293e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 294e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tanstatic dbus_bool_t 295e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tandbus_send_message(const struct interface *ifp, const char *reason, 296e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan const char *prefix, struct dhcp_message *message) 297e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan{ 298e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan const struct if_options *ifo = ifp->options; 299e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan DBusMessage* msg; 300e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan DBusMessageIter args, dict; 301e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan int pid = getpid(); 302e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan char **env = NULL; 303e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan ssize_t e, elen; 304e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan int retval; 305e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan int success = FALSE; 306e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 307e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan syslog(LOG_INFO, "event %s on interface %s", reason, ifp->name); 308e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 309e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan msg = dbus_message_new_signal(SERVICE_PATH, SERVICE_NAME, "Event"); 310e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan if (msg == NULL) { 311e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan syslog(LOG_ERR, "failed to make a configure message"); 312e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan return FALSE; 313e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan } 314e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan dbus_message_iter_init_append(msg, &args); 315e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan dbus_message_iter_append_basic(&args, DBUS_TYPE_UINT32, &pid); 316e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &reason); 317e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan dbus_message_iter_open_container(&args, DBUS_TYPE_ARRAY, 318e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING 319e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan DBUS_TYPE_STRING_AS_STRING 320e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan DBUS_TYPE_VARIANT_AS_STRING 321e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan DBUS_DICT_ENTRY_END_CHAR_AS_STRING, 322e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan &dict); 323e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan if (prefix == NULL || message == NULL) 324e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan retval = 0; 325e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan else { 326e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan e = dhcp_env(NULL, NULL, message, ifp); 327e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan if (e > 0) { 328e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan char *config_prefix = strdup(prefix); 329e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan if (config_prefix == NULL) { 330e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan logger(dhcpcd_ctx, LOG_ERR, 331e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "Memory exhausted (strdup)"); 332e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan eloop_exit(dhcpcd_ctx->eloop, EXIT_FAILURE); 333e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan } 334e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan char *p = config_prefix + strlen(config_prefix) - 1; 335e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan if (p >= config_prefix && *p == '_') 336e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan *p = '\0'; 337e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan env = calloc(e + 1, sizeof(char *)); 338e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan if (env == NULL) { 339e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan logger(dhcpcd_ctx, LOG_ERR, 340e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "Memory exhausted (calloc)"); 341e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan eloop_exit(dhcpcd_ctx->eloop, EXIT_FAILURE); 342e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan } 343e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan elen = dhcp_env(env, config_prefix, message, ifp); 344e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan free(config_prefix); 345e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan } 346e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan retval = append_config(&dict, prefix, env, elen); 347e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan } 348e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 349e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan /* Release memory allocated for env. */ 350e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan if (env) { 351e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan char **current = env; 352e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan while (*current) 353e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan free(*current++); 354e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan free(env); 355e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan } 356e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 357e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan dbus_message_iter_close_container(&args, &dict); 358e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan if (retval == 0) { 359e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan success = dbus_connection_send(connection, msg, NULL); 360e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan if (!success) 361e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan syslog(LOG_ERR, "failed to send dhcp to dbus"); 362e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan } else 363e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan syslog(LOG_ERR, "failed to construct dbus message"); 364e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan dbus_message_unref(msg); 365e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 366e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan return success; 367e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan} 368e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 3698e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan#ifdef INET6 3708e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tanstatic dbus_bool_t 3718e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tandbus_send_dhcpv6_message(const struct interface *ifp, const char *reason, 3728e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan const char *prefix, struct dhcp6_message *message, size_t length) 3738e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan{ 3748e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan const struct if_options *ifo = ifp->options; 3758e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan DBusMessage* msg; 3768e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan DBusMessageIter args, dict; 3778e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan int pid = getpid(); 3788e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan char **env = NULL; 3798e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan ssize_t e, elen; 3808e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan int retval; 3818e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan int success = FALSE; 3828e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan 3838e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan syslog(LOG_INFO, "event %s on interface %s", reason, ifp->name); 3848e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan 3858e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan msg = dbus_message_new_signal(SERVICE_PATH, SERVICE_NAME, "Event"); 3868e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan if (msg == NULL) { 3878e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan syslog(LOG_ERR, "failed to make a configure message"); 3888e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan return FALSE; 3898e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan } 3908e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan dbus_message_iter_init_append(msg, &args); 3918e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan dbus_message_iter_append_basic(&args, DBUS_TYPE_UINT32, &pid); 3928e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &reason); 3938e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan dbus_message_iter_open_container(&args, DBUS_TYPE_ARRAY, 3948e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING 3958e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan DBUS_TYPE_STRING_AS_STRING 3968e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan DBUS_TYPE_VARIANT_AS_STRING 3978e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan DBUS_DICT_ENTRY_END_CHAR_AS_STRING, 3988e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan &dict); 3998e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan if (prefix == NULL || message == NULL) 4008e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan retval = 0; 4018e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan else { 4028e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan e = dhcp6_env(NULL, NULL, ifp, message, length); 4038e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan if (e > 0) { 4048e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan char *config_prefix = strdup(prefix); 4058e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan if (config_prefix == NULL) { 4068e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan logger(dhcpcd_ctx, LOG_ERR, 4078e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan "Memory exhausted (strdup)"); 4088e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan eloop_exit(dhcpcd_ctx->eloop, EXIT_FAILURE); 4098e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan } 4108e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan char *p = config_prefix + strlen(config_prefix) - 1; 4118e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan if (p >= config_prefix && *p == '_') 4128e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan *p = '\0'; 4138e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan env = calloc(e + 1, sizeof(char *)); 4148e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan if (env == NULL) { 4158e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan logger(dhcpcd_ctx, LOG_ERR, 4168e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan "Memory exhausted (calloc)"); 4178e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan eloop_exit(dhcpcd_ctx->eloop, EXIT_FAILURE); 4188e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan } 4198e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan elen = dhcp6_env(env, "new", ifp, message, length); 4208e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan free(config_prefix); 4218e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan } 4228e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan retval = append_config(&dict, prefix, env, elen); 4238e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan } 4248e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan 4258e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan /* Release memory allocated for env. */ 4268e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan if (env) { 4278e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan char **current = env; 4288e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan while (*current) 4298e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan free(*current++); 4308e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan free(env); 4318e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan } 4328e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan 4338e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan dbus_message_iter_close_container(&args, &dict); 4348e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan if (retval == 0) { 4358e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan success = dbus_connection_send(connection, msg, NULL); 4368e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan if (!success) 4378e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan syslog(LOG_ERR, "failed to send dhcpv6 to dbus"); 4388e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan } else 4398e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan syslog(LOG_ERR, "failed to construct dbus message"); 4408e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan dbus_message_unref(msg); 4418e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan 4428e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan return success; 4438e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan} 4448e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan#endif 4458e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan 446e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tanstatic DBusHandlerResult 447e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tanintrospect(DBusConnection *con, DBusMessage *msg) 448e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan{ 449e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan DBusMessage *reply; 450e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan char *xml; 451e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan size_t len; 452e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 453e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan len = sizeof(introspection_header_xml) - 1 454e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan + sizeof(dhcpcd_introspection_xml) - 1 455e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan + sizeof(introspection_footer_xml) - 1 456e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan + 1; /* terminal \0 */ 457e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan xml = malloc(len); 458e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan if (xml == NULL) 459e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan return DBUS_HANDLER_RESULT_HANDLED; 460e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan snprintf(xml, len, "%s%s%s", 461e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan introspection_header_xml, 462e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan dhcpcd_introspection_xml, 463e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan introspection_footer_xml); 464e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan reply = dbus_message_new_method_return(msg); 465e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan dbus_message_append_args(reply, 466e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan DBUS_TYPE_STRING, &xml, 467e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan DBUS_TYPE_INVALID); 468e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan dbus_connection_send(con, reply, NULL); 469e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan dbus_message_unref(reply); 470e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan free(xml); 471e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan return DBUS_HANDLER_RESULT_HANDLED; 472e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan} 473e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 474e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tanstatic DBusHandlerResult 475e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tanversion(DBusConnection *con, DBusMessage *msg, const char *ver) 476e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan{ 477e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan DBusMessage *reply; 478e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 479e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan reply = dbus_message_new_method_return(msg); 480e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan dbus_message_append_args(reply, 481e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan DBUS_TYPE_STRING, &ver, 482e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan DBUS_TYPE_INVALID); 483e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan dbus_connection_send(con, reply, NULL); 484e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan dbus_message_unref(reply); 485e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan return DBUS_HANDLER_RESULT_HANDLED; 486e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan} 487e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 488e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tanstatic DBusHandlerResult 489e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tandbus_ack(DBusConnection *con, DBusMessage *msg) 490e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan{ 491e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan DBusMessage *reply; 492e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 493e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan reply = dbus_message_new_method_return(msg); 494e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan dbus_connection_send(con, reply, NULL); 495e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan dbus_message_unref(reply); 496e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan return DBUS_HANDLER_RESULT_HANDLED; 497e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan} 498e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 499e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tanstatic DBusHandlerResult 500e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tanmsg_handler(DBusConnection *con, DBusMessage *msg, __unused void *data) 501e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan{ 502e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan#define IsMethod(msg, method) \ 503e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan dbus_message_is_method_call(msg, SERVICE_NAME, method) 504e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 505e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan if (dbus_message_is_method_call(msg, DBUS_INTERFACE_INTROSPECTABLE, 506e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "Introspect")) { 507e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan return introspect(con, msg); 508e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan } else if (IsMethod(msg, "GetVersion")) { 509e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan return version(con, msg, VERSION); 510e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan } else if (IsMethod(msg, "Rebind")) { 511e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan const char *iface_name; 512e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan if (!dbus_message_get_args(msg, NULL, 513e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan DBUS_TYPE_STRING, &iface_name, 514e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan DBUS_TYPE_INVALID)) { 515e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan logger(dhcpcd_ctx, LOG_ERR, 516e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "Invalid arguments for Rebind"); 517e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan return get_dbus_error(con, msg, S_EINVAL, S_ARGS); 518e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan } 519e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan dhcpcd_start_interface(dhcpcd_ctx, iface_name); 520e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan return dbus_ack(con, msg); 521e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan } else if (IsMethod(msg, "Release")) { 522e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan const char *iface_name; 523e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan if (!dbus_message_get_args(msg, NULL, 524e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan DBUS_TYPE_STRING, &iface_name, 525e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan DBUS_TYPE_INVALID)) { 526e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan logger(dhcpcd_ctx, LOG_ERR, 527e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "Invalid arguments for Release"); 528e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan return get_dbus_error(con, msg, S_EINVAL, S_ARGS); 529e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan } 530e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan dhcpcd_release_ipv4(dhcpcd_ctx, iface_name); 531e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan return dbus_ack(con, msg); 532e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan } else if (IsMethod(msg, "Stop")) { 533e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan const char *iface_name; 534e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan if (!dbus_message_get_args(msg, NULL, 535e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan DBUS_TYPE_STRING, &iface_name, 536e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan DBUS_TYPE_INVALID)) { 537e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan logger(dhcpcd_ctx, LOG_ERR, 538e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "Invalid arguments for Stop"); 539e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan return get_dbus_error(con, msg, S_EINVAL, S_ARGS); 540e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan } 541e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan dhcpcd_stop_interface(dhcpcd_ctx, iface_name); 542e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan (void) dbus_ack(con, msg); 543e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan exit(EXIT_FAILURE); 544e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan } else if (dbus_message_is_signal(msg, DBUS_INTERFACE_LOCAL, 545e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "Disconnected")) { 546e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan dhcpcd_stop_interfaces(dhcpcd_ctx); 547e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan exit(EXIT_FAILURE); 548e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan } 549e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan return get_dbus_error(con, msg, S_EINVAL, S_ARGS); 550e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan#undef IsMethod 551e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan} 552e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 553e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tanstatic void 554e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tandbus_handle_event(DBusWatch *watch, int flags) 555e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan{ 556e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan dbus_watch_handle((DBusWatch *)watch, flags); 557e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 558e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan if (connection != NULL) { 559e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan dbus_connection_ref(connection); 560e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan while (dbus_connection_dispatch(connection) == 561e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan DBUS_DISPATCH_DATA_REMAINS) 562e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan ; 563e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan dbus_connection_unref(connection); 564e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan } 565e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan} 566e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 567e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tanstatic void 568e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tandbus_read_event(void *watch) 569e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan{ 570e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan dbus_handle_event((DBusWatch *)watch, DBUS_WATCH_READABLE); 571e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan} 572e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 573e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tanstatic void 574e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tandbus_write_event(void *watch) 575e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan{ 576e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan dbus_handle_event((DBusWatch *)watch, DBUS_WATCH_WRITABLE); 577e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan} 578e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 579e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tanstatic dbus_bool_t 580e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tanadd_watch(DBusWatch *watch, __unused void *data) 581e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan{ 582e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan int fd, flags; 583e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan void (*read_event)(void *) = NULL; 584e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan void *read_arg = NULL; 585e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan void (*write_event)(void *) = NULL; 586e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan void *write_arg = NULL; 587e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 588e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan fd = dbus_watch_get_unix_fd(watch); 589e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan flags = dbus_watch_get_flags(watch); 590e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan if (flags & DBUS_WATCH_READABLE) { 591e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan read_event = dbus_read_event; 592e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan read_arg = watch; 593e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan } 594e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan if (flags & DBUS_WATCH_WRITABLE) { 595e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan write_event = dbus_write_event; 596e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan write_arg = watch; 597e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan } 598e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 599e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan if (eloop_event_add(dhcpcd_ctx->eloop, fd, read_event, read_arg, 600e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan write_event, write_arg) == 0) 601e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan return TRUE; 602e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan return FALSE; 603e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan} 604e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 605e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tanstatic void 606e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tanremove_watch(DBusWatch *watch, __unused void *data) 607e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan{ 608e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan int fd, flags; 609e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan int write_only = 0; 610e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan fd = dbus_watch_get_unix_fd(watch); 611e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan flags = dbus_watch_get_flags(watch); 612e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan if (!(flags & DBUS_WATCH_READABLE) && (flags & DBUS_WATCH_WRITABLE)) 613e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan write_only = 1; 614e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan eloop_event_delete(dhcpcd_ctx->eloop, fd, write_only); 615e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan} 616e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 617e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tanstatic DBusHandlerResult 618e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tandhcpcd_dbus_filter(DBusConnection *conn, DBusMessage *msg, void *user_data) 619e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan{ 620e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan const char *service = NULL; 621e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan const char *old_owner = NULL; 622e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan const char *new_owner = NULL; 623e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 624e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan if (!dbus_message_is_signal(msg, DBUS_INTERFACE_DBUS, 625e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "NameOwnerChanged")) 626e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 627e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 628e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan if (!dbus_message_get_args(msg, NULL, 629e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan DBUS_TYPE_STRING, &service, 630e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan DBUS_TYPE_STRING, &old_owner, 631e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan DBUS_TYPE_STRING, &new_owner, 632e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan DBUS_TYPE_INVALID)) { 633e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan syslog(LOG_ERR, 634e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "Invalid arguments for NameOwnerChanged signal"); 635e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 636e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan } 637e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan if (strcmp(service, "org.chromium.flimflam") == 0 && 638e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan strlen(new_owner) == 0) { 639e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan syslog(LOG_INFO, "exiting because flimflamd has died"); 640e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan dhcpcd_stop_interfaces(dhcpcd_ctx); 641e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan exit(EXIT_FAILURE); 642e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan } 643e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; 644e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan} 645e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 646e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tanint 647e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tanrpc_init(struct dhcpcd_ctx *ctx) 648e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan{ 649e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan DBusObjectPathVTable vt = { 650e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan NULL, &msg_handler, NULL, NULL, NULL, NULL 651e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan }; 652e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan DBusError err; 653e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan int ret; 654e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 655e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan dhcpcd_ctx = ctx; 656e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 657e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan dbus_error_init(&err); 658e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan connection = dbus_bus_get(DBUS_BUS_SYSTEM, &err); 659e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan if (connection == NULL) { 660e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan if (dbus_error_is_set(&err)) 661e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan syslog(LOG_ERR, "%s", err.message); 662e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan else 663e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan syslog(LOG_ERR, "failed to get a dbus connection"); 664e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan return -1; 665e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan } 666e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan atexit(rpc_close); 667e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 668e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan if (!dbus_connection_set_watch_functions(connection, 669e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan add_watch, remove_watch, NULL, NULL, NULL)) 670e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { 671e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan syslog(LOG_ERR, "dbus: failed to set watch functions"); 672e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan return -1; 673e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan } 674e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan if (!dbus_connection_register_object_path(connection, 675e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan SERVICE_PATH, &vt, NULL)) 676e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan { 677e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan syslog(LOG_ERR, "dbus: failed to register object path"); 678e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan return -1; 679e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan } 680e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan dbus_connection_add_filter(connection, dhcpcd_dbus_filter, NULL, NULL); 681e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan dbus_bus_add_match(connection, service_watch_rule, &err); 682e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan if (dbus_error_is_set(&err)) { 683e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan syslog(LOG_ERR, "Cannot add rule: %s", err.message); 684e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan return -1; 685e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan } 686e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan return 0; 687e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan} 688e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 689e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tanvoid 690e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tanrpc_close(void) 691e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan{ 692e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan if (connection) { 693e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan dbus_bus_remove_match(connection, service_watch_rule, NULL); 694e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan dbus_connection_remove_filter(connection, 695e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan dhcpcd_dbus_filter, 696e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan NULL); 697e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan dbus_connection_unref(connection); 698e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan connection = NULL; 699e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan } 700e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan} 701e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 702e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tanvoid 703e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tanrpc_signal_status(const char *status) 704e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan{ 705e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan DBusMessage *msg; 706e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan DBusMessageIter args; 707e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan int pid = getpid(); 708e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 709e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan syslog(LOG_INFO, "status changed to %s", status); 710e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 711e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan msg = dbus_message_new_signal(SERVICE_PATH, SERVICE_NAME, 712e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan "StatusChanged"); 713e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan if (msg == NULL) { 714e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan syslog(LOG_ERR, "failed to make a status changed message"); 715e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan return; 716e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan } 717e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan dbus_message_iter_init_append(msg, &args); 718e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan dbus_message_iter_append_basic(&args, DBUS_TYPE_UINT32, &pid); 719e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &status); 720e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan if (!dbus_connection_send(connection, msg, NULL)) 721e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan syslog(LOG_ERR, "failed to send status to dbus"); 722e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan dbus_message_unref(msg); 723e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan} 724e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 725e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 726e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tanint 727e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tanrpc_update_ipv4(struct interface *ifp) 728e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan{ 729e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan struct dhcp_state *state = D_STATE(ifp); 730e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan if (state->new != NULL) { 731e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan /* push state over d-bus */ 732e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan dbus_send_message(ifp, state->reason, "new_", state->new); 733e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan rpc_signal_status("Bound"); 734e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan } else { 735e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan rpc_signal_status("Release"); 736e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan } 737e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan return 0; 738e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan} 739e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 7408e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan#ifdef INET6 741e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tanint 742e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tanrpc_update_ipv6(struct interface *ifp) 743e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan{ 7448e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan struct dhcp6_state *state = D6_STATE(ifp); 7458e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan if (state->new != NULL) { 7468e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan /* push state over d-bus */ 7478e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan dbus_send_dhcpv6_message(ifp, state->reason, "new_", 7488e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan state->new, state->new_len); 7498e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan rpc_signal_status("Bound6"); 7508e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan } else { 7518e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan rpc_signal_status("Release6"); 7528e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan } 753e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan return 0; 754e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan} 7558e603a0d0354b88712f1a81cc48dbd9936244fd5Samuel Tan#endif 756e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan 757e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tanint 758e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tanrpc_notify_unicast_arp(struct interface *ifp) { 759e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan struct dhcp_state *state = D_STATE(ifp); 760e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan return dbus_send_message(ifp, "GATEWAY-ARP", "saved_", state->offer); 761e942e091ac1efb0ee1916add2b12f64fdfd59476Samuel Tan} 762