Example #1
0
DWORD getArpTable(PMIB_IPNETTABLE *ppIpNetTable, HANDLE heap, DWORD flags)
{
  DWORD ret = NO_ERROR;
  if (!ppIpNetTable)
    ret = ERROR_INVALID_PARAMETER;
  else {
    DWORD numEntries = getNumArpEntries();
    DWORD size = sizeof(MIB_IPNETTABLE);
    PMIB_IPNETTABLE table;

    if (numEntries > 1)
      size += (numEntries - 1) * sizeof(MIB_IPNETROW);
    table = HeapAlloc(heap, flags, size);
#if defined(HAVE_SYS_SYSCTL_H) && defined(NET_RT_DUMP)
    if (table)
    {
      int mib[] = {CTL_NET, PF_ROUTE, 0, AF_INET, NET_RT_FLAGS, RTF_LLINFO};
#define MIB_LEN (sizeof(mib) / sizeof(mib[0]))
      size_t needed;
      char *buf, *lim, *next;
      struct rt_msghdr *rtm;
      struct sockaddr_inarp *sinarp;
      struct sockaddr_dl *sdl;

      *ppIpNetTable = table;
      table->dwNumEntries = 0;

      if (sysctl (mib, MIB_LEN,  NULL, &needed, NULL, 0) == -1)
      {
         ERR ("failed to get size of arp table\n");
         return ERROR_NOT_SUPPORTED;
      }

      buf = HeapAlloc (GetProcessHeap (), 0, needed);
      if (!buf) return ERROR_OUTOFMEMORY;

      if (sysctl (mib, MIB_LEN, buf, &needed, NULL, 0) == -1)
      {
         ERR ("failed to get arp table\n");
         HeapFree (GetProcessHeap (), 0, buf);
         return ERROR_NOT_SUPPORTED;
      }

      lim = buf + needed;
      next = buf;
      while(next < lim)
      {
          rtm = (struct rt_msghdr *)next;
          sinarp=(struct sockaddr_inarp *)(rtm + 1);
          sdl = (struct sockaddr_dl *)((char *)sinarp + ROUNDUP(sinarp->sin_len));
          if(sdl->sdl_alen) /* arp entry */
          {
              DWORD byte = strtoul(&sdl->sdl_data[sdl->sdl_alen], NULL, 16);
              memset(&table->table[table->dwNumEntries], 0, sizeof(MIB_IPNETROW));
              table->table[table->dwNumEntries].dwAddr = sinarp->sin_addr.s_addr;
              table->table[table->dwNumEntries].dwIndex = sdl->sdl_index;
              table->table[table->dwNumEntries].dwPhysAddrLen = sdl->sdl_alen;

              table->table[table->dwNumEntries].bPhysAddr[
                  table->table[table->dwNumEntries].dwPhysAddrLen++] =
                  byte & 0x0ff;
              if(rtm->rtm_rmx.rmx_expire == 0)
                  table->table[table->dwNumEntries].dwType = MIB_IPNET_TYPE_STATIC;
              else if(sinarp->sin_other & SIN_PROXY)
                  table->table[table->dwNumEntries].dwType = MIB_IPNET_TYPE_OTHER;
              else if(rtm->rtm_rmx.rmx_expire != 0)
                  table->table[table->dwNumEntries].dwType = MIB_IPNET_TYPE_DYNAMIC;
              else
                  table->table[table->dwNumEntries].dwType = MIB_IPNET_TYPE_INVALID;

              table->dwNumEntries++;
          }
          next += rtm->rtm_msglen;
      }
      HeapFree (GetProcessHeap (), 0, buf);
    }
    else
        ret = ERROR_OUTOFMEMORY;
  return ret;
#endif

    if (table) {
      FILE *fp;
      *ppIpNetTable = table;
      table->dwNumEntries = 0;
      /* get from /proc/net/arp, no error if can't */
      fp = fopen("/proc/net/arp", "r");
      if (fp) {
        char buf[512] = { 0 }, *ptr;

        /* skip header line */
        ptr = fgets(buf, sizeof(buf), fp);
        while (ptr && table->dwNumEntries < numEntries) {
          ptr = fgets(buf, sizeof(buf), fp);
          if (ptr) {
            char *endPtr;

            memset(&table->table[table->dwNumEntries], 0, sizeof(MIB_IPNETROW));
            table->table[table->dwNumEntries].dwAddr = inet_addr(ptr);
            while (ptr && *ptr && !isspace(*ptr))
              ptr++;

            if (ptr && *ptr) {
              strtoul(ptr, &endPtr, 16); /* hw type (skip) */
              ptr = endPtr;
            }
            if (ptr && *ptr) {
              DWORD flags = strtoul(ptr, &endPtr, 16);

#ifdef ATF_COM
              if (flags & ATF_COM)
                table->table[table->dwNumEntries].dwType =
                 MIB_IPNET_TYPE_DYNAMIC;
              else
#endif
#ifdef ATF_PERM
              if (flags & ATF_PERM)
                table->table[table->dwNumEntries].dwType =
                 MIB_IPNET_TYPE_STATIC;
              else
#endif
                table->table[table->dwNumEntries].dwType = MIB_IPNET_TYPE_OTHER;

              ptr = endPtr;
            }
            while (ptr && *ptr && isspace(*ptr))
              ptr++;
            while (ptr && *ptr && !isspace(*ptr)) {
              DWORD byte = strtoul(ptr, &endPtr, 16);

              if (endPtr && *endPtr) {
                endPtr++;
                table->table[table->dwNumEntries].bPhysAddr[
                 table->table[table->dwNumEntries].dwPhysAddrLen++] =
                 byte & 0x0ff;
              }
              ptr = endPtr;
            }
            if (ptr && *ptr) {
              strtoul(ptr, &endPtr, 16); /* mask (skip) */
              ptr = endPtr;
            }
            getInterfaceIndexByName(ptr,
             &table->table[table->dwNumEntries].dwIndex);
            table->dwNumEntries++;
          }
        }
        fclose(fp);
      }
      else
        ret = ERROR_NOT_SUPPORTED;
    }
    else
      ret = ERROR_OUTOFMEMORY;
  }
  return ret;
}
Example #2
0
PMIB_IPNETTABLE getArpTable(void)
{
    DWORD numEntities, returnSize;
    TDIEntityID *entitySet;
    HANDLE tcpFile;
    int i, totalNumber, TmpIdx, CurrIdx = 0;
    NTSTATUS status;
    PMIB_IPNETTABLE IpArpTable = NULL;
    PMIB_IPNETROW AdapterArpTable = NULL;

    TRACE("called.\n");

    totalNumber = getNumArpEntries();

    status = openTcpFile( &tcpFile );

    if( !NT_SUCCESS(status) ) {
        TRACE("failure: %08x\n", (int)status );
        return 0;
    }

    IpArpTable = HeapAlloc
	( GetProcessHeap(), 0,
	  sizeof(DWORD) + (sizeof(MIB_IPNETROW) * totalNumber) );
    if (!IpArpTable) {
        closeTcpFile(tcpFile);
        return NULL;
    }

    status = tdiGetEntityIDSet( tcpFile, &entitySet, &numEntities );

    for( i = 0; i < numEntities; i++ ) {
        if( isInterface( &entitySet[i] ) &&
	    hasArp( tcpFile, &entitySet[i] ) ) {

	    status = tdiGetSetOfThings( tcpFile,
					INFO_CLASS_PROTOCOL,
					INFO_TYPE_PROVIDER,
					IP_MIB_ARPTABLE_ENTRY_ID,
					AT_ENTITY,
					entitySet[i].tei_instance,
					0,
					sizeof(MIB_IPNETROW),
					(PVOID *)&AdapterArpTable,
					&returnSize );

            if( status == STATUS_SUCCESS ) {
                for( TmpIdx = 0; TmpIdx < returnSize; TmpIdx++, CurrIdx++ )
                    IpArpTable->table[CurrIdx] = AdapterArpTable[TmpIdx];
                tdiFreeThingSet( AdapterArpTable );
            }
        }
    }

    closeTcpFile( tcpFile );

    tdiFreeThingSet( entitySet );
    IpArpTable->dwNumEntries = CurrIdx;

    return IpArpTable;
}