From: Cheoleun Moon Date: Wed, 24 Apr 2019 08:04:57 +0000 (+0900) Subject: Modify send_arp X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fheads%2Fdrafts%2Ffor%2Ftizen;p=platform%2Fcore%2Fconnectivity%2Fnet-config.git Modify send_arp Change-Id: I66abe1648127e8a690f77418a2fb93b04cfc7f9c Signed-off-by: Cheoleun Moon --- diff --git a/src/ip-conflict-detect.c b/src/ip-conflict-detect.c index 4c2a3f3..958cb7b 100755 --- a/src/ip-conflict-detect.c +++ b/src/ip-conflict-detect.c @@ -59,29 +59,23 @@ 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) diff --git a/src/network-state.c b/src/network-state.c index 428550c..e7af8ad 100755 --- a/src/network-state.c +++ b/src/network-state.c @@ -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 *