I am trying to get MAC address of the currenly used network interface.
First of all this simple code based on msdn tcp client example. It is a simplified version of my client app part. It prints out IP address which is used to establish TCP connection with the server (server IP and port are passed as command line parameters). In my client application I get MAC from the IP adress, which I get from socket via getsockname fucntion.
int __cdecl main(int argc, char **argv)
{
WSADATA wsaData;
SOCKET ConnectSocket = INVALID_SOCKET;
struct addrinfo *result = NULL,
*ptr = NULL,
hints;
int iResult;
// Validate the parameters
if (argc != 3) {
printf("usage: %s server-name port\n", argv[0]);
return 1;
}
// Initialize Winsock
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
printf("WSAStartup failed with error: %d\n", iResult);
return 1;
}
ZeroMemory( &hints, sizeof(hints) );
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = IPPROTO_TCP;
// Resolve the server address and port
iResult = getaddrinfo(argv[1], argv[2], &hints, &result);
if ( iResult != 0 ) {
printf("getaddrinfo failed with error: %d\n", iResult);
WSACleanup();
return 1;
}
// Attempt to connect to an address until one succeeds
for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {
static size_t attempt = 0;
std::cout << "attempt: " << attempt++ << std::endl;
// Create a SOCKET for connecting to server
ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype,
ptr->ai_protocol);
if (ConnectSocket == INVALID_SOCKET) {
printf("socket failed with error: %ld\n", WSAGetLastError());
WSACleanup();
return 1;
}
// Connect to server.
iResult = connect( ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
if (iResult == SOCKET_ERROR) {
closesocket(ConnectSocket);
ConnectSocket = INVALID_SOCKET;
continue;
}
break;
}
freeaddrinfo(result);
if (ConnectSocket == INVALID_SOCKET) {
printf("Unable to connect to server!\n");
WSACleanup();
return 1;
}
{
char ip_address_info [128] = "";
SOCKADDR_IN host = {0};
int host_size = sizeof (SOCKADDR_IN);
int res;
res = getsockname(ConnectSocket, (SOCKADDR*) &host, &host_size);
if (res == 0) {
sprintf (ip_address_info, "%s:%d", inet_ntoa (host.sin_addr), htons (host.sin_port));
std::cout << "ip_address_info: " << ip_address_info << std::endl;
}
else {
std::cout << "res == 0 after getsockname" << std::endl;
}
host_size = sizeof (SOCKADDR_IN);
res = getpeername (ConnectSocket, (SOCKADDR*) &host, &host_size);
if (res == 0) {
sprintf (ip_address_info, "%s:%d", inet_ntoa (host.sin_addr), htons (host.sin_port));
std::cout << "ip_address_info: " << ip_address_info << std::endl;
}
else {
std::cout << "res == 0 after getpeername" << std::endl;
}
}
// shutdown the connection since no more data will be sent
iResult = shutdown(ConnectSocket, SD_SEND);
if (iResult == SOCKET_ERROR) {
printf("shutdown failed with error: %d\n", WSAGetLastError());
closesocket(ConnectSocket);
WSACleanup();
return 1;
}
std::cout << "shutdown run" << std::endl;
// cleanup
closesocket(ConnectSocket);
WSACleanup();
return 0;
}
Now the problem and question! When I try using this utility though server port 3128 in my LAN, Kaspersky antivirus (and I assume other antiviruses/farewalls) starts checking it's content (web port or something like that). And I get proxy connection: my app -> Kaspersky -> my server. The IP I get from getsockname function becomes 127.0.0.1. I used to get my currently used MAC from IP in my app, but I can't do so when IP is 127.0.0.1. When I change my server port to something like 2370 all is OK: I get good IP, get MAC. The problem however is that users, who install my program sometimes use proxy servers and port 3128 is common for them, the same goes for antivirus.
P.S.: I tested this on windows only (and currently interested also), but I assume something like this is possible on other platforms.
Call GetBestInterfaceEx with your destination socket address.
I believe you use the resulting index value returned from this function to match to the MIB_IFROW array returned from GetIfTable. the MIB_IFROW struct has a member value called bPhysAddr, which is the MAC address.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With