Skip to content

Commit

Permalink
examples:dns_matching: make it work as DNS sniffer
Browse files Browse the repository at this point in the history
Reason:
The intention of initial version of this example was to provide
a loop-uprolling example and expected functionality was to drop
DNS packets requesting the DNS name contained in the map.
   But the functionality doesn't work as exepected because the
BPF program attached to the raw socket only filters the packets
received by the python program.

With these modifications, it still serves as a loop-unrolling
example, with slightly different functionality.

Inverted return values of bpf program. It keeps the packet if the
name in DNS packet is also exists in the map. All other packets
are dropped.
Python program is modified to read packets from raw socket.
DNS data from the packet is parsed and printed using dnslib library.
  • Loading branch information
pbhole committed Oct 4, 2017
1 parent 7436872 commit af83f6f
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 5 deletions.
8 changes: 4 additions & 4 deletions examples/networking/dns_matching/dns_matching.c
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,14 @@ int dns_matching(struct __sk_buff *skb)

struct Leaf * lookup_leaf = cache.lookup(&key);

// If DNS name is contained in our map, drop packet.
// If DNS name is contained in our map, keep the packet
if(lookup_leaf) {
bpf_trace_printk("Matched1\n");
return 0;
return -1;
}
}
}
}

return -1;
// Drop the packet
return 0;
}
27 changes: 26 additions & 1 deletion examples/networking/dns_matching/dns_matching.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import socket
import os
import struct
import dnslib


def encode_dns(name):
Expand Down Expand Up @@ -55,4 +56,28 @@ def add_cache_entry(cache, name):
add_cache_entry(cache, "foo.bar")
add_cache_entry(cache, "another.sample.domain")

bpf.trace_print()
socket_fd = function_dns_matching.sock
sock = socket.fromfd(socket_fd, socket.PF_PACKET, socket.SOCK_RAW, socket.IPPROTO_IP)
sock.setblocking(True)

while 1:
#retrieve raw packet from socket
packet_str = os.read(socket_fd, 2048)
packet_bytearray = bytearray(packet_str)

ETH_HLEN = 14
UDP_HLEN = 8

#IP HEADER
#calculate ip header length
ip_header_length = packet_bytearray[ETH_HLEN] #load Byte
ip_header_length = ip_header_length & 0x0F #mask bits 0..3
ip_header_length = ip_header_length << 2 #shift to obtain length

#calculate payload offset
payload_offset = ETH_HLEN + ip_header_length + UDP_HLEN

payload = packet_bytearray[payload_offset:]
# pass the payload to dnslib for parsing
dnsrec = dnslib.DNSRecord.parse(payload)
print (dnsrec.questions, "\n")

0 comments on commit af83f6f

Please sign in to comment.