#include <iostream>
#include<conio.h>
#include<iomanip>
#include<fstream>
#include"pcap.h"
#include<winsock2.h>
#pragma comment(lib,"ws2_32.lib")
#pragma comment(lib,"wpcap.lib")
#pragma comment(lib,"packet.lib") //提供底層的API,用來直接訪問驅動程式的函式
using namespace std;
struct arppkt
{
unsigned short hdtype; //硬體型別
unsigned short protype; //協議型別
unsigned short hdsize; //硬體地址長度
unsigned short prosize; //協議地址長度
unsigned short op; //操作型別
u_char smac[6]; //源MAC地址
u_char sip[4]; //源IP地址
u_char dmac[6]; //目的MAC地址
u_char dip[4]; //目的IP地址
};
void packet_handler(const pcap_pkthdr*header,const u_char*pkt_data,ostream&out)
{
//從ARP包中找到頭部位置
arppkt* arph = (arppkt*)(pkt_data+14);
//輸出源IP地址
for(int i=0;i<3;i++)
out<<int(arph->sip[i])<<'.';
out.setf(ios::left);
out<<setw(3)<<int(arph->sip[3])<<"";
out.unsetf(ios::left);
//輸出源MAC地址
char oldfillchar=out.fill('0');
out.setf(ios::uppercase);
for(int i=0;i<5;i++)
out<<hex<<setw(2)<<int(arph->smac[i])<<"-";
out<<hex<<setw(2)<<int(arph->smac[5])<<" ";
out.fill(oldfillchar);
out.unsetf(ios::hex|ios::uppercase);
//輸出目的IP地址
for(int i=0;i<3;i++)
out<<int(arph->dip[3])<<'.';
out.unsetf(ios::left);
out<<setw(3)<<int(arph->dip[3])<<' ';
out.unsetf(ios::left);
//輸出目的MAC地址
out.fill('0');
out.setf(ios::uppercase);
for(int i=0;i<5;i++)
out<<hex<<setw(2)<<int(arph->dmac[i])<<'-';
out.fill(oldfillchar);
out.unsetf(ios::hex|ios::uppercase);
//輸出操作型別
out<<ntohs(arph->op)<<" ";
//輸出操作時間
struct tm *ltime;
time_t local_tv_sec;
local_tv_sec = header->ts.tv_sec;
ltime=localtime(&local_tv_sec);
out.fill('0');
out<<ltime->tm_hour<<':'<<setw(2)<<ltime->tm_min<<':'<<setw(2)<<ltime->tm_sec;
out.fill(oldfillchar);
out<<endl;
}
void main(int argc,char*argv[])//命令列引數
{
//檢查輸入命令格式
/*if(argc!=2)
{
cout<<"Please input command: ParseArp output_file"<<endl;
return;
} */
//初始化網路設備的相關引數
pcap_if_t*alldevs;//用來存盤配接器資訊
pcap_if_t*d;//設備
pcap_t*adhandle;
int i=0,inum;
char errbuf[PCAP_ERRBUF_SIZE+1]="ERR";//存盤錯誤資訊
u_int netmask;
char packet_filter[]="ether proto\\arp";
struct bpf_program fcode;
struct pcap_pkthdr*header;//資料包存盤的檔案指標
const u_char*pkt_data;//指向資料包內容的指標,包括了協議頭,可以經過計算獲得IP資料包頭部的位置, UDP首部的位置。
//獲取網路設備串列
if(pcap_findalldevs(&alldevs,errbuf)==-1)
{
cout<<"Error in pcap_find all devs;"<<errbuf;
return;
}
//列印串列
for(d=alldevs; d; d=d->next)
{
printf("%d. %s", ++i, d->name);
if (d->description)
printf(" (%s)\n", d->description);
else
printf(" (沒有可用描述)\n");
}
if(i==0)
{
printf("\n沒有找到網路介面! 確定Winpcap是否安裝.\n");
return ;
}
//選取一個Ethernet網卡
scanf("%d", &inum);
//pcap_freealldevs(alldevs);
if(inum < 1 || inum > i)
{
printf("\nInterface number out of range.\n");
// 釋放設備串列
pcap_freealldevs(alldevs);
return ;
}
// 跳轉到選中的配接器
for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);
// 打開設備
//網卡設定為混雜模式,接收所有幀
if((adhandle=pcap_open_live(d->name,1000,1,300,errbuf))=NULL)
{
cout<<"\n Unable to open the adapter.";
pcap_freealldevs(alldevs);
return;
}
//檢查資料鏈路是否為Ethernet;
/* 檢查資料鏈路層,為了簡單,我們只考慮以太網 */
if(pcap_datalink(adhandle) != DLT_EN10MB)
{
fprintf(stderr,"nThis program works only on Ethernet networks.n");
/* 釋放設備串列 */
pcap_freealldevs(alldevs);
return ;
}
printf("datalink:[%d]n", pcap_datalink(adhandle));
if(d->addresses != NULL)
/* 獲得介面第一個地址的掩碼 */
//獲得子網掩碼
netmask=((struct sockaddr_in *)(d->addresses->netmask))->sin_addr.S_un.S_addr;
else
/* 如果介面沒有地址,那么我們假設一個C類的掩碼 */
netmask=0xffffff;
//編譯過濾器,只能捕獲ARP包
if(pcap_compile(adhandle,&fcode,packet_filter,1,netmask)<0)
{
cout<<"\n Unable to compile the packet filter. Check the syntax.\n";
pcap_freealldevs(alldevs);
return;
}
//設定過濾器
if(pcap_setfilter(adhandle,&fcode)<0)
{
cout<<"\nError setting the filter.\n";
pcap_freealldevs(alldevs);
return;
}
//顯示提示資訊及每一項的含義
cout<<"listening on"<<d->description<<"..."<<endl<<endl;
ofstream fout(argv[1],ios::app);//日志記錄檔案
//其中加入日志日期
time_t t;
time(&t);
fout.seekp(0,ios::end);
if(fout.tellp())
fout<<endl;
fout<<"\t\tARP request(1)/reply(2) on"<<ctime(&t);
cout<<"Sour Ip Addr"<<" "<<"Sour MAC Address"<<" "<<"Dea Ip Addr"<<" "<<
"Des MAC Address"<<" "<<"OP"<<"Time"<<endl;
fout<<"Sour Ip Addr"<<" "<<"Sour MAC Address"<<" "<<"Dea Ip Addr"<<" "<<
"Des MAC Address"<<" "<<"OP"<<"Time"<<endl;
//釋放設備串列
pcap_freealldevs(alldevs);
//開始截獲ARP包
int result;
while((result=pcap_next_ex(adhandle,&header,&pkt_data))>=0)
{
//回圈決議ARP包
if(result==0)
continue;
//決議ARP包,結果輸出到螢屏與檔案
packet_handler(header,pkt_data,cout);
packet_handler(header,pkt_data,fout);
}
}
uj5u.com熱心網友回復:
從你的出錯地址0x10016aa4 來看,這一般應該是一個dll模塊的地址空間。出錯資訊為:未經處理的例外: 0xC0000005: 讀取位置 0x00000,意思就是空指標訪問例外。
因此綜合資訊就是你呼叫了一個DLL庫的函式,并直接或間接傳遞了一個空指標引數(或結構、類成員變數?)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/75924.html
標籤:網絡及通訊開發
上一篇:關于query提交默認值的問題
下一篇:圖片縮放如何保持不失真
