您的位置:首页 > 理论基础 > 计算机网络

TcpFlow 1.4.6( C++版本)源代码分析之main函数分析

2016-06-13 14:34 841 查看
最近公司项目拟定使用tcpflow来分析http协议

分析源代码后才能更好的利用源代码进行二次开发

代码下载地址:https://github.com/simsong/tcpflow

1.从main函数开始分析

第一步:process_infile函数处理-r 和 -R参数的pcap文件解析

//打开pcap离线文件,根据pcap文件格式进行解析
pd = pcap_open_offline(file_path.c_str(), error);

//查找处理某一网络层的函数
handler = find_handler(dlt, infile.c_str());

如果infile值等于空则执行linux下pcap抓包分析的流程
pcap_lookupdev
pcap_open_live
find_handler
pcap_compile
pcap_setfilter
其中pcap_compile和pcap_setfilter是设置过滤器并安装到libpcap中

不管是在线抓包还是分析离线文件pcap格式文件,最终都会调用pcap_loop函数
解析struct pcap_pkthdr hdr; pcap数据包包头结构
/* Read the packet */
if(fread(p->pktbuf,hdr.caplen,1,p->fp)!=1) break; // no more to read
解析pcap文件的实际数据包

/* Process the packet */
(*callback)(user,&hdr,p->pktbuf);
使用callback指向的回调函数来处理数据包包头和真实数据部分


暂时先分析到这里,后续会图文并茂的完整分析下C++版的tcpflow

scanner_info *info;

结构体是在什么地方使用的。

scanner_info结构体中存储有一个packet_callback_t回调函数指针

packet_callback_t *packet_cb; // v2: (output) callback for processing network packets, or NULL

void *packet_user;

定位到load_scanner_packet_handlers,将回调函数的user和packet_cb回调函数指针加入到packet_handlers中

void be13::plugin::load_scanner_packet_handlers()

{

for(scanner_vector::const_iterator it = current_scanners.begin(); it!=current_scanners.end(); it++){

if((*it)->enabled){

const scanner_def *sd = (*it);

if(sd->info.packet_cb){

packet_handlers.push_back(packet_plugin_info(sd->info.packet_user,sd->info.packet_cb));

}

}

}

}

packet_handlers的类型其实就是一个vector数组

typedef std::vector packet_plugin_info_vector_t;

packet_plugin_info_vector_t packet_handlers; // pcap callback handlers

继续跟踪谁在使用packet_handlers变量

在Plugin.cpp源文件的process_packet函数中

void be13::plugin::process_packet(const be13::packet_info &pi)

{

for(packet_plugin_info_vector_t::iterator it = packet_handlers.begin(); it != packet_handlers.end(); it++){

(*(*it).callback)((*it).user,pi);

}

}

玩linux的时候经常会看到stdin stdout stderr 这3个可以称为终端(Terminal)的标准输入(standard input),标准输出( standard out)和标准错误输出(standard error)。

fprintf(stdout,”process_infile(): deal pcap offline file\r\n”);

离线文件处理流程

{ dl_ethernet, DLT_EN10MB },

{ dl_ethernet, DLT_IEEE802 },

进入dl_ethernet函数,进入be13::plugin::process_packet(pi);函数

在process_packet()函数中

for(packet_plugin_info_vector_t::iterator it = packet_handlers.begin(); it !=packet_handlers.end(); it++)

{

(*(*it).callback)((*it).user,pi);



加载并扫描packet_handlers

void be13::plugin::load_scanner_packet_handlers()

{

for(scanner_vector::const_iterator it = current_scanners.begin(); it!=current_scanners.end(); it++){

if((*it)->enabled){

const scanner_def *sd = (*it);

if(sd->info.packet_cb){

packet_handlers.push_back(packet_plugin_info(sd->info.packet_user,sd->info.packet_cb));

}

}

}

}

scan_tcpdemux 设置info结构体的packet_user和packet_cb

packet_cb = packet_handler

packet_handler调用process_pkt

处理ip数据包tcp数据包
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息