-
Notifications
You must be signed in to change notification settings - Fork 2
/
pcap-tools.c
102 lines (100 loc) · 2.51 KB
/
pcap-tools.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
101
102
#include <unistd.h>
#include <stdlib.h>
#include <err.h>
#include <pcap.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <assert.h>
pcap_t *
my_pcap_open_offline(const char *pcapfile)
{
char errbuf[PCAP_ERRBUF_SIZE + 1];
char fifoname[256];
int waitstatus;
const char *readfile = pcapfile;
fifoname[0] = '\0';
static unsigned int fifocount = 0;
pcap_t *in;
assert(pcapfile);
if (pcapfile[0] == '|') {
char **args = 0;
const char *s;
unsigned int nargs = 0;
unsigned int i = 0;
/* count arguments */
nargs++; /* first arg */
for (s = pcapfile; *s; s++) {
if (*s == ' ')
nargs++;
}
nargs++; /* terminating null */
args = calloc(nargs, sizeof(char *));
args[0] = strtok((char *) pcapfile + 1, " ");
for (i = 1; i < nargs - 1; i++) {
args[i] = strtok(NULL, " ");
assert(args[i]);
}
snprintf(fifoname, 256, "/tmp/fifo.%d.%u", getpid(), fifocount++);
mkfifo(fifoname, 0600);
if (0 == fork()) {
close(1);
open(fifoname, O_WRONLY);
execvp(args[0], args);
perror(args[0]);
abort();
}
readfile = fifoname;
} else if (0 == strcmp(pcapfile + strlen(pcapfile) - 3, ".gz")) {
snprintf(fifoname, 256, "/tmp/fifo.%d.%u", getpid(), fifocount++);
mkfifo(fifoname, 0600);
if (0 == fork()) {
close(1);
open(fifoname, O_WRONLY);
execlp("gzip", "gzip", "-dc", pcapfile, NULL);
perror("gzip");
abort();
}
readfile = fifoname;
} else if (0 == strcmp(pcapfile + strlen(pcapfile) - 4, ".bz2")) {
snprintf(fifoname, 256, "/tmp/fifo.%d.%u", getpid(), fifocount++);
mkfifo(fifoname, 0600);
if (0 == fork()) {
close(1);
open(fifoname, O_WRONLY);
execlp("bzip2", "bzip2", "-dc", pcapfile, NULL);
perror("bzip2");
abort();
}
readfile = fifoname;
} else if (0 == strcmp(pcapfile + strlen(pcapfile) - 3, ".xz")) {
snprintf(fifoname, 256, "/tmp/fifo.%d.%u", getpid(), fifocount++);
mkfifo(fifoname, 0600);
if (0 == fork()) {
close(1);
open(fifoname, O_WRONLY);
execlp("xz", "xz", "-dc", pcapfile, NULL);
perror("xz");
abort();
}
readfile = fifoname;
}
in = pcap_open_offline(readfile, errbuf);
if (fifoname[0])
unlink(fifoname);
if (NULL == in && fifoname[0]) {
waitpid(-1, &waitstatus, 0);
return 0;
}
if (NULL == in)
errx(1, "[%d] %s(%d) %s: %s", getpid(), __FILE__, __LINE__, pcapfile, errbuf);
return in;
}
void
my_pcap_close_offline(pcap_t * in)
{
int waitstatus;
pcap_close(in);
waitpid(-1, &waitstatus, 0);
}