进入tcpdump.c(函数入口)之前,先看一些头文件
netdissect.h里定义了一个数据结构struct netdissect_options来描述tcdpump支持的所有参数动作,每一个参数有对应的flag, 在tcpdump 的main 里面, 会根据用户的传入的参数来增加相应flag数值, 最后根据这些flag数值来实现特定动作。各个参数含义请参考源代码注释。
1.netdissect.h 头文件
struct netdissect_options {
int ndo_bflag; /* 以 ASDOT 表示法打印 4 字节 AS 号 */
int ndo_eflag; /* 打印以太网头 */
int ndo_fflag; /* 不翻译“外部”IP 地址 */
int ndo_Kflag; /* 不检查 IP、TCP 或 UDP 校验和 */
int ndo_nflag; /* 将地址显示为数字形式 */
int ndo_Nflag; /* 打印主机名时去掉域名 */
int ndo_qflag; /* 简短输出 */
int ndo_Sflag; /* 打印原始 TCP 序列号 */
int ndo_tflag; /* 打印数据包到达时间 */
int ndo_uflag; /* 打印未解码的 NFS 句柄 */
int ndo_vflag; /* 冗余级别 */
int ndo_xflag; /* 以十六进制打印数据包 */
int ndo_Xflag; /* 以十六进制/ASCII 打印数据包 */
int ndo_Aflag; /* 仅以 ASCII 打印数据包,并将 TAB、LF、CR 和 SPACE 视为图形字符 */
int ndo_Hflag; /* 解析 802.11s 草案网状标准 */
const char *ndo_protocol; /* 协议 */
jmp_buf ndo_early_end; /* 用于 setjmp()/longjmp() 的 jmp_buf */
void *ndo_last_mem_p; /* 指向最后分配的内存块的指针 */
int ndo_packet_number; /* 在行首打印数据包编号 */
int ndo_print_sampling; /* 打印每 N 个数据包 */
int ndo_suppress_default_print; /* 对未知的数据包类型不使用 default_print() */
int ndo_tstamp_precision; /* 请求的时间戳精度 */
const char *program_name; /* 使用该库的程序名称 */
char *ndo_espsecret; /* ESP 密钥 */
struct sa_list *ndo_sa_list_head; /* 由 print-esp.c 使用 */
struct sa_list *ndo_sa_default;
char *ndo_sigsecret; /* 签名验证密钥 */
int ndo_packettype; /* 由 -T 指定的数据包类型 */
int ndo_snaplen; /* 抓取长度 */
int ndo_ll_hdr_len; /* 链路层头长度 */
/* 全局指针,指向当前数据包的开始和结束(在打印过程中) */
const u_char *ndo_packetp;
const u_char *ndo_snapend;
/* 保存的数据包边界和缓冲区信息的堆栈 */
struct netdissect_saved_packet_info *ndo_packet_info_stack;
/* 指向 if_printer 函数的指针 */
if_printer ndo_if_printer;
/* 指向输出内容的 void 函数的指针 */
void (*ndo_default_print)(netdissect_options *,
const u_char *bp, u_int length);
/* 指向执行常规输出的函数的指针 */
int (*ndo_printf)(netdissect_options *,
const char *fmt, ...)
PRINTFLIKE_FUNCPTR(2, 3);
/* 指向输出错误的函数的指针 */
void NORETURN_FUNCPTR (*ndo_error)(netdissect_options *,
status_exit_codes_t status,
const char *fmt, ...)