#include <netpacket/packet.h>
#include <net/ethernet.h>
-#include <net/if_arp.h>
#include <linux/if.h>
#include <linux/filter.h>
#include "common.h"
#define DISCOVER_TIMEOUT 3
-#define DISCOVER_RETRIES 5
+#define DISCOVER_RETRIES 10
#define REQUEST_TIMEOUT 3
#define REQUEST_RETRIES 5
server, SERVER_PORT);
}
-static gboolean interface_is_up(int index)
-{
- int sk, err;
- struct ifreq ifr;
- gboolean ret = FALSE;
-
- sk = socket(PF_INET, SOCK_DGRAM, 0);
- if (sk < 0) {
- perror("Open socket error");
- return FALSE;
- }
- memset(&ifr, 0, sizeof(ifr));
- ifr.ifr_ifindex = index;
-
- err = ioctl(sk, SIOCGIFNAME, &ifr);
- if (err < 0) {
- perror("Get interface name error");
- goto done;
- }
-
- err = ioctl(sk, SIOCGIFFLAGS, &ifr);
- if (err < 0) {
- perror("Get interface flags error");
- goto done;
- }
-
- if (ifr.ifr_flags & IFF_UP)
- ret = TRUE;
-
-done:
- close(sk);
-
- return ret;
-}
-
-static char *get_interface_name(int index)
-{
- struct ifreq ifr;
- int sk, err;
-
- if (index < 0)
- return NULL;
-
- sk = socket(PF_INET, SOCK_DGRAM, 0);
- if (sk < 0) {
- perror("Open socket error");
- return NULL;
- }
-
- memset(&ifr, 0, sizeof(ifr));
- ifr.ifr_ifindex = index;
-
- err = ioctl(sk, SIOCGIFNAME, &ifr);
- if (err < 0) {
- perror("Get interface name error");
- close(sk);
- return NULL;
- }
-
- close(sk);
-
- return g_strdup(ifr.ifr_name);
-}
static void get_interface_mac_address(int index, uint8_t *mac_address)
{
setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &filter_prog,
sizeof(filter_prog));
+ memset(&sock, 0, sizeof(sock));
sock.sll_family = AF_PACKET;
sock.sll_protocol = htons(ETH_P_IP);
sock.sll_ifindex = ifindex;
{
GDHCPClient *dhcp_client = user_data;
+ debug(dhcp_client, "request timeout (retries %d)",
+ dhcp_client->retry_times);
+
dhcp_client->retry_times++;
start_request(dhcp_client);
GIOChannel *listener_channel;
int listener_sockfd;
+ debug(dhcp_client, "switch listening mode (%d ==> %d)",
+ dhcp_client->listen_mode, listen_mode);
+
if (dhcp_client->listen_mode == listen_mode)
return 0;
static void start_request(GDHCPClient *dhcp_client)
{
+ debug(dhcp_client, "start request (retries %d)",
+ dhcp_client->retry_times);
+
if (dhcp_client->retry_times == REQUEST_RETRIES) {
dhcp_client->state = INIT_SELECTING;
static void restart_dhcp(GDHCPClient *dhcp_client, int retry_times)
{
+ debug(dhcp_client, "restart DHCP (retries %d)", retry_times);
+
if (dhcp_client->timeout > 0) {
g_source_remove(dhcp_client->timeout);
dhcp_client->timeout = 0;
{
GDHCPClient *dhcp_client = user_data;
+ debug(dhcp_client, "start rebound timeout");
+
switch_listening_mode(dhcp_client, L2);
dhcp_client->lease_seconds >>= 1;
static void start_rebound(GDHCPClient *dhcp_client)
{
+ debug(dhcp_client, "start rebound");
+
dhcp_client->state = REBINDING;
dhcp_client->timeout = g_timeout_add_seconds_full(G_PRIORITY_HIGH,
{
GDHCPClient *dhcp_client = user_data;
+ debug(dhcp_client, "start renew timeout");
+
dhcp_client->state = RENEWING;
dhcp_client->lease_seconds >>= 1;
static void start_bound(GDHCPClient *dhcp_client)
{
+ debug(dhcp_client, "start bound");
+
dhcp_client->state = BOUND;
dhcp_client->timeout = g_timeout_add_seconds_full(G_PRIORITY_HIGH,
{
GDHCPClient *dhcp_client = user_data;
+ debug(dhcp_client, "restart DHCP timeout");
+
dhcp_client->ack_retry_times++;
restart_dhcp(dhcp_client, dhcp_client->ack_retry_times);
return ret;
}
-static GList *get_option_value_list(char *value)
+static GList *get_option_value_list(char *value, GDHCPOptionType type)
{
char *pos = value;
GList *list = NULL;
+ if (pos == NULL)
+ return NULL;
+
+ if (type == OPTION_STRING)
+ return g_list_append(list, g_strdup(value));
+
while ((pos = strchr(pos, ' ')) != NULL) {
*pos = '\0';
- list = g_list_append(list, g_strdup(value));
+ list = g_list_append(list, g_strdup(value));
value = ++pos;
}
- list = g_list_append(list, g_strdup(value));
+ list = g_list_append(list, g_strdup(value));
return list;
}
g_hash_table_remove(dhcp_client->code_value_hash,
GINT_TO_POINTER((int) code));
- value_list = get_option_value_list(option_value);
+ value_list = get_option_value_list(option_value, type);
g_free(option_value);
message_type = dhcp_get_option(&packet, DHCP_MESSAGE_TYPE);
if (message_type == NULL)
- /* No message type option, ignore pakcage */
+ /* No message type option, ignore package */
return TRUE;
debug(dhcp_client, "received DHCP packet (current state %d)",