From d22b85229e5ead20a53be012f0165fa93a32bab5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fran=C3=A7ois=20De=20Keersmaeker?=
 <francois.dekeersmaeker@uclouvain.be>
Date: Thu, 1 Jun 2023 17:02:28 +0200
Subject: [PATCH] Dispatch mDNS from DNS to add custom functionality

---
 src/packet/DNS.py          |  12 +++++++++-
 src/packet/Packet.py       |   5 +++++
 src/packet/mDNS.py         |  44 +++++++++++++++++++++++++++++++++++++
 traces/mdns-responses.pcap | Bin 0 -> 2204 bytes
 4 files changed, 60 insertions(+), 1 deletion(-)
 create mode 100644 src/packet/mDNS.py
 create mode 100644 traces/mdns-responses.pcap

diff --git a/src/packet/DNS.py b/src/packet/DNS.py
index 6e9d750..e147b99 100644
--- a/src/packet/DNS.py
+++ b/src/packet/DNS.py
@@ -52,6 +52,15 @@ class DNS(Packet):
             layer_idx += 1
             question_record = question_records.getlayer(layer_idx)
 
+    
+    def get_field(self) -> str:
+        """
+        Randomly pick a DNS field to be modified.
+
+        :return: Field name.
+        """
+        return random.choice(self.fields)
+
 
     def tweak(self) -> dict:
         """
@@ -63,7 +72,8 @@ class DNS(Packet):
         :return: Dictionary containing tweak information.
         """
         # Get field which will be modified
-        field = random.choice(self.fields)
+        field = self.get_field()
+        
         # Get auxiliary fields
         qdcount = self.layer.getfieldval("qdcount")
         question_records = self.layer.getfieldval("qd") if qdcount > 0 else None
diff --git a/src/packet/Packet.py b/src/packet/Packet.py
index d739cff..2f37f82 100644
--- a/src/packet/Packet.py
+++ b/src/packet/Packet.py
@@ -116,9 +116,14 @@ class Packet:
             try:
                 protocol = layer.name.replace(" ", "_")
                 if protocol == "IP" and packet.getfieldval("version") == 4:
+                    # IPv4 packet
                     protocol = "IPv4"
                 elif protocol == "IP" and packet.getfieldval("version") == 6:
+                    # IPv6 packet
                     protocol = "IPv6"
+                elif protocol == "DNS" and packet.getfieldval("sport") == 5353 and packet.getfieldval("sport") == 5353:
+                    # mDNS packet
+                    protocol = "mDNS"
                 else:
                     protocol = Packet.protocols.get(protocol, protocol)
                 module = importlib.import_module(f"packet.{protocol}")
diff --git a/src/packet/mDNS.py b/src/packet/mDNS.py
new file mode 100644
index 0000000..1c566b4
--- /dev/null
+++ b/src/packet/mDNS.py
@@ -0,0 +1,44 @@
+import random
+import scapy.all as scapy
+from scapy.layers import dns
+from packet.DNS import DNS
+
+class mDNS(DNS):
+
+    # Class variables
+    name = "mDNS"
+
+    # Modifiable fields
+    fields = {
+        "query": [
+            "qr",
+            "qtype",
+            "qname"
+        ],
+        "response": [
+            "qr"
+        ]
+    }
+
+    
+    def __init__(self, packet: scapy.Packet, id: int = 0, last_layer_index: int = -1) -> None:
+        """
+        mDNS packet constructor.
+
+        :param packet: Scapy packet to be edited.
+        :param id: Packet integer identifier.
+        :param last_layer_index: [Optional] Index of the last layer of the packet.
+                                 If not specified, it will be calculated.
+        """
+        super().__init__(packet, id, last_layer_index)
+        qr = self.layer.getfieldval("qr")
+        self.qr_str = "query" if qr == 0 else "response"
+
+    
+    def get_field(self) -> str:
+        """
+        Randomly pick a DNS field to be modified.
+
+        :return: Field name.
+        """
+        return random.choice(self.fields[self.qr_str])
diff --git a/traces/mdns-responses.pcap b/traces/mdns-responses.pcap
new file mode 100644
index 0000000000000000000000000000000000000000..54f42b62f93bd1c8894ed02cc89801a329ab4e02
GIT binary patch
literal 2204
zcmca|c+)~A1{MYcU}0bca`fieB&`f!V-RFw0AogmI0lB_8;*uJhct6AxH2#?&tB@l
z@L$kc_rMCq;s-!Ek(VMb8Q*_TV_;|j8O8;~EX;<6ri_NnhGrJbhL%R`nR&X2DJexP
ziA4p83=BLCAd4y(<i%Z_gLN$o3=Dicbe#;GO-)Tqj7?1}j9GK?lM{0o_>rW+!tog;
zB?T<;CCLQ`ych&PrU*^}I+`=SIJKxOGdZ=GJw7F`ShqNZCB8HTq=pCNC7>Fn1BnL`
zk$8dVMzh4H01Zut8(Jxlo0x2i>?VQS{FKxjTZEH1Gs@%3Qj2UI4f)a_EF(PwLp=jy
zf!q|Zgt4B1o`G(Xxgj4=AT!0**xbO(z|6v!8>p)|Ge6H3sGg%JH9fw##MY1_H@Cpn
z!ob4tKqZnp_Z--R#9MQ~h=CCrb}XRKKM=^E2<3Btf}SDZfYE_9sABRHfMPrh`cQRj
zKsFNt2T&(i1Q<4)KsGA_Lj!{YP%A=k4NTAou9p>LzXK?NoE}XeqX`680?`L1khe4N
hmLSW(C5X;w2{Ix}5Ksc)pE;U9MynWTy@OuG002LH71sa&

literal 0
HcmV?d00001

-- 
GitLab