3 #include <linux/types.h>
4 #include <uapi/linux/tcp.h>
5 #include <uapi/linux/udp.h>
6 #include <uapi/linux/ip.h>
7 #include <uapi/linux/ipv6.h>
11 unsigned id :16; /* query identification number */
12 #if BYTE_ORDER == BIG_ENDIAN
13 /* fields in third byte */
14 unsigned qr: 1; /* response flag */
15 unsigned opcode: 4; /* purpose of message */
16 unsigned aa: 1; /* authoritative answer */
17 unsigned tc: 1; /* truncated message */
18 unsigned rd: 1; /* recursion desired */
19 /* fields in fourth byte */
20 unsigned ra: 1; /* recursion available */
21 unsigned unused :1; /* unused bits (MBZ as of 4.9.3a3) */
22 unsigned ad: 1; /* authentic data from named */
23 unsigned cd: 1; /* checking disabled by resolver */
24 unsigned rcode :4; /* response code */
25 #elif BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN
26 /* fields in third byte */
27 unsigned rd :1; /* recursion desired */
28 unsigned tc :1; /* truncated message */
29 unsigned aa :1; /* authoritative answer */
30 unsigned opcode :4; /* purpose of message */
31 unsigned qr :1; /* response flag */
32 /* fields in fourth byte */
33 unsigned rcode :4; /* response code */
34 unsigned cd: 1; /* checking disabled by resolver */
35 unsigned ad: 1; /* authentic data from named */
36 unsigned unused :1; /* unused bits (MBZ as of 4.9.3a3) */
37 unsigned ra :1; /* recursion available */
40 unsigned qdcount :16; /* number of question entries */
41 unsigned ancount :16; /* number of answer entries */
42 unsigned nscount :16; /* number of authority entries */
43 unsigned arcount :16; /* number of resource entries */
62 BPF_TABLE("hash", u32, u64, v4filter, 1024);
63 BPF_TABLE("hash", struct KeyV6, u64, v6filter, 1024);
64 BPF_TABLE("hash", struct QNameKey, struct QNameValue, qnamefilter, 1024);
65 BPF_TABLE("prog", int, int, progsarray, 1);
67 int bpf_qname_filter(struct __sk_buff *skb)
69 uint32_t qname_off = skb->cb[0];
70 ssize_t labellen = skb->cb[3];
72 struct QNameKey qkey = { 0 };
83 #define FILL_ONE_KEY \
84 temp = load_byte(skb, qname_off + idx); \
88 if (labellen == 0) { \
91 } else if (temp >= 'A' && temp <= 'Z') { \
92 temp += ('a' - 'A'); \
94 qkey.qname[idx] = temp; \
381 /* the only value that makes sense for
382 qkey.qname[255] is 0, and it's already
388 u16 qtype = load_half(skb, (qname_off + idx));
390 struct QNameValue* qvalue = qnamefilter.lookup(&qkey);
392 (qvalue->qtype == 255 || qtype == qvalue->qtype)) {
393 __sync_fetch_and_add(&qvalue->counter, 1);
401 int bpf_dns_filter(struct __sk_buff *skb) {
404 int nh_off = BPF_LL_OFF + ETH_HLEN;
406 if (skb->protocol == ntohs(0x0800)) {
408 int off = nh_off + offsetof(struct iphdr, saddr);
409 key = load_word(skb, off);
411 u64* counter = v4filter.lookup(&key);
413 __sync_fetch_and_add(counter, 1);
417 ip_proto = load_byte(skb, nh_off + offsetof(struct iphdr, protocol));
418 proto_off = nh_off + sizeof(struct iphdr);
420 else if (skb->protocol == ntohs(0x86DD)) {
422 int off = nh_off + offsetof(struct ipv6hdr, saddr);
423 key.src[0] = load_byte(skb, off++);
424 key.src[1] = load_byte(skb, off++);
425 key.src[2] = load_byte(skb, off++);
426 key.src[3] = load_byte(skb, off++);
427 key.src[4] = load_byte(skb, off++);
428 key.src[5] = load_byte(skb, off++);
429 key.src[6] = load_byte(skb, off++);
430 key.src[7] = load_byte(skb, off++);
431 key.src[8] = load_byte(skb, off++);
432 key.src[9] = load_byte(skb, off++);
433 key.src[10] = load_byte(skb, off++);
434 key.src[11] = load_byte(skb, off++);
435 key.src[12] = load_byte(skb, off++);
436 key.src[13] = load_byte(skb, off++);
437 key.src[14] = load_byte(skb, off++);
438 key.src[15] = load_byte(skb, off++);
440 u64* counter = v6filter.lookup(&key);
442 __sync_fetch_and_add(counter, 1);
446 ip_proto = load_byte(skb, nh_off + offsetof(struct ipv6hdr, nexthdr));
447 proto_off = nh_off + sizeof(struct ipv6hdr);
450 /* neither IPv4 not IPv6, well */
455 if (ip_proto == IPPROTO_TCP) {
459 struct QNameKey qkey = { 0 };
460 int dns_off = proto_off + sizeof(struct udphdr);
461 int qname_off = dns_off + sizeof(struct dnsheader);
462 skb->cb[0] = (uint32_t) qname_off;
465 uint8_t temp = load_byte(skb, qname_off);
471 /* root, nothing else to see */
472 qtype = load_half(skb, (qname_off + 1));
474 struct QNameValue* qvalue = qnamefilter.lookup(&qkey);
476 (qvalue->qtype == 255 || qtype == qvalue->qtype)) {
477 __sync_fetch_and_add(&qvalue->counter, 1);
483 ssize_t labellen = temp;
485 qkey.qname[0] = temp;
487 temp = load_byte(skb, qname_off + 1);
489 if (temp >= 'A' && temp <= 'Z') {
493 skb->cb[3] = labellen;
494 progsarray.call(skb, 0);