@@ -1520,13 +1520,37 @@ def make_reply(self, req):
15201520 if IPv6 in req :
15211521 resp [IPv6 ].underlayer .remove_payload ()
15221522 resp /= IPv6 (dst = req [IPv6 ].src , src = self .src_ip6 or req [IPv6 ].dst )
1523- else :
1523+ elif IP in req :
15241524 resp [IP ].underlayer .remove_payload ()
15251525 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
15271534 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
15301554 if rq .qtype in [1 , 28 ]:
15311555 # A or AAAA
15321556 if rq .qtype == 28 :
@@ -1598,6 +1622,9 @@ def make_reply(self, req):
15981622 # Error
15991623 break
16001624 else :
1625+ if not ans :
1626+ # No rq was actually answered, as none was valid. Discard.
1627+ return
16011628 # All rq were answered
16021629 resp /= self .cls (id = req .id , qr = 1 , qd = req .qd , an = ans )
16031630 return resp
0 commit comments