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