コード例 #1
0
ファイル: net.c プロジェクト: HupuInc/zabbix
int	NET_TCP_LISTEN(AGENT_REQUEST *request, AGENT_RESULT *result)
{
	MIB_TCPTABLE	*pTcpTable = NULL;
	DWORD		dwSize, dwRetVal;
	int		i, ret = SYSINFO_RET_FAIL;
	unsigned short	port;
	char		*port_str;

	if (1 < request->nparam)
	{
		SET_MSG_RESULT(result, zbx_strdup(NULL, "Too many parameters."));
		return SYSINFO_RET_FAIL;
	}

	port_str = get_rparam(request, 0);

	if (NULL == port_str || SUCCEED != is_ushort(port_str, &port))
	{
		SET_MSG_RESULT(result, zbx_strdup(NULL, "Invalid first parameter."));
		return SYSINFO_RET_FAIL;
	}

	dwSize = sizeof(MIB_TCPTABLE);
	pTcpTable = (MIB_TCPTABLE *)zbx_malloc(pTcpTable, dwSize);

	/* Make an initial call to GetTcpTable to
	   get the necessary size into the dwSize variable */
	if (ERROR_INSUFFICIENT_BUFFER == (dwRetVal = GetTcpTable(pTcpTable, &dwSize, TRUE)))
		pTcpTable = (MIB_TCPTABLE *)zbx_realloc(pTcpTable, dwSize);

	/* Make a second call to GetTcpTable to get
	   the actual data we require */
	if (NO_ERROR == (dwRetVal = GetTcpTable(pTcpTable, &dwSize, TRUE)))
	{
		for (i = 0; i < (int)pTcpTable->dwNumEntries; i++)
		{
			if (MIB_TCP_STATE_LISTEN == pTcpTable->table[i].dwState &&
					port == ntohs((u_short)pTcpTable->table[i].dwLocalPort))
			{
				SET_UI64_RESULT(result, 1);
				break;
			}
		}
		ret = SYSINFO_RET_OK;
	}
	else
	{
		zabbix_log(LOG_LEVEL_DEBUG, "GetTcpTable failed with error: %s", strerror_from_system(dwRetVal));
		SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot obtain system information: %s",
				strerror_from_system(dwRetVal)));
		goto clean;
	}

	if (!ISSET_UI64(result))
		SET_UI64_RESULT(result, 0);
clean:
	zbx_free(pTcpTable);

	return ret;
}
コード例 #2
0
ファイル: PortsManager.cpp プロジェクト: fara-ramin/firewall
PortSet PortsManager::GetNowPorts()
{
	PortSet newPorts;

	PMIB_TCPTABLE pTcpTable;
	DWORD dwSize = 0;
	DWORD dwRetVal = 0;
	unsigned short *port_ptr;
	DWORD i;

	/* Get size required by GetTcpTable() */
	if (GetTcpTable(NULL, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER) {
		pTcpTable = (MIB_TCPTABLE *) malloc (dwSize);
	}

	/* Get actual data using GetTcpTable() */
	if ((dwRetVal = GetTcpTable(pTcpTable, &dwSize, 0)) == NO_ERROR) {
		if (pTcpTable->dwNumEntries > 0) {
			for (i=0; i<pTcpTable->dwNumEntries; i++) {
				//addr_ptr = (char *)&pTcpTable->table[i].dwLocalAddr;
				//port_ptr = (unsigned short *)&pTcpTable->table[i].dwLocalPort;
				//addr_ptr = (char *)&pTcpTable->table[i].dwRemoteAddr;
				port_ptr = (unsigned short *)&pTcpTable->table[i].dwRemotePort;
				DWORD state = pTcpTable->table[i].dwState;
				newPorts.insert(Port(*port_ptr, state));
			}
		}
	}
	free(pTcpTable);
	return newPorts;
}
コード例 #3
0
ファイル: IPStat.Cpp プロジェクト: nizihabi/sdk71examples
//----------------------------------------------------------------------------
// Wrapper to GetTcpTable()
//----------------------------------------------------------------------------
DWORD MyGetTcpTable(PMIB_TCPTABLE& pTcpTable, BOOL fOrder)
{
    DWORD status = NO_ERROR;
    DWORD statusRetry = NO_ERROR;
    DWORD dwActualSize = 0;


    // query for buffer size needed
    status = GetTcpTable(pTcpTable, &dwActualSize, fOrder);

    if (status == NO_ERROR)
    {
        printf("No error\n");
        return status;
    }
    else if (status == ERROR_INSUFFICIENT_BUFFER)
    {
        // need more space
        pTcpTable = (PMIB_TCPTABLE) malloc(dwActualSize);
        assert(pTcpTable);
        
        statusRetry = GetTcpTable(pTcpTable, &dwActualSize, fOrder);
        return statusRetry;
    }
    else
    {
        return status;
    }
}
コード例 #4
0
ファイル: net.c プロジェクト: aries4/MIRACLE-ZBX-2.0.3-NoSQL
int	NET_TCP_LISTEN(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result)
{
	MIB_TCPTABLE	*pTcpTable = NULL;
	DWORD		dwSize, dwRetVal;
	int		i, ret = SYSINFO_RET_FAIL;
	unsigned short	port;
	char		tmp[8];

	assert(result);

	init_result(result);

	if (num_param(param) > 1)
		return SYSINFO_RET_FAIL;

	if (0 != get_param(param, 1, tmp, sizeof(tmp)))
		return SYSINFO_RET_FAIL;

	if (SUCCEED != is_ushort(tmp, &port))
		return SYSINFO_RET_FAIL;

	dwSize = sizeof(MIB_TCPTABLE);
	pTcpTable = (MIB_TCPTABLE *)zbx_malloc(pTcpTable, dwSize);

	/* Make an initial call to GetTcpTable to
	   get the necessary size into the dwSize variable */
	if (ERROR_INSUFFICIENT_BUFFER == (dwRetVal = GetTcpTable(pTcpTable, &dwSize, TRUE)))
		pTcpTable = (MIB_TCPTABLE *)zbx_realloc(pTcpTable, dwSize);

	/* Make a second call to GetTcpTable to get
	   the actual data we require */
	if (NO_ERROR == (dwRetVal = GetTcpTable(pTcpTable, &dwSize, TRUE)))
	{
		for (i = 0; i < (int)pTcpTable->dwNumEntries; i++)
		{
			if (MIB_TCP_STATE_LISTEN == pTcpTable->table[i].dwState &&
					port == ntohs((u_short)pTcpTable->table[i].dwLocalPort))
			{
				SET_UI64_RESULT(result, 1);
				break;
			}
		}
		ret = SYSINFO_RET_OK;
	}
	else
	{
		zabbix_log(LOG_LEVEL_DEBUG, "GetTcpTable failed with error: %s", strerror_from_system(dwRetVal));
		goto clean;
	}

	if (!ISSET_UI64(result))
		SET_UI64_RESULT(result, 0);
clean:
	zbx_free(pTcpTable);

	return ret;
}
コード例 #5
0
ファイル: AdbUtils.cpp プロジェクト: zhangyongproject/VC
HRESULT AdbUtils::GetPortState(ULONG nPort, ULONG *nStateID)
{
	MIB_TCPTABLE TcpTable[100];
	DWORD nSize = sizeof(TcpTable);
	if (NO_ERROR == GetTcpTable(&TcpTable[0], &nSize, TRUE))
	{
		DWORD nCount = TcpTable[0].dwNumEntries;
		if (nCount > 0)
		{
			for (DWORD i=0; i<nCount; i++)
			{
				MIB_TCPROW TcpRow = TcpTable[0].table[i];
				DWORD temp1 = TcpRow.dwLocalPort;
				int temp2 = temp1 / 256 + (temp1 % 256) * 256;
				if (temp2 == nPort)
				{
					*nStateID = TcpRow.dwState;
					return S_OK;
				}
			}
		}
		return S_FALSE;
	}
	return S_FALSE;
}
コード例 #6
0
ファイル: Proxy.cpp プロジェクト: willbill4/workspaceer
int GetValidPort(){
	int port;
	HINSTANCE hdll;
	int CurrentUsePort[1000] = {0};
	int portnum = 0, i = 0;
	unsigned long table_len;
	MIB_TCPTABLE tcp_table;
	MIB_UDPTABLE udp_table;
	port=0;
	DWORD (*GetTcpTable)(PMIB_TCPTABLE,PDWORD,bool);
	DWORD (*GetUdpTable)(PMIB_UDPTABLE,PDWORD,bool);
	hdll=LoadLibrary("iphlpapi.dll");
	if(!hdll) return port;
	(FARPROC &)GetTcpTable=GetProcAddress(hdll,"GetTcpTable");
	(FARPROC &)GetUdpTable=GetProcAddress(hdll,"GetUdpTable");
	if(GetTcpTable){
		TRACE("get tcp table\r\n");
		table_len=(unsigned long)sizeof(tcp_table);
		GetTcpTable(&tcp_table,(PDWORD)&table_len,false);
	}
	if(GetUdpTable){
		TRACE("get udp table\r\n");
		table_len=sizeof(MIB_UDPTABLE);
		//GetUdpTable(&udp_table,&table_len,1);
	}
	FreeLibrary(hdll);
	return port;
}
コード例 #7
0
ファイル: tcpTable.c プロジェクト: vincentbernat/net-snmp
int
tcpTable_load(netsnmp_cache *cache, void *vmagic)
{
    PMIB_TCPTABLE pTcpTable = NULL;
    DWORD         dwActualSize = 0;
    DWORD         status = NO_ERROR;

    /*
     * query for the buffer size needed
     */
    status = GetTcpTable(pTcpTable, &dwActualSize, TRUE);
    if (status == ERROR_INSUFFICIENT_BUFFER) {
        pTcpTable = (PMIB_TCPTABLE) malloc(dwActualSize);
        if (pTcpTable != NULL) {
            /*
             * Get the sorted TCP table
             */
            status = GetTcpTable(pTcpTable, &dwActualSize, TRUE);
        }
    }

    if (status == NO_ERROR) {
        int           i;

        DEBUGMSGTL(("mibII/tcpTable", "Loaded TCP Table (WIN32)\n"));
        tcp_size = pTcpTable->dwNumEntries -1;  /* entries are counted starting with 0 */
        tcp_head = pTcpTable->table;

        /*
         * Count the number of established connections
         * Probably not actually necessary for Windows
         */
        for (i = 0; i < tcp_size; i++) {
            if (tcp_head[i].dwState == 5 /* established */ ||
                    tcp_head[i].dwState == 8 /*  closeWait  */ )
                tcp_estab++;
        }
        return 0;
    }

    DEBUGMSGTL(("mibII/tcpTable", "Failed to load TCP Table (win32)\n"));
    if (pTcpTable)
        free(pTcpTable);
    return -1;
}
コード例 #8
0
ファイル: netstat.c プロジェクト: Strongc/reactos
VOID ShowTcpTable()
{
    PMIB_TCPTABLE tcpTable;
    DWORD error, dwSize;
    DWORD i;
    CHAR HostIp[HOSTNAMELEN], HostPort[PORTNAMELEN];
    CHAR RemoteIp[HOSTNAMELEN], RemotePort[PORTNAMELEN];
    CHAR Host[ADDRESSLEN];
    CHAR Remote[ADDRESSLEN];

    /* Get the table of TCP endpoints */
    dwSize = sizeof (MIB_TCPTABLE);
    /* Should also work when we get new connections between 2 GetTcpTable()
     * calls: */
    do
    {
        tcpTable = (PMIB_TCPTABLE) HeapAlloc(GetProcessHeap(), 0, dwSize);
        error = GetTcpTable(tcpTable, &dwSize, TRUE);
        if ( error != NO_ERROR )
            HeapFree(GetProcessHeap(), 0, tcpTable);
    }
    while  ( error == ERROR_INSUFFICIENT_BUFFER );

    if (error != NO_ERROR)
    {
        printf("Failed to snapshot TCP endpoints.\n");
        DoFormatMessage(error);
        exit(EXIT_FAILURE);
    }

    /* Dump the TCP table */
    for (i = 0; i < tcpTable->dwNumEntries; i++)
    {
        /* If we aren't showing all connections, only display established, close wait
         * and time wait. This is the default output for netstat */
        if (bDoShowAllCons || (tcpTable->table[i].dwState ==  MIB_TCP_STATE_ESTAB)
            || (tcpTable->table[i].dwState ==  MIB_TCP_STATE_CLOSE_WAIT)
            || (tcpTable->table[i].dwState ==  MIB_TCP_STATE_TIME_WAIT))
        {
            /* I've split this up so it's easier to follow */
            GetIpHostName(TRUE, tcpTable->table[i].dwLocalAddr, HostIp, HOSTNAMELEN);
            GetPortName(tcpTable->table[i].dwLocalPort, "tcp", HostPort, PORTNAMELEN);
            GetIpHostName(FALSE, tcpTable->table[i].dwRemoteAddr, RemoteIp, HOSTNAMELEN);
            GetPortName(tcpTable->table[i].dwRemotePort, "tcp", RemotePort, PORTNAMELEN);

            sprintf(Host, "%s:%s", HostIp, HostPort);
            sprintf(Remote, "%s:%s", RemoteIp, RemotePort);

            _tprintf(_T("  %-6s %-22s %-22s %s\n"), _T("TCP"),
            Host, Remote, TcpState[tcpTable->table[i].dwState]);
        }
    }
    HeapFree(GetProcessHeap(), 0, tcpTable);
}
コード例 #9
0
static void NETSTAT_tcp_table(void)
{
    PMIB_TCPTABLE table;
    DWORD err, size, i;
    WCHAR HostIp[MAX_HOSTNAME_LEN], HostPort[32];
    WCHAR RemoteIp[MAX_HOSTNAME_LEN], RemotePort[32];
    WCHAR Host[MAX_HOSTNAME_LEN + 32];
    WCHAR Remote[MAX_HOSTNAME_LEN + 32];

    size = sizeof(MIB_TCPTABLE);
    do
    {
        table = (PMIB_TCPTABLE)HeapAlloc(GetProcessHeap(), 0, size);
        err = GetTcpTable(table, &size, TRUE);
        if (err != NO_ERROR) HeapFree(GetProcessHeap(), 0, table);
    } while (err == ERROR_INSUFFICIENT_BUFFER);

    if (err) return;

    for (i = 0; i < table->dwNumEntries; i++)
    {
        if ((table->table[i].u.dwState ==  MIB_TCP_STATE_CLOSE_WAIT) ||
                (table->table[i].u.dwState ==  MIB_TCP_STATE_ESTAB) ||
                (table->table[i].u.dwState ==  MIB_TCP_STATE_TIME_WAIT))
        {
            NETSTAT_host_name(table->table[i].dwLocalAddr, HostIp);
            NETSTAT_port_name(table->table[i].dwLocalPort, HostPort);
            NETSTAT_host_name(table->table[i].dwRemoteAddr, RemoteIp);
            NETSTAT_port_name(table->table[i].dwRemotePort, RemotePort);

            sprintfW(Host, fmtcolon, HostIp, HostPort);
            sprintfW(Remote, fmtcolon, RemoteIp, RemotePort);
            NETSTAT_wprintf(fmttcpout, tcpW, Host, Remote, tcpstatesW[table->table[i].u.dwState]);
        }
    }
    HeapFree(GetProcessHeap(), 0, table);
}
コード例 #10
0
ファイル: AdbUtils.cpp プロジェクト: zhangyongproject/VC
BOOL AdbUtils::PortUsedTCP(ULONG uPort)
{
	MIB_TCPTABLE TcpTable[100];
	DWORD nSize = sizeof(TcpTable);
	if (NO_ERROR == GetTcpTable(&TcpTable[0], &nSize, TRUE))
	{
		DWORD nCount = TcpTable[0].dwNumEntries;
		if (nCount > 0)
		{
			for (DWORD i=0; i<nCount; i++)
			{
				MIB_TCPROW TcpRow = TcpTable[0].table[i];
				DWORD temp1 = TcpRow.dwLocalPort;
				int temp2 = temp1 / 256 + (temp1 % 256) * 256;
				if (temp2 == uPort)
				{
					return TRUE;
				}
			}
		}
		return FALSE;
	}
	return FALSE;
}
コード例 #11
0
/*
 * retrieve tcp table for win 2000 and NT4 ?
 */
DWORD windows_get_tcp_table_win2000_down(struct connection_table **table_connection)
{
	PMIB_TCPTABLE pTcpTable = NULL;
	struct connection_entry * current_connection;
	DWORD dwSize = 0;
	DWORD dwRetVal = 0;
	DWORD result = ERROR_SUCCESS;
	DWORD i, state;

	do {
		dwRetVal = GetTcpTable(pTcpTable, &dwSize, TRUE);
		dprintf("[NETSTAT TCP] need %d bytes",dwSize);
		/* Get the size required by GetTcpTable() */
		if (dwRetVal == ERROR_INSUFFICIENT_BUFFER) {
			pTcpTable = (MIB_TCPTABLE *) malloc (dwSize);
		}
		else if (dwRetVal != NO_ERROR) {
				result = ERROR_NOT_SUPPORTED;
				break;
		}

		if ((dwRetVal = GetTcpTable(pTcpTable, &dwSize, TRUE)) == NO_ERROR) {
			dprintf("[NETSTAT] found %d tcp connections", pTcpTable->dwNumEntries);
			for (i = 0 ; i < pTcpTable->dwNumEntries ; i++) {
				// check available memory and allocate if necessary
				if (check_and_allocate(table_connection) == ERROR_NOT_ENOUGH_MEMORY) {
					free(pTcpTable);
					return ERROR_NOT_ENOUGH_MEMORY;
				}
				current_connection = &(*table_connection)->table[(*table_connection)->entries];
				current_connection->type             = AF_INET;
				current_connection->local_addr.addr  = pTcpTable->table[i].dwLocalAddr;
				current_connection->remote_addr.addr = pTcpTable->table[i].dwRemoteAddr;
				current_connection->local_port       = ntohs((u_short)(pTcpTable->table[i].dwLocalPort & 0x0000ffff));
				// if socket is in LISTEN, remote_port is garbage, force value to 0
				if (pTcpTable->table[i].dwState == MIB_TCP_STATE_LISTEN)
					current_connection->remote_port  = 0;
				else
					current_connection->remote_port  = ntohs((u_short)(pTcpTable->table[i].dwRemotePort & 0x0000ffff));

				state = pTcpTable->table[i].dwState;
				if ((state <= 0) || (state > 12))
					state = 13; // points to UNKNOWN in the state array
				strncpy(current_connection->state, tcp_connection_states[state], sizeof(current_connection->state));
				strncpy(current_connection->protocol, "tcp", sizeof(current_connection->protocol));

				// force program_name to "-"
				strncpy(current_connection->program_name, "-", sizeof(current_connection->program_name));

				(*table_connection)->entries++;
			}
			free(pTcpTable);
		}
		else { // GetTcpTable failed
			result = GetLastError();
			break;
		}
	} while (0) ;

	return result;
}
コード例 #12
0
ファイル: main.cpp プロジェクト: KenjiTakahashi/dotNET
void FillTcpTable(HWND hwnd) {
	MIB_TCPTABLE *tcpTable = (MIB_TCPTABLE*)malloc(sizeof(MIB_TCPTABLE));
	HWND listView = GetDlgItem(hwnd, TCP_LIST);
	LVITEM item;
	memset(&item, 0, sizeof(item));
	item.mask = LVIF_TEXT;
	item.cchTextMax = 256;
	struct in_addr IpAddr;
	TCHAR szLocalAddr[128];
	TCHAR szLocalPort[6];
	TCHAR szRemoteAddr[128];
	TCHAR szRemotePort[6];
	size_t num;
	DWORD expSize = sizeof(MIB_TCPTABLE);
	if(GetTcpTable(tcpTable, &expSize, TRUE) == ERROR_INSUFFICIENT_BUFFER) {
		free(tcpTable);
		tcpTable = (MIB_TCPTABLE*)malloc(expSize);
	}
	if(GetTcpTable(tcpTable, &expSize, TRUE) != NO_ERROR) {
		MessageBox(NULL, TEXT("Error retrieving TCP table!"), NULL, 0);
	} else {
		SendMessage(listView, LVM_DELETEALLITEMS, 0, 0);
		for(int i = 0; i < (int)tcpTable->dwNumEntries; ++i) {
			item.iItem = i;
			item.iSubItem = 0;
			switch(tcpTable->table[i].dwState) {
			case MIB_TCP_STATE_CLOSED:
				item.pszText = TEXT("CLOSED");
				break;
			case MIB_TCP_STATE_LISTEN:
				item.pszText = TEXT("LISTEN");
				break;
			case MIB_TCP_STATE_SYN_SENT:
				item.pszText = TEXT("SYN-SENT");
				break;
			case MIB_TCP_STATE_SYN_RCVD:
				item.pszText = TEXT("SYN-RECEIVED");
				break;
			case MIB_TCP_STATE_ESTAB:
				item.pszText = TEXT("ESTABLISHED");
				break;
			case MIB_TCP_STATE_FIN_WAIT1:
				item.pszText = TEXT("FIN-WAIT-1");
				break;
			case MIB_TCP_STATE_FIN_WAIT2:
				item.pszText = TEXT("FIN-WAIT-2");
				break;
			case MIB_TCP_STATE_CLOSE_WAIT:
				item.pszText = TEXT("CLOSE-WAIT");
				break;
			case MIB_TCP_STATE_CLOSING:
				item.pszText = TEXT("CLOSING");
				break;
			case MIB_TCP_STATE_LAST_ACK:
				item.pszText = TEXT("LAST-ACK");
				break;
			case MIB_TCP_STATE_TIME_WAIT:
				item.pszText = TEXT("TIME-WAIT");
				break;
			case MIB_TCP_STATE_DELETE_TCB:
				item.pszText = TEXT("DELETE-TCB");
				break;
			default:
				item.pszText = TEXT("UNKNOWN");
				break;
			}
			SendMessage(listView, LVM_INSERTITEM, i, (LPARAM)&item);
			IpAddr.S_un.S_addr = (u_long)tcpTable->table[i].dwLocalAddr;
			mbstowcs_s(&num, szLocalAddr, inet_ntoa(IpAddr), 128);
			item.iSubItem = 1;
			item.pszText = szLocalAddr;
			SendMessage(listView, LVM_SETITEM, i, (LPARAM)&item);
			_itow_s((u_short)tcpTable->table[i].dwLocalPort, szLocalPort, 6, 10);
			item.iSubItem = 2;
			item.pszText = szLocalPort;
			SendMessage(listView, LVM_SETITEM, i, (LPARAM)&item);
			IpAddr.S_un.S_addr = (u_long)tcpTable->table[i].dwRemoteAddr;
			mbstowcs_s(&num, szRemoteAddr, inet_ntoa(IpAddr), 128);
			item.iSubItem = 3;
			item.pszText = szRemoteAddr;
			SendMessage(listView, LVM_SETITEM, i, (LPARAM)&item);
			_itow_s((u_short)tcpTable->table[i].dwRemotePort, szRemotePort, 6, 10);
			item.iSubItem = 4;
			item.pszText = szRemotePort;
			SendMessage(listView, LVM_SETITEM, i, (LPARAM)&item);
		}
	}
	if(tcpTable) {
		free(tcpTable);
	}
}
コード例 #13
0
ファイル: socket.c プロジェクト: AlexSteel/wine
DWORD WINAPI WsControl(DWORD protocol,
                       DWORD action,
                       LPVOID pRequestInfo,
                       LPDWORD pcbRequestInfoLen,
                       LPVOID pResponseInfo,
                       LPDWORD pcbResponseInfoLen)
{

   /* Get the command structure into a pointer we can use,
      rather than void */
   TDIObjectID *pcommand = pRequestInfo;

   /* validate input parameters.  Error codes are from winerror.h, not from
    * winsock.h.  pcbResponseInfoLen is apparently allowed to be NULL for some
    * commands, since winipcfg.exe fails if we ensure it's non-NULL in every
    * case.
    */
   if (protocol != IPPROTO_TCP) return ERROR_INVALID_PARAMETER;
   if (!pcommand) return ERROR_INVALID_PARAMETER;
   if (!pcbRequestInfoLen) return ERROR_INVALID_ACCESS;
   if (*pcbRequestInfoLen < sizeof(TDIObjectID)) return ERROR_INVALID_ACCESS;
   if (!pResponseInfo) return ERROR_INVALID_PARAMETER;
   if (pcommand->toi_type != INFO_TYPE_PROVIDER) return ERROR_INVALID_PARAMETER;

   TRACE ("   WsControl TOI_ID=>0x%lx<, {TEI_ENTITY=0x%lx, TEI_INSTANCE=0x%lx}, TOI_CLASS=0x%lx, TOI_TYPE=0x%lx\n",
      pcommand->toi_id, pcommand->toi_entity.tei_entity,
      pcommand->toi_entity.tei_instance,
      pcommand->toi_class, pcommand->toi_type );

   switch (action)
   {
   case WSCNTL_TCPIP_QUERY_INFO:
   {
      if (pcommand->toi_class != INFO_CLASS_GENERIC &&
       pcommand->toi_class != INFO_CLASS_PROTOCOL)
      {
         ERR("Unexpected class %ld for WSCNTL_TCPIP_QUERY_INFO\n",
          pcommand->toi_class);
         return ERROR_BAD_ENVIRONMENT;
      }

      switch (pcommand->toi_id)
      {
         /* ENTITY_LIST_ID gets the list of "entity IDs", where an entity
            may represent an interface, or a datagram service, or address
            translation, or other fun things.  Typically an entity ID represents
            a class of service, which is further queried for what type it is.
            Different types will then have more specific queries defined.
         */
         case ENTITY_LIST_ID:
         {
            TDIEntityID *baseptr = pResponseInfo;
            DWORD numInt, i, ifTable, spaceNeeded;
            PMIB_IFTABLE table;

            if (!pcbResponseInfoLen)
               return ERROR_BAD_ENVIRONMENT;
            if (pcommand->toi_class != INFO_CLASS_GENERIC)
            {
               FIXME ("Unexpected Option for ENTITY_LIST_ID request -> toi_class=0x%lx\n",
                    pcommand->toi_class);
               return (ERROR_BAD_ENVIRONMENT);
            }

            GetNumberOfInterfaces(&numInt);
            spaceNeeded = sizeof(TDIEntityID) * (numInt * 2 + 3);

            if (*pcbResponseInfoLen < spaceNeeded)
               return (ERROR_LOCK_VIOLATION);

            ifTable = 0;
            GetIfTable(NULL, &ifTable, FALSE);
            table = HeapAlloc( GetProcessHeap(), 0, ifTable );
            if (!table)
               return ERROR_NOT_ENOUGH_MEMORY;
            GetIfTable(table, &ifTable, FALSE);

            spaceNeeded = sizeof(TDIEntityID) * (table->dwNumEntries + 4);
            if (*pcbResponseInfoLen < spaceNeeded)
            {
               HeapFree( GetProcessHeap(), 0, table );
               return ERROR_LOCK_VIOLATION;
            }

            memset(baseptr, 0, spaceNeeded);

            for (i = 0; i < table->dwNumEntries; i++)
            {
               /* Return IF_GENERIC and CL_NL_ENTITY on every interface, and
                * AT_ENTITY, CL_TL_ENTITY, and CO_TL_ENTITY on the first
                * interface.  MS returns them only on the loopback interface,
                * but it doesn't seem to matter.
                */
               if (i == 0)
               {
                  baseptr->tei_entity = CO_TL_ENTITY;
                  baseptr->tei_instance = table->table[i].dwIndex;
                  baseptr++;
                  baseptr->tei_entity = CL_TL_ENTITY;
                  baseptr->tei_instance = table->table[i].dwIndex;
                  baseptr++;
                  baseptr->tei_entity = AT_ENTITY;
                  baseptr->tei_instance = table->table[i].dwIndex;
                  baseptr++;
               }
               baseptr->tei_entity = CL_NL_ENTITY;
               baseptr->tei_instance = table->table[i].dwIndex;
               baseptr++;
               baseptr->tei_entity = IF_GENERIC;
               baseptr->tei_instance = table->table[i].dwIndex;
               baseptr++;
            }

            *pcbResponseInfoLen = spaceNeeded;
            HeapFree( GetProcessHeap(), 0, table );
            break;
         }

         /* Returns MIB-II statistics for an interface */
         case ENTITY_TYPE_ID:
            switch (pcommand->toi_entity.tei_entity)
            {
            case IF_GENERIC:
               if (pcommand->toi_class == INFO_CLASS_GENERIC)
               {
                  if (!pcbResponseInfoLen)
                     return ERROR_BAD_ENVIRONMENT;
                  *((ULONG *)pResponseInfo) = IF_MIB;
                  *pcbResponseInfoLen = sizeof(ULONG);
               }
               else if (pcommand->toi_class == INFO_CLASS_PROTOCOL)
               {
                  MIB_IFROW row;
                  DWORD index = pcommand->toi_entity.tei_instance, ret;
                  DWORD size = sizeof(row) - sizeof(row.wszName) -
                   sizeof(row.bDescr);

                  if (!pcbResponseInfoLen)
                     return ERROR_BAD_ENVIRONMENT;
                  if (*pcbResponseInfoLen < size)
                     return (ERROR_LOCK_VIOLATION);
                  row.dwIndex = index;
                  ret = GetIfEntry(&row);
                  if (ret != NO_ERROR)
                  {
                     /* FIXME: Win98's arp.exe insists on querying index 1 for
                      * its MIB-II stats, regardless of the tei_instances
                      * returned in the ENTITY_LIST query above.  If the query
                      * fails, arp.exe fails.  So, I do this hack return value
                      * if index is 1 and the query failed just to get arp.exe
                      * to continue.
                      */
                     if (index == 1)
                        return NO_ERROR;
                     ERR ("Error retrieving data for interface index %u\n",
                      index);
                     return ret;
                  }
                  size = sizeof(row) - sizeof(row.wszName) -
                   sizeof(row.bDescr) + row.dwDescrLen;
                  if (*pcbResponseInfoLen < size)
                     return (ERROR_LOCK_VIOLATION);
                  memcpy(pResponseInfo, &row.dwIndex, size);
                  *pcbResponseInfoLen = size;
               }
               break;

            /* Returns address-translation related data.  In our case, this is
             * ARP.
             */
            case AT_ENTITY:
               if (pcommand->toi_class == INFO_CLASS_GENERIC)
               {
                  if (!pcbResponseInfoLen)
                     return ERROR_BAD_ENVIRONMENT;
                  *((ULONG *)pResponseInfo) = AT_ARP;
                  *pcbResponseInfoLen = sizeof(ULONG);
               }
               else if (pcommand->toi_class == INFO_CLASS_PROTOCOL)
               {
                  PMIB_IPNETTABLE table;
                  DWORD size;
                  PULONG output = pResponseInfo;

                  if (!pcbResponseInfoLen)
                     return ERROR_BAD_ENVIRONMENT;
                  if (*pcbResponseInfoLen < sizeof(ULONG) * 2)
                     return (ERROR_LOCK_VIOLATION);
                  GetIpNetTable(NULL, &size, FALSE);
                  table = HeapAlloc( GetProcessHeap(), 0, size );
                  if (!table)
                     return ERROR_NOT_ENOUGH_MEMORY;
                  GetIpNetTable(table, &size, FALSE);
                  /* FIXME: I don't understand the meaning of the ARP output
                   * very well, but it seems to indicate how many ARP entries
                   * exist.  I don't know whether this should reflect the
                   * number per interface, as I'm only testing with a single
                   * interface.  So, I lie and say all ARP entries exist on
                   * a single interface--the first one that appears in the
                   * ARP table.
                   */
                  *(output++) = table->dwNumEntries;
                  *output = table->table[0].dwIndex;
                  HeapFree( GetProcessHeap(), 0, table );
                  *pcbResponseInfoLen = sizeof(ULONG) * 2;
               }
               break;

            /* Returns connectionless network layer statistics--in our case,
             * this is IP.
             */
            case CL_NL_ENTITY:
               if (pcommand->toi_class == INFO_CLASS_GENERIC)
               {
                  if (!pcbResponseInfoLen)
                     return ERROR_BAD_ENVIRONMENT;
                  *((ULONG *)pResponseInfo) = CL_NL_IP;
                  *pcbResponseInfoLen = sizeof(ULONG);
               }
               else if (pcommand->toi_class == INFO_CLASS_PROTOCOL)
               {
                  if (!pcbResponseInfoLen)
                     return ERROR_BAD_ENVIRONMENT;
                  if (*pcbResponseInfoLen < sizeof(MIB_IPSTATS))
                     return ERROR_LOCK_VIOLATION;
                  GetIpStatistics(pResponseInfo);

                  *pcbResponseInfoLen = sizeof(MIB_IPSTATS);
               }
               break;

            /* Returns connectionless transport layer statistics--in our case,
             * this is UDP.
             */
            case CL_TL_ENTITY:
               if (pcommand->toi_class == INFO_CLASS_GENERIC)
               {
                  if (!pcbResponseInfoLen)
                     return ERROR_BAD_ENVIRONMENT;
                  *((ULONG *)pResponseInfo) = CL_TL_UDP;
                  *pcbResponseInfoLen = sizeof(ULONG);
               }
               else if (pcommand->toi_class == INFO_CLASS_PROTOCOL)
               {
                  if (!pcbResponseInfoLen)
                     return ERROR_BAD_ENVIRONMENT;
                  if (*pcbResponseInfoLen < sizeof(MIB_UDPSTATS))
                     return ERROR_LOCK_VIOLATION;
                  GetUdpStatistics(pResponseInfo);
                  *pcbResponseInfoLen = sizeof(MIB_UDPSTATS);
               }
               break;

            /* Returns connection-oriented transport layer statistics--in our
             * case, this is TCP.
             */
            case CO_TL_ENTITY:
               if (pcommand->toi_class == INFO_CLASS_GENERIC)
               {
                  if (!pcbResponseInfoLen)
                     return ERROR_BAD_ENVIRONMENT;
                  *((ULONG *)pResponseInfo) = CO_TL_TCP;
                  *pcbResponseInfoLen = sizeof(ULONG);
               }
               else if (pcommand->toi_class == INFO_CLASS_PROTOCOL)
               {
                  if (!pcbResponseInfoLen)
                     return ERROR_BAD_ENVIRONMENT;
                  if (*pcbResponseInfoLen < sizeof(MIB_TCPSTATS))
                     return ERROR_LOCK_VIOLATION;
                  GetTcpStatistics(pResponseInfo);
                  *pcbResponseInfoLen = sizeof(MIB_TCPSTATS);
               }
               break;

            default:
               ERR("Unknown entity %ld for ENTITY_TYPE_ID query\n",
                pcommand->toi_entity.tei_entity);
         }
         break;

         /* This call returns the IP address, subnet mask, and broadcast
          * address for an interface.  If there are multiple IP addresses for
          * the interface with the given index, returns the "first" one.
          */
         case IP_MIB_ADDRTABLE_ENTRY_ID:
         {
            DWORD index = pcommand->toi_entity.tei_instance;
            PMIB_IPADDRROW baseIPInfo = pResponseInfo;
            PMIB_IPADDRTABLE table;
            DWORD tableSize, i;

            if (!pcbResponseInfoLen)
               return ERROR_BAD_ENVIRONMENT;
            if (*pcbResponseInfoLen < sizeof(MIB_IPADDRROW))
               return (ERROR_LOCK_VIOLATION);

            /* get entire table, because there isn't an exported function that
               gets just one entry. */
            tableSize = 0;
            GetIpAddrTable(NULL, &tableSize, FALSE);
            table = HeapAlloc( GetProcessHeap(), 0, tableSize );
            if (!table)
               return ERROR_NOT_ENOUGH_MEMORY;
            GetIpAddrTable(table, &tableSize, FALSE);
            for (i = 0; i < table->dwNumEntries; i++)
            {
               if (table->table[i].dwIndex == index)
               {
                  TRACE("Found IP info for tei_instance 0x%x:\n", index);
                  TRACE("IP 0x%08x, mask 0x%08x\n", table->table[i].dwAddr,
                   table->table[i].dwMask);
                  *baseIPInfo = table->table[i];
                  break;
               }
            }
            HeapFree( GetProcessHeap(), 0, table );

            *pcbResponseInfoLen = sizeof(MIB_IPADDRROW);
            break;
         }

         case IP_MIB_TABLE_ENTRY_ID:
         {
            switch (pcommand->toi_entity.tei_entity)
            {
            /* This call returns the routing table.
             * No official documentation found, even the name of the command is unknown.
             * Work is based on
             * http://www.cyberport.com/~tangent/programming/winsock/articles/wscontrol.html
             * and testings done with winipcfg.exe, route.exe and ipconfig.exe.
             * pcommand->toi_entity.tei_instance seems to be the interface number
             * but route.exe outputs only the information for the last interface
             * if only the routes for the pcommand->toi_entity.tei_instance
             * interface are returned. */
               case CL_NL_ENTITY:
               {
                  DWORD routeTableSize, numRoutes, ndx, ret;
                  PMIB_IPFORWARDTABLE table;
                  IPRouteEntry *winRouteTable  = pResponseInfo;

                  if (!pcbResponseInfoLen)
                     return ERROR_BAD_ENVIRONMENT;
                  ret = GetIpForwardTable(NULL, &routeTableSize, FALSE);
                  if (ret != ERROR_INSUFFICIENT_BUFFER)
                      return ret;
                  numRoutes = (routeTableSize - sizeof(MIB_IPFORWARDTABLE))
                   / sizeof(MIB_IPFORWARDROW) + 1;
                  if (*pcbResponseInfoLen < sizeof(IPRouteEntry) * numRoutes)
                     return (ERROR_LOCK_VIOLATION);
                  table = HeapAlloc( GetProcessHeap(), 0, routeTableSize );
                  if (!table)
                     return ERROR_NOT_ENOUGH_MEMORY;
                  ret = GetIpForwardTable(table, &routeTableSize, FALSE);
                  if (ret != NO_ERROR) {
                     HeapFree( GetProcessHeap(), 0, table );
                     return ret;
                  }

                  memset(pResponseInfo, 0, sizeof(IPRouteEntry) * numRoutes);
                  for (ndx = 0; ndx < table->dwNumEntries; ndx++)
                  {
                     winRouteTable->ire_addr = table->table[ndx].dwForwardDest;
                     winRouteTable->ire_index =
                      table->table[ndx].dwForwardIfIndex;
                     winRouteTable->ire_metric =
                      table->table[ndx].dwForwardMetric1;
                     /* winRouteTable->ire_option4 =
                     winRouteTable->ire_option5 =
                     winRouteTable->ire_option6 = */
                     winRouteTable->ire_gw = table->table[ndx].dwForwardNextHop;
                     /* winRouteTable->ire_option8 =
                     winRouteTable->ire_option9 =
                     winRouteTable->ire_option10 = */
                     winRouteTable->ire_mask = table->table[ndx].dwForwardMask;
                     /* winRouteTable->ire_option12 = */
                     winRouteTable++;
                  }

                  /* calculate the length of the data in the output buffer */
                  *pcbResponseInfoLen = sizeof(IPRouteEntry) *
                   table->dwNumEntries;

                  HeapFree( GetProcessHeap(), 0, table );
               }
               break;

               case AT_ARP:
               {
                  DWORD arpTableSize, numEntries, ret;
                  PMIB_IPNETTABLE table;

                  if (!pcbResponseInfoLen)
                     return ERROR_BAD_ENVIRONMENT;
                  ret = GetIpNetTable(NULL, &arpTableSize, FALSE);
                  if (ret != ERROR_INSUFFICIENT_BUFFER)
                      return ret;
                  numEntries = (arpTableSize - sizeof(MIB_IPNETTABLE))
                   / sizeof(MIB_IPNETROW) + 1;
                  if (*pcbResponseInfoLen < sizeof(MIB_IPNETROW) * numEntries)
                     return (ERROR_LOCK_VIOLATION);
                  table = HeapAlloc( GetProcessHeap(), 0, arpTableSize );
                  if (!table)
                     return ERROR_NOT_ENOUGH_MEMORY;
                  ret = GetIpNetTable(table, &arpTableSize, FALSE);
                  if (ret != NO_ERROR) {
                     HeapFree( GetProcessHeap(), 0, table );
                     return ret;
                  }
                  if (*pcbResponseInfoLen < sizeof(MIB_IPNETROW) *
                   table->dwNumEntries)
                  {
                     HeapFree( GetProcessHeap(), 0, table );
                     return ERROR_LOCK_VIOLATION;
                  }
                  memcpy(pResponseInfo, table->table, sizeof(MIB_IPNETROW) *
                   table->dwNumEntries);

                  /* calculate the length of the data in the output buffer */
                  *pcbResponseInfoLen = sizeof(MIB_IPNETROW) *
                   table->dwNumEntries;

                  HeapFree( GetProcessHeap(), 0, table );
               }
               break;

               case CO_TL_ENTITY:
               {
                  DWORD tcpTableSize, numEntries, ret;
                  PMIB_TCPTABLE table;
                  DWORD i;

                  if (!pcbResponseInfoLen)
                     return ERROR_BAD_ENVIRONMENT;
                  ret = GetTcpTable(NULL, &tcpTableSize, FALSE);
                  if (ret != ERROR_INSUFFICIENT_BUFFER)
                      return ret;
                  numEntries = (tcpTableSize - sizeof(MIB_TCPTABLE))
                   / sizeof(MIB_TCPROW) + 1;
                  if (*pcbResponseInfoLen < sizeof(MIB_TCPROW) * numEntries)
                     return (ERROR_LOCK_VIOLATION);
                  table = HeapAlloc( GetProcessHeap(), 0, tcpTableSize );
                  if (!table)
                     return ERROR_NOT_ENOUGH_MEMORY;
                  ret = GetTcpTable(table, &tcpTableSize, FALSE);
                  if (ret != NO_ERROR) {
                     HeapFree( GetProcessHeap(), 0, table );
                     return ret;
                  }
                  if (*pcbResponseInfoLen < sizeof(MIB_TCPROW) *
                   table->dwNumEntries)
                  {
                     HeapFree( GetProcessHeap(), 0, table );
                     return ERROR_LOCK_VIOLATION;
                  }
                  for (i = 0; i < table->dwNumEntries; i++)
                  {
                     USHORT sPort;

                     sPort = ntohs((USHORT)table->table[i].dwLocalPort);
                     table->table[i].dwLocalPort = (DWORD)sPort;
                     sPort = ntohs((USHORT)table->table[i].dwRemotePort);
                     table->table[i].dwRemotePort = (DWORD)sPort;
                  }
                  memcpy(pResponseInfo, table->table, sizeof(MIB_TCPROW) *
                   table->dwNumEntries);

                  /* calculate the length of the data in the output buffer */
                  *pcbResponseInfoLen = sizeof(MIB_TCPROW) *
                   table->dwNumEntries;

                  HeapFree( GetProcessHeap(), 0, table );
               }
               break;

               default:
               {
                  FIXME ("Command ID Not Supported -> toi_id=0x%lx, toi_entity={tei_entity=0x%lx, tei_instance=0x%lx}, toi_class=0x%lx\n",
                     pcommand->toi_id, pcommand->toi_entity.tei_entity,
                     pcommand->toi_entity.tei_instance, pcommand->toi_class);

                  return (ERROR_BAD_ENVIRONMENT);
               }
            }
         }
         break;


         default:
         {
            FIXME ("Command ID Not Supported -> toi_id=0x%lx, toi_entity={tei_entity=0x%lx, tei_instance=0x%lx}, toi_class=0x%lx\n",
               pcommand->toi_id, pcommand->toi_entity.tei_entity,
               pcommand->toi_entity.tei_instance, pcommand->toi_class);

            return (ERROR_BAD_ENVIRONMENT);
         }
      }

      break;
   }

   case WSCNTL_TCPIP_ICMP_ECHO:
   {
      unsigned int addr = *(unsigned int*)pRequestInfo;
#if 0
         int timeout= *(unsigned int*)(inbuf+4);
         short x1 = *(unsigned short*)(inbuf+8);
         short sendbufsize = *(unsigned short*)(inbuf+10);
         char x2 = *(unsigned char*)(inbuf+12);
         char ttl = *(unsigned char*)(inbuf+13);
         char service = *(unsigned char*)(inbuf+14);
         char type= *(unsigned char*)(inbuf+15); /* 0x2: don't fragment*/
#endif

      FIXME("(ICMP_ECHO) to 0x%08x stub\n", addr);
      break;
   }

   default:
      FIXME("Protocol Not Supported -> protocol=0x%x, action=0x%x, Request=%p, RequestLen=%p, Response=%p, ResponseLen=%p\n",
       protocol, action, pRequestInfo, pcbRequestInfoLen, pResponseInfo, pcbResponseInfoLen);

      return (WSAEOPNOTSUPP);

   }

   return (WSCTL_SUCCESS);
}
コード例 #14
0
ファイル: w_iphlpapi.c プロジェクト: berenddeboer/eposix
EIF_INTEGER posix_gettcptable(EIF_POINTER pTcpTable, EIF_POINTER pwdSize, EIF_BOOLEAN bOrder) {
    return GetTcpTable (pTcpTable, pwdSize, bOrder);
}