Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/lib/net/dns/question.rb
Views: 11780
# -*- coding: binary -*-1#---2# $Id: Question.rb,v 1.8 2006/07/28 19:00:03 bluemonk Exp $3#+++45require 'net/dns/dns'6require 'net/dns/names/names'7require 'net/dns/rr/types'8require 'net/dns/rr/classes'910module Net # :nodoc:11module DNS1213#14# =Name15#16# Net::DNS::Question - DNS packet question class17#18# =Synopsis19#20# require 'net/dns/question'21#22# =Description23#24# This class represent the Question portion of a DNS packet. The number25# of question entries is stored in the +qdCount+ variable of an Header26# object.27#28# A new object can be created passing the name of the query and the type29# of answer desired, plus an optional argument containing the class:30#31# question = Net::DNS::Question.new("google.com.", Net::DNS::A)32# #=> "google.com. A IN"33#34# Alternatevly, a new object is created when processing a binary35# packet, as when an answer is received.36# To obtain the binary data from a question object you can use37# the method Question#data:38#39# question.data40# #=> "\006google\003com\000\000\001\000\001"41#42# A lot of methods were written to keep a compatibility layer with43# the Perl version of the library, as long as methods name which are44# more or less the same.45#46# =Error classes47#48# Some error classes has been defined for the Net::DNS::Header class,49# which are listed here to keep a light and browsable main documentation.50# We have:51#52# * QuestionArgumentError: generic argument error53# * QuestionNameError: an error in the +name+ part of a Question entry54#55# =Copyright56#57# Copyright (c) 2006 Marco Ceresa58#59# All rights reserved. This program is free software; you may redistribute60# it and/or modify it under the same terms as Ruby itself.61#62class Question6364include Net::DNS::Names6566# +name+ part of a Question entry67attr_reader :qName68# +type+ part of a Question entry69attr_reader :qType70# +class+ part of a Question entry71attr_reader :qClass7273# Creates a new Net::DNS::Question object:74#75# question = Net::DNS::Question.new("example.com")76# #=> "example.com A IN"77# question = Net::DNS::Question.new("example.com", Net::DNS::MX)78# #=> "example.com MX IN"79# question = Net::DNS::Question.new("example.com", Net::DNS::TXT, Net::DNS::HS)80# #=> "example.com TXT HS"8182# If not specified, +type+ and +cls+ arguments defaults83# to Net::DNS::A and Net::DNS::IN respectively.84#85def initialize(name,type=Net::DNS::A,cls=Net::DNS::IN)86@qName = check_name name87@qType = Net::DNS::RR::Types.new type88@qClass = Net::DNS::RR::Classes.new cls89end9091# Return a new Net::DNS::Question object created by92# parsing binary data, such as an answer from the93# nameserver.94#95# question = Net::DNS::Question.parse(data)96# puts "Queried for #{question.qName} type #{question.qType.to_s}"97# #=> Queried for example.com type A98#99def self.parse(arg)100if arg.kind_of? String101o = allocate102o.send(:new_from_binary,arg)103o104else105raise QuestionArgumentError, "Wrong argument format, must be a String"106end107end108109# Known inspect method with nice formatting110def inspect111if @qName.size > 29 then112len = @qName.size + 1113else114len = 29115end116[@qName,@qClass.to_s,@qType.to_s].pack("A#{len} A8 A8")117end118119# Outputs binary data from a Question object120#121# question.data122# #=> "\006google\003com\000\000\001\000\001"123#124def data125[pack_name(@qName),@qType.to_i,@qClass.to_i].pack("a*nn")126end127128# Return the binary data of the objects, plus an offset129# and an Hash with references to compressed names. For use in130# Net::DNS::Packet compressed packet creation.131#132def comp_data133arr = @qName.split(".")134str = pack_name(@qName)135string = ""136names = {}137offset = Net::DNS::HFIXEDSZ138arr.size.times do |i|139x = i+1140elem = arr[-x]141len = elem.size142string = ((string.reverse)+([len,elem].pack("Ca*")).reverse).reverse143names[string] = offset144offset += len145end146offset += 2 * Net::DNS::INT16SZ147str += "\000"148[[str,@qType.to_i,@qClass.to_i].pack("a*nn"),offset,names]149end150151private152153def build_qName(str)154result = ""155offset = 0156loop do157len = str.unpack("@#{offset} C")[0]158break if len == 0159offset += 1160result += str[offset..offset+len-1]161result += "."162offset += len163end164result165end166167def check_name(name)168name.strip!169if name =~ /[^\w\.\-_]/170raise QuestionNameError, "Question name #{name.inspect} not valid"171else172name173end174rescue175raise QuestionNameError, "Question name #{name.inspect} not valid"176end177178def new_from_binary(data)179str,type,cls = data.unpack("a#{data.size-4}nn")180@qName = build_qName(str)181@qType = Net::DNS::RR::Types.new type182@qClass = Net::DNS::RR::Classes.new cls183rescue StandardError => e184raise QuestionArgumentError, "Invalid data: #{data.inspect}\n{e.backtrace}"185end186187end # class Question188189end # class DNS190end # module Net191192class QuestionArgumentError < ArgumentError # :nodoc:193end194class QuestionNameError < StandardError # :nodoc:195end196197198