@@ -1520,13 +1520,37 @@ def make_reply(self, req):
1520
1520
if IPv6 in req :
1521
1521
resp [IPv6 ].underlayer .remove_payload ()
1522
1522
resp /= IPv6 (dst = req [IPv6 ].src , src = self .src_ip6 or req [IPv6 ].dst )
1523
- else :
1523
+ elif IP in req :
1524
1524
resp [IP ].underlayer .remove_payload ()
1525
1525
resp /= IP (dst = req [IP ].src , src = self .src_ip or req [IP ].dst )
1526
- resp /= UDP (sport = req .dport , dport = req .sport )
1526
+ else :
1527
+ warning ("No IP or IPv6 layer in %s" , req .command ())
1528
+ return
1529
+ try :
1530
+ resp /= UDP (sport = req [UDP ].dport , dport = req [UDP ].sport )
1531
+ except IndexError :
1532
+ warning ("No UDP layer in %s" , req .command (), exc_info = True )
1533
+ return
1527
1534
ans = []
1528
- req = req .getlayer (self .cls )
1529
- for rq in req .qd :
1535
+ try :
1536
+ req = req [self .cls ]
1537
+ except IndexError :
1538
+ warning (
1539
+ "No %s layer in %s" ,
1540
+ self .cls .__name__ ,
1541
+ req .command (),
1542
+ exc_info = True ,
1543
+ )
1544
+ return
1545
+ try :
1546
+ queries = req .qd
1547
+ except AttributeError :
1548
+ warning ("No qd attribute in %s" , req .command (), exc_info = True )
1549
+ return
1550
+ for rq in queries :
1551
+ if isinstance (rq , Raw ):
1552
+ warning ("Cannot parse qd element %s" , rq .command (), exc_info = True )
1553
+ continue
1530
1554
if rq .qtype in [1 , 28 ]:
1531
1555
# A or AAAA
1532
1556
if rq .qtype == 28 :
@@ -1598,6 +1622,9 @@ def make_reply(self, req):
1598
1622
# Error
1599
1623
break
1600
1624
else :
1625
+ if not ans :
1626
+ # No rq was actually answered, as none was valid. Discard.
1627
+ return
1601
1628
# All rq were answered
1602
1629
resp /= self .cls (id = req .id , qr = 1 , qd = req .qd , an = ans )
1603
1630
return resp
0 commit comments