Linux 环境下tcpdump 源代码分析 韩大卫@吉林师范大学 tcpdump.c 是tcpdump 工具的main.c, 本文旨对tcpdump的框架有简单了解,只展示linux平台使用的一部分核心代码。 Tcpdump 的使用目的就是打印出指定条件的报文,即使有再多的正则表达式作为过滤条件。所以只要懂得tcpdump -nXXi eth0 的实现原理即可。 进入main之前,先看一些头文件 netdissect.h里定义了一个数据结构struct netdissect_options来描述tcdpump支持的所有参数动作,每一个参数有对应的flag, 在tcpdump 的main 里面, 会根据用户的传入的参数来增加相应flag数值, 最后根据这些flag数值来实现特定动作。各个参数含义请参考源代码注释。 struct netdissect_options { int ndo_aflag; /* translate network and broadcast addresses */ //打印出以太网头部 int ndo_eflag; /* print ethernet header */ int ndo_fflag; /* don't translate "foreign" IP address */ int ndo_Kflag; /* don't check TCP checksums */ //不将地址转换为名字 int ndo_nflag; /* leave addresses as numbers */ int ndo_Nflag; /* remove domains from printed host names */ int ndo_qflag; /* quick (shorter) output */ int ndo_Rflag; /* print sequence # field in AH/ESP*/ int ndo_sflag; /* use the libsmi to translate OIDs */ int ndo_Sflag; /* print raw TCP sequence numbers */ // 报文到达时间 int ndo_tflag; /* print packet arrival time */ int ndo_Uflag; /* "unbuffered" output of dump files */ int ndo_uflag; /* Print undecoded NFS handles */ //详细信息 int ndo_vflag; /* verbose */ // 十六进制打印报文 int ndo_xflag; /* print packet in hex */ // 十六进制和ASCII码打印报文 int ndo_Xflag; /* print packet in hex/ascii */ //以ASCII码显示打印报文 int ndo_Aflag; /* print packet only in ascii observing TAB, * LF, CR and SPACE as graphical chars */ ... //默认的打印函数 void (*ndo_default_print)(netdissect_options *, register const u_char *bp, register u_int length); void (*ndo_info)(netdissect_options *, int verbose); ... } interface.h 接口头文件,定义了一堆宏就为了方便调用struct netdissect_options里的成员。 #ifndef NETDISSECT_REWORKED extern netdissect_options *gndo; ... #define nflag gndo->ndo_nflag ... #define tflag gndo->ndo_tflag ... #define vflag gndo->ndo_vflag #define xflag gndo->ndo_xflag #define Xflag gndo->ndo_Xflag ... #endif tcpdump.c int main(int argc, char **argv) { register char *cp, *infile, *cmdbuf, *device, *RFileName, *WFileName; pcap_handler callback; int type; struct bpf_program fcode; struct print_info printinfo; ... //对netdissect_options中一些参数初始化 gndo->ndo_Oflag=1; gndo->ndo_Rflag=1; gndo->ndo_dlt=-1; gndo->ndo_default_print=ndo_default_print; gndo->ndo_printf=tcpdump_printf; gndo->ndo_error=ndo_error; gndo->ndo_warning=ndo_warning; gndo->ndo_snaplen = DEFAULT_SNAPLEN; ... opterr = 0; while ( /*经典的getopt框架。 字符数组为tcpdump 支持的全部参数。可以看到, 参数x, X,t这些参数后面没有:或::, 这说明这些参数会产生叠加的效果。 */ (op = getopt(argc, argv, "aA" B_FLAG "c:C:d" D_FLAG "eE:fF:G:i:" I_FLAG "KlLm:M:nNOpqr:Rs:StT:u" U_FLAG "vw:W:xXy:Yz:Z:")) != -1) switch (op) { ... //case 里面的处理大多相似,以下仅用-i,-X,-x<
linux环境下tcpdump源代码分析
最新推荐文章于 2025-01-16 21:11:32 发布