29 pcap = calloc(1,
sizeof(*pcap));
33 pcap->handle = phandle;
34 pcap->datalink = pcap_datalink(phandle);
36 pcap->reasm = reasm_ip_new();
37 if (pcap->reasm == NULL) {
42 reasm_ip_set_timeout(pcap->reasm, 60);
44 if (pcap_file(phandle) == NULL)
45 pcap->type = nmsg_pcap_type_live;
47 pcap->type = nmsg_pcap_type_file;
54 pcap_freecode(&(*pcap)->userbpf);
55 pcap_close((*pcap)->handle);
56 if ((*pcap)->user != NULL)
57 pcap_close((*pcap)->user);
59 reasm_ip_free((*pcap)->reasm);
61 free((*pcap)->new_pkt);
62 free((*pcap)->userbpft);
73 const u_char *pkt_data;
75 struct pcap_pkthdr *pkt_hdr;
77 assert(pcap->raw ==
false);
80 pcap_res = pcap_next_ex(pcap->handle, &pkt_hdr, &pkt_data);
84 _nmsg_dprintf(1,
"%s: pcap_next_ex() failed: %s\n", __func__,
85 pcap_geterr(pcap->handle));
92 ts->tv_sec = pkt_hdr->ts.tv_sec;
93 ts->tv_nsec = pkt_hdr->ts.tv_usec * 1000;
101 const uint8_t **pkt_data,
struct timespec *ts)
105 assert(pcap->raw ==
true);
108 pcap_res = pcap_next_ex(pcap->handle, pkt_hdr, (
const u_char **) pkt_data);
111 if (pcap_res == -1) {
112 _nmsg_dprintf(1,
"%s: pcap_next_ex() failed: %s\n", __func__,
113 pcap_geterr(pcap->handle));
120 ts->tv_sec = (*pkt_hdr)->ts.tv_sec;
121 ts->tv_nsec = (*pkt_hdr)->ts.tv_usec * 1000;
133 bool need_vlan =
false;
136 struct bpf_program bpf;
138 tmp = strdup(userbpft);
142 if (pcap->user == NULL) {
143 pcap->user = pcap_open_dead(DLT_RAW, 1500);
144 if (pcap->user == NULL)
149 free(pcap->userbpft);
150 pcap_freecode(&pcap->userbpf);
153 res = pcap_compile(pcap->user, &pcap->userbpf, (
char *) userbpft, 1, 0);
155 _nmsg_dprintf(1,
"%s: unable to compile bpf '%s': %s\n", __func__,
156 userbpft, pcap_geterr(pcap->handle));
159 pcap->userbpft = strdup(userbpft);
162 res = pcap_compile(pcap->handle, &bpf,
"vlan and ip", 1, 0);
167 _nmsg_dprintf(5,
"%s: need_vlan=%u\n", __func__, need_vlan);
171 res = nmsg_asprintf(&bpfstr,
"(%s) or (vlan and (%s))", tmp, tmp);
181 _nmsg_dprintf(3,
"%s: using bpf '%s'\n", __func__, bpfstr);
182 res = pcap_compile(pcap->handle, &bpf, bpfstr, 1, 0);
184 _nmsg_dprintf(1,
"%s: pcap_compile() failed: %s\n", __func__,
185 pcap_geterr(pcap->handle));
192 if (pcap_setfilter(pcap->handle, &bpf) != 0) {
193 _nmsg_dprintf(1,
"%s: pcap_setfilter() failed: %s\n", __func__,
194 pcap_geterr(pcap->handle));
208 static const char *bpf_ipv4_frags =
"(ip[6:2] & 0x3fff != 0)";
209 static const char *bpf_ip =
"(ip)";
210 static const char *bpf_ip6 =
"(ip6)";
212 bool need_ip6 =
true;
213 bool need_ipv4_frags =
true;
214 bool need_vlan =
false;
215 bool userbpf_ip_only =
true;
218 struct bpf_program bpf;
221 if (pcap->user == NULL) {
222 pcap->user = pcap_open_dead(DLT_RAW, 1500);
223 if (pcap->user == NULL)
228 free(pcap->userbpft);
229 pcap_freecode(&pcap->userbpf);
232 res = pcap_compile(pcap->user, &pcap->userbpf, (
char *) userbpft, 1, 0);
234 _nmsg_dprintf(1,
"%s: unable to compile bpf '%s': %s\n", __func__,
235 userbpft, pcap_geterr(pcap->handle));
238 pcap->userbpft = strdup(userbpft);
241 res = nmsg_asprintf(&tmp,
"(%s) and %s", userbpft, bpf_ip6);
244 res = pcap_compile(pcap->handle, &bpf, tmp, 1, 0);
251 _nmsg_dprintf(5,
"%s: need_ip6=%u\n", __func__, need_ip6);
254 res = nmsg_asprintf(&tmp,
"(%s) and %s", userbpft, bpf_ipv4_frags);
257 res = pcap_compile(pcap->handle, &bpf, tmp, 1, 0);
260 need_ipv4_frags =
false;
264 _nmsg_dprintf(5,
"%s: need_ipv4_frags=%u\n", __func__, need_ipv4_frags);
267 res = pcap_compile(pcap->handle, &bpf,
"vlan and ip", 1, 0);
272 _nmsg_dprintf(5,
"%s: need_vlan=%u\n", __func__, need_vlan);
275 res = nmsg_asprintf(&tmp,
"%s and (%s)", bpf_ip, userbpft);
278 res = pcap_compile(pcap->handle, &bpf, tmp, 1, 0);
281 userbpf_ip_only =
false;
285 _nmsg_dprintf(5,
"%s: userbpf_ip_only=%u\n", __func__, userbpf_ip_only);
288 res = nmsg_asprintf(&tmp,
"((%s%s(%s))%s%s%s%s)",
289 userbpf_ip_only ? bpf_ip :
"",
290 userbpf_ip_only ?
" and " :
"",
292 need_ipv4_frags ?
" or " :
"",
293 need_ipv4_frags ? bpf_ipv4_frags :
"",
294 need_ip6 ?
" or " :
"",
295 need_ip6 ? bpf_ip6 :
"");
300 res = nmsg_asprintf(&bpfstr,
"%s or (vlan and %s)", tmp, tmp);
310 _nmsg_dprintf(3,
"%s: using bpf '%s'\n", __func__, bpfstr);
311 res = pcap_compile(pcap->handle, &bpf, bpfstr, 1, 0);
313 _nmsg_dprintf(1,
"%s: pcap_compile() failed: %s\n", __func__,
314 pcap_geterr(pcap->handle));
321 if (pcap_setfilter(pcap->handle, &bpf) != 0) {
322 _nmsg_dprintf(1,
"%s: pcap_setfilter() failed: %s\n", __func__,
323 pcap_geterr(pcap->handle));
337 return (pcap_snapshot(pcap->handle));
347 return (pcap->datalink);
352 struct bpf_insn *fcode;
354 fcode = pcap->userbpf.bf_insns;
357 return (bpf_filter(fcode, (u_char *) pkt, len, len) != 0);
#define NMSG_IPSZ_MAX
Maximize size of an IP datagram.
nmsg_res nmsg_ipdg_parse_pcap(struct nmsg_ipdg *dg, nmsg_pcap_t pcap, struct pcap_pkthdr *pkt_hdr, const u_char *pkt)
Parse IP datagrams from the data link layer, performing reassembly if necessary.