Commit 199a7c6f authored by Christian Spielberger's avatar Christian Spielberger Committed by Slava Monich

dhcp: Add sending of DHCP decline

Add sending of DHCP decline in case of address conflict for a DHCP lease.
parent db1ae094
......@@ -67,6 +67,7 @@ typedef enum _dhcp_client_state {
REBOOTING,
REQUESTING,
BOUND,
DECLINED,
RENEWING,
REBINDING,
RELEASED,
......@@ -497,6 +498,30 @@ static int send_discover(GDHCPClient *dhcp_client, uint32_t requested)
dhcp_client->request_bcast);
}
int g_dhcp_client_decline(GDHCPClient *dhcp_client, uint32_t requested)
{
struct dhcp_packet packet;
dhcp_client->state = DECLINED;
dhcp_client->retry_times = 0;
debug(dhcp_client, "sending DHCP decline");
init_packet(dhcp_client, &packet, DHCPDECLINE);
packet.xid = dhcp_client->xid;
packet.secs = dhcp_attempt_secs(dhcp_client);
if (requested)
dhcp_add_option_uint32(&packet, DHCP_REQUESTED_IP, requested);
add_send_options(dhcp_client, &packet);
return dhcp_send_raw_packet(&packet, INADDR_ANY, CLIENT_PORT,
INADDR_BROADCAST, SERVER_PORT, MAC_BCAST_ADDR,
dhcp_client->ifindex, true);
}
static int send_request(GDHCPClient *dhcp_client)
{
struct dhcp_packet packet;
......@@ -2736,6 +2761,7 @@ int g_dhcp_client_start(GDHCPClient *dhcp_client, const char *last_address)
int re;
uint32_t addr;
uint64_t rand;
ClientState oldstate = dhcp_client->state;
if (!dhcp_client)
return 0;
......@@ -2855,7 +2881,7 @@ int g_dhcp_client_start(GDHCPClient *dhcp_client, const char *last_address)
g_hash_table_remove_all(dhcp_client->secs_bcast_hash);
}
if (!last_address) {
if (!last_address || oldstate == DECLINED) {
addr = 0;
} else {
addr = ntohl(inet_addr(last_address));
......@@ -3056,6 +3082,7 @@ char *g_dhcp_client_get_netmask(GDHCPClient *dhcp_client)
case REBOOTING:
case REQUESTING:
case RELEASED:
case DECLINED:
case IPV4LL_PROBE:
case IPV4LL_ANNOUNCE:
case INFORMATION_REQ:
......
......@@ -140,6 +140,7 @@ GDHCPClient *g_dhcp_client_new(GDHCPType type, int index,
int g_dhcp_client_start(GDHCPClient *client, const char *last_address);
void g_dhcp_client_stop(GDHCPClient *client);
int g_dhcp_client_decline(GDHCPClient *client, uint32_t requested);
GDHCPClient *g_dhcp_client_ref(GDHCPClient *client);
void g_dhcp_client_unref(GDHCPClient *client);
......
......@@ -493,6 +493,7 @@ int __connman_dhcp_start(struct connman_ipconfig *ipconfig,
struct connman_network *network, dhcp_cb callback,
gpointer user_data);
void __connman_dhcp_stop(struct connman_ipconfig *ipconfig);
void __connman_dhcp_decline(struct connman_ipconfig *ipconfig);
int __connman_dhcp_init(void);
void __connman_dhcp_cleanup(void);
int __connman_dhcpv6_init(void);
......
......@@ -718,6 +718,30 @@ void __connman_dhcp_stop(struct connman_ipconfig *ipconfig)
}
}
void __connman_dhcp_decline(struct connman_ipconfig *ipconfig)
{
struct connman_dhcp *dhcp;
const char *address;
struct in_addr addr;
DBG("ipconfig_table %p ipconfig %p", ipconfig_table, ipconfig);
if (!ipconfig_table)
return;
dhcp = g_hash_table_lookup(ipconfig_table, ipconfig);
if (dhcp) {
address = __connman_ipconfig_get_local(ipconfig);
if (!address)
return;
if (inet_pton(AF_INET, address, &addr) != 1)
connman_error("Could not convert address %s", address);
g_dhcp_client_decline(dhcp->dhcp_client, htonl(addr.s_addr));
}
}
int __connman_dhcp_init(void)
{
DBG("");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment