网卡抓包

1.安装npcap程序与sdk

2.抓包并打印长度

  1. 创建项目
  2. 在项目中包含头文件与库文件
  3. 编写代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79


#include <stdio.h>
#include <stdlib.h>
#include "pcap.h"

#pragma comment(lib,"wpcap.lib")
#pragma comment(lib,"packet.lib")

// 回调函数,处理捕获到的每个数据包
void packet_handler(u_char* param, const struct pcap_pkthdr* header, const u_char* pkt_data) {
printf("Packet captured! Length: %d\n", header->len);
// 这里可以添加更多的数据包处理逻辑
}

int main() {
pcap_if_t* alldevs;
pcap_if_t* d;
int inum;
int i = 0;
pcap_t* adhandle;
char errbuf[PCAP_ERRBUF_SIZE];

// 获取设备列表
if (pcap_findalldevs(&alldevs, errbuf) == -1) {
fprintf(stderr, "Error in pcap_findalldevs: %s\n", errbuf);
return 1;
}

// 打印设备列表
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 Npcap is installed.\n");
return 1;
}

printf("Enter the interface number (1-%d): ", i);
char buffer[100];
fgets(buffer, sizeof(buffer), stdin);
inum = atoi(buffer);

// 检查用户输入的接口编号是否有效
if (inum < 1 || inum > i) {
printf("Invalid interface number.\n");
pcap_freealldevs(alldevs);
return 1;
}

// 跳转到选定的设备
for (d = alldevs, i = 0; i < inum - 1; d = d->next, i++);

// 打开设备
if ((adhandle = pcap_open_live(d->name, 65536, 1, 1000, errbuf)) == NULL) {
fprintf(stderr, "\nUnable to open the adapter. %s is not supported by Npcap\n", d->name);
pcap_freealldevs(alldevs);
return 1;
}

printf("\nListening on %s...\n", d->description);

// 释放设备列表
pcap_freealldevs(alldevs);

// 开始捕获数据包
pcap_loop(adhandle, 0, packet_handler, NULL);

// 关闭捕获会话
pcap_close(adhandle);

return 0;
}

  1. 编译并运行选择网卡开始抓包。

3.打印16进制数据到日志文件中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include <pcap.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#pragma comment(lib,"wpcap.lib")
#pragma comment(lib,"packet.lib")

#define LOG_FILE "traffic.log"
#define HEX_PER_LINE 16

void packet_handler(u_char* param, const struct pcap_pkthdr* header, const u_char* pkt_data) {
FILE* logfile = fopen(LOG_FILE, "a");
if (logfile == NULL) {
printf("Unable to open log file.\n");
return;
}

// Get the timestamp
char timestamp[64];
time_t local_tv_sec = header->ts.tv_sec;
struct tm ltime;
localtime_s(&ltime, &local_tv_sec);
strftime(timestamp, sizeof timestamp, "%Y-%m-%d %H:%M:%S", &ltime);

fprintf(logfile, "Timestamp: %s.%.6ld\n", timestamp, header->ts.tv_usec);
fprintf(logfile, "Packet length: %d bytes\n", header->len);

// Print the packet data in hex
for (u_int i = 0; i < header->len; i++) {
fprintf(logfile, "%02X ", pkt_data[i]);
if ((i + 1) % HEX_PER_LINE == 0)
fprintf(logfile, "\n");
}
fprintf(logfile, "\n\n");

fclose(logfile);
}

int main() {
pcap_if_t* alldevs;
pcap_if_t* d;
pcap_t* adhandle;
char errbuf[PCAP_ERRBUF_SIZE];
int i = 0, inum;
char filter_exp[] = ""; // Empty filter to capture all traffic
struct bpf_program fp;

// Retrieve the device list from the local machine
if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1) {
fprintf(stderr, "Error in pcap_findalldevs_ex: %s\n", errbuf);
// Additional debugging information
fprintf(stderr, "Check if Npcap is installed and running properly.\n");
exit(1);
}


// Print the list of devices
printf("Available network interfaces:\n");
for (d = alldevs; d != NULL; 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) {
fprintf(stderr, "No interfaces found! Make sure Npcap is installed.\n");
exit(1);
}

printf("Enter the interface number (1-%d): ", i);
scanf_s("%d", &inum);
if (inum < 1 || inum > i) {
fprintf(stderr, "Interface number out of range.\n");
pcap_freealldevs(alldevs);
exit(1);
}

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

// Open the device
if ((adhandle = pcap_open(d->name, // Device name
65536, // Snap length
PCAP_OPENFLAG_PROMISCUOUS, // Promiscuous mode
1000, // Read timeout
NULL, // Authentication on remote machines
errbuf // Error buffer
)) == NULL) {
fprintf(stderr, "Unable to open adapter %s: %s\n", d->name, errbuf);
pcap_freealldevs(alldevs);
exit(1);
}

printf("\nListening on %s...\n", d->description ? d->description : d->name);

// Compile and set the filter
if (pcap_compile(adhandle, &fp, filter_exp, 1, PCAP_NETMASK_UNKNOWN) == -1) {
fprintf(stderr, "Error compiling filter: %s\n", pcap_geterr(adhandle));
pcap_freealldevs(alldevs);
exit(1);
}
if (pcap_setfilter(adhandle, &fp) == -1) {
fprintf(stderr, "Error setting filter: %s\n", pcap_geterr(adhandle));
pcap_freealldevs(alldevs);
exit(1);
}

// Start the capture
pcap_loop(adhandle, 0, packet_handler, NULL);

// Cleanup
pcap_freealldevs(alldevs);
pcap_close(adhandle);
return 0;
}

  • 运行后会将抓取的包输出到相同目录下的traffic.log文件中。

4. 打印16进制前解析并打印地址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
// Include necessary headers
#define _CRT_SECURE_NO_WARNINGS
#include <pcap.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <stdint.h> // Include this header for uint32_t

#pragma comment(lib, "wpcap.lib")
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "Packet.lib")

#define LOG_FILE "traffic.log"
#define HEX_PER_LINE 16

// Ethernet header
#pragma pack(push, 1)
struct ether_header {
u_char ether_dhost[6]; // Destination host address
u_char ether_shost[6]; // Source host address
u_short ether_type; // EtherType field
};
#pragma pack(pop)

// IP header
#pragma pack(push, 1)
struct ip_header {
#if BYTE_ORDER == LITTLE_ENDIAN
u_char ihl : 4;
u_char version : 4;
#elif BYTE_ORDER == BIG_ENDIAN
u_char version : 4;
u_char ihl : 4;
#endif
u_char tos;
u_short tot_len;
u_short id;
u_short frag_off;
u_char ttl;
u_char protocol;
u_short checksum;
uint32_t saddr; // Changed to uint32_t
uint32_t daddr; // Changed to uint32_t
};
#pragma pack(pop)

void packet_handler(u_char* param, const struct pcap_pkthdr* header, const u_char* pkt_data) {
FILE* logfile = fopen(LOG_FILE, "a");
if (logfile == NULL) {
printf("Unable to open log file.\n");
return;
}

// Get the timestamp
char timestamp[64];
time_t local_tv_sec = header->ts.tv_sec;
struct tm ltime;
localtime_s(&ltime, &local_tv_sec);
strftime(timestamp, sizeof(timestamp), "%Y-%m-%d %H:%M:%S", &ltime);

fprintf(logfile, "Timestamp: %s.%.6ld\n", timestamp, header->ts.tv_usec);
fprintf(logfile, "Packet length: %d bytes\n", header->len);

// Parse Ethernet header
struct ether_header* eth_header = (struct ether_header*)pkt_data;

// Check for IPv4 packets (EtherType == 0x0800)
if (ntohs(eth_header->ether_type) == 0x0800) {
// Parse IP header
const struct ip_header* ip_header = (struct ip_header*)(pkt_data + sizeof(struct ether_header));

// Convert addresses to hexadecimal format
char src_ip_hex[9], dst_ip_hex[9];
snprintf(src_ip_hex, sizeof(src_ip_hex), "%08X", ntohl(ip_header->saddr));
snprintf(dst_ip_hex, sizeof(dst_ip_hex), "%08X", ntohl(ip_header->daddr));

fprintf(logfile, "Source IP: %s\n", src_ip_hex);
fprintf(logfile, "Destination IP: %s\n", dst_ip_hex);

// Optional: Parse TCP or UDP headers for port numbers
if (ip_header->protocol == IPPROTO_TCP) {
fprintf(logfile, "Protocol: TCP\n");
// Parse TCP header here if needed
}
else if (ip_header->protocol == IPPROTO_UDP) {
fprintf(logfile, "Protocol: UDP\n");
// Parse UDP header here if needed
}
else {
fprintf(logfile, "Protocol: %d\n", ip_header->protocol);
}
}
else {
fprintf(logfile, "Non-IPv4 packet. EtherType: 0x%04X\n", ntohs(eth_header->ether_type));
}

// Print the packet data in hex
for (u_int i = 0; i < header->len; i++) {
fprintf(logfile, "%02X ", pkt_data[i]);
if ((i + 1) % HEX_PER_LINE == 0)
fprintf(logfile, "\n");
}
fprintf(logfile, "\n\n");

fclose(logfile);
}

int main() {
pcap_if_t* alldevs;
pcap_if_t* d;
pcap_t* adhandle;
char errbuf[PCAP_ERRBUF_SIZE];
int i = 0, inum;
char filter_exp[] = ""; // Empty filter to capture all traffic
struct bpf_program fp;
bpf_u_int32 netmask = 0xffffff; // Default netmask

// Initialize WinSock
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
fprintf(stderr, "WSAStartup failed.\n");
return 1;
}

// Retrieve the device list from the local machine
if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1) {
fprintf(stderr, "Error in pcap_findalldevs_ex: %s\n", errbuf);
printf("Make sure Npcap is installed and run the program as Administrator.\n");
return 1;
}

// Print the list of devices
printf("Available network interfaces:\n");
for (d = alldevs; d != NULL; 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) {
fprintf(stderr, "No interfaces found! Make sure Npcap is installed.\n");
return 1;
}

printf("Enter the interface number (1-%d): ", i);
scanf("%d", &inum);
if (inum < 1 || inum > i) {
fprintf(stderr, "Interface number out of range.\n");
pcap_freealldevs(alldevs);
return 1;
}

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

// Open the device
if ((adhandle = pcap_open(d->name, // Device name
65536, // Snap length
PCAP_OPENFLAG_PROMISCUOUS, // Promiscuous mode
1000, // Read timeout
NULL, // Authentication on remote machines
errbuf // Error buffer
)) == NULL) {
fprintf(stderr, "Unable to open adapter %s: %s\n", d->name, errbuf);
pcap_freealldevs(alldevs);
return 1;
}

printf("\nListening on %s...\n", d->description ? d->description : d->name);

// Compile and set the filter
if (pcap_compile(adhandle, &fp, filter_exp, 1, netmask) == -1) {
fprintf(stderr, "Error compiling filter: %s\n", pcap_geterr(adhandle));
pcap_freealldevs(alldevs);
return 1;
}
if (pcap_setfilter(adhandle, &fp) == -1) {
fprintf(stderr, "Error setting filter: %s\n", pcap_geterr(adhandle));
pcap_freealldevs(alldevs);
return 1;
}

// Start the capture
pcap_loop(adhandle, 0, packet_handler, NULL);

// Cleanup
pcap_freealldevs(alldevs);
pcap_close(adhandle);
WSACleanup();
return 0;
}

5. 支持ipv6

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
// Include necessary headers
#define _CRT_SECURE_NO_WARNINGS
#include <pcap.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <stdint.h> // Include this header for uint32_t and uint8_t
#include <winsock2.h>

#pragma comment(lib, "wpcap.lib")
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "Packet.lib")

#define LOG_FILE "traffic.log"
#define HEX_PER_LINE 16

// Ethernet header
#pragma pack(push, 1)
struct ether_header {
u_char ether_dhost[6]; // Destination host address
u_char ether_shost[6]; // Source host address
u_short ether_type; // EtherType field
};
#pragma pack(pop)

// IPv4 header
#pragma pack(push, 1)
struct ipv4_header {
#if BYTE_ORDER == LITTLE_ENDIAN
u_char ihl : 4;
u_char version : 4;
#elif BYTE_ORDER == BIG_ENDIAN
u_char version : 4;
u_char ihl : 4;
#endif
u_char tos;
u_short tot_len;
u_short id;
u_short frag_off;
u_char ttl;
u_char protocol;
u_short checksum;
uint32_t saddr;
uint32_t daddr;
};
#pragma pack(pop)

// IPv6 header
#pragma pack(push, 1)
struct ipv6_header {
uint32_t version_tc_flow; // 4 bits version, 8 bits traffic class, 20 bits flow label
uint16_t payload_length;
uint8_t next_header;
uint8_t hop_limit;
uint8_t saddr[16]; // Source address
uint8_t daddr[16]; // Destination address
};
#pragma pack(pop)

void packet_handler(u_char* param, const struct pcap_pkthdr* header, const u_char* pkt_data) {
FILE* logfile = fopen(LOG_FILE, "a");
if (logfile == NULL) {
printf("Unable to open log file.\n");
return;
}

// Get the timestamp
char timestamp[64];
time_t local_tv_sec = header->ts.tv_sec;
struct tm ltime;
localtime_s(&ltime, &local_tv_sec);
strftime(timestamp, sizeof(timestamp), "%Y-%m-%d %H:%M:%S", &ltime);

fprintf(logfile, "Timestamp: %s.%.6ld\n", timestamp, header->ts.tv_usec);
fprintf(logfile, "Packet length: %d bytes\n", header->len);

// Parse Ethernet header
struct ether_header* eth_header = (struct ether_header*)pkt_data;

// Determine EtherType
uint16_t ether_type = ntohs(eth_header->ether_type);

if (ether_type == 0x0800) {
// IPv4 packet
const struct ipv4_header* ip_header = (struct ipv4_header*)(pkt_data + sizeof(struct ether_header));

// Convert addresses to hexadecimal format
char src_ip_hex[9], dst_ip_hex[9];
snprintf(src_ip_hex, sizeof(src_ip_hex), "%08X", ntohl(ip_header->saddr));
snprintf(dst_ip_hex, sizeof(dst_ip_hex), "%08X", ntohl(ip_header->daddr));

fprintf(logfile, "Protocol: IPv4\n");
fprintf(logfile, "Source IP: %s\n", src_ip_hex);
fprintf(logfile, "Destination IP: %s\n", dst_ip_hex);

// Optional: Parse transport layer protocols here

}
else if (ether_type == 0x86DD) {
// IPv6 packet
const struct ipv6_header* ip6_header = (struct ipv6_header*)(pkt_data + sizeof(struct ether_header));

// Convert IPv6 addresses to hexadecimal strings
char src_ip_hex[33], dst_ip_hex[33];
for (int i = 0; i < 16; i++) {
sprintf(&src_ip_hex[i * 2], "%02X", ip6_header->saddr[i]);
sprintf(&dst_ip_hex[i * 2], "%02X", ip6_header->daddr[i]);
}
src_ip_hex[32] = '\0';
dst_ip_hex[32] = '\0';

fprintf(logfile, "Protocol: IPv6\n");
fprintf(logfile, "Source IP: %s\n", src_ip_hex);
fprintf(logfile, "Destination IP: %s\n", dst_ip_hex);

// Optional: Parse next header (transport layer) if needed

}
else {
fprintf(logfile, "Non-IP packet. EtherType: 0x%04X\n", ether_type);
}

// Print the packet data in hex
for (u_int i = 0; i < header->len; i++) {
fprintf(logfile, "%02X ", pkt_data[i]);
if ((i + 1) % HEX_PER_LINE == 0)
fprintf(logfile, "\n");
}
fprintf(logfile, "\n\n");

fclose(logfile);
}

int main() {
pcap_if_t* alldevs;
pcap_if_t* d;
pcap_t* adhandle;
char errbuf[PCAP_ERRBUF_SIZE];
int i = 0, inum;
char filter_exp[] = ""; // Empty filter to capture all traffic
struct bpf_program fp;
bpf_u_int32 netmask = 0xffffff; // Default netmask

// Initialize WinSock
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
fprintf(stderr, "WSAStartup failed.\n");
return 1;
}

// Retrieve the device list from the local machine
if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1) {
fprintf(stderr, "Error in pcap_findalldevs_ex: %s\n", errbuf);
printf("Make sure Npcap is installed and run the program as Administrator.\n");
return 1;
}

// Print the list of devices
printf("Available network interfaces:\n");
for (d = alldevs; d != NULL; 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) {
fprintf(stderr, "No interfaces found! Make sure Npcap is installed.\n");
return 1;
}

printf("Enter the interface number (1-%d): ", i);
scanf("%d", &inum);
if (inum < 1 || inum > i) {
fprintf(stderr, "Interface number out of range.\n");
pcap_freealldevs(alldevs);
return 1;
}

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

// Open the device
if ((adhandle = pcap_open(d->name, // Device name
65536, // Snap length
PCAP_OPENFLAG_PROMISCUOUS, // Promiscuous mode
1000, // Read timeout
NULL, // Authentication on remote machines
errbuf // Error buffer
)) == NULL) {
fprintf(stderr, "Unable to open adapter %s: %s\n", d->name, errbuf);
pcap_freealldevs(alldevs);
return 1;
}

printf("\nListening on %s...\n", d->description ? d->description : d->name);

// Compile and set the filter
if (pcap_compile(adhandle, &fp, filter_exp, 1, netmask) == -1) {
fprintf(stderr, "Error compiling filter: %s\n", pcap_geterr(adhandle));
pcap_freealldevs(alldevs);
return 1;
}
if (pcap_setfilter(adhandle, &fp) == -1) {
fprintf(stderr, "Error setting filter: %s\n", pcap_geterr(adhandle));
pcap_freealldevs(alldevs);
return 1;
}

// Start the capture
pcap_loop(adhandle, 0, packet_handler, NULL);

// Cleanup
pcap_freealldevs(alldevs);
pcap_close(adhandle);
WSACleanup();
return 0;
}

6. 显示端口 并使用点分十进制显示地址

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
// Include necessary headers
#define _CRT_SECURE_NO_WARNINGS
#include <pcap.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <stdint.h> // For integer types
#include <winsock2.h>
#include <ws2tcpip.h> // For inet_ntop and IP constants

#pragma comment(lib, "wpcap.lib")
#pragma comment(lib, "ws2_32.lib")
#pragma comment(lib, "Packet.lib")

#define LOG_FILE "traffic.log"
#define HEX_PER_LINE 16

// Ethernet header
#pragma pack(push, 1)
struct ether_header {
u_char ether_dhost[6]; // Destination host address
u_char ether_shost[6]; // Source host address
u_short ether_type; // EtherType field
};
#pragma pack(pop)

// IPv4 header
#pragma pack(push, 1)
struct ipv4_header {
#if BYTE_ORDER == LITTLE_ENDIAN
u_char ihl : 4;
u_char version : 4;
#elif BYTE_ORDER == BIG_ENDIAN
u_char version : 4;
u_char ihl : 4;
#endif
u_char tos;
u_short tot_len;
u_short id;
u_short frag_off;
u_char ttl;
u_char protocol;
u_short checksum;
uint32_t saddr;
uint32_t daddr;
};
#pragma pack(pop)

// IPv6 header
#pragma pack(push, 1)
struct ipv6_header {
uint32_t version_tc_flow; // Version, Traffic Class, Flow Label
uint16_t payload_length;
uint8_t next_header;
uint8_t hop_limit;
uint8_t saddr[16]; // Source address
uint8_t daddr[16]; // Destination address
};
#pragma pack(pop)

// TCP header
#pragma pack(push, 1)
struct tcp_header {
u_short src_port;
u_short dst_port;
uint32_t seq_number;
uint32_t ack_number;
#if BYTE_ORDER == LITTLE_ENDIAN
u_char reserved : 4;
u_char data_offset : 4;
#elif BYTE_ORDER == BIG_ENDIAN
u_char data_offset : 4;
u_char reserved : 4;
#endif
u_char flags;
u_short window;
u_short checksum;
u_short urgent_pointer;
};
#pragma pack(pop)

// UDP header
#pragma pack(push, 1)
struct udp_header {
u_short src_port;
u_short dst_port;
u_short length;
u_short checksum;
};
#pragma pack(pop)

void packet_handler(u_char* param, const struct pcap_pkthdr* header, const u_char* pkt_data) {
FILE* logfile = fopen(LOG_FILE, "a");
if (logfile == NULL) {
printf("Unable to open log file.\n");
return;
}

// Get the timestamp
char timestamp[64];
time_t local_tv_sec = header->ts.tv_sec;
struct tm ltime;
localtime_s(&ltime, &local_tv_sec);
strftime(timestamp, sizeof(timestamp), "%Y-%m-%d %H:%M:%S", &ltime);

fprintf(logfile, "Timestamp: %s.%.6ld\n", timestamp, header->ts.tv_usec);
fprintf(logfile, "Packet length: %d bytes\n", header->len);

// Parse Ethernet header
struct ether_header* eth_header = (struct ether_header*)pkt_data;

// Determine EtherType
uint16_t ether_type = ntohs(eth_header->ether_type);

if (ether_type == 0x0800) {
// IPv4 packet
const struct ipv4_header* ip_header = (struct ipv4_header*)(pkt_data + sizeof(struct ether_header));
char src_ip_str[INET_ADDRSTRLEN];
char dst_ip_str[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &(ip_header->saddr), src_ip_str, INET_ADDRSTRLEN);
inet_ntop(AF_INET, &(ip_header->daddr), dst_ip_str, INET_ADDRSTRLEN);

u_short src_port = 0;
u_short dst_port = 0;
const u_char* transport_header = pkt_data + sizeof(struct ether_header) + ip_header->ihl * 4;

if (ip_header->protocol == IPPROTO_TCP) {
const struct tcp_header* tcp_header = (struct tcp_header*)transport_header;
src_port = ntohs(tcp_header->src_port);
dst_port = ntohs(tcp_header->dst_port);
fprintf(logfile, "Protocol: TCP\n");
}
else if (ip_header->protocol == IPPROTO_UDP) {
const struct udp_header* udp_header = (struct udp_header*)transport_header;
src_port = ntohs(udp_header->src_port);
dst_port = ntohs(udp_header->dst_port);
fprintf(logfile, "Protocol: UDP\n");
}
else {
fprintf(logfile, "Protocol: Other (%d)\n", ip_header->protocol);
}

fprintf(logfile, "Source IP: %s:%d\n", src_ip_str, src_port);
fprintf(logfile, "Destination IP: %s:%d\n", dst_ip_str, dst_port);

}
else if (ether_type == 0x86DD) {
// IPv6 packet
const struct ipv6_header* ip6_header = (struct ipv6_header*)(pkt_data + sizeof(struct ether_header));
char src_ip_str[INET6_ADDRSTRLEN];
char dst_ip_str[INET6_ADDRSTRLEN];
inet_ntop(AF_INET6, ip6_header->saddr, src_ip_str, INET6_ADDRSTRLEN);
inet_ntop(AF_INET6, ip6_header->daddr, dst_ip_str, INET6_ADDRSTRLEN);

u_short src_port = 0;
u_short dst_port = 0;
const u_char* transport_header = pkt_data + sizeof(struct ether_header) + sizeof(struct ipv6_header);

if (ip6_header->next_header == IPPROTO_TCP) {
const struct tcp_header* tcp_header = (struct tcp_header*)transport_header;
src_port = ntohs(tcp_header->src_port);
dst_port = ntohs(tcp_header->dst_port);
fprintf(logfile, "Protocol: TCP\n");
}
else if (ip6_header->next_header == IPPROTO_UDP) {
const struct udp_header* udp_header = (struct udp_header*)transport_header;
src_port = ntohs(udp_header->src_port);
dst_port = ntohs(udp_header->dst_port);
fprintf(logfile, "Protocol: UDP\n");
}
else {
fprintf(logfile, "Protocol: Other (%d)\n", ip6_header->next_header);
}

fprintf(logfile, "Source IP: %s:%d\n", src_ip_str, src_port);
fprintf(logfile, "Destination IP: %s:%d\n", dst_ip_str, dst_port);

}
else {
fprintf(logfile, "Non-IP packet. EtherType: 0x%04X\n", ether_type);
}

// Print the packet data in hex
for (u_int i = 0; i < header->len; i++) {
fprintf(logfile, "%02X ", pkt_data[i]);
if ((i + 1) % HEX_PER_LINE == 0)
fprintf(logfile, "\n");
}
fprintf(logfile, "\n\n");

fclose(logfile);
}

int main() {
pcap_if_t* alldevs;
pcap_if_t* d;
pcap_t* adhandle;
char errbuf[PCAP_ERRBUF_SIZE];
int i = 0, inum;
char filter_exp[] = ""; // Empty filter to capture all traffic
struct bpf_program fp;
bpf_u_int32 netmask = 0xffffff; // Default netmask

// Initialize WinSock
WSADATA wsaData;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
fprintf(stderr, "WSAStartup failed.\n");
return 1;
}

// Retrieve the device list from the local machine
if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING, NULL, &alldevs, errbuf) == -1) {
fprintf(stderr, "Error in pcap_findalldevs_ex: %s\n", errbuf);
printf("Make sure Npcap is installed and run the program as Administrator.\n");
return 1;
}

// Print the list of devices
printf("Available network interfaces:\n");
for (d = alldevs; d != NULL; 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) {
fprintf(stderr, "No interfaces found! Make sure Npcap is installed.\n");
return 1;
}

printf("Enter the interface number (1-%d): ", i);
scanf("%d", &inum);
if (inum < 1 || inum > i) {
fprintf(stderr, "Interface number out of range.\n");
pcap_freealldevs(alldevs);
return 1;
}

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

// Open the device
if ((adhandle = pcap_open(d->name, // Device name
65536, // Snap length
PCAP_OPENFLAG_PROMISCUOUS, // Promiscuous mode
1000, // Read timeout
NULL, // Authentication on remote machines
errbuf // Error buffer
)) == NULL) {
fprintf(stderr, "Unable to open adapter %s: %s\n", d->name, errbuf);
pcap_freealldevs(alldevs);
return 1;
}

printf("\nListening on %s...\n", d->description ? d->description : d->name);

// Compile and set the filter
if (pcap_compile(adhandle, &fp, filter_exp, 1, netmask) == -1) {
fprintf(stderr, "Error compiling filter: %s\n", pcap_geterr(adhandle));
pcap_freealldevs(alldevs);
return 1;
}
if (pcap_setfilter(adhandle, &fp) == -1) {
fprintf(stderr, "Error setting filter: %s\n", pcap_geterr(adhandle));
pcap_freealldevs(alldevs);
return 1;
}

// Start the capture
pcap_loop(adhandle, 0, packet_handler, NULL);

// Cleanup
pcap_freealldevs(alldevs);
pcap_close(adhandle);
WSACleanup();
return 0;
}