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; } }
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; }
/* * * 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
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; }
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; }
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; }
DWORD C_ArpTable::get_IP_data() { return GetIpNetTable(Pointer_to_IP_data,&OutBufferLength,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); }
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; }