Imported Upstream version 0.9.2
[platform/upstream/iotivity.git] / resource / csdk / connectivity / src / ip_adapter / linux / caipnwmonitor.c
1 /******************************************************************
2 *
3 * Copyright 2014 Samsung Electronics All Rights Reserved.
4 *
5 *
6 *
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 *      http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 ******************************************************************/
20
21 #include "caipinterface.h"
22
23 #include <sys/types.h>
24 #include <ifaddrs.h>
25 #include <net/if.h>
26 #include <sys/socket.h>
27 #include <netdb.h>
28 #include <string.h>
29 #include <errno.h>
30 #include <unistd.h>
31
32 #include "caadapterutils.h"
33 #include "logger.h"
34 #include "oic_malloc.h"
35 #include "oic_string.h"
36
37 #define TAG "IP_MONITOR"
38
39 u_arraylist_t *CAIPGetInterfaceInformation(int desiredIndex)
40 {
41     u_arraylist_t *iflist = u_arraylist_create();
42     if (!iflist)
43     {
44         OIC_LOG_V(ERROR, TAG, "Failed to create iflist: %s", strerror(errno));
45         return NULL;
46     }
47
48     struct ifaddrs *ifp = NULL;
49     if (-1 == getifaddrs(&ifp))
50     {
51         OIC_LOG_V(ERROR, TAG, "Failed to get ifaddrs: %s", strerror(errno));
52         u_arraylist_destroy(iflist);
53         return NULL;
54     }
55     OIC_LOG(DEBUG, TAG, "Got ifaddrs");
56
57     struct ifaddrs *ifa = NULL;
58     for (ifa = ifp; ifa; ifa = ifa->ifa_next)
59     {
60         int family = ifa->ifa_addr->sa_family;
61         if ((ifa->ifa_flags & IFF_LOOPBACK) || (AF_INET != family && AF_INET6 != family))
62         {
63             continue;
64         }
65
66         int ifindex = if_nametoindex(ifa->ifa_name);
67         if (desiredIndex && (ifindex != desiredIndex))
68         {
69             continue;
70         }
71
72         int length = u_arraylist_length(iflist);
73         int already = false;
74         for (int i = length-1; i >= 0; i--)
75         {
76             CAInterface_t *ifitem = (CAInterface_t *)u_arraylist_get(iflist, i);
77             if (ifitem->index == ifindex && ifitem->family == family)
78             {
79                 already = true;
80                 break;
81             }
82         }
83         if (already)
84         {
85             continue;
86         }
87
88         CAInterface_t *ifitem = (CAInterface_t *)OICCalloc(1, sizeof(CAInterface_t));
89         if (!ifitem)
90         {
91             OIC_LOG(ERROR, TAG, "Malloc failed");
92             goto exit;
93         }
94
95         OICStrcpy(ifitem->name, INTERFACE_NAME_MAX, ifa->ifa_name);
96         ifitem->index = ifindex;
97         ifitem->family = family;
98         ifitem->ipv4addr = ((struct sockaddr_in *)(ifa->ifa_addr))->sin_addr.s_addr;
99         ifitem->flags = ifa->ifa_flags;
100
101         CAResult_t result = u_arraylist_add(iflist, ifitem);
102         if (CA_STATUS_OK != result)
103         {
104             OIC_LOG(ERROR, TAG, "u_arraylist_add failed.");
105             goto exit;
106         }
107
108         OIC_LOG_V(ERROR, TAG, "Added interface: %s (%d)", ifitem->name, family);
109     }
110
111     freeifaddrs(ifp);
112     return iflist;
113
114 exit:
115     freeifaddrs(ifp);
116     u_arraylist_destroy(iflist);
117     return NULL;
118 }