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 u_arraylist_t *CAFindInterfaceChange()
66 u_arraylist_t *iflist = NULL;
71 * @todo Implement network interface monitoring.
72 * Not critical for win32 bring-up.
74 CAResult_t CAIPSetNetworkMonitorCallback(CAIPAdapterStateChangeCallback callback,
75 CATransportAdapter_t adapter)
77 return CA_NOT_SUPPORTED;
80 bool IsValidAdapter(PIP_ADAPTER_ADDRESSES pAdapterAddr, int desiredIndex, uint16_t family)
84 // If desiredIndex is non-zero, then only retrieve adapter corresponding to desiredIndex.
85 // If desiredIndex is zero, then retrieve all adapters.
86 if (desiredIndex && (pAdapterAddr->IfIndex != desiredIndex))
88 OIC_LOG_V(DEBUG, TAG, "\t\tInterface %i not interesting.", pAdapterAddr->IfIndex);
92 if (pAdapterAddr->IfType & IF_TYPE_SOFTWARE_LOOPBACK)
94 OIC_LOG_V(DEBUG, TAG, "\t\tInterface %i is loopback.", pAdapterAddr->IfIndex);
98 // If the adapter must support the requested family
99 if ((family == AF_INET6) && ((pAdapterAddr->Flags & IP_ADAPTER_IPV6_ENABLED) == 0))
101 OIC_LOG_V(DEBUG, TAG, "\t\tInterface %i does not support IPv6", pAdapterAddr->IfIndex);
104 else if ((family == AF_INET) && ((pAdapterAddr->Flags & IP_ADAPTER_IPV4_ENABLED) == 0))
106 OIC_LOG_V(DEBUG, TAG, "\t\tInterface %i does not support IPv4", pAdapterAddr->IfIndex);
110 if ((pAdapterAddr->OperStatus & IfOperStatusUp) == 0)
112 OIC_LOG_V(DEBUG, TAG, "\t\tInterface %i is not operational.", pAdapterAddr->IfIndex);
120 bool AddCAInterface(u_arraylist_t *iflist, const char * name, uint32_t index, uint16_t family)
122 bool bSucceeded = false;
123 CAInterface_t *ifitem = (CAInterface_t *)OICCalloc(1, sizeof(*ifitem));
126 OICStrcpy(ifitem->name, INTERFACE_NAME_MAX, name);
127 ifitem->index = index;
128 ifitem->family = family;
129 ifitem->flags |= IFF_UP;// IsValidAddress() will have filtered out non-operational addresses already.
131 if (u_arraylist_add(iflist, ifitem))
137 OIC_LOG(ERROR, TAG, "u_arraylist_add failed");
143 OIC_LOG(ERROR, TAG, "Allocating memory for a CAInterface_t failed");
148 bool AddInterfaces(PIP_ADAPTER_ADDRESSES pAdapterAddr, u_arraylist_t *iflist, int desiredIndex)
150 bool bSucceeded = false;
151 for (PIP_ADAPTER_ADDRESSES pCurAdapterAddr = pAdapterAddr;
152 pCurAdapterAddr != NULL; pCurAdapterAddr = pCurAdapterAddr->Next)
154 OIC_LOG_V(DEBUG, TAG, "\tInterface Index: %u", pCurAdapterAddr->IfIndex);
155 OIC_LOG_V(DEBUG, TAG, "\tInterface name: %s", pCurAdapterAddr->AdapterName);
157 // Prefer IPv6 over IPv4.
158 if (pCurAdapterAddr->Flags & IP_ADAPTER_IPV6_ENABLED)
160 // Do not add loopback, duplicate, or non-operational adapters
161 if (IsValidAdapter(pCurAdapterAddr, desiredIndex, AF_INET6))
163 if (AddCAInterface(iflist, pCurAdapterAddr->AdapterName, pCurAdapterAddr->IfIndex, AF_INET6))
165 OIC_LOG_V(DEBUG, TAG, "\t\tAdded IPv6 interface %i", pCurAdapterAddr->IfIndex);
170 OIC_LOG_V(ERROR, TAG, "\tAdding IPv6 interface %i failed", pCurAdapterAddr->IfIndex);
176 OIC_LOG_V(DEBUG, TAG, "\t\tIPv6 interface %i not valid, skipping...", pCurAdapterAddr->IfIndex);
180 if (pCurAdapterAddr->Flags & IP_ADAPTER_IPV4_ENABLED)
182 // Do not add loopback, duplicate, or non-operational adapters
183 if (IsValidAdapter(pCurAdapterAddr, desiredIndex, AF_INET))
185 if (AddCAInterface(iflist, pCurAdapterAddr->AdapterName, pCurAdapterAddr->IfIndex, AF_INET))
187 OIC_LOG_V(DEBUG, TAG, "\t\tAdded IPv4 interface %i", pCurAdapterAddr->IfIndex);
192 OIC_LOG_V(ERROR, TAG, "\tAdding IPv4 interface %i failed", pCurAdapterAddr->IfIndex);
198 OIC_LOG_V(DEBUG, TAG, "\t\tIPv6 interface %i not valid, skipping...", pCurAdapterAddr->IfIndex);
206 PIP_ADAPTER_ADDRESSES GetAdapters()
208 ULONG ulOutBufLen = sizeof(IP_ADAPTER_ADDRESSES);
209 PIP_ADAPTER_ADDRESSES pAdapterAddr = (IP_ADAPTER_ADDRESSES *) OICMalloc(ulOutBufLen);
210 if (pAdapterAddr != NULL)
213 ULONG ret = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, pAdapterAddr, &ulOutBufLen);
214 if (ERROR_BUFFER_OVERFLOW == ret)
216 // Redo with updated length
217 OICFree(pAdapterAddr);
218 pAdapterAddr = (PIP_ADAPTER_ADDRESSES) OICMalloc(ulOutBufLen);
219 if (pAdapterAddr != NULL) {
220 ret = GetAdaptersAddresses(AF_UNSPEC, flags, NULL, pAdapterAddr, &ulOutBufLen);
223 OIC_LOG(ERROR, TAG, "GetAdaptersAddresses() failed");
224 OICFree(pAdapterAddr);
229 // Succeeded getting adapters
234 OIC_LOG(ERROR, TAG, "Second time allocating memory for GetAdaptersAddresses() failed");
239 OIC_LOG(ERROR, TAG, "Expected GetAdaptersAddresses() to fail on first try, but it didn't.");
244 OIC_LOG(ERROR, TAG, "First time allocating memory for GetAdaptersAddresses() failed");
249 u_arraylist_t *CAIPGetInterfaceInformation(int desiredIndex)
251 u_arraylist_t *iflist = u_arraylist_create();
254 PIP_ADAPTER_ADDRESSES pAdapterAddr = NULL;
255 pAdapterAddr = GetAdapters();
258 // Cycle through adapters
259 // Add valid adapters to the interface list.
260 bool ret = AddInterfaces(pAdapterAddr, iflist, desiredIndex);
263 OIC_LOG(ERROR, TAG, "AddInterfaces() failed");
264 u_arraylist_destroy(iflist);
268 // Finished with Adapter List
269 OICFree(pAdapterAddr);
273 OIC_LOG(ERROR, TAG, "Enumerating Adapters failed");
274 u_arraylist_destroy(iflist);
280 OIC_LOG(ERROR, TAG, "Failed to create iflist");