1 /*- 2 * Copyright (c) 2011-2012 Irene Ruengeler 3 * Copyright (c) 2011-2012 Michael Tuexen 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * 27 */ 28 29 30 #ifdef _WIN32 31 #include <netinet/sctp_pcb.h> 32 #include <sys/timeb.h> 33 #include <iphlpapi.h> 34 #pragma comment(lib, "IPHLPAPI.lib") 35 #endif 36 #include <netinet/sctp_os_userspace.h> 37 38 #ifndef _WIN32 39 int 40 sctp_userspace_get_mtu_from_ifn(uint32_t if_index, int af) 41 { 42 struct ifreq ifr; 43 int fd; 44 45 if_indextoname(if_index, ifr.ifr_name); 46 /* TODO can I use the raw socket here and not have to open a new one with each query? */ 47 if ((fd = socket(af, SOCK_DGRAM, 0)) < 0) 48 return (0); 49 if (ioctl(fd, SIOCGIFMTU, &ifr) < 0) { 50 close(fd); 51 return (0); 52 } 53 close(fd); 54 return ifr.ifr_mtu; 55 } 56 #endif 57 58 #ifdef _WIN32 59 int 60 sctp_userspace_get_mtu_from_ifn(uint32_t if_index, int af) 61 { 62 PIP_ADAPTER_ADDRESSES pAdapterAddrs, pAdapt; 63 DWORD AdapterAddrsSize, Err; 64 65 AdapterAddrsSize = 0; 66 if ((Err = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, NULL, &AdapterAddrsSize)) != 0) { 67 if ((Err != ERROR_BUFFER_OVERFLOW) && (Err != ERROR_INSUFFICIENT_BUFFER)) { 68 SCTPDBG(SCTP_DEBUG_USR, "GetAdaptersAddresses() sizing failed with error code %d, AdapterAddrsSize = %d\n", Err, AdapterAddrsSize); 69 return (-1); 70 } 71 } 72 if ((pAdapterAddrs = (PIP_ADAPTER_ADDRESSES) GlobalAlloc(GPTR, AdapterAddrsSize)) == NULL) { 73 SCTPDBG(SCTP_DEBUG_USR, "Memory allocation error!\n"); 74 return (-1); 75 } 76 if ((Err = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, pAdapterAddrs, &AdapterAddrsSize)) != ERROR_SUCCESS) { 77 SCTPDBG(SCTP_DEBUG_USR, "GetAdaptersAddresses() failed with error code %d\n", Err); 78 return (-1); 79 } 80 for (pAdapt = pAdapterAddrs; pAdapt; pAdapt = pAdapt->Next) { 81 if (pAdapt->IfIndex == if_index) 82 return (pAdapt->Mtu); 83 } 84 return (0); 85 } 86 87 void 88 getwintimeofday(struct timeval *tv) 89 { 90 struct timeb tb; 91 92 ftime(&tb); 93 tv->tv_sec = tb.time; 94 tv->tv_usec = tb.millitm * 1000; 95 } 96 97 int 98 Win_getifaddrs(struct ifaddrs** interfaces) 99 { 100 #if defined(INET) || defined(INET6) 101 DWORD Err, AdapterAddrsSize; 102 int count; 103 PIP_ADAPTER_ADDRESSES pAdapterAddrs, pAdapt; 104 struct ifaddrs *ifa; 105 #endif 106 #if defined(INET) 107 struct sockaddr_in *addr; 108 #endif 109 #if defined(INET6) 110 struct sockaddr_in6 *addr6; 111 #endif 112 #if defined(INET) || defined(INET6) 113 count = 0; 114 #endif 115 #if defined(INET) 116 AdapterAddrsSize = 0; 117 if ((Err = GetAdaptersAddresses(AF_INET, 0, NULL, NULL, &AdapterAddrsSize)) != 0) { 118 if ((Err != ERROR_BUFFER_OVERFLOW) && (Err != ERROR_INSUFFICIENT_BUFFER)) { 119 SCTPDBG(SCTP_DEBUG_USR, "GetAdaptersV4Addresses() sizing failed with error code %d and AdapterAddrsSize = %d\n", Err, AdapterAddrsSize); 120 return (-1); 121 } 122 } 123 /* Allocate memory from sizing information */ 124 if ((pAdapterAddrs = (PIP_ADAPTER_ADDRESSES) GlobalAlloc(GPTR, AdapterAddrsSize)) == NULL) { 125 SCTPDBG(SCTP_DEBUG_USR, "Memory allocation error!\n"); 126 return (-1); 127 } 128 /* Get actual adapter information */ 129 if ((Err = GetAdaptersAddresses(AF_INET, 0, NULL, pAdapterAddrs, &AdapterAddrsSize)) != ERROR_SUCCESS) { 130 SCTPDBG(SCTP_DEBUG_USR, "GetAdaptersV4Addresses() failed with error code %d\n", Err); 131 return (-1); 132 } 133 /* Enumerate through each returned adapter and save its information */ 134 for (pAdapt = pAdapterAddrs, count; pAdapt; pAdapt = pAdapt->Next, count++) { 135 addr = (struct sockaddr_in *)malloc(sizeof(struct sockaddr_in)); 136 ifa = (struct ifaddrs *)malloc(sizeof(struct ifaddrs)); 137 if ((addr == NULL) || (ifa == NULL)) { 138 SCTPDBG(SCTP_DEBUG_USR, "Can't allocate memory\n"); 139 return (-1); 140 } 141 ifa->ifa_name = strdup(pAdapt->AdapterName); 142 ifa->ifa_flags = pAdapt->Flags; 143 ifa->ifa_addr = (struct sockaddr *)addr; 144 memcpy(&addr, &pAdapt->FirstUnicastAddress->Address.lpSockaddr, sizeof(struct sockaddr_in)); 145 interfaces[count] = ifa; 146 } 147 #endif 148 #if defined(INET6) 149 if (SCTP_BASE_VAR(userspace_rawsctp6) != -1) { 150 AdapterAddrsSize = 0; 151 if ((Err = GetAdaptersAddresses(AF_INET6, 0, NULL, NULL, &AdapterAddrsSize)) != 0) { 152 if ((Err != ERROR_BUFFER_OVERFLOW) && (Err != ERROR_INSUFFICIENT_BUFFER)) { 153 SCTPDBG(SCTP_DEBUG_USR, "GetAdaptersV6Addresses() sizing failed with error code %d AdapterAddrsSize = %d\n", Err, AdapterAddrsSize); 154 return (-1); 155 } 156 } 157 /* Allocate memory from sizing information */ 158 if ((pAdapterAddrs = (PIP_ADAPTER_ADDRESSES) GlobalAlloc(GPTR, AdapterAddrsSize)) == NULL) { 159 SCTPDBG(SCTP_DEBUG_USR, "Memory allocation error!\n"); 160 return (-1); 161 } 162 /* Get actual adapter information */ 163 if ((Err = GetAdaptersAddresses(AF_INET6, 0, NULL, pAdapterAddrs, &AdapterAddrsSize)) != ERROR_SUCCESS) { 164 SCTPDBG(SCTP_DEBUG_USR, "GetAdaptersV6Addresses() failed with error code %d\n", Err); 165 return (-1); 166 } 167 /* Enumerate through each returned adapter and save its information */ 168 for (pAdapt = pAdapterAddrs, count; pAdapt; pAdapt = pAdapt->Next, count++) { 169 addr6 = (struct sockaddr_in6 *)malloc(sizeof(struct sockaddr_in6)); 170 ifa = (struct ifaddrs *)malloc(sizeof(struct ifaddrs)); 171 if ((addr6 == NULL) || (ifa == NULL)) { 172 SCTPDBG(SCTP_DEBUG_USR, "Can't allocate memory\n"); 173 return (-1); 174 } 175 ifa->ifa_name = strdup(pAdapt->AdapterName); 176 ifa->ifa_flags = pAdapt->Flags; 177 ifa->ifa_addr = (struct sockaddr *)addr6; 178 memcpy(&addr6, &pAdapt->FirstUnicastAddress->Address.lpSockaddr, sizeof(struct sockaddr_in6)); 179 interfaces[count] = ifa; 180 } 181 } 182 #endif 183 return (0); 184 } 185 186 int 187 win_if_nametoindex(const char *ifname) 188 { 189 IP_ADAPTER_ADDRESSES *addresses, *addr; 190 ULONG status, size; 191 int index = 0; 192 193 if (!ifname) { 194 return 0; 195 } 196 197 size = 0; 198 status = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, NULL, &size); 199 if (status != ERROR_BUFFER_OVERFLOW) { 200 return 0; 201 } 202 addresses = malloc(size); 203 status = GetAdaptersAddresses(AF_UNSPEC, 0, NULL, addresses, &size); 204 if (status == ERROR_SUCCESS) { 205 for (addr = addresses; addr; addr = addr->Next) { 206 if (addr->AdapterName && !strcmp(ifname, addr->AdapterName)) { 207 index = addr->IfIndex; 208 break; 209 } 210 } 211 } 212 213 free(addresses); 214 return index; 215 } 216 217 #if WINVER < 0x0600 218 /* These functions are written based on the code at 219 * http://www.cs.wustl.edu/~schmidt/win32-cv-1.html 220 * Therefore, for the rest of the file the following applies: 221 * 222 * 223 * Copyright and Licensing Information for ACE(TM), TAO(TM), CIAO(TM), 224 * DAnCE(TM), and CoSMIC(TM) 225 * 226 * [1]ACE(TM), [2]TAO(TM), [3]CIAO(TM), DAnCE(TM), and [4]CoSMIC(TM) 227 * (henceforth referred to as "DOC software") are copyrighted by 228 * [5]Douglas C. Schmidt and his [6]research group at [7]Washington 229 * University, [8]University of California, Irvine, and [9]Vanderbilt 230 * University, Copyright (c) 1993-2012, all rights reserved. Since DOC 231 * software is open-source, freely available software, you are free to 232 * use, modify, copy, and distribute--perpetually and irrevocably--the 233 * DOC software source code and object code produced from the source, as 234 * well as copy and distribute modified versions of this software. You 235 * must, however, include this copyright statement along with any code 236 * built using DOC software that you release. No copyright statement 237 * needs to be provided if you just ship binary executables of your 238 * software products. 239 * 240 * You can use DOC software in commercial and/or binary software releases 241 * and are under no obligation to redistribute any of your source code 242 * that is built using DOC software. Note, however, that you may not 243 * misappropriate the DOC software code, such as copyrighting it yourself 244 * or claiming authorship of the DOC software code, in a way that will 245 * prevent DOC software from being distributed freely using an 246 * open-source development model. You needn't inform anyone that you're 247 * using DOC software in your software, though we encourage you to let 248 * [10]us know so we can promote your project in the [11]DOC software 249 * success stories. 250 * 251 * The [12]ACE, [13]TAO, [14]CIAO, [15]DAnCE, and [16]CoSMIC web sites 252 * are maintained by the [17]DOC Group at the [18]Institute for Software 253 * Integrated Systems (ISIS) and the [19]Center for Distributed Object 254 * Computing of Washington University, St. Louis for the development of 255 * open-source software as part of the open-source software community. 256 * Submissions are provided by the submitter ``as is'' with no warranties 257 * whatsoever, including any warranty of merchantability, noninfringement 258 * of third party intellectual property, or fitness for any particular 259 * purpose. In no event shall the submitter be liable for any direct, 260 * indirect, special, exemplary, punitive, or consequential damages, 261 * including without limitation, lost profits, even if advised of the 262 * possibility of such damages. Likewise, DOC software is provided as is 263 * with no warranties of any kind, including the warranties of design, 264 * merchantability, and fitness for a particular purpose, 265 * noninfringement, or arising from a course of dealing, usage or trade 266 * practice. Washington University, UC Irvine, Vanderbilt University, 267 * their employees, and students shall have no liability with respect to 268 * the infringement of copyrights, trade secrets or any patents by DOC 269 * software or any part thereof. Moreover, in no event will Washington 270 * University, UC Irvine, or Vanderbilt University, their employees, or 271 * students be liable for any lost revenue or profits or other special, 272 * indirect and consequential damages. 273 * 274 * DOC software is provided with no support and without any obligation on 275 * the part of Washington University, UC Irvine, Vanderbilt University, 276 * their employees, or students to assist in its use, correction, 277 * modification, or enhancement. A [20]number of companies around the 278 * world provide commercial support for DOC software, however. DOC 279 * software is Y2K-compliant, as long as the underlying OS platform is 280 * Y2K-compliant. Likewise, DOC software is compliant with the new US 281 * daylight savings rule passed by Congress as "The Energy Policy Act of 282 * 2005," which established new daylight savings times (DST) rules for 283 * the United States that expand DST as of March 2007. Since DOC software 284 * obtains time/date and calendaring information from operating systems 285 * users will not be affected by the new DST rules as long as they 286 * upgrade their operating systems accordingly. 287 * 288 * The names ACE(TM), TAO(TM), CIAO(TM), DAnCE(TM), CoSMIC(TM), 289 * Washington University, UC Irvine, and Vanderbilt University, may not 290 * be used to endorse or promote products or services derived from this 291 * source without express written permission from Washington University, 292 * UC Irvine, or Vanderbilt University. This license grants no permission 293 * to call products or services derived from this source ACE(TM), 294 * TAO(TM), CIAO(TM), DAnCE(TM), or CoSMIC(TM), nor does it grant 295 * permission for the name Washington University, UC Irvine, or 296 * Vanderbilt University to appear in their names. 297 * 298 * If you have any suggestions, additions, comments, or questions, please 299 * let [21]me know. 300 * 301 * [22]Douglas C. Schmidt 302 * 303 * References 304 * 305 * 1. http://www.cs.wustl.edu/~schmidt/ACE.html 306 * 2. http://www.cs.wustl.edu/~schmidt/TAO.html 307 * 3. http://www.dre.vanderbilt.edu/CIAO/ 308 * 4. http://www.dre.vanderbilt.edu/cosmic/ 309 * 5. http://www.dre.vanderbilt.edu/~schmidt/ 310 * 6. http://www.cs.wustl.edu/~schmidt/ACE-members.html 311 * 7. http://www.wustl.edu/ 312 * 8. http://www.uci.edu/ 313 * 9. http://www.vanderbilt.edu/ 314 * 10. mailto:doc_group (at) cs.wustl.edu 315 * 11. http://www.cs.wustl.edu/~schmidt/ACE-users.html 316 * 12. http://www.cs.wustl.edu/~schmidt/ACE.html 317 * 13. http://www.cs.wustl.edu/~schmidt/TAO.html 318 * 14. http://www.dre.vanderbilt.edu/CIAO/ 319 * 15. http://www.dre.vanderbilt.edu/~schmidt/DOC_ROOT/DAnCE/ 320 * 16. http://www.dre.vanderbilt.edu/cosmic/ 321 * 17. http://www.dre.vanderbilt.edu/ 322 * 18. http://www.isis.vanderbilt.edu/ 323 * 19. http://www.cs.wustl.edu/~schmidt/doc-center.html 324 * 20. http://www.cs.wustl.edu/~schmidt/commercial-support.html 325 * 21. mailto:d.schmidt (at) vanderbilt.edu 326 * 22. http://www.dre.vanderbilt.edu/~schmidt/ 327 * 23. http://www.cs.wustl.edu/ACE.html 328 */ 329 330 void 331 InitializeXPConditionVariable(userland_cond_t *cv) 332 { 333 cv->waiters_count = 0; 334 InitializeCriticalSection(&(cv->waiters_count_lock)); 335 cv->events_[C_SIGNAL] = CreateEvent (NULL, FALSE, FALSE, NULL); 336 cv->events_[C_BROADCAST] = CreateEvent (NULL, TRUE, FALSE, NULL); 337 } 338 339 void 340 DeleteXPConditionVariable(userland_cond_t *cv) 341 { 342 CloseHandle(cv->events_[C_BROADCAST]); 343 CloseHandle(cv->events_[C_SIGNAL]); 344 DeleteCriticalSection(&(cv->waiters_count_lock)); 345 } 346 347 int 348 SleepXPConditionVariable(userland_cond_t *cv, userland_mutex_t *mtx) 349 { 350 int result, last_waiter; 351 352 EnterCriticalSection(&cv->waiters_count_lock); 353 cv->waiters_count++; 354 LeaveCriticalSection(&cv->waiters_count_lock); 355 LeaveCriticalSection (mtx); 356 result = WaitForMultipleObjects(2, cv->events_, FALSE, INFINITE); 357 if (result==-1) { 358 result = GetLastError(); 359 } 360 EnterCriticalSection(&cv->waiters_count_lock); 361 cv->waiters_count--; 362 last_waiter = 363 result == (C_SIGNAL + C_BROADCAST && (cv->waiters_count == 0)); 364 LeaveCriticalSection(&cv->waiters_count_lock); 365 if (last_waiter) 366 ResetEvent(cv->events_[C_BROADCAST]); 367 EnterCriticalSection (mtx); 368 return result; 369 } 370 371 void 372 WakeAllXPConditionVariable(userland_cond_t *cv) 373 { 374 int have_waiters; 375 EnterCriticalSection(&cv->waiters_count_lock); 376 have_waiters = cv->waiters_count > 0; 377 LeaveCriticalSection(&cv->waiters_count_lock); 378 if (have_waiters) 379 SetEvent (cv->events_[C_BROADCAST]); 380 } 381 #endif 382 #endif 383