anchor.diff:  gethostbyaddr(IP) ->
       case dnip(IP) of
   	{ok, {IP1, HType, HLen, DnIP}} ->
  -            RRs = match_rr(dns_rr_match(DnIP, in, ptr)),
  -	    ent_gethostbyaddr(RRs,  IP1, HType, HLen);
  +            gethostbyaddr(IP1, HType, HLen, DnIP, []);
   	Error -> Error
  +    end.
  +
  +gethostbyaddr(IP, HType, HLen, DnIP, DnIPs) ->
  +    MatchPtrRR = dns_rr_match(DnIP, in, ptr),
  +    case match_rr(MatchPtrRR) of
  +        [] ->
  +            case lookup_cname(DnIP) of
  +                [#dns_rr{data = DnIP_1} | _] ->
  +                    DnIPs_1 = [DnIP | DnIPs],
  +                    %% CName loop protection
  +                    case lists:member(DnIP_1, DnIPs_1) of
  +                        true ->
  +                            {error, nxdomain};
  +                        false ->
  +                            gethostbyaddr(IP, HType, HLen, DnIP_1, DnIPs_1)
  +                    end;
  +                CNames when is_list(CNames) ->
  +                    {error, nxdomain}
  +            end;
  +        RRs when is_list(RRs) ->
  +            ent_gethostbyaddr(RRs, IP, HType, HLen)
       end.
   
   %%
  
positive.code: 	    {ok, make_hostent(Domain, Addrs, Aliases, Type)}
      end.
  
  %% lookup address record
  lookup_type(Domain, Type) ->
      [R#dns_rr.data || R <- lookup_rr(Domain, in, Type) ].
  
  %% lookup canonical name
  lookup_cname(Domain) ->
      [R#dns_rr.data || R <- lookup_rr(Domain, in, ?S_CNAME) ].
  
  lookup_cname(Domain, Type) ->
      case Type of
       a -> [];
       aaaa -> [];
       cname -> lookup_cname(Domain);
       _ -> []
      end.
  
  
  %% lookup resource record
  lookup_rr(Domain, Class, Type) ->
      match_rr(dns_rr_match(tolower(Domain), Class, Type)).
  
negative.code: %%
  res_gethostbyaddr(IP, Rec) ->
      {ok, {IP1, HType, HLen}} = dnt(IP),
      RRs =
          [RR#dns_rr{domain = tolower(N)} ||
              #dns_rr{
                 domain = N,
                 class = in,
                 type = T} = RR <- Rec#dns_rec.anlist,
              T =:= ?S_PTR orelse T =:= ?S_CNAME],
      res_cache_answer(RRs),
      case [RR || #dns_rr{type = ?S_PTR} = RR <- RRs] of
          [] ->
              {error, nxdomain};
          PtrRRs ->
              ent_gethostbyaddr(PtrRRs, IP1, HType, HLen)
      end.
  
  ent_gethostbyaddr([RR|RRs], IP, AddrType, Length) ->
      %% debug
      if RRs =/= [] ->
              ?dbg("gethostbyaddr found extra=~p~n", [RRs]);
         true -> ok
      end,
      Domain = RR#dns_rr.data,
      H =
          #hostent{
             h_name = Domain,
             %% Since a PTR record should point to
             %% the canonical name, this Domain should
             %% have no canonical name, so it this really reasonable?
             h_aliases = lookup_cname(Domain),
             h_addr_list = [IP],
             h_addrtype = AddrType,
             h_length = Length },
      {ok, H}.
  
  
  dnip(IP) ->
      case dnt(IP) of
  