Commit 782b34f0 authored by yonghong-song's avatar yonghong-song Committed by GitHub

Merge pull request #1374 from pbhole/dns_matching1

 examples:dns_matching: make it work as a DNS sniffer
parents 422db709 b2b9133f
...@@ -90,14 +90,14 @@ int dns_matching(struct __sk_buff *skb) ...@@ -90,14 +90,14 @@ int dns_matching(struct __sk_buff *skb)
struct Leaf * lookup_leaf = cache.lookup(&key); 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) { if(lookup_leaf) {
bpf_trace_printk("Matched1\n"); bpf_trace_printk("Matched1\n");
return 0; return -1;
} }
} }
} }
} }
// Drop the packet
return -1; return 0;
} }
...@@ -8,6 +8,8 @@ import sys ...@@ -8,6 +8,8 @@ import sys
import socket import socket
import os import os
import struct import struct
import dnslib
import argparse
def encode_dns(name): def encode_dns(name):
...@@ -27,8 +29,22 @@ def encode_dns(name): ...@@ -27,8 +29,22 @@ def encode_dns(name):
return (c_ubyte * size).from_buffer(b) return (c_ubyte * size).from_buffer(b)
def add_cache_entry(cache, name):
key = cache.Key()
key.p = encode_dns(name)
leaf = cache.Leaf()
leaf.p = (c_ubyte * 4).from_buffer(bytearray(4))
cache[key] = leaf
parser = argparse.ArgumentParser(usage='For detailed information about usage,\
try with -h option')
req_args = parser.add_argument_group("Required arguments")
req_args.add_argument("-i", "--interface", type=str, required=True, help="Interface name")
req_args.add_argument("-d", "--domains", type=str, required=True,
help='List of domain names separated by comma. For example: -d "abc.def, xyz.mno"')
args = parser.parse_args()
# initialize BPF - load source code from http-parse-simple.c # initialize BPF - load source code from http-parse-simple.c
bpf = BPF(src_file = "dns_matching.c", debug=0) bpf = BPF(src_file = "dns_matching.c", debug=0)
# print(bpf.dump_func("dns_test")) # print(bpf.dump_func("dns_test"))
...@@ -39,19 +55,47 @@ bpf = BPF(src_file = "dns_matching.c", debug=0) ...@@ -39,19 +55,47 @@ bpf = BPF(src_file = "dns_matching.c", debug=0)
function_dns_matching = bpf.load_func("dns_matching", BPF.SOCKET_FILTER) function_dns_matching = bpf.load_func("dns_matching", BPF.SOCKET_FILTER)
#create raw socket, bind it to eth0 #create raw socket, bind it to user provided interface
#attach bpf program to socket created #attach bpf program to socket created
BPF.attach_raw_socket(function_dns_matching, "eth1") BPF.attach_raw_socket(function_dns_matching, args.interface)
# Get the table. # Get the table.
cache = bpf.get_table("cache") cache = bpf.get_table("cache")
# Create first entry for foo.bar # Add cache entries
key = cache.Key() entries = [i.strip() for i in args.domains.split(",")]
key.p = encode_dns("foo.bar") for e in entries:
print(">>>> Adding map entry: ", e)
leaf = cache.Leaf() add_cache_entry(cache, e)
leaf.p = (c_ubyte * 4).from_buffer(bytearray(4))
cache[key] = leaf print("\nTry to lookup some domain names using nslookup from another terminal.")
print("For exmaple: nslookup foo.bar")
bpf.trace_print() print("\nBPF program will filter-in DNS packets which match with map entries.")
print("Packets received by user space program will be printed here")
print("\nHit Ctrl+C to end...")
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")
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment