calculate tcp_payload offset and size

前言

看到wireshark在分析包时, 会出现tcp_payload占用的字节数,不到包结尾的情况。
去看了一下wireshark代码,还没单步跟完,自己想明白了。
calculate tcp_payload offset and size_第1张图片
calculate tcp_payload offset and size_第2张图片
calculate tcp_payload offset and size_第3张图片

用libpcap捕获包, 进入包解析回掉后, 每个包有捕获长度.
如果要取tcp_payload, 步骤如下:
网卡头是固定长度的,去掉.
IP头中total_length声明的长度 = IP头长度 + TCP头长度 + tcp_payload长度
IP头中total_length长度有可能比包捕获长度小, total_length长度之外的padding字节都是0,写了一个独立demo, 统计了一下,padding字节数量比较固定,长度2,6. 没做大量统计。
经过统计,带padding都是小包(e.g. tcp重传请求). 真正带tcp_payload的包都没有padding(在真机上随便统计的, 不确认这一点)

IP头长度由4 * (p_ip_hdr->ver_ihl & 0x0F)决定
TCP头长度由((p_tcp_hdr->data_offset >> 4) & 0x0f) * 4决定
抛掉IP头,TCP头, IP头.total_length中剩下的长度,就是tcp_payload的长度。

实验工程下载点

win10.1803 + vs2017
抓实际网卡的包,显示包,保存包,如果抓到10个带padding的包就停止。
然后可以人工用wireshark打开保存的pcap文件和程序显示结果进行比对。
src_calculate_tcp_payload_offset_and_size.7z

实验预览

// dy_load_wpcap_dll.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "wpcap_dll_ex.h"

// please declare _CRT_SECURE_NO_WARNING on project

#ifndef MYLOG_I
#define MYLOG_I printf
#endif // #ifndef MYLOG_I

#ifndef LINE_80
#define LINE_80 "--------------------------------------------------------------------------------"
#endif // #ifndef LINE_80

#include 

typedef uint32_t addr_t;
typedef uint16_t port_t;

// @ref https://stackoverflow.com/questions/16519846/parse-ip-and-tcp-header-especially-common-tcp-header-optionsof-packets-capture
#pragma pack(push, 1)
typedef struct {
	u_char  dst_addr[6];
	u_char  src_addr[6];
	u_short type;
} TAG_ETHER_HEADER;

typedef struct {
	uint8_t  ver_ihl;  // 4 bits version and 4 bits internet header length
	uint8_t  tos;
	uint16_t total_length;
	uint16_t id;
	uint16_t flags_fo; // 3 bits flags and 13 bits fragment-offset
	uint8_t  ttl;
	uint8_t  protocol;
	uint16_t checksum;
	addr_t   src_addr;
	addr_t   dst_addr;
} TAG_IP_HEADER;

typedef struct {
	uint16_t src_port;
	uint16_t dst_port;
	uint32_t seq;
	uint32_t ack;
	uint8_t  data_offset;  // high 4 bits * 4 is tcp-payload
	uint8_t  flags;
	uint16_t window_size;
	uint16_t checksum;
	uint16_t urgent_p;
} TAG_TCP_HEADER;

/*
TAG_TCP_HEADER.flags
Flags: 0x011 (FIN, ACK)
000. .... .... = Reserved: Not set
...0 .... .... = Nonce: Not set
.... 0... .... = Congestion Window Reduced (CWR): Not set
.... .0.. .... = ECN-Echo: Not set
.... ..0. .... = Urgent: Not set
.... ...1 .... = Acknowledgment: Set
.... .... 0... = Push: Not set
.... .... .0.. = Reset: Not set
.... .... ..0. = Syn: Not set
.... .... ...1 = Fin: Set
[TCP Flags: ·······A···F]
*/

#define FLAG_BIT_TCP_FIN 0x01
#define FLAG_BIT_TCP_SYN 0x02
#define FLAG_BIT_TCP_ACK 0x10

typedef struct {
	uint8_t kind;
	uint8_t size;
} TAG_TCP_OPTION;

typedef struct {
	port_t   src_port;
	port_t   dst_port;
	uint16_t length;
	uint16_t checksum;
} TAG_UDP_HEADER;
#pragma pack(pop)

#define PCAP_FILE_DUMP_TO "c:\\test\\abc.pcap"
#define MY_CAPTRUE_FILTER "tcp"
const long int gc_l_max_padding_packet_recv_then_quit = 10; // 最多收到几个有padding的包, 就退出程序

pcap_t* adhandle = NULL;
pcap_dumper_t* dumpfile = NULL;

struct bpf_program my_bpf_program;
bool b_valid_bpf = false;

void packet_handler(u_char *dumpfile, const struct pcap_pkthdr *header, const u_char *pkt_data);
void print_packet(const char* psz_tip, const char* pdata, int iLen);
char get_hex_char_to_disp(u_char c);
bool is_char_can_print(char c);

BOOL WINAPI phandler_routine(DWORD CtrlType)
{
	BOOL rc = FALSE;
	switch (CtrlType) {
	case CTRL_C_EVENT:
		{
			if (NULL != adhandle) {
				pcap_breakloop(adhandle);
			}
		}
		rc = TRUE;
		break;
	default:
		break;
	}

	return rc;
}

int _tmain(int argc, _TCHAR* argv[])
{
	bool rc = false;
	pcap_if_t *alldevs = NULL;
	pcap_if_t *d = NULL;
	int inum = 0;
	int i = 0;
	char errbuf[PCAP_ERRBUF_SIZE] = {'\0'};

	do {
		if (!fn_dy_load_wpcap()) {
			break;
		}

		if (!SetConsoleCtrlHandler(phandler_routine, TRUE)) {
			break;
		}

		/* Retrieve the device list on the local machine */
		if (pcap_findalldevs(&alldevs, errbuf) == -1)
		{
			fprintf(stderr, "Error in pcap_findalldevs: %s\n", errbuf);
			exit(1);
		}

		// npcap已经不能在win10.1803.17134.191上正常工作了, alldevs此时为NULL
		// 为了做抓包实验, 必须将npcap0.9卸掉. 将以前winpcap装的usbpcap卸掉
		// 然后, 重新装WinPcap_4_1_3.exe, 抓包才好使

		/* Print the list */
		for (d = alldevs; d; d = d->next)
		{
			printf("%d. %s", ++i, d->name);
			if (d->description)
				printf(" (%s)\n", 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_s("%d", &inum);

		if (inum < 1 || inum > i)
		{
			printf("\nInterface number out of range.\n");
			/* Free the device list */
			pcap_freealldevs(alldevs);
			return -1;
		}

		/* Jump to the selected adapter */
		for (d = alldevs, i = 0; i< inum - 1; d = d->next, i++);

		// 走这里了
		// argv[2] is netcard name
		adhandle = pcap_create(d->name, errbuf);
		if (NULL == adhandle) {
			printf("5. watch\n");
			return -1;
		}

		pcap_set_promisc(adhandle, 1); // interface_opts->promisc_mode is 1
		pcap_set_timeout(adhandle, -1); // timeout is 250

		pcap_set_buffer_size(adhandle, 10 * 1024 * 1024);

		int err = 0;
		err = pcap_activate(adhandle);
		if (0 != err) {
			printf("7. watch\n");
			return -1;
		}

		int	old_datalink = pcap_datalink(adhandle);
		printf("old_datalink = %d\n", old_datalink);

		if (0 != old_datalink) {
			err = pcap_set_datalink(adhandle, 0);
			if (0 != err) {
				printf("8. watch, err continue\n");
				// return -1;
			}
		}

		// capture_loop_init_filter

		int snaplen = pcap_snapshot(adhandle);
		printf("snaplen = %d\n", snaplen);

		/* Open the device */
		//if ( (adhandle= pcap_open(d->name,			// name of the device
		//						  65536,			// portion of the packet to capture
		//											// 65536 guarantees that the whole packet will be captured on all the link layers
		//						  PCAP_OPENFLAG_PROMISCUOUS, 	// promiscuous mode
		//						  1000,				// read timeout
		//						  NULL,				// authentication on the remote machine
		//						  errbuf			// error buffer
		//						  ) ) == NULL)
		//{
		//	fprintf(stderr,"\nUnable to open the adapter. %s is not supported by WinPcap\n", d->name);
		//	/* Free the device list */
		//	pcap_freealldevs(alldevs);
		//	return -1;
		//}

		/* Open the dump file */
		dumpfile = pcap_dump_open(adhandle, PCAP_FILE_DUMP_TO);

		if (dumpfile == NULL)
		{
			fprintf(stderr, "\nError opening output file\n");
			return -1;
		}

		printf("\nlistening on %s... Press Ctrl+C to stop...\n", d->description);

		/* At this point, we no longer need the device list. Free it */
		pcap_freealldevs(alldevs);

		// compile BPF
		if (pcap_compile(adhandle, &my_bpf_program, MY_CAPTRUE_FILTER, 1, 0) == -1) {
			fprintf(stderr, "error\n");
			break;
		}

		b_valid_bpf = true;

		// set BPF filter
		if (pcap_setfilter(adhandle, &my_bpf_program) == -1) {
			fprintf(stderr, "error\n");
			break;
		}

		/* start the capture */
		pcap_loop(adhandle, 0, packet_handler, (unsigned char *)dumpfile);

		printf("task over\n");
		rc = true;
	} while (0);

	if (!rc) {
		printf("error happen\n");
	}

	if (NULL != dumpfile) {
		pcap_dump_close(dumpfile);
		dumpfile = NULL;
	}

	if (b_valid_bpf) {
		b_valid_bpf = false;
		pcap_freecode(&my_bpf_program);
	}

	if (NULL != adhandle) {
		pcap_close(adhandle);
		adhandle = NULL;
	}

	system("pause");
	return 0;
}

/* Callback function invoked by libpcap for every incoming packet */
void packet_handler(u_char *dumpfile, const struct pcap_pkthdr *header, const u_char *pkt_data)
{
	/* save the packet on the dump file */
	// 假设抓的都是tcp的包数据

	static int cnt = 0; // 收到的包计数
	static long int l_padding_packet_recv = 0; // 收到带padding的tcp包

	const u_char* pc_data_left = NULL; // 没处理的数据
	int len_data_left = 0; // 没处理的数据长度
	int len_padding_bytes = 0; // tcp-payload 之后的 padding字节数量

	TAG_ETHER_HEADER* p_ether_hdr = NULL;
	TAG_IP_HEADER* p_ip_hdr = NULL;
	TAG_TCP_HEADER* p_tcp_hdr = NULL;
	int ip_header_size = 0;
	bool is_process_ok = false;

	// ip. total_length	10240	unsigned short
	// ip头 + tcp头 + tcp-payload 的总长度
	unsigned short uw_tcp_ip_data_length_by_ip_header = 0; // ip头中声明的当前包-数据总长度

	// 说明tcp-option部分可能长度为0~40
	unsigned char uc_tcp_header_length = 0; // tcp头的长度, 由TAG_TCP_HEADER.data_offset高4位 * 4决定, 最终值为20~60

	printf(">>%s\n", LINE_80);
	do {
		cnt++;
		printf("recv cnt = %d\n", cnt);
		// print_packet("recv", (const char*)pkt_data, header->caplen);
		pcap_dump(dumpfile, header, pkt_data); // 要保存一份抓包文件,用于比对分析结果

		if ((NULL == dumpfile) || (NULL == header) || (NULL == pkt_data)) {
			printf("error\n");
			break;
		}

		len_data_left = header->caplen; // 最开始能确定的包数据总长度为包捕获长度
		pc_data_left = pkt_data;

		// remove ether header from data in
		if (len_data_left < (int)sizeof(TAG_ETHER_HEADER)) {
			printf("error\n");
			break;
		}

		p_ether_hdr = (TAG_ETHER_HEADER*)pc_data_left;
		pc_data_left += sizeof(TAG_ETHER_HEADER);
		len_data_left -= sizeof(TAG_ETHER_HEADER);

		// remove ip header from data in
		if (len_data_left < (int)sizeof(TAG_IP_HEADER)) {
			printf("error\n");
			break;
		}

		p_ip_hdr = (TAG_IP_HEADER*)pc_data_left;
		uw_tcp_ip_data_length_by_ip_header = ntohs(p_ip_hdr->total_length);
		ip_header_size = 4 * (p_ip_hdr->ver_ihl & 0x0F);

		if (len_data_left < (int)uw_tcp_ip_data_length_by_ip_header) {
			printf("error\n");
			break;
		} else if (len_data_left > (int)uw_tcp_ip_data_length_by_ip_header) {
			len_padding_bytes = len_data_left - (int)uw_tcp_ip_data_length_by_ip_header;
			printf("find packet have padding %dbytes\n", len_padding_bytes);
		} else {
			printf("this packet not padding bytes\n");
		}

		// 已经扒掉了网卡头, 现在, 剩下的数据长度就是ip头中指定的ip_hdr + tcp_hdr + tcp_payload的总长度
		len_data_left = uw_tcp_ip_data_length_by_ip_header;

		pc_data_left += ip_header_size;
		len_data_left -= ip_header_size;

		// remove tcp header from data in
		if (len_data_left < (int)sizeof(TAG_TCP_HEADER)) {
			printf("error\n");
			break;
		}

		p_tcp_hdr = (TAG_TCP_HEADER*)pc_data_left;
		uc_tcp_header_length = ((p_tcp_hdr->data_offset >> 4) & 0x0f) * 4;

		if (len_data_left < (int)uc_tcp_header_length) {
			printf("error\n");
			break;
		}

		pc_data_left += uc_tcp_header_length;
		len_data_left -= uc_tcp_header_length;

		// 如果发现有padding字节,显示一下
		if (len_padding_bytes > 0) {
			// 只有发现有padding字节时, 才打印tcp-payload的内容
			print_packet("tcp payload", (const char*)pc_data_left, len_data_left);

			pc_data_left += len_data_left;
			len_data_left = 0;
			print_packet("find padding", (const char*)pc_data_left, len_padding_bytes);
			l_padding_packet_recv++;

			if ((l_padding_packet_recv >= gc_l_max_padding_packet_recv_then_quit) && (NULL != adhandle)) {
				pcap_breakloop(adhandle);
			}
		}

		if ( ((p_tcp_hdr->flags & FLAG_BIT_TCP_SYN) > 0)
			&& ((p_tcp_hdr->flags & FLAG_BIT_TCP_ACK) > 0))
		{
			printf("find tcp hand shark package\n");
		} else if (((p_tcp_hdr->flags & FLAG_BIT_TCP_FIN) > 0)
			&& ((p_tcp_hdr->flags & FLAG_BIT_TCP_ACK) > 0))
		{
			printf("find tcp goodbye package\n");
		}

		is_process_ok = true;
	} while (0);

	if (!is_process_ok) {
		if (NULL != adhandle) {
			pcap_breakloop(adhandle);
		}
	}

	printf("<<%s\n", LINE_80);
}

void print_packet(const char* psz_tip, const char* pdata, int iLen)
{
	char szBuf[260] = { '\0' };
	const int iOneRowChars = 16;
	const unsigned char* pCur = NULL;
	int iPos = 0;

	do {
		if (NULL == pdata) {
			break;
		}

		MYLOG_I("%s : %d(bytes)\n", ((NULL != psz_tip) && ((int)strlen(psz_tip) > 0)) ? psz_tip : "print_packet", iLen);

		do {
			pCur = (unsigned char*)(pdata + iPos);
			if (iLen >= iOneRowChars) {
				sprintf_s(szBuf, sizeof(szBuf), "%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X  |  %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c",
					*(pCur + 0),
					*(pCur + 1),
					*(pCur + 2),
					*(pCur + 3),
					*(pCur + 4),
					*(pCur + 5),
					*(pCur + 6),
					*(pCur + 7),
					*(pCur + 8),
					*(pCur + 9),
					*(pCur + 10),
					*(pCur + 11),
					*(pCur + 12),
					*(pCur + 13),
					*(pCur + 14),
					*(pCur + 15),
					get_hex_char_to_disp(*(pCur + 0)),
					get_hex_char_to_disp(*(pCur + 1)),
					get_hex_char_to_disp(*(pCur + 2)),
					get_hex_char_to_disp(*(pCur + 3)),
					get_hex_char_to_disp(*(pCur + 4)),
					get_hex_char_to_disp(*(pCur + 5)),
					get_hex_char_to_disp(*(pCur + 6)),
					get_hex_char_to_disp(*(pCur + 7)),
					get_hex_char_to_disp(*(pCur + 8)),
					get_hex_char_to_disp(*(pCur + 9)),
					get_hex_char_to_disp(*(pCur + 10)),
					get_hex_char_to_disp(*(pCur + 11)),
					get_hex_char_to_disp(*(pCur + 12)),
					get_hex_char_to_disp(*(pCur + 13)),
					get_hex_char_to_disp(*(pCur + 14)),
					get_hex_char_to_disp(*(pCur + 15)));

				MYLOG_I("%s\n", szBuf);
				iPos += iOneRowChars;
				iLen -= iOneRowChars;
			}
			else {
				switch (iLen) {
				case 15: {
					sprintf_s(szBuf, sizeof(szBuf), "%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X     |  %c%c%c%c%c%c%c%c%c%c%c%c%c%c%c ",
						*(pCur + 0),
						*(pCur + 1),
						*(pCur + 2),
						*(pCur + 3),
						*(pCur + 4),
						*(pCur + 5),
						*(pCur + 6),
						*(pCur + 7),
						*(pCur + 8),
						*(pCur + 9),
						*(pCur + 10),
						*(pCur + 11),
						*(pCur + 12),
						*(pCur + 13),
						*(pCur + 14),
						get_hex_char_to_disp(*(pCur + 0)),
						get_hex_char_to_disp(*(pCur + 1)),
						get_hex_char_to_disp(*(pCur + 2)),
						get_hex_char_to_disp(*(pCur + 3)),
						get_hex_char_to_disp(*(pCur + 4)),
						get_hex_char_to_disp(*(pCur + 5)),
						get_hex_char_to_disp(*(pCur + 6)),
						get_hex_char_to_disp(*(pCur + 7)),
						get_hex_char_to_disp(*(pCur + 8)),
						get_hex_char_to_disp(*(pCur + 9)),
						get_hex_char_to_disp(*(pCur + 10)),
						get_hex_char_to_disp(*(pCur + 11)),
						get_hex_char_to_disp(*(pCur + 12)),
						get_hex_char_to_disp(*(pCur + 13)),
						get_hex_char_to_disp(*(pCur + 14)));

					MYLOG_I("%s\n", szBuf);
				}
						 break;
				case 14: {
					sprintf_s(szBuf, sizeof(szBuf), "%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X        |  %c%c%c%c%c%c%c%c%c%c%c%c%c%c  ",
						*(pCur + 0),
						*(pCur + 1),
						*(pCur + 2),
						*(pCur + 3),
						*(pCur + 4),
						*(pCur + 5),
						*(pCur + 6),
						*(pCur + 7),
						*(pCur + 8),
						*(pCur + 9),
						*(pCur + 10),
						*(pCur + 11),
						*(pCur + 12),
						*(pCur + 13),
						get_hex_char_to_disp(*(pCur + 0)),
						get_hex_char_to_disp(*(pCur + 1)),
						get_hex_char_to_disp(*(pCur + 2)),
						get_hex_char_to_disp(*(pCur + 3)),
						get_hex_char_to_disp(*(pCur + 4)),
						get_hex_char_to_disp(*(pCur + 5)),
						get_hex_char_to_disp(*(pCur + 6)),
						get_hex_char_to_disp(*(pCur + 7)),
						get_hex_char_to_disp(*(pCur + 8)),
						get_hex_char_to_disp(*(pCur + 9)),
						get_hex_char_to_disp(*(pCur + 10)),
						get_hex_char_to_disp(*(pCur + 11)),
						get_hex_char_to_disp(*(pCur + 12)),
						get_hex_char_to_disp(*(pCur + 13)));

					MYLOG_I("%s\n", szBuf);
				}
						 break;
				case 13: {
					sprintf_s(szBuf, sizeof(szBuf), "%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X           |  %c%c%c%c%c%c%c%c%c%c%c%c%c   ",
						*(pCur + 0),
						*(pCur + 1),
						*(pCur + 2),
						*(pCur + 3),
						*(pCur + 4),
						*(pCur + 5),
						*(pCur + 6),
						*(pCur + 7),
						*(pCur + 8),
						*(pCur + 9),
						*(pCur + 10),
						*(pCur + 11),
						*(pCur + 12),
						get_hex_char_to_disp(*(pCur + 0)),
						get_hex_char_to_disp(*(pCur + 1)),
						get_hex_char_to_disp(*(pCur + 2)),
						get_hex_char_to_disp(*(pCur + 3)),
						get_hex_char_to_disp(*(pCur + 4)),
						get_hex_char_to_disp(*(pCur + 5)),
						get_hex_char_to_disp(*(pCur + 6)),
						get_hex_char_to_disp(*(pCur + 7)),
						get_hex_char_to_disp(*(pCur + 8)),
						get_hex_char_to_disp(*(pCur + 9)),
						get_hex_char_to_disp(*(pCur + 10)),
						get_hex_char_to_disp(*(pCur + 11)),
						get_hex_char_to_disp(*(pCur + 12)));

					MYLOG_I("%s\n", szBuf);
				}
						 break;
				case 12: {
					sprintf_s(szBuf, sizeof(szBuf), "%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X              |  %c%c%c%c%c%c%c%c%c%c%c%c    ",
						*(pCur + 0),
						*(pCur + 1),
						*(pCur + 2),
						*(pCur + 3),
						*(pCur + 4),
						*(pCur + 5),
						*(pCur + 6),
						*(pCur + 7),
						*(pCur + 8),
						*(pCur + 9),
						*(pCur + 10),
						*(pCur + 11),
						get_hex_char_to_disp(*(pCur + 0)),
						get_hex_char_to_disp(*(pCur + 1)),
						get_hex_char_to_disp(*(pCur + 2)),
						get_hex_char_to_disp(*(pCur + 3)),
						get_hex_char_to_disp(*(pCur + 4)),
						get_hex_char_to_disp(*(pCur + 5)),
						get_hex_char_to_disp(*(pCur + 6)),
						get_hex_char_to_disp(*(pCur + 7)),
						get_hex_char_to_disp(*(pCur + 8)),
						get_hex_char_to_disp(*(pCur + 9)),
						get_hex_char_to_disp(*(pCur + 10)),
						get_hex_char_to_disp(*(pCur + 11)));

					MYLOG_I("%s\n", szBuf);
				}
						 break;
				case 11: {
					sprintf_s(szBuf, sizeof(szBuf), "%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X                 |  %c%c%c%c%c%c%c%c%c%c%c     ",
						*(pCur + 0),
						*(pCur + 1),
						*(pCur + 2),
						*(pCur + 3),
						*(pCur + 4),
						*(pCur + 5),
						*(pCur + 6),
						*(pCur + 7),
						*(pCur + 8),
						*(pCur + 9),
						*(pCur + 10),
						get_hex_char_to_disp(*(pCur + 0)),
						get_hex_char_to_disp(*(pCur + 1)),
						get_hex_char_to_disp(*(pCur + 2)),
						get_hex_char_to_disp(*(pCur + 3)),
						get_hex_char_to_disp(*(pCur + 4)),
						get_hex_char_to_disp(*(pCur + 5)),
						get_hex_char_to_disp(*(pCur + 6)),
						get_hex_char_to_disp(*(pCur + 7)),
						get_hex_char_to_disp(*(pCur + 8)),
						get_hex_char_to_disp(*(pCur + 9)),
						get_hex_char_to_disp(*(pCur + 10)));

					MYLOG_I("%s\n", szBuf);
				}
						 break;
				case 10: {
					sprintf_s(szBuf, sizeof(szBuf), "%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X                    |  %c%c%c%c%c%c%c%c%c%c      ",
						*(pCur + 0),
						*(pCur + 1),
						*(pCur + 2),
						*(pCur + 3),
						*(pCur + 4),
						*(pCur + 5),
						*(pCur + 6),
						*(pCur + 7),
						*(pCur + 8),
						*(pCur + 9),
						get_hex_char_to_disp(*(pCur + 0)),
						get_hex_char_to_disp(*(pCur + 1)),
						get_hex_char_to_disp(*(pCur + 2)),
						get_hex_char_to_disp(*(pCur + 3)),
						get_hex_char_to_disp(*(pCur + 4)),
						get_hex_char_to_disp(*(pCur + 5)),
						get_hex_char_to_disp(*(pCur + 6)),
						get_hex_char_to_disp(*(pCur + 7)),
						get_hex_char_to_disp(*(pCur + 8)),
						get_hex_char_to_disp(*(pCur + 9)));

					MYLOG_I("%s\n", szBuf);
				}
						 break;
				case 9: {
					sprintf_s(szBuf, sizeof(szBuf), "%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X                       |  %c%c%c%c%c%c%c%c%c       ",
						*(pCur + 0),
						*(pCur + 1),
						*(pCur + 2),
						*(pCur + 3),
						*(pCur + 4),
						*(pCur + 5),
						*(pCur + 6),
						*(pCur + 7),
						*(pCur + 8),
						get_hex_char_to_disp(*(pCur + 0)),
						get_hex_char_to_disp(*(pCur + 1)),
						get_hex_char_to_disp(*(pCur + 2)),
						get_hex_char_to_disp(*(pCur + 3)),
						get_hex_char_to_disp(*(pCur + 4)),
						get_hex_char_to_disp(*(pCur + 5)),
						get_hex_char_to_disp(*(pCur + 6)),
						get_hex_char_to_disp(*(pCur + 7)),
						get_hex_char_to_disp(*(pCur + 8)));

					MYLOG_I("%s\n", szBuf);
				}
						break;
				case 8: {
					sprintf_s(szBuf, sizeof(szBuf), "%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X                          |  %c%c%c%c%c%c%c%c        ",
						*(pCur + 0),
						*(pCur + 1),
						*(pCur + 2),
						*(pCur + 3),
						*(pCur + 4),
						*(pCur + 5),
						*(pCur + 6),
						*(pCur + 7),
						get_hex_char_to_disp(*(pCur + 0)),
						get_hex_char_to_disp(*(pCur + 1)),
						get_hex_char_to_disp(*(pCur + 2)),
						get_hex_char_to_disp(*(pCur + 3)),
						get_hex_char_to_disp(*(pCur + 4)),
						get_hex_char_to_disp(*(pCur + 5)),
						get_hex_char_to_disp(*(pCur + 6)),
						get_hex_char_to_disp(*(pCur + 7)));

					MYLOG_I("%s\n", szBuf);
				}
						break;
				case 7: {
					sprintf_s(szBuf, sizeof(szBuf), "%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X %2.2X                             |  %c%c%c%c%c%c%c         ",
						*(pCur + 0),
						*(pCur + 1),
						*(pCur + 2),
						*(pCur + 3),
						*(pCur + 4),
						*(pCur + 5),
						*(pCur + 6),
						get_hex_char_to_disp(*(pCur + 0)),
						get_hex_char_to_disp(*(pCur + 1)),
						get_hex_char_to_disp(*(pCur + 2)),
						get_hex_char_to_disp(*(pCur + 3)),
						get_hex_char_to_disp(*(pCur + 4)),
						get_hex_char_to_disp(*(pCur + 5)),
						get_hex_char_to_disp(*(pCur + 6)));

					MYLOG_I("%s\n", szBuf);
				}
						break;
				case 6: {
					sprintf_s(szBuf, sizeof(szBuf), "%2.2X %2.2X %2.2X %2.2X %2.2X %2.2X                                |  %c%c%c%c%c%c          ",
						*(pCur + 0),
						*(pCur + 1),
						*(pCur + 2),
						*(pCur + 3),
						*(pCur + 4),
						*(pCur + 5),
						get_hex_char_to_disp(*(pCur + 0)),
						get_hex_char_to_disp(*(pCur + 1)),
						get_hex_char_to_disp(*(pCur + 2)),
						get_hex_char_to_disp(*(pCur + 3)),
						get_hex_char_to_disp(*(pCur + 4)),
						get_hex_char_to_disp(*(pCur + 5)));

					MYLOG_I("%s\n", szBuf);
				}
						break;
				case 5: {
					sprintf_s(szBuf, sizeof(szBuf), "%2.2X %2.2X %2.2X %2.2X %2.2X                                   |  %c%c%c%c%c           ",
						*(pCur + 0),
						*(pCur + 1),
						*(pCur + 2),
						*(pCur + 3),
						*(pCur + 4),
						get_hex_char_to_disp(*(pCur + 0)),
						get_hex_char_to_disp(*(pCur + 1)),
						get_hex_char_to_disp(*(pCur + 2)),
						get_hex_char_to_disp(*(pCur + 3)),
						get_hex_char_to_disp(*(pCur + 4)));

					MYLOG_I("%s\n", szBuf);
				}
						break;
				case 4: {
					sprintf_s(szBuf, sizeof(szBuf), "%2.2X %2.2X %2.2X %2.2X                                      |  %c%c%c%c            ",
						*(pCur + 0),
						*(pCur + 1),
						*(pCur + 2),
						*(pCur + 3),
						get_hex_char_to_disp(*(pCur + 0)),
						get_hex_char_to_disp(*(pCur + 1)),
						get_hex_char_to_disp(*(pCur + 2)),
						get_hex_char_to_disp(*(pCur + 3)));

					MYLOG_I("%s\n", szBuf);
				}
						break;
				case 3: {
					sprintf_s(szBuf, sizeof(szBuf), "%2.2X %2.2X %2.2X                                         |  %c%c%c             ",
						*(pCur + 0),
						*(pCur + 1),
						*(pCur + 2),
						get_hex_char_to_disp(*(pCur + 0)),
						get_hex_char_to_disp(*(pCur + 1)),
						get_hex_char_to_disp(*(pCur + 2)));

					MYLOG_I("%s\n", szBuf);
				}
						break;
				case 2: {
					sprintf_s(szBuf, sizeof(szBuf), "%2.2X %2.2X                                            |  %c%c              ",
						*(pCur + 0),
						*(pCur + 1),
						get_hex_char_to_disp(*(pCur + 0)),
						get_hex_char_to_disp(*(pCur + 1)));

					MYLOG_I("%s\n", szBuf);
				}
						break;
				case 1: {
					sprintf_s(szBuf, sizeof(szBuf), "%2.2X                                               |  %c               ",
						*(pCur + 0),
						get_hex_char_to_disp(*(pCur + 0)));

					MYLOG_I("%s\n", szBuf);
				}
						break;
				default:
					break;
				}
				iPos += iLen;
				iLen -= iLen;
			}
		} while (iLen > 0);
	} while (0);
}

bool is_char_can_print(char c)
{
	return ((c >= 32) && (c < 127));
}

char get_hex_char_to_disp(u_char c)
{
	char c_rc = '.';

	if (is_char_can_print((char)c)) {
		c_rc = (char)c;
	}

	return c_rc;
}

运行结果

 1. \Device\NPF_{3F23803F-6625-480F-A3F0-64DC12977FCD} (VMware Virtual Ethernet Adapter)
2. \Device\NPF_{56E02764-D399-48A4-AC72-5730D3BB27D3} (Realtek Ethernet Controller)
3. \Device\NPF_{101CA05F-3A63-46F7-8757-F5D04B31ABFA} (VMware Virtual Ethernet Adapter)
Enter the interface number (1-3):2
old_datalink = 1
8. watch, err continue
snaplen = 65535

listening on Realtek Ethernet Controller... Press Ctrl+C to stop...
>>--------------------------------------------------------------------------------
recv cnt = 1
this packet not padding bytes
<<--------------------------------------------------------------------------------
>>--------------------------------------------------------------------------------
recv cnt = 2
this packet not padding bytes
<<--------------------------------------------------------------------------------
>>--------------------------------------------------------------------------------
recv cnt = 3
this packet not padding bytes
find tcp hand shark package
<<--------------------------------------------------------------------------------
>>--------------------------------------------------------------------------------
recv cnt = 4
this packet not padding bytes
<<--------------------------------------------------------------------------------
>>--------------------------------------------------------------------------------
recv cnt = 5
this packet not padding bytes
find tcp goodbye package
<<--------------------------------------------------------------------------------
>>--------------------------------------------------------------------------------
recv cnt = 6
this packet not padding bytes
find tcp goodbye package
<<--------------------------------------------------------------------------------
>>--------------------------------------------------------------------------------
recv cnt = 7
this packet not padding bytes
find tcp goodbye package
<<--------------------------------------------------------------------------------
>>--------------------------------------------------------------------------------
recv cnt = 8
this packet not padding bytes
find tcp goodbye package
<<--------------------------------------------------------------------------------
>>--------------------------------------------------------------------------------
recv cnt = 9
this packet not padding bytes
<<--------------------------------------------------------------------------------
>>--------------------------------------------------------------------------------
recv cnt = 10
this packet not padding bytes
find tcp goodbye package
<<--------------------------------------------------------------------------------
>>--------------------------------------------------------------------------------
recv cnt = 11
find packet have padding 6bytes
tcp payload : 0(bytes)
find padding : 6(bytes)
00 00 00 00 00 00                                |  ......
find tcp goodbye package
<<--------------------------------------------------------------------------------
>>--------------------------------------------------------------------------------
recv cnt = 12
this packet not padding bytes
<<--------------------------------------------------------------------------------
>>--------------------------------------------------------------------------------
recv cnt = 13
this packet not padding bytes
<<--------------------------------------------------------------------------------
>>--------------------------------------------------------------------------------
recv cnt = 14
this packet not padding bytes
find tcp goodbye package
<<--------------------------------------------------------------------------------
>>--------------------------------------------------------------------------------
recv cnt = 15
this packet not padding bytes
<<--------------------------------------------------------------------------------
>>--------------------------------------------------------------------------------
recv cnt = 16
this packet not padding bytes
<<--------------------------------------------------------------------------------
>>--------------------------------------------------------------------------------
recv cnt = 17
this packet not padding bytes
<<--------------------------------------------------------------------------------
>>--------------------------------------------------------------------------------
recv cnt = 18
find packet have padding 6bytes
tcp payload : 0(bytes)
find padding : 6(bytes)
00 00 00 00 00 00                                |  ......
<<--------------------------------------------------------------------------------
>>--------------------------------------------------------------------------------
recv cnt = 19
this packet not padding bytes
<<--------------------------------------------------------------------------------
>>--------------------------------------------------------------------------------
recv cnt = 20
find packet have padding 2bytes
tcp payload : 0(bytes)
find padding : 2(bytes)
00 00                                            |  ..
find tcp hand shark package
<<--------------------------------------------------------------------------------
>>--------------------------------------------------------------------------------
recv cnt = 21
this packet not padding bytes
<<--------------------------------------------------------------------------------
>>--------------------------------------------------------------------------------
recv cnt = 22
this packet not padding bytes
<<--------------------------------------------------------------------------------
>>--------------------------------------------------------------------------------
recv cnt = 23
find packet have padding 6bytes
tcp payload : 0(bytes)
find padding : 6(bytes)
00 00 00 00 00 00                                |  ......
find tcp goodbye package
<<--------------------------------------------------------------------------------
>>--------------------------------------------------------------------------------
recv cnt = 24
this packet not padding bytes
<<--------------------------------------------------------------------------------
>>--------------------------------------------------------------------------------
recv cnt = 25
find packet have padding 2bytes
tcp payload : 0(bytes)
find padding : 2(bytes)
00 00                                            |  ..
find tcp hand shark package
<<--------------------------------------------------------------------------------
>>--------------------------------------------------------------------------------
recv cnt = 26
find packet have padding 6bytes
tcp payload : 0(bytes)
find padding : 6(bytes)
00 00 00 00 00 00                                |  ......
<<--------------------------------------------------------------------------------
>>--------------------------------------------------------------------------------
recv cnt = 27
this packet not padding bytes
<<--------------------------------------------------------------------------------
>>--------------------------------------------------------------------------------
recv cnt = 28
this packet not padding bytes
<<--------------------------------------------------------------------------------
>>--------------------------------------------------------------------------------
recv cnt = 29
this packet not padding bytes
<<--------------------------------------------------------------------------------
>>--------------------------------------------------------------------------------
recv cnt = 30
this packet not padding bytes
<<--------------------------------------------------------------------------------
>>--------------------------------------------------------------------------------
recv cnt = 31
find packet have padding 6bytes
tcp payload : 0(bytes)
find padding : 6(bytes)
00 00 00 00 00 00                                |  ......
<<--------------------------------------------------------------------------------
>>--------------------------------------------------------------------------------
recv cnt = 32
this packet not padding bytes
<<--------------------------------------------------------------------------------
>>--------------------------------------------------------------------------------
recv cnt = 33
find packet have padding 6bytes
tcp payload : 0(bytes)
find padding : 6(bytes)
00 00 00 00 00 00                                |  ......
find tcp goodbye package
<<--------------------------------------------------------------------------------
>>--------------------------------------------------------------------------------
recv cnt = 34
this packet not padding bytes
<<--------------------------------------------------------------------------------
>>--------------------------------------------------------------------------------
recv cnt = 35
this packet not padding bytes
find tcp goodbye package
<<--------------------------------------------------------------------------------
>>--------------------------------------------------------------------------------
recv cnt = 36
find packet have padding 6bytes
tcp payload : 0(bytes)
find padding : 6(bytes)
00 00 00 00 00 00                                |  ......
<<--------------------------------------------------------------------------------
>>--------------------------------------------------------------------------------
recv cnt = 37
this packet not padding bytes
<<--------------------------------------------------------------------------------
>>--------------------------------------------------------------------------------
recv cnt = 38
this packet not padding bytes
<<--------------------------------------------------------------------------------
>>--------------------------------------------------------------------------------
recv cnt = 39
this packet not padding bytes
<<--------------------------------------------------------------------------------
>>--------------------------------------------------------------------------------
recv cnt = 40
this packet not padding bytes
<<--------------------------------------------------------------------------------
>>--------------------------------------------------------------------------------
recv cnt = 41
this packet not padding bytes
<<--------------------------------------------------------------------------------
>>--------------------------------------------------------------------------------
recv cnt = 42
find packet have padding 6bytes
tcp payload : 0(bytes)
find padding : 6(bytes)
00 00 00 00 00 00                                |  ......
<<--------------------------------------------------------------------------------
task over
请按任意键继续. . .

2018-11-07

发现了p_ip_hdr->total_length中内容为0的包,这种包是下行包,而且因为包大,分成小包了。
如果这样,算包有效总长度的代码就要改下。

uw_tcp_ip_data_length_by_ip_header = ntohs(p_ip_hdr->total_length);
if (0 == uw_tcp_ip_data_length_by_ip_header) {
  uw_tcp_ip_data_length_by_ip_header = header->caplen - sizeof(TAG_ETHER_HEADER);
}

你可能感兴趣的:(抓包)