请问:怎样在Windows下实现SOCK_PACKET 类型的套接字?

george3038 2006-05-13 04:12:44
Linux支持一种 SOCK_PACKET 类型的套接字,用它可以收发完整的以太网帧,请问怎样在Windows下实现这种类型的套接字?
或者有没有类似的解决方法?
我现在想在windows捕获包含以太网头的数据包。
如果哪位告诉我winpcap的话,请把例子给我附一个,谢谢
...全文
511 10 打赏 收藏 转发到动态 举报
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
george3038 2006-05-23
  • 打赏
  • 举报
回复
我没有用你的程序,我看了看Winpcap的例子,和libpcap差不多,所以我就用winpcap。

还是非常感谢你,分给你了。
lk_517 2006-05-14
  • 打赏
  • 举报
回复
去看看pcap的源代码吧

实在不行你就看一看pcap相关函数的含义,也不多,然后用我这个程序去做
george3038 2006-05-14
  • 打赏
  • 举报
回复
我看了 windows 网络编程 这本书
但是没有你所说的实现方法,不知道如果要是监测到以太网桢结构,需要调用windows哪个API?
lk_517 2006-05-13
  • 打赏
  • 举报
回复
no

办法太多了

除了pcap这种开发库

简单直接的socket编程就可以了

建议找“windows网络编程”这本书看一看
george3038 2006-05-13
  • 打赏
  • 举报
回复
那就是说在windows下除了winpcap,没有其他方法获得以太网桢结构?
lk_517 2006-05-13
  • 打赏
  • 举报
回复
另外说一句,把pcap执行起来以后,通过回调函数就能对数据进行解析处理

就是这个

void packet_handler( u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data )

其中header就是头。data就是数据
lk_517 2006-05-13
  • 打赏
  • 举报
回复
#include "class_Pcap.h"

Pcap::Pcap()
{
alldevs = new pcap_if[MAX_DEVICE_NUM];
for( int i = 0;i < MAX_DEVICE_NUM;i++ )
{
device_name[i] = new char[MAX_DEVICE_NAME_LENGTH];
device_description[i] = new char[MAX_DEVICE_DESCRIPTION_LENGTH];
}
}

Pcap::~Pcap()
{
delete []alldevs;
for( int i = 0;i < MAX_DEVICE_NUM;i++ )
delete []device_name[i];
for( int i = 0;i < MAX_DEVICE_NUM;i++ )
delete []device_description[i];
outfile.close();

}

int Pcap::show_info_of_device( void )
{
pcap_if *temp;
char *Pstr;
int i = 0;
if( ( pcap_findalldevs( &alldevs,errbuf ) ) == -1 ) // error in find device
{
cerr <<" error in fine device! " <<endl;
exit(1);
}
else // no error,print the info
{
for( temp = alldevs;temp != NULL;temp = temp->next )
{
// name
if( temp->name )
{
cout << i <<":" <<" device'name is " <<temp->name <<endl;
device_name[i] = temp->name;
}
// description
if( temp->description )
{
cout << i <<":" <<" device'description is " <<temp->description <<endl;
device_description[i] = temp->description;
}
else
cout << i <<":" <<" no descripton avalable! " <<endl;
// flag
if( temp->flags )
cout << i <<":" <<" device'flag is " <<temp->flags <<endl;
else
cout << i <<":" <<" no flag avalable! " <<endl;

#ifdef PRINT_ADDRESS_OPEN
if( i != 0 )
{
// addr
if( temp->addresses->addr )
{
Pstr = inet_ntoa( temp->addresses->addr->sin_addr );
device_addr[i] = Pstr;
cout << i <<":" <<" device's address is " <<Pstr <<endl;
}
if( temp->addresses->broadaddr )
{
Pstr = inet_ntoa( temp->addresses->broadaddr->sin_addr );
device_broadaddr[i] = Pstr;
cout << i <<":" <<" device's broadcast address is " <<Pstr <<endl;
}
if( temp->addresses->dstaddr )
{
Pstr = inet_ntoa( temp->addresses->dstaddr->sin_addr );
device_dstaddr[i] = Pstr;
cout << i <<":" <<" device's destination address for p2p is " <<Pstr <<endl;
}
if( temp->addresses->netmask )
{
Pstr = inet_ntoa( temp->addresses->netmask->sin_addr );
device_netmask[i] = Pstr;
cout << i <<":" <<" device's netmask is " <<Pstr <<endl;
}
}
#endif
i++;
} // end of for
if( i == 0 )
{
cerr <<" there is no net device in your computer! ";
exit(1);
}
else
device_num = i; // obtain the device number in the machine
} // end of else
return(0);
}

int Pcap::select_device( void )
{
cout <<endl;
for( int i = 0;i < device_num;i++ )
cout <<" 设备 " <<i <<" 的名字是 " <<device_name[i] <<endl;
//cout <<" please input the devise youn want to choose: " <<endl;
cout <<" 请输入你希望选择的设备: " <<endl;
cin >>operating_flag; // indicate the device bing used
if( operating_flag < 0 || operating_flag > MAX_DEVICE_NUM )
{
//cerr <<" the num you input is not exist !" <<endl;
cerr <<" 你输入的号码并不存在,请核对后重新输入 !" <<endl;
pcap_freealldevs( alldevs );
exit(1);
}
return 0;
}

int Pcap::open_device( void )
{
if( ( caphandle = pcap_open( device_name[operating_flag],PACKET_PORTION,PCAP_OPENFLAG_PROMISCUOUS,
WAIT_TIME_FOR_READ,NULL,errbuf ) ) == NULL )
{
cerr <<" 不能打开网络适配器, " <<device_name[operating_flag]
<<" 不被本软件所支持 !" <<endl;
exit(1); // error in open
pcap_freealldevs( alldevs );
}
return 0; // suceeding opening
}

int Pcap::dump_file( void )
{
char *file_name = new char[20];
cout<<"请输入你希望保存的文件名"<<endl;
cin>>file_name;
outfile.open( file_name );
dumpfile = pcap_dump_open( caphandle,file_name );
if( dumpfile == NULL )
{
cerr<<"Error opening output file" <<endl;
return -1;
}
else
return 0;
}


int Pcap::set_filter( char *str_for_compile )
{
if( pcap_lookupnet( device_name[operating_flag],&netaddr,&netmask,errbuf ) == -1 )
{
cerr <<" lookupnet函数中的错误是 " <<errbuf <<endl;
exit(1);
}
if( pcap_compile( caphandle,&filter_expression,str_for_compile,1,netmask ) != 0 )
{
pcap_perror( caphandle," compile函数中的错误是 ");
exit(1);
}
// no error in compile
if( pcap_setfilter( caphandle,&filter_expression ) != 0 )
{
pcap_perror( caphandle," setfilter函数中的错误是 ");
exit(1);
}
pcap_freecode( &filter_expression ); // free this part of ram
return 0;
}

int Pcap::capture_packet( void )
{
int error_flag;

// no error
cout <<" 正在监听 " <<device_description[operating_flag] <<endl <<endl;
//pcap_freealldevs( alldevs ); // now,we don't need any more the device list
pcap_setmintocopy( caphandle,PACKET_NUM_KERNEL_TO_USER ); // kernel is forced to wait 32 packets and then copy the data to the user
error_flag = pcap_loop( caphandle,PACKET_NUM,packet_handler,NULL ); // start capturing

// error disposal
if( error_flag == 0 )
{
cerr <<" 监听结束,可能您设定的数据包值已经达到 " <<endl;
}
if( error_flag == -1 )
{
cerr <<" 出了些问题 " <<endl;
pcap_perror( caphandle," 捕获过程中的错误是 " );
}
if( error_flag == -2 )
cerr <<" pcap_breakloop()运行,导致循环还没有捕获到数据包就已经结束 " <<endl;
// no error
return(0);
}

int Pcap::free_device( void )
{
pcap_freealldevs( alldevs ); // now,we don't need any more the device list
return(0);
}


这是好早以前写的一个pcap的类,当时确认运行没有问题,后来一直没有动过

我先说一句,楼主如果直接看我这个类可能看不懂,除非你了解常用的pcap函数,而且我也没有提供main函数,具体调用关系请自行学习后解决。

这只是给你作为学习参考
sankt 2006-05-13
  • 打赏
  • 举报
回复
The following are the only two type specifications supported for Windows Sockets 1.1:

SOCK_STREAM
Provides sequenced, reliable, two-way, connection-based byte streams with an OOB data transmission mechanism. Uses TCP for the Internet address family.


SOCK_DGRAM
Supports datagrams, which are connectionless, unreliable buffers of a fixed (typically small) maximum length. Uses UDP for the Internet address family.


In Windows Sockets 2, many new socket types will be introduced and no longer need to be specified, since an application can dynamically discover the attributes of each available transport protocol through the WSAEnumProtocols function. Socket type definitions appear in Winsock2.h, which will be periodically updated as new socket types, address families, and protocols are defined.



george3038 2006-05-13
  • 打赏
  • 举报
回复
无人问津?????
george3038 2006-05-13
  • 打赏
  • 举报
回复
谢谢各位

64,648

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

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