如何取得远程主机网卡的MAC 地址?

Kylix_XP 2003-07-07 08:45:38
比如说当http://www.163.com给我所在的主机发送数据包时,如何取得远程主机(www.163.com)网卡的MAC 地址?
用winpcap编程的代码如下:d->name表示设备的名称,d->description表示设备的描述,那么怎么取得MAC地址呢?
#include "pcap.h"

main()
{
pcap_if_t *alldevs;
pcap_if_t *d;
int i=0;
char errbuf[PCAP_ERRBUF_SIZE];

/* Retrieve the device list *//*取得网卡列表*/
if (pcap_findalldevs(&alldevs, errbuf) == -1)
{
fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
exit(1);
}

/* Print the list */
for(d=alldevs;d;d=d->next)
{
printf("%d. %s", ++i, d->name);
if (d->description)
printf(" (%s)\n", d->description);
else printf(" (No description available)\n");
}

if(i==0)
{
printf("\nNo interfaces found! Make sure WinPcap is installed.\n");
return;
}

/* We don't need any more the device list. Free it */
pcap_freealldevs(alldevs);
}

在WIND2000下,输出结果如下:


1. {4E273621-5161-46C8-895A-48D0E52A0B83} (Realtek RTL8029(AS) Ethernet Adapter)
2. {5D24AE04-C486-4A96-83FB-8B5EC6C7F430} (3Com EtherLink PCI)



...全文
388 34 打赏 收藏 转发到动态 举报
写回复
用AI写文章
34 条回复
切换为时间正序
请发表友善的回复…
发表回复
Skt32 2003-07-15
  • 打赏
  • 举报
回复
翻出一个代码,留个EMAIL到我消息里,发给你
qsfsea 2003-07-15
  • 打赏
  • 举报
回复
gz
双杯献酒 2003-07-15
  • 打赏
  • 举报
回复
GZ
zjyang1 2003-07-15
  • 打赏
  • 举报
回复
up
jvcit 2003-07-13
  • 打赏
  • 举报
回复
关注
cwanter 2003-07-13
  • 打赏
  • 举报
回复
通过ARP协议是不行了,因为arp协议包是没有IP地址的,所以不可路由,根本不可能在路由器间转发。snmp可能是可行途径,但我对snmp不了解。
Skt32 2003-07-12
  • 打赏
  • 举报
回复
得到远程机器MAC地址源代码http://www.chinaoak.com/download/sources/network/RenoteMAC.doc
hookuy 2003-07-12
  • 打赏
  • 举报
回复
可以用NetBIOS获得M局域网内主机MAC地址。

大家都没有用NetBIOS,是不是现在已经不用这个了吗?
laker_tmj 2003-07-12
  • 打赏
  • 举报
回复
http://www.chinaoak.com/download/sources/network/RenoteMAC.doc

行不行,我不太會,請高手試試, 謝謝!!!
laker_tmj 2003-07-12
  • 打赏
  • 举报
回复
up learn
ulovexd 2003-07-12
  • 打赏
  • 举报
回复
Up
Carapee 2003-07-09
  • 打赏
  • 举报
回复


实现文件:
// ResolveThread.cpp : implementation file
//

#include "stdafx.h"
#include <nb30.h>
#include <string.h>
#include "pinger.h"
#include "ResolveThread.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CResolveThread

IMPLEMENT_DYNCREATE(CResolveThread, CWinThread)

CResolveThread::CResolveThread()
{
m_dwTimeout = 2000;
m_dwCount = 3;
}

CResolveThread::CResolveThread(DWORD dwTimeout, DWORD dwCount)
{
m_dwTimeout = dwTimeout;
m_dwCount = dwCount;
}

CResolveThread::~CResolveThread()
{
}

BOOL CResolveThread::InitInstance()
{
// TODO: perform and per-thread initialization here
m_sockNbt = WSASocket(AF_INET, SOCK_DGRAM, IPPROTO_UDP, NULL, 0, WSA_FLAG_OVERLAPPED);
if (INVALID_SOCKET == m_sockNbt)
{
return FALSE;
}

int nTimeout = (int)m_dwTimeout;
if (SOCKET_ERROR == setsockopt(m_sockNbt, SOL_SOCKET, SO_SNDTIMEO, (char*)(&nTimeout), sizeof(nTimeout)))
{
closesocket(m_sockNbt);
return FALSE;
}

m_nUniID = (USHORT)m_nThreadID;

return TRUE;
}

int CResolveThread::ExitInstance()
{
// TODO: perform any per-thread cleanup here
return CWinThread::ExitInstance();
}

BEGIN_MESSAGE_MAP(CResolveThread, CWinThread)
//{{AFX_MSG_MAP(CResolveThread)
// NOTE - the ClassWizard will add and remove mapping macros here.
ON_THREAD_MESSAGE(UM_RESOLVE_HOST_NAME, OnResolveHostName)
ON_THREAD_MESSAGE(UM_DESTROY_THREAD, OnDestroyThread)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CResolveThread message handlers

void CResolveThread::OnResolveHostName(WPARAM /* wParam */, LPARAM lParam)
{
RESOLVE_HOST_NAME_MESSAGE * pResolveHostNameMessage = (RESOLVE_HOST_NAME_MESSAGE *)lParam;
DWORD dwIpAddress = pResolveHostNameMessage->dwIpAddress;

sockaddr_in to_addr;
sockaddr_in from_addr;
int from_addr_len = sizeof(from_addr);
to_addr.sin_addr.s_addr = dwIpAddress;
to_addr.sin_port = htons(137);
to_addr.sin_family = AF_INET;

NBTSTAT_REQUEST_PACKET * pRequest = (NBTSTAT_REQUEST_PACKET*)m_pSendBuf;
memset(pRequest, 0, sizeof(NBTSTAT_REQUEST_PACKET));
pRequest->question_count = htons(1);
pRequest->name_len = 0x20;
memcpy(pRequest->name, NETBIOS_QUERY_NAME, 32);
pRequest->type = htons(0x21);
pRequest->protocol = htons(1);

BOOL bNetBiosNameResolved = FALSE;

for (DWORD i=0; i<3/*m_dwCount*/; i++)
{
int nRet;
int nTimeout = (int)m_dwTimeout;

pRequest->id = ++m_nUniID;

if (SOCKET_ERROR == sendto(m_sockNbt, (char*)m_pSendBuf, sizeof(NBTSTAT_REQUEST_PACKET), 0, (struct sockaddr*)(&to_addr), sizeof(to_addr)))
{
continue;
}

if (SOCKET_ERROR == setsockopt(m_sockNbt, SOL_SOCKET, SO_RCVTIMEO, (char*)(&nTimeout), sizeof(nTimeout)))
{
continue;
}

nRet = recvfrom(m_sockNbt, (char*)m_pRecvBuf, BUFFER_SIZE, 0, (struct sockaddr*)(&from_addr), &from_addr_len);
if (nRet == SOCKET_ERROR)
{
continue;
}
else
{
PNBTSTAT_RESPONSE_HEADER pResponseHeader = (PNBTSTAT_RESPONSE_HEADER)m_pRecvBuf;
PNETBIOS_NAME_ENTRY pNameEntry = (PNETBIOS_NAME_ENTRY)(m_pRecvBuf + sizeof(NBTSTAT_RESPONSE_HEADER));
if (pResponseHeader->id == m_nUniID && pResponseHeader->name_number != 0 && pResponseHeader->name_number < 64 && pNameEntry->name_term == 0)
{
CHAR szNetBiosName[64];

char * pNameEnd = strchr((char*)(pNameEntry->name), 0x20);
if (NULL != pNameEnd)
{
pNameEnd[0] = 0;
}
else
{
szNetBiosName[15] = 0;
}

strncpy(szNetBiosName, (char*)(pNameEntry->name), 15);

for (USHORT j=0; j<pResponseHeader->name_number; j++)
{
if (0 == memcmp(pNameEntry[j].name, "\x01\x02__MSBROWSE__\x02\x01", 16))
{
strcat(szNetBiosName, "!");
}
}

*(pResolveHostNameMessage->pstrHostName) = szNetBiosName;
bNetBiosNameResolved = TRUE;
break;
}
}
}
/*
if (FALSE == bNetBiosNameResolved)
{
HOSTENT * pHostEnt = gethostbyaddr((char*)&dwIpAddress, sizeof(dwIpAddress), AF_INET);
if (NULL != pHostEnt)
{
*(pResolveHostNameMessage->pstrHostName) = pHostEnt->h_name;
}
}
*/
SetEvent(pResolveHostNameMessage->hEvent);
}

void CResolveThread::OnDestroyThread(WPARAM wParam, LPARAM lParam)
{
PostThreadMessage(WM_QUIT, 0, 0);
}


Carapee 2003-07-09
  • 打赏
  • 举报
回复
没有一种100%可行的办法满足你的需求。有一些办法不是很完美
1)如果在局域网中,可以使用ARP解析得到目的主机的MAC地址,这个方法只限于局域网内,相同网段的主机有效,不同子网的ARP请求只能得到网关的MAC地址。相关的API:
CreateIpNetEntry
CreateProxyArpEntry
DeleteIpNetEntry
DeleteProxyArpEntry
FlushIpNetTable
GetIpNetTable
SendARP
SetIpNetEntry

2)如果目的主机使用了WINS服务器,你可以把自己的机器设置成使用相同的WINS服务器,然后使用NBTSTAT -A 命令行就可以得到目的主机的MAC地址

2)如果目的主机在公网上,也不是说完全不可能得到它的MAC地址,但是要有一些条件限制:
目的主机与你相连的的网络接口是以太网接口或者PPPOE接口;
目的主机打开了137端口;
你与目的主机之间的网络互连设备没有设置NETBIOS过滤的ACL;
这种条件下,可以通过NetBIOS name query得到目的主机的MAC地址。
代码如下:


头文件:
#if !defined(AFX_RESOLVETHREAD_H__325B3F03_E8F6_4B98_81D3_19C32CADCA21__INCLUDED_)
#define AFX_RESOLVETHREAD_H__325B3F03_E8F6_4B98_81D3_19C32CADCA21__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
// ResolveThread.h : header file
//

#define NETBIOS_QUERY_NAME "\x43\x4b\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41\x41"

#pragma pack(1)

typedef struct tagNBTSTAT_REQUEST_PACKET
{
USHORT id;
USHORT flag;
USHORT question_count;
USHORT answer_count;
USHORT authority_count;
USHORT additional_record_count;
UCHAR name_len;
UCHAR name[32];
UCHAR name_term;
USHORT type;
USHORT protocol;
} NBTSTAT_REQUEST_PACKET, *PNBTSTAT_REQUEST_PACKET;

typedef struct tagNBTSTAT_RESPONSE_HEADER
{
USHORT id;
USHORT flag;
USHORT question_count;
USHORT answer_count;
USHORT authority_count;
USHORT additional_record_count;
UCHAR name_len;
UCHAR name[32];
UCHAR name_term;
USHORT type;
USHORT protocol;
ULONG time_to_live;
USHORT length;
UCHAR name_number;
} NBTSTAT_RESPONSE_HEADER, *PNBTSTAT_RESPONSE_HEADER;

typedef struct tagNETBIOS_NAME_ENTRY
{
UCHAR name[16];
UCHAR name_flag;
UCHAR name_term;
} NETBIOS_NAME_ENTRY, *PNETBIOS_NAME_ENTRY;

typedef struct tagNBTSTAT_RESPONSE_TAIL
{
UCHAR unit_id[6];
UCHAR jumpers;
UCHAR test_result;
USHORT version_number;
USHORT period_of_statistics;
USHORT number_of_crcs;
USHORT number_alignment_errors;
USHORT number_of_collisions;
USHORT number_send_abort;
ULONG number_good_sends;
ULONG number_good_receives;
USHORT number_retransmits;
USHORT number_no_resource_conditions;
USHORT number_free_command_blocks;
USHORT total_number_command_blocks;
USHORT max_total_number_command_blocks;
USHORT number_pending_sessions;
USHORT max_number_pending_sessions;
USHORT max_total_session_possible;
USHORT session_data_packet_size;
} NBTSTAT_RESPONSE_TAIL, *pNBTSTAT_RESPONSE_TAIL;

#pragma pack()

typedef struct tagRESOLVE_HOST_NAME_MESSAGE
{
DWORD dwIpAddress;
CString * pstrHostName;
DWORD dwResult;
HANDLE hEvent;
} RESOLVE_HOST_NAME_MESSAGE;

/////////////////////////////////////////////////////////////////////////////
// CResolveThread thread

class CResolveThread : public CWinThread
{
DECLARE_DYNCREATE(CResolveThread)
public:
CResolveThread(); // protected constructor used by dynamic creation
CResolveThread(DWORD dwTimeout, DWORD dwCount);
virtual ~CResolveThread();

// Attributes
public:

// Operations
public:

// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CResolveThread)
public:
virtual BOOL InitInstance();
virtual int ExitInstance();
//}}AFX_VIRTUAL

// Implementation
protected:

// Generated message map functions
//{{AFX_MSG(CResolveThread)
// NOTE - the ClassWizard will add and remove member functions here.
afx_msg void OnResolveHostName(WPARAM wParam, LPARAM lParam);
afx_msg void OnDestroyThread(WPARAM wParam, LPARAM lParam);
//}}AFX_MSG

DECLARE_MESSAGE_MAP()
public:
UCHAR m_pSendBuf[BUFFER_SIZE];
UCHAR m_pRecvBuf[BUFFER_SIZE];
SOCKET m_sockNbt;
DWORD m_dwTimeout;
DWORD m_dwCount;
USHORT m_nUniID;
};

/////////////////////////////////////////////////////////////////////////////

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_RESOLVETHREAD_H__325B3F03_E8F6_4B98_81D3_19C32CADCA21__INCLUDED_)

whoo 2003-07-09
  • 打赏
  • 举报
回复
这个问题以前有人问过,楼主可以找一找。

至于解决方法,我好像在那本杂志上看过,“计算机世界”??,忘了名字了。

大概的方法是这样子的:通过SNMP访问路由器来查询。
fengge8ylf 2003-07-09
  • 打赏
  • 举报
回复
这个问题困惑我好长时间了
daphant 2003-07-08
  • 打赏
  • 举报
回复
你可以先 ping它,它会有个返回包,用winpcap捕包,可以取到这个包的mac地址。不过,我没有在外网上试过
Semigod 2003-07-08
  • 打赏
  • 举报
回复
这个问题比较难。我以前也问过。不管怎么样,收藏了先
sunyou 2003-07-08
  • 打赏
  • 举报
回复
gz
chenqsbeast 2003-07-08
  • 打赏
  • 举报
回复
只能去局域网的mac
http://www.zgtcc.com/upload/files/xinxi/F:XBakX20030305XNetAdminXNetAdminXLib.zip
曾经的猎狐 2003-07-08
  • 打赏
  • 举报
回复
看来你要求助masterz 了
加载更多回复(14)

18,356

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧