Modify send_arp drafts/for/tizen
authorCheoleun Moon <chleun.moon@samsung.com>
Wed, 24 Apr 2019 08:04:57 +0000 (17:04 +0900)
committerCheoleun Moon <chleun.moon@samsung.com>
Wed, 24 Apr 2019 08:06:21 +0000 (17:06 +0900)
Change-Id: I66abe1648127e8a690f77418a2fb93b04cfc7f9c
Signed-off-by: Cheoleun Moon <chleun.moon@samsung.com>
src/ip-conflict-detect.c
src/network-state.c

index 4c2a3f3..958cb7b 100755 (executable)
                hwaddr[2], hwaddr[3], hwaddr[4], hwaddr[5]);\
                } while (0)
 
-struct arp_message {
-       /* Ethernet header */
-       unsigned char   h_dest[MAC_ADDRESS_LENGTH];     /* destination ether addr */
-       unsigned char   h_source[MAC_ADDRESS_LENGTH];   /* source ether addr */
-       unsigned short  h_proto;                                /* packet type ID field */
-
-       /* ARP packet */
-       unsigned short hw_type;                         /* hardware type(ARPHRD_ETHER) */
-       unsigned short p_type;                          /* protocol type(ETH_P_IP) */
-       unsigned char  hw_len;                          /* hardware address length */
-       unsigned char  p_len;                                   /* protocol address length */
-       unsigned short operation;                               /* ARP opcode */
-       unsigned char  s_hwaddr[MAC_ADDRESS_LENGTH];            /* sender hardware address */
-       unsigned char  s_IPaddr[IP_ADDRESS_LENGTH];             /* sender IP address */
-       unsigned char  t_hwaddr[MAC_ADDRESS_LENGTH];            /* target hardware address */
-       unsigned char  t_IPaddr[IP_ADDRESS_LENGTH];             /* target IP address */
-       unsigned char  pad[18];                         /* pad for min. Ethernet payload (60 bytes) */
-};
+
+typedef struct {
+       unsigned short arp_hrd;
+       unsigned short arp_pro;
+       unsigned char arp_hln;
+       unsigned char arp_pln;
+       unsigned short arp_op;
+       unsigned char arp_sha[MAC_ADDRESS_LENGTH];
+       unsigned char arp_sip[IP_ADDRESS_LENGTH];
+       unsigned char arp_tha[MAC_ADDRESS_LENGTH];
+       unsigned char arp_tip[IP_ADDRESS_LENGTH];
+} arp_message_s;
 
 typedef enum {
        NETCONFIG_IP_CONFLICT_STATE_UNKNOWN,
        NETCONFIG_IP_CONFLICT_STATE_CONFLICT_NOT_DETECTED,
-       NETCONFIG_IP_CONFLICT_STATE_CONFLICT_DETECTED
+       NETCONFIG_IP_CONFLICT_STATE_CONFLICT_DETECTED,
 } ip_conflict_state_e;
 
 struct timer_data {
@@ -148,17 +142,18 @@ static gboolean __netconfig_check_arp_receive(GIOChannel *source,
        struct sock_data *sd = data;
        gchar buffer[ARP_PACKET_SIZE] = {0, };
        gsize bytes_read = 0;
-       struct arp_message arp_recv;
+       arp_message_s *arp_recv = NULL;
        char sbuf[WLAN_MAC_ADDR_MAX];
        char tbuf[WLAN_MAC_ADDR_MAX];
        const char *default_ip = NULL;
+       gchar *ptr = NULL;
 
        if (g_io_channel_read_chars(source, buffer, ARP_PACKET_SIZE,
                                &bytes_read, NULL) == G_IO_STATUS_NORMAL) {
                unsigned int target_ip = 0;
 
-               memset(&arp_recv, 0, sizeof(arp_recv));
-               memcpy(&arp_recv, buffer, sizeof(buffer));
+               ptr = buffer + ETH_HLEN;
+               arp_recv = (arp_message_s *)ptr;
 
                default_ip = netconfig_get_default_ipaddress();
                if (default_ip == NULL) {
@@ -169,11 +164,11 @@ static gboolean __netconfig_check_arp_receive(GIOChannel *source,
 
 
                /* Only handle ARP replies */
-               if (arp_recv.operation != htons(ARPOP_REPLY))
+               if (arp_recv->arp_op != htons(ARPOP_REPLY))
                        goto out;
 
-               UCHAR_TO_ADDRESS(arp_recv.t_hwaddr, tbuf);
-               UCHAR_TO_ADDRESS(arp_recv.s_hwaddr, sbuf);
+               UCHAR_TO_ADDRESS(arp_recv->arp_tha, tbuf);
+               UCHAR_TO_ADDRESS(arp_recv->arp_sha, sbuf);
 
                int zero_mac = strcmp(tbuf , GRATUITOUS_ARP_MAC_ADDR);
                if (zero_mac == 0) {
@@ -188,8 +183,8 @@ static gboolean __netconfig_check_arp_receive(GIOChannel *source,
                }
 skip:
                mac_cmp = strcmp(sbuf, netconfig_get_default_mac_address());
-               DBG("target ip = %d source ip = %d", target_ip, __convert_uchar_to_uint(arp_recv.s_IPaddr));
-               if ((mac_cmp != 0) && (__convert_uchar_to_uint(arp_recv.s_IPaddr) == target_ip)) {
+               DBG("target ip = %d source ip = %d", target_ip, __convert_uchar_to_uint(arp_recv->arp_sip));
+               if ((mac_cmp != 0) && (__convert_uchar_to_uint(arp_recv->arp_sip) == target_ip)) {
                        sd->iteration = 0;
                        if (conflict_state != NETCONFIG_IP_CONFLICT_STATE_CONFLICT_DETECTED) {
                                INFO("ip conflict is detected !\n");
@@ -257,100 +252,138 @@ static int __open_channel_and_sock(struct sock_data *sd)
        return 0;
 }
 
-static gboolean send_arp(gpointer data)
+static int __get_iface_info(int *ifindex, unsigned char *mac, unsigned char *ip)
 {
-       struct sock_data *sd = data;
-       struct ether_addr *source_mac = NULL;
-       struct arp_message arp;
-       char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
-       unsigned int source_ip = 0;
-       unsigned int target_ip = 0;
-       const unsigned char broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-       struct sockaddr_ll addr = {0};
        struct ifreq net_ifr;
-       int ifindex = 0;
-       errno = 0;
-       const char *default_ip = NULL;
-       const char *if_name = NULL;
-       static int initial_send_arp_count = 0;
+       int sock = -1;
 
-       if (initial_bursts && initial_send_arp_count >= INITIAL_BURST_ARP_COUNT) {
-               initial_bursts = false;
-               initial_send_arp_count = 0;
+       const char *default_mac = netconfig_get_default_mac_address();
+       if (default_mac == NULL) {
+               ERR("MAC is NULL");
+               return -1;
        }
 
-       if (initial_bursts)
-               initial_send_arp_count++;
-
-       const char *mac = netconfig_get_default_mac_address();
-       if (mac == NULL)
-               goto err;
-       source_mac = ether_aton(mac);
-       if (source_mac == NULL) {
-               INFO("Mac address is NULL");
-               goto err;
+       memcpy(mac, ether_aton(default_mac), MAC_ADDRESS_LENGTH);
+       if (mac == NULL) {
+               ERR("ether_aton fail");
+               return -1;
        }
 
-       memset(&arp, 0, sizeof(arp));
-
-       unsigned char  broadcast_mac_addr[MAC_ADDRESS_LENGTH];
-       memset(broadcast_mac_addr, 0xff, sizeof(broadcast_mac_addr));
-       memcpy(arp.h_dest, broadcast_mac_addr, MAC_ADDRESS_LENGTH);             /* MAC dest */
-       memcpy(arp.h_source, source_mac, MAC_ADDRESS_LENGTH);                   /* MAC source */
-
-       arp.h_proto = htons(ETH_P_ARP);                                         /* protocol type (Ethernet) */
-       arp.hw_type = htons(ARPHRD_ETHER);                                      /* hardware type */
-       arp.p_type = htons(ETH_P_IP);                                           /* protocol type (ARP message) */
-       arp.hw_len = MAC_ADDRESS_LENGTH;                                        /* hardware address length */
-       arp.p_len = IP_ADDRESS_LENGTH;                                          /* protocol address length */
-       arp.operation = htons(ARPOP_REQUEST);                                   /* ARP op code */
-       default_ip = netconfig_get_default_ipaddress();
-       if (default_ip == NULL) {
-               INFO("ip address is not set yet");
-               goto err;
+       ip = netconfig_get_default_ipaddress();
+       if (ip == NULL) {
+               ERR("ip address is not set yet");
+               return -1;
        }
 
-       source_ip = inet_addr(ARP_SOURCE_IP);
-       target_ip = inet_addr(default_ip);
-       memcpy(arp.s_IPaddr, &source_ip, IP_ADDRESS_LENGTH);                    /* source IP address */
-       memcpy(arp.s_hwaddr, source_mac, MAC_ADDRESS_LENGTH);                   /* source hardware address */
-       memcpy(arp.t_IPaddr, &target_ip, IP_ADDRESS_LENGTH);                    /* target IP addressshek" */
-
        memset(&net_ifr, 0, sizeof(net_ifr));
-       /* ifreq structure creation */
        if_name = netconfig_get_default_ifname();
        size_t if_name_len = strlen(if_name);
 
        if (if_name_len == 0) {
-               INFO("Error : Unable to get interface name ");
-               goto err;
+               ERR("Error : Unable to get interface name ");
+               return -1;
        }
 
        if (if_name_len < sizeof(net_ifr.ifr_name)) {
-               memcpy(net_ifr.ifr_name, netconfig_get_default_ifname(), if_name_len);
+               memcpy(net_ifr.ifr_name, if_name, if_name_len);
                net_ifr.ifr_name[if_name_len] = 0;
        } else {
-               INFO("Error : Interface name is too long");
-               goto err;
+               ERR("Error : Interface name is too long");
+               return -1;
        }
 
-       if (ioctl(sd->chk_conflict_sd, SIOCGIFINDEX, &net_ifr) == -1) {
+       if (ioctl(sock, SIOCGIFINDEX, &net_ifr) == -1) {
                INFO("ioctl Failed. Error..... = %s\n",
                                strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
+               return -1;
+       }
+
+       return 0;
+}
+
+static void __init_ll_addr(struct sockaddr_ll *ll_addr, int ifindex, unsigned char *mac)
+{
+       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 = MAC_ADDRESS_LENGTH;
+       ll_addr->sll_addr[6] = 0x00;
+       ll_addr->sll_addr[7] = 0x00;
+       ll_addr->sll_ifindex = ifindex;
+       memcpy(ll_addr->sll_addr, mac, MAC_ADDRESS_LENGTH);
+}
+
+static void __set_defend_arp_ethhdr(unsigned char *hw_addr, struct ethhdr *eh)
+{
+       memset(eh->h_dest, 0xff, MAC_ADDRESS_LENGTH);
+       memcpy(eh->h_source, hw_addr, MAC_ADDRESS_LENGTH);
+       eh->h_proto = htons(ETH_P_ARP);
+       return;
+}
+
+static void __set_defend_arp(unsigned char *hw_addr, unsigned char *ip_addr, arp_message_s *ah)
+{
+       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, hw_addr, 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);
+
+       memset(ah->arp_tha, 0x00, ETH_ALEN);
+
+       memcpy(ah->arp_tip, ip_addr, 4);
+       return;
+}
+
+static gboolean send_arp(gpointer data)
+{
+       struct sock_data *sd = data;
+       char error_buf[MAX_SIZE_ERROR_BUFFER] = {0, };
+       unsigned int source_ip = 0;
+       unsigned int target_ip = 0;
+       struct sockaddr_ll addr = {0};
+       int ifindex = 0;
+       errno = 0;
+       const char *default_ip = NULL;
+       static int initial_send_arp_count = 0;
+       unsigned char buf[60] = {0, };
+       unsigned char *pos = NULL;
+
+       if (initial_bursts && initial_send_arp_count >= INITIAL_BURST_ARP_COUNT) {
+               initial_bursts = false;
+               initial_send_arp_count = 0;
+       }
+
+       if (initial_bursts)
+               initial_send_arp_count++;
+
+       if (__get_iface_info(&ifindex, mac, ip) == -1) {
+               ERR("__get_iface_info fail");
                goto err;
        }
 
-       ifindex = net_ifr.ifr_ifindex;
-       /* Construct the destination address */
-       addr.sll_family = AF_PACKET;
-       addr.sll_ifindex = ifindex;
-       addr.sll_halen = ETHER_ADDR_LEN;
-       addr.sll_protocol = htons(ETH_P_ARP);
-       memcpy(addr.sll_addr, broadcast_addr, ETHER_ADDR_LEN);
-
-       if (sendto(sd->chk_conflict_sd, &arp, sizeof(arp), 0,
-                               (struct sockaddr*)&addr, sizeof(addr)) < 0) {
-               INFO("Sending ARP Packet Failed. Error. = %s\n",
+       pos = buf;
+       __set_defend_arp_ethhdr(source_mac, (struct ethhdr *)pos);
+
+       pos += ETH_HLEN;
+       __set_defend_arp(source_mac, default_ip, (arp_message_s *)pos);
+
+       __init_ll_addr(&addr, ifindex, mac);
+
+       if (sendto(sd->chk_conflict_sd, buf, 42, 0,
+                               (struct sockaddr*)&addr, sizeof(struct sockaddr_ll)) < 0) {
+               ERR("Sending ARP Packet Failed. Error. = %s\n",
                                strerror_r(errno, error_buf, MAX_SIZE_ERROR_BUFFER));
                __close_channel_and_sock(sd);
                if (__open_channel_and_sock(sd) == -1)
index 428550c..e7af8ad 100755 (executable)
@@ -371,6 +371,7 @@ static void __netconfig_get_default_connection_info(const char *profile)
        gchar *key2 = NULL;
        gboolean found_profile = 0;
 
+       DBG("MOON + profile %p", profile);
        message = netconfig_invoke_dbus_method(CONNMAN_SERVICE,
                        CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE,
                        "GetServices", NULL);
@@ -1145,6 +1146,7 @@ void netconfig_update_default_profile(const char *profile)
 {
        static char *old_profile = NULL;
 
+       DBG("MOON + profile %p", profile);
        /* It's automatically updated by signal-handler
         * DO NOT update manually
         *