-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathpcap.c
100 lines (84 loc) · 1.98 KB
/
pcap.c
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
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdbool.h>
#include <stdint.h>
#include <time.h>
#include <assert.h>
#include "pcap.h"
#define LINKTYPE_RAW 101
typedef struct {
uint32_t magic_number; /* magic number */
uint16_t version_major; /* major version number */
uint16_t version_minor; /* minor version number */
int32_t thiszone; /* GMT to local correction */
uint32_t sigfigs; /* accuracy of timestamps */
uint32_t snaplen; /* max length of captured packets, in octets */
uint32_t network; /* data link type */
} pcap_hdr;
typedef struct {
uint32_t ts_sec; /* timestamp seconds */
uint32_t ts_usec; /* timestamp microseconds */
uint32_t incl_len; /* number of octets of packet saved in file */
uint32_t orig_len; /* actual length of packet */
} pcaprec_hdr;
struct pcap_file {
FILE *f;
char buf[1024 * 16];
};
pcap_file *
pcap_open(const char *fn)
{
pcap_file *pcap = (pcap_file *) malloc(sizeof(*pcap));
if (!pcap)
return NULL;
FILE *f;
pcap->f = f = fopen(fn, "wb");
if (!f) {
free(pcap);
return NULL;
}
setvbuf(f, pcap->buf, _IOFBF, sizeof(pcap->buf));
pcap_hdr hdr;
hdr.magic_number = 0xa1b2c3d4;
hdr.version_major = 2;
hdr.version_minor = 4;
hdr.thiszone = 0;
hdr.sigfigs = 0;
hdr.snaplen = 65535;
hdr.network = LINKTYPE_RAW;
if (fwrite(&hdr, 1, sizeof(hdr), f) != sizeof(hdr)) {
fclose(f);
unlink(fn);
free(pcap);
return NULL;
}
return pcap;
}
void
pcap_close(pcap_file *pcap)
{
if (pcap) {
fclose(pcap->f);
free(pcap);
}
}
bool
pcap_write_ip(pcap_file *pcap,
const void *raw_ip, size_t len)
{
assert(pcap);
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
pcaprec_hdr hdr;
hdr.ts_sec = ts.tv_sec;
hdr.ts_usec = ts.tv_nsec / 1000;
hdr.incl_len = len;
hdr.orig_len = len;
if (fwrite(&hdr, 1, sizeof(hdr), pcap->f) != sizeof(hdr))
return false;
if (fwrite(raw_ip, 1, len, pcap->f) != len)
return false;
return true;
}