Ejemplo n.º 1
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;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
static void uv__getaddrinfo_work(struct uv__work* w) {
  uv_getaddrinfo_t* req;
  int err;

  req = container_of(w, uv_getaddrinfo_t, work_req);
  err = GetAddrInfoW(req->node, req->service, req->hints, &req->res);
  req->retcode = uv__getaddrinfo_translate_error(err);
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
static
BOOL
ResolveTarget(PCWSTR target)
{
    ADDRINFOW hints;
    int Status;

    ZeroMemory(&hints, sizeof(hints));
    hints.ai_family = Family;
    hints.ai_flags = AI_NUMERICHOST;

    Status = GetAddrInfoW(target, NULL, &hints, &Target);
    if (Status != 0)
    {
        hints.ai_flags = AI_CANONNAME;

        Status = GetAddrInfoW(target, NULL, &hints, &Target);
        if (Status != 0)
        {
            ConResPrintf(StdOut, IDS_UNKNOWN_HOST, target);
            return FALSE;
        }

        wcsncpy(CanonName, Target->ai_canonname, wcslen(Target->ai_canonname));
    }
    else if (ResolveAddress)
    {
        Status = GetNameInfoW(Target->ai_addr, Target->ai_addrlen,
                              CanonName, _countof(CanonName),
                              NULL, 0,
                              NI_NAMEREQD);
        if (Status != 0)
        {
            DPRINT("GetNameInfoW failed: %d\n", WSAGetLastError());
        }
    }

    Family = Target->ai_family;

    return TRUE;
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
0
  void TCPSocket::bind( const wstring& host, const wstring& service,
  Protocol protocol )
  {
    if ( mState != State_Closed )
      EXCEPT( L"Cannot bind, socket is not closed" );

    ADDRINFOW resolve;
    PADDRINFOW address = nullptr;
    PADDRINFOW resolved = nullptr;

    memset( &resolve, 0, sizeof( ADDRINFOW ) );

    resolve.ai_family   = util::protocolToFamily( protocol );
    resolve.ai_socktype = SOCK_STREAM;
    resolve.ai_protocol = IPPROTO_TCP;

    if ( GetAddrInfoW( host.c_str(), service.c_str(), &resolve, &resolved ) )
      EXCEPT_WSA( L"Couldn't resolve" );

    for ( address = resolved; address != nullptr; address = address->ai_next )
    {
      if ( address->ai_socktype != SOCK_STREAM || address->ai_protocol != IPPROTO_TCP )
        continue;

      mSocket = WSASocketW(
        address->ai_family, address->ai_socktype, address->ai_protocol,
        nullptr, 0, mOverlapped ? WSA_FLAG_OVERLAPPED : 0 );

      if ( mSocket == INVALID_SOCKET )
        continue;

      if ( ::bind( mSocket, address->ai_addr, (int)address->ai_addrlen ) != SOCKET_ERROR )
        break;

      closesocket( mSocket );
    }

    if ( address == nullptr )
      EXCEPT_WSA( L"Couldn't bind" );

    mBound = true;

    mConnectionInfo.update( mSocket, false );
  }
Ejemplo n.º 8
0
/* getaddrinfo worker thread implementation */
static DWORD WINAPI getaddrinfo_thread_proc(void* parameter) {
  uv_getaddrinfo_t* req = (uv_getaddrinfo_t*) parameter;
  uv_loop_t* loop = req->loop;
  int ret;

  assert(req != NULL);

  /* call OS function on this thread */
  ret = GetAddrInfoW(req->node,
                     req->service,
                     req->hints,
                     &req->res);
  req->retcode = ret;

  /* post getaddrinfo completed */
  POST_COMPLETION_FOR_REQ(loop, req);

  return 0;
}
Ejemplo n.º 9
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;
}
Ejemplo n.º 10
0
/* getaddrinfo worker thread implementation */
static DWORD WINAPI getaddrinfo_thread_proc(void* parameter) {
  uv_getaddrinfo_t* handle = (uv_getaddrinfo_t*) parameter;
  uv_loop_t* loop = handle->loop;
  int ret;

  assert(handle != NULL);

  if (handle != NULL) {
    /* call OS function on this thread */
    ret = GetAddrInfoW(handle->node,
                       handle->service,
                       handle->hints,
                       &handle->res);
    handle->retcode = ret;

    /* post getaddrinfo completed */
    POST_COMPLETION_FOR_REQ(loop, &handle->getadddrinfo_req);
  }

  return 0;
}
Ejemplo n.º 11
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;
}
Ejemplo n.º 12
0
__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;
}
Ejemplo n.º 13
0
  void EventTCPSocket::connect( const wstring& host,
  const wstring& service, Protocol protocol )
  {
    if ( mState != State_Closed )
      EXCEPT( L"Cannot connect, socket is not closed" );

    mState = State_Connecting;

    ADDRINFOW resolve;
    PADDRINFOW address = NULL;
    PADDRINFOW resolved = NULL;

    memset( &resolve, NULL, sizeof( ADDRINFOW ) );

    resolve.ai_family   = util::protocolToFamily( protocol );
    resolve.ai_socktype = SOCK_STREAM;
    resolve.ai_protocol = IPPROTO_TCP;

    if ( GetAddrInfoW( host.c_str(), service.c_str(), &resolve, &resolved ) )
    {
      mState = State_Closed;
      EXCEPT_WSA( L"Couldn't resolve" );
    }

    for ( address = resolved; address != nullptr; address = address->ai_next )
    {
      if ( address->ai_socktype != SOCK_STREAM || address->ai_protocol != IPPROTO_TCP )
        continue;

      mSocket = WSASocketW( address->ai_family, address->ai_socktype,
        address->ai_protocol, nullptr, 0,
        mOverlapped ? WSA_FLAG_OVERLAPPED : 0 );

      if ( mSocket == INVALID_SOCKET )
        continue;

      if ( !WSAConnect( mSocket, address->ai_addr, (int)address->ai_addrlen,
        nullptr, nullptr, nullptr, nullptr ) )
        break;

      closesocket( mSocket );
    }

    if ( address == nullptr )
    {
      mState = State_Closed;
      EXCEPT_WSA( L"Couldn't connect" );
    }

    mBound = true;
    
    mConnectionInfo.update( mSocket, false );
    mConnectionInfo.update( mSocket, true );

    if ( WSAEventSelect( mSocket, mNetworkEvent, FD_READ | FD_CLOSE ) == SOCKET_ERROR )
      EXCEPT_WSA( L"Couldn't select socket events" );

    mState = State_Connected;

    for ( SocketListener* listener : mListeners )
      if ( listener->connectCallback( this ) )
        break;
  }
Ejemplo n.º 14
0
Socket *CreateClientSocket(const wchar_t *host, uint16_t port, int timeoutMS)
{
	wchar_t portstr[7] = {0};
	StringFormat::wsnprintf(portstr, 6, L"%d", port);
	
    addrinfoW hints;
	RDCEraseEl(hints);
	hints.ai_family = AF_INET;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = IPPROTO_TCP;
	
    addrinfoW *result = NULL;
	GetAddrInfoW(host, portstr, &hints, &result);
	
    for(addrinfoW *ptr = result; ptr != NULL; ptr = ptr->ai_next)
	{
		SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

		if(s == INVALID_SOCKET)
			return NULL;
		
		u_long enable = 1;
		ioctlsocket(s, FIONBIO, &enable);
		
		int result = connect(s, ptr->ai_addr, (int)ptr->ai_addrlen);
		if(result == SOCKET_ERROR)
		{
			fd_set set;
			FD_ZERO(&set);
			FD_SET(s, &set);

			int err = WSAGetLastError();

			if(err == WSAEWOULDBLOCK)
			{
				timeval timeout;
				timeout.tv_sec = (timeoutMS/1000);
				timeout.tv_usec = (timeoutMS%1000)*1000;
				result = select(0, NULL, &set, NULL, &timeout);

				if(result <= 0)
				{
					RDCDEBUG("connect timed out");
					closesocket(s);
					continue;
				}
				else
				{
					RDCDEBUG("connect before timeout");
				}
			}
			else
			{
				RDCDEBUG("problem other than blocking");
				closesocket(s);
				continue;
			}
		}
		else
		{
			RDCDEBUG("connected immediately");
		}

		BOOL nodelay = TRUE;
		setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (const char *)&nodelay, sizeof(nodelay));
		
		return new Socket((ptrdiff_t)s);
	}

	RDCWARN("Failed to connect to %ls:%d", host, port);
	return NULL;
}
Ejemplo n.º 15
0
Socket *CreateClientSocket(const char *host, uint16_t port, int timeoutMS)
{
	wchar_t portwstr[7] = {0};

	{
		char buf[7] = {0};
		int n = StringFormat::snprintf(buf, 6, "%d", port);
		for(int i=0; i < n && i < 6; i++) portwstr[i] = (wchar_t)buf[i];
	}

	addrinfoW hints;
	RDCEraseEl(hints);
	hints.ai_family = AF_INET;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_protocol = IPPROTO_TCP;

	std::wstring whost = StringFormat::UTF82Wide(string(host));

	addrinfoW *addrResult = NULL;
	GetAddrInfoW(whost.c_str(), portwstr, &hints, &addrResult);

	for(addrinfoW *ptr = addrResult; ptr != NULL; ptr = ptr->ai_next)
	{
		SOCKET s = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_NO_HANDLE_INHERIT);

		if(s == INVALID_SOCKET)
			return NULL;

		u_long enable = 1;
		ioctlsocket(s, FIONBIO, &enable);

		int result = connect(s, ptr->ai_addr, (int)ptr->ai_addrlen);
		if(result == SOCKET_ERROR)
		{
			fd_set set;
			FD_ZERO(&set);

			// macro FD_SET contains the do { } while(0) idiom, which warns
#pragma warning(push)
#pragma warning(disable : 4127) // conditional expression is constant
			FD_SET(s, &set);
#pragma warning(pop)

			int err = WSAGetLastError();

			if(err == WSAEWOULDBLOCK)
			{
				timeval timeout;
				timeout.tv_sec = (timeoutMS/1000);
				timeout.tv_usec = (timeoutMS%1000)*1000;
				result = select(0, NULL, &set, NULL, &timeout);

				if(result <= 0)
				{
					RDCDEBUG("connect timed out");
					closesocket(s);
					continue;
				}
				else
				{
					RDCDEBUG("connect before timeout");
				}
			}
			else
			{
				RDCDEBUG("problem other than blocking");
				closesocket(s);
				continue;
			}
		}
		else
		{
			RDCDEBUG("connected immediately");
		}

		BOOL nodelay = TRUE;
		setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (const char *)&nodelay, sizeof(nodelay));

		return new Socket((ptrdiff_t)s);
	}

	RDCWARN("Failed to connect to %s:%d", host, port);
	return NULL;
}
Ejemplo n.º 16
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);
}
Ejemplo n.º 17
0
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 = &sc;
                    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;
}
Ejemplo n.º 18
0
/*!
 * \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;
}