1 /* *****************************************************************
3 * Copyright 2016 Intel Corporation
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 ******************************************************************/
21 #include "caipinterface.h"
23 #include <sys/types.h>
28 #include "platform_features.h"
31 #include "caadapterutils.h"
33 #include "oic_malloc.h"
34 #include "oic_string.h"
35 #include "caipnwmonitor.h"
37 #define TAG "IP_MONITOR"
40 * @todo Implement network interface monitoring in case the IP changes.
41 * Not critical for win32 bring-up.
43 CAResult_t CAIPStartNetworkMonitor(CAIPAdapterStateChangeCallback callback,
44 CATransportAdapter_t adapter)
50 * @todo Implement network interface monitoring in case the IP changes.
51 * Not critical for win32 bring-up.
53 CAResult_t CAIPStopNetworkMonitor(CATransportAdapter_t adapter)
60 * @todo Implement network interface monitoring.
61 * Not used in win32, but caipserver currently requires this function
62 * be defined. not critical.
64 int CAGetPollingInterval(int interval)
70 * @todo Implement network interface monitoring.
71 * Not used in win32, but caipserver currently requires this function
72 * be defined. not critical.
74 u_arraylist_t *CAFindInterfaceChange()
76 u_arraylist_t *iflist = NULL;
81 * @todo Implement network interface monitoring.
82 * Not critical for win32 bring-up.
84 CAResult_t CAIPSetNetworkMonitorCallback(CAIPAdapterStateChangeCallback callback,
85 CATransportAdapter_t adapter)
87 return CA_NOT_SUPPORTED;
90 bool IsValidAdapter(PIP_ADAPTER_ADDRESSES pAdapterAddr, int desiredIndex, uint16_t family)
94 // If desiredIndex is non-zero, then only retrieve adapter corresponding to desiredIndex.
95 // If desiredIndex is zero, then retrieve all adapters.
96 if (desiredIndex && (pAdapterAddr->IfIndex != desiredIndex))
98 OIC_LOG_V(DEBUG, TAG, "\t\tInterface %i not interesting.", pAdapterAddr->IfIndex);
102 if (pAdapterAddr->IfType & IF_TYPE_SOFTWARE_LOOPBACK)
104 OIC_LOG_V(DEBUG, TAG, "\t\tInterface %i is loopback.", pAdapterAddr->IfIndex);
108 // If the adapter must support the requested family
109 if ((family == AF_INET6) && ((pAdapterAddr->Flags & IP_ADAPTER_IPV6_ENABLED) == 0))
111 OIC_LOG_V(DEBUG, TAG, "\t\tInterface %i does not support IPv6", pAdapterAddr->IfIndex);
114 else if ((family == AF_INET) && ((pAdapterAddr->Flags & IP_ADAPTER_IPV4_ENABLED) == 0))
116 OIC_LOG_V(DEBUG, TAG, "\t\tInterface %i does not support IPv4", pAdapterAddr->IfIndex);
120 if ((pAdapterAddr->OperStatus & IfOperStatusUp) == 0)
122 OIC_LOG_V(DEBUG, TAG, "\t\tInterface %i is not operational.", pAdapterAddr->IfIndex);
130 bool AddCAInterface(u_arraylist_t *iflist, const char * name, uint32_t index, uint16_t family)
132 bool bSucceeded = false;
133 CAInterface_t *ifitem = (CAInterface_t *)OICCalloc(1, sizeof(*ifitem));
136 OICStrcpy(ifitem->name, INTERFACE_NAME_MAX, name);
137 ifitem->index = index;
138 ifitem->family = family;
139 ifitem->flags |= IFF_UP;// IsValidAddress() will have filtered out non-operational addresses already.
141 if (u_arraylist_add(iflist, ifitem))
147 OIC_LOG(ERROR, TAG, "u_arraylist_add failed");
153 OIC_LOG(ERROR, TAG, "Allocating memory for a CAInterface_t failed");
158 bool AddInterfaces(PIP_ADAPTER_ADDRESSES pAdapterAddr, u_arraylist_t *iflist, int desiredIndex)
160 bool bSucceeded = false;
161 for (PIP_ADAPTER_ADDRESSES pCurAdapterAddr = pAdapterAddr;
162 pCurAdapterAddr != NULL; pCurAdapterAddr = pCurAdapterAddr->Next)
164 OIC_LOG_V(DEBUG, TAG, "\tInterface Index: %u", pCurAdapterAddr->IfIndex);
165 OIC_LOG_V(DEBUG, TAG, "\tInterface name: %s", pCurAdapterAddr->AdapterName);
167 // Prefer IPv6 over IPv4.
168 if (pCurAdapterAddr->Flags & IP_ADAPTER_IPV6_ENABLED)
170 // Do not add loopback, duplicate, or non-operational adapters
171 if (IsValidAdapter(pCurAdapterAddr, desiredIndex, AF_INET6))
173 if (AddCAInterface(iflist, pCurAdapterAddr->AdapterName, pCurAdapterAddr->IfIndex, AF_INET6))
175 OIC_LOG_V(DEBUG, TAG, "\t\tAdded IPv6 interface %i", pCurAdapterAddr->IfIndex);
180 OIC_LOG_V(ERROR, TAG, "\tAdding IPv6 interface %i failed", pCurAdapterAddr->IfIndex);
186 OIC_LOG_V(DEBUG, TAG, "\t\tIPv6 interface %i not valid, skipping...", pCurAdapterAddr->IfIndex);
190 if (pCurAdapterAddr->Flags & IP_ADAPTER_IPV4_ENABLED)
192 // Do not add loopback, duplicate, or non-operational adapters
193 if (IsValidAdapter(pCurAdapterAddr, desiredIndex, AF_INET))
195 if (AddCAInterface(iflist, pCurAdapterAddr->AdapterName, pCurAdapterAddr->IfIndex, AF_INET))
197 OIC_LOG_V(DEBUG, TAG, "\t\tAdded IPv4 interface %i", pCurAdapterAddr->IfIndex);
202 OIC_LOG_V(ERROR, TAG, "\tAdding IPv4 interface %i failed", pCurAdapterAddr->IfIndex);
208 OIC_LOG_V(DEBUG, TAG, "\t\tIPv6 interface %i not valid, skipping...", pCurAdapterAddr->IfIndex);
216 PIP_ADAPTER_ADDRESSES GetAdapters()
218 ULONG ulOutBufLen = sizeof(IP_ADAPTER_ADDRESSES);
219 PIP_ADAPTER_ADDRESSES pAdapterAddr = (IP_ADAPTER_ADDRESSES *) OICMalloc(ulOutBufLen);
220 if (pAdapterAddr != NULL)
223 ULONG ret = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, pAdapterAddr, &ulOutBufLen);
224 if (ERROR_BUFFER_OVERFLOW == ret)
226 // Redo with updated length
227 OICFree(pAdapterAddr);
228 pAdapterAddr = (PIP_ADAPTER_ADDRESSES) OICMalloc(ulOutBufLen);
229 if (pAdapterAddr != NULL) {
230 ret = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, pAdapterAddr, &ulOutBufLen);
233 OIC_LOG(ERROR, TAG, "GetAdaptersAddresses() failed");
234 OICFree(pAdapterAddr);
239 // Succeeded getting adapters
244 OIC_LOG(ERROR, TAG, "Second time allocating memory for GetAdaptersAddresses() failed");
249 OIC_LOG(ERROR, TAG, "Expected GetAdaptersAddresses() to fail on first try, but it didn't.");
254 OIC_LOG(ERROR, TAG, "First time allocating memory for GetAdaptersAddresses() failed");
259 u_arraylist_t *CAIPGetInterfaceInformation(int desiredIndex)
261 u_arraylist_t *iflist = u_arraylist_create();
264 PIP_ADAPTER_ADDRESSES pAdapterAddr = NULL;
265 pAdapterAddr = GetAdapters();
268 // Cycle through adapters
269 // Add valid adapters to the interface list.
270 bool ret = AddInterfaces(pAdapterAddr, iflist, desiredIndex);
273 OIC_LOG(ERROR, TAG, "AddInterfaces() failed");
274 u_arraylist_destroy(iflist);
278 // Finished with Adapter List
279 OICFree(pAdapterAddr);
283 OIC_LOG(ERROR, TAG, "Enumerating Adapters failed");
284 u_arraylist_destroy(iflist);
290 OIC_LOG(ERROR, TAG, "Failed to create iflist");