DWORD SrvConOpen(PWCHAR Host, PWCHAR Port, PSRV_CON *pSrvCon) { SOCKET Socket; DWORD Err; ADDRINFOW Hints, *AddrInfo; PSRV_CON SrvCon; int OptVal; SrvCon = malloc(sizeof(*SrvCon)); if (!SrvCon) return FB_E_NO_MEMORY; memset(SrvCon, 0, sizeof(*SrvCon)); memset(&Hints, 0, sizeof(Hints)); Hints.ai_family = AF_INET; Hints.ai_socktype = SOCK_STREAM; Hints.ai_protocol = IPPROTO_TCP; Hints.ai_flags = AI_PASSIVE; if (GetAddrInfoW(Host, Port, &Hints, &AddrInfo)) { Err = WSAGetLastError(); printf("GetAddrInfoW failed Error %d\n", Err); free(SrvCon); return Err; } Socket = socket(AddrInfo->ai_family, AddrInfo->ai_socktype, AddrInfo->ai_protocol); if (Socket == INVALID_SOCKET) { Err = WSAGetLastError(); FreeAddrInfoW(AddrInfo); free(SrvCon); return Err; } OptVal = 1; if (setsockopt(Socket, SOL_SOCKET, SO_REUSEADDR, (char *) &OptVal, sizeof (OptVal))) { Err = WSAGetLastError(); printf("socket connect failed Error %d\n", Err); FreeAddrInfoW(AddrInfo); closesocket(Socket); free(SrvCon); return Err; } if (connect(Socket, AddrInfo->ai_addr, (int)AddrInfo->ai_addrlen)) { Err = WSAGetLastError(); printf("socket connect failed Error %d\n", Err); FreeAddrInfoW(AddrInfo); closesocket(Socket); free(SrvCon); return Err; } SrvCon->Socket = Socket; *pSrvCon = SrvCon; return 0; }
BOOL GetAddress(const WCHAR *name, INTERNET_PORT port, struct sockaddr *psa, int *sa_len, char *addr_str) { ADDRINFOW *res, hints; void *addr = NULL; int ret; TRACE("%s\n", debugstr_w(name)); memset( &hints, 0, sizeof(hints) ); /* Prefer IPv4 to IPv6 addresses, since some servers do not listen on * their IPv6 addresses even though they have IPv6 addresses in the DNS. */ hints.ai_family = AF_INET; ret = GetAddrInfoW(name, NULL, &hints, &res); if (ret != 0) { TRACE("failed to get IPv4 address of %s, retrying with IPv6\n", debugstr_w(name)); hints.ai_family = AF_INET6; ret = GetAddrInfoW(name, NULL, &hints, &res); } if (ret != 0) { TRACE("failed to get address of %s\n", debugstr_w(name)); return FALSE; } if (*sa_len < res->ai_addrlen) { WARN("address too small\n"); FreeAddrInfoW(res); return FALSE; } *sa_len = res->ai_addrlen; memcpy( psa, res->ai_addr, res->ai_addrlen ); /* Copy port */ switch (res->ai_family) { case AF_INET: addr = &((struct sockaddr_in *)psa)->sin_addr; ((struct sockaddr_in *)psa)->sin_port = htons(port); break; case AF_INET6: addr = &((struct sockaddr_in6 *)psa)->sin6_addr; ((struct sockaddr_in6 *)psa)->sin6_port = htons(port); break; } if(addr_str) inet_ntop(res->ai_family, addr, addr_str, INET6_ADDRSTRLEN); FreeAddrInfoW(res); return TRUE; }
int make_serv_sock(SERVINFO *servinfo, int servinfonum) { ADDRINFOW aiwHints; ADDRINFOW *paiwResult; ADDRINFOW *paiw; int i; BOOL use = TRUE; ZeroMemory(&aiwHints, sizeof(aiwHints)); if(!serv_loopback) { aiwHints.ai_flags = AI_PASSIVE; } aiwHints.ai_family = AF_UNSPEC; aiwHints.ai_socktype = SOCK_STREAM; aiwHints.ai_protocol = IPPROTO_TCP; if(GetAddrInfoW(nullptr, serv_port, &aiwHints, &paiwResult) != 0) { return 0; } for(i = 0, paiw = paiwResult; i < servinfonum, paiw != nullptr; paiw = paiw->ai_next) { servinfo[i].sock = socket(paiw->ai_family, paiw->ai_socktype, paiw->ai_protocol); if(servinfo[i].sock == INVALID_SOCKET) { continue; } if(setsockopt(servinfo[i].sock, SOL_SOCKET, SO_REUSEADDR, (const char *)&use, sizeof(use)) == SOCKET_ERROR) { disconnect(servinfo[i].sock); continue; } if(bind(servinfo[i].sock, paiw->ai_addr, (int)paiw->ai_addrlen) == SOCKET_ERROR) { disconnect(servinfo[i].sock); continue; } if(listen(servinfo[i].sock, 1) == SOCKET_ERROR) { disconnect(servinfo[i].sock); continue; } servinfo[i].live = TRUE; i++; } FreeAddrInfoW(paiwResult); return i; }
bool SimpleSocket::InitializeSocket(std::wstring server, std::wstring port) { //0 for success, 1 for error //Initialize the variables...Maybe not neccessary TheSocket = INVALID_SOCKET; ptr = NULL; result = NULL; int iResult; iResult = WSAStartup(MAKEWORD(2,2), &wsaData); if (iResult != 0) { onSysMsg(L"WSAStartup failed: %d", iResult); return 1; iStatus=SOCKET_CLOSED; } struct addrinfoW hints; ZeroMemory( &hints, sizeof(hints) ); hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; iResult = GetAddrInfoW(server.c_str(), port.c_str(), &hints, &result); if (iResult != 0) { onSysMsg(L"GetAddrInfoW failed: %d", iResult); WSACleanup(); iStatus=SOCKET_CLOSED; return 1; } // Attempt to connect to the first address returned by // the call to GetAddrInfoW ptr=result; // Create a SOCKET for connecting to server TheSocket = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol); if (TheSocket == INVALID_SOCKET) { onSysMsg(L"Error at socket(): %d", WSAGetLastError()); FreeAddrInfoW(result); WSACleanup(); iStatus=SOCKET_CLOSED; return 1; } DWORD RCVTIMEO=15000; iResult = setsockopt(TheSocket, SOL_SOCKET, SO_RCVTIMEO, (char *) &RCVTIMEO, sizeof(DWORD)); iStatus=SOCKET_INITIALIZED; return 0; }
//****************************************************************************** // Routine: // GetSockAddrFromString // // Arguments: // strAddress - Address in the String format // pSocketAddress - Pointer to SOCKADDR_STORAGE structure where the // address is returned // // Description: // Takes a string format address and returns a pointer to // SOCKADDR_STORAGE structure containing the address. // Only resolves numeric addresses //****************************************************************************** BOOL GetSockAddrFromString(const WCHAR *strAddress, PSOCKADDR_STORAGE pSocketAddress) { BOOL result = FALSE; ADDRINFOW *pAddress = NULL; int wsaResult = 0; ADDRINFOW hints; ZeroMemory(&hints, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_flags = AI_NUMERICHOST; // Resolve the address wsaResult = GetAddrInfoW(strAddress, NULL, &hints, &pAddress); if (0 != wsaResult) { printf("Failed to resolve \"%S\". GetAddrInfoW() failed with 0x%x\n", strAddress, wsaResult); goto Exit; } // Make sure the address resolved to only one entry if (NULL != pAddress->ai_next) { printf("%S Resolved to more than one address. Please use a numeric Address\n", strAddress); goto Exit; } // Copy the address to the storage CopyMemory(pSocketAddress, pAddress->ai_addr, pAddress->ai_addrlen); result = TRUE; Exit: // Cleanup if (NULL != pAddress) { FreeAddrInfoW(pAddress); } return result; }
bool SimpleSocket::ConnectSocket() { //0 for success, 1 for error int iResult=SOCKET_ERROR; // try the next address returned by GetAddrInfoW if the connect call failed for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) { iResult = connect( TheSocket, ptr->ai_addr, (int)ptr->ai_addrlen); /*ipv4*/ sockaddr_in* tmp_addr=(sockaddr_in*)(ptr->ai_addr); unsigned char i1=(tmp_addr->sin_addr.S_un.S_un_b.s_b1); unsigned char i2=(tmp_addr->sin_addr.S_un.S_un_b.s_b2); unsigned char i3=(tmp_addr->sin_addr.S_un.S_un_b.s_b3); unsigned char i4=(tmp_addr->sin_addr.S_un.S_un_b.s_b4); wchar_t buffer[32]=L""; swprintf_s(buffer,32,L"%d.%d.%d.%d",i1,i2,i3,i4); ipv4=std::wstring(buffer); if (iResult == SOCKET_ERROR) { //ERROR closesocket(TheSocket); TheSocket = INVALID_SOCKET; iStatus=SOCKET_CLOSED; } else if (iResult == 0) { //OK break; } } FreeAddrInfoW(result); // after success connection or tried all addrs in result, free "result" if (TheSocket == INVALID_SOCKET) { onSysMsg(L"Unable to connect to server!"); WSACleanup(); iStatus=SOCKET_CLOSED; return 1; } else { iStatus=SOCKET_CONNECTED; return 0; } }
/*! * \brief * This function pings an IP-Address with a specified Time-To-Live-value. * * \param targetIP * The textual representation of the IP-Address to ping (both IPv4 and IPv6 are accepted) * * \param ttl * The Time-To-Live-value to perform the ping with * * \param out * The Buffer into which the result of the ping-command will be written * * \param outSize * The maximum number of characters that can be written into "out" * * \returns * True if the execution succeded and false otherwise. The following will be written in "out": "TARGET "+TargetIP if the target was reached, "HOP "+HopIP if an intermediate Host was reached or "NO_REPLY" if an execution error occurred. If an internal error occured, a message describing that error will be written. * * \remarks * Writing the "ping"-function in Javascript and calling the iphlpapi.dll (and others) using c-types turned out to be impossible. The reason for that is the fact that calling GetLastError() is not possible using c-types. Therefore it is implemented in c-code and compiled into the crossbear.dll. * */ extern "C" __declspec( dllexport ) bool ping(WCHAR * targetIP, int ttl, WCHAR * out, int outSize){ // Validate the Time-To-Live-Parameter: less than 1 is invalid and more than 255 doesn't make sense and might cause _itow problems if(ttl<1 || ttl>255){ outPutWstring(std::wstring(L"TTL Parameter invalid"),out,outSize); return false; } // Verify if targetIP is a valid address if yes convert it into a addrinfo-struct struct addrinfoW *ai; if(! (0==GetAddrInfoW(targetIP,NULL,NULL,&ai))){ outPutWstring(std::wstring(L"could not parse IP Address : ")+getFormatedLastError(),out,outSize); return false; } // Check if the IP-version of the targetIP is v6 ... if(ai->ai_family == AF_INET6){ // ... and if it is perform a ping using ICMPv4 return ping6(ai, ttl, out, outSize); } // Check if the IP-version of the targetIP is v4 ... else if(ai->ai_family == AF_INET){ // ... and if it is perform a ping using ICMPv6 return ping4(ai, ttl, out, outSize); } // In case the passed address is neither IPv4 nor IPv6: Return an error message outPutWstring(std::wstring(L"Unknown type of IPAddress"),out,outSize); FreeAddrInfoW(ai); return false; }
int main (int argc, char **argv) { int ret; int r = 1; WSADATA wsd; GUID prov; GUID sc; wchar_t *cmdl; int wargc; wchar_t **wargv; if (WSAStartup(MAKEWORD(2,2), &wsd) != 0) { fprintf (stderr, "WSAStartup() failed: %lu\n", GetLastError()); return 5; } cmdl = GetCommandLineW (); if (cmdl == NULL) { WSACleanup(); return 2; } wargv = CommandLineToArgvW (cmdl, &wargc); if (wargv == NULL) { WSACleanup(); return 3; } r = 4; if (wargc == 5) { if (wcscmp (wargv[1], L"A") == 0) sc = SVCID_DNS_TYPE_A; else if (wcscmp (wargv[1], L"AAAA") == 0) sc = SVCID_DNS_TYPE_AAAA; else if (wcscmp (wargv[1], L"name") == 0) sc = SVCID_HOSTNAME; else if (wcscmp (wargv[1], L"addr") == 0) sc = SVCID_INET_HOSTADDRBYNAME; else wargc -= 1; if (wcscmp (wargv[4], L"mswdns") == 0) prov = W32_DNS; else if (wcscmp (wargv[4], L"gnunetdns") == 0) prov = GNUNET_NAMESPACE_PROVIDER_DNS; else wargc -= 1; } else if (wargc == 3) { } else { fprintf (stderr, "Usage: %S <record type> <service name> <NSP library path> <NSP id>\n" "record type - one of the following: A | AAAA | name | addr\n" "service name - a string to resolve; \" \" (a space) means 'blank'\n" "NSP library path - path to libw32nsp\n" "NSP id - one of the following: mswdns | gnunetdns\n", wargv[0]); } if (wargc == 5) { HMODULE nsp; nsp = LoadLibraryW (wargv[3]); if (nsp == NULL) { fprintf (stderr, "Failed to load library `%S'\n", wargv[3]); } else { LPNSPSTARTUP startup = (LPNSPSTARTUP) GetProcAddress (nsp, "NSPStartup"); if (startup == NULL) startup = (LPNSPSTARTUP) GetProcAddress (nsp, "NSPStartup@8"); if (startup != NULL) { NSP_ROUTINE api; api.cbSize = sizeof (api); ret = startup (&prov, &api); if (NO_ERROR != ret) fprintf (stderr, "startup failed: %lu\n", GetLastError ()); else { HANDLE lookup; WSAQUERYSETW search; char buf[4096]; WSAQUERYSETW *result = (WSAQUERYSETW *) buf; DWORD resultsize; DWORD err; memset (&search, 0, sizeof (search)); search.dwSize = sizeof (search); search.lpszServiceInstanceName = (wcscmp (wargv[2], L" ") == 0) ? NULL : wargv[2]; search.lpServiceClassId = ≻ search.lpNSProviderId = &prov; search.dwNameSpace = NS_ALL; ret = api.NSPLookupServiceBegin (&prov, &search, NULL, LUP_RETURN_ALL, &lookup); if (ret != NO_ERROR) { fprintf (stderr, "lookup start failed\n"); } else { resultsize = 4096; ret = api.NSPLookupServiceNext (lookup, LUP_RETURN_ALL, &resultsize, result); err = GetLastError (); if (ret != NO_ERROR) { fprintf (stderr, "lookup next failed: %lu\n", err); } else { int i; printf ("Got result:\n"); printf (" lpszServiceInstanceName: %S\n", result->lpszServiceInstanceName ? result->lpszServiceInstanceName : L"NULL"); if (result->lpServiceClassId) printf (" lpServiceClassId: { 0x%08lX,0x%04X,0x%04X, { 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X } }\n", result->lpServiceClassId->Data1, result->lpServiceClassId->Data2, result->lpServiceClassId->Data3, result->lpServiceClassId->Data4[0], result->lpServiceClassId->Data4[1], result->lpServiceClassId->Data4[2], result->lpServiceClassId->Data4[3], result->lpServiceClassId->Data4[4], result->lpServiceClassId->Data4[5], result->lpServiceClassId->Data4[6], result->lpServiceClassId->Data4[7]); else printf (" lpServiceClassId: NULL\n"); if (result->lpVersion) printf (" lpVersion: 0x%08lX, %d\n", result->lpVersion->dwVersion, result->lpVersion->ecHow); else printf (" lpVersion: NULL\n"); printf (" lpszComment: %S\n", result->lpszComment ? result->lpszComment : L"NULL"); printf (" dwNameSpace: %lu\n", result->dwNameSpace); if (result->lpNSProviderId) printf (" lpNSProviderId: { 0x%08lX,0x%04X,0x%04X, { 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X, 0x%02X } }\n", result->lpNSProviderId->Data1, result->lpNSProviderId->Data2, result->lpNSProviderId->Data3, result->lpNSProviderId->Data4[0], result->lpNSProviderId->Data4[1], result->lpNSProviderId->Data4[2], result->lpNSProviderId->Data4[3], result->lpNSProviderId->Data4[4], result->lpNSProviderId->Data4[5], result->lpNSProviderId->Data4[6], result->lpNSProviderId->Data4[7]); else printf (" lpNSProviderId: NULL\n"); printf (" lpszContext: %S\n", result->lpszContext ? result->lpszContext : L"NULL"); printf (" dwNumberOfProtocols: %lu\n", result->dwNumberOfProtocols); printf (" lpszQueryString: %S\n", result->lpszQueryString ? result->lpszQueryString : L"NULL"); printf (" dwNumberOfCsAddrs: %lu\n", result->dwNumberOfCsAddrs); for (i = 0; i < result->dwNumberOfCsAddrs; i++) { switch (result->lpcsaBuffer[i].iSocketType) { case SOCK_STREAM: printf (" %d: iSocketType = SOCK_STREAM\n", i); break; case SOCK_DGRAM: printf (" %d: iSocketType = SOCK_DGRAM\n", i); break; default: printf (" %d: iSocketType = %d\n", i, result->lpcsaBuffer[i].iSocketType); } switch (result->lpcsaBuffer[i].iProtocol) { case IPPROTO_TCP: printf (" %d: iProtocol = IPPROTO_TCP\n", i); break; case IPPROTO_UDP: printf (" %d: iProtocol = IPPROTO_UDP\n", i); break; default: printf (" %d: iProtocol = %d\n", i, result->lpcsaBuffer[i].iProtocol); } switch (result->lpcsaBuffer[i].LocalAddr.lpSockaddr->sa_family) { case AF_INET: printf (" %d: loc family = AF_INET\n", i); break; case AF_INET6: printf (" %d: loc family = AF_INET6\n", i); break; default: printf (" %d: loc family = %hu\n", i, result->lpcsaBuffer[i].LocalAddr.lpSockaddr->sa_family); } switch (result->lpcsaBuffer[i].RemoteAddr.lpSockaddr->sa_family) { case AF_INET: printf (" %d: rem family = AF_INET\n", i); break; case AF_INET6: printf (" %d: rem family = AF_INET6\n", i); break; default: printf (" %d: rem family = %hu\n", i, result->lpcsaBuffer[i].RemoteAddr.lpSockaddr->sa_family); } char buf[1024]; DWORD buflen = 1024; if (NO_ERROR == WSAAddressToStringA (result->lpcsaBuffer[i].LocalAddr.lpSockaddr, result->lpcsaBuffer[i].LocalAddr.iSockaddrLength, NULL, buf, &buflen)) printf("\tLocal Address #%d: %s\n", i, buf); else printf("\tLocal Address #%d: Can't convert: %lu\n", i, GetLastError ()); buflen = 1024; if (NO_ERROR == WSAAddressToStringA (result->lpcsaBuffer[i].RemoteAddr.lpSockaddr, result->lpcsaBuffer[i].RemoteAddr.iSockaddrLength, NULL, buf, &buflen)) printf("\tRemote Address #%d: %s\n", i, buf); else printf("\tRemote Address #%d: Can't convert: %lu\n", i, GetLastError ()); } printf (" dwOutputFlags: 0x%08lX\n", result->dwOutputFlags); printf (" lpBlob: 0x%p\n", result->lpBlob); if (result->lpBlob) { struct hostent *he = malloc (result->lpBlob->cbSize); if (he != NULL) { GNUNET_memcpy (he, result->lpBlob->pBlobData, result->lpBlob->cbSize); UnpackHostEnt (he); print_hostent (he); free (he); } } } ret = api.NSPLookupServiceEnd (lookup); if (ret != NO_ERROR) printf ("NSPLookupServiceEnd() failed: %lu\n", GetLastError ()); } api.NSPCleanup (&prov); } } FreeLibrary (nsp); } } else if (wargc == 3) { int s; ADDRINFOW hints; ADDRINFOW *result; ADDRINFOW *pos; memset (&hints, 0, sizeof (struct addrinfo)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; if (0 != (s = GetAddrInfoW (wargv[2], NULL, &hints, &result))) { fprintf (stderr, "Cound not resolve `%S' using GetAddrInfoW: %lu\n", wargv[2], GetLastError ()); } else { for (pos = result; pos != NULL; pos = pos->ai_next) { wchar_t tmpbuf[1024]; DWORD buflen = 1024; if (0 == WSAAddressToStringW (pos->ai_addr, pos->ai_addrlen, NULL, tmpbuf, &buflen)) fprintf (stderr, "Result:\n" " flags: 0x%X\n" " family: 0x%X\n" " socktype: 0x%X\n" " protocol: 0x%X\n" " addrlen: %u\n" " addr: %S\n" " canonname: %S\n", pos->ai_flags, pos->ai_family, pos->ai_socktype, pos->ai_protocol, pos->ai_addrlen, tmpbuf, pos->ai_canonname); else fprintf (stderr, "Result:\n" " flags: 0x%X\n" " family: 0x%X\n" " socktype: 0x%X\n" " protocol: 0x%X\n" " addrlen: %u\n" " addr: %S\n" " canonname: %S\n", pos->ai_flags, pos->ai_family, pos->ai_socktype, pos->ai_protocol, pos->ai_addrlen, L"<can't stringify>", pos->ai_canonname); } if (NULL != result) FreeAddrInfoW (result); } } WSACleanup(); return r; }
/* * Called from uv_run when complete. Call user specified callback * then free returned addrinfo * Returned addrinfo strings are converted from UTF-16 to UTF-8. * * To minimize allocation we calculate total size required, * and copy all structs and referenced strings into the one block. * Each size calculation is adjusted to avoid unaligned pointers. */ void uv_process_getaddrinfo_req(uv_loop_t* loop, uv_getaddrinfo_t* handle, uv_req_t* req) { int addrinfo_len = 0; int name_len = 0; size_t addrinfo_struct_len = ALIGNED_SIZE(sizeof(struct addrinfo)); struct addrinfoW* addrinfow_ptr; struct addrinfo* addrinfo_ptr; char* alloc_ptr = NULL; char* cur_ptr = NULL; uv_err_code uv_ret; /* release input parameter memory */ if (handle->alloc != NULL) { free(handle->alloc); handle->alloc = NULL; } uv_ret = uv_translate_eai_error(handle->retcode); if (handle->retcode == 0) { /* convert addrinfoW to addrinfo */ /* first calculate required length */ addrinfow_ptr = handle->res; while (addrinfow_ptr != NULL) { addrinfo_len += addrinfo_struct_len + ALIGNED_SIZE(addrinfow_ptr->ai_addrlen); if (addrinfow_ptr->ai_canonname != NULL) { name_len = uv_utf16_to_utf8(addrinfow_ptr->ai_canonname, -1, NULL, 0); if (name_len == 0) { uv_ret = uv_translate_sys_error(GetLastError()); goto complete; } addrinfo_len += ALIGNED_SIZE(name_len); } addrinfow_ptr = addrinfow_ptr->ai_next; } /* allocate memory for addrinfo results */ alloc_ptr = (char*)malloc(addrinfo_len); /* do conversions */ if (alloc_ptr != NULL) { cur_ptr = alloc_ptr; addrinfow_ptr = handle->res; while (addrinfow_ptr != NULL) { /* copy addrinfo struct data */ assert(cur_ptr + addrinfo_struct_len <= alloc_ptr + addrinfo_len); addrinfo_ptr = (struct addrinfo*)cur_ptr; addrinfo_ptr->ai_family = addrinfow_ptr->ai_family; addrinfo_ptr->ai_socktype = addrinfow_ptr->ai_socktype; addrinfo_ptr->ai_protocol = addrinfow_ptr->ai_protocol; addrinfo_ptr->ai_flags = addrinfow_ptr->ai_flags; addrinfo_ptr->ai_addrlen = addrinfow_ptr->ai_addrlen; addrinfo_ptr->ai_canonname = NULL; addrinfo_ptr->ai_addr = NULL; addrinfo_ptr->ai_next = NULL; cur_ptr += addrinfo_struct_len; /* copy sockaddr */ if (addrinfo_ptr->ai_addrlen > 0) { assert(cur_ptr + addrinfo_ptr->ai_addrlen <= alloc_ptr + addrinfo_len); memcpy(cur_ptr, addrinfow_ptr->ai_addr, addrinfo_ptr->ai_addrlen); addrinfo_ptr->ai_addr = (struct sockaddr*)cur_ptr; cur_ptr += ALIGNED_SIZE(addrinfo_ptr->ai_addrlen); } /* convert canonical name to UTF-8 */ if (addrinfow_ptr->ai_canonname != NULL) { name_len = uv_utf16_to_utf8(addrinfow_ptr->ai_canonname, -1, NULL, 0); assert(name_len > 0); assert(cur_ptr + name_len <= alloc_ptr + addrinfo_len); name_len = uv_utf16_to_utf8(addrinfow_ptr->ai_canonname, -1, cur_ptr, name_len); assert(name_len > 0); addrinfo_ptr->ai_canonname = cur_ptr; cur_ptr += ALIGNED_SIZE(name_len); } assert(cur_ptr <= alloc_ptr + addrinfo_len); /* set next ptr */ addrinfow_ptr = addrinfow_ptr->ai_next; if (addrinfow_ptr != NULL) { addrinfo_ptr->ai_next = (struct addrinfo*)cur_ptr; } } } else { uv_ret = UV_ENOMEM; } } /* return memory to system */ if (handle->res != NULL) { FreeAddrInfoW(handle->res); handle->res = NULL; } complete: /* finally do callback with converted result */ handle->getaddrinfo_cb(handle, uv_ret, (struct addrinfo*)alloc_ptr); uv_unref(loop); }
/* * Called from uv_run when complete. Call user specified callback * then free returned addrinfo * Returned addrinfo strings are converted from UTF-16 to UTF-8. * * To minimize allocation we calculate total size required, * and copy all structs and referenced strings into the one block. * Each size calculation is adjusted to avoid unaligned pointers. */ static void uv__getaddrinfo_done(struct uv__work* w, int status) { uv_getaddrinfo_t* req; int addrinfo_len = 0; int name_len = 0; size_t addrinfo_struct_len = ALIGNED_SIZE(sizeof(struct addrinfo)); struct addrinfoW* addrinfow_ptr; struct addrinfo* addrinfo_ptr; char* alloc_ptr = NULL; char* cur_ptr = NULL; req = container_of(w, uv_getaddrinfo_t, work_req); /* release input parameter memory */ if (req->alloc != NULL) { free(req->alloc); req->alloc = NULL; } if (status == UV_ECANCELED) { assert(req->retcode == 0); req->retcode = UV_EAI_CANCELED; if (req->res != NULL) { FreeAddrInfoW(req->res); req->res = NULL; } goto complete; } if (req->retcode == 0) { /* convert addrinfoW to addrinfo */ /* first calculate required length */ addrinfow_ptr = req->res; while (addrinfow_ptr != NULL) { addrinfo_len += addrinfo_struct_len + ALIGNED_SIZE(addrinfow_ptr->ai_addrlen); if (addrinfow_ptr->ai_canonname != NULL) { name_len = uv_utf16_to_utf8(addrinfow_ptr->ai_canonname, -1, NULL, 0); if (name_len == 0) { req->retcode = uv_translate_sys_error(GetLastError()); goto complete; } addrinfo_len += ALIGNED_SIZE(name_len); } addrinfow_ptr = addrinfow_ptr->ai_next; } /* allocate memory for addrinfo results */ alloc_ptr = (char*)malloc(addrinfo_len); /* do conversions */ if (alloc_ptr != NULL) { cur_ptr = alloc_ptr; addrinfow_ptr = req->res; while (addrinfow_ptr != NULL) { /* copy addrinfo struct data */ assert(cur_ptr + addrinfo_struct_len <= alloc_ptr + addrinfo_len); addrinfo_ptr = (struct addrinfo*)cur_ptr; addrinfo_ptr->ai_family = addrinfow_ptr->ai_family; addrinfo_ptr->ai_socktype = addrinfow_ptr->ai_socktype; addrinfo_ptr->ai_protocol = addrinfow_ptr->ai_protocol; addrinfo_ptr->ai_flags = addrinfow_ptr->ai_flags; addrinfo_ptr->ai_addrlen = addrinfow_ptr->ai_addrlen; addrinfo_ptr->ai_canonname = NULL; addrinfo_ptr->ai_addr = NULL; addrinfo_ptr->ai_next = NULL; cur_ptr += addrinfo_struct_len; /* copy sockaddr */ if (addrinfo_ptr->ai_addrlen > 0) { assert(cur_ptr + addrinfo_ptr->ai_addrlen <= alloc_ptr + addrinfo_len); memcpy(cur_ptr, addrinfow_ptr->ai_addr, addrinfo_ptr->ai_addrlen); addrinfo_ptr->ai_addr = (struct sockaddr*)cur_ptr; cur_ptr += ALIGNED_SIZE(addrinfo_ptr->ai_addrlen); } /* convert canonical name to UTF-8 */ if (addrinfow_ptr->ai_canonname != NULL) { name_len = uv_utf16_to_utf8(addrinfow_ptr->ai_canonname, -1, NULL, 0); assert(name_len > 0); assert(cur_ptr + name_len <= alloc_ptr + addrinfo_len); name_len = uv_utf16_to_utf8(addrinfow_ptr->ai_canonname, -1, cur_ptr, name_len); assert(name_len > 0); addrinfo_ptr->ai_canonname = cur_ptr; cur_ptr += ALIGNED_SIZE(name_len); } assert(cur_ptr <= alloc_ptr + addrinfo_len); /* set next ptr */ addrinfow_ptr = addrinfow_ptr->ai_next; if (addrinfow_ptr != NULL) { addrinfo_ptr->ai_next = (struct addrinfo*)cur_ptr; } } } else { req->retcode = UV_EAI_MEMORY; } } /* return memory to system */ if (req->res != NULL) { FreeAddrInfoW(req->res); req->res = NULL; } complete: uv__req_unregister(req->loop, req); /* finally do callback with converted result */ req->getaddrinfo_cb(req, req->retcode, (struct addrinfo*)alloc_ptr); }
__declspec(dllexport) BOOL SoaronModuleFunc(void) { SQLHDBC hdbc; HSTMT hstmt; unsigned int NumOfLinks, LinkID; WSADATA wd; SQLRETURN sqlret; HANDLE hHeap; FTNAddr LinkAddr; wchar_t Ip[256]; lpLinksCheckInfo LinksTable; WSAEVENT * EventsTable; WSANETWORKEVENTS evt; unsigned int i, j; int res; ADDRINFOW *result = NULL; ADDRINFOW hints; wchar_t LogStr[255]; memset(&hints, 0, sizeof(hints)); LinkAddr.point = 0; NumOfLinks = 0; SQLAllocHandle(SQL_HANDLE_DBC, cfg.henv, &hdbc); sqlret = SQLDriverConnectW(hdbc, NULL, cfg.ConnectionString, SQL_NTS, NULL, 0, NULL, SQL_DRIVER_NOPROMPT); if (sqlret != SQL_SUCCESS && sqlret != SQL_SUCCESS_WITH_INFO) { SetEvent(cfg.hExitEvent); return FALSE;//fatal error } SQLAllocHandle(SQL_HANDLE_STMT, hdbc, &hstmt); AddLogEntry(L"Checking binkp links alive"); //get links info SQLExecDirectW(hstmt, L"update Links set DialOut=0 where datediff(minute,LastSessionTime,GetDate())>40 and LinkType=1", SQL_NTS); sqlret = SQLExecDirectW(hstmt, L"select count(*) from Links where dialout=0 and passivelink=0 and LinkType=1 and isnull(ip,'')<>''", SQL_NTS); if ((sqlret == SQL_SUCCESS) || (sqlret = SQL_SUCCESS_WITH_INFO)) { sqlret = SQLFetch(hstmt); if ((sqlret == SQL_SUCCESS) || (sqlret = SQL_SUCCESS_WITH_INFO)) { SQLGetData(hstmt, 1, SQL_C_ULONG, &NumOfLinks, 0, NULL); } } SQLCloseCursor(hstmt); if (NumOfLinks == 0) goto exit; hHeap = HeapCreate(HEAP_NO_SERIALIZE, 8192, 0); LinksTable = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, NumOfLinks*sizeof(LinksCheckInfo)); EventsTable = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, sizeof(WSAEVENT)*NumOfLinks); i = 0; hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; WSAStartup(MAKEWORD(2, 2), &wd); sqlret = SQLExecDirectW(hstmt, L"select LinkID,Zone,Net,Node, Ip from Links where dialout=0 and passivelink=0 and LinkType=1 and isnull(ip,'')<>''", SQL_NTS); if ((sqlret == SQL_SUCCESS) || (sqlret = SQL_SUCCESS_WITH_INFO)) { SQLBindCol(hstmt, 1, SQL_C_ULONG, &LinkID, 0, NULL); SQLBindCol(hstmt, 2, SQL_C_USHORT, &(LinkAddr.zone), 0, NULL); SQLBindCol(hstmt, 3, SQL_C_USHORT, &(LinkAddr.net), 0, NULL); SQLBindCol(hstmt, 4, SQL_C_USHORT, &(LinkAddr.node), 0, NULL); SQLBindCol(hstmt, 5, SQL_C_WCHAR, Ip, 512, NULL); sqlret = SQLFetch(hstmt); while ((sqlret == SQL_SUCCESS) || (sqlret == SQL_SUCCESS_WITH_INFO)) { // res = GetAddrInfoW(Ip, L"24554", &hints, &result); if (res == 0) { memcpy(&(LinksTable[i].sa), result->ai_addr, sizeof(struct sockaddr_in)); // printf("%u %u %S %u.%u.%u.%u\n", i,LinkID, Ip, LinksTable[i].sa.sin_addr.S_un.S_un_b.s_b1, LinksTable[i].sa.sin_addr.S_un.S_un_b.s_b2, LinksTable[i].sa.sin_addr.S_un.S_un_b.s_b3, LinksTable[i].sa.sin_addr.S_un.S_un_b.s_b4); LinksTable[i].LinkID = LinkID; LinksTable[i].LinkAddr.FullAddr = LinkAddr.FullAddr; LinksTable[i].s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); EventsTable[i] = WSACreateEvent(); WSAEventSelect(LinksTable[i].s, EventsTable[i], FD_CONNECT); FreeAddrInfoW(result); ++i; } else { wsprintfW(LogStr,L"%u:%u/%u: Ip address %s cannot be resolved", LinkAddr.zone, LinkAddr.net, LinkAddr.node,Ip); AddLogEntry(LogStr); } sqlret = SQLFetch(hstmt); } } SQLCloseCursor(hstmt); SQLFreeStmt(hstmt, SQL_UNBIND); NumOfLinks = i; for (i = 0; i < NumOfLinks; i++) { connect(LinksTable[i].s, (struct sockaddr *)&(LinksTable[i].sa), sizeof(struct sockaddr_in)); } j = 0; SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 0, 0, &LinkID, 0, NULL); SQLPrepareW(hstmt, L"Update Links set DialOut=1 where LinkID=?", SQL_NTS); while (j < NumOfLinks) { res = WSAWaitForMultipleEvents(NumOfLinks, EventsTable, FALSE, WSA_INFINITE, FALSE); WSAEnumNetworkEvents(LinksTable[res].s, EventsTable[res], &evt); shutdown(LinksTable[res].s, SD_BOTH); closesocket(LinksTable[res].s); if (evt.iErrorCode[FD_CONNECT_BIT] == 0) { wsprintfW(LogStr, L"%u:%u/%u: OK", LinksTable[res].LinkAddr.zone, LinksTable[res].LinkAddr.net, LinksTable[res].LinkAddr.node); LinkID = LinksTable[res].LinkID; SQLExecute(hstmt); } else { switch (evt.iErrorCode[FD_CONNECT_BIT]) { case WSAECONNREFUSED: wsprintfW(LogStr, L"%u:%u/%u: Connection refused", LinksTable[res].LinkAddr.zone, LinksTable[res].LinkAddr.net, LinksTable[res].LinkAddr.node); break; case WSAETIMEDOUT: wsprintfW(LogStr, L"%u:%u/%u: Connection timed out", LinksTable[res].LinkAddr.zone, LinksTable[res].LinkAddr.net, LinksTable[res].LinkAddr.node); break; default:wsprintfW(LogStr, L"%u:%u/%u: Unknown connection error", LinksTable[res].LinkAddr.zone, LinksTable[res].LinkAddr.net, LinksTable[res].LinkAddr.node); } } AddLogEntry(LogStr); ++j; } // for (j = 0; j < NumOfLinks; j++) { WSACloseEvent(EventsTable[j]); } SQLFreeStmt(hstmt, SQL_RESET_PARAMS); // WSACleanup(); HeapDestroy(hHeap); exit: SQLFreeHandle(SQL_HANDLE_STMT, hstmt); SQLDisconnect(hdbc); SQLFreeHandle(SQL_HANDLE_DBC, hdbc); AddLogEntry(L"Links alive check done"); SetEvent(cfg.hLinksUpdateEvent); return TRUE; }
/*! * \brief * This function pings an IPv4-Address with a specified Time-To-Live-value. * * \param ai * The AddrInfo-representation of the TargetIP * * \param ttl * The Time-To-Live-value to perform the ping with * * \param out * The Buffer into which the result of the ping-command will be written * * \param outSize * The maximum number of characters that can be written into "out" * * \returns * True if the execution succeded and false otherwise. The following will be written in "out": "TARGET "+TargetIP if the target was reached, "HOP "+HopIP if an intermediate Host was reached or "NO_REPLY" if an execution error occurred. If an internal error occured, a message describing that error will be written. * * \remarks * ai will be Freed */ bool ping4(struct addrinfoW *ai, int ttl, WCHAR * out, int outSize){ // Create a handle to a hIcmpFile (required by IcmpSendEcho2) HANDLE hIcmpFile = IcmpCreateFile(); if (hIcmpFile == INVALID_HANDLE_VALUE) { outPutWstring(std::wstring(L"IcmpCreatefile returned error: ")+getFormatedLastError(),out,outSize); // Free all allocated resources FreeAddrInfoW(ai); return false; } // Build the payload of the ICMP-request (mustn't be empty) char SendData[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"; // Allocate space for a single reply DWORD ReplySize = sizeof (ICMP_ECHO_REPLY) + sizeof (SendData) + 8 + sizeof(IO_STATUS_BLOCK); LPVOID ReplyBuffer = (VOID *) malloc(ReplySize); // Convert the IP-Address into the correct format IPAddr ipaddr; memcpy(&ipaddr, &((sockaddr_in *)ai->ai_addr)->sin_addr, sizeof(ipaddr)); // Create a IP_OPTION_INFORMATION and set its TTL-field so IcmpSendEcho2 will perform a ping with the correct TTL IP_OPTION_INFORMATION ipopts; memset(&ipopts,0,sizeof(ipopts)); ipopts.Ttl = (unsigned char)ttl; //Try to perform the actual ping DWORD dwRetVal = IcmpSendEcho2(hIcmpFile, NULL, NULL, NULL, ipaddr, SendData, sizeof (SendData), &ipopts, ReplyBuffer, ReplySize, 1000); if (dwRetVal == 0) { // In case it failed: Did it fail because of a timeout or because of a serious problem? bool success = false; DWORD lastError = GetLastError(); if(IP_REQ_TIMED_OUT == lastError || IP_DEST_NET_UNREACHABLE == lastError ){ // If it failed because of a Timeout return "NO_REPLY" outPutWstring(std::wstring(L"NO_REPLY"),out,outSize); success = true; } else{ // If it failed because of a serious problem return a detailed description about the failure outPutWstring(std::wstring(L"Call to IcmpSendEcho2 failed: ")+getFormatedLastError(),out,outSize); } // Free all allocated resources FreeAddrInfoW(ai); free(ReplyBuffer); IcmpCloseHandle(hIcmpFile); return success; } // Parse the reply on the ICMP-request PICMP_ECHO_REPLY pEchoReply = (PICMP_ECHO_REPLY) ReplyBuffer; // Extract the address of the replying host struct in_addr ReplyAddr; ReplyAddr.S_un.S_addr = pEchoReply->Address; std::wstring hopName = s2ws(std::string(inet_ntoa(ReplyAddr))); // Switch according to status of reply ULONG status = pEchoReply->Status; if(status == IP_SUCCESS){ // Ping reached the target outPutWstring(std::wstring(L"TARGET ")+ hopName,out,outSize); } else if(status == IP_TTL_EXPIRED_TRANSIT || status == IP_TTL_EXPIRED_REASSEM){ // Ping got a reply from a hop on the way to target outPutWstring(std::wstring(L"HOP ")+ hopName,out,outSize); } else{ // Something didn't work outPutWstring(std::wstring(L"NO_REPLY"),out,outSize); } // Free all allocated resources free(ReplyBuffer); FreeAddrInfoW(ai); IcmpCloseHandle(hIcmpFile); return true; }
/*! * \brief * This function pings an IPv6-Address with a specified Time-To-Live-value. * * \param ai * The AddrInfo-representation of the TargetIP * * \param ttl * The Time-To-Live-value to perform the ping with * * \param out * The Buffer into which the result of the ping-command will be written * * \param outSize * The maximum number of characters that can be written into "out" * * \returns * True if the execution succeded and false otherwise. The following will be written in "out": "TARGET "+TargetIP if the target was reached, "HOP "+HopIP if an intermediate Host was reached or "NO_REPLY" if an execution error occurred. If an internal error occured, a message describing that error will be written. * * \remarks * ai will be Freed */ bool ping6(struct addrinfoW *ai, int ttl, WCHAR * out, int outSize){ // Create a handle to a hIcmpFile (required by Icmp6SendEcho2) HANDLE hIcmpFile = Icmp6CreateFile(); if (hIcmpFile == INVALID_HANDLE_VALUE) { outPutWstring(std::wstring(L"Icmp6Createfile returned error: ")+getFormatedLastError(),out,outSize); // Free all allocated resources FreeAddrInfoW(ai); return false; } // A ICMP-request using IPv6 requires a source address: Get the system's IPv6 addresses ADDRINFOW hints; memset(&hints,0,sizeof(ADDRINFOW)); hints.ai_family = AF_INET6; struct addrinfoW *lai; if(! (0==GetAddrInfoW(L"",NULL,&hints,&lai))){ outPutWstring(std::wstring(L"Invalid Socket (Localhost) : ")+getFormatedLastError(),out,outSize); // Free all allocated resources FreeAddrInfoW(ai); IcmpCloseHandle(hIcmpFile); return false; } // Out of all of the system's IPv6-addresses: get a global IPv6 IP-Address for localhost struct addrinfoW *sourceGlobal = lai; while(sourceGlobal != NULL){ sockaddr_in6 * a = (sockaddr_in6 *)sourceGlobal->ai_addr; if(IN6_IS_ADDR_GLOBAL(&a->sin6_addr)) break; sourceGlobal = sourceGlobal->ai_next; } // If there is none then there is no way to perform an ICMP-request on a IPv6-address -> abbort! if(sourceGlobal == NULL){ outPutWstring(std::wstring(L"No global IPv6 interface found on localhost: ")+getFormatedLastError(),out,outSize); // Free all allocated resources FreeAddrInfoW(ai); FreeAddrInfoW(lai); IcmpCloseHandle(hIcmpFile); return false; } // Build the payload of the ICMP-request (mustn't be empty) char SendData[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ012345"; // Allocate space for a single reply DWORD ReplySize = sizeof (ICMPV6_ECHO_REPLY) + sizeof (SendData) + 8 + sizeof(IO_STATUS_BLOCK); LPVOID ReplyBuffer = (VOID *) malloc(ReplySize); // Create a IP_OPTION_INFORMATION and set its TTL-field so Icmp6SendEcho2 will perform a ping with the correct TTL IP_OPTION_INFORMATION ipopts; memset(&ipopts,0,sizeof(ipopts)); ipopts.Ttl = (unsigned char)ttl; //Try to perform the actual ping DWORD dwRetVal = Icmp6SendEcho2(hIcmpFile, NULL, NULL, NULL,(sockaddr_in6 *)sourceGlobal->ai_addr, (sockaddr_in6 *)ai->ai_addr, SendData, sizeof (SendData), &ipopts, ReplyBuffer, ReplySize, 1000); if (dwRetVal == 0) { // In case it failed: Did it fail because of a timeout or because of a serious problem? bool success = false; DWORD lastError = GetLastError(); if(IP_REQ_TIMED_OUT == lastError || IP_DEST_NET_UNREACHABLE == lastError ){ // If it failed because of a Timeout return "NO_REPLY" outPutWstring(std::wstring(L"NO_REPLY"),out,outSize); success = true; } else{ // If it failed because of a serious problem return a detailed description about the failure outPutWstring(std::wstring(L"Call to Icmp6SendEcho2 failed: ")+getFormatedLastError(),out,outSize); } // Free all allocated resources FreeAddrInfoW(ai); FreeAddrInfoW(lai); free(ReplyBuffer); IcmpCloseHandle(hIcmpFile); return success; } // Parse the reply on the ICMP-request PICMPV6_ECHO_REPLY pEchoReply = (PICMPV6_ECHO_REPLY) ReplyBuffer; /* * Extract the address of the replying host */ // First: copy the reply data into a sockaddr_in6-struckture PIPV6_ADDRESS_EX pIP6Addr = &pEchoReply->Address;; sockaddr_in6 sock6; sock6.sin6_family = AF_INET6; sock6.sin6_flowinfo = pIP6Addr->sin6_flowinfo; sock6.sin6_port = pIP6Addr->sin6_port; sock6.sin6_scope_id = pIP6Addr->sin6_scope_id; memcpy(&sock6.sin6_addr, pIP6Addr->sin6_addr,sizeof(IN6_ADDR)); // Second: convert it into human readable version WCHAR ip6AddressString[256]; DWORD bufferLenght = 256; if(0 != WSAAddressToStringW((LPSOCKADDR)&sock6,sizeof(sockaddr_in6),NULL,ip6AddressString,&bufferLenght)){ outPutWstring(std::wstring(L"Call to WSAAddressToStringW failed: ")+getFormatedLastError(),out,outSize); // Free all allocated resources FreeAddrInfoW(ai); FreeAddrInfoW(lai); free(ReplyBuffer); IcmpCloseHandle(hIcmpFile); return false; } // Third: convert it into a wstring std::wstring hopName = std::wstring(ip6AddressString); /* * Switch according to status of reply */ ULONG status = pEchoReply->Status; if(status == IP_SUCCESS){ // Ping reached the target outPutWstring(std::wstring(L"TARGET ")+ hopName,out,outSize); } else if(status == IP_TTL_EXPIRED_TRANSIT || status == IP_TTL_EXPIRED_REASSEM){ // Ping got a reply from a hop on the way to target outPutWstring(std::wstring(L"HOP ")+ hopName,out,outSize); } else{ // Something didn't work outPutWstring(std::wstring(L"NO_REPLY"),out,outSize); } // Free all allocated resources free(ReplyBuffer); FreeAddrInfoW(ai); FreeAddrInfoW(lai); IcmpCloseHandle(hIcmpFile); return true; }
int wmain(int argc, WCHAR *argv[]) { WSADATA wsaData; ULONG i; DWORD StrLen = 46; int Status; /* Initialize the Console Standard Streams */ ConInitStdStreams(); IpOptions.Ttl = 128; if (!ParseCmdLine(argc, argv)) return 1; if (!SetConsoleCtrlHandler(ConsoleCtrlHandler, TRUE)) { DPRINT("Failed to set control handler: %lu\n", GetLastError()); return 1; } Status = WSAStartup(MAKEWORD(2, 2), &wsaData); if (Status != 0) { ConResPrintf(StdErr, IDS_WINSOCK_FAIL, Status); return 1; } if (!ResolveTarget(TargetName)) { WSACleanup(); return 1; } if (WSAAddressToStringW(Target->ai_addr, (DWORD)Target->ai_addrlen, NULL, Address, &StrLen) != 0) { DPRINT("WSAAddressToStringW failed: %d\n", WSAGetLastError()); FreeAddrInfoW(Target); WSACleanup(); return 1; } if (Family == AF_INET6) hIcmpFile = Icmp6CreateFile(); else hIcmpFile = IcmpCreateFile(); if (hIcmpFile == INVALID_HANDLE_VALUE) { DPRINT("IcmpCreateFile failed: %lu\n", GetLastError()); FreeAddrInfoW(Target); WSACleanup(); return 1; } if (*CanonName) ConResPrintf(StdOut, IDS_PINGING_HOSTNAME, CanonName, Address); else ConResPrintf(StdOut, IDS_PINGING_ADDRESS, Address); ConResPrintf(StdOut, IDS_PING_SIZE, RequestSize); Ping(); i = 1; while (i < PingCount) { Sleep(1000); Ping(); if (!PingForever) i++; } PrintStats(); IcmpCloseHandle(hIcmpFile); FreeAddrInfoW(Target); WSACleanup(); return 0; }
void ConnectSKKServer() { ADDRINFOW *paiwResult; ADDRINFOW *paiw; u_long mode; timeval tv; fd_set fdw, fde; ADDRINFOW aiwHints = {}; aiwHints.ai_family = AF_UNSPEC; aiwHints.ai_socktype = SOCK_STREAM; aiwHints.ai_protocol = IPPROTO_TCP; if(GetAddrInfoW(host, port, &aiwHints, &paiwResult) != 0) { return; } for(paiw = paiwResult; paiw != nullptr; paiw = paiw->ai_next) { sock = socket(paiw->ai_family, paiw->ai_socktype, paiw->ai_protocol); if(sock == INVALID_SOCKET) { continue; } if(setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (const char*)&timeout, sizeof(timeout)) == SOCKET_ERROR) { closesocket(sock); sock = INVALID_SOCKET; continue; } if(setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const char*)&timeout, sizeof(timeout)) == SOCKET_ERROR) { closesocket(sock); sock = INVALID_SOCKET; continue; } mode = 1; ioctlsocket(sock, FIONBIO, &mode); if(connect(sock, paiw->ai_addr, (int)paiw->ai_addrlen) == SOCKET_ERROR) { if(WSAGetLastError() != WSAEWOULDBLOCK) { closesocket(sock); sock = INVALID_SOCKET; continue; } } mode = 0; ioctlsocket(sock, FIONBIO, &mode); tv.tv_sec = timeout / 1000; tv.tv_usec = (timeout % 1000) * 1000; FD_ZERO(&fdw); FD_ZERO(&fde); FD_SET(sock, &fdw); FD_SET(sock, &fde); select(0, nullptr, &fdw, &fde, &tv); if(FD_ISSET(sock, &fdw)) { break; } DisconnectSKKServer(); } FreeAddrInfoW(paiwResult); }
/* * @implemented */ INT WSAAPI GetAddrInfoW(IN PCWSTR pszNodeName, IN PCWSTR pszServiceName, IN const ADDRINFOW *ptHints, OUT PADDRINFOW *pptResult) { INT iError = 0; INT iFlags = 0; INT iFamily = PF_UNSPEC; INT iSocketType = 0; INT iProtocol = 0; WORD wPort = 0; DWORD dwAddress = 0; PSERVENT ptService = NULL; PCHAR pc = NULL; BOOL bClone = FALSE; WORD wTcpPort = 0; WORD wUdpPort = 0; WCHAR CanonicalName[0x42]; CHAR AnsiServiceName[256]; CHAR AnsiNodeName[256]; DPRINT("GetAddrInfoW: %S, %S, %p, %p\n", pszNodeName, pszServiceName, ptHints, pptResult); /* Assume error */ *pptResult = NULL; /* We must have at least one name to work with */ if (!(pszNodeName) && !(pszServiceName)) { /* Fail */ SetLastError(EAI_NONAME); return EAI_NONAME; } /* Check if we got hints */ if (ptHints) { /* Make sure these are empty */ if ((ptHints->ai_addrlen) || (ptHints->ai_canonname) || (ptHints->ai_addr) || (ptHints->ai_next)) { /* Fail if they aren't */ SetLastError(EAI_FAIL); return EAI_FAIL; } /* Save the flags and validate them */ iFlags = ptHints->ai_flags; if ((iFlags & AI_CANONNAME) && !pszNodeName) { SetLastError(EAI_BADFLAGS); return EAI_BADFLAGS; } /* Save family and validate it */ iFamily = ptHints->ai_family; if ((iFamily != PF_UNSPEC) && (iFamily != PF_INET)) { SetLastError(EAI_FAMILY); return EAI_FAMILY; } /* Save socket type and validate it */ iSocketType = ptHints->ai_socktype; if ((iSocketType != 0) && (iSocketType != SOCK_STREAM) && (iSocketType != SOCK_DGRAM) && (iSocketType != SOCK_RAW)) { SetLastError(EAI_SOCKTYPE); return EAI_SOCKTYPE; } /* Save the protocol */ iProtocol = ptHints->ai_protocol; } /* Check if we have a service name */ if (pszServiceName) { /* We need to convert it to ANSI */ WideCharToMultiByte(CP_ACP, 0, pszServiceName, -1, AnsiServiceName, sizeof(AnsiServiceName), NULL, 0); /* Get the port */ wPort = (WORD)strtoul(AnsiServiceName, &pc, 10); /* Check if the port string is numeric */ if (*pc == '\0') { /* Get the port directly */ wPort = wTcpPort = wUdpPort = htons(wPort); #if 0 /* Check if this is both TCP and UDP */ if (iSocketType == 0) { /* Set it to TCP for now, but remember to clone */ bClone = TRUE; iSocketType = SOCK_STREAM; } #endif } else { wPort = 0; /* The port name was a string. Check if this is a UDP socket */ if ((iSocketType == 0) || (iSocketType == SOCK_DGRAM)) { /* It's UDP, do a getservbyname */ ptService = getservbyname(AnsiServiceName, "udp"); /* If we got a servent, return the port from it */ if (ptService) wPort = wUdpPort = ptService->s_port; } /* Check if this is a TCP socket */ if ((iSocketType == 0) || (iSocketType == SOCK_STREAM)) { /* It's TCP, do a getserbyname */ ptService = getservbyname(AnsiServiceName, "tcp"); /* Return the port from the servent */ if (ptService) wPort = wTcpPort = ptService->s_port; } /* If we got 0, then fail */ if (wPort == 0) { SetLastError(EAI_SERVICE); return EAI_SERVICE; } /* Check if this was for both */ if (iSocketType == 0) { /* Do the TCP case right now */ if (wTcpPort && !wUdpPort) iSocketType = SOCK_STREAM; if (!wTcpPort && wUdpPort) iSocketType = SOCK_DGRAM; //bClone = (wTcpPort && wUdpPort); } } } /* Check if no node was given or if this is is a valid IPv4 address */ if ((!pszNodeName) || (ParseV4Address(pszNodeName, &dwAddress))) { /* Check if we don't have a node name */ if (!pszNodeName) { /* Make one up based on the flags */ dwAddress = htonl((iFlags & AI_PASSIVE) ? INADDR_ANY : INADDR_LOOPBACK); } /* Create the Addr Info */ *pptResult = NewAddrInfo(iSocketType, iProtocol, wPort, dwAddress); /* If we didn't get one back, assume out of memory */ if (!(*pptResult)) iError = EAI_MEMORY; /* Check if we have success and a nodename */ if (!iError && pszNodeName) { /* Set AI_NUMERICHOST since this is a numeric string */ (*pptResult)->ai_flags |= AI_NUMERICHOST; /* Check if the canonical name was requested */ if (iFlags & AI_CANONNAME) { /* Get the canonical name */ GetNameInfoW((*pptResult)->ai_addr, (socklen_t)(*pptResult)->ai_addrlen, CanonicalName, 0x41, NULL, 0, 2); /* Allocate memory for a copy */ (*pptResult)->ai_canonname = HeapAlloc(WsSockHeap, 0, wcslen(CanonicalName)); if (!(*pptResult)->ai_canonname) { /* No memory for the copy */ iError = EAI_MEMORY; } else { /* Duplicate the string */ RtlMoveMemory((*pptResult)->ai_canonname, CanonicalName, wcslen(CanonicalName)); } } } } else if (iFlags & AI_NUMERICHOST) { /* No name for this request (we have a non-numeric name) */ iError = EAI_NONAME; } else { /* We need to convert it to ANSI */ WideCharToMultiByte(CP_ACP, 0, pszNodeName, -1, AnsiNodeName, sizeof(AnsiNodeName), NULL, 0); /* Non-numeric name, do DNS lookup */ iError = LookupAddressForName(AnsiNodeName, iSocketType, iProtocol, wPort, (iFlags & AI_CANONNAME), pptResult); } /* If all was good and the caller requested UDP and TCP */ if (!iError && bClone) { /* Process UDP now, we already did TCP */ iError = CloneAddrInfo(wUdpPort, *pptResult); } /* If we've hit an error till here */ if (iError) { /* Free the address info and return nothing */ FreeAddrInfoW(*pptResult); *pptResult = NULL; } /* Return to caller */ SetLastError(iError); return iError; }