From cb8ad22eef856cb2b76b63f7db20bacd91c13c83 Mon Sep 17 00:00:00 2001 From: rudolfkoenig <> Date: Sat, 19 May 2018 07:24:56 +0000 Subject: [PATCH] HttpUtils.pm: Handle in-name compression in DNS answer (Forum #87840) git-svn-id: https://svn.fhem.de/fhem/trunk@16759 2b470e98-0d58-463d-a4d8-8e2adae1ed80 --- fhem/FHEM/HttpUtils.pm | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/fhem/FHEM/HttpUtils.pm b/fhem/FHEM/HttpUtils.pm index ade3ade0b..df0b9b92e 100644 --- a/fhem/FHEM/HttpUtils.pm +++ b/fhem/FHEM/HttpUtils.pm @@ -136,30 +136,38 @@ ip2str($) return "[$h]"; } -# http://www.ccs.neu.edu/home/amislove/teaching/cs4700/fall09/handouts/project1-primer.pdf +# https://mislove.org/teaching/cs4700/spring11/handouts/project1-primer.pdf my %HU_dnsCache; sub HttpUtils_dnsParse($$$) { - my ($a, $ql,$try6) = @_; # $ql: avoid hardcoding query length + my ($a,$ql,$try6) = @_; # $ql: query length + my $ml = length($a); + return "short DNS answer" if(length($a) <= $ql); return "wrong message ID" if(unpack("H*",substr($a,0,2)) ne "7072"); - while(length($a) >= $ql+16) { + return "Cant find host" if(unpack("n",substr($a,6,2)) == 0); + + while($ml >= $ql+16) { # there is a header my $l = unpack("C",substr($a,$ql, 1)); if(($l & 0xC0) == 0xC0) { # DNS packed compression $ql += 2; } else { - while($l != 0) { + while($l != 0 && ($ql+$l+1)<$ml) { # skip a name $ql += $l+1; $l = unpack("C",substr($a,$ql,2)); + if(($l & 0xC0) == 0xC0) { # DNS packed compression + $ql++; + last; + } } $ql++; } return (undef, substr($a,$ql+10,16),unpack("N",substr($a,$ql+4,4))) - if(unpack("N",substr($a,$ql,4)) == 0x1c0001 && $try6); + if($ql+4<= $ml && unpack("N",substr($a,$ql,4)) == 0x1c0001 && $try6); return (undef, substr($a,$ql+10,4), unpack("N",substr($a,$ql+4,4))) - if(unpack("N",substr($a,$ql,4)) == 0x10001 && !$try6); - $ql += 10+unpack("n",substr($a,$ql+8)) if(length($a) >= $ql+10); + if($ql+4 <= $ml && unpack("N",substr($a,$ql,4)) == 0x10001 && !$try6); + $ql += 10+unpack("n",substr($a,$ql+8)) if($ql+10 <= $ml); } return "No A record found"; }