Skip to content

Commit 54cb7d2

Browse files
committed
piglet wrapper
1 parent dfe5a07 commit 54cb7d2

File tree

6 files changed

+792
-0
lines changed

6 files changed

+792
-0
lines changed

piglet-bpf-filter/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
piglet-bpf-filter

piglet-bpf-filter/Makefile

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#!/usr/bin/env bash
2+
3+
piglet-bpf-filter: piglet-bpf-filter.cc daq_print.cc daq_print.h
4+
c++ -ggdb -std=c++14 -lstdc++ $^ -lpcap -ldaq -lpacket -o $@
5+
6+
clean:
7+
rm piglet-bpf-filter

piglet-bpf-filter/daq_print.cc

Lines changed: 228 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,228 @@
1+
// print_packet, coppied from many of my tools using libpacket
2+
// Victor Roemer, wtfbbqhax <[email protected]>
3+
4+
#include <cstdio>
5+
#include <cstdint>
6+
#include <ctype.h>
7+
#include <arpa/inet.h>
8+
#include <netdb.h>
9+
10+
#include <daq.h>
11+
#include <packet/packet.h>
12+
#include <packet/stats.h>
13+
#include <packet/dns.h>
14+
15+
#include "daq_print.h"
16+
17+
#define IS_SET(flags, bit) ((flags & bit) == bit)
18+
19+
// From https://github.com/the-tcpdump-group/tcpdump/blob/master/nameser.h#L312
20+
21+
/*
22+
* Macros for subfields of flag fields.
23+
*/
24+
#define DNS_QR(flags) ((flags) & 0x8000) /* response flag */
25+
#define DNS_OPCODE(flags) (((flags) >> 11) & 0xF) /* purpose of message */
26+
#define DNS_AA(flags) (flags & 0x0400) /* authoritative answer */
27+
#define DNS_TC(flags) (flags & 0x0200) /* truncated message */
28+
#define DNS_RD(flags) (flags & 0x0100) /* recursion desired */
29+
#define DNS_RA(flags) (flags & 0x0080) /* recursion available */
30+
#define DNS_AD(flags) (flags & 0x0020) /* authentic data from named */
31+
#define DNS_CD(flags) (flags & 0x0010) /* checking disabled by resolver */
32+
#define DNS_RCODE(flags) (flags & 0x000F) /* response code */
33+
34+
// Function to decode the DNS protocol
35+
int print_dns(dns const& dns)
36+
{
37+
bool is_response = DNS_QR(dns.h.flags);
38+
39+
if (is_response)
40+
{
41+
printf("[dns response] [rcode:%d, id:%d, qdcount: %d, ancount: %d, nscount: %d, arcount:%d]\n",
42+
DNS_RCODE(dns.h.flags),
43+
dns.h.id,
44+
dns.h.qdcount,
45+
dns.h.ancount,
46+
dns.h.nscount,
47+
dns.h.arcount);
48+
}
49+
else
50+
{
51+
printf("[dns query] [id:%d, qdcount: %d]\n",
52+
dns.h.id,
53+
dns.h.qdcount);
54+
}
55+
56+
// Parsing Question Section
57+
for (int i = 0; i < dns.h.qdcount; i++)
58+
{
59+
struct dns_query const& q = dns.questions[i];
60+
// FIXME: Formatting/printing the QNAME
61+
//struct dns_query *q = &dns.questions[i];
62+
// Display QNAME
63+
// Display QTYPE and QCLASS (assuming a structure in Packet to store this information)
64+
printf("[query] [label: %s, type: %d, class: %d]\n",
65+
q.label.c_str(),
66+
q.dns_qtype,
67+
q.dns_qclass);
68+
}
69+
70+
// Parsing Answers Section
71+
for (int i = 0; i < dns.h.ancount; i++)
72+
{
73+
char addr[INET6_ADDRSTRLEN];
74+
std::string human;
75+
76+
struct dns_answer const &a = dns.answers[i];
77+
if (a.dns_atype == 1)
78+
{
79+
inet_ntop(AF_INET, a.data.data(), addr, sizeof(addr));
80+
human.append(addr, strnlen(addr, INET6_ADDRSTRLEN));
81+
82+
}
83+
else
84+
{
85+
human = a.data;
86+
}
87+
printf("[answer] [data: %s, type: %d, class %d, ttl: %d]\n",
88+
human.c_str(),
89+
a.dns_atype,
90+
a.dns_aclass,
91+
a.dns_ttl);
92+
// // Display QNAME
93+
// // Display QTYPE and QCLASS (assuming a structure in Packet to store this information)
94+
// (void)dns[0].questions[i].dns_qtype;
95+
// (void)dns[0].questions[i].dns_qclass;
96+
}
97+
98+
return 0;
99+
}
100+
101+
// Taken from Pcapstats BSD License
102+
//
103+
void print_data(uint8_t const * data, int64_t length)
104+
{
105+
int i, x, j, c;
106+
int w = 0;
107+
108+
for( i=0; length>0; length -= 16 )
109+
{
110+
c = length >= 16 ? 16 : length;
111+
printf("%06X ", w);
112+
w+=16;
113+
114+
for( j=0; j<c; j++ )
115+
printf("%2.02X ", data[i+j]);
116+
117+
for( x = length; x<16; x++ )
118+
printf(" ");
119+
120+
for( j=0; j<c; j++ )
121+
printf("%c", (isprint(data[i+j]) ? data[i+j] : '.'));
122+
123+
printf("\n");
124+
i+=c;
125+
}
126+
}
127+
128+
129+
void
130+
print_packet(int const instance_id, DAQ_PktHdr_t const* hdr, uint8_t const * data, size_t const len)
131+
{
132+
Packet packet;
133+
134+
packet_clear(&packet);
135+
136+
int error = packet_decode(&packet, data, len);
137+
(void)error;
138+
139+
struct ipaddr src = packet_srcaddr(&packet);
140+
struct ipaddr dst = packet_dstaddr(&packet);
141+
struct ipaddr *a = &src;
142+
struct ipaddr *b = &dst;
143+
uint32_t sport = packet_srcport(&packet);
144+
uint32_t dport = packet_dstport(&packet);
145+
uint32_t proto = packet_protocol(&packet);
146+
147+
#ifdef PRINT_PACKET_LAYERS
148+
// Extra debug logging
149+
unsigned it;
150+
for (Protocol *_p = packet_proto_first(&packet, &it);
151+
_p; _p = packet_proto_next(&packet, &it))
152+
{
153+
printf("%s:", packet_proto_name(_p));
154+
}
155+
printf("\n");
156+
#endif
157+
158+
int version = packet_version(&packet);
159+
int af = AF_INET;
160+
if (version == 6) {
161+
af = AF_INET6;
162+
}
163+
164+
char addr[INET6_ADDRSTRLEN];
165+
printf("[src: %s, ", inet_ntop(af, a, addr, sizeof(addr)));
166+
printf("dst: %s, ", inet_ntop(af, b, addr, sizeof(addr)));
167+
printf("proto: %d, id: %d, sp: %d, dp: %d, dlen: %u] [instance: %d]\n",
168+
proto,
169+
packet_id(&packet),
170+
sport,
171+
dport,
172+
packet_paysize(&packet),
173+
instance_id);
174+
175+
if (packet_is_fragment(&packet))
176+
{
177+
printf(" |ip off: %u %s\n",
178+
packet_frag_offset(&packet),
179+
packet_frag_mf(&packet) ? "mf" : "");
180+
}
181+
182+
if (sport == 53 || dport == 53)
183+
{
184+
dns _dns;
185+
decode_dns(packet_payload(&packet),
186+
packet_paysize(&packet),
187+
&_dns);
188+
print_dns(_dns);
189+
}
190+
191+
uint32_t max = packet_paysize(&packet);
192+
const uint8_t *payload = packet_payload(&packet);
193+
max = max > 128 ? 128 : max;
194+
print_data(payload, max);
195+
196+
//print_data(data, len);
197+
198+
#ifdef PRINT_PACKET_STATS
199+
// Packet stats are useful for determining decoding errors
200+
struct packet_stats const * stats;
201+
packet_stats(&stats);
202+
203+
printf("ip4 headers: %u\n"
204+
"ip4 badsum: %u\n"
205+
"ip4 tooshort: %u\n"
206+
"ip4 toosmall: %u\n"
207+
"ip4 badhlen: %u\n"
208+
"ip4 badlen: %u\n",
209+
stats->ips_packets,
210+
stats->ips_badsum,
211+
stats->ips_tooshort,
212+
stats->ips_toosmall,
213+
stats->ips_badhlen,
214+
stats->ips_badlen);
215+
printf("tcp headers: %u\n"
216+
"tcp badsum: %u\n"
217+
"tcp badoff: %u\n"
218+
"tcp tooshort %u\n",
219+
stats->tcps_packets,
220+
stats->tcps_badsum,
221+
stats->tcps_badoff,
222+
stats->tcps_tooshort);
223+
#endif
224+
}
225+
226+
227+
228+

piglet-bpf-filter/daq_print.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#ifndef MINISNORT_PRINT_PACKET_H
2+
#define MINISNORT_PRINT_PACKET_H
3+
4+
#include <cstdint>
5+
#include <sys/types.h>
6+
7+
/*
8+
* PRINT_PACKET_LAYERS
9+
* @desc Print the protocol layer composition.
10+
*/
11+
#undef PRINT_PACKET_LAYERS
12+
13+
/*
14+
* PRINT_PACKET_STATS
15+
* @desc Print the packet decoding stats.
16+
* Useful for debugging decoding errors.
17+
*/
18+
#undef PRINT_PACKET_STATS
19+
20+
typedef struct _daq_pkt_hdr DAQ_PktHdr_t;
21+
void print_packet(int const instance_id, DAQ_PktHdr_t const * hdr, uint8_t const * data, size_t const len);
22+
23+
#endif // MINISNORT_PRINT_PACKET_H
24+

piglet-bpf-filter/pcaps/dns.pcap

4.24 KB
Binary file not shown.

0 commit comments

Comments
 (0)