1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Copyright 2008, The Android Open Source Project
3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * you may not use this file except in compliance with the License.
6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * You may obtain a copy of the License at
7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *     http://www.apache.org/licenses/LICENSE-2.0
9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * See the License for the specific language governing permissions and
14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * limitations under the License.
15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* Utilities for managing the dhcpcd DHCP client daemon */
18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h>
20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h>
21b93e5812faffd3b6c5fb349072413aace31918d8Olivier Bailly#include <string.h>
22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <unistd.h>
23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <arpa/inet.h>
24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <netinet/in.h>
25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <cutils/properties.h>
27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
289363b7d5da7e17842432251384f8dc46902ac323Dmitry Shmidtstatic const char DAEMON_NAME[]        = "dhcpcd";
299363b7d5da7e17842432251384f8dc46902ac323Dmitry Shmidtstatic const char DAEMON_PROP_NAME[]   = "init.svc.dhcpcd";
309363b7d5da7e17842432251384f8dc46902ac323Dmitry Shmidtstatic const char HOSTNAME_PROP_NAME[] = "net.hostname";
31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const char DHCP_PROP_NAME_PREFIX[]  = "dhcp";
3262d6f7486323fd2bd27299940a28f3c6de73f65dDmitry Shmidtstatic const char DHCP_CONFIG_PATH[]   = "/system/etc/dhcpcd/dhcpcd.conf";
33b1723b68921512f26562384898b9600f8f11d25eIrfan Sheriffstatic const int NAP_TIME = 200;   /* wait for 200ms at a time */
34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                                  /* when polling for property values */
359d157870345fa18ee7e639a85f6bcc4afb50c648TK MUNstatic const char DAEMON_NAME_RENEW[]  = "iprenew";
36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic char errmsg[100];
3789f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff/* interface length for dhcpcd daemon start (dhcpcd_<interface> as defined in init.rc file)
3889f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff * or for filling up system properties dhcpcd.<interface>.ipaddress, dhcpcd.<interface>.dns1
3989f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff * and other properties on a successful bind
4089f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff */
4189f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff#define MAX_INTERFACE_LENGTH 25
4289f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff
4389f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff/*
4489f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff * P2p interface names increase sequentially p2p-p2p0-1, p2p-p2p0-2.. after
4589f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff * group formation. This does not work well with system properties which can quickly
4689f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff * exhaust or for specifiying a dhcp start target in init which requires
4789f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff * interface to be pre-defined in init.rc file.
4889f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff *
4989f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff * This function returns a common string p2p for all p2p interfaces.
5089f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff */
5189f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriffvoid get_p2p_interface_replacement(const char *interface, char *p2p_interface) {
5289f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    /* Use p2p for any interface starting with p2p. */
5389f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    if (strncmp(interface, "p2p",3) == 0) {
5489f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff        strncpy(p2p_interface, "p2p", MAX_INTERFACE_LENGTH);
5589f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    } else {
5689f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff        strncpy(p2p_interface, interface, MAX_INTERFACE_LENGTH);
5789f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    }
5889f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff}
59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Wait for a system property to be assigned a specified value.
62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * If desired_value is NULL, then just wait for the property to
63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * be created with any value. maxwait is the maximum amount of
64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * time in seconds to wait before giving up.
65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int wait_for_property(const char *name, const char *desired_value, int maxwait)
67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char value[PROPERTY_VALUE_MAX] = {'\0'};
69b1723b68921512f26562384898b9600f8f11d25eIrfan Sheriff    int maxnaps = (maxwait * 1000) / NAP_TIME;
70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (maxnaps < 1) {
72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        maxnaps = 1;
73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    while (maxnaps-- > 0) {
76b1723b68921512f26562384898b9600f8f11d25eIrfan Sheriff        usleep(NAP_TIME * 1000);
77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        if (property_get(name, value, NULL)) {
78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            if (desired_value == NULL ||
79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                    strcmp(value, desired_value) == 0) {
80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project                return 0;
81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            }
82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        }
83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return -1; /* failure */
85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
87faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwaltstatic int fill_ip_info(const char *interface,
88faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt                     char *ipaddr,
89faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt                     char *gateway,
90faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt                     uint32_t *prefixLength,
91faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt                     char *dns1,
92faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt                     char *dns2,
93faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt                     char *server,
940fb8ec8e9a056cd219216b1f5724d289b50dc993Jeff Sharkey                     uint32_t *lease,
950fb8ec8e9a056cd219216b1f5724d289b50dc993Jeff Sharkey                     char *vendorInfo)
96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char prop_name[PROPERTY_KEY_MAX];
98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char prop_value[PROPERTY_VALUE_MAX];
9989f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    /* Interface name after converting p2p0-p2p0-X to p2p to reuse system properties */
10089f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    char p2p_interface[MAX_INTERFACE_LENGTH];
10189f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff
10289f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    get_p2p_interface_replacement(interface, p2p_interface);
103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
10489f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    snprintf(prop_name, sizeof(prop_name), "%s.%s.ipaddress", DHCP_PROP_NAME_PREFIX, p2p_interface);
105faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt    property_get(prop_name, ipaddr, NULL);
106faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt
10789f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    snprintf(prop_name, sizeof(prop_name), "%s.%s.gateway", DHCP_PROP_NAME_PREFIX, p2p_interface);
108faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt    property_get(prop_name, gateway, NULL);
109faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt
11089f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    snprintf(prop_name, sizeof(prop_name), "%s.%s.server", DHCP_PROP_NAME_PREFIX, p2p_interface);
111bdaaec1ba0a7cf832ad7fe475a7c541ed9973e52Irfan Sheriff    property_get(prop_name, server, NULL);
112bdaaec1ba0a7cf832ad7fe475a7c541ed9973e52Irfan Sheriff
113bdaaec1ba0a7cf832ad7fe475a7c541ed9973e52Irfan Sheriff    //TODO: Handle IPv6 when we change system property usage
114bdaaec1ba0a7cf832ad7fe475a7c541ed9973e52Irfan Sheriff    if (strcmp(gateway, "0.0.0.0") == 0) {
115bdaaec1ba0a7cf832ad7fe475a7c541ed9973e52Irfan Sheriff        //DHCP server is our best bet as gateway
116bdaaec1ba0a7cf832ad7fe475a7c541ed9973e52Irfan Sheriff        strncpy(gateway, server, PROPERTY_VALUE_MAX);
117bdaaec1ba0a7cf832ad7fe475a7c541ed9973e52Irfan Sheriff    }
118bdaaec1ba0a7cf832ad7fe475a7c541ed9973e52Irfan Sheriff
11989f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    snprintf(prop_name, sizeof(prop_name), "%s.%s.mask", DHCP_PROP_NAME_PREFIX, p2p_interface);
120faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt    if (property_get(prop_name, prop_value, NULL)) {
121faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt        int p;
122faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt        // this conversion is v4 only, but this dhcp client is v4 only anyway
123faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt        in_addr_t mask = ntohl(inet_addr(prop_value));
124faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt        // Check netmask is a valid IP address.  ntohl gives NONE response (all 1's) for
125faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt        // non 255.255.255.255 inputs.  if we get that value check if it is legit..
126faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt        if (mask == INADDR_NONE && strcmp(prop_value, "255.255.255.255") != 0) {
127faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt            snprintf(errmsg, sizeof(errmsg), "DHCP gave invalid net mask %s", prop_value);
128faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt            return -1;
129faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt        }
130faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt        for (p = 0; p < 32; p++) {
131faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt            if (mask == 0) break;
132faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt            // check for non-contiguous netmask, e.g., 255.254.255.0
133faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt            if ((mask & 0x80000000) == 0) {
134faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt                snprintf(errmsg, sizeof(errmsg), "DHCP gave invalid net mask %s", prop_value);
135faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt                return -1;
136faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt            }
137faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt            mask = mask << 1;
138faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt        }
139faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt        *prefixLength = p;
140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
14189f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    snprintf(prop_name, sizeof(prop_name), "%s.%s.dns1", DHCP_PROP_NAME_PREFIX, p2p_interface);
142faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt    property_get(prop_name, dns1, NULL);
143faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt
14489f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    snprintf(prop_name, sizeof(prop_name), "%s.%s.dns2", DHCP_PROP_NAME_PREFIX, p2p_interface);
145faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt    property_get(prop_name, dns2, NULL);
146faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt
14789f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    snprintf(prop_name, sizeof(prop_name), "%s.%s.leasetime", DHCP_PROP_NAME_PREFIX, p2p_interface);
148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (property_get(prop_name, prop_value, NULL)) {
149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        *lease = atol(prop_value);
150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1510fb8ec8e9a056cd219216b1f5724d289b50dc993Jeff Sharkey
15289f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    snprintf(prop_name, sizeof(prop_name), "%s.%s.vendorInfo", DHCP_PROP_NAME_PREFIX,
15389f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff            p2p_interface);
1540fb8ec8e9a056cd219216b1f5724d289b50dc993Jeff Sharkey    property_get(prop_name, vendorInfo, NULL);
1550fb8ec8e9a056cd219216b1f5724d289b50dc993Jeff Sharkey
156faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt    return 0;
157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1598c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczakstatic const char *ipaddr_to_string(in_addr_t addr)
1608c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak{
1618c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak    struct in_addr in_addr;
1628c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak
1638c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak    in_addr.s_addr = addr;
1648c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak    return inet_ntoa(in_addr);
1658c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak}
1668c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak
167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Start the dhcp client daemon, and wait for it to finish
169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * configuring the interface.
17035c28608bf3dc31bab8cd6c2579739643e0145d8Irfan Sheriff *
17135c28608bf3dc31bab8cd6c2579739643e0145d8Irfan Sheriff * The device init.rc file needs a corresponding entry for this work.
17235c28608bf3dc31bab8cd6c2579739643e0145d8Irfan Sheriff *
17335c28608bf3dc31bab8cd6c2579739643e0145d8Irfan Sheriff * Example:
17462d6f7486323fd2bd27299940a28f3c6de73f65dDmitry Shmidt * service dhcpcd_<interface> /system/bin/dhcpcd -ABKL -f dhcpcd.conf
175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint dhcp_do_request(const char *interface,
177faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt                    char *ipaddr,
178faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt                    char *gateway,
179faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt                    uint32_t *prefixLength,
180faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt                    char *dns1,
181faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt                    char *dns2,
182faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt                    char *server,
1830fb8ec8e9a056cd219216b1f5724d289b50dc993Jeff Sharkey                    uint32_t *lease,
1840fb8ec8e9a056cd219216b1f5724d289b50dc993Jeff Sharkey                    char *vendorInfo)
185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char result_prop_name[PROPERTY_KEY_MAX];
1879d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    char daemon_prop_name[PROPERTY_KEY_MAX];
188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char prop_value[PROPERTY_VALUE_MAX] = {'\0'};
18962d6f7486323fd2bd27299940a28f3c6de73f65dDmitry Shmidt    char daemon_cmd[PROPERTY_VALUE_MAX * 2 + sizeof(DHCP_CONFIG_PATH)];
190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const char *ctrl_prop = "ctl.start";
191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const char *desired_status = "running";
19289f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    /* Interface name after converting p2p0-p2p0-X to p2p to reuse system properties */
19389f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    char p2p_interface[MAX_INTERFACE_LENGTH];
194a329b4296cab06ea0b6e95065d8eabb82d3fd76drepo sync
19589f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    get_p2p_interface_replacement(interface, p2p_interface);
196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    snprintf(result_prop_name, sizeof(result_prop_name), "%s.%s.result",
198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            DHCP_PROP_NAME_PREFIX,
19989f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff            p2p_interface);
2009d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN
2019d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    snprintf(daemon_prop_name, sizeof(daemon_prop_name), "%s_%s",
2029d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN            DAEMON_PROP_NAME,
20389f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff            p2p_interface);
2049d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN
205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* Erase any previous setting of the dhcp result property */
206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    property_set(result_prop_name, "");
207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* Start the daemon and wait until it's ready */
2099363b7d5da7e17842432251384f8dc46902ac323Dmitry Shmidt    if (property_get(HOSTNAME_PROP_NAME, prop_value, NULL) && (prop_value[0] != '\0'))
21062d6f7486323fd2bd27299940a28f3c6de73f65dDmitry Shmidt        snprintf(daemon_cmd, sizeof(daemon_cmd), "%s_%s:-f %s -h %s %s", DAEMON_NAME,
21162d6f7486323fd2bd27299940a28f3c6de73f65dDmitry Shmidt                 p2p_interface, DHCP_CONFIG_PATH, prop_value, interface);
2129363b7d5da7e17842432251384f8dc46902ac323Dmitry Shmidt    else
21362d6f7486323fd2bd27299940a28f3c6de73f65dDmitry Shmidt        snprintf(daemon_cmd, sizeof(daemon_cmd), "%s_%s:-f %s %s", DAEMON_NAME,
21462d6f7486323fd2bd27299940a28f3c6de73f65dDmitry Shmidt                 DHCP_CONFIG_PATH, p2p_interface, interface);
2159363b7d5da7e17842432251384f8dc46902ac323Dmitry Shmidt    memset(prop_value, '\0', PROPERTY_VALUE_MAX);
2169363b7d5da7e17842432251384f8dc46902ac323Dmitry Shmidt    property_set(ctrl_prop, daemon_cmd);
2179d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    if (wait_for_property(daemon_prop_name, desired_status, 10) < 0) {
218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        snprintf(errmsg, sizeof(errmsg), "%s", "Timed out waiting for dhcpcd to start");
219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* Wait for the daemon to return a result */
223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (wait_for_property(result_prop_name, NULL, 30) < 0) {
224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        snprintf(errmsg, sizeof(errmsg), "%s", "Timed out waiting for DHCP to finish");
225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!property_get(result_prop_name, prop_value, NULL)) {
229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        /* shouldn't ever happen, given the success of wait_for_property() */
230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        snprintf(errmsg, sizeof(errmsg), "%s", "DHCP result property was not set");
231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (strcmp(prop_value, "ok") == 0) {
2348c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak        char dns_prop_name[PROPERTY_KEY_MAX];
2350fb8ec8e9a056cd219216b1f5724d289b50dc993Jeff Sharkey        if (fill_ip_info(interface, ipaddr, gateway, prefixLength,
2360fb8ec8e9a056cd219216b1f5724d289b50dc993Jeff Sharkey                dns1, dns2, server, lease, vendorInfo) == -1) {
237faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt            return -1;
238faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt        }
239faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt
240faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt        /* copy dns data to system properties - TODO - remove this after we have async
241faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt         * notification of renewal's */
2428c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak        snprintf(dns_prop_name, sizeof(dns_prop_name), "net.%s.dns1", interface);
2438c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak        property_set(dns_prop_name, *dns1 ? ipaddr_to_string(*dns1) : "");
2448c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak        snprintf(dns_prop_name, sizeof(dns_prop_name), "net.%s.dns2", interface);
2458c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak        property_set(dns_prop_name, *dns2 ? ipaddr_to_string(*dns2) : "");
246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 0;
247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        snprintf(errmsg, sizeof(errmsg), "DHCP result was %s", prop_value);
249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**
254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Stop the DHCP client daemon.
255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint dhcp_stop(const char *interface)
257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char result_prop_name[PROPERTY_KEY_MAX];
2599d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    char daemon_prop_name[PROPERTY_KEY_MAX];
2609d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    char daemon_cmd[PROPERTY_VALUE_MAX * 2];
261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const char *ctrl_prop = "ctl.stop";
262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const char *desired_status = "stopped";
263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
26489f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    char p2p_interface[MAX_INTERFACE_LENGTH];
265a329b4296cab06ea0b6e95065d8eabb82d3fd76drepo sync
26689f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    get_p2p_interface_replacement(interface, p2p_interface);
267a329b4296cab06ea0b6e95065d8eabb82d3fd76drepo sync
268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    snprintf(result_prop_name, sizeof(result_prop_name), "%s.%s.result",
269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            DHCP_PROP_NAME_PREFIX,
27089f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff            p2p_interface);
2719d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN
2729d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    snprintf(daemon_prop_name, sizeof(daemon_prop_name), "%s_%s",
2739d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN            DAEMON_PROP_NAME,
27489f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff            p2p_interface);
2759d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN
27689f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    snprintf(daemon_cmd, sizeof(daemon_cmd), "%s_%s", DAEMON_NAME, p2p_interface);
2779d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN
278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* Stop the daemon and wait until it's reported to be stopped */
2799d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    property_set(ctrl_prop, daemon_cmd);
2809d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    if (wait_for_property(daemon_prop_name, desired_status, 5) < 0) {
281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    property_set(result_prop_name, "failed");
284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**
288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Release the current DHCP client lease.
289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint dhcp_release_lease(const char *interface)
291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
2929d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    char daemon_prop_name[PROPERTY_KEY_MAX];
2939d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    char daemon_cmd[PROPERTY_VALUE_MAX * 2];
294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const char *ctrl_prop = "ctl.stop";
295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const char *desired_status = "stopped";
296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
29789f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    char p2p_interface[MAX_INTERFACE_LENGTH];
298a329b4296cab06ea0b6e95065d8eabb82d3fd76drepo sync
29989f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    get_p2p_interface_replacement(interface, p2p_interface);
300a329b4296cab06ea0b6e95065d8eabb82d3fd76drepo sync
3019d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    snprintf(daemon_prop_name, sizeof(daemon_prop_name), "%s_%s",
3029d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN            DAEMON_PROP_NAME,
30389f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff            p2p_interface);
3049d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN
30589f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    snprintf(daemon_cmd, sizeof(daemon_cmd), "%s_%s", DAEMON_NAME, p2p_interface);
3069d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN
307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* Stop the daemon and wait until it's reported to be stopped */
3089d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    property_set(ctrl_prop, daemon_cmd);
3099d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    if (wait_for_property(daemon_prop_name, desired_status, 5) < 0) {
310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectchar *dhcp_get_errmsg() {
316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return errmsg;
317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
3189d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN
3199d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN/**
32035c28608bf3dc31bab8cd6c2579739643e0145d8Irfan Sheriff * The device init.rc file needs a corresponding entry.
32135c28608bf3dc31bab8cd6c2579739643e0145d8Irfan Sheriff *
32235c28608bf3dc31bab8cd6c2579739643e0145d8Irfan Sheriff * Example:
32335c28608bf3dc31bab8cd6c2579739643e0145d8Irfan Sheriff * service iprenew_<interface> /system/bin/dhcpcd -n
32435c28608bf3dc31bab8cd6c2579739643e0145d8Irfan Sheriff *
3259d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN */
3269d157870345fa18ee7e639a85f6bcc4afb50c648TK MUNint dhcp_do_request_renew(const char *interface,
32789f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff                    char *ipaddr,
32889f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff                    char *gateway,
329ed21633a5e81f7bb9688da98bc9ea9b08b6bce20tk.mun                    uint32_t *prefixLength,
33089f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff                    char *dns1,
33189f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff                    char *dns2,
33289f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff                    char *server,
3330fb8ec8e9a056cd219216b1f5724d289b50dc993Jeff Sharkey                    uint32_t *lease,
3340fb8ec8e9a056cd219216b1f5724d289b50dc993Jeff Sharkey                    char *vendorInfo)
3359d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN{
3369d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    char result_prop_name[PROPERTY_KEY_MAX];
3379d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    char prop_value[PROPERTY_VALUE_MAX] = {'\0'};
3389d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    char daemon_cmd[PROPERTY_VALUE_MAX * 2];
3399d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    const char *ctrl_prop = "ctl.start";
3409d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN
34189f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    char p2p_interface[MAX_INTERFACE_LENGTH];
342a329b4296cab06ea0b6e95065d8eabb82d3fd76drepo sync
34389f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    get_p2p_interface_replacement(interface, p2p_interface);
344a329b4296cab06ea0b6e95065d8eabb82d3fd76drepo sync
3459d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    snprintf(result_prop_name, sizeof(result_prop_name), "%s.%s.result",
3469d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN            DHCP_PROP_NAME_PREFIX,
34789f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff            p2p_interface);
3489d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN
3499d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    /* Erase any previous setting of the dhcp result property */
3509d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    property_set(result_prop_name, "");
3519d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN
3529d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    /* Start the renew daemon and wait until it's ready */
353a329b4296cab06ea0b6e95065d8eabb82d3fd76drepo sync    snprintf(daemon_cmd, sizeof(daemon_cmd), "%s_%s:%s", DAEMON_NAME_RENEW,
35489f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff            p2p_interface, interface);
3559d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    memset(prop_value, '\0', PROPERTY_VALUE_MAX);
3569d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    property_set(ctrl_prop, daemon_cmd);
3579d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN
3589d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    /* Wait for the daemon to return a result */
3599d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    if (wait_for_property(result_prop_name, NULL, 30) < 0) {
3609d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN        snprintf(errmsg, sizeof(errmsg), "%s", "Timed out waiting for DHCP Renew to finish");
3619d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN        return -1;
3629d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    }
3639d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN
3649d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    if (!property_get(result_prop_name, prop_value, NULL)) {
3659d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN        /* shouldn't ever happen, given the success of wait_for_property() */
3669d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN        snprintf(errmsg, sizeof(errmsg), "%s", "DHCP Renew result property was not set");
3679d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN        return -1;
3689d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    }
3699d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    if (strcmp(prop_value, "ok") == 0) {
3700fb8ec8e9a056cd219216b1f5724d289b50dc993Jeff Sharkey        fill_ip_info(interface, ipaddr, gateway, prefixLength,
3710fb8ec8e9a056cd219216b1f5724d289b50dc993Jeff Sharkey                dns1, dns2, server, lease, vendorInfo);
3729d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN        return 0;
3739d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    } else {
3749d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN        snprintf(errmsg, sizeof(errmsg), "DHCP Renew result was %s", prop_value);
3759d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN        return -1;
3769d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    }
3779d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN}
378