lib/net/dns/header.rb in net-dns-0.3 vs lib/net/dns/header.rb in net-dns-0.4

- old
+ new

@@ -69,41 +69,131 @@ # # All rights reserved. This program is free software; you may redistribute # it and/or modify it under the same terms as Ruby itself. # class Header + + # + # =Name + # + # Net::DNS::Header::RCode - DNS Header RCode handling class + # + # =Synopsis + # + # It should be used internally by Net::DNS::Header class. However, it's still + # possible to instantiate it directly. + # + # require 'net/dns/header' + # rcode = Net::DNS::Header::RCode.new 0 + # + # =Description + # + # The RCode class represents the RCode field in the Header portion of a + # DNS packet. This field (called Response Code) is used to get informations + # about the status of a DNS operation, such as a query or an update. These + # are the values in the original Mockapetris's standard (RFC1035): + # + # * 0 No error condition + # * 1 Format error - The name server was unable to interpret + # the query. + # * 2 Server failure - The name server was + # unable to process this query due to a + # problem with the name server. + # * 3 Name Error - Meaningful only for + # responses from an authoritative name + # server, this code signifies that the + # domain name referenced in the query does + # not exist. + # * 4 Not Implemented - The name server does + # not support the requested kind of query. + # * 5 Refused - The name server refuses to + # perform the specified operation for + # policy reasons. For example, a name + # server may not wish to provide the + # information to the particular requester, + # or a name server may not wish to perform + # a particular operation (e.g., zone + # transfer) for particular data. + # * 6-15 Reserved for future use. + # + # In the next DNS RFCs, codes 6-15 has been assigned to the following + # errors: + # + # * 6 YXDomain + # * 7 YXRRSet + # * 8 NXRRSet + # * 9 NotAuth + # * 10 NotZone + # + # More RCodes has to come for TSIGs and other operations. + # + class RCode + + # Constant for +rcode+ Response Code No Error + NOERROR = 0 + # Constant for +rcode+ Response Code Format Error + FORMAT = 1 + # Constant for +rcode+ Response Code Server Format Error + SERVER = 2 + # Constant for +rcode+ Response Code Name Error + NAME = 3 + # Constant for +rcode+ Response Code Not Implemented Error + NOTIMPLEMENTED = 4 + # Constant for +rcode+ Response Code Refused Error + REFUSED = 5 + + + RCodeType = %w[NoError FormErr ServFail NXDomain NotImp + Refused YXDomain YXRRSet NXRRSet NotAuth NotZone] + + RCodeErrorString = ["No errors", + "The name server was unable to interpret the query", + "The name server was unable to process this query due to problem with the name server", + "Domain name referenced in the query does not exists", + "The name server does not support the requested kind of query", + "The name server refuses to perform the specified operation for policy reasons", + "", + "", + "", + "", + ""] + + attr_reader :code, :type, :explanation + + def initialize(code) + if (0..10).include? code + @code = code + @type = RCodeType[code] + @explanation = RCodeErrorString[code] + else + raise HeaderArgumentError, "RCode #{code} out of range" + end + end + + def to_s + @code.to_s + end + end + # Constant for +opCode+ query QUERY = 0 # Constant for +opCode+ iquery IQUERY = 1 # Constant for +opCode+ status STATUS = 2 # Array with given strings OPARR = %w[QUERY IQUERY STATUS] - # Constant for +rcode+ Response Code No Error - NOERROR = 0 - # Constant for +rcode+ Response Code Format Error - FORMAT = 1 - # Constant for +rcode+ Response Code Server Format Error - SERVER = 2 - # Constant for +rcode+ Response Code Name Error - NAME = 3 - # Constant for +rcode+ Response Code Not Implemented Error - NOTIMPLEMENTED = 4 - # Constant for +rcode+ Response Code Refused Error - REFUSED = 5 - # Array with given strings - CODEARR = %w[NOERROR FORMAT SERVER NAME NOTIMPLEMENTED REFUSED] - @@id_arr = [] # Reader for +id+ attribute attr_reader :id # Reader for the operational code attr_reader :opCode + # Reader for the rCode instance + attr_reader :rCode # Reader for question section entries number attr_reader :qdCount # Reader for answer section entries number attr_reader :anCount # Reader for authority section entries number @@ -174,11 +264,10 @@ else raise HeaderArgumentError, "Wrong argument class: #{arg.class}" end end - # Inspect method, prints out all the options and relative values. # # p Net::DNS::Header.new # # ;; id = 18123 # # ;; qr = 0 opCode: 0 aa = 0 tc = 0 rd = 1 @@ -199,11 +288,11 @@ "tc = #@tc\t" + "rd = #@rd\n" + ";; ra = #@ra\t" + "ad = #@ad\t" + "cd = #@cd\t" + - "rcode = #{rCode_str[0] || "NOERROR"}\n" + + "rcode = #{@rCode.type}\n" + ";; qdCount = #@qdCount\t"+ "anCount = #@anCount\t"+ "nsCount = #@nsCount\t"+ "arCount = #@arCount\n" end @@ -258,11 +347,11 @@ # def data arr = [] arr.push(@id) arr.push((@qr<<7)|(@opCode<<3)|(@aa<<2)|(@tc<<1)|@rd) - arr.push((@ra<<7)|(@ad<<5)|(@cd<<4)|@rCode) + arr.push((@ra<<7)|(@ad<<5)|(@cd<<4)|@rCode.code) arr.push(@qdCount) arr.push(@anCount) arr.push(@nsCount) arr.push(@arCount) arr.pack("n C2 n4") @@ -536,54 +625,34 @@ end # Returns an error array for the header response code, or # +nil+ if no error is generated. # - # error, cause = header.rcode_str + # error, cause = header.rCode_str # puts "Error #{error} cause by: #{cause}" if error - # #=> Error Format Error caused by: The name server + # #=> Error ForErr caused by: The name server # #=> was unable to interpret the query # def rCode_str - case @rCode - when NOERROR - return nil,nil - when FORMAT - return "Format Error", "The name server was unable to interpret the query" - when SERVER - return "Server Failure", - "The name server was unable to process this query due to problem with the name server" - when NAME - return "Name Error", "Domain name referenced in the query does not exists" - when NOTIMPLEMENTED - return "Not Implemented", - "The name server does not support the requested kind of query" - when REFUSED - return "Refused", - "The name server refuses to perform the specified operation for policy reasons" - end + return rCode.type, rCode.explanation end - # Return the value of rCode variable + # Checks for errors in the DNS packet # - # if header.rcode == Net::DNS::Header::NOERROR + # unless header.error? # puts "No errors in DNS answer packet" # end # - def rCode - @rCode + def error? + @rCode.code > 0 end # Set the rCode value. This should only be done in DNS # answer packets. # def rCode=(val) - if (0..5).include? val - @rCode = val - else - raise HeaderArgumentError, ":rCode must be one of #{CODEARR.join(" ")}" - end + @rCode = RCode.new(val) end # Sets the number of entries in a question section # def qdCount=(val) @@ -627,11 +696,11 @@ private def new_from_scratch @id = genID # generate ad unique id @qr = @aa = @tc = @ra = @ad = @cd = 0 - @rCode = NOERROR + @rCode = RCode.new(0) # no error @anCount = @nsCount = @arCount = 0 @rd = @qdCount = 1 @opCode = QUERY # standard query, default message end @@ -647,10 +716,10 @@ @tc = (arr[1] >> 1) & 0x01 @rd = arr[1] & 0x1 @ra = (arr[2] >> 7) & 0x01 @ad = (arr[2] >> 5) & 0x01 @cd = (arr[2] >> 4) & 0x01 - @rCode = arr[2] & 0xf + @rCode = RCode.new(arr[2] & 0xf) @qdCount = arr[3] @anCount = arr[4] @nsCount = arr[5] @arCount = arr[6] end