Ejemplo n.º 1
0
VOID ShowEthernetStatistics()
{
    PMIB_IFTABLE pIfTable;
    DWORD dwSize = 0;
    DWORD dwRetVal = 0;

    pIfTable = (MIB_IFTABLE*) HeapAlloc(GetProcessHeap(), 0, sizeof(MIB_IFTABLE));

    if (GetIfTable(pIfTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER)
    {
        HeapFree(GetProcessHeap(), 0, pIfTable);
        pIfTable = (MIB_IFTABLE*) HeapAlloc(GetProcessHeap(), 0, dwSize);

        if ((dwRetVal = GetIfTable(pIfTable, &dwSize, 0)) == NO_ERROR)
        {
            _tprintf(_T("Interface Statistics\n\n"));
            _tprintf(_T("                           Received            Sent\n\n"));
            _tprintf(_T("%-20s %14lu %15lu\n"), _T("Bytes"),
                pIfTable->table[0].dwInOctets, pIfTable->table[0].dwOutOctets);
            _tprintf(_T("%-20s %14lu %15lu\n"), _T("Unicast packets"),
                pIfTable->table[0].dwInUcastPkts, pIfTable->table[0].dwOutUcastPkts);
            _tprintf(_T("%-20s %14lu %15lu\n"), _T("Non-unicast packets"),
                pIfTable->table[0].dwInNUcastPkts, pIfTable->table[0].dwOutNUcastPkts);
            _tprintf(_T("%-20s %14lu %15lu\n"), _T("Discards"),
                pIfTable->table[0].dwInDiscards, pIfTable->table[0].dwOutDiscards);
            _tprintf(_T("%-20s %14lu %15lu\n"), _T("Errors"),
                pIfTable->table[0].dwInErrors, pIfTable->table[0].dwOutErrors);
            _tprintf(_T("%-20s %14lu\n"), _T("Unknown Protocols"),
                pIfTable->table[0].dwInUnknownProtos);
        }
        else
            DoFormatMessage(dwRetVal);
    }
    HeapFree(GetProcessHeap(), 0, pIfTable);
}
Ejemplo n.º 2
0
static PMIB_IFTABLE win32_get_devices()
{
	PMIB_IFTABLE if_table;
	PMIB_IFTABLE tmp;
	unsigned long dwSize = 0;

	// Allocate memory for pointers
	if_table = sg_malloc(sizeof(MIB_IFTABLE));
	if(if_table == NULL) {
		return NULL;
	}

	// Get necessary size for the buffer
	if(GetIfTable(if_table, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER) {
		tmp = sg_realloc(if_table, dwSize);
		if(tmp == NULL) {
			free(if_table);
			return NULL;
		}
		if_table = tmp;
	}

	// Get the data
	if(GetIfTable(if_table, &dwSize, 0) != NO_ERROR) {
		free(if_table);
		return NULL;
	}
	return if_table;
}
Ejemplo n.º 3
0
NetUsage::NetUsage()
{
	m_OutLen = 0;
	GetIfTable(NULL, &m_OutLen, FALSE);
	m_OutBuf = new BYTE[m_OutLen];
	DWORD ret = GetIfTable((PMIB_IFTABLE)m_OutBuf, &m_OutLen, FALSE);
	USES_CONVERSION;
	if(ret == NO_ERROR)
	{
		MIB_IFTABLE *pIfTable = (MIB_IFTABLE *)m_OutBuf;
		for(DWORD a=0; a<pIfTable->dwNumEntries; a++)
		{
			MIB_IFROW & row = pIfTable->table[a];
			NetIf ni;
			ni.InSpeed = 0;
			ni.LastIn = row.dwInOctets;
			ni.LastOut = row.dwOutOctets;
			ni.Name = A2W((LPCSTR)row.bDescr);
			ni.OutSpeed = 0;
			m_IfRow.push_back(ni);

		}
		
	}
	SYSTEMTIME st;
	::GetLocalTime(&st);
	FILETIME ft;
	SystemTimeToFileTime(&st, &ft);
	//m_LastTime = time((time_t *)&m_LastTime);
	memcpy(&m_LastTime, &ft, sizeof(ULONGLONG));
}
Ejemplo n.º 4
0
/*
 * Returns the interface structure from the table with the matching index.
 */
MIB_IFROW *getIF(jint index) {
    MIB_IFTABLE *tableP;
    MIB_IFROW *ifrowP, *ret = NULL;
    ULONG size;
    DWORD i, count;
    jint ifindex;

    /*
     * Ask the IP Helper library to enumerate the adapters
     */
    size = sizeof(MIB_IFTABLE);
    tableP = (MIB_IFTABLE *)malloc(size);
    if(tableP == NULL)
        return NULL;

    count = GetIfTable(tableP, &size, TRUE);
    if (count == ERROR_INSUFFICIENT_BUFFER || count == ERROR_BUFFER_OVERFLOW) {
        MIB_IFTABLE* newTableP =  (MIB_IFTABLE *)realloc(tableP, size);
        if (newTableP == NULL) {
            free(tableP);
            return NULL;
        }
        tableP = newTableP;

        count = GetIfTable(tableP, &size, TRUE);
    }

    if (count != NO_ERROR) {
        free(tableP);
        return NULL;
    }

    {
        ifrowP = tableP->table;
        for (i=0; i<tableP->dwNumEntries; i++) {
            /*
             * Warning: the real index is obtained by GetFriendlyIfIndex()
            */
            ifindex = GetFriendlyIfIndex(ifrowP->dwIndex);
            if (ifindex == index) {
                /*
                 * Create a copy of the entry so that we can free the table.
                 */
                ret = (MIB_IFROW *) malloc(sizeof(MIB_IFROW));
                if (ret == NULL) {
                    free(tableP);
                    return NULL;
                }
                memcpy(ret, ifrowP, sizeof(MIB_IFROW));
                break;
            }

            /* onto the next interface */
            ifrowP++;
        }
        free(tableP);
    }
    return ret;
}
Ejemplo n.º 5
0
Archivo: main.c Proyecto: iamfil/wine
static void mib2IfNumberInit(void)
{
    DWORD size = 0, ret = GetIfTable(NULL, &size, FALSE);

    if (ret == ERROR_INSUFFICIENT_BUFFER)
    {
        ifTable = HeapAlloc(GetProcessHeap(), 0, size);
        if (ifTable)
            GetIfTable(ifTable, &size, FALSE);
    }
}
Ejemplo n.º 6
0
static void mib2IfNumberInit(void)
{
    DWORD size = 0, ret = GetIfTable(NULL, &size, FALSE);

    if (ret == ERROR_INSUFFICIENT_BUFFER)
    {
        MIB_IFTABLE *table = HeapAlloc(GetProcessHeap(), 0, size);
        if (table)
        {
            if (!GetIfTable(table, &size, FALSE)) ifTable = table;
            else HeapFree(GetProcessHeap(), 0, table );
        }
    }
}
Ejemplo n.º 7
0
void get_iface_stats_win32 (char verbose) {
	PMIB_IFTABLE if_table,tmp;
	unsigned long tableSize;
	int i,current_if_num,hidden_if=0,err;
	char name[MAX_INTERFACE_NAME_LEN];
	t_iface_speed_stats tmp_if_stats;
	t_iface_speed_stats stats; /* local struct, used to calc total values */

	memset(&stats,0,(size_t)sizeof(t_iface_speed_stats)); /* init it */
	tableSize=sizeof(MIB_IFTABLE);
	if_table = malloc(sizeof(MIB_IFTABLE));
	if (if_table==NULL) return;

	/* get table size or data if table is big enough */
	if ((err=GetIfTable(if_table, &tableSize, 0)==ERROR_INSUFFICIENT_BUFFER)) {
		tmp = realloc(if_table, tableSize);
		if (tmp==NULL) {
			free(if_table);
			return;
		}
		if_table=tmp;
		/* get data */
		err=GetIfTable(if_table, &tableSize, 0);
	}
	if (err != NO_ERROR) {
		free(if_table);
		return;
	}

	current_if_num=0;

	for (i=0; i<if_table->dwNumEntries; i++) {
		strncpy(name,(char*)(if_table->table[i].bDescr),MAX_INTERFACE_NAME_LEN);	
		name[MAX_INTERFACE_NAME_LEN-1]='\0';
		tmp_if_stats.bytes.in=if_table->table[i].dwInOctets;
		tmp_if_stats.bytes.out=if_table->table[i].dwOutOctets;
		tmp_if_stats.packets.in=if_table->table[i].dwInUcastPkts + if_table->table[i].dwInNUcastPkts;
		tmp_if_stats.packets.out=if_table->table[i].dwOutUcastPkts + if_table->table[i].dwOutNUcastPkts;
		tmp_if_stats.errors.in=if_table->table[i].dwInErrors;
		tmp_if_stats.errors.out=if_table->table[i].dwOutErrors;
		/* init new interfaces and add fetched data to old or new one */
		hidden_if = process_if_data (hidden_if, tmp_if_stats, &stats, name, current_if_num, verbose, 1);
		current_if_num++;
	}	
	/* add to total stats and output current stats if verbose */
	finish_iface_stats (verbose, stats, hidden_if,current_if_num);

	free(if_table);
	return;
}
Ejemplo n.º 8
0
Archivo: net.c Proyecto: cinience/saker
static int  get_if_stats(const char *if_name, MIB_IFROW *pIfRow) {
    DWORD       dwSize, dwRetVal, i;
    int     ret = UGERR;
    /* variables used for GetIfTable and GetIfEntry */
    MIB_IFTABLE *pIfTable = NULL;
    MIB_IFROW   TmpIfRow;
    /* Allocate memory for our pointers. */
    dwSize = sizeof(MIB_IFTABLE);
    pIfTable = (MIB_IFTABLE *)zmalloc( dwSize);

    /* Before calling GetIfEntry, we call GetIfTable to make
       sure there are entries to get and retrieve the interface index.
       Make an initial call to GetIfTable to get the necessary size into dwSize */
    if (ERROR_INSUFFICIENT_BUFFER == GetIfTable(pIfTable, &dwSize, 0))
        pIfTable = (MIB_IFTABLE *)zrealloc(pIfTable, dwSize);

    /* Make a second call to GetIfTable to get the actual data we want. */
    if (NO_ERROR != (dwRetVal = GetIfTable(pIfTable, &dwSize, 0))) {
        LOG_DEBUG("GetIfTable failed with error: %s", xerrmsg());
        goto clean;
    }

    memset(pIfRow,0,sizeof(MIB_IFROW));
    for (i = 0; i < pIfTable->dwNumEntries; i++) {
        memset(&TmpIfRow,0,sizeof(MIB_IFROW));
        TmpIfRow.dwIndex = pIfTable->table[i].dwIndex;
        if (NO_ERROR != (dwRetVal = GetIfEntry(&TmpIfRow))) {
            LOG_DEBUG("GetIfEntry failed with error: %s",
                      xerrmsg());
            continue;
        }

        /* ignore loopback addr */
        if (0 == strcmp(if_name, TmpIfRow.bDescr))
            continue;
        pIfRow->dwInOctets+=TmpIfRow.dwInOctets;
        pIfRow->dwOutOctets+=TmpIfRow.dwOutOctets;
        pIfRow->dwInErrors+=TmpIfRow.dwInErrors;
        pIfRow->dwOutErrors+=TmpIfRow.dwOutErrors;
        pIfRow->dwInUcastPkts+=TmpIfRow.dwInUcastPkts;
        pIfRow->dwInNUcastPkts+=TmpIfRow.dwInNUcastPkts;
        pIfRow->dwOutUcastPkts+=TmpIfRow.dwOutUcastPkts;
        pIfRow->dwOutNUcastPkts+=TmpIfRow.dwOutNUcastPkts;
        ret = UGOK;
    }
clean:
    zfree(pIfTable);
    return ret;
}
Ejemplo n.º 9
0
	bool CheckNetworkAlive()
	{
		bool bRet = false;

		DWORD dwTableSize = 0;
		PMIB_IFTABLE lpTable = NULL;

		// Get struct size
		if (ERROR_INSUFFICIENT_BUFFER != GetIfTable(NULL, &dwTableSize, FALSE))
		{
			return bRet;
		}

		// Allocate memory
		lpTable = (PMIB_IFTABLE) new char[dwTableSize];
		if (NULL == lpTable)
		{
			return bRet;
		}

		// Get Info
		if (ERROR_SUCCESS != GetIfTable(lpTable, &dwTableSize, FALSE))
		{
			delete [] lpTable;
			return bRet;
		}

		for (DWORD i=0; i<lpTable->dwNumEntries; ++i)
		{
			if(( lpTable->table[i].dwType == MIB_IF_TYPE_ETHERNET || 
				lpTable->table[i].dwType == MIB_IF_TYPE_PPP) && 
				( lpTable->table[i].dwOperStatus == MIB_IF_OPER_STATUS_CONNECTED ||
				lpTable->table[i].dwOperStatus ==  MIB_IF_OPER_STATUS_OPERATIONAL))
			{
				if(IsIPAvailable())
				{
					bRet = true;
					break;
				}
			}
		}

		if (NULL != lpTable)
		{
			delete [] lpTable;
		}

		return bRet;
	}
Ejemplo n.º 10
0
BOOL NetUsage::Update()
{
	SYSTEMTIME st;
	::GetLocalTime(&st);
	FILETIME ft;
	SystemTimeToFileTime(&st, &ft);
	
	ULONGLONG t = 0;
	memcpy(&t, &ft, sizeof(ULONGLONG));
	DWORD ret = GetIfTable((PMIB_IFTABLE)m_OutBuf, &m_OutLen, FALSE);
	if(ret == NO_ERROR)
	{
		MIB_IFTABLE *pIfTable = (MIB_IFTABLE *)m_OutBuf;
		for(DWORD a=0; a<pIfTable->dwNumEntries; a++)
		{
			MIB_IFROW & row = pIfTable->table[a];
			NetIf & ni = m_IfRow[a];
			DWORD n =(DWORD) (t - m_LastTime)/10000;
			if(n==0) break;
			ni.InSpeed = (1000*(row.dwInOctets - ni.LastIn))/n;
			ni.OutSpeed = (1000*(row.dwOutOctets - ni.LastOut))/n;
			ni.LastOut = row.dwOutOctets;
			ni.LastIn = row.dwInOctets;
			
		}
		
	}
	memcpy(&m_LastTime, &t, sizeof(ULONGLONG));
	return ret;
}
Ejemplo n.º 11
0
int
get_min_mtu( void )
{
  DWORD ret, dwInterface, dwSize = 0;
  PMIB_IFTABLE ifTable;
  PMIB_IFROW ifRow;
  unsigned min_mtu = 0;

  dwSize = sizeof(MIB_IFTABLE);
  ifTable = (PMIB_IFTABLE)malloc(dwSize);
  while ((ret = GetIfTable(ifTable, &dwSize, 1)) == ERROR_INSUFFICIENT_BUFFER) {
    ifTable = (PMIB_IFTABLE)realloc(ifTable, dwSize);
  }

  if (ret = NO_ERROR) {
    for (dwInterface = 0; dwInterface < (ifTable -> dwNumEntries); dwInterface++) {
      ifRow = &(ifTable -> table[dwInterface]);

      if ((ifRow -> dwType != MIB_IF_TYPE_LOOPBACK) && (ifRow -> dwOperStatus ==MIB_IF_OPER_STATUS_OPERATIONAL)) {
        if (min_mtu) {
          if (ifRow -> dwMtu < min_mtu) {
            min_mtu = ifRow -> dwMtu;
          }
        } else {
          min_mtu = ifRow -> dwMtu;
        }
      }
    }
    free(ifTable);
  }
  return min_mtu;
}
Ejemplo n.º 12
0
static void NETSTAT_eth_stats(void)
{
    PMIB_IFTABLE table;
    DWORD err, size, i;
    DWORD octets[2], ucastpkts[2], nucastpkts[2], discards[2], errors[2], unknown;
    WCHAR recv[19];

    size = sizeof(MIB_IFTABLE);
    do
    {
        table = (PMIB_IFTABLE)HeapAlloc(GetProcessHeap(), 0, size);
        err = GetIfTable(table, &size, FALSE);
        if (err != NO_ERROR) HeapFree(GetProcessHeap(), 0, table);
    } while (err == ERROR_INSUFFICIENT_BUFFER);

    if (err) return;

    NETSTAT_wprintf(NETSTAT_load_message(IDS_ETH_STAT));
    NETSTAT_wprintf(fmtn);
    NETSTAT_wprintf(fmtn);
    strcpyW(recv, NETSTAT_load_message(IDS_ETH_RECV));
    NETSTAT_wprintf(fmtethheader, recv, NETSTAT_load_message(IDS_ETH_SENT));

    octets[0] = octets[1] = 0;
    ucastpkts[0] = ucastpkts[1] = 0;
    nucastpkts[0] = nucastpkts[1] = 0;
    discards[0] = discards[1] = 0;
    errors[0] = errors[1] = 0;
    unknown = 0;

    for (i = 0; i < table->dwNumEntries; i++)
    {
        octets[0] += table->table[i].dwInOctets;
        octets[1] += table->table[i].dwOutOctets;
        ucastpkts[0] += table->table[i].dwInUcastPkts;
        ucastpkts[1] += table->table[i].dwOutUcastPkts;
        nucastpkts[0] += table->table[i].dwInNUcastPkts;
        nucastpkts[1] += table->table[i].dwOutNUcastPkts;
        discards[0] += table->table[i].dwInDiscards;
        discards[1] += table->table[i].dwOutDiscards;
        errors[0] += table->table[i].dwInErrors;
        errors[1] += table->table[i].dwOutErrors;
        unknown += table->table[i].dwInUnknownProtos;
    }

    NETSTAT_wprintf(fmtethout, NETSTAT_load_message(IDS_ETH_BYTES), octets[0], octets[1]);
    NETSTAT_wprintf(fmtethout, NETSTAT_load_message(IDS_ETH_UNICAST), ucastpkts[0], ucastpkts[1]);
    NETSTAT_wprintf(fmtethout, NETSTAT_load_message(IDS_ETH_NUNICAST), nucastpkts[0], nucastpkts[1]);
    NETSTAT_wprintf(fmtethout, NETSTAT_load_message(IDS_ETH_DISCARDS), discards[0], discards[1]);
    NETSTAT_wprintf(fmtethout, NETSTAT_load_message(IDS_ETH_ERRORS), errors[0], errors[1]);
    NETSTAT_wprintf(fmtethoutu, NETSTAT_load_message(IDS_ETH_UNKNOWN), unknown);

    HeapFree(GetProcessHeap(), 0, table);
}
Ejemplo n.º 13
0
static time_t
get_netbw(double *in_bytes, double *out_bytes,
    double *in_pkts, double *out_pkts)
{
  PMIB_IFTABLE iftable;
  double bytes_in = 0, bytes_out = 0, pkts_in = 0, pkts_out = 0;
  static DWORD dwSize;
  DWORD ret, dwInterface;
  struct timeb timebuffer;
  PMIB_IFROW ifrow;

  dwSize = sizeof(MIB_IFTABLE);
  
  iftable = (PMIB_IFTABLE) malloc (dwSize);
  while ((ret = GetIfTable(iftable, &dwSize, 1)) == ERROR_INSUFFICIENT_BUFFER) {
     iftable = (PMIB_IFTABLE) realloc (iftable, dwSize);
  }
 
  if (ret == NO_ERROR) { 

    ftime ( &timebuffer );

    /* scan the interface table */
    for (dwInterface = 0; dwInterface < (iftable -> dwNumEntries); dwInterface++) {
      ifrow = &(iftable -> table[dwInterface]);
    
    /* exclude loopback */
      if ( (ifrow -> dwType != MIB_IF_TYPE_LOOPBACK ) && (ifrow -> dwOperStatus ==MIB_IF_OPER_STATUS_OPERATIONAL ) ) {
        bytes_in += ifrow -> dwInOctets;
        bytes_out += ifrow -> dwOutOctets;
      
        /* does not include multicast traffic (dw{In,Out}NUcastPkts) */
        pkts_in += ifrow -> dwInUcastPkts;
        pkts_out += ifrow -> dwOutUcastPkts;
      }
    }
    free (iftable);
  } else {
    err_msg("get_netbw() got an error from GetIfTable()");
  }

  if (in_bytes) *in_bytes = bytes_in;
  if (out_bytes) *out_bytes = bytes_out;
  if (in_pkts) *in_pkts = pkts_in;
  if (out_pkts) *out_pkts = pkts_out;

  return timebuffer.time;
}
Ejemplo n.º 14
0
static int
_refresh_tables(intf_t *intf)
{
	MIB_IFROW *ifrow;
	ULONG len;
	u_int i, ret;

	/* Get interface table. */
	for (len = sizeof(intf->iftable[0]); ; ) {
		if (intf->iftable)
			free(intf->iftable);
		intf->iftable = malloc(len);
		ret = GetIfTable(intf->iftable, &len, FALSE);
		if (ret == NO_ERROR)
			break;
		else if (ret != ERROR_INSUFFICIENT_BUFFER)
			return (-1);
	}
	/* Get IP address table. */
	for (len = sizeof(intf->iptable[0]); ; ) {
		if (intf->iptable)
			free(intf->iptable);
		intf->iptable = malloc(len);
		ret = GetIpAddrTable(intf->iptable, &len, FALSE);
		if (ret == NO_ERROR)
			break;
		else if (ret != ERROR_INSUFFICIENT_BUFFER)
			return (-1);
	}
	/*
	 * Map "unfriendly" win32 interface indices to ours.
	 * XXX - like IP_ADAPTER_INFO ComboIndex
	 */
	for (i = 0; i < intf->iftable->dwNumEntries; i++) {
		ifrow = &intf->iftable->table[i];
		if (ifrow->dwType < MIB_IF_TYPE_MAX) {
			_ifcombo_add(&intf->ifcombo[ifrow->dwType],
			    ifrow->dwIndex);
		} else
			return (-1);
	}
	return (0);
}
Ejemplo n.º 15
0
static int win32_getiftable(struct ifstat_driver *driver,
			    PMIB_IFTABLE *iftable) {
  struct win32_driver_data *data = driver->data;
  ULONG size;
  DWORD ret;

  size = data->len;
  while ((ret = GetIfTable((PMIB_IFTABLE) data->buf,
			   &size, 1)) == ERROR_INSUFFICIENT_BUFFER) {
    data->len = size * 2;
    if ((data->buf = realloc(data->buf, data->len)) == NULL) {
      perror("realloc");
      return 0;
    }
  }
  
  if (ret == NO_ERROR) {
    *iftable = (PMIB_IFTABLE) data->buf;
    return 1;
  }
  
  perror("GetIfTable");
  return 0;
}
Ejemplo n.º 16
0
/*
 * returns interface statistics by IP address or interface name
 */
static int	get_if_stats(const char *if_name, MIB_IFROW *pIfRow)
{
	DWORD		dwSize, dwRetVal, i, j;
	int		ret = FAIL;
	char		ip[16];
	/* variables used for GetIfTable and GetIfEntry */
	MIB_IFTABLE	*pIfTable = NULL;
	/* variables used for GetIpAddrTable */
	MIB_IPADDRTABLE	*pIPAddrTable = NULL;
	IN_ADDR		in_addr;

	/* Allocate memory for our pointers. */
	dwSize = sizeof(MIB_IPADDRTABLE);
	pIPAddrTable = (MIB_IPADDRTABLE *)zbx_malloc(pIPAddrTable, sizeof(MIB_IPADDRTABLE));

	/* Make an initial call to GetIpAddrTable to get the
	   necessary size into the dwSize variable */
	if (ERROR_INSUFFICIENT_BUFFER == GetIpAddrTable(pIPAddrTable, &dwSize, 0))
		pIPAddrTable = (MIB_IPADDRTABLE *)zbx_realloc(pIPAddrTable, dwSize);

	/* Make a second call to GetIpAddrTable to get the
	   actual data we want */
	if (NO_ERROR != (dwRetVal = GetIpAddrTable(pIPAddrTable, &dwSize, 0)))
	{
		zabbix_log(LOG_LEVEL_DEBUG, "GetIpAddrTable failed with error: %s", strerror_from_system(dwRetVal));
		goto clean;
	}

	/* Allocate memory for our pointers. */
	dwSize = sizeof(MIB_IFTABLE);
	pIfTable = (MIB_IFTABLE *)zbx_malloc(pIfTable, dwSize);

	/* Before calling GetIfEntry, we call GetIfTable to make
	   sure there are entries to get and retrieve the interface index.
	   Make an initial call to GetIfTable to get the necessary size into dwSize */
	if (ERROR_INSUFFICIENT_BUFFER == GetIfTable(pIfTable, &dwSize, 0))
		pIfTable = (MIB_IFTABLE *)zbx_realloc(pIfTable, dwSize);

	/* Make a second call to GetIfTable to get the actual data we want. */
	if (NO_ERROR != (dwRetVal = GetIfTable(pIfTable, &dwSize, 0)))
	{
		zabbix_log(LOG_LEVEL_DEBUG, "GetIfTable failed with error: %s", strerror_from_system(dwRetVal));
		goto clean;
	}

	for (i = 0; i < pIfTable->dwNumEntries; i++)
	{
		LPTSTR	wdescr;
		LPSTR	utf8_descr;

		pIfRow->dwIndex = pIfTable->table[i].dwIndex;
		if (NO_ERROR != (dwRetVal = GetIfEntry(pIfRow)))
		{
			zabbix_log(LOG_LEVEL_DEBUG, "GetIfEntry failed with error: %s",
					strerror_from_system(dwRetVal));
			continue;
		}

		wdescr = zbx_acp_to_unicode(pIfRow->bDescr);
		utf8_descr = zbx_unicode_to_utf8(wdescr);
		if (0 == strcmp(if_name, utf8_descr))
			ret = SUCCEED;
		zbx_free(utf8_descr);
		zbx_free(wdescr);

		if (SUCCEED == ret)
			break;

		for (j = 0; j < pIPAddrTable->dwNumEntries; j++)
		{
			if (pIPAddrTable->table[j].dwIndex == pIfRow->dwIndex)
			{
				in_addr.S_un.S_addr = pIPAddrTable->table[j].dwAddr;
				zbx_snprintf(ip, sizeof(ip), "%s", inet_ntoa(in_addr));
				if (0 == strcmp(if_name, ip))
				{
					ret = SUCCEED;
					break;
				}
			}
		}

		if (SUCCEED == ret)
			break;
	}
clean:
	zbx_free(pIfTable);
	zbx_free(pIPAddrTable);

	return ret;
}
Ejemplo n.º 17
0
int	NET_IF_LIST(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result)
{
	DWORD		dwSize, dwRetVal, i, j;
	char		*buf = NULL;
	size_t		buf_alloc = 512, buf_offset = 0;
	int		ret = SYSINFO_RET_FAIL;
	/* variables used for GetIfTable and GetIfEntry */
	MIB_IFTABLE	*pIfTable = NULL;
	MIB_IFROW	pIfRow;
	/* variables used for GetIpAddrTable */
	MIB_IPADDRTABLE	*pIPAddrTable = NULL;
	IN_ADDR		in_addr;

	/* Allocate memory for our pointers. */
	dwSize = sizeof(MIB_IPADDRTABLE);
	pIPAddrTable = (MIB_IPADDRTABLE *)zbx_malloc(pIPAddrTable, sizeof(MIB_IPADDRTABLE));

	/* Make an initial call to GetIpAddrTable to get the
	   necessary size into the dwSize variable */
	if (ERROR_INSUFFICIENT_BUFFER == GetIpAddrTable(pIPAddrTable, &dwSize, 0))
		pIPAddrTable = (MIB_IPADDRTABLE *)zbx_realloc(pIPAddrTable, dwSize);

	/* Make a second call to GetIpAddrTable to get the
	   actual data we want */
	if (NO_ERROR != (dwRetVal = GetIpAddrTable(pIPAddrTable, &dwSize, 0)))
	{
		zabbix_log(LOG_LEVEL_DEBUG, "GetIpAddrTable failed with error: %s", strerror_from_system(dwRetVal));
		goto clean;
	}

	/* Allocate memory for our pointers. */
	dwSize = sizeof(MIB_IFTABLE);
	pIfTable = (MIB_IFTABLE *)zbx_malloc(pIfTable, dwSize);

	/* Before calling GetIfEntry, we call GetIfTable to make
	   sure there are entries to get and retrieve the interface index.
	   Make an initial call to GetIfTable to get the necessary size into dwSize */
	if (ERROR_INSUFFICIENT_BUFFER == GetIfTable(pIfTable, &dwSize, 0))
		pIfTable = (MIB_IFTABLE *)zbx_realloc(pIfTable, dwSize);

	/* Make a second call to GetIfTable to get the actual data we want. */
	if (NO_ERROR != (dwRetVal = GetIfTable(pIfTable, &dwSize, 0)))
	{
		zabbix_log(LOG_LEVEL_DEBUG, "GetIfTable failed with error: %s", strerror_from_system(dwRetVal));
		goto clean;
	}

	buf = (char *)zbx_malloc(buf, sizeof(char) * buf_alloc);

	if (pIfTable->dwNumEntries > 0)
	{
		for (i = 0; i < (int)pIfTable->dwNumEntries; i++)
		{
			LPTSTR	wdescr;
			LPSTR	utf8_descr;

			pIfRow.dwIndex = pIfTable->table[i].dwIndex;
			if (NO_ERROR != (dwRetVal = GetIfEntry(&pIfRow)))
			{
				zabbix_log(LOG_LEVEL_DEBUG, "GetIfEntry failed with error: %s",
						strerror_from_system(dwRetVal));
				continue;
			}

			zbx_snprintf_alloc(&buf, &buf_alloc, &buf_offset,
					"%-25s", get_if_type_string(pIfRow.dwType));

			zbx_snprintf_alloc(&buf, &buf_alloc, &buf_offset,
					" %-8s", get_if_adminstatus_string(pIfRow.dwAdminStatus));

			for (j = 0; j < pIPAddrTable->dwNumEntries; j++)
				if (pIPAddrTable->table[j].dwIndex == pIfRow.dwIndex)
				{
					in_addr.S_un.S_addr = pIPAddrTable->table[j].dwAddr;
					zbx_snprintf_alloc(&buf, &buf_alloc, &buf_offset,
							" %-15s", inet_ntoa(in_addr));
					break;
				}

			if (j == pIPAddrTable->dwNumEntries)
				zbx_strcpy_alloc(&buf, &buf_alloc, &buf_offset, " -");

			wdescr = zbx_acp_to_unicode(pIfRow.bDescr);
			utf8_descr = zbx_unicode_to_utf8(wdescr);
			zbx_snprintf_alloc(&buf, &buf_alloc, &buf_offset, " %s\n", utf8_descr);
			zbx_free(utf8_descr);
			zbx_free(wdescr);
		}
	}

	SET_TEXT_RESULT(result, buf);

	ret = SYSINFO_RET_OK;
clean:
	zbx_free(pIfTable);
	zbx_free(pIPAddrTable);

	return ret;
}
jbyteArray getHardwareAddress(JNIEnv* env, jstring ifName)
{
    MIB_IFTABLE* ifTable = NULL;
    ULONG size = 15000;
    int found = 0;
    jbyteArray hwaddr = NULL;
    DWORD ret = 0;
    DWORD i = 0;
    WCHAR* wname = NULL;
    MIB_IFROW ifi;
    jclass clazz = (*env)->GetObjectClass(env, ifName);
    jmethodID method = (*env)->GetMethodID(env, clazz, "compareTo", "(Ljava/lang/String;)I");

    if(method == NULL)
    {
        return NULL;
    }

    memset(&ifi, 0x00, sizeof(MIB_IFROW));

    do
    {
        ifTable = malloc(size);

        if(!ifTable)
        {
            /* out of memory */
            return NULL;
        }

        ret = GetIfTable(ifTable, &size, 1);

    }while(ret == ERROR_INSUFFICIENT_BUFFER);

    if(ret != ERROR_SUCCESS)
    {
        free(ifTable);
        return NULL;
    }

    for(i = 0 ; i < ifTable->dwNumEntries ; i++)
    {
        jstring tmp = NULL;
        ifi = ifTable->table[i];

        if(ifi.dwType == IF_TYPE_OTHER)
        {
            continue;
        }

        /* jstring created by NewStringUTF will be garbage collected at 
         * the end of the function 
         */
        tmp = (*env)->NewStringUTF(env, ifi.bDescr);

        if(!tmp)
        {
            /* printf("error\n"); */
            continue;
        }

        if((*env)->CallIntMethod(env, ifName, method, tmp) == 0)
        {
            found = 1;
            break;
        }
    }

    if(found)
    {
        DWORD hwlen = ifi.dwPhysAddrLen;

        if(hwlen > 0)
        {
            hwaddr = (*env)->NewByteArray(env, hwlen);

            if(hwaddr)
            {
                /* copy the hardware address and return it */
                (*env)->SetByteArrayRegion(env, hwaddr, 0, hwlen, ifi.bPhysAddr);
            }
        }
    }

    /* cleanup */
    free(ifTable);

    return hwaddr;
}
Ejemplo n.º 19
0
int	NET_IF_DISCOVERY(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result)
{
	DWORD		dwSize, dwRetVal, i;
	int		ret = SYSINFO_RET_FAIL;
	/* variables used for GetIfTable and GetIfEntry */
	MIB_IFTABLE	*pIfTable = NULL;
	MIB_IFROW	pIfRow;
	struct zbx_json	j;
	LPTSTR		wdescr;
	LPSTR		utf8_descr;

	zbx_json_init(&j, ZBX_JSON_STAT_BUF_LEN);

	zbx_json_addarray(&j, ZBX_PROTO_TAG_DATA);

	/* Allocate memory for our pointers. */
	dwSize = sizeof(MIB_IFTABLE);
	pIfTable = (MIB_IFTABLE *)zbx_malloc(pIfTable, dwSize);

	/* Before calling GetIfEntry, we call GetIfTable to make
	   sure there are entries to get and retrieve the interface index.
	   Make an initial call to GetIfTable to get the necessary size into dwSize */
	if (ERROR_INSUFFICIENT_BUFFER == GetIfTable(pIfTable, &dwSize, 0))
		pIfTable = (MIB_IFTABLE *)zbx_realloc(pIfTable, dwSize);

	/* Make a second call to GetIfTable to get the actual data we want. */
	if (NO_ERROR != (dwRetVal = GetIfTable(pIfTable, &dwSize, 0)))
	{
		zabbix_log(LOG_LEVEL_DEBUG, "GetIfTable failed with error: %s", strerror_from_system(dwRetVal));
		goto clean;
	}

	for (i = 0; i < pIfTable->dwNumEntries; i++)
	{
		pIfRow.dwIndex = pIfTable->table[i].dwIndex;
		if (NO_ERROR != (dwRetVal = GetIfEntry(&pIfRow)))
		{
			zabbix_log(LOG_LEVEL_DEBUG, "GetIfEntry failed with error: %s", strerror_from_system(dwRetVal));
			continue;
		}

		zbx_json_addobject(&j, NULL);

		wdescr = zbx_acp_to_unicode(pIfRow.bDescr);
		utf8_descr = zbx_unicode_to_utf8(wdescr);
		zbx_json_addstring(&j, "{#IFNAME}", utf8_descr, ZBX_JSON_TYPE_STRING);
		zbx_free(utf8_descr);
		zbx_free(wdescr);

		zbx_json_close(&j);
	}

	zbx_json_close(&j);

	SET_STR_RESULT(result, strdup(j.buffer));

	zbx_json_free(&j);

	ret = SYSINFO_RET_OK;
clean:
	zbx_free(pIfTable);

	return ret;
}
Ejemplo n.º 20
0
/*
** Reads the tables for all net interfaces
**
*/
void CMeasureNet::UpdateIFTable()
{
	bool logging = false;

	if (c_GetIfTable2)
	{
		if (c_Table)
		{
			c_FreeMibTable(c_Table);
			c_Table = NULL;
		}

		if (c_GetIfTable2((MIB_IF_TABLE2**)&c_Table) == NO_ERROR)
		{
			MIB_IF_TABLE2* ifTable = (MIB_IF_TABLE2*)c_Table;

			if (c_NumOfTables != ifTable->NumEntries)
			{
				c_NumOfTables = ifTable->NumEntries;
				logging = true;
			}

			if (Rainmeter->GetDebug() && logging)
			{
				Log(LOG_DEBUG, L"------------------------------");
				LogWithArgs(LOG_DEBUG, L"* NETWORK-INTERFACE: Count=%i", c_NumOfTables);

				for (size_t i = 0; i < c_NumOfTables; ++i)
				{
					std::wstring type;
					switch (ifTable->Table[i].Type)
					{
					case IF_TYPE_ETHERNET_CSMACD:
						type += L"Ethernet";
						break;
					case IF_TYPE_PPP:
						type += L"PPP";
						break;
					case IF_TYPE_SOFTWARE_LOOPBACK:
						type += L"Loopback";
						break;
					case IF_TYPE_IEEE80211:
						type += L"IEEE802.11";
						break;
					case IF_TYPE_TUNNEL:
						type += L"Tunnel";
						break;
					case IF_TYPE_IEEE1394:
						type += L"IEEE1394";
						break;
					default:
						type += L"Other";
						break;
					}

					LogWithArgs(LOG_DEBUG, L"%i: %s", (int)i + 1, ifTable->Table[i].Description);
					LogWithArgs(LOG_DEBUG, L"  Alias: %s", ifTable->Table[i].Alias);
					LogWithArgs(LOG_DEBUG, L"  Type=%s(%i), Hardware=%s, Filter=%s",
						type.c_str(), ifTable->Table[i].Type,
						(ifTable->Table[i].InterfaceAndOperStatusFlags.HardwareInterface == 1) ? L"Yes" : L"No",
						(ifTable->Table[i].InterfaceAndOperStatusFlags.FilterInterface == 1) ? L"Yes" : L"No");
				}
				Log(LOG_DEBUG, L"------------------------------");
			}
		}
		else
		{
			// Something's wrong. Unable to get the table.
			c_Table = NULL;
			c_NumOfTables = 0;
		}
	}
	else
	{
		if (c_Table == NULL)
		{
			// Gotta reserve few bytes for the tables
			DWORD value = 0;
			if (GetNumberOfInterfaces(&value) == NO_ERROR)
			{
				if (c_NumOfTables != value)
				{
					c_NumOfTables = value;
					logging = true;
				}

				if (c_NumOfTables > 0)
				{
					DWORD size = sizeof(MIB_IFTABLE) + sizeof(MIB_IFROW) * c_NumOfTables;
					c_Table = new BYTE[size];
				}
			}
		}

		if (c_Table)
		{
			DWORD ret, size = 0;

			MIB_IFTABLE* ifTable = (MIB_IFTABLE*)c_Table;

			if ((ret = GetIfTable(ifTable, &size, FALSE)) == ERROR_INSUFFICIENT_BUFFER)
			{
				delete [] c_Table;
				c_Table = new BYTE[size];

				ifTable = (MIB_IFTABLE*)c_Table;

				ret = GetIfTable(ifTable, &size, FALSE);
			}

			if (ret == NO_ERROR)
			{
				if (c_NumOfTables != ifTable->dwNumEntries)
				{
					c_NumOfTables = ifTable->dwNumEntries;
					logging = true;
				}

				if (Rainmeter->GetDebug() && logging)
				{
					Log(LOG_DEBUG, L"------------------------------");
					LogWithArgs(LOG_DEBUG, L"* NETWORK-INTERFACE: Count=%i", c_NumOfTables);

					for (size_t i = 0; i < c_NumOfTables; ++i)
					{
						std::string desc((char*)ifTable->table[i].bDescr, ifTable->table[i].dwDescrLen);

						std::wstring type;
						switch (ifTable->table[i].dwType)
						{
						case IF_TYPE_ETHERNET_CSMACD:
							type += L"Ethernet";
							break;
						case IF_TYPE_PPP:
							type += L"PPP";
							break;
						case IF_TYPE_SOFTWARE_LOOPBACK:
							type += L"Loopback";
							break;
						case IF_TYPE_IEEE80211:
							type += L"IEEE802.11";
							break;
						case IF_TYPE_TUNNEL:
							type += L"Tunnel";
							break;
						case IF_TYPE_IEEE1394:
							type += L"IEEE1394";
							break;
						default:
							type += L"Other";
							break;
						}

						LogWithArgs(LOG_DEBUG, L"%i: %s", (int)i + 1, ConvertToWide(desc.c_str()).c_str());
						LogWithArgs(LOG_DEBUG, L"  Type=%s(%i)",
							type.c_str(), ifTable->table[i].dwType);
					}
					Log(LOG_DEBUG, L"------------------------------");
				}
			}
			else
			{
				// Something's wrong. Unable to get the table.
				delete [] c_Table;
				c_Table = NULL;
				c_NumOfTables = 0;
			}
		}
	}
}
Ejemplo n.º 21
0
int main()
{
    // Declare and initialize variables.
    DWORD dwSize = 0;
    DWORD dwRetVal = 0;

    int i, j;

    /* variables used for GetIfTable and GetIfEntry */
    MIB_IFTABLE *pIfTable;
    MIB_IFROW *pIfRow;

    // Allocate memory for our pointers.
    pIfTable = (MIB_IFTABLE *) MALLOC(sizeof (MIB_IFTABLE));
    if (pIfTable == NULL) {
        printf("Error allocating memory needed to call GetIfTable\n");
        return 1;
    }
    // Make an initial call to GetIfTable to get the
    // necessary size into dwSize
    dwSize = sizeof (MIB_IFTABLE);
    if (GetIfTable(pIfTable, &dwSize, FALSE) == ERROR_INSUFFICIENT_BUFFER)
    {
        FREE(pIfTable);
        pIfTable = (MIB_IFTABLE *) MALLOC(dwSize);
        if (pIfTable == NULL)
        {
            printf("Error allocating memory needed to call GetIfTable\n");
            return 1;
        }
    }
    // Make a second call to GetIfTable to get the actual
    // data we want.
    if ((dwRetVal = GetIfTable(pIfTable, &dwSize, FALSE)) == NO_ERROR)
    {
        printf("\tNum Entries: %ld\n\n", pIfTable->dwNumEntries);
        for (i = 0; i < (int) pIfTable->dwNumEntries; i++)
        {
            pIfRow = (MIB_IFROW *) & pIfTable->table[i];
            printf("\tIndex[%d]:\t %ld\n", i, pIfRow->dwIndex);
            printf("\tInterfaceName[%d]:\t %ws", i, pIfRow->wszName);
            printf("\n");
            printf("\tDescription[%d]:\t ", i);
            for (j = 0; j < (int) pIfRow->dwDescrLen; j++)
                printf("%c", pIfRow->bDescr[j]);
            printf("\n");
            printf("\tType[%d]:\t ", i);
            switch (pIfRow->dwType)
            {
            case IF_TYPE_OTHER:
                printf("Other\n");
                break;
            case IF_TYPE_ETHERNET_CSMACD:
                printf("Ethernet\n");
                break;
            case IF_TYPE_ISO88025_TOKENRING:
                printf("Token Ring\n");
                break;
            case IF_TYPE_PPP:
                printf("PPP\n");
                break;
            case IF_TYPE_SOFTWARE_LOOPBACK:
                printf("Software Lookback\n");
                break;
            case IF_TYPE_ATM:
                printf("ATM\n");
                break;
            case IF_TYPE_IEEE80211:
                printf("IEEE 802.11 Wireless\n");
                break;
            case IF_TYPE_TUNNEL:
                printf("Tunnel type encapsulation\n");
                break;
            case IF_TYPE_IEEE1394:
                printf("IEEE 1394 Firewire\n");
                break;
            default:
                printf("Unknown type %ld\n", pIfRow->dwType);
                break;
            }
            printf("\tMtu[%d]:\t\t %ld\n", i, pIfRow->dwMtu);
            printf("\tSpeed[%d]:\t %ld\n", i, pIfRow->dwSpeed);
            printf("\tPhysical Addr:\t ");
            if (pIfRow->dwPhysAddrLen == 0)
                printf("\n");
            for (j = 0; j < (int) pIfRow->dwPhysAddrLen; j++)
            {
                if (j == (pIfRow->dwPhysAddrLen - 1))
                    printf("%.2X\n", (int) pIfRow->bPhysAddr[j]);
                else
                    printf("%.2X-", (int) pIfRow->bPhysAddr[j]);
            }
            printf("\tAdmin Status[%d]:\t %ld\n", i, pIfRow->dwAdminStatus);
            printf("\tOper Status[%d]:\t ", i);
            switch (pIfRow->dwOperStatus)
            {
            case IF_OPER_STATUS_NON_OPERATIONAL:
                printf("Non Operational\n");
                break;
            case IF_OPER_STATUS_UNREACHABLE:
                printf("Unreachable\n");
                break;
            case IF_OPER_STATUS_DISCONNECTED:
                printf("Disconnected\n");
                break;
            case IF_OPER_STATUS_CONNECTING:
                printf("Connecting\n");
                break;
            case IF_OPER_STATUS_CONNECTED:
                printf("Connected\n");
                break;
            case IF_OPER_STATUS_OPERATIONAL:
                printf("Operational\n");
                break;
            default:
                printf("Unknown status %ld\n", pIfRow->dwAdminStatus);
                break;
            }
            printf("\n");
        }
    } 
    else
    {
        printf("GetIfTable failed with error: \n", dwRetVal);
        if (pIfTable != NULL)
        {
            FREE(pIfTable);
            pIfTable = NULL;
        } 
        return 1;
        // Here you can use FormatMessage to find out why
        // it failed.
    }
    if (pIfTable != NULL)
    {
        FREE(pIfTable);
        pIfTable = NULL;
    }
    return 0;
}
Ejemplo n.º 22
0
/**
 * Canonize interface name. If attempt is not NULL, pick the interface
 * which has that address.
 * If attempt is NULL, pick interfaces in the following order of preference
 * 1. eth0
 * 2. Anything starting with eth0:
 * 3. Anything starting with eth
 * 4. Anything else
 * 5. localhost
 * 6. zero address
 */
net_if_t *getNetIf(const char *wanted) {
#ifndef __MINGW32__
	struct ifreq *ifrp, *ifend, *chosen;
	struct ifconf ifc;
	int s;
#else /* __MINGW32__ */
	int i;

	int etherNo=-1;
	int wantedEtherNo=-2; /* Wanted ethernet interface */

	MIB_IPADDRTABLE *iptab=NULL;
	MIB_IFTABLE *iftab=NULL;

	MIB_IPADDRROW *iprow, *chosen=NULL;
	MIB_IFROW *chosenIf=NULL;
	WORD wVersionRequested; /* Version of Winsock to load */
	WSADATA wsaData; /* Winsock implementation details */
	ULONG a;

	int r;
#endif /* __MINGW32__ */

	int lastGoodness=0;
	struct in_addr wantedAddress;
	int isAddress=0;
	int wantedLen=0;
	net_if_t *net_if;

	if(wanted == NULL) {
	    wanted = getenv("IFNAME");
	}

	if(wanted && INET_ATON(wanted, &wantedAddress))
	    isAddress=1;
	else
	    wantedAddress.s_addr=0;

	if(wanted)
	    wantedLen=strlen(wanted);

	net_if = MALLOC(net_if_t);
	if(net_if == NULL)
	    udpc_fatal(1, "Out of memory error");

#ifndef __MINGW32__

	s = socket(PF_INET, SOCK_DGRAM, 0);
	if (s < 0) {
	    perror("make socket");
	    exit(1);
	}

	ifc.ifc_len = sizeof(struct ifreq) * 10;
	while(1) {
	    size_t len = ifc.ifc_len;
	    ifc.ifc_buf = (caddr_t) malloc(ifc.ifc_len);
	    if(ifc.ifc_buf == NULL) {
		udpc_fatal(1, "Out of memory error");
	    }

	    if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0 ||
		ifc.ifc_len < (signed int)sizeof(struct ifreq)) {
		perror("udpcast: SIOCGIFCONF: ");
		exit(1);
	    }

	    if(len == ifc.ifc_len) {
		ifc.ifc_len += sizeof(struct ifreq) * 10;
		free(ifc.ifc_buf);
	    } else
		break;
	}

	ifend = (struct ifreq *)((char *)ifc.ifc_buf + ifc.ifc_len);
	chosen=NULL;

	for (ifrp = (struct ifreq *) ifc.ifc_buf ; ifrp < ifend;
#ifdef IFREQ_SIZE
	     ifrp = IFREQ_SIZE(*ifrp) + (char *)ifrp
#else
	     ifrp++
#endif
	     ) {
	    unsigned long iaddr = getSinAddr(&ifrp->ifr_addr).s_addr;
	    int goodness;

	    if(ifrp->ifr_addr.sa_family != PF_INET)
		continue;

	    if(wanted) {
		if(isAddress && iaddr == wantedAddress.s_addr) {
		    goodness=8;
		} else if(strcmp(wanted, ifrp->ifr_name) ==0) {
		    /* perfect match on interface name */
		    goodness=12;
		} else if(wanted != NULL &&
			  strncmp(wanted, ifrp->ifr_name, wantedLen) ==0) {
		    /* prefix match on interface name */
		    goodness=7;
		} else {
		    /* no match, try next */
		    continue;
		}
	    } else {
		if(iaddr == 0) {
		    /* disregard interfaces whose address is zero */
		    goodness = 1;
		} else if(iaddr == htonl(0x7f000001)) {
		    /* disregard localhost type devices */
		    goodness = 2;
		} else if(strcmp("eth0", ifrp->ifr_name) == 0 ||
			  strcmp("en0",  ifrp->ifr_name) == 0) {
		    /* prefer first ethernet interface */
		    goodness = 6;
		} else if(strncmp("eth0:", ifrp->ifr_name, 5) == 0) {
		    /* second choice: any secondary addresses of first ethernet */
		    goodness = 5;
		} else if(strncmp("eth", ifrp->ifr_name, 3) == 0 ||
			  strncmp("en",  ifrp->ifr_name, 2) == 0) {
		    /* and, if not available, any other ethernet device */
		    goodness = 4;
		} else {
		    goodness = 3;
		}
	    }

	    if(hasLink(s, ifrp->ifr_name))
	      /* Good or unknown link status privileged over known
	       * disconnected */
	      goodness += 3;

	    /* If all else is the same, prefer interfaces that
	     * have broadcast */
	    goodness = goodness * 2;
	    if(goodness >= lastGoodness) {
		/* Privilege broadcast-enabled interfaces */
		if(ioctl(s,  SIOCGIFBRDADDR, ifrp) < 0)
		    udpc_fatal(-1, "Error getting broadcast address for %s: %s",
			       ifrp->ifr_name, strerror(errno));
		if(getSinAddr(&ifrp->ifr_ifru.ifru_broadaddr).s_addr)
		    goodness++;
	    }

	    if(goodness > lastGoodness) {
		chosen = ifrp;
		lastGoodness = goodness;
		net_if->addr.s_addr = iaddr;
	    }
	}


	if(!chosen) {
	    fprintf(stderr, "No suitable network interface found\n");
	    fprintf(stderr, "The following interfaces are available:\n");

	    for (ifrp = (struct ifreq *) ifc.ifc_buf ; ifrp < ifend;
#ifdef IFREQ_SIZE
		 ifrp = IFREQ_SIZE(*ifrp) + (char *)ifrp
#else
		 ifrp++
#endif
		 ) {
		char buffer[16];

		if(ifrp->ifr_addr.sa_family != PF_INET)
		    continue;

		fprintf(stderr, "\t%s\t%s\n",
			ifrp->ifr_name,
			udpc_getIpString((struct sockaddr_in *)&ifrp->ifr_addr, buffer));
	    }
	    exit(1);
	}

	net_if->name = strdup(chosen->ifr_name);

#ifdef HAVE_STRUCT_IP_MREQN_IMR_IFINDEX
	/* Index for multicast subscriptions */
	if(ioctl(s,  SIOCGIFINDEX, chosen) < 0)
	    udpc_fatal(-1, "Error getting index for %s: %s", net_if->name,
		       strerror(errno));
	net_if->index = chosen->ifr_ifindex;
#endif

	/* Broadcast */
	if(ioctl(s,  SIOCGIFBRDADDR, chosen) < 0)
	    udpc_fatal(-1, "Error getting broadcast address for %s: %s",
		       net_if->name, strerror(errno));
	net_if->bcast = getSinAddr(&chosen->ifr_ifru.ifru_broadaddr);

	close(s);
	free(ifc.ifc_buf);

#else /* __MINGW32__ */

	/* WINSOCK initialization */
	wVersionRequested = MAKEWORD(2, 0); /* Request Winsock v2.0 */
	if (WSAStartup(wVersionRequested, &wsaData) != 0) /* Load Winsock DLL */ {
	    fprintf(stderr,"WSAStartup() failed");
	    exit(1);
	}
	/* End WINSOCK initialization */


	a=0;
	r=GetIpAddrTable(iptab, &a, TRUE);
	iptab=malloc(a);
	r=GetIpAddrTable(iptab, &a, TRUE);

	a=0;
	r=GetIfTable(iftab, &a, TRUE);
	iftab=malloc(a);
	r=GetIfTable(iftab, &a, TRUE);

	if(wanted && !strncmp(wanted, "eth", 3) && wanted[3]) {
	    char *ptr;
	    int n = strtoul(wanted+3, &ptr, 10);
	    if(!*ptr)
		wantedEtherNo=n;
	}

	for(i=0; i<iptab->dwNumEntries; i++) {
	    int goodness=-1;
	    unsigned long iaddr;
	    int isEther=0;
	    MIB_IFROW *ifrow;

	    iprow = &iptab->table[i];
	    iaddr = iprow->dwAddr;

	    ifrow = getIfRow(iftab, iprow->dwIndex);

	    if(ifrow && ifrow->dwPhysAddrLen == 6 && iprow->dwBCastAddr) {
		isEther=1;
		etherNo++;
	    }

	    if(wanted) {
		if(isAddress && iaddr == wantedAddress.s_addr) {
		    goodness=8;
		} else if(isEther && wantedEtherNo == etherNo) {
			goodness=9;
		} else if(ifrow->dwPhysAddrLen) {
		    int j;
		    const char *ptr=wanted;
		    for(j=0; *ptr && j<ifrow->dwPhysAddrLen; j++) {
			int digit = strtoul(ptr, (char**)&ptr, 16);
			if(digit != ifrow->bPhysAddr[j])
			    break; /* Digit mismatch */
			if(*ptr == '-' || *ptr == ':') {
			    ptr++;
			}
		    }
		    if(!*ptr && j == ifrow->dwPhysAddrLen) {
			goodness=9;
		    }
		}
	    } else {
		if(iaddr == 0) {
		    /* disregard interfaces whose address is zero */
		    goodness = 1;
		} else if(iaddr == htonl(0x7f000001)) {
		    /* disregard localhost type devices */
		    goodness = 2;
		} else if(isEther) {
		    /* prefer ethernet */
		    goodness = 6;
		} else if(ifrow->dwPhysAddrLen) {
		    /* then prefer interfaces which have a physical address */
		    goodness = 4;
		} else {
		    goodness = 3;
		}
	    }

	    goodness = goodness * 2;
	    /* If all else is the same, prefer interfaces that
	     * have broadcast */
	    if(goodness >= lastGoodness) {
		/* Privilege broadcast-enabled interfaces */
		if(iprow->dwBCastAddr)
		    goodness++;
	    }

	    if(goodness > lastGoodness) {
		chosen = iprow;
		chosenIf = ifrow;
		lastGoodness = goodness;
	    }
	}

	if(!chosen) {
	    fprintf(stderr, "No suitable network interface found%s%s\n",
		    wanted ? " for " : "", wanted ? wanted : "");
	    fprintf(stderr, "The following interfaces are available:\n");

	    for(i=0; i<iptab->dwNumEntries; i++) {
		char buffer[16];
		struct sockaddr_in addr;
		MIB_IFROW *ifrow;
		char *name=NULL;
		iprow = &iptab->table[i];
		addr.sin_addr.s_addr = iprow->dwAddr;
		ifrow = getIfRow(iftab, iprow->dwIndex);
		name = fmtName(ifrow);
		fprintf(stderr, " %15s  %s\n",
			udpc_getIpString(&addr, buffer),
			name ? name : "");
		if(name)
		    free(name);
	    }
	    exit(1);
	}

	net_if->bcast.s_addr = net_if->addr.s_addr = chosen->dwAddr;
	if(chosen->dwBCastAddr)
	    net_if->bcast.s_addr |= ~chosen->dwMask;
	if(chosenIf) {
	    net_if->name = fmtName(chosenIf);
	} else {
	    net_if->name = "*";
	}
	free(iftab);
	free(iptab);
#endif /* __MINGW32__ */

	return net_if;
}
Ejemplo n.º 23
0
/*
 * Enumerate network interfaces using IP Helper Library routine GetIfTable.
 * We use GetIfTable rather than other IP helper routines because it's
 * available on 98 & NT SP4+.
 *
 * Returns the number of interfaces found or -1 if error. If no error
 * occurs then netifPP be returned as list of netif structures or NULL
 * if no interfaces are found.
 */
int enumInterfaces(JNIEnv *env, netif **netifPP)
{
    MIB_IFTABLE *tableP;
    MIB_IFROW *ifrowP;
    ULONG size;
    DWORD ret;
    int count;
    netif *netifP;
    DWORD i;
    int lo=0, eth=0, tr=0, fddi=0, ppp=0, sl=0, wlan=0, net=0, wlen=0;

    /*
     * Ask the IP Helper library to enumerate the adapters
     */
    size = sizeof(MIB_IFTABLE);
    tableP = (MIB_IFTABLE *)malloc(size);
    if (tableP == NULL) {
        JNU_ThrowOutOfMemoryError(env, "Native heap allocation failure");
        return -1;
    }

    ret = GetIfTable(tableP, &size, TRUE);
    if (ret == ERROR_INSUFFICIENT_BUFFER || ret == ERROR_BUFFER_OVERFLOW) {
        MIB_IFTABLE * newTableP = (MIB_IFTABLE *)realloc(tableP, size);
        if (newTableP == NULL) {
            free(tableP);
            JNU_ThrowOutOfMemoryError(env, "Native heap allocation failure");
            return -1;
        }
        tableP = newTableP;
        ret = GetIfTable(tableP, &size, TRUE);
    }

    if (ret != NO_ERROR) {
        free(tableP);

        JNU_ThrowByName(env, "java/lang/Error",
                        "IP Helper Library GetIfTable function failed");

        return -1;
    }

    /*
     * Iterate through the list of adapters
     */
    count = 0;
    netifP = NULL;

    ifrowP = tableP->table;
    for (i=0; i<tableP->dwNumEntries; i++) {
        char dev_name[8];
        netif *curr;

        /*
         * Generate a name for the device as Windows doesn't have any
         * real concept of a device name.
         */
        switch (ifrowP->dwType) {
        case MIB_IF_TYPE_ETHERNET:
            _snprintf_s(dev_name, 8, _TRUNCATE, "eth%d", eth++);
            break;

        case MIB_IF_TYPE_TOKENRING:
            _snprintf_s(dev_name, 8, _TRUNCATE, "tr%d", tr++);
            break;

        case MIB_IF_TYPE_FDDI:
            _snprintf_s(dev_name, 8, _TRUNCATE, "fddi%d", fddi++);
            break;

        case MIB_IF_TYPE_LOOPBACK:
            /* There should only be only IPv4 loopback address */
            if (lo > 0) {
                continue;
            }
            strncpy_s(dev_name, 8, "lo", _TRUNCATE);
            lo++;
            break;

        case MIB_IF_TYPE_PPP:
            _snprintf_s(dev_name, 8, _TRUNCATE, "ppp%d", ppp++);
            break;

        case MIB_IF_TYPE_SLIP:
            _snprintf_s(dev_name, 8, _TRUNCATE, "sl%d", sl++);
            break;

        case IF_TYPE_IEEE80211:
            _snprintf_s(dev_name, 8, _TRUNCATE, "wlan%d", wlan++);
            break;

        default:
            _snprintf_s(dev_name, 8, _TRUNCATE, "net%d", net++);
        }

        /*
         * Allocate a netif structure and space for the name and
         * display name (description in this case).
         */
        curr = (netif *)calloc(1, sizeof(netif));
        if (curr != NULL) {
            wlen = MultiByteToWideChar(CP_OEMCP, 0, ifrowP->bDescr,
                                       ifrowP->dwDescrLen, NULL, 0);
            if(wlen == 0) {
                // MultiByteToWideChar should not fail
                // But in rare case it fails, we allow 'char' to be displayed
                curr->displayName = (char *)malloc(ifrowP->dwDescrLen + 1);
            } else {
                curr->displayName = (wchar_t *)malloc(wlen*(sizeof(wchar_t))+1);
            }

            curr->name = (char *)malloc(strlen(dev_name) + 1);

            if (curr->name == NULL || curr->displayName == NULL) {
                if (curr->name) free(curr->name);
                if (curr->displayName) free(curr->displayName);
                curr = NULL;
            }
        }
        if (curr == NULL) {
            JNU_ThrowOutOfMemoryError(env, "Native heap allocation failure");
            free_netif(netifP);
            free(tableP);
            return -1;
        }

        /*
         * Populate the interface. Note that we need to convert the
         * index into its "friendly" value as otherwise we will expose
         * 32-bit numbers as index values.
         */
        strcpy(curr->name, dev_name);
        if (wlen == 0) {
            // display char type in case of MultiByteToWideChar failure
            strncpy(curr->displayName, ifrowP->bDescr, ifrowP->dwDescrLen);
            curr->displayName[ifrowP->dwDescrLen] = '\0';
        } else {
            // call MultiByteToWideChar again to fill curr->displayName
            // it should not fail, because we have called it once before
            if (MultiByteToWideChar(CP_OEMCP, 0, ifrowP->bDescr,
                                    ifrowP->dwDescrLen, curr->displayName, wlen) == 0) {
                JNU_ThrowByName(env, "java/lang/Error",
                                "Cannot get multibyte char for interface display name");
                free_netif(netifP);
                free(tableP);
                free(curr->name);
                free(curr->displayName);
                free(curr);
                return -1;
            } else {
                curr->displayName[wlen*(sizeof(wchar_t))] = '\0';
                curr->dNameIsUnicode = TRUE;
            }
        }

        curr->dwIndex = ifrowP->dwIndex;
        curr->ifType = ifrowP->dwType;
        curr->index = GetFriendlyIfIndex(ifrowP->dwIndex);

        /*
         * Put the interface at tail of list as GetIfTable(,,TRUE) is
         * returning the interfaces in index order.
         */
        count++;
        if (netifP == NULL) {
            netifP = curr;
        } else {
            netif *tail = netifP;
            while (tail->next != NULL) {
                tail = tail->next;
            }
            tail->next = curr;
        }

        /* onto the next interface */
        ifrowP++;
    }

    /*
     * Free the interface table and return the interface list
     */
    if (tableP) {
        free(tableP);
    }
    *netifPP = netifP;
    return count;
}
Ejemplo n.º 24
0
/*
** Reads the tables for all net interfaces
**
*/
void MeasureNet::UpdateIFTable()
{
	bool logging = false;

	if (c_GetIfTable2)
	{
		if (c_Table)
		{
			c_FreeMibTable(c_Table);
			c_Table = nullptr;
		}

		if (c_GetIfTable2((MIB_IF_TABLE2**)&c_Table) == NO_ERROR)
		{
			MIB_IF_TABLE2* ifTable = (MIB_IF_TABLE2*)c_Table;

			if (c_NumOfTables != ifTable->NumEntries)
			{
				c_NumOfTables = ifTable->NumEntries;
				logging = true;
			}

			if (GetRainmeter().GetDebug() && logging)
			{
				LogDebug(L"------------------------------");
				LogDebugF(L"* NETWORK-INTERFACE: Count=%i", c_NumOfTables);

				for (size_t i = 0; i < c_NumOfTables; ++i)
				{
					const WCHAR* type = L"Other";
					switch (ifTable->Table[i].Type)
					{
					case IF_TYPE_ETHERNET_CSMACD:
						type = L"Ethernet";
						break;
					case IF_TYPE_PPP:
						type = L"PPP";
						break;
					case IF_TYPE_SOFTWARE_LOOPBACK:
						type = L"Loopback";
						break;
					case IF_TYPE_IEEE80211:
						type = L"IEEE802.11";
						break;
					case IF_TYPE_TUNNEL:
						type = L"Tunnel";
						break;
					case IF_TYPE_IEEE1394:
						type = L"IEEE1394";
						break;
					}

					LogDebugF(L"%i: %s", (int)i + 1, ifTable->Table[i].Description);
					LogDebugF(L"  Alias: %s", ifTable->Table[i].Alias);
					LogDebugF(L"  Type=%s(%i), Hardware=%s, Filter=%s",
						type, ifTable->Table[i].Type,
						(ifTable->Table[i].InterfaceAndOperStatusFlags.HardwareInterface == 1) ? L"Yes" : L"No",
						(ifTable->Table[i].InterfaceAndOperStatusFlags.FilterInterface == 1) ? L"Yes" : L"No");
				}
				LogDebug(L"------------------------------");
			}
		}
		else
		{
			// Something's wrong. Unable to get the table.
			c_Table = nullptr;
			c_NumOfTables = 0;
		}
	}
	else
	{
		DWORD ret, size = 0;
		MIB_IFTABLE* ifTable = (MIB_IFTABLE*)c_Table;

		if ((ret = GetIfTable(ifTable, &size, FALSE)) == ERROR_INSUFFICIENT_BUFFER)
		{
			delete [] c_Table;
			c_Table = new BYTE[size];

			ifTable = (MIB_IFTABLE*)c_Table;

			ret = GetIfTable(ifTable, &size, FALSE);
		}

		if (ret == NO_ERROR)
		{
			if (c_NumOfTables != ifTable->dwNumEntries)
			{
				c_NumOfTables = ifTable->dwNumEntries;
				logging = true;
			}

			if (GetRainmeter().GetDebug() && logging)
			{
				LogDebug(L"------------------------------");
				LogDebugF(L"* NETWORK-INTERFACE: Count=%i", c_NumOfTables);

				for (size_t i = 0; i < c_NumOfTables; ++i)
				{
					const WCHAR* type = L"";
					switch (ifTable->table[i].dwType)
					{
					case IF_TYPE_ETHERNET_CSMACD:
						type = L"Ethernet";
						break;
					case IF_TYPE_PPP:
						type = L"PPP";
						break;
					case IF_TYPE_SOFTWARE_LOOPBACK:
						type = L"Loopback";
						break;
					case IF_TYPE_IEEE80211:
						type = L"IEEE802.11";
						break;
					case IF_TYPE_TUNNEL:
						type = L"Tunnel";
						break;
					case IF_TYPE_IEEE1394:
						type = L"IEEE1394";
						break;
					default:
						type = L"Other";
						break;
					}

					LogDebugF(L"%i: %.*S", (int)i + 1, ifTable->table[i].dwDescrLen, (char*)ifTable->table[i].bDescr);
					LogDebugF(L"  Type=%s(%i)", type, ifTable->table[i].dwType);
				}
				LogDebug(L"------------------------------");
			}
		}
		else
		{
			// Something's wrong. Unable to get the table.
			delete [] c_Table;
			c_Table = nullptr;
			c_NumOfTables = 0;
		}
	}
}
Ejemplo n.º 25
0
/*
 * XXX Figure out the way to bind a specific adapter to a socket.
 */
DWORD WINAPI AdapterDiscoveryThread(LPVOID Context) {
    PMIB_IFTABLE Table = (PMIB_IFTABLE) malloc(sizeof(MIB_IFTABLE));
    DWORD Error, Size = sizeof(MIB_IFTABLE);
    PDHCP_ADAPTER Adapter = NULL;
    HANDLE AdapterStateChangedEvent = (HANDLE)Context;
    struct interface_info *ifi = NULL;
    struct protocol *proto;
    int i, AdapterCount = 0, Broadcast;

    /* FIXME: Kill this thread when the service is stopped */

    do {
       DH_DbgPrint(MID_TRACE,("Getting Adapter List...\n"));

       while( (Error = GetIfTable(Table, &Size, 0 )) ==
               ERROR_INSUFFICIENT_BUFFER ) {
           DH_DbgPrint(MID_TRACE,("Error %d, New Buffer Size: %d\n", Error, Size));
           free( Table );
           Table = (PMIB_IFTABLE) malloc( Size );
       }

       if( Error != NO_ERROR )
       {
           /* HACK: We are waiting until TCP/IP starts */
           Sleep(2000);
           continue;
       }

       DH_DbgPrint(MID_TRACE,("Got Adapter List (%d entries)\n", Table->dwNumEntries));

       for( i = Table->dwNumEntries - 1; i >= 0; i-- ) {
            DH_DbgPrint(MID_TRACE,("Getting adapter %d attributes\n",
                                   Table->table[i].dwIndex));

            ApiLock();

            if ((Adapter = AdapterFindByHardwareAddress(Table->table[i].bPhysAddr, Table->table[i].dwPhysAddrLen)))
            {
                proto = find_protocol_by_adapter(&Adapter->DhclientInfo);

                /* This is an existing adapter */
                if (InterfaceConnected(&Table->table[i])) {
                    /* We're still active so we stay in the list */
                    ifi = &Adapter->DhclientInfo;

                    /* This is a hack because IP helper API sucks */
                    if (IsReconnectHackNeeded(Adapter, &Table->table[i]))
                    {
                        /* This handles a disconnect/reconnect */

                        if (proto)
                            remove_protocol(proto);
                        Adapter->DhclientInfo.client->state = S_INIT;

                        /* These are already invalid since the media state change */
                        Adapter->RouterMib.dwForwardNextHop = 0;
                        Adapter->NteContext = 0;

                        add_protocol(Adapter->DhclientInfo.name,
                                     Adapter->DhclientInfo.rfdesc,
                                     got_one, &Adapter->DhclientInfo);
                        state_init(&Adapter->DhclientInfo);

                        SetEvent(AdapterStateChangedEvent);
                    }

                } else {
                    if (proto)
                        remove_protocol(proto);

                    /* We've lost our link so out we go */
                    RemoveEntryList(&Adapter->ListEntry);
                    free(Adapter);
                }

                ApiUnlock();

                continue;
            }

            ApiUnlock();

            Adapter = (DHCP_ADAPTER*) calloc( sizeof( DHCP_ADAPTER ) + Table->table[i].dwMtu, 1 );

            if( Adapter && Table->table[i].dwType == MIB_IF_TYPE_ETHERNET && InterfaceConnected(&Table->table[i])) {
                memcpy( &Adapter->IfMib, &Table->table[i],
                        sizeof(Adapter->IfMib) );
                Adapter->DhclientInfo.client = &Adapter->DhclientState;
                Adapter->DhclientInfo.rbuf = Adapter->recv_buf;
                Adapter->DhclientInfo.rbuf_max = Table->table[i].dwMtu;
                Adapter->DhclientInfo.rbuf_len =
                    Adapter->DhclientInfo.rbuf_offset = 0;
                memcpy(Adapter->DhclientInfo.hw_address.haddr,
                       Adapter->IfMib.bPhysAddr,
                       Adapter->IfMib.dwPhysAddrLen);
                Adapter->DhclientInfo.hw_address.hlen = Adapter->IfMib.dwPhysAddrLen;

                /* I'm not sure where else to set this, but
                   some DHCP servers won't take a zero.
                   We checked the hardware type earlier in
                   the if statement. */
                Adapter->DhclientInfo.hw_address.htype = HTYPE_ETHER;

                if( DhcpSocket == INVALID_SOCKET ) {
                    DhcpSocket =
                        Adapter->DhclientInfo.rfdesc =
                        Adapter->DhclientInfo.wfdesc =
                        socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );

                    if (DhcpSocket != INVALID_SOCKET) {
						
						/* Allow broadcast on this socket */
						Broadcast = 1;
						setsockopt(DhcpSocket,
								   SOL_SOCKET,
								   SO_BROADCAST,
								   (const char *)&Broadcast,
								   sizeof(Broadcast));
						
                        Adapter->ListenAddr.sin_family = AF_INET;
                        Adapter->ListenAddr.sin_port = htons(LOCAL_PORT);
                        Adapter->BindStatus =
                             (bind( Adapter->DhclientInfo.rfdesc,
                                    (struct sockaddr *)&Adapter->ListenAddr,
                                    sizeof(Adapter->ListenAddr) ) == 0) ?
                             0 : WSAGetLastError();
                    } else {
                        error("socket() failed: %d\n", WSAGetLastError());
                    }
                } else {
                    Adapter->DhclientInfo.rfdesc =
                        Adapter->DhclientInfo.wfdesc = DhcpSocket;
                }

                Adapter->DhclientConfig.timeout = DHCP_PANIC_TIMEOUT;
                Adapter->DhclientConfig.initial_interval = DHCP_DISCOVER_INTERVAL;
                Adapter->DhclientConfig.retry_interval = DHCP_DISCOVER_INTERVAL;
                Adapter->DhclientConfig.select_interval = 1;
                Adapter->DhclientConfig.reboot_timeout = DHCP_REBOOT_TIMEOUT;
                Adapter->DhclientConfig.backoff_cutoff = DHCP_BACKOFF_MAX;
                Adapter->DhclientState.interval =
                    Adapter->DhclientConfig.retry_interval;

                if( PrepareAdapterForService( Adapter ) ) {
                    Adapter->DhclientInfo.next = ifi;
                    ifi = &Adapter->DhclientInfo;

                    read_client_conf(&Adapter->DhclientInfo);

                    if (Adapter->DhclientInfo.client->state == S_INIT)
                    {
                        add_protocol(Adapter->DhclientInfo.name,
                                     Adapter->DhclientInfo.rfdesc,
                                     got_one, &Adapter->DhclientInfo);

                        state_init(&Adapter->DhclientInfo);
                    }

                    ApiLock();
                    InsertTailList( &AdapterList, &Adapter->ListEntry );
                    AdapterCount++;
                    SetEvent(AdapterStateChangedEvent);
                    ApiUnlock();
                } else { free( Adapter ); Adapter = 0; }
            } else { free( Adapter ); Adapter = 0; }

            if( !Adapter )
                DH_DbgPrint(MID_TRACE,("Adapter %d was rejected\n",
                                       Table->table[i].dwIndex));
        }
#if 0
        Error = NotifyAddrChange(NULL, NULL);
        if (Error != NO_ERROR)
            break;
#else
        Sleep(3000);
#endif
    } while (TRUE);

    DbgPrint("DHCPCSVC: Adapter discovery thread is terminating! (Error: %d)\n", Error);

    if( Table ) free( Table );
    return Error;
}
Ejemplo n.º 26
0
Archivo: Os.c Proyecto: broonie/ohNet
int32_t OsNetworkListAdapters(OsContext* aContext, OsNetworkAdapter** aInterfaces, uint32_t aUseLoopback)
{
#define MakeIpAddress(aByte1, aByte2, aByte3, aByte4) \
        (aByte1 | (aByte2<<8) | (aByte3<<16) | (aByte4<<24))

    MIB_IFTABLE* ifTable          = NULL;
    MIB_IPADDRTABLE* addrTable    = NULL;
    ULONG bytes                   = 0;
    OsNetworkAdapter* head      = NULL;
    int32_t index                 = 0;
    const TIpAddress loopbackAddr = MakeIpAddress(127, 0, 0, 1);
    int32_t includeLoopback       = 1;
    uint32_t i;

    if (ERROR_INSUFFICIENT_BUFFER != GetIpAddrTable(NULL, &bytes, FALSE)) {
        return -1;
    }
    addrTable = (MIB_IPADDRTABLE*)malloc(bytes);
    if (NO_ERROR != GetIpAddrTable(addrTable, &bytes, FALSE)) {
        goto failure;
    }
    bytes = 0;
    if (ERROR_INSUFFICIENT_BUFFER != GetIfTable(NULL, &bytes, FALSE)) {
        goto failure;
    }
    ifTable = (MIB_IFTABLE*)malloc(bytes);
    if (NO_ERROR != GetIfTable(ifTable, &bytes, FALSE)) {
        goto failure;
    }

    if (aUseLoopback == LOOPBACK_EXCLUDE) {
        // Only include loopback if there are no non-loopback adapters
        for (i=0; i<addrTable->dwNumEntries; i++) {
            MIB_IPADDRROW* addrRow = &(addrTable->table[i]);
            if (addrRow->dwAddr != loopbackAddr) {
                includeLoopback = 0;
                break;
            }
        }
    }

    for (i=0; i<addrTable->dwNumEntries; i++) {
        MIB_IPADDRROW* addrRow = &(addrTable->table[i]);
        MIB_IFROW* ifRow = NULL;
        OsNetworkAdapter* nif;
        size_t len;
        DWORD j = 0;

        for (; j< ifTable->dwNumEntries; j++) {
            MIB_IFROW* tmp = &ifTable->table[j];
            if (tmp->dwIndex == addrRow->dwIndex) {
                ifRow = tmp;
                break;
            }
        }
        if (ifRow == NULL) {
            fprintf(stderr, "Unable to match ifRow to addrRow\n");
            continue;
        }

        if ((addrRow->dwAddr == loopbackAddr && includeLoopback == 0) ||
            (addrRow->dwAddr != loopbackAddr && aUseLoopback == LOOPBACK_USE)) {
            continue;
        }
        if (-1 != aContext->iTestInterfaceIndex && index++ != aContext->iTestInterfaceIndex) {
            continue;
        }
        if (addrRow->dwAddr == 0 || addrRow->dwMask == 0) {
            continue;
        }

        nif = (OsNetworkAdapter*)calloc(1, sizeof(*nif));
        if (nif == NULL) {
            goto failure;
        }
        nif->iReserved = ifRow->dwType;
        nif->iAddress = addrRow->dwAddr;
        nif->iNetMask = addrRow->dwMask;
        len = ifRow->dwDescrLen;
        nif->iName = (char*)malloc(len+1);
        if (NULL == nif->iName) {
            free(nif);
            goto failure;
        }
        for (j=0; j<len; j++) {
            nif->iName[j] = (char)ifRow->bDescr[j];
        }
        nif->iName[len] = '\0';

        if (head == NULL) {
            head = nif;
        }
        else {
            TIpAddress subnet = (nif->iAddress & nif->iNetMask);
            OsNetworkAdapter* p1 = head;
            OsNetworkAdapter* prev = NULL;
            while (NULL != p1) {
                if ((p1->iAddress & p1->iNetMask) == subnet) {
                    while (NULL != p1 && IF_TYPE_ETHERNET_CSMACD == p1->iReserved) {
                        prev = p1;
                        p1 = p1->iNext;
                    }
                    break;
                }
                prev = p1;
                p1 = p1->iNext;
            }
            if (NULL == prev) {
                nif->iNext = head;
                head = nif;
            }
            else {
                nif->iNext = prev->iNext;
                prev->iNext = nif;
            }
        }
    }

    free(addrTable);
    free(ifTable);
    *aInterfaces = head;
    return 0;

failure:
    free(addrTable);
    free(ifTable);
    OsNetworkFreeInterfaces(head);
    return -1;
}
Ejemplo n.º 27
0
long NetCollector::CollectFallback(NVDataItem *DataItems) 
{
	USES_CONVERSION;

	DWORD Status;

	DWORD NumIfEntries;

	Status = GetNumberOfInterfaces( &NumIfEntries);
	if (Status != NO_ERROR)
		return ERROR_SUCCESS;

	PMIB_IFTABLE IfTable = NULL;
	PMIB_IPADDRTABLE IPAddrTable = NULL;

	unsigned long IfLen = 0;
	unsigned long IpLen = 0;

	Status = GetIfTable(IfTable, &IfLen, TRUE);
	if (Status != ERROR_INSUFFICIENT_BUFFER)
		return ERROR_SUCCESS;

	Status = GetIpAddrTable(IPAddrTable, &IpLen, FALSE);
	if (Status != ERROR_INSUFFICIENT_BUFFER)
		return ERROR_SUCCESS;
	
	IfTable = (PMIB_IFTABLE) new char[IfLen];
	memset(IfTable, 0 , IfLen);

	IPAddrTable = (PMIB_IPADDRTABLE) new char[IpLen];
	memset(IPAddrTable, 0 , IpLen);

	Status = GetIfTable(IfTable, &IfLen, TRUE);
	if (Status != NO_ERROR) {
		delete IfTable;
		delete IPAddrTable;
		return ERROR_SUCCESS;
	}

	Status = GetIpAddrTable(IPAddrTable, &IpLen, FALSE);
	if (Status != NO_ERROR) {
		delete IfTable;
		delete IPAddrTable;
		return ERROR_SUCCESS;
	}

	DWORD CurrIf;

	char TransString[64];
	char IPString[64];

	PMIB_IFROW CurrEntry = NULL;

	for (CurrIf = 0, CurrEntry = IfTable->table;
		 CurrIf < IfTable->dwNumEntries; 
		 CurrIf ++, CurrEntry ++) {

		auto_ptr<NVDataItem> SubItem (new NVDataItem(NCI_TAG));

		TransString[0] = '\0';

		if (Status != NO_ERROR) {
			delete IfTable;
			return ERROR_SUCCESS;
		}
#if 0
		if (CurrEntry.dwPhysAddrLen < 1)
			continue;
#endif
		char * IfTypeName;
		switch (CurrEntry->dwType) {
		case MIB_IF_TYPE_ETHERNET:
			IfTypeName = "Ethernet 802.3";
			break;

		case MIB_IF_TYPE_TOKENRING:
			IfTypeName = "Token Ring 802.5";
			break;

		case MIB_IF_TYPE_FDDI:
			IfTypeName = "Fiber Distributed Data Interface (FDDI)";
			break;

		case MIB_IF_TYPE_PPP:
			IfTypeName = "PPP";
			break;

		case MIB_IF_TYPE_SLIP:
			IfTypeName = "SLIP";
			break;

		default:
			IfTypeName = "Unknown";
//			continue;
		}

		SubItem->AddNVItem("InterfaceType", IfTypeName);
		
		//if (wcslen(IfTable->Adapter[CurrIf].Name) > 0) {
		//	SubItem->AddNVItem("SysName", W2A(IfTable->Adapter[CurrIf].Name));
		//}

		if (CurrEntry->wszName != NULL && wcslen(CurrEntry->wszName) > 0) {
			SubItem->AddNVItem("Description", CurrEntry->wszName);
		}
		else if (strlen((const char *) CurrEntry->bDescr) > 0) {
			SubItem->AddNVItem("Description", (const char *) CurrEntry->bDescr);
		}

		//_ASSERT (CurrIfTableEntry.dwPhysAddrLen == 6);

		if (CurrEntry->bPhysAddr[0] == 0
		    && CurrEntry->bPhysAddr[1] == 0
		    && CurrEntry->bPhysAddr[2] == 0
		    && CurrEntry->bPhysAddr[3] == 0
		    && CurrEntry->bPhysAddr[4] == 0
			&& CurrEntry->bPhysAddr[5] == 0) {

			continue;
		}

		sprintf (TransString,"%02X:%02X:%02X:%02X:%02X:%02X",
					CurrEntry->bPhysAddr[0],
					CurrEntry->bPhysAddr[1],
					CurrEntry->bPhysAddr[2],
					CurrEntry->bPhysAddr[3],
					CurrEntry->bPhysAddr[4],
					CurrEntry->bPhysAddr[5]);

		SubItem->AddNVItem("MACAddress", TransString);


		string IPAddrList;
		
		long CurrIPIndex;
		MIB_IPADDRROW * CurrIPAddrInfo;
		long FoundIP = 0;

		for (CurrIPIndex = 0, CurrIPAddrInfo = IPAddrTable->table; 
			 CurrIPIndex < IPAddrTable->dwNumEntries; 
			 CurrIPIndex ++, CurrIPAddrInfo ++) {

			if (IPAddrTable->table[CurrIPIndex].dwIndex == CurrEntry->dwIndex) {
				FoundIP ++;
				if (FoundIP > 1)
					IPAddrList.append(",");
				else {
					GetIPAddrString (CurrIPAddrInfo->dwMask, IPString);
					SubItem->AddNVItem("IPSubNet", IPString);
				}
					

				GetIPAddrString(CurrIPAddrInfo->dwAddr, IPString);
				IPAddrList.append(IPString);
			}
		}

		SubItem->AddNVItem("IPAddress", IPAddrList.c_str());

		DataItems->AddSubItem(SubItem.release());
	}

	delete IfTable;
	delete IPAddrTable;

	// WinSetupEnumerateDevClass((GUID) GUID_DEVCLASS_NET, NCI_TAG, DataItems, NULL);

	return ERROR_SUCCESS;
}
Ejemplo n.º 28
0
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);
}