void arp_table::get_arp_table()
{
    //функция, возвращающая arp-таблицу
    //table - указатель на arp-таблицу
    //size - размер
    //true - таблица отсортированна в порядке возрастания ip адресов
    GetIpNetTable(table, &size, true);
    table = (PMIB_IPNETTABLE) new MIB_IPNETTABLE[size];
    //продолжить работу, если функция отработала без ошибок
    if (GetIpNetTable(table, &size, true) != NO_ERROR)
        return;
    _table = new Cell[table->dwNumEntries - 4];
    _count = 0;
    for (int i = 0; i < table->dwNumEntries - 4; i++)
    {
        mac_to_string(table->table[i].bPhysAddr, table->table[i].dwPhysAddrLen, mac);
        switch (table->table[i].dwType)
        {
            case 1:
                strcpy(type, "other");
                break;
            case 2:
                strcpy(type, "Invalidated");
                break;
            case 3:
                strcpy(type, "Dynamic");
                break;
            case 4:
                strcpy(type, "Static");
                break;
            default:
                strcpy(type,"");
        }
        //структура, представляет собой ip адрес (в различных типах данных)
        struct in_addr adr;
        adr.s_addr = table->table[i].dwAddr;
        item = new Cell();
        strcpy(item->ip, inet_ntoa(adr));
        strcpy(item->mac, mac);
        strcpy(item->type, type);
        if (strcmp(item->mac,"")!=0)
        {
            *(_table + _count) = *item;
            _count++;
        }
        delete item;
    }
}
Beispiel #2
0
JNIEXPORT jobjectArray JNICALL Java_org_krakenapps_winapi_ArpCache_getArpEntries(JNIEnv *env, jobject obj) {
	jclass clzArpEntry = (*env)->FindClass(env, "org/krakenapps/winapi/ArpEntry");
	jmethodID arpCacheInit = (*env)->GetMethodID(env, clzArpEntry, "<init>", "(I[B[BLjava/lang/String;)V");
	jobjectArray cache = NULL;
	PMIB_IPNETTABLE pIpNetTable = NULL;
	DWORD dwSize = 0;
	WORD i;

	GetIpNetTable(NULL, &dwSize, TRUE);
	if(dwSize == 0) {
		fprintf(stderr, "Error in GetIpNetTable\n");
		return 0;
	}
	pIpNetTable = (PMIB_IPNETTABLE)malloc(dwSize);
	GetIpNetTable(pIpNetTable, &dwSize, TRUE);

	cache = (*env)->NewObjectArray(env, pIpNetTable->dwNumEntries, clzArpEntry, NULL);
	for(i=0; i<pIpNetTable->dwNumEntries; i++) {
		MIB_IPNETROW row = pIpNetTable->table[i];
		jobject c = NULL;
		jint index = row.dwIndex;
		jbyteArray physAddr = (*env)->NewByteArray(env, row.dwPhysAddrLen);
		jbyteArray addr = (*env)->NewByteArray(env, 4);
		jstring type = NULL;
		const char *t = "Other";

		(*env)->SetByteArrayRegion(env, physAddr, 0, row.dwPhysAddrLen, row.bPhysAddr);
		(*env)->SetByteArrayRegion(env, addr, 0, 4, (const jbyte *)&row.dwAddr);
		switch(row.dwType) {
			case MIB_IPNET_TYPE_STATIC:
				t = "Static"; break;
			case MIB_IPNET_TYPE_DYNAMIC:
				t = "Dynamic"; break;
			case MIB_IPNET_TYPE_INVALID:
				t = "Invalid"; break;
		}
		type = (*env)->NewStringUTF(env, t);

		c = (*env)->NewObject(env, clzArpEntry, arpCacheInit, index, physAddr, addr, type);
		(*env)->SetObjectArrayElement(env, cache, i, c);
	}
	free(pIpNetTable);

	return cache;
}
Beispiel #3
0
/*
 *
 * Takes an internet address and an optional interface address as
 * arguments and checks their validity.
 * Add the interface number and IP to an MIB_IPNETROW structure
 * and remove the entry from the ARP cache.
 * Code adapted from ReactOS 
 */
int ArpDeleteHost(struct in_addr addr)
{
PMIB_IPNETTABLE pIpNetTable = NULL;
ULONG Size = 0;
DWORD dwIpAddr = 0;
INT iRet;
MIB_IPNETROW DelHost;
DWORD Ark;

    /* check IP address */
    dwIpAddr = addr.s_addr;

    /* We need the IpNetTable to get the adapter index */
    /* Return required buffer size */
    GetIpNetTable(NULL, &Size, 0);

    /* allocate memory for ARP address table */
    pIpNetTable = (PMIB_IPNETTABLE) calloc (Size, 1);
    if (		pIpNetTable == NULL 
		||   (iRet = GetIpNetTable(pIpNetTable, &Size, TRUE)) != NO_ERROR )
        goto cleanup;

     /* we need to read the ARP table in order to get the right interface table */
	for ( Ark=0 ; 
		  Ark<pIpNetTable->dwNumEntries && pIpNetTable->table[Ark].dwAddr != dwIpAddr ; 
		  Ark++) ;
	if ( Ark<pIpNetTable->dwNumEntries )
	{
        DelHost.dwAddr = dwIpAddr;
        DelHost.dwIndex = pIpNetTable->table[Ark].dwIndex;
		iRet = DeleteIpNetEntry (& DelHost);
		if (iRet != NO_ERROR) LOG (5, "IP address %s flushed from ARP table", inet_ntoa (addr));
    }

cleanup:
    if (pIpNetTable != NULL) free (pIpNetTable);
    return 0;
} // ArpDeleteHost 
Beispiel #4
0
static bool findMac(const IP_ADAPTER_INFO *adapterInfo, quint32 ipv4Host, QByteArray& mac)
{
	Q_UNUSED(adapterInfo)

	DWORD ip = qToBigEndian(ipv4Host);

	ULONG bufferLen = sizeof(MIB_IPNETROW) * 1000;
	std::vector<BYTE> buffer(bufferLen);
	MIB_IPNETTABLE *ipTable = reinterpret_cast<MIB_IPNETTABLE*>(&buffer[0]);
	if (NO_ERROR != GetIpNetTable(ipTable, &bufferLen, FALSE)) {
		return false;
	}

	for (DWORD i = 0; i < ipTable->dwNumEntries; i++) {
		const MIB_IPNETROW& row = ipTable->table[i];
		if (row.dwAddr == ip && row.dwPhysAddrLen == 6) {
			mac = QByteArray(reinterpret_cast<const char*>(&row.bPhysAddr[0]), 6);
			return true;
		}
	}

	return false;
}
Beispiel #5
0
static int GetIpNetTable_wrap(MIB_IPNETTABLE **table, ULONG *size)
{
  int rc;

  *table = NULL;
  *size  = 0;

  for(;;)
    {
      if(*size > 0 && (*table = malloc(*size)) == NULL)
	return -1;

      if((rc = GetIpNetTable(*table, size, FALSE)) == NO_ERROR)
	return 0;

      free(*table);
      *table = NULL;

      if(rc != ERROR_INSUFFICIENT_BUFFER)
	break;
    }

  return -1;
}
Beispiel #6
0
u_char         *
var_atEntry(struct variable *vp,
            oid * name,
            size_t * length,
            int exact, size_t * var_len, WriteMethod ** write_method)
{
    /*
     * Address Translation table object identifier is of form:
     * 1.3.6.1.2.1.3.1.?.interface.1.A.B.C.D,  where A.B.C.D is IP address.
     * Interface is at offset 10,
     * IPADDR starts at offset 12.
     *
     * IP Net to Media table object identifier is of form:
     * 1.3.6.1.2.1.4.22.1.?.interface.A.B.C.D,  where A.B.C.D is IP address.
     * Interface is at offset 10,
     * IPADDR starts at offset 11.
     */
    u_char         *cp;
    oid            *op;
    oid             lowest[16];
    oid             current[16];
    int             oid_length;
    int             lowState = -1;      /* Don't have one yet */
    PMIB_IPNETTABLE pIpNetTable = NULL;
    DWORD           status = NO_ERROR;
    DWORD           dwActualSize = 0;
    UINT            i;
    u_char          dest_addr[4];
    static in_addr_t	addr_ret;
    
    /*
     * fill in object part of name for current (less sizeof instance part) 
     */
    memcpy((char *) current, (char *) vp->name,
           (int) vp->namelen * sizeof(oid));

    if (current[6] == 3) {      /* AT group oid */
        oid_length = 16;
    } else {                    /* IP NetToMedia group oid */
        oid_length = 15;
    }

    status = GetIpNetTable(pIpNetTable, &dwActualSize, TRUE);
    if (status == ERROR_INSUFFICIENT_BUFFER) {
        pIpNetTable = (PMIB_IPNETTABLE) malloc(dwActualSize);
        if (pIpNetTable != NULL) {
            /*
             * Get the sorted IpNet Table 
             */
            status = GetIpNetTable(pIpNetTable, &dwActualSize, TRUE);
        }
    }


    if (status == NO_ERROR) {
        for (i = 0; i < pIpNetTable->dwNumEntries; ++i) {
            current[10] = pIpNetTable->table[i].dwIndex;


            if (current[6] == 3) {      /* AT group oid */
                current[11] = 1;
                op = current + 12;
            } else {            /* IP NetToMedia group oid */
                op = current + 11;
            }
            cp = (u_char *) & pIpNetTable->table[i].dwAddr;
            *op++ = *cp++;
            *op++ = *cp++;
            *op++ = *cp++;
            *op++ = *cp++;

            if (exact) {
                if (snmp_oid_compare(current, oid_length, name, *length) ==
                    0) {
                    memcpy((char *) lowest, (char *) current,
                           oid_length * sizeof(oid));
                    lowState = 0;
                    break;      /* no need to search further */
                }
            } else {
                if (snmp_oid_compare(current, oid_length, name, *length) >
                    0) {
                    memcpy((char *) lowest, (char *) current,
                           oid_length * sizeof(oid));
                    lowState = 0;
                    break;      /* As the table is sorted, no need to search further */
                }
            }
        }
    }
    if (arp_row == NULL) {
        /*
         * Free allocated memory in case of SET request's FREE phase 
         */
        arp_row = (PMIB_IPNETROW) malloc(sizeof(MIB_IPNETROW));
    }

    if (lowState < 0 || status != NO_ERROR) {
        /*
         * for creation of new row, only ipNetToMediaTable case is considered 
         */
        if (*length == 15 || *length == 16) {
            create_flag = 1;
            *write_method = write_arp;
            arp_row->dwIndex = name[10];

            if (*length == 15) {        /* ipNetToMediaTable */
                i = 11;
            } else {            /* at Table */

                i = 12;
            }

            dest_addr[0] = (u_char) name[i];
            dest_addr[1] = (u_char) name[i + 1];
            dest_addr[2] = (u_char) name[i + 2];
            dest_addr[3] = (u_char) name[i + 3];
            arp_row->dwAddr = *((DWORD *) dest_addr);

            arp_row->dwType = 4;        /* Static */
            arp_row->dwPhysAddrLen = 0;
        }
        free(pIpNetTable);
        return (NULL);
    }

    create_flag = 0;
    memcpy((char *) name, (char *) lowest, oid_length * sizeof(oid));
    *length = oid_length;
    *write_method = write_arp;
    *arp_row = pIpNetTable->table[i];

    switch (vp->magic) {
    case IPMEDIAIFINDEX:       /* also ATIFINDEX */
        *var_len = sizeof long_return;
        long_return = pIpNetTable->table[i].dwIndex;
        free(pIpNetTable);
        return (u_char *) & long_return;
    case IPMEDIAPHYSADDRESS:   /* also ATPHYSADDRESS */
        *var_len = pIpNetTable->table[i].dwPhysAddrLen;
        memcpy(return_buf, pIpNetTable->table[i].bPhysAddr, *var_len);
        free(pIpNetTable);
        return (u_char *) return_buf;
    case IPMEDIANETADDRESS:    /* also ATNETADDRESS */
        *var_len = sizeof(addr_ret);
        addr_ret = pIpNetTable->table[i].dwAddr;
        free(pIpNetTable);
        return (u_char *) & addr_ret;
    case IPMEDIATYPE:
        *var_len = sizeof long_return;
        long_return = pIpNetTable->table[i].dwType;
        free(pIpNetTable);
        return (u_char *) & long_return;
    default:
        DEBUGMSGTL(("snmpd", "unknown sub-id %d in var_atEntry\n",
                    vp->magic));
    }
    return NULL;
}
Beispiel #7
0
DWORD C_ArpTable::get_IP_data()
{
	return GetIpNetTable(Pointer_to_IP_data,&OutBufferLength,0);
}
Beispiel #8
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);
}
Beispiel #9
0
int winsock_getipnettable(LPSTMACADDRESS mac_address,unsigned int ip_address){
#ifdef _WIN32
#ifdef I_USE_WINDOWS_SDK
  MIB_IPNETTABLE* m;

  static char buf[65536];

  int len;
  int i;

  len=sizeof(buf);
  m=(MIB_IPNETTABLE*)buf;
  memset(buf,0,sizeof(buf));

  GetIpNetTable(m,&len,0);

  for(i=0;i<(int)m->dwNumEntries;i++)
  {
    if(m->table[i].dwAddr==ip_address)
    {

      unsigned int w;


      w=(unsigned char)(m->table[i].bPhysAddr[0]);
      w<<=8;
      w|=(unsigned char)(m->table[i].bPhysAddr[1]);
      mac_address->hi=w;

      w=(unsigned char)(m->table[i].bPhysAddr[2]);
      w<<=8;
      w|=(unsigned char)(m->table[i].bPhysAddr[3]);
      w<<=8;
      w|=(unsigned char)(m->table[i].bPhysAddr[4]);
      w<<=8;
      w|=(unsigned char)(m->table[i].bPhysAddr[5]);

      mac_address->lo=w;

      return 1;
    }
  }
  return 0;
#else
  return 0;
#endif
#endif
#if (defined _SH2)||(defined _SH4)
  char buf[6];
  int ret;
  unsigned int w;

  ret=tfGetArpEntryByIpAddr(ip_address,buf,sizeof(buf));
  if(ret)return 0;

  w=(unsigned char)buf[0];
  w<<=8;
  w|=(unsigned char)buf[1];
  mac_address->hi=w;

  w=(unsigned char)buf[2];
  w<<=8;
  w|=(unsigned char)buf[3];
  w<<=8;
  w|=(unsigned char)buf[4];
  w<<=8;
  w|=(unsigned char)buf[5];

  mac_address->lo=w;

  return 1;
#endif
#if (defined linux)&&!(defined __CYGWIN__)
  int sock;
  struct arpreq req;
  struct sockaddr_in * sin;
  unsigned int w, i;
  unsigned char * ptr;

  sock = socket(AF_INET, SOCK_DGRAM, 0);
  if( sock < 0 ){
	  close( sock );
	  return 0;
  }

  memset(&req, 0, sizeof(struct arpreq));
  strncpy(req.arp_dev, NIFNAME, NIFNAMESIZE+1); //device name

  sin = (struct sockaddr_in *)&req.arp_pa;
  memset(sin, 0, sizeof(struct sockaddr_in));

  sin->sin_family = AF_INET; //Address Familiy
  memcpy( &sin->sin_addr, &ip_address, sizeof(struct in_addr)); //IP

  if( ioctl(sock, SIOCGARP, &req) < 0 ){
	  close(sock);
	  return 0;
  }
  close( sock );

  ptr = (unsigned char*)(&req.arp_ha.sa_data[0]);

  /*MACが 0 ではないことを確認*/
  for( i=0; i<SL_SIZE_OF_MAC; i++){
	  if( *(ptr+i) ){ break; }
  }
  if( SL_SIZE_OF_MAC==i ){ return 0; }

  memset( &w, 0, sizeof(unsigned int));
  w=(unsigned char)*ptr;
  w<<=8;
  w|=(unsigned char)*(ptr+1);
  mac_address->hi=w;

  memset( &w, 0, sizeof(unsigned int));
  w=(unsigned char)*(ptr+2);
  w<<=8;
  w|=(unsigned char)*(ptr+3);
  w<<=8;
  w|=(unsigned char)*(ptr+4);
  w<<=8;
  w|=(unsigned char)*(ptr+5);

  mac_address->lo=w;

  return 1;
#endif

  return 0;
}