Определение MAC-адреса

 

По просьбе в ветке вопросов https://www.mql5.com/ru/forum/160683/page2452#comment_54698028 сделал код.

Решил создать тему, потому что инструмент простой, но кому-то пригодится. А там его не увидят.

В 2021 уже выкладывал код для определения UUID матплаты.

Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам
Любые вопросы новичков по MQL4 и MQL5, помощь и обсуждение по алгоритмам и кодам
  • 2024.09.28
  • Tretyakov Rostyslav
  • www.mql5.com
В этой ветке я хочу начать свою помощь тем, кто действительно хочет разобраться и научиться программированию на новом MQL4 и желает легко перейти н...
 
Edgar Akhmadeev:

По просьбе в ветке вопросов сделал код

https://www.mql5.com/ru/forum/160683/page2452#comment_54698028

Решил создать тему, потому что инструмент простой, но кому-то пригодится. А там его не увидят.

В 2021 уже выкладывал код для определения UUID матплаты. Ссылка там же.

Отлично, огромное спасибо!

--

Запустил скрипт, результат такой


===

P.S. Сменил IP и заработало

==

Получается, что IP на разных машинах непостоянен, и данный способ не особо надёжен, лучше использовать UUID матплаты?

 
Vitaly Muzichenko #:

Отлично, огромное спасибо!

--

Запустил скрипт, результат такой


===

P.S. Сменил IP и заработало

==

Получается, что IP на разных машинах непостоянен, и данный способ не особо надёжен, лучше использовать UUID матплатs?

Локальный IP-адрес у каждой машины разный, и его надо скармливать данному коду для определения MAC. Если требуется найти программно - это делается через IPHlpAPI.dll. Если надо, сделаю завтра после обеда.

UUID более логично, но есть небольшой процент noname-мамок, у которых UUID совпадает. Поэтому можно объединить оба способа. Учитывая, что MAC теоретически можно поменять.

 
Edgar Akhmadeev #:

Локальный IP-адрес у каждой машины разный, и его надо скармливать данному коду для определения MAC. Если требуется найти программно - это делается через IPHlpAPI.dll. Если надо, сделаю завтра после обеда.

UUID более логично, но есть небольшой процент noname-мамок, у которых UUID совпадает. Поэтому можно объединить оба способа. Учитывая, что MAC теоретически можно поменять.

Есть такой софт, помню использовал его лет 15 назад, когда Интернет-провайдеры вязали по МАС

--

Если требуется найти программно

Было-бы супер :)

 
Edgar Akhmadeev #:
UUID более логично, но есть небольшой процент noname-мамок, у которых UUID совпадает.

Исходно, речь о MAC зашла при обсуждении клонированных виртуалок. Не знаю, что у них с UUID, но всё, что хранится на диске (если не принять специальных мер) - полностью совпадает, включая /etc/machine-id, на основании которого (вместо MAC) во многих современных системах запрашивается IP от DHCP.

А MAC при создании виртуалки обычно автогенерится, если нет задачи его склонировать или назначить явно. Так что контроль MAC - это защита от случайного, а не умышленного, запуска двух одинаковых советников с разных машин на одном счету. Хотя наличие в сети двух машин с одинаковым MAC обычно ведёт к большому гемору, особенно для человека, не знающего, как это работает ))

 
JRandomTrader #:

Исходно, речь о MAC зашла при обсуждении клонированных виртуалок. Не знаю, что у них с UUID, но всё, что хранится на диске (если не принять специальных мер) - полностью совпадает, включая /etc/machine-id, на основании которого (вместо MAC) во многих современных системах запрашивается IP от DHCP.

А MAC при создании виртуалки обычно автогенерится, если нет задачи его склонировать или назначить явно. Так что контроль MAC - это защита от случайного, а не умышленного, запуска двух одинаковых советников с разных машин на одном счету. Хотя наличие в сети двух машин с одинаковым MAC обычно ведёт к большому гемору, особенно для человека, не знающего, как это работает ))

Да и для знающего гемор может быть большой :)

 
Понятно. Я не отслеживал тему, да и не интересуюсь защитами в коммерческих продуктах. Для меня это просто технические упражнения.
 
Edgar Akhmadeev #:

Локальный IP-адрес у каждой машины разный, и его надо скармливать данному коду для определения MAC. Если требуется найти программно - это делается через IPHlpAPI.dll. Если надо, сделаю завтра после обеда.

UUID более логично, но есть небольшой процент noname-мамок, у которых UUID совпадает. Поэтому можно объединить оба способа. Учитывая, что MAC теоретически можно поменять.

 

 
// Test MAC.mq5
#property copyright "(c)2020-2024 Edgar Akhmadeev"
#property link      "https://www.mql5.com/en/users/dali"



#define AF_INET                         2               // internetwork: UDP, TCP, etc.
#define SOCK_DGRAM                      2               // datagram socket
#define IPPROTO_IP                      0               // dummy for IP



union bytes4 {
        uint    v;
        uchar   b[4];
};

union bytes6 {
        ulong   v;
        uchar   b[6];
};

struct sockAddr {
        short   family;
        ushort  port;
        bytes4  addr;
        char    zero[8];
};

#import "IPHlpAPI.dll"
        uint    SendARP(uint dstIP, uint srcIP, uchar& mac[], uint& macLen);

#import "Ws2_32.dll"
        ushort  htons(ushort port);
        int             connect(int sock, sockAddr& addr, int addrLen);
        int             socket(int af, int type, int protocol);
        int             closesocket(int sock);
        int             getsockname(int s, sockAddr& addr, int& addrLen);
        int             WSAGetLastError();
#import



void 
OnStart() {
        bytes4 IP;
        if (!GetLocalIP(IP)) {
                Print("!GetLocalIP()");
                return;
        }
        
        Print(StringFormat("IP: %d.%d.%d.%d", IP.b[0], IP.b[1], IP.b[2], IP.b[3]));
        
        bytes6 MAC;
        if (!GetMAC(IP.v, MAC)) {
                Print("!GetMAC()");
                return;
        }
        
        Print(StringFormat("MAC: %X-%X-%X-%X-%X-%X", MAC.b[0], MAC.b[1], MAC.b[2], MAC.b[3], MAC.b[4], MAC.b[5]));
}



bool
GetLocalIP(bytes4& IP) {
        int rc;
        
        int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP);
        if (sock < 0) {
                rc = WSAGetLastError();
                Print("!socket(): ", rc);
                return false;
        }
        
        sockAddr addr = { 0 };
        addr.family = AF_INET;
        
        // Google DNS
        addr.addr.b[0] = 8;
        addr.addr.b[1] = 8;
        addr.addr.b[2] = 8;
        addr.addr.b[3] = 8;
        addr.port = htons(53);
        
        rc = connect(sock, addr, sizeof(addr));
        if (rc != 0) {
                rc = WSAGetLastError();
                Print("!connect(): ", rc);
                return false;
        }
        
        int addrLen = sizeof(addr);
        rc = getsockname(sock, addr, addrLen);
        if (rc != 0) {
                rc = WSAGetLastError();
                Print("!getsockname(): ", rc);
                return false;
        }
        
        closesocket(sock);
        
        IP.v = addr.addr.v;
        return true;
}



bool
GetMAC(uint IP, bytes6& MAC) {
        MAC.v = 0;
        
    uchar mac[6];
    uint len = 6;
        uint rc = SendARP(IP, 0, mac, len);
        if (rc != 0 || len != 6) {
                Print("!SendARP(): ", rc);
                return false;
        }
        
        ArrayCopy(MAC.b, mac);
        return true;
}
 
Edgar Akhmadeev #:

Ого :)

Спасибо, огромное! Считаю, что пригодится не только мне.

Пойду изучать код.

 
Форматирование текста съезжает при копировании из редактора. У меня используется табуляция в 4 символа. "Я художник, я так вижу". Здесь заменяется на пробелы.