- 论坛徽章:
- 0
|
RT,当客户机第一次上网的时候,要302到一个广告页面,用winpcap抓包,libnet拼装包并发送,但每次调用libnet_write发送拼装好的包的时候,pcap_loop会报缓冲区溢出的错误,搞不定了...向各位大神求助...代码如下...(代码是本机上做测试用的,重定向到百度...嗯..不要在意这些细节...)
#include "stdafx.h"
#include "Test.h"
#include "libnet/libnet-headers.h"
#include "libnet/libnet-functions.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#define HTTP_PORT 0x5000
#define TCP_WID_SIZE 4096
typedef struct libnet_ipv4_hdr IPHeader;
typedef struct libnet_tcp_hdr TCPHeader;
typedef struct libnet_ethernet_hdr EthernetHeader;
typedef uint32_t u_int32_t;
typedef uint16_t u_int16_t;
typedef uint8_t u_int8_t;
void analyzePackage(const u_char* packageData);
// 唯一的应用程序对象
CWinApp theApp;
static pcap_t *adhandle;
int listener();
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data);
using namespace std;
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
HMODULE hModule = ::GetModuleHandle(NULL);
if (hModule != NULL)
{
// 初始化 MFC 并在失败时显示错误
if (!AfxWinInit(hModule, NULL, ::GetCommandLine(), 0))
{
// TODO: 更改错误代码以符合您的需要
_tprintf(_T("错误: MFC 初始化失败\n" );
nRetCode = 1;
}
else
{
// TODO: 在此处为应用程序的行为编写代码。
listener();
//openNetDevice();
}
}
else
{
// TODO: 更改错误代码以符合您的需要
_tprintf(_T("错误: GetModuleHandle 失败\n" );
nRetCode = 1;
}
return nRetCode;
}
static char* dev_name=NULL;
u_int8_t httpContent[] =
"HTTP/1.0 302 Found\n"
"Location: %s\n"
"Connection:close\n\n"
"<html>\n\t<head>\n\t\t<meta http-equiv=\"Refresh\"content=\"0 ; "
"url=www.baidu.com\">\n\t</head>\n</html>\n";
static int fl = 0;
static libnet_t* libnet = NULL;
void openNetDevice()
{
static char buf[LIBNET_ERRBUF_SIZE];
printf("%s",dev_name+ ;
libnet = libnet_init(LIBNET_RAW4,(dev_name+ , buf);
if(NULL==libnet){
printf(buf);
}
}
void createTcpHeader(u_char* tcpPackage,u_int8_t flag,u_int8_t* httpContent){
TCPHeader *tcp = (TCPHeader*)tcpPackage;
u_int32_t seq = libnet_get_prand(LIBNET_PRu32);
u_int32_t ack = tcp->th_seq;
ack++;
size_t httpSize = httpContent!=NULL?strlen((const char*)httpContent):0;
int fla= libnet_build_tcp(ntohs(tcp->th_dport),ntohs(tcp->th_sport),ntohl(seq),ntohl(ack),flag,TCP_WID_SIZE,0,0,20+httpSize,
httpContent!=NULL?httpContent:NULL,httpSize,libnet,0);
}
void createIpHeader(u_char* ipPackage,u_int16_t httpContentSize){
IPHeader *ip = (IPHeader*)ipPackage;
u_int16_t ipLength = 40;
u_int8_t typeOfService = 0;
u_int8_t identification = 0;
u_int16_t frag = 0x4000;
u_int8_t timeToLive = 63;
u_int8_t protocol =IPPROTO_TCP;
u_int16_t checkSum = 0;//设置为0,libnet会自动计算校验和
u_int32_t sourceIpAddr =ip->ip_dst.S_un.S_addr;
u_int32_t destinationIpAddr = ip->ip_src.S_un.S_addr;
int re = libnet_build_ipv4(ipLength ,typeOfService, identification,frag, timeToLive, IPPROTO_TCP,checkSum,
sourceIpAddr,destinationIpAddr,NULL,0, libnet, 0);
}
void createEthernetHeader(u_char* ethernetHeaderData){
EthernetHeader *ethernetHeader = (EthernetHeader*)ethernetHeaderData;
libnet_ptag_t ethernet_protocol_tag = 0;
libnet_build_ethernet(ethernetHeader->ether_shost,ethernetHeader->ether_dhost,
ETHERTYPE_IP,0,NULL,libnet,ethernet_protocol_tag);
}
void createHttp302(u_char* ipPackage, u_char* tcpPackage){
createTcpHeader(tcpPackage,TH_ACK|TH_PUSH|TH_FIN,httpContent);
size_t httpSize = httpContent!=NULL?strlen((const char*)httpContent):0;
createIpHeader(ipPackage,httpSize);
}
void createACKTcpHeader(u_char* ipPackage, u_char* tcpPackage){
createTcpHeader(tcpPackage,TH_ACK|TH_SYN,NULL);
createIpHeader(ipPackage,0);
}
void sendPackage(){
pcap_breakloop(adhandle);
if(libnet==NULL){printf("libnet context is NULL" ;return;}
fl = libnet_write(libnet);
//if(fla==0)return;
libnet_clear_packet(libnet);
libnet_close_raw4(libnet);
libnet_destroy(libnet);
}
void analyzePackage(const u_char* packageData){
EthernetHeader *ethernetHeader = (EthernetHeader*)packageData;
IPHeader *requestIp = (IPHeader*)(packageData+14);
TCPHeader *requestTcp = (TCPHeader*)((u_char*)requestIp+(requestIp->ip_hl&0xf)*4);//包数据数组偏移ip头长度
if(requestIp->ip_p==IPPROTO_TCP/*&&requestTcp->th_dport==HTTP_PORT*/){
libnet_t* libnet = NULL;
if(requestTcp->th_flags == TH_SYN){
pcap_breakloop(adhandle);
/********************************
* 对于这样的一个握手数据包
* 我们应该要建立连接了
* 回复一个syn ack 就是了
*********************************/
openNetDevice();
createACKTcpHeader((u_char*)requestIp,( u_char*)requestTcp);
createEthernetHeader((u_char*)ethernetHeader);
sendPackage();
}
else if (requestTcp->th_flags == (TH_ACK|TH_SYN))
{
openNetDevice();
createHttp302(( u_char*)requestIp,(u_char*)requestTcp);
createEthernetHeader((u_char*)ethernetHeader);
sendPackage();
}
}
}
int listener(){
pcap_if_t *alldevs;
pcap_if_t *d;
int inum;
int i=0;
char errbuf[PCAP_ERRBUF_SIZE];
u_int netmask;
char packet_filter[] = "ip and tcp";
struct bpf_program fcode;
/* 获得设备列表 */
if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1)
{
fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
exit(1);
}
/* 打印列表 */
for(d=alldevs; d; d=d->next)
{
printf("%d. %s", ++i, d->name);
if (d->description)
printf(" (%s)\n(%s)\n",d->name, d->description);
else
printf(" (No description available)\n" ;
}
if(i==0)
{
printf("\nNo interfaces found! Make sure WinPcap is installed.\n" ;
return -1;
}
printf("Enter the interface number (1-%d):",i);
scanf("%d", &inum);
if(inum < 1 || inum > i)
{
printf("\nInterface number out of range.\n" ;
/* 释放设备列表 */
pcap_freealldevs(alldevs);
return -1;
}
/* 跳转到已选设备 */
for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);
dev_name = new char[strlen(d->name)];
strcpy(dev_name , d->name);
/* 打开适配器 */
if ( (adhandle= pcap_open(d->name, // 设备名
65536, // 要捕捉的数据包的部分
// 65535保证能捕获到不同数据链路层上的每个数据包的全部内容
PCAP_OPENFLAG_PROMISCUOUS, // 混杂模式
1000, // 读取超时时间
NULL, // 远程机器验证
errbuf // 错误缓冲池
) ) == NULL)
{
fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n" ;
/* 释放设备列表 */
pcap_freealldevs(alldevs);
return -1;
}
/* 检查数据链路层,为了简单,我们只考虑以太网 */
if(pcap_datalink(adhandle) != DLT_EN10MB)
{
fprintf(stderr,"\nThis program works only on Ethernet networks.\n" ;
/* 释放设备列表 */
pcap_freealldevs(alldevs);
return -1;
}
if(d->addresses != NULL)
/* 获得接口第一个地址的掩码 */
netmask=((struct sockaddr_in *)(d->addresses->netmask))->sin_addr.S_un.S_addr;
else
/* 如果接口没有地址,那么我们假设一个C类的掩码 */
netmask=0xffffff;
//编译过滤器
if (pcap_compile(adhandle, &fcode, packet_filter, 1, netmask) <0 )
{
fprintf(stderr,"\nUnable to compile the packet filter. Check the syntax.\n" ;
/* 释放设备列表 */
pcap_freealldevs(alldevs);
return -1;
}
//设置过滤器
if (pcap_setfilter(adhandle, &fcode)<0)
{
fprintf(stderr,"\nError setting the filter.\n" ;
/* 释放设备列表 */
pcap_freealldevs(alldevs);
return -1;
}
printf("\nlistening on %s...\n", d->description);
/* 释放设备列表 */
pcap_freealldevs(alldevs);
/* 开始捕捉 */
pcap_loop(adhandle, 0, packet_handler, NULL);
return 0;
}
void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
analyzePackage(pkt_data);
}
|
|