[network] Определение своего IP адреса
От: butcher Россия http://bu7cher.blogspot.com
Дата: 19.07.04 10:35
Оценка: 20 (4)
Здравствуйте,

Уже раз 5 на моей памяти в форумах поднимался вопрос по определению IP адресов локальной машины, решил выложить несколько реализаций.
Способ №1: Используя вызов WSAIoctl Winsock2 c кодом SIO_ADDRESS_LIST_QUERY
#include    <iostream>
#include    <winsock2.h>

#pragma        comment (lib, "ws2_32.lib")

int main(void)
{
    using            std::cout;
    using            std::cerr;
    using            std::endl;

    WSADATA        wd;
    SOCKET        sock;
    char            buf[65535];
    DWORD            dwSize = 65535;
    int                nRet;
    SOCKET_ADDRESS_LIST *pAddr;
    SOCKADDR*    saddr;
    
    nRet = WSAStartup(MAKEWORD(2,0), &wd);
    if(nRet != 0){
        cerr << "WSAStartup fail with code " << nRet << endl;
        return -1;
    }
    sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if(sock == INVALID_SOCKET){
        cerr << "socket fail with code " << WSAGetLastError() << endl;
        return -2;
    }
    ZeroMemory(buf, 65535);
    nRet = WSAIoctl(sock, SIO_ADDRESS_LIST_QUERY, NULL, 0, buf, 65535, &dwSize, NULL, NULL);
    if(nRet != SOCKET_ERROR){
        pAddr = reinterpret_cast<SOCKET_ADDRESS_LIST*>(buf);
        nRet = pAddr->iAddressCount;
        saddr = pAddr->Address->lpSockaddr;
        while (0 < nRet--){
            cout << inet_ntoa(reinterpret_cast<SOCKADDR_IN*>(saddr)->sin_addr) << endl;
            saddr++;
        }
        nRet = 0;
    }else {
        cerr << "WSAIoctl fail with code " << WSAGetLastError() << endl;
        nRet = -3;
    }
    closesocket(sock);
    WSACleanup();
    return nRet;
}

Способ №2: Используя IP Helper API
#include    <iostream>
#include    <windows.h>
#include    <iphlpapi.h>

#pragma        comment (lib, "iphlpapi")

void main (void)
{
    using                            std::cout;
    using                            std::cerr;
    using                            std::endl;
    
    char*                            buf;
    PIP_ADAPTER_INFO    pAdaptersInfo;
    PIP_ADDR_STRING        pAddr;
    DWORD                            dwSize = 0;

    if(GetAdaptersInfo(NULL, &dwSize) != ERROR_BUFFER_OVERFLOW){
        cerr << "GetAdaptersInfo fail" << endl;
        return;
    }
    buf = new char[dwSize];
    if (!buf) return;
    pAdaptersInfo = reinterpret_cast<PIP_ADAPTER_INFO>(buf);
    if (GetAdaptersInfo (pAdaptersInfo, &dwSize) == ERROR_SUCCESS){
        while (pAdaptersInfo){
            pAddr = &pAdaptersInfo->IpAddressList;
            while (pAddr){
                cout <<"Address: " << pAddr->IpAddress.String << "/" << 
                    pAddr->IpMask.String << endl;
                pAddr = pAddr->Next;
            }
            pAdaptersInfo = pAdaptersInfo->Next;
        }
    }
    delete[] buf;
}

Чуть позже представлю ещё один способ..

Нет ничего невозможного..
Re: [network] Определение своего IP адреса
От: butcher Россия http://bu7cher.blogspot.com
Дата: 19.07.04 10:55
Оценка: 6 (2)
Здравствуйте,

Способ №3: собственно, самый простой
#include    <iostream>
#include    <winsock2.h>

#pragma        comment (lib, "ws2_32.lib")

int main(void)
{
    using            std::cout;
    using            std::cerr;
    using            std::endl;

    WSADATA            wd;
    char            buf[65535];
    int                nRet;
    struct hostent    *phe;
    struct in_addr    *paddr;
    
    nRet = WSAStartup(MAKEWORD(1, 1), &wd);
    if(nRet != 0){
        cerr << "WSAStartup fail with code " << nRet << endl;
        return -1;
    }
    if(gethostname(buf, 65535) != SOCKET_ERROR){
        phe = gethostbyname(buf);
        if(phe != 0){
            while(phe->h_addr_list[nRet]){
                paddr = reinterpret_cast<struct in_addr*>(phe->h_addr_list[nRet++]);
                cout << inet_ntoa(*paddr) << endl;
            }
        }
    }
    WSACleanup();
    return nRet;
}

Нет ничего невозможного..
Re[2]: [network] Определение своего IP адреса
От: sercher Украина  
Дата: 19.07.04 14:26
Оценка:
Способ №4:

здесь
Автор: GarikTot
Дата: 08.09.03
Re[3]: [network] Определение своего IP адреса
От: butcher Россия http://bu7cher.blogspot.com
Дата: 20.07.04 08:46
Оценка:
Здравствуйте,

Способ №5: Используя SNMP Extension Agent API
#include    <iostream>
#include    <winsock2.h>
#include    <snmp.h>

#pragma        comment(lib, "snmpapi.lib")
#pragma        comment(lib, "ws2_32.lib")

namespace bsnmp {
    PFNSNMPEXTENSIONINIT    SnmpExtensionInit;
    PFNSNMPEXTENSIONQUERY    SnmpExtensionQuery;
};

int main(void)
{
    HANDLE                    hPollForTrapEvent;
    AsnObjectIdentifier        SupportedView;
    HMODULE                    hLib;
    UINT                    OID[] = { 1, 3, 6, 1, 2, 1, 4 , 20, 1 ,1 };
    SnmpVarBindList            SVBList;
    SnmpVarBind                SVBVars[1];
    AsnObjectIdentifier        AsnOID = { sizeof(OID)/sizeof(UINT), OID };
    AsnInteger32            ErrorStatus, ErrorIndex;

    hLib = LoadLibrary("inetmib1.dll");
    if (!hLib){
        std::cerr << "Loadlibrary fail" << std::endl;
        return -1;
    }
    bsnmp::SnmpExtensionInit = reinterpret_cast<PFNSNMPEXTENSIONINIT>(GetProcAddress(hLib, "SnmpExtensionInit"));
    bsnmp::SnmpExtensionQuery = reinterpret_cast<PFNSNMPEXTENSIONQUERY>(GetProcAddress(hLib, "SnmpExtensionQuery"));
    if(!bsnmp::SnmpExtensionInit || !bsnmp::SnmpExtensionQuery){
        std::cerr << "GetProcAddress fail" << std::endl;
        return -2;
    }
    if(bsnmp::SnmpExtensionInit(0, &hPollForTrapEvent, &SupportedView)){
        SVBList.len = 1;
        SVBList.list = SVBVars;
        SnmpUtilOidCpy(&SVBVars[0].name, &AsnOID);
        while(true){
            if(bsnmp::SnmpExtensionQuery(ASN_RFC1157_GETNEXTREQUEST, &SVBList, &ErrorStatus, &ErrorIndex) != 0){
                if(SnmpUtilOidNCmp(&SVBVars[0].name, &AsnOID, AsnOID.idLength)) break;
                std::cout << inet_ntoa(*reinterpret_cast<struct in_addr*>(SVBVars[0].value.asnValue.address.stream))
                    << std::endl;
            }else break;
        }
        SnmpUtilOidFree(&SVBVars[0].name);
    }else {
        std::cerr << "SnmpExtensionInit fail" << std::endl;
    }
    FreeLibrary(hLib);
    return 0;
}

Нет ничего невозможного..
Re: [network] Определение своего IP адреса
От: GrayWizard Россия  
Дата: 20.07.04 12:36
Оценка: :)))
Здравствуйте,

А без
B>#include <iostream>

реально? У меня что-то не получается...
Всё может быть... и не всё ещё было!
Re[2]: [network] Определение своего IP адреса
От: butcher Россия http://bu7cher.blogspot.com
Дата: 20.07.04 13:49
Оценка:
Здравствуйте, GrayWizard, Вы писали:

GW>А без

B>>#include <iostream>

GW>реально? У меня что-то не получается...

Убираешь все строчик, в которых встречается слова cout, cerr, endl;
Должно зароботать..

Нет ничего невозможного..
Re: [network] Определение своего IP адреса
От: Аноним  
Дата: 07.09.04 14:28
Оценка:
Здравствуйте, butcher, Вы писали:

B>Здравствуйте,


B> Уже раз 5 на моей памяти в форумах поднимался вопрос по определению IP адресов локальной машины, решил выложить несколько реализаций.

...

Можно и так:

'Returns the IP address for each IP-enabled network adapter installed in a computer.

strComputer = "."
'strComputer = "сетевое имя удаленного компа"
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set IPConfigSet = objWMIService.ExecQuery _
("Select * from Win32_NetworkAdapterConfiguration where IPEnabled=TRUE")
For Each IPConfig in IPConfigSet
If Not IsNull(IPConfig.IPAddress) Then
For i=LBound(IPConfig.IPAddress) to UBound(IPConfig.IPAddress)
WScript.Echo IPConfig.IPAddress(i), IPConfig.Description(i)
Next
End If
Next

Arthur
Re[4]: [network] Определение своего IP адреса
От: butcher Россия http://bu7cher.blogspot.com
Дата: 20.09.04 14:32
Оценка:
Здравствуйте,

Способ №3: Используя библиотеку WinPCAP


здесь
Автор: butcher
Дата: 20.09.04

Нет ничего невозможного..
Re[5]: [network] Определение своего IP адреса
От: CyberDemon Россия  
Дата: 21.09.04 14:01
Оценка:
Здравствуйте, butcher, Вы писали:

А вот у меня есть вопросец. У компа может быть > 1 адреса, например, один — выход в инет, т.е. публичный IP address, второй — адрес в локальной сети. Вроде как я где-то слышал, что есть определенное соглашение, что для локалок выбираются адреса из 192.168.x.x, 10.0.x.x и что-то еще. Но не все этого знают, не все так делают Собственно, если ли какой-нить надежный способ определения реального интернетного IP адреса? Например, у моего провайдера (Точка.ру) я получаю динамически 2 адреса — один нормальный, а второй вида 3.4.5.6 — вроде тоже нормальный, но он же не "настоящий"
Re[6]: [network] Определение своего IP адреса
От: butcher Россия http://bu7cher.blogspot.com
Дата: 21.09.04 18:32
Оценка:
Здравствуйте, CyberDemon, Вы писали:

CD>А вот у меня есть вопросец. У компа может быть > 1 адреса, например, один — выход в инет, т.е. публичный IP address, второй — адрес в локальной сети. Вроде как я где-то слышал, что есть определенное соглашение, что для локалок выбираются адреса из 192.168.x.x, 10.0.x.x и что-то еще. Но не все этого знают, не все так делают Собственно, если ли какой-нить надежный способ определения реального интернетного IP адреса? Например, у моего провайдера (Точка.ру) я получаю динамически 2 адреса — один нормальный, а второй вида 3.4.5.6 — вроде тоже нормальный, но он же не "настоящий"


Помоему, единственный верный способ, это поставить на машине с заведомо реальным IP адресом сервис, который будет делать вот что:
  • вы запускаете специальный клиент этого сервиса, который соединяется с сервером и пересылает список IP адресов вашей машины;
  • сервис пытается соединится с вами по этим адресам (естественно, локалхосты всякие отпадают);
  • если среди списка IP адресов нету адреса по которому с вами можно соединится, значит у вас нет реального адреса;
  • если соединится удаётся, но в списке такого адреса нет, значит соединение происходит через NAT;
  • и, наконец, тот адрес по которому удаётся соединится — будет реальным.
    ИМХО.

  • Нет ничего невозможного..
    Re[7]: [network] Определение своего IP адреса
    От: CyberDemon Россия  
    Дата: 21.09.04 19:04
    Оценка:
    [skipped]

    Нда...
    То есть, получается, нет надежного способа определить реальный интернет IP именно на клиенте? Блин, придется напрягать клиента выбором адреса (дело в том, что надо знать IP, по которому к клиенту может прицепиться интернет-юзер).
    Re[8]: [network] Определение своего IP адреса
    От: AvaLANche Россия  
    Дата: 21.09.04 22:42
    Оценка:
    Здравствуйте, CyberDemon, Вы писали:

    CD>[skipped]


    CD>Нда...

    CD>То есть, получается, нет надежного способа определить реальный интернет IP именно на клиенте? Блин, придется напрягать клиента выбором адреса (дело в том, что надо знать IP, по которому к клиенту может прицепиться интернет-юзер).

    Почему же? Собираешь список всех IP-адресов и выкидываешь из него виртуальные: с 10.0.0.0 по 10.255.255.255, с 172.16.0.0 по 172.31.255.255 и c 192.168.0.0 по 192.168.255.255 (RFC 1597).
    Re[9]: [network] Определение своего IP адреса
    От: CyberDemon Россия  
    Дата: 22.09.04 05:36
    Оценка:
    Здравствуйте, AvaLANche, Вы писали:

    ALA>Здравствуйте, CyberDemon, Вы писали:


    CD>>Нда...

    CD>>То есть, получается, нет надежного способа определить реальный интернет IP именно на клиенте? Блин, придется напрягать клиента выбором адреса (дело в том, что надо знать IP, по которому к клиенту может прицепиться интернет-юзер).

    ALA>Почему же? Собираешь список всех IP-адресов и выкидываешь из него виртуальные: с 10.0.0.0 по 10.255.255.255, с 172.16.0.0 по 172.31.255.255 и c 192.168.0.0 по 192.168.255.255 (RFC 1597).


    Ну я же написал уже про умников-провайдеров. Вот, свежачок — в данный момент у меня (провайдер точка.ру) 2 ip адреса:
    12.13.14.15
    83.237.3.46

    Какой выкинуть?
    Re[10]: [network] Определение своего IP адреса
    От: sercher Украина  
    Дата: 22.09.04 06:25
    Оценка:
    CD>Ну я же написал уже про умников-провайдеров. Вот, свежачок — в данный момент у меня (провайдер точка.ру) 2 ip адреса:
    CD>12.13.14.15
    CD>83.237.3.46

    CD>Какой выкинуть?


    Первый.
    Re[4]: [network] Определение своего IP адреса
    От: Аноним  
    Дата: 17.05.05 07:55
    Оценка:
    Здравствуйте, butcher,
    а как используя SNMP Extension Agent API можно изменить IP адрес?
    Re: [network] Определение своего IP адреса
    От: Аноним  
    Дата: 26.10.05 17:09
    Оценка:
    Здравствуйте, butcher, Вы писали:

    B>Здравствуйте,


    B> Уже раз 5 на моей памяти в форумах поднимался вопрос по определению IP адресов локальной машины, решил выложить несколько реализаций.

    B>Способ №1: Используя вызов WSAIoctl Winsock2 c кодом SIO_ADDRESS_LIST_QUERY
    B>
    B>#include    <iostream>
    B>#include    <winsock2.h>
    
    B>#pragma        comment (lib, "ws2_32.lib")
    
    B>int main(void)
    B>{
    B>    using            std::cout;
    B>    using            std::cerr;
    B>    using            std::endl;
    
    B>    WSADATA        wd;
    B>    SOCKET        sock;
    B>    char            buf[65535];
    B>    DWORD            dwSize = 65535;
    B>    int                nRet;
    B>    SOCKET_ADDRESS_LIST *pAddr;
    B>    SOCKADDR*    saddr;
        
    B>    nRet = WSAStartup(MAKEWORD(2,0), &wd);
    B>    if(nRet != 0){
    B>        cerr << "WSAStartup fail with code " << nRet << endl;
    B>        return -1;
    B>    }
    B>    sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    B>    if(sock == INVALID_SOCKET){
    B>        cerr << "socket fail with code " << WSAGetLastError() << endl;
    B>        return -2;
    B>    }
    B>    ZeroMemory(buf, 65535);
    B>    nRet = WSAIoctl(sock, SIO_ADDRESS_LIST_QUERY, NULL, 0, buf, 65535, &dwSize, NULL, NULL);
    B>    if(nRet != SOCKET_ERROR){
    B>        pAddr = reinterpret_cast<SOCKET_ADDRESS_LIST*>(buf);
    B>        nRet = pAddr->iAddressCount;
    B>        saddr = pAddr->Address->lpSockaddr;
    B>        while (0 < nRet--){
    B>            cout << inet_ntoa(reinterpret_cast<SOCKADDR_IN*>(saddr)->sin_addr) << endl;
    B>            saddr++;
    B>        }
    B>        nRet = 0;
    B>    }else {
    B>        cerr << "WSAIoctl fail with code " << WSAGetLastError() << endl;
    B>        nRet = -3;
    B>    }
    B>    closesocket(sock);
    B>    WSACleanup();
    B>    return nRet;
    B>}
    B>

    B>Способ №2: Используя IP Helper API
    B>
    B>#include    <iostream>
    B>#include    <windows.h>
    B>#include    <iphlpapi.h>
    
    B>#pragma        comment (lib, "iphlpapi")
    
    B>void main (void)
    B>{
    B>    using                            std::cout;
    B>    using                            std::cerr;
    B>    using                            std::endl;
        
    B>    char*                            buf;
    B>    PIP_ADAPTER_INFO    pAdaptersInfo;
    B>    PIP_ADDR_STRING        pAddr;
    B>    DWORD                            dwSize = 0;
    
    B>    if(GetAdaptersInfo(NULL, &dwSize) != ERROR_BUFFER_OVERFLOW){
    B>        cerr << "GetAdaptersInfo fail" << endl;
    B>        return;
    B>    }
    B>    buf = new char[dwSize];
    B>    if (!buf) return;
    B>    pAdaptersInfo = reinterpret_cast<PIP_ADAPTER_INFO>(buf);
    B>    if (GetAdaptersInfo (pAdaptersInfo, &dwSize) == ERROR_SUCCESS){
    B>        while (pAdaptersInfo){
    B>            pAddr = &pAdaptersInfo->IpAddressList;
    B>            while (pAddr){
    B>                cout <<"Address: " << pAddr->IpAddress.String << "/" << 
    B>                    pAddr->IpMask.String << endl;
    B>                pAddr = pAddr->Next;
    B>            }
    B>            pAdaptersInfo = pAdaptersInfo->Next;
    B>        }
    B>    }
    B>    delete[] buf;
    B>}
    B>

    B>Чуть позже представлю ещё один способ..

    Дайте пример на установку IP адресса используя IP Helper API.
    Re[11]: [network] Определение своего IP адреса
    От: Аноним  
    Дата: 13.11.07 14:23
    Оценка:
    А я что-то слышал про то что есть сайты, которым шлешь запрос,а они возвращают тебе твой ip. помоему реальнее такого айпишника трудно придумать). Только вот к сожалению конкретно сайты и то как делать этот запрос я не знаю... Не подскажете?
    Re[12]: [network] Определение своего IP адреса
    От: x-code  
    Дата: 24.11.07 16:46
    Оценка:
    Здравствуйте, Аноним, Вы писали:

    А>А я что-то слышал про то что есть сайты, которым шлешь запрос,а они возвращают тебе твой ip. помоему реальнее такого айпишника трудно придумать). Только вот к сожалению конкретно сайты и то как делать этот запрос я не знаю... Не подскажете?


    Например, http://2ip.ru
    Re[8]: [network] Определение своего IP адреса
    От: GarryIV  
    Дата: 28.11.07 06:47
    Оценка:
    Здравствуйте, CyberDemon, Вы писали:

    CD>Нда...

    CD>То есть, получается, нет надежного способа определить реальный интернет IP именно на клиенте? Блин, придется напрягать клиента выбором адреса (дело в том, что надо знать IP, по которому к клиенту может прицепиться интернет-юзер).

    Ясен пень нет. Я больше скажу — в какой нибудь локалке или офисе на клиенте вообще может не быть "реального интернет IP" (NAT/PAT)...
    С другой стороны имея IP 10.*.*.* (не выходя в инет) я имею возможноть доступаться к некоторым инет ресурсам (torrents.ru например) — такая вот конфигурация сети...

    Вобщем гадание по IP насколько увлекательно настолько и неточно

    PS: Смотри как это сделано в emule, торрент клиентах и прочих...
    WBR, Igor Evgrafov
     
    Подождите ...
    Wait...
    Пока на собственное сообщение не было ответов, его можно удалить.