[connman] Added Tizen Wi-Fi Mesh
[platform/upstream/connman.git] / src / inet.c
index b887aa0..25e5372 100644 (file)
@@ -190,6 +190,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
+
 int connman_inet_ifindex(const char *name)
 {
        struct ifreq ifr;
@@ -330,6 +402,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
+
 struct in6_ifreq {
        struct in6_addr ifr6_addr;
        __u32 ifr6_prefixlen;
@@ -1282,6 +1394,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));
@@ -1381,6 +1523,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("");
 
@@ -1459,6 +1604,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;
@@ -2651,7 +2799,8 @@ char **__connman_inet_get_running_interfaces(void)
 
        g_free(ifr);
 
-       if (count < numif) {
+       if (count < numif)
+       {
                char **prev_result = result;
                result = g_try_realloc(result, (count + 1) * sizeof(char *));
                if (!result) {