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"
36 #define TAG "IP_MONITOR"
39 * @todo Implement network interface monitoring in case the IP changes.
40 * Not critical for win32 bring-up.
42 CAResult_t CAIPStartNetworkMonitor()
48 * @todo Implement network interface monitoring in case the IP changes.
49 * Not critical for win32 bring-up.
51 CAResult_t CAIPStopNetworkMonitor()
57 * @todo Implement network interface monitoring.
58 * Not used in win32, but caipserver currently requires this function
59 * be defined. not critical.
61 int CAGetPollingInterval(int interval)
67 * @todo Implement network interface monitoring.
68 * Not used in win32, but caipserver currently requires this function
69 * be defined. not critical.
71 CAInterface_t *CAFindInterfaceChange()
73 CAInterface_t *foundNewInterface = NULL;
74 return foundNewInterface;
78 * @todo Implement network interface monitoring.
79 * Not critical for win32 bring-up.
81 void CAIPSetNetworkMonitorCallback(CAIPConnectionStateChangeCallback callback)
86 bool IsValidAdapter(PIP_ADAPTER_ADDRESSES pAdapterAddr, int desiredIndex, uint16_t family)
90 // If desiredIndex is non-zero, then only retrieve adapter corresponding to desiredIndex.
91 // If desiredIndex is zero, then retrieve all adapters.
92 if (desiredIndex && (pAdapterAddr->IfIndex != desiredIndex))
94 OIC_LOG_V(DEBUG, TAG, "\t\tInterface %i not interesting.", pAdapterAddr->IfIndex);
98 if (pAdapterAddr->IfType & IF_TYPE_SOFTWARE_LOOPBACK)
100 OIC_LOG_V(DEBUG, TAG, "\t\tInterface %i is loopback.", pAdapterAddr->IfIndex);
104 // If the adapter must support the requested family
105 if ((family == AF_INET6) && ((pAdapterAddr->Flags & IP_ADAPTER_IPV6_ENABLED) == 0))
107 OIC_LOG_V(DEBUG, TAG, "\t\tInterface %i does not support IPv6", pAdapterAddr->IfIndex);
110 else if ((family == AF_INET) && ((pAdapterAddr->Flags & IP_ADAPTER_IPV4_ENABLED) == 0))
112 OIC_LOG_V(DEBUG, TAG, "\t\tInterface %i does not support IPv4", pAdapterAddr->IfIndex);
116 if ((pAdapterAddr->OperStatus & IfOperStatusUp) == 0)
118 OIC_LOG_V(DEBUG, TAG, "\t\tInterface %i is not operational.", pAdapterAddr->IfIndex);
126 bool AddCAInterface(u_arraylist_t *iflist, const char * name, uint32_t index, uint16_t family)
128 bool bSucceeded = false;
129 CAInterface_t *ifitem = (CAInterface_t *)OICCalloc(1, sizeof(*ifitem));
132 OICStrcpy(ifitem->name, INTERFACE_NAME_MAX, name);
133 ifitem->index = index;
134 ifitem->family = family;
135 ifitem->flags |= IFF_UP;// IsValidAddress() will have filtered out non-operational addresses already.
137 if (u_arraylist_add(iflist, ifitem))
143 OIC_LOG(ERROR, TAG, "u_arraylist_add failed");
149 OIC_LOG(ERROR, TAG, "Allocating memory for a CAInterface_t failed");
154 bool AddInterfaces(PIP_ADAPTER_ADDRESSES pAdapterAddr, u_arraylist_t *iflist, int desiredIndex)
156 bool bSucceeded = false;
157 for (PIP_ADAPTER_ADDRESSES pCurAdapterAddr = pAdapterAddr;
158 pCurAdapterAddr != NULL; pCurAdapterAddr = pCurAdapterAddr->Next)
160 OIC_LOG_V(DEBUG, TAG, "\tInterface Index: %u", pCurAdapterAddr->IfIndex);
161 OIC_LOG_V(DEBUG, TAG, "\tInterface name: %s", pCurAdapterAddr->AdapterName);
163 // Prefer IPv6 over IPv4.
164 if (pCurAdapterAddr->Flags & IP_ADAPTER_IPV6_ENABLED)
166 // Do not add loopback, duplicate, or non-operational adapters
167 if (IsValidAdapter(pCurAdapterAddr, desiredIndex, AF_INET6))
169 if (AddCAInterface(iflist, pCurAdapterAddr->AdapterName, pCurAdapterAddr->IfIndex, AF_INET6))
171 OIC_LOG_V(DEBUG, TAG, "\t\tAdded IPv6 interface %i", pCurAdapterAddr->IfIndex);
176 OIC_LOG_V(ERROR, TAG, "\tAdding IPv6 interface %i failed", pCurAdapterAddr->IfIndex);
182 OIC_LOG_V(DEBUG, TAG, "\t\tIPv6 interface %i not valid, skipping...", pCurAdapterAddr->IfIndex);
185 else if (pCurAdapterAddr->Flags & IP_ADAPTER_IPV4_ENABLED)
187 // Do not add loopback, duplicate, or non-operational adapters
188 if (IsValidAdapter(pCurAdapterAddr, desiredIndex, AF_INET))
190 if (AddCAInterface(iflist, pCurAdapterAddr->AdapterName, pCurAdapterAddr->IfIndex, AF_INET))
192 OIC_LOG_V(DEBUG, TAG, "\t\tAdded IPv4 interface %i", pCurAdapterAddr->IfIndex);
197 OIC_LOG_V(ERROR, TAG, "\tAdding IPv4 interface %i failed", pCurAdapterAddr->IfIndex);
203 OIC_LOG_V(DEBUG, TAG, "\t\tIPv6 interface %i not valid, skipping...", pCurAdapterAddr->IfIndex);
211 PIP_ADAPTER_ADDRESSES GetAdapters()
213 ULONG ulOutBufLen = sizeof(IP_ADAPTER_ADDRESSES);
214 PIP_ADAPTER_ADDRESSES pAdapterAddr = (IP_ADAPTER_ADDRESSES *) OICMalloc(ulOutBufLen);
215 if (pAdapterAddr != NULL)
218 ULONG ret = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, pAdapterAddr, &ulOutBufLen);
219 if (ERROR_BUFFER_OVERFLOW == ret)
221 // Redo with updated length
222 OICFree(pAdapterAddr);
223 pAdapterAddr = (PIP_ADAPTER_ADDRESSES) OICMalloc(ulOutBufLen);
224 if (pAdapterAddr != NULL) {
225 ret = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, pAdapterAddr, &ulOutBufLen);
228 OIC_LOG(ERROR, TAG, "GetAdaptersAddresses() failed");
229 OICFree(pAdapterAddr);
234 // Succeeded getting adapters
239 OIC_LOG(ERROR, TAG, "Second time allocating memory for GetAdaptersAddresses() failed");
244 OIC_LOG(ERROR, TAG, "Expected GetAdaptersAddresses() to fail on first try, but it didn't.");
249 OIC_LOG(ERROR, TAG, "First time allocating memory for GetAdaptersAddresses() failed");
254 u_arraylist_t *CAIPGetInterfaceInformation(int desiredIndex)
256 u_arraylist_t *iflist = u_arraylist_create();
259 PIP_ADAPTER_ADDRESSES pAdapterAddr = NULL;
260 pAdapterAddr = GetAdapters();
263 // Cycle through adapters
264 // Add valid adapters to the interface list.
265 bool ret = AddInterfaces(pAdapterAddr, iflist, desiredIndex);
268 OIC_LOG(ERROR, TAG, "AddInterfaces() failed");
269 u_arraylist_destroy(iflist);
273 // Finished with Adapter List
274 OICFree(pAdapterAddr);
278 OIC_LOG(ERROR, TAG, "Enumerating Adapters failed");
279 u_arraylist_destroy(iflist);
285 OIC_LOG(ERROR, TAG, "Failed to create iflist");