Remove and replace ARP related from ip conflict detection module 92/190092/1
authorYu <jiung.yu@samsung.com>
Tue, 18 Sep 2018 07:13:41 +0000 (16:13 +0900)
committerYu <jiung.yu@samsung.com>
Tue, 18 Sep 2018 07:46:55 +0000 (16:46 +0900)
Change-Id: Ibc25d34d4f1276bb7005b7bd457e6069492d8084
Signed-off-by: Yu Jiung <jiung.yu@samsung.com>
include/inm-ip-conflict.h
src/inm-ip-conflict.c
test/inm-test.c

index dfee3f5a082f64a6b2bcb1ececa37920acb68a12..0097370a733eafb2d2019f09038a0e379f17a4d4 100644 (file)
@@ -21,7 +21,7 @@
 
  * This file declares functions for detecting IP conflict.
  *
- * @file        nm-ip-conflict.h
+ * @file        inm-ip-conflict.h
  * @author      Jiung Yu (jiung.yu@samsung.com)
  * @version     0.1
  */
index 40bc0491d029fd92caa9e98465cb8743071a6d1c..6a9842ddbe83e1cfa7176bd311dbce1feb72a0e9 100644 (file)
 /**
  * This file implements Detecting IP conflict functions.
  *
- * @file        nm-ip-conflict.c
+ * @file        inm-ip-conflict.c
  * @author      Jiung Yu (jiung.yu@samsung.com)
  * @version     0.1
  */
-#include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 
 #include <errno.h>
 
-#include <sys/ioctl.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-
-#include <linux/if.h>
-#include <linux/if_packet.h>
-#include <linux/if_ether.h>
-#include <linux/if_arp.h>
-#include <net/ethernet.h>
-
-#include <arpa/inet.h>
-
 #include <glib.h>
 
 #include "inm-manager-log.h"
 #define MAX_ARP_SEND_TIME 32000
 #define INITIAL_BURST_ARP_COUNT 5
 #define MSEC 1000
-#define IP_ALEN 4
-
-#ifndef MAC_FMT
-#define MAC_FMT "%02x:%02x:%02x:%02x:%02x:%02x"
-#endif
-
-#ifndef IP_FMT
-#define IP_FMT "%d.%d.%d.%d"
-#endif
 
-typedef struct __attribute__((packed))
-{
+typedef struct {
        unsigned short arp_hrd;
        unsigned short arp_pro;
        unsigned char arp_hln;
@@ -77,30 +53,21 @@ typedef struct __attribute__((packed))
        unsigned char arp_sip[IP_ALEN];
        unsigned char arp_tha[ETH_ALEN];
        unsigned char arp_tip[IP_ALEN];
-} arp_message_s;
 
-typedef struct {
-       gboolean detection_enabled;
+}__attribute__((packed))arp_message_s;
 
-       gchar if_name[IFNAMSIZ];
+typedef struct {
+       arp_data_s arp_data;
 
-       int ifindex;
-       unsigned char hwaddr[ETH_ALEN];
-       unsigned char ipaddr[IP_ALEN];
+       gboolean detection_enabled;
 
        gboolean initial_bursts;
        gint iteration;
        guint timeout;
 
-       /* arp sock related */
-       gint sock;
-       GIOChannel * sock_io_channel;
-       guint sock_source_id;
        guint timer_source_id;
        guint arp_reply_timer_source_id;
 
-       struct sockaddr_ll ll_addr;
-
        inm_ip_conflict_state_e state;
 
        ip_conflict_callback cb;
@@ -112,49 +79,11 @@ typedef struct {
 
        guint initial_time;
 
-       GHashTable *ip_conflict_cb_tbl;
+       GData *ip_conflict_cb_dl;
 } ip_conflict_mon_s;
 
 ip_conflict_mon_s ip_conflict_mon;
 
-static gboolean __send_arp(gpointer user_data);
-
-static void __print_mac(guchar *mac)
-{
-       INM_LOGI(MAC_FMT "\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
-}
-
-static void __print_ip(guchar *ip)
-{
-       INM_LOGI(IP_FMT "\n", ip[0], ip[1], ip[2], ip[3]);
-}
-
-static void __init_ll_addr(struct sockaddr_ll *ll_addr)
-{
-       ll_addr->sll_family = AF_PACKET;
-       ll_addr->sll_protocol = htons(ETH_P_ARP);
-       ll_addr->sll_hatype = htons(ARPHRD_ETHER);
-       ll_addr->sll_pkttype = (PACKET_BROADCAST);
-       ll_addr->sll_halen = ETH_ALEN;
-       ll_addr->sll_addr[6] = 0x00;
-       ll_addr->sll_addr[7] = 0x00;
-       return;
-}
-
-static void __init_ip_conflict_sock_data(ip_conflict_data_s *ip_conflict_data)
-{
-       ip_conflict_data->initial_bursts = TRUE;
-       ip_conflict_data->sock = -1;
-       ip_conflict_data->sock_io_channel = NULL;
-       ip_conflict_data->sock_source_id = 0;
-       ip_conflict_data->timer_source_id = 0;
-       ip_conflict_data->iteration = 0;
-       ip_conflict_data->state = IP_CONFLICT_STATE_UNKNOWN;
-       ip_conflict_data->detection_enabled = FALSE;
-
-       return;
-}
-
 static gboolean __arp_reply_timeout_cb(gpointer data)
 {
        __INM_FUNC_ENTER__;
@@ -171,46 +100,34 @@ static gboolean __arp_reply_timeout_cb(gpointer data)
                ip_conflict_data->initial_bursts = TRUE;
                if (ip_conflict_data->cb)
                        ip_conflict_data->cb(ip_conflict_data->state,
-                                       ip_conflict_data->if_name,
-                                       ip_conflict_data->ipaddr,
+                                       ip_conflict_data->arp_data.if_name,
+                                       ip_conflict_data->arp_data.ipaddr,
                                        ip_conflict_data->cb_user_data);
        }
 
-       ip_conflict_data->timer_source_id = g_timeout_add(ip_conflict_data->timeout, __send_arp, ip_conflict_data);
+       ip_conflict_data->timer_source_id =
+                       g_timeout_add(ip_conflict_data->timeout,
+                                       util_send_arp,
+                                       &(ip_conflict_data->arp_data));
        __INM_FUNC_EXIT__;
        return G_SOURCE_REMOVE;
 }
 
-static gboolean __check_arp_receive(GIOChannel *source,
-                                                 GIOCondition condition, gpointer data)
+static void __check_arp_receive(arp_message_s* ah, gpointer data)
 {
-       arp_message_s *ah = NULL;
-       ip_conflict_data_s *ip_conflict_data = (ip_conflict_data_s *)data;
-       gchar buf[ARP_PACKET_SIZE] = {0, };
-       gchar *ptr = NULL;
-       gsize bytes_read = 0;
-       GError *error = NULL;
-
-       if (g_io_channel_read_chars(source, buf, ARP_PACKET_SIZE,
-                               &bytes_read, &error) != G_IO_STATUS_NORMAL) {
-               INM_LOGI("Failure received arp packet[%d]:[%s]",
-                               error->code, error->message);
-               g_error_free(error);
-               return TRUE;
-       }
+       ip_conflict_data_s *ip_conflict_data;
+       arp_data_s *arp_data;
 
-       ptr = buf + ETH_HLEN;
-       ah = (arp_message_s *)ptr;
+       if (!data || !ah)
+               return;
 
-       /* Only handle ARP replies */
-       if (ah->arp_op != htons(ARPOP_REPLY)) {
-               return TRUE;
-       }
+       ip_conflict_data = (ip_conflict_data_s *)data;
+       arp_data = &(ip_conflict_data->arp_data);
 
-       if (memcmp(ah->arp_sha, ip_conflict_data->hwaddr, ETH_ALEN) == 0 ||
-               memcmp(ah->arp_sip, ip_conflict_data->ipaddr, 4) != 0) {
+       if (memcmp(ah->arp_sha, arp_data->hwaddr, ETH_ALEN) == 0 ||
+               memcmp(ah->arp_sip, arp_data->ipaddr, 4) != 0) {
                INM_LOGI("Packet not intended to us.\n");
-               return TRUE;
+               return;
        }
 
        ip_conflict_data->iteration = 0;
@@ -219,145 +136,46 @@ static gboolean __check_arp_receive(GIOChannel *source,
        ip_conflict_data->timeout = BURST_ARP_SEND_TIME;
        if (ip_conflict_data->cb)
                ip_conflict_data->cb(ip_conflict_data->state,
-                               ip_conflict_data->if_name,
-                               ip_conflict_data->ipaddr,
+                               arp_data->if_name,
+                               arp_data->ipaddr,
                                ip_conflict_data->cb_user_data);
 
        REMOVE_G_SOURCE(ip_conflict_data->arp_reply_timer_source_id);
        REMOVE_G_SOURCE(ip_conflict_data->timer_source_id);
        ip_conflict_data->timer_source_id =
-                       g_timeout_add(ip_conflict_data->timeout, __send_arp, NULL);
+                       g_timeout_add(ip_conflict_data->timeout, util_send_arp, &(ip_conflict_data->arp_data));
 
-       return TRUE;
-}
-
-int __get_iface_info(ip_conflict_data_s *ip_conflict_data)
-{
-       struct ifreq ifr;
-       char err_str[128] = {0,};
-       int sock = -1;
-
-       __INM_FUNC_ENTER__;
-
-       /* TODO laod local Iface info */
-
-       memset(&ifr, 0x00, sizeof(ifr));
-       if (strlen(ip_conflict_data->if_name) == 0)
-               return -1;
-
-       g_strlcpy(ifr.ifr_name, ip_conflict_data->if_name, strlen(ip_conflict_data->if_name) + 1);
-       INM_LOGI("get %s info\n", ifr.ifr_name);
-       sock = socket(AF_INET, SOCK_DGRAM, 0);
-       if (sock < 0) {
-               strerror_r(errno, err_str, 128);
-               INM_LOGE("errno[%d]: %s\n", errno, err_str);
-               __INM_FUNC_EXIT__;
-               return -1;
-       }
-
-       if (ioctl(sock, SIOCGIFHWADDR, &ifr) <0) {
-               strerror_r(errno, err_str, 128);
-               INM_LOGE("errno[%d]: %s\n", errno, err_str);
-               __INM_FUNC_EXIT__;
-               close(sock);
-               return -1;
-       }
-
-       memcpy(ip_conflict_data->hwaddr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
-       INM_LOGI("Successfully got our MAC address: ");
-       __print_mac(ip_conflict_data->hwaddr);
-
-       if (ioctl(sock, SIOCGIFINDEX, &ifr) < 0) {
-               strerror_r(errno, err_str, 128);
-               INM_LOGE("errno[%d]: %s\n", errno, err_str);
-               __INM_FUNC_EXIT__;
-               close(sock);
-               return -1;
-       }
-       ip_conflict_data->ifindex = ifr.ifr_ifindex;
-       INM_LOGI("Successfully got interface index: %i\n", ip_conflict_data->ifindex);
-
-       if (ioctl(sock, SIOCGIFADDR, &ifr) < 0) {
-               strerror_r(errno, err_str, 128);
-               INM_LOGE("errno[%d]: %s\n", errno, err_str);
-               close(sock);
-               __INM_FUNC_EXIT__;
-               return -1;
-       }
-
-       if (ifr.ifr_addr.sa_family != AF_INET) {
-               INM_LOGE("addr is not AF_INET\n");
-               close(sock);
-               __INM_FUNC_EXIT__;
-               return -1;
-       }
-
-       memcpy(ip_conflict_data->ipaddr, &(ifr.ifr_addr.sa_data[2]), 4);
-       INM_LOGI("IP addr: ");
-       __print_ip(ip_conflict_data->ipaddr);
-       close(sock);
-
-       __INM_FUNC_EXIT__;
-       return 0;
-}
-
-void __set_defend_arp_ethhdr(ip_conflict_data_s *ip_conflict_data, struct ethhdr *eh)
-{
-       memset(eh->h_dest, 0xff, ETH_ALEN);
-       memcpy(eh->h_source, ip_conflict_data->hwaddr, ETH_ALEN);
-       eh->h_proto = htons(ETH_P_ARP);
        return;
 }
 
-void __set_defend_arp(ip_conflict_data_s *ip_conflict_data, arp_message_s *ah)
+static inline void __init_ip_conflict_data(ip_conflict_data_s *ip_conflict_data)
 {
-       ah->arp_hrd = htons(ARPHRD_ETHER);
-       ah->arp_pro = htons(ETH_P_IP);
-       ah->arp_hln = ETH_ALEN;
-       ah->arp_pln = 4;
-       ah->arp_op = htons(ARPOP_REQUEST);
-
-       memcpy(ah->arp_sha, ip_conflict_data->hwaddr, ETH_ALEN);
-       /* by RFC 5227 2.1.1.  Probe Details,
-        'sender IP address' field MUST be set to all zeroes;
-        this is to avoid polluting ARP caches in other hosts
-        on the same link in the case where the address turns
-        out to be already in use by another host. */
-
-       memset(ah->arp_sip, 0x00, 4);
-       //memcpy(ah->arp_sip, ip_conflict_mons.ipaddr, 4);
+       ip_conflict_data->initial_bursts = TRUE;
+       ip_conflict_data->timer_source_id = 0;
+       ip_conflict_data->iteration = 0;
+       ip_conflict_data->timeout = ip_conflict_mon.initial_time;
 
-       memset(ah->arp_tha, 0x00, ETH_ALEN);
+       ip_conflict_data->arp_data.recv_func = (user_recv_func)__check_arp_receive;
+       ip_conflict_data->arp_data.user_data = ip_conflict_data;
 
-       memcpy(ah->arp_tip, ip_conflict_data->ipaddr, 4);
        return;
 }
-
-static int __recover_socket(ip_conflict_data_s *ip_conflict_data)
+static void __start_ip_conflict_mon(GQuark key_id,
+        gpointer value,
+        gpointer user_data)
 {
-       char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
-       if (ip_conflict_data->sock >= 0) {
-               close(ip_conflict_data->sock);
-               ip_conflict_data->sock = -1;
-       }
+       __INM_FUNC_ENTER__;
+       ip_conflict_data_s *ip_conflict_data = (ip_conflict_data_s *)value;
+       static gint initial_send_arp_count = 0;
+       gboolean ret;
 
-       /* reopen socket */
-       if ((ip_conflict_data->sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ARP))) == -1) {
-               INM_LOGI("socket %d", ip_conflict_data->sock);
-               strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
-               INM_LOGI("socket Failed. Error = %s\n", error_buf);
+       if (!ip_conflict_data->detection_enabled) {
+               INM_LOGI("IP conflict detection disabled");
+               __INM_FUNC_EXIT__;
+               return;
        }
 
-       return ip_conflict_data->sock;
-}
-
-static gboolean __send_arp(gpointer user_data)
-{
-       ip_conflict_data_s *ip_conflict_data = (ip_conflict_data_s *)user_data;
-       static gint initial_send_arp_count = 0;
-       guchar buf[60] = {0,};
-       guchar *pos = NULL;
-       gint ret = 0;
+       __init_ip_conflict_data(ip_conflict_data);
 
        if (ip_conflict_data->initial_bursts &&
                        initial_send_arp_count >= INITIAL_BURST_ARP_COUNT) {
@@ -368,26 +186,13 @@ static gboolean __send_arp(gpointer user_data)
        if (ip_conflict_data->initial_bursts)
                initial_send_arp_count++;
 
-       __get_iface_info(ip_conflict_data);
-
-       pos = buf;
-       __set_defend_arp_ethhdr(ip_conflict_data, (struct ethhdr *)pos);
-
-       pos = buf + ETH_HLEN;
-       __set_defend_arp(ip_conflict_data, (arp_message_s *)pos);
+       util_create_arp_sock(&(ip_conflict_data->arp_data));
+       ret = util_send_arp(&(ip_conflict_data->arp_data));
 
-       /* Construct the destination address */
-       memcpy(ip_conflict_data->ll_addr.sll_addr, ip_conflict_data->hwaddr, ETH_ALEN);
-       ip_conflict_data->ll_addr.sll_ifindex = ip_conflict_data->ifindex;
-
-       ret = sendto(ip_conflict_data->sock, buf, 42, 0,
-               (struct sockaddr *) &(ip_conflict_data->ll_addr),
-               sizeof(struct sockaddr_ll));
-
-       if (ret == -1 && __recover_socket(ip_conflict_data) < 0) {
+       if (!ret && util_recover_arp_sock(&(ip_conflict_data->arp_data)) < 0) {
                REMOVE_G_SOURCE(ip_conflict_data->timer_source_id);
                ip_conflict_data->timer_source_id =
-                               g_timeout_add(ip_conflict_data->timeout, __send_arp, ip_conflict_data);
+                               g_timeout_add(ip_conflict_data->timeout, util_send_arp, &(ip_conflict_data->arp_data));
        } else {
                INM_LOGD("Sent ARP Packet \n");
                REMOVE_G_SOURCE(ip_conflict_data->timer_source_id);
@@ -403,99 +208,21 @@ static gboolean __send_arp(gpointer user_data)
                                g_timeout_add(1000, __arp_reply_timeout_cb, ip_conflict_data);
        }
 
-       return FALSE;
-}
-
-static void __start_ip_conflict_mon(gpointer key,
-        gpointer value,
-        gpointer user_data)
-{
-       __INM_FUNC_ENTER__;
-       gchar error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
-       ip_conflict_data_s *ip_conflict_data = (ip_conflict_data_s *)value;
-       ip_conflict_mon_s *mon = (ip_conflict_mon_s *)user_data;
-
-       gint sock = -1;
-
-       if (!ip_conflict_data->detection_enabled) {
-               INM_LOGI("IP conflict detection disabled");
-               __INM_FUNC_EXIT__;
-               return;
-       }
-
-       __init_ip_conflict_sock_data(ip_conflict_data);
-
-       sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ARP));
-       if (sock < 0) {
-               strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER);
-               INM_LOGI("socket Failed. Error = %s\n", error_buf);
-               __INM_FUNC_EXIT__;
-               return;
-       }
-
-       ip_conflict_data->sock = sock;
-       ip_conflict_data->sock_io_channel = g_io_channel_unix_new(sock);
-       if (!ip_conflict_data->sock_io_channel) {
-               INM_LOGI("Failed to create channel");
-               ip_conflict_data->sock = -1;
-               close(sock);
-               __INM_FUNC_EXIT__;
-               return;
-       }
-
-       g_io_channel_set_close_on_unref(ip_conflict_data->sock_io_channel, TRUE);
-
-       if (G_IO_STATUS_NORMAL !=
-                       g_io_channel_set_encoding(ip_conflict_data->sock_io_channel,
-                                       NULL, NULL))
-               INM_LOGI("Failed to set encoding NULL on io channel");
-
-       if (G_IO_STATUS_NORMAL !=
-                       g_io_channel_set_flags(ip_conflict_data->sock_io_channel,
-                                       G_IO_FLAG_NONBLOCK, NULL))
-               INM_LOGI("Failed to set flags on io channel");
-
-       ip_conflict_data->sock_source_id =
-                       g_io_add_watch(ip_conflict_data->sock_io_channel, G_IO_IN,
-                                       __check_arp_receive, ip_conflict_data);
-       INM_LOGD("socket %d", sock);
-
-       ip_conflict_data->timeout = mon->initial_time;
-       __send_arp(ip_conflict_data);
-
        __INM_FUNC_EXIT__;
        return;
 }
 
-static void __stop_ip_conflict_mon(gpointer key,
+static void __stop_ip_conflict_mon(GQuark key_id,
         gpointer value,
         gpointer user_data)
 {
-       GError* error = NULL;
        ip_conflict_data_s *ip_conflict_data = (ip_conflict_data_s *)value;
 
        __INM_FUNC_ENTER__;
 
        REMOVE_G_SOURCE(ip_conflict_data->timer_source_id);
 
-       if (ip_conflict_data->sock < 0) {
-               __INM_FUNC_EXIT__;
-               return;
-       }
-
-       if (G_IO_STATUS_NORMAL !=
-               g_io_channel_shutdown(ip_conflict_data->sock_io_channel,
-                               FALSE,
-                               &error)) {
-               INM_LOGI("Failure received while shutdown io channel[%d]:[%s]",
-                               error->code, error->message);
-               g_error_free(error);
-       }
-
-       g_io_channel_unref(ip_conflict_data->sock_io_channel);
-       REMOVE_G_SOURCE(ip_conflict_data->sock_source_id);
-       close(ip_conflict_data->sock);
-       ip_conflict_data->sock = -1;
+       util_destroy_arp_sock(&(ip_conflict_data->arp_data));
 
        __INM_FUNC_EXIT__;
        return;
@@ -505,16 +232,19 @@ int inm_ip_conflict_enable_detection(gchar *if_name, gboolean enable)
 {
        gint ret = INM_IP_CONFLICT_ERROR_NONE;
        ip_conflict_data_s *ip_conflict_data = NULL;
+       GQuark if_key;
 
        __INM_FUNC_ENTER__;
 
        if (!ip_conflict_mon.is_initialized) {
+               INM_LOGE("Not intialiezed");
                __INM_FUNC_EXIT__;
                return INM_IP_CONFLICT_ERROR_NOT_INITIALIZED;
        }
 
+       if_key = g_quark_from_string(if_name);
        ip_conflict_data =
-                       g_hash_table_lookup(ip_conflict_mon.ip_conflict_cb_tbl, if_name);
+                       g_datalist_get_data(&(ip_conflict_mon.ip_conflict_cb_dl), if_name);
        if (!ip_conflict_data) {
                INM_LOGI("ip_conflict_data not found");
                __INM_FUNC_EXIT__;
@@ -522,23 +252,26 @@ int inm_ip_conflict_enable_detection(gchar *if_name, gboolean enable)
        }
 
        if (enable) {
-               if (ip_conflict_data->sock != -1) {
+               if (ip_conflict_data->arp_data.sock != -1) {
                        __INM_FUNC_EXIT__;
                        return INM_IP_CONFLICT_ERROR_IN_PROGRESS;
                }
 
                ip_conflict_data->detection_enabled = TRUE;
-               ip_conflict_data->state = IP_CONFLICT_STATE_UNKNOWN;
+               ip_conflict_data->state = IP_CONFLICT_STATE_CONFLICT_NOT_DETECTED;
 
-               __start_ip_conflict_mon(if_name, ip_conflict_data, &ip_conflict_mon);
-               if (!ip_conflict_data->sock_source_id == 0) {
+               __start_ip_conflict_mon(if_key, ip_conflict_data, NULL);
+               if (ip_conflict_data->arp_data.sock_source_id == 0) {
                        INM_LOGI("Failed to start IP conflict monitoring");
+                       __stop_ip_conflict_mon(if_key, ip_conflict_data, NULL);
                        ip_conflict_data->detection_enabled = FALSE;
+                       ip_conflict_data->state = IP_CONFLICT_STATE_UNKNOWN;
                        return INM_IP_CONFLICT_ERROR_OPERATION_FAILED;
                }
+
        } else {
-               if (ip_conflict_data->sock != -1) {
-                       __stop_ip_conflict_mon(if_name, ip_conflict_data, &ip_conflict_mon);
+               if (ip_conflict_data->arp_data.sock != -1) {
+                       __stop_ip_conflict_mon(if_key, ip_conflict_data, NULL);
                        ip_conflict_data->detection_enabled = FALSE;
                        ip_conflict_data->state = IP_CONFLICT_STATE_UNKNOWN;
                }
@@ -588,12 +321,12 @@ int inm_ip_conflict_set_detection_period(guint period)
 
        ip_conflict_mon.initial_time = period * MSEC;
 
-       g_hash_table_foreach(ip_conflict_mon.ip_conflict_cb_tbl,
+       g_datalist_foreach(&(ip_conflict_mon.ip_conflict_cb_dl),
                        __stop_ip_conflict_mon,
-                       &ip_conflict_mon);
-       g_hash_table_foreach(ip_conflict_mon.ip_conflict_cb_tbl,
+                       NULL);
+       g_datalist_foreach(&(ip_conflict_mon.ip_conflict_cb_dl),
                        __start_ip_conflict_mon,
-                       &ip_conflict_mon);
+                       NULL);
 
        __INM_FUNC_EXIT__;
        return ret;
@@ -617,13 +350,14 @@ int inm_ip_conflict_get_state(gchar *if_name, guint *state)
        }
 
        ip_conflict_data =
-                       g_hash_table_lookup(ip_conflict_mon.ip_conflict_cb_tbl, if_name);
+                       g_datalist_get_data(&(ip_conflict_mon.ip_conflict_cb_dl), if_name);
        if (!ip_conflict_data) {
                INM_LOGI("ip_conflict_data not found");
                __INM_FUNC_EXIT__;
                return INM_IP_CONFLICT_ERROR_OPERATION_FAILED;
        }
 
+       INM_LOGI("state [%d]", ip_conflict_data->state);
        *state = ip_conflict_data->state;
 
        __INM_FUNC_EXIT__;
@@ -648,25 +382,38 @@ int inm_ip_conflict_is_detection_enabled(gchar *if_name, gboolean *enabled)
        }
 
        ip_conflict_data =
-                       g_hash_table_lookup(ip_conflict_mon.ip_conflict_cb_tbl, if_name);
+                       g_datalist_get_data(&(ip_conflict_mon.ip_conflict_cb_dl), if_name);
        if (!ip_conflict_data) {
                INM_LOGI("ip_conflict_data not found");
                __INM_FUNC_EXIT__;
                return INM_IP_CONFLICT_ERROR_OPERATION_FAILED;
        }
 
+       INM_LOGI("enabled [%d]", ip_conflict_data->detection_enabled);
        *enabled = ip_conflict_data->detection_enabled;
 
        __INM_FUNC_EXIT__;
        return ret;
 }
 
+void __destroy_ip_conflict_data(gpointer user_data)
+{
+       ip_conflict_data_s *ip_conflict_data = (ip_conflict_data_s *)user_data;
+
+       if (!ip_conflict_data)
+               return;
+
+       __stop_ip_conflict_mon(0, ip_conflict_data, &ip_conflict_mon);
+       g_free(ip_conflict_data);
+
+       return;
+}
+
 ip_conflict_data_s *__create_ip_confilct_data(gchar *if_name)
 {
        ip_conflict_data_s *ip_conflict_data = NULL;
-
        ip_conflict_data =
-                       g_hash_table_lookup(ip_conflict_mon.ip_conflict_cb_tbl, if_name);
+                       g_datalist_get_data(&(ip_conflict_mon.ip_conflict_cb_dl), if_name);
        if (ip_conflict_data)
                return ip_conflict_data;
 
@@ -678,35 +425,16 @@ ip_conflict_data_s *__create_ip_confilct_data(gchar *if_name)
                return NULL;
        }
 
-       if (!g_hash_table_insert(
-                       ip_conflict_mon.ip_conflict_cb_tbl,
-                       g_strdup(if_name),
-                       ip_conflict_data)) {
-               g_free(ip_conflict_data);
-               INM_LOGI("Error! Failed to insert ip_conflict_data");
-               __INM_FUNC_EXIT__;
-               return NULL;
-       }
+       ip_conflict_data->arp_data.sock = -1;
 
-       __init_ip_conflict_sock_data(ip_conflict_data);
-       __init_ll_addr((struct sockaddr_ll *)&(ip_conflict_data->ll_addr));
+       g_datalist_set_data_full(&(ip_conflict_mon.ip_conflict_cb_dl),
+                       if_name,
+                       ip_conflict_data,
+                       __destroy_ip_conflict_data);
 
        return ip_conflict_data;
 }
 
-void __destroy_ip_conflict_data(gpointer user_data)
-{
-       ip_conflict_data_s *ip_conflict_data = (ip_conflict_data_s *)user_data;
-
-       if (!ip_conflict_data)
-               return;
-
-       __stop_ip_conflict_mon(ip_conflict_data->if_name, ip_conflict_data, &ip_conflict_mon);
-       g_free(ip_conflict_data);
-
-       return;
-}
-
 int ip_conflict_set_callback(gchar *if_name, ip_conflict_callback cb, gpointer user_data)
 {
        gint ret = INM_IP_CONFLICT_ERROR_NONE;
@@ -730,7 +458,7 @@ int ip_conflict_set_callback(gchar *if_name, ip_conflict_callback cb, gpointer u
                return INM_IP_CONFLICT_ERROR_OPERATION_FAILED;
        }
 
-       g_strlcpy(ip_conflict_data->if_name, if_name, IFNAMSIZ);
+       g_strlcpy(ip_conflict_data->arp_data.if_name, if_name, IFNAMSIZ);
        ip_conflict_data->cb = cb;
        ip_conflict_data->cb_user_data = user_data;
 
@@ -756,14 +484,14 @@ int ip_conflict_unset_callback(gchar *if_name)
        }
 
        ip_conflict_data =
-                       g_hash_table_lookup(ip_conflict_mon.ip_conflict_cb_tbl, if_name);
+                       g_datalist_get_data(&(ip_conflict_mon.ip_conflict_cb_dl), if_name);
        if (!ip_conflict_data) {
                INM_LOGI("ip_conflict_data not found");
                __INM_FUNC_EXIT__;
                return INM_IP_CONFLICT_ERROR_OPERATION_FAILED;
        }
 
-       g_hash_table_remove(ip_conflict_mon.ip_conflict_cb_tbl, ip_conflict_data);
+       g_datalist_remove_data(&(ip_conflict_mon.ip_conflict_cb_dl), if_name);
 
        __INM_FUNC_EXIT__;
        return ret;
@@ -780,11 +508,7 @@ int ip_conflict_detection_init()
        ip_conflict_mon.is_initialized = TRUE;
        ip_conflict_mon.initial_time = MIN_ARP_SEND_TIME;
 
-       ip_conflict_mon.ip_conflict_cb_tbl = g_hash_table_new_full(g_str_hash,
-                       g_str_equal,
-                       g_free,
-                       __destroy_ip_conflict_data
-                       );
+       g_datalist_init(&(ip_conflict_mon.ip_conflict_cb_dl));
 
        __INM_FUNC_EXIT__;
        return ret;
@@ -801,11 +525,13 @@ int ip_conflict_detection_deinit()
                return INM_IP_CONFLICT_ERROR_NOT_INITIALIZED;
        }
 
-       g_hash_table_remove_all(ip_conflict_mon.ip_conflict_cb_tbl);
-       g_hash_table_unref(ip_conflict_mon.ip_conflict_cb_tbl);
+       g_datalist_clear(&(ip_conflict_mon.ip_conflict_cb_dl));
+       //g_hash_table_remove_all(ip_conflict_mon.ip_conflict_cb_tbl);
+       //g_hash_table_unref(ip_conflict_mon.ip_conflict_cb_tbl);
 
        memset(&ip_conflict_mon, 0x00, sizeof(ip_conflict_mon));
 
        __INM_FUNC_EXIT__;
        return ret;
 }
+
index a3fea830b9f2690a5f741b3e6a2826f4843c26a9..885a2010f50a814336fed699721724728c677eef 100644 (file)
@@ -435,7 +435,7 @@ int is_digit(const char* str)
        return 0;
 }
 
-void ip_con_callback(int state, unsigned char *arp_sha, gpointer user_data)
+void ip_con_callback(int state, char *if_name, unsigned char *arp_sha, gpointer user_data)
 {
        printf("User callback IP conflict state[%s] :", print_ip_conflict_state(state));
        if (arp_sha)
@@ -1092,7 +1092,7 @@ void test_inm_statistics_start_monitor()
        int ret = 0;
 
 
-       ret = inm_statistics_start_monitor(__nm_statistics_callback, NULL);
+       ret = inm_statistics_start_monitor(__inm_statistics_callback, NULL);
        if (ret == INM_STATISTICS_ERROR_NONE) {
                printf(MAKE_GREEN"inm_statistics_start_monitor"RESET_COLOR"\n");
        } else {
@@ -1208,7 +1208,7 @@ void test_inm_retry_tx_rate_start_monitor()
 {
        int ret = 0;
 
-       ret = inm_retry_tx_rate_monitor_start(__nm_retry_tx_rate_callback, NULL);
+       ret = inm_retry_tx_rate_monitor_start(__inm_retry_tx_rate_callback, NULL);
        if (ret == INM_MANAGER_ERROR_NONE) {
                printf(MAKE_GREEN"inm_retry_tx_rate_monitor_start"RESET_COLOR"\n");
        } else {
@@ -1243,7 +1243,7 @@ void test_inm_channel_interference_start_monitor()
 {
        int ret = 0;
 
-       ret = inm_channel_interference_monitor_start(__nm_channel_interference_callback, NULL);
+       ret = inm_channel_interference_monitor_start(__inm_channel_interference_callback, NULL);
        if (ret == INM_MANAGER_ERROR_NONE) {
                printf(MAKE_GREEN"inm_channel_interference_monitor_start"RESET_COLOR"\n");
        } else {