高手指点 在WINDOWS下怎么设置网卡的混杂模式

suirun00 2005-06-16 11:28:38
对网卡混杂模式的设置是通过原始套接字(raw socket)来实现的,这也有别于通常经常使用的数据流套接字和数据报套接字。在创建了原始套接字后,需要通过setsockopt()函数来设置IP头操作选项,然后再通过bind()函数将原始套接字绑定到本地网卡。为了让原始套接字能接受所有的数据,还需要通过ioctlsocket()来进行设置,而且还可以指定是否亲自处理IP头。至此,实际就可以开始对网络数据包进行嗅探了,对数据包的获取仍象流式套接字或数据报套接字那样通过recv()函数来完成。
这个好想只能设置接收到IP层的信息,不能实现显示网卡的MAC地址!!
高手指点 怎么才能完成接收网卡的MAC地址的功能
...全文
4185 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
Kudeet 2005-06-20
  • 打赏
  • 举报
回复
用Raw Socket实现代码如下:
setsockopt(sock, IPPROTO_IP, IP_HDRINCL, (char*)&flag, sizeof(flag); //设置 IP 头操作选项
bind(sockRaw, (PSOCKADDR)&addrLocal, sizeof(addrLocal); //把 sockRaw 绑定到本地网卡上
ioctlsocket(sockRaw, SIO_RCVALL, &dwValue); //让 sockRaw 接受所有的数据
flag 标志是用来设置 IP 头操作的, 也就是说要亲自处理 IP 头: bool flag = ture;
addrLocal 为本地地址: SOCKADDR_IN addrLocal;
dwValue 为输入输出参数, 为 1 时执行, 0 时取消: DWORD dwValue = 1;
lonelyeagle 2005-06-20
  • 打赏
  • 举报
回复
int err;

m_sockCap = socket(AF_INET , SOCK_RAW , IPPROTO_IP);
if(m_sockCap==INVALID_SOCKET)
return WSAGetLastError();

char name[MAX_HOSTNAME_LAN];
err = gethostname(name, MAX_HOSTNAME_LAN);
if(err==SOCKET_ERROR)
return WSAGetLastError();

struct hostent FAR * pHostent;
pHostent = gethostbyname(name);

m_nCapPort = capPort;

SOCKADDR_IN sa;
sa.sin_family = AF_INET;
sa.sin_port = htons(m_nCapPort);
memcpy(&sa.sin_addr.S_un.S_addr, pHostent->h_addr_list[0], pHostent->h_length);

err = bind(m_sockCap, (PSOCKADDR)&sa, sizeof(sa));
if(err==SOCKET_ERROR)
return WSAGetLastError();

BOOL bopt=TRUE;
err = setsockopt(m_sockCap, SOL_SOCKET, SO_REUSEADDR, (char*)&bopt, sizeof(bopt));

bopt = TRUE;
err = setsockopt(m_sockCap, IPPROTO_IP, IP_HDRINCL, (char*)&bopt, sizeof(bopt));
if(err==SOCKET_ERROR)
return WSAGetLastError();

// Set this option to receive all the IP packets.
DWORD dwBufferLen[10];
DWORD dwBufferInLen = 1;
DWORD dwBytesReturned = 0;
err = WSAIoctl(m_sockCap,
SIO_RCVALL,
&dwBufferInLen,
sizeof(dwBufferInLen),
dwBufferLen,
sizeof(dwBufferLen),
&dwBytesReturned,
NULL,
NULL);
if(err==SOCKET_ERROR)
return WSAGetLastError();
fisker0303 2005-06-17
  • 打赏
  • 举报
回复
RAW SOCKET只能截取为数不多的几种协议包,不支持很正常。
yhqs540 2005-06-17
  • 打赏
  • 举报
回复
使用winpcap
里面有一个SetAdapterxxxxx函数,具体名字忘了,查一下文档。
oyljerry 2005-06-17
  • 打赏
  • 举报
回复
winpcap功能要强大些
kingzai 2005-06-16
  • 打赏
  • 举报
回复
winpcap can do it.
see winpcap example "testapp" ,it can capture your mac address and other.
suirun00 2005-06-16
  • 打赏
  • 举报
回复
这个好象只能显示本机器的MAC地址吧
aiyue2010 2005-06-16
  • 打赏
  • 举报
回复
// Function name : SetAdapterReceiveAll
// Description : 设置网卡可以接收所有IP的数据(混杂模式)
// Return type : void
bool SetAdapterReceiveAll()
{
//检查Winsock版本
WORD ver=MAKEWORD(2,2);
WSADATA wsaData;
int err=WSAStartup(ver,&wsaData);
if(err!=0)
{
_RPT2( _CRT_ERROR,"启动WinSocket version %d.%d 错误!",2,2);
return false;
}
//创建原始套接字
s=socket(AF_INET,SOCK_RAW,IPPROTO_RAW);
//设置为对IP头亲自操
BOOL bFlag=TRUE;
err=setsockopt(s,IPPROTO_IP,IP_HDRINCL,(char *)&bFlag,sizeof(bFlag));
if(err!=0)
return false;
//获得本机地址
char hostname[256];
memset(hostname,0,256);
err=gethostname(hostname,256);
if(err!=0)
return false;
struct hostent * phost=gethostbyname(hostname);
if(!phost)
return false;
//把原始套接字绑定到本定网卡
struct sockaddr_in addr_in;
memset(&addr_in,0,sizeof(addr_in));
addr_in.sin_addr=*(in_addr *)phost->h_addr_list[0];
addr_in.sin_family = AF_INET;
addr_in.sin_port = htons(57274);//端口号,可以是任意值,但最好不要和公共端口冲突
bind(s, (PSOCKADDR)&addr_in, sizeof(addr_in));
// dwValue为输入输出参数,为1时执行,0时取消
DWORD dwValue = 1;
// 设置 SOCK_RAW 为SIO_RCVALL,以便接收所有的IP包。其中SIO_RCVALL
// 的定义为: #define SIO_RCVALL _WSAIOW(IOC_VENDOR,1)
ioctlsocket(s, SIO_RCVALL, &dwValue);
return true;
}
qrlvls 2005-06-16
  • 打赏
  • 举报
回复
使用winpcap
http://www.winpcap.org/

18,356

社区成员

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

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