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,
91fdd573188d08fbd3739aeda19ef0f2d03752db9fRobert Greenwalt                     char *dns[],
92faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt                     char *server,
930fb8ec8e9a056cd219216b1f5724d289b50dc993Jeff Sharkey                     uint32_t *lease,
946ecbdca4c19bc6f8eb371dd2c7a85fac06e1854dRobert Greenwalt                     char *vendorInfo,
95be06210c508d5878dcc7d185e5613f4c7e38dfe8Dmitry Shmidt                     char *domain,
96be06210c508d5878dcc7d185e5613f4c7e38dfe8Dmitry Shmidt                     char *mtu)
97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char prop_name[PROPERTY_KEY_MAX];
99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char prop_value[PROPERTY_VALUE_MAX];
10089f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    /* Interface name after converting p2p0-p2p0-X to p2p to reuse system properties */
10189f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    char p2p_interface[MAX_INTERFACE_LENGTH];
102fdd573188d08fbd3739aeda19ef0f2d03752db9fRobert Greenwalt    int x;
10389f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff
10489f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    get_p2p_interface_replacement(interface, p2p_interface);
105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
10689f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    snprintf(prop_name, sizeof(prop_name), "%s.%s.ipaddress", DHCP_PROP_NAME_PREFIX, p2p_interface);
107faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt    property_get(prop_name, ipaddr, NULL);
108faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt
10989f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    snprintf(prop_name, sizeof(prop_name), "%s.%s.gateway", DHCP_PROP_NAME_PREFIX, p2p_interface);
110faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt    property_get(prop_name, gateway, NULL);
111faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt
11289f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    snprintf(prop_name, sizeof(prop_name), "%s.%s.server", DHCP_PROP_NAME_PREFIX, p2p_interface);
113bdaaec1ba0a7cf832ad7fe475a7c541ed9973e52Irfan Sheriff    property_get(prop_name, server, NULL);
114bdaaec1ba0a7cf832ad7fe475a7c541ed9973e52Irfan Sheriff
115bdaaec1ba0a7cf832ad7fe475a7c541ed9973e52Irfan Sheriff    //TODO: Handle IPv6 when we change system property usage
11694cecfc4a00237cfd08e4327a836c67104ff2e20Irfan Sheriff    if (gateway[0] == '\0' || strncmp(gateway, "0.0.0.0", 7) == 0) {
117bdaaec1ba0a7cf832ad7fe475a7c541ed9973e52Irfan Sheriff        //DHCP server is our best bet as gateway
118bdaaec1ba0a7cf832ad7fe475a7c541ed9973e52Irfan Sheriff        strncpy(gateway, server, PROPERTY_VALUE_MAX);
119bdaaec1ba0a7cf832ad7fe475a7c541ed9973e52Irfan Sheriff    }
120bdaaec1ba0a7cf832ad7fe475a7c541ed9973e52Irfan Sheriff
12189f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    snprintf(prop_name, sizeof(prop_name), "%s.%s.mask", DHCP_PROP_NAME_PREFIX, p2p_interface);
122faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt    if (property_get(prop_name, prop_value, NULL)) {
123faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt        int p;
124faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt        // this conversion is v4 only, but this dhcp client is v4 only anyway
125faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt        in_addr_t mask = ntohl(inet_addr(prop_value));
126faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt        // Check netmask is a valid IP address.  ntohl gives NONE response (all 1's) for
127faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt        // non 255.255.255.255 inputs.  if we get that value check if it is legit..
128faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt        if (mask == INADDR_NONE && strcmp(prop_value, "255.255.255.255") != 0) {
129faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt            snprintf(errmsg, sizeof(errmsg), "DHCP gave invalid net mask %s", prop_value);
130faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt            return -1;
131faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt        }
132faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt        for (p = 0; p < 32; p++) {
133faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt            if (mask == 0) break;
134faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt            // check for non-contiguous netmask, e.g., 255.254.255.0
135faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt            if ((mask & 0x80000000) == 0) {
136faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt                snprintf(errmsg, sizeof(errmsg), "DHCP gave invalid net mask %s", prop_value);
137faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt                return -1;
138faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt            }
139faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt            mask = mask << 1;
140faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt        }
141faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt        *prefixLength = p;
142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
143faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt
144fdd573188d08fbd3739aeda19ef0f2d03752db9fRobert Greenwalt    for (x=0; dns[x] != NULL; x++) {
145fdd573188d08fbd3739aeda19ef0f2d03752db9fRobert Greenwalt        snprintf(prop_name, sizeof(prop_name), "%s.%s.dns%d", DHCP_PROP_NAME_PREFIX, p2p_interface, x+1);
146fdd573188d08fbd3739aeda19ef0f2d03752db9fRobert Greenwalt        property_get(prop_name, dns[x], NULL);
147fdd573188d08fbd3739aeda19ef0f2d03752db9fRobert Greenwalt    }
148faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt
14989f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    snprintf(prop_name, sizeof(prop_name), "%s.%s.leasetime", DHCP_PROP_NAME_PREFIX, p2p_interface);
150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (property_get(prop_name, prop_value, NULL)) {
151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        *lease = atol(prop_value);
152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
1530fb8ec8e9a056cd219216b1f5724d289b50dc993Jeff Sharkey
15489f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    snprintf(prop_name, sizeof(prop_name), "%s.%s.vendorInfo", DHCP_PROP_NAME_PREFIX,
15589f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff            p2p_interface);
1560fb8ec8e9a056cd219216b1f5724d289b50dc993Jeff Sharkey    property_get(prop_name, vendorInfo, NULL);
1570fb8ec8e9a056cd219216b1f5724d289b50dc993Jeff Sharkey
1586ecbdca4c19bc6f8eb371dd2c7a85fac06e1854dRobert Greenwalt    snprintf(prop_name, sizeof(prop_name), "%s.%s.domain", DHCP_PROP_NAME_PREFIX,
1596ecbdca4c19bc6f8eb371dd2c7a85fac06e1854dRobert Greenwalt            p2p_interface);
1606ecbdca4c19bc6f8eb371dd2c7a85fac06e1854dRobert Greenwalt    property_get(prop_name, domain, NULL);
1616ecbdca4c19bc6f8eb371dd2c7a85fac06e1854dRobert Greenwalt
162be06210c508d5878dcc7d185e5613f4c7e38dfe8Dmitry Shmidt    snprintf(prop_name, sizeof(prop_name), "%s.%s.mtu", DHCP_PROP_NAME_PREFIX,
163be06210c508d5878dcc7d185e5613f4c7e38dfe8Dmitry Shmidt            p2p_interface);
164be06210c508d5878dcc7d185e5613f4c7e38dfe8Dmitry Shmidt    property_get(prop_name, mtu, NULL);
165be06210c508d5878dcc7d185e5613f4c7e38dfe8Dmitry Shmidt
166faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt    return 0;
167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1698c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczakstatic const char *ipaddr_to_string(in_addr_t addr)
1708c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak{
1718c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak    struct in_addr in_addr;
1728c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak
1738c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak    in_addr.s_addr = addr;
1748c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak    return inet_ntoa(in_addr);
1758c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak}
1768c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak
177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Start the dhcp client daemon, and wait for it to finish
179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * configuring the interface.
18035c28608bf3dc31bab8cd6c2579739643e0145d8Irfan Sheriff *
18135c28608bf3dc31bab8cd6c2579739643e0145d8Irfan Sheriff * The device init.rc file needs a corresponding entry for this work.
18235c28608bf3dc31bab8cd6c2579739643e0145d8Irfan Sheriff *
18335c28608bf3dc31bab8cd6c2579739643e0145d8Irfan Sheriff * Example:
18462d6f7486323fd2bd27299940a28f3c6de73f65dDmitry Shmidt * service dhcpcd_<interface> /system/bin/dhcpcd -ABKL -f dhcpcd.conf
185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint dhcp_do_request(const char *interface,
187faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt                    char *ipaddr,
188faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt                    char *gateway,
189faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt                    uint32_t *prefixLength,
190fdd573188d08fbd3739aeda19ef0f2d03752db9fRobert Greenwalt                    char *dns[],
191faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt                    char *server,
1920fb8ec8e9a056cd219216b1f5724d289b50dc993Jeff Sharkey                    uint32_t *lease,
1936ecbdca4c19bc6f8eb371dd2c7a85fac06e1854dRobert Greenwalt                    char *vendorInfo,
194be06210c508d5878dcc7d185e5613f4c7e38dfe8Dmitry Shmidt                    char *domain,
195be06210c508d5878dcc7d185e5613f4c7e38dfe8Dmitry Shmidt                    char *mtu)
196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char result_prop_name[PROPERTY_KEY_MAX];
1989d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    char daemon_prop_name[PROPERTY_KEY_MAX];
199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char prop_value[PROPERTY_VALUE_MAX] = {'\0'};
20062d6f7486323fd2bd27299940a28f3c6de73f65dDmitry Shmidt    char daemon_cmd[PROPERTY_VALUE_MAX * 2 + sizeof(DHCP_CONFIG_PATH)];
201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const char *ctrl_prop = "ctl.start";
202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const char *desired_status = "running";
20389f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    /* Interface name after converting p2p0-p2p0-X to p2p to reuse system properties */
20489f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    char p2p_interface[MAX_INTERFACE_LENGTH];
205a329b4296cab06ea0b6e95065d8eabb82d3fd76drepo sync
20689f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    get_p2p_interface_replacement(interface, p2p_interface);
207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    snprintf(result_prop_name, sizeof(result_prop_name), "%s.%s.result",
209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            DHCP_PROP_NAME_PREFIX,
21089f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff            p2p_interface);
2119d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN
2129d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    snprintf(daemon_prop_name, sizeof(daemon_prop_name), "%s_%s",
2139d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN            DAEMON_PROP_NAME,
21489f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff            p2p_interface);
2159d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN
216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* Erase any previous setting of the dhcp result property */
217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    property_set(result_prop_name, "");
218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* Start the daemon and wait until it's ready */
2209363b7d5da7e17842432251384f8dc46902ac323Dmitry Shmidt    if (property_get(HOSTNAME_PROP_NAME, prop_value, NULL) && (prop_value[0] != '\0'))
22162d6f7486323fd2bd27299940a28f3c6de73f65dDmitry Shmidt        snprintf(daemon_cmd, sizeof(daemon_cmd), "%s_%s:-f %s -h %s %s", DAEMON_NAME,
22262d6f7486323fd2bd27299940a28f3c6de73f65dDmitry Shmidt                 p2p_interface, DHCP_CONFIG_PATH, prop_value, interface);
2239363b7d5da7e17842432251384f8dc46902ac323Dmitry Shmidt    else
22462d6f7486323fd2bd27299940a28f3c6de73f65dDmitry Shmidt        snprintf(daemon_cmd, sizeof(daemon_cmd), "%s_%s:-f %s %s", DAEMON_NAME,
225ba2ba5c011a3fb13cba538296b70888dd0fb129bMatt Gumbel                 p2p_interface, DHCP_CONFIG_PATH, interface);
2269363b7d5da7e17842432251384f8dc46902ac323Dmitry Shmidt    memset(prop_value, '\0', PROPERTY_VALUE_MAX);
2279363b7d5da7e17842432251384f8dc46902ac323Dmitry Shmidt    property_set(ctrl_prop, daemon_cmd);
2289d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    if (wait_for_property(daemon_prop_name, desired_status, 10) < 0) {
229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        snprintf(errmsg, sizeof(errmsg), "%s", "Timed out waiting for dhcpcd to start");
230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* Wait for the daemon to return a result */
234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (wait_for_property(result_prop_name, NULL, 30) < 0) {
235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        snprintf(errmsg, sizeof(errmsg), "%s", "Timed out waiting for DHCP to finish");
236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (!property_get(result_prop_name, prop_value, NULL)) {
240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        /* shouldn't ever happen, given the success of wait_for_property() */
241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        snprintf(errmsg, sizeof(errmsg), "%s", "DHCP result property was not set");
242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    if (strcmp(prop_value, "ok") == 0) {
2458c85a00db6da092ec3766facd49132fa4fc319a1Szymon Jakubczak        char dns_prop_name[PROPERTY_KEY_MAX];
246fdd573188d08fbd3739aeda19ef0f2d03752db9fRobert Greenwalt        if (fill_ip_info(interface, ipaddr, gateway, prefixLength, dns,
247be06210c508d5878dcc7d185e5613f4c7e38dfe8Dmitry Shmidt                server, lease, vendorInfo, domain, mtu) == -1) {
248faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt            return -1;
249faab26d542740f03cbe12e44f6af1f97e8e7c12eRobert Greenwalt        }
250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return 0;
251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    } else {
252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        snprintf(errmsg, sizeof(errmsg), "DHCP result was %s", prop_value);
253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**
258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Stop the DHCP client daemon.
259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint dhcp_stop(const char *interface)
261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    char result_prop_name[PROPERTY_KEY_MAX];
2639d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    char daemon_prop_name[PROPERTY_KEY_MAX];
2649d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    char daemon_cmd[PROPERTY_VALUE_MAX * 2];
265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const char *ctrl_prop = "ctl.stop";
266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const char *desired_status = "stopped";
267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
26889f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    char p2p_interface[MAX_INTERFACE_LENGTH];
269a329b4296cab06ea0b6e95065d8eabb82d3fd76drepo sync
27089f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    get_p2p_interface_replacement(interface, p2p_interface);
271a329b4296cab06ea0b6e95065d8eabb82d3fd76drepo sync
272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    snprintf(result_prop_name, sizeof(result_prop_name), "%s.%s.result",
273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project            DHCP_PROP_NAME_PREFIX,
27489f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff            p2p_interface);
2759d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN
2769d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    snprintf(daemon_prop_name, sizeof(daemon_prop_name), "%s_%s",
2779d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN            DAEMON_PROP_NAME,
27889f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff            p2p_interface);
2799d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN
28089f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    snprintf(daemon_cmd, sizeof(daemon_cmd), "%s_%s", DAEMON_NAME, p2p_interface);
2819d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN
282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* Stop the daemon and wait until it's reported to be stopped */
2839d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    property_set(ctrl_prop, daemon_cmd);
2849d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    if (wait_for_property(daemon_prop_name, desired_status, 5) < 0) {
285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    property_set(result_prop_name, "failed");
288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/**
292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Release the current DHCP client lease.
293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint dhcp_release_lease(const char *interface)
295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
2969d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    char daemon_prop_name[PROPERTY_KEY_MAX];
2979d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    char daemon_cmd[PROPERTY_VALUE_MAX * 2];
298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const char *ctrl_prop = "ctl.stop";
299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    const char *desired_status = "stopped";
300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
30189f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    char p2p_interface[MAX_INTERFACE_LENGTH];
302a329b4296cab06ea0b6e95065d8eabb82d3fd76drepo sync
30389f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    get_p2p_interface_replacement(interface, p2p_interface);
304a329b4296cab06ea0b6e95065d8eabb82d3fd76drepo sync
3059d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    snprintf(daemon_prop_name, sizeof(daemon_prop_name), "%s_%s",
3069d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN            DAEMON_PROP_NAME,
30789f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff            p2p_interface);
3089d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN
30989f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    snprintf(daemon_cmd, sizeof(daemon_cmd), "%s_%s", DAEMON_NAME, p2p_interface);
3109d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN
311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    /* Stop the daemon and wait until it's reported to be stopped */
3129d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    property_set(ctrl_prop, daemon_cmd);
3139d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    if (wait_for_property(daemon_prop_name, desired_status, 5) < 0) {
314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project        return -1;
315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    }
316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return 0;
317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectchar *dhcp_get_errmsg() {
320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    return errmsg;
321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
3229d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN
3239d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN/**
32435c28608bf3dc31bab8cd6c2579739643e0145d8Irfan Sheriff * The device init.rc file needs a corresponding entry.
32535c28608bf3dc31bab8cd6c2579739643e0145d8Irfan Sheriff *
32635c28608bf3dc31bab8cd6c2579739643e0145d8Irfan Sheriff * Example:
32735c28608bf3dc31bab8cd6c2579739643e0145d8Irfan Sheriff * service iprenew_<interface> /system/bin/dhcpcd -n
32835c28608bf3dc31bab8cd6c2579739643e0145d8Irfan Sheriff *
3299d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN */
3309d157870345fa18ee7e639a85f6bcc4afb50c648TK MUNint dhcp_do_request_renew(const char *interface,
33189f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff                    char *ipaddr,
33289f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff                    char *gateway,
333ed21633a5e81f7bb9688da98bc9ea9b08b6bce20tk.mun                    uint32_t *prefixLength,
334fdd573188d08fbd3739aeda19ef0f2d03752db9fRobert Greenwalt                    char *dns[],
33589f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff                    char *server,
3360fb8ec8e9a056cd219216b1f5724d289b50dc993Jeff Sharkey                    uint32_t *lease,
3376ecbdca4c19bc6f8eb371dd2c7a85fac06e1854dRobert Greenwalt                    char *vendorInfo,
338be06210c508d5878dcc7d185e5613f4c7e38dfe8Dmitry Shmidt                    char *domain,
339be06210c508d5878dcc7d185e5613f4c7e38dfe8Dmitry Shmidt                    char *mtu)
3409d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN{
3419d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    char result_prop_name[PROPERTY_KEY_MAX];
3429d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    char prop_value[PROPERTY_VALUE_MAX] = {'\0'};
3439d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    char daemon_cmd[PROPERTY_VALUE_MAX * 2];
3449d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    const char *ctrl_prop = "ctl.start";
3459d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN
34689f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    char p2p_interface[MAX_INTERFACE_LENGTH];
347a329b4296cab06ea0b6e95065d8eabb82d3fd76drepo sync
34889f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff    get_p2p_interface_replacement(interface, p2p_interface);
349a329b4296cab06ea0b6e95065d8eabb82d3fd76drepo sync
3509d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    snprintf(result_prop_name, sizeof(result_prop_name), "%s.%s.result",
3519d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN            DHCP_PROP_NAME_PREFIX,
35289f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff            p2p_interface);
3539d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN
3549d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    /* Erase any previous setting of the dhcp result property */
3559d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    property_set(result_prop_name, "");
3569d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN
3579d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    /* Start the renew daemon and wait until it's ready */
358a329b4296cab06ea0b6e95065d8eabb82d3fd76drepo sync    snprintf(daemon_cmd, sizeof(daemon_cmd), "%s_%s:%s", DAEMON_NAME_RENEW,
35989f58cf827ecac8e67f5bcdb1dc7a9ed43e69cefIrfan Sheriff            p2p_interface, interface);
3609d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    memset(prop_value, '\0', PROPERTY_VALUE_MAX);
3619d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    property_set(ctrl_prop, daemon_cmd);
3629d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN
3639d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    /* Wait for the daemon to return a result */
3649d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    if (wait_for_property(result_prop_name, NULL, 30) < 0) {
3659d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN        snprintf(errmsg, sizeof(errmsg), "%s", "Timed out waiting for DHCP Renew to finish");
3669d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN        return -1;
3679d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    }
3689d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN
3699d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    if (!property_get(result_prop_name, prop_value, NULL)) {
3709d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN        /* shouldn't ever happen, given the success of wait_for_property() */
3719d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN        snprintf(errmsg, sizeof(errmsg), "%s", "DHCP Renew result property was not set");
3729d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN        return -1;
3739d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    }
3749d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    if (strcmp(prop_value, "ok") == 0) {
3750a0a8768cbc9ce36d3c9a0cc712dc8c309811565Colin Cross        return fill_ip_info(interface, ipaddr, gateway, prefixLength, dns,
376be06210c508d5878dcc7d185e5613f4c7e38dfe8Dmitry Shmidt                server, lease, vendorInfo, domain, mtu);
3779d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    } else {
3789d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN        snprintf(errmsg, sizeof(errmsg), "DHCP Renew result was %s", prop_value);
3799d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN        return -1;
3809d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN    }
3819d157870345fa18ee7e639a85f6bcc4afb50c648TK MUN}
382