@@ -1271,9 +1271,10 @@ def __getattr__(self, attr):
12711271
12721272class DNS (DNSCompressedPacket ):
12731273 name = "DNS"
1274+ FORCE_TCP = False
12741275 fields_desc = [
12751276 ConditionalField (ShortField ("length" , None ),
1276- lambda p : isinstance (p .underlayer , TCP )),
1277+ lambda p : p . FORCE_TCP or isinstance (p .underlayer , TCP )),
12771278 ShortField ("id" , 0 ),
12781279 BitField ("qr" , 0 , 1 ),
12791280 BitEnumField ("opcode" , 0 , 4 , {0 : "QUERY" , 1 : "IQUERY" , 2 : "STATUS" }),
@@ -1300,7 +1301,7 @@ class DNS(DNSCompressedPacket):
13001301
13011302 def get_full (self ):
13021303 # Required for DNSCompressedPacket
1303- if isinstance (self .underlayer , TCP ):
1304+ if isinstance (self .underlayer , TCP ) or self . FORCE_TCP :
13041305 return self .original [2 :]
13051306 else :
13061307 return self .original
@@ -1332,7 +1333,10 @@ def mysummary(self):
13321333 )
13331334
13341335 def post_build (self , pkt , pay ):
1335- if isinstance (self .underlayer , TCP ) and self .length is None :
1336+ if (
1337+ (isinstance (self .underlayer , TCP ) or self .FORCE_TCP ) and
1338+ self .length is None
1339+ ):
13361340 pkt = struct .pack ("!H" , len (pkt ) - 2 ) + pkt [2 :]
13371341 return pkt + pay
13381342
@@ -1363,6 +1367,14 @@ def pre_dissect(self, s):
13631367 return s
13641368
13651369
1370+ class DNSTCP (DNS ):
1371+ """
1372+ A DNS packet that is always under TCP
1373+ """
1374+ FORCE_TCP = True
1375+ match_subclass = True
1376+
1377+
13661378bind_layers (UDP , DNS , dport = 5353 )
13671379bind_layers (UDP , DNS , sport = 5353 )
13681380bind_layers (UDP , DNS , dport = 53 )
@@ -1413,16 +1425,18 @@ def dns_resolve(qname, qtype="A", raw=False, tcp=False, verbose=1, timeout=3, **
14131425 try :
14141426 # Spawn a socket, connect to the nameserver on port 53
14151427 if tcp :
1428+ cls = DNSTCP
14161429 sock = socket .socket (socket .AF_INET , socket .SOCK_STREAM )
14171430 else :
1431+ cls = DNS
14181432 sock = socket .socket (socket .AF_INET , socket .SOCK_DGRAM )
14191433 sock .settimeout (kwargs ["timeout" ])
14201434 sock .connect ((nameserver , 53 ))
14211435 # Connected. Wrap it with DNS
1422- sock = StreamSocket (sock , DNS )
1436+ sock = StreamSocket (sock , cls )
14231437 # I/O
14241438 res = sock .sr1 (
1425- DNS (qd = [DNSQR (qname = qname , qtype = qtype )], id = RandShort ()),
1439+ cls (qd = [DNSQR (qname = qname , qtype = qtype )], id = RandShort ()),
14261440 ** kwargs ,
14271441 )
14281442 except IOError as ex :
0 commit comments