Merge tag 'upstream/1.40' into tizen.
[platform/upstream/connman.git] / src / inet.c
index df94d1e..268dc51 100644 (file)
@@ -196,6 +196,78 @@ done:
        return err;
 }
 
+#if defined TIZEN_EXT_WIFI_MESH
+char *connman_inet_ifaddr(const char *name)
+{
+       struct ifreq ifr;
+       struct ether_addr eth;
+       char *str;
+       int sk, err;
+
+       sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+       if (sk < 0)
+               return NULL;
+
+       strncpy(ifr.ifr_name, name, IFNAMSIZ-1);
+
+       err = ioctl(sk, SIOCGIFHWADDR, &ifr);
+       close(sk);
+
+       if (err < 0)
+               return NULL;
+
+       str = g_malloc(18);
+       if (!str)
+               return NULL;
+
+       memcpy(&eth, &ifr.ifr_hwaddr.sa_data, sizeof(eth));
+       snprintf(str, 13, "%02x%02x%02x%02x%02x%02x",
+                                               eth.ether_addr_octet[0],
+                                               eth.ether_addr_octet[1],
+                                               eth.ether_addr_octet[2],
+                                               eth.ether_addr_octet[3],
+                                               eth.ether_addr_octet[4],
+                                               eth.ether_addr_octet[5]);
+
+       return str;
+}
+
+char *connman_inet_ifname2addr(const char *name)
+{
+       struct ifreq ifr;
+       struct ether_addr eth;
+       char *str;
+       int sk, err;
+
+       sk = socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0);
+       if (sk < 0)
+               return NULL;
+
+       strncpy(ifr.ifr_name, name, IFNAMSIZ-1);
+
+       err = ioctl(sk, SIOCGIFHWADDR, &ifr);
+       close(sk);
+
+       if (err < 0)
+               return NULL;
+
+       str = g_malloc(18);
+       if (!str)
+               return NULL;
+
+       memcpy(&eth, &ifr.ifr_hwaddr.sa_data, sizeof(eth));
+       snprintf(str, 18, "%02x:%02x:%02x:%02x:%02x:%02x",
+                                               eth.ether_addr_octet[0],
+                                               eth.ether_addr_octet[1],
+                                               eth.ether_addr_octet[2],
+                                               eth.ether_addr_octet[3],
+                                               eth.ether_addr_octet[4],
+                                               eth.ether_addr_octet[5]);
+
+       return str;
+}
+#endif
+
 static bool is_addr_unspec(int family, struct sockaddr *addr)
 {
        struct sockaddr_in *in4;
@@ -396,6 +468,46 @@ done:
        return err;
 }
 
+#if defined TIZEN_EXT
+void connman_inet_update_device_ident(struct connman_device *device)
+{
+       int index;
+       enum connman_device_type type;
+       char *ident = NULL, *addr = NULL;
+
+       index = connman_device_get_index(device);
+       type = connman_device_get_type(device);
+
+       switch (type) {
+       case CONNMAN_DEVICE_TYPE_UNKNOWN:
+               return;
+       case CONNMAN_DEVICE_TYPE_ETHERNET:
+       case CONNMAN_DEVICE_TYPE_GADGET:
+       case CONNMAN_DEVICE_TYPE_WIFI:
+               addr = index2addr(index);
+               ident = index2ident(index, NULL);
+               break;
+       case CONNMAN_DEVICE_TYPE_CELLULAR:
+               ident = index2ident(index, NULL);
+               break;
+       case CONNMAN_DEVICE_TYPE_BLUETOOTH:
+       case CONNMAN_DEVICE_TYPE_GPS:
+       case CONNMAN_DEVICE_TYPE_VENDOR:
+               break;
+       }
+
+       if (ident != NULL) {
+               connman_device_set_ident(device, ident);
+               g_free(ident);
+       }
+
+       if (addr != NULL) {
+               connman_device_set_string(device, "Address", addr);
+               g_free(addr);
+       }
+}
+#endif
+
 bool connman_inet_is_ifup(int index)
 {
        int sk;
@@ -1556,6 +1668,36 @@ static int icmpv6_recv(int fd, struct xs_cb_data *data)
                return -errno;
        }
 
+#if defined TIZEN_EXT
+       /* Set Received Source Address from router as IPv6 Gateway Address */
+       char src_addr[INET6_ADDRSTRLEN];
+       if(inet_ntop(AF_INET6, &(saddr.sin6_addr), src_addr, INET6_ADDRSTRLEN)
+                       == NULL)
+               return -errno;
+
+       DBG("Received Source Address %s from router", src_addr);
+
+       /* icmpv6_recv() function can be called in two scenarios :
+        * 1. When __connman_inet_ipv6_send_rs() is called from check_dhcpv6()
+        * 2. When __connman_inet_ipv6_send_rs() is called from
+        * __connman_6to4_probe()
+        * In the second case it is not  required to set DHCPv6 Gateway  Address
+        * as DHCPv6 was not started and  network structure was not passed as
+        * user_data. If it is tried  to add Source Address as  Gateway Address
+        * then it will lead to  crash because of  user_data being ip_address
+        * instead of network structure. So Adding Gateway Address in case 1st
+        * case only.
+        */
+       char *address = data->user_data;
+       int err = 0;
+       unsigned char buffer[sizeof(struct in6_addr)] = {0, };
+       /* Checking if user_data is an ip_address */
+       err = inet_pton(AF_INET, address, buffer);
+       /* Setting Received Source Address from
+        * router as Gateway Address */
+       if(err <= 0)
+               __connman_network_set_auto_ipv6_gateway(src_addr, data->user_data);
+#endif
        hdr = (struct nd_router_advert *)buf;
        DBG("code %d len %zd hdr %zd", hdr->nd_ra_code, len,
                                sizeof(struct nd_router_advert));
@@ -1655,6 +1797,9 @@ static int ndisc_send_unspec(int type, int oif, const struct in6_addr *dest,
        char cbuf[CMSG_SPACE(sizeof(*pinfo))];
        struct iovec iov[2];
        int fd, datalen, ret, iovlen = 1;
+#if defined TIZEN_EXT
+       char ebuf[256];
+#endif
 
        DBG("");
 
@@ -1733,6 +1878,9 @@ static int ndisc_send_unspec(int type, int oif, const struct in6_addr *dest,
        msgh.msg_controllen = cmsg->cmsg_len;
 
        ret = sendmsg(fd, &msgh, 0);
+#if defined TIZEN_EXT
+       DBG("sendmsg errno: %d/%s", errno, strerror_r(errno, ebuf, sizeof(ebuf)));
+#endif
 
        close(fd);
        return ret;