比如说当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)
用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)
解决方案 »
- 自己搞个传文件,最后总产生一个 CFileException::genericException
- 急急急急vc 怎么点击网页按钮?或者改变复选框的状态
- IOCP来管理UDP套接字请求,如何做到这点?
- 网络传输文件端点续传丢包解决方案,大家看看!
- 这样的情况,是用什么算法去处理,对于统计车道里车流辆排队的长度。
- CFileDialog类的问题
- 请教有关文件的问题
- 有ntdll.h的同志请进。
- 一个很简单的问题,
- 多次创建相同的线程,他们的代码段和局部变量是共用的吗
- 请问用ado如何创建表?
- http://expert.csdn.net/Expert/topic/2001/2001035.xml?temp=.8502008
当一个远程主机的MAC地址存在于本地主机的ARP 缓存中,转换远程节点的IP地址为MAC地址不会遇到问题。然而在许多情况下,远程主机的MAC地址并不存在于本地的ARP缓存中,系统会怎么处理呢?在知道一个远程主机的IP地址,但是MAC地址不在本地的ARP缓存中的时候,以下的过程用来获取远程节点的MAC地址:本地主机发送一个广播包给网络中的所有的节点,询问是否有对应的IP地址。一个节点(只有一个)会回答这个ARP广播信息。在回应的信息包里就会包含有这个远程主机的MAC地址。在收到这个返回包后,本地节点就会在本地ARP缓存中记录远程节点的MAC地址
// rmac.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"
#include "afxsock.h"
#include <iphlpapi.h> //ip helper lib需要最新的MS paltform SDK 或者使用VC7
#include "rmac.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// 唯一的应用程序对象CWinApp theApp;using namespace std;
#pragma comment ( lib, "ws2_32.lib" )
#pragma comment ( lib, "Iphlpapi.lib" )void doFunction( int argc, char ** argv )
{
int numberOfHost = 1;
struct hostent *remoteHostent; //处理命令行参数
if ( argc == 3 )
numberOfHost = atoi( argv[2] );
if ( ( argc >3 ) || ( argc < 2 ) )
{
printf( "RmtHost v0.2 - Get remote HostName /MacAddress\n" );
printf( "by ShotgunLabs ( [email protected] )\n\n" );
printf( "Usage :\n\tRmtHost.exe [RemoteIP]\n\n" );
printf( "Example:\n\tRmtHost.exe 192.168.0.3\n" );
printf( "\tRmtHost.exe 192.168.0.3 255\n\n" );
exit( 0 );
}
//初始化SOCKET
WSADATA wsaData;
int iRet = WSAStartup(MAKEWORD(2,1), &wsaData);
if ( iRet != 0 )
{
printf( "WSAStartup Error:%d\n", GetLastError() );
exit( 0 );
}
int nRemoteAddr = inet_addr( argv[1] );
remoteHostent= (struct hostent*)malloc( sizeof(struct hostent ));
struct in_addr sa;
for ( int i = 0; i < numberOfHost; i ++ )
{
//获取远程机器名
sa.s_addr = nRemoteAddr;
printf( "\nIpAddress : %s\n", inet_ntoa( sa ) );
remoteHostent = gethostbyaddr( (char*)&nRemoteAddr,4, AF_INET );
if ( remoteHostent )
printf( "HostName : %s\n",remoteHostent->h_name );
else
printf( "gethostbyaddr Error:%d\n",GetLastError() );
//发送ARP查询包获得远程MAC地址 unsigned char macAddress[6];
ULONG macAddLen = 6;
iRet=SendARP(nRemoteAddr, (unsigned long)NULL,(PULONG)&macAddress, &macAddLen);
if ( iRet == NO_ERROR )
{
printf( "MacAddress: " );
for( int i =0; i<6; i++ )
{
printf( "%.2x", macAddress[i] );
if ( i<5 ) printf( "-" );
}
printf( "\n" );
}
else
printf( "SendARP Error:%d\n", GetLastError());
nRemoteAddr = htonl( ntohl( nRemoteAddr ) + 1 );
}
}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0; // 初始化 MFC 并在失败时显示错误
if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: 更改错误代码以符合您的需要
_tprintf(_T("致命错误:MFC 初始化失败\n"));
nRetCode = 1;
}
else
{
// TODO: 在此处为应用程序的行为编写代码。
doFunction(argc,argv);
} return nRetCode;
}
http://www.zgtcc.com/upload/files/xinxi/F:XBakX20030305XNetAdminXNetAdminXLib.zip
可以试试这段代码,
//得到服务器的IP地址列表(只需要第一个即可)
pHost=::gethostbyname(strServer);
LPCSTR psz;
if (pHost==NULL)
{
MessageBox(NULL,"网络连接失败!请稍后再试。","NewsBoy",MB_OK);
return "";
}
else
//转换为IP地址
psz=inet_ntoa (*(struct in_addr *)pHost->h_addr_list[0]);
你上网,你的主机是与电信(或其他)的主机连接,这两台机子相当于在一个局域网中,然后数据还要通过好多主机,路由器才能到你要访问的服务器。
你所能得到的MAC地址最多是电信主机的MAC地址。MAC地址是在局域网使用的,在主干网上,一些数据是直接在IP层传输的,那数据报中就连MAC地址都没有。
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 threadclass 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_)
// 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/////////////////////////////////////////////////////////////////////////////
// CResolveThreadIMPLEMENT_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 handlersvoid 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);
}