Class: Net::DNS::Packet
- Inherits:
-
Object
- Object
- Net::DNS::Packet
- Defined in:
- lib/Net/DNS/Packet.rb
Overview
NAME
Net::DNS::Packet - DNS packet object class
DESCRIPTION
A Net::DNS::Packet object represents a DNS packet.
COPYRIGHT
Copyright © 1997-2002 Michael Fuhr.
Portions Copyright © 2002-2004 Chris Reinhardt.
Portions Copyright © 2002-2005 Olaf Kolkman
Ruby version Copyright © 2006 AlexD (Nominet UK)
All rights reserved. This program is free software; you may redistribute it and/or modify it under the same terms as Perl itself.
SEE ALSO
Net::DNS, Net::DNS::Resolver, Net::DNS::Update, Net::DNS::Header, Net::DNS::Question, Net::DNS::RR, RFC 1035 Section 4.1, RFC 2136 Section 2, RFC 2845
Direct Known Subclasses
Instance Attribute Summary collapse
-
#additional ⇒ Object
additional = packet.additional.
-
#answer ⇒ Object
(also: #pre, #prerequisite)
answer = packet.answer.
-
#answerfrom ⇒ Object
print “packet received from ”, packet.answerfrom, “n”.
-
#answersize ⇒ Object
print “packet size: ”, packet.answersize, “ bytesn”.
-
#authority ⇒ Object
(also: #update)
authority = packet.authority.
-
#compnames ⇒ Object
Returns the value of attribute compnames.
-
#header ⇒ Object
header = packet.header.
-
#question ⇒ Object
(also: #zone)
question = packet.question.
Class Method Summary collapse
-
.dn_expand(packet, offset) ⇒ Object
name, nextoffset = dn_expand(data, offset).
- .dn_expand_PP(packet, offset) ⇒ Object
-
.new_from_binary(*args) ⇒ Object
packet = Net::DNS::Packet.new_from_binary(data) packet = Net::DNS::Packet.new_from_binary(data, 1) # set debugging.
-
.new_from_values(qName, qType = "A", qClass = "IN") ⇒ Object
packet = Net::DNS::Packet.new_from_values(“example.com”) packet = Net::DNS::Packet.new_from_values(“example.com”, “MX”, “IN”).
-
.parse_question(data, offset) ⇒ Object
– —————————————————————————— parse_question.
-
.parse_rr(data, offset) ⇒ Object
– —————————————————————————— parse_rr.
-
.sign_sig0(*args) ⇒ Object
SIG0 support is provided through the Net::DNS::RR::SIG class.
Instance Method Summary collapse
-
#data ⇒ Object
data.
-
#dn_comp(name, offset) ⇒ Object
compname = packet.dn_comp(“foo.example.com”, $offset).
-
#each_address ⇒ Object
Iterators.
- #each_cname ⇒ Object
- #each_mx ⇒ Object
- #each_nameserver ⇒ Object
- #each_ptr ⇒ Object
-
#initialize(*args) ⇒ Packet
constructor
Do not use new with arguments! Use either Packet.new_from_binary or Packet.new_from_values to create a packet from data.
-
#inspect ⇒ Object
print packet.inspect.
-
#pop(section) ⇒ Object
rr = packet.pop(“pre”) rr = packet.pop(“update”) rr = packet.pop(“additional”) rr = packet.pop(“question”).
-
#push(insection, rr) ⇒ Object
packet.push(“pre”, rr) packet.push(“update”, rr) packet.push(“additional”, rr).
-
#sign_tsig(*args) ⇒ Object
key_name = “tsig-key” key = “awwLOtRfpGE+rRKF2+DEiw==”.
-
#unique_push(section, rrs) ⇒ Object
packet.unique_push(“pre” => rr) packet.unique_push(“update” => rr) packet.unique_push(“additional” => rr).
Constructor Details
#initialize(*args) ⇒ Packet
Do not use new with arguments! Use either Packet.new_from_binary or Packet.new_from_values to create a packet from data
107 108 109 110 111 112 113 114 115 116 117 118 |
# File 'lib/Net/DNS/Packet.rb', line 107 def initialize(*args) if (args.length > 0) raise ArgumentError, "Do not use new with arguments! Use either Packet.new_from_binary or Packet.new_from_values to create a packet from data" end @compnames = Hash.new() @seen=Hash.new() @header = Net::DNS::Header.new @answer=[] @question=[] @authority=[] @additional=[] end |
Instance Attribute Details
#additional ⇒ Object
additional = packet.additional
Returns a list of Net::DNS::RR objects representing the additional section of the packet.
83 84 85 |
# File 'lib/Net/DNS/Packet.rb', line 83 def additional @additional end |
#answer ⇒ Object Also known as: pre, prerequisite
answer = packet.answer
Returns a list of Net::DNS::RR objects representing the answer section of the packet.
In dynamic update packets, this section is known as pre or prerequisite and specifies the RRs or RRsets which must or must not preexist.
68 69 70 |
# File 'lib/Net/DNS/Packet.rb', line 68 def answer @answer end |
#answerfrom ⇒ Object
print “packet received from ”, packet.answerfrom, “n”
Returns the IP address from which we received this packet. User-created packets will return nil for this method.
89 90 91 |
# File 'lib/Net/DNS/Packet.rb', line 89 def answerfrom @answerfrom end |
#answersize ⇒ Object
print “packet size: ”, packet.answersize, “ bytesn”
Returns the size of the packet in bytes as it was received from a nameserver. User-created packets will return nil for this method (use packet.data.length instead).
96 97 98 |
# File 'lib/Net/DNS/Packet.rb', line 96 def answersize @answersize end |
#authority ⇒ Object Also known as: update
authority = packet.authority
Returns a list of Net::DNS::RR objects representing the authority section of the packet.
In dynamic update packets, this section is known as update and specifies the RRs or RRsets to be added or delted.
77 78 79 |
# File 'lib/Net/DNS/Packet.rb', line 77 def @authority end |
#compnames ⇒ Object
Returns the value of attribute compnames.
99 100 101 |
# File 'lib/Net/DNS/Packet.rb', line 99 def compnames @compnames end |
#header ⇒ Object
header = packet.header
Returns a Net::DNS::Header object representing the header section of the packet.
49 50 51 |
# File 'lib/Net/DNS/Packet.rb', line 49 def header @header end |
#question ⇒ Object Also known as: zone
question = packet.question
Returns a list of Net::DNS::Question objects representing the question section of the packet.
In dynamic update packets, this section is known as zone and specifies the zone to be updated.
58 59 60 |
# File 'lib/Net/DNS/Packet.rb', line 58 def question @question end |
Class Method Details
.dn_expand(packet, offset) ⇒ Object
name, nextoffset = dn_expand(data, offset)
name, nextoffset = Net::DNS::Packet::(data, offset)
Expands the domain name stored at a particular location in a DNS packet. The first argument is a reference to a scalar containing the packet data. The second argument is the offset within the packet where the (possibly compressed) domain name is stored.
Returns the domain name and the offset of the next location in the packet.
Returns nil, nil if the domain name couldn’t be expanded.
587 588 589 590 591 592 593 594 595 |
# File 'lib/Net/DNS/Packet.rb', line 587 def Packet.(packet, offset) if (Net::DNS::HAVE_XS) (name, roffset)=(packet, offset); else (name, roffset)=(packet, offset); end return name, roffset end |
.dn_expand_PP(packet, offset) ⇒ Object
597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 |
# File 'lib/Net/DNS/Packet.rb', line 597 def Packet.(packet, offset) name = ""; packetlen = packet.length; int16sz = Net::DNS::INT16SZ; while (true) return nil, nil if packetlen < (offset + 1); len = packet.unpack("\@#{offset} C") [0]; if (len == 0) offset+=1; break elsif ((len & 0xc0) == 0xc0) return nil, nil if packetlen < (offset + int16sz); ptr = packet.unpack("\@#{offset} n") [0]; ptr = ptr&(0x3fff); name2 = (packet, ptr) [0]; # pass $seen for debugging return nil, nil unless name2!=nil; name += name2; offset += int16sz; break else offset+=1; return nil, nil if packetlen < (offset + len); elem = packet[offset, len] name += Net::DNS::wire2presentation(elem)+"."; offset += len; end end name.gsub!(/\.$/o, "") return name, offset end |
.new_from_binary(*args) ⇒ Object
packet = Net::DNS::Packet.new_from_binary(data)
packet = Net::DNS::Packet.new_from_binary(data, 1) # set debugging
(packet, err) = Net::DNS::Packet.new_from_binary(data)
If passed a reference to a scalar containing DNS packet data, new creates a packet object from that data. A second argument can be passed to turn on debugging output for packet parsing.
If called in array context, returns a packet object and an error string. The error string will only be defined if the packet object is undefined (i.e., couldn’t be created).
Returns nil if unable to create a packet object (e.g., if the packet data is truncated).
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 |
# File 'lib/Net/DNS/Packet.rb', line 135 def Packet.new_from_binary(*args) packet = Packet.new # if args[0].is_a? String data = args[0] debug = args[1] debug = false if debug == nil #-------------------------------------------------------------- # Parse the header section. #-------------------------------------------------------------- print ";; HEADER SECTION\n" if debug packet.header= Net::DNS::Header.new(data) raise ArgumentError, "header section incomplete" if packet.header == nil print packet.header.inspect if debug offset = Net::DNS::HFIXEDSZ #-------------------------------------------------------------- # Parse the question/zone section. #-------------------------------------------------------------- if debug then print "\n" section = (packet.header.opcode == "UPDATE") ? "ZONE" : "QUESTION" print ";; #{section} SECTION (#{packet.header.qdcount} record #{packet.header.qdcount == 1 ? '' : 's'})\n" end packet.question = [] packet.header.qdcount.times { (qobj, offset) = parse_question(data, offset) # raise ArgumentError, "question section incomplete" if qobj == nil if (qobj==nil) if (packet.header.tc==1) return packet else return nil end end # unless (defined $qobj) { # last PARSE if $self{"header"}->tc; # return wantarray # ? (nil, "question section incomplete") # : nil; # } packet.push("question", qobj) if debug then print ";; " print qobj.inspect end } #-------------------------------------------------------------- # Parse the answer/prerequisite section. #-------------------------------------------------------------- if debug then print "\n" section = (packet.header.opcode == "UPDATE") ? "PREREQUISITE" : "ANSWER" print ";; #{section} SECTION (#{packet.header.ancount} record #{packet.header.ancount == 1 ? '' : 's'})\n" end packet.answer = [] packet.header.ancount.times { (rrobj, offset) = parse_rr(data, offset) # raise ArgumentError, "answer section incomplete" if rrobj == nil if (rrobj==nil) if (packet.header.tc==1) return packet else return nil end end packet.push("answer", rrobj) print rrobj.inspect + "\n" if debug } #-------------------------------------------------------------- # Parse the authority/update section. #-------------------------------------------------------------- if debug then print "\n" section = (packet.header.opcode == "UPDATE") ? "UPDATE" : "AUTHORITY" print ";; #{section} SECTION (#{packet.header.nscount} record#{packet.header.nscount == 1 ? '' : 's'})\n" end packet. = [] packet.header.nscount.times { rrobj = nil (rrobj, offset) = parse_rr(data, offset) # raise ArgumentError, "authority section incomplete" if rrobj == nil if (rrobj==nil) if (packet.header.tc==1) return packet else return nil end end packet.push("authority", rrobj) print rrobj.inspect + "\n" if debug } #-------------------------------------------------------------- # Parse the additional section. #-------------------------------------------------------------- if debug then print "\n"; print ";; ADDITIONAL SECTION (#{packet.header.adcount} record#{packet.header.adcount == 1 ? '' : 's'})\n"; end packet.additional = []; packet.header.arcount.times { rrobj=nil (rrobj, offset) = parse_rr(data, offset) raise ArgumentError, "additional section incomplete" if rrobj == nil if (rrobj==nil) if (packet.header.tc==1) return packet else return nil end end packet.push("additional", rrobj); print rrobj.inspect + "\n" if debug } packet.header= Net::DNS::Header.new(data) return packet end |
.new_from_values(qName, qType = "A", qClass = "IN") ⇒ Object
packet = Net::DNS::Packet.new_from_values(“example.com”)
packet = Net::DNS::Packet.new_from_values("example.com", "MX", "IN")
If passed a domain, type, and class, new creates a packet object appropriate for making a DNS query for the requested information. The type and class can be omitted; they default to A and IN.
286 287 288 289 290 291 |
# File 'lib/Net/DNS/Packet.rb', line 286 def Packet.new_from_values(qName, qType="A", qClass="IN") packet = Packet.new packet.header.qdcount=(1) packet.question = [ Net::DNS::Question.new(qName, qType, qClass) ] return packet end |
.parse_question(data, offset) ⇒ Object
–
parse_question
queryobj, newoffset = parse_question(data, offset)
Parses a question section record contained at a particular location within a DNS packet. The first argument is a reference to the packet data. The second argument is the offset within the packet where the question record begins.
Returns a Net::DNS::Question object and the offset of the next location in the packet.
Returns nil, nil if the question object couldn’t be created (e.g., if there isn’t enough data).
744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 |
# File 'lib/Net/DNS/Packet.rb', line 744 def Packet.parse_question(data, offset) qname, offset = (data, offset); return nil, nil unless qname!=nil; if data.length < (offset + 2 * Net::DNS::INT16SZ) return nil, nil end qtype, qclass = data.unpack("\@#{offset} n2"); offset += 2 * Net::DNS::INT16SZ; qtype = Net::DNS::typesbyval(qtype); qclass = Net::DNS::classesbyval(qclass); return Net::DNS::Question.new(qname, qtype, qclass), offset; end |
.parse_rr(data, offset) ⇒ Object
–
parse_rr
rrobj, newoffset = parse_rr(data, offset)
Parses a DNS resource record (RR) contained at a particular location within a DNS packet. The first argument is a reference to a scalar containing the packet data. The second argument is the offset within the data where the RR is located.
Returns a Net::DNS::RR object and the offset of the next location in the packet.
775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 |
# File 'lib/Net/DNS/Packet.rb', line 775 def Packet.parse_rr(data, offset) name, offset = (data, offset); return nil, nil unless name!=nil; if data.length < (offset + Net::DNS::RRFIXEDSZ) return nil, nil end type, klass, ttl, rdlength = data.unpack("\@#{offset} n2 N n"); type = Net::DNS::typesbyval(type) || type; # Special case for OPT RR where CLASS should be interperted as 16 bit # unsigned 2671 sec 4.3 if (type != "OPT") klass = Net::DNS::classesbyval(klass) || klass; end # else just keep at its numerical value offset += Net::DNS::RRFIXEDSZ; if data.length < (offset + rdlength) return nil, nil end rrobj = Net::DNS::RR.create(name, type, klass, ttl, rdlength, data, offset) return nil, nil unless rrobj!=nil; offset += rdlength; return rrobj, offset; end |
.sign_sig0(*args) ⇒ Object
SIG0 support is provided through the Net::DNS::RR::SIG class. This class is not part of the default Net::DNS distribution but resides in the Net::DNS::SEC distribution.
update = Net::DNS::Update.new("example.com")
update.push("update", rr_add("foo.example.com A 10.1.2.3"))
update.sign_sig0("Kexample.com+003+25317.private")
SIG0 support is experimental see Net::DNS::RR::SIG for details.
The method will raise a RuntimeError if Net::DNS::RR::SIG cannot be found.
701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 |
# File 'lib/Net/DNS/Packet.rb', line 701 def Packet.sign_sig0(*args) raise RuntimeError, 'The sign_sig0() method is only available when the Net::DNS::SEC package is installed.' unless Net::DNS::DNSSEC; # @TODO implement this!!! # if (@_ == 1 && ref($_[0])) { # if (UNIVERSAL::isa($_[0],"Net::DNS::RR::SIG::Private")) { # Carp::carp('Net::DNS::RR::SIG::Private is deprecated use Net::DNS::SEC::Private instead'); # $sig0 = Net::DNS::RR::SIG->create('', $_[0]) if $_[0]; # # } elsif (UNIVERSAL::isa($_[0],"Net::DNS::SEC::Private")) { # $sig0 = Net::DNS::RR::SIG->create('', $_[0]) if $_[0]; # # } elsif (UNIVERSAL::isa($_[0],"Net::DNS::RR::SIG")) { # $sig0 = $_[0]; # } else { # Carp::croak('You are passing an incompatible class as argument to sign_sig0: ' . ref($_[0])); # } # elsif (@_ == 1 && ! ref($_[0])) # my $key_name = $_[0]; # $sig0 = Net::DNS::RR::SIG->create('', $key_name) if $key_name # end # # $self->push('additional', $sig0) if $sig0; # return $sig0; end |
Instance Method Details
#data ⇒ Object
data
data = packet.data
Returns the packet data in binary format, suitable for sending to a nameserver.
299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 |
# File 'lib/Net/DNS/Packet.rb', line 299 def data #---------------------------------------------------------------------- # Flush the cache of already-compressed names. This should fix the bug # that caused this method to work only the first time it was called. #---------------------------------------------------------------------- @compnames = Hash.new() #---------------------------------------------------------------------- # Get the data for each section in the packet. #---------------------------------------------------------------------- # Note that EDNS OPT RR data should inly be appended to the additional # section of the packet. TODO: Packet is dropped silently if is tried to # have it appended to one of the other section # Collect the data first, and count the number of records along # the way. ( see rt.cpan.org: Ticket #8608 ) qdcount = 0 ancount = 0 nscount = 0 arcount = 0 # Note that the only pieces we;ll fill in later have predefined # length. headerlength=@header.data.length data = @header.data # foreach my $question (@{$self->{"question"}}) { @question.each { |question| offset = data.length data = data + question.data(self, offset) qdcount = qdcount + 1 } # foreach my $rr (@{$self->{"answer"}}) { @answer.each { |rr| offset = data.length data = data + rr.data(self, offset) ancount = ancount + 1 } # foreach my $rr (@{$self->{"authority"}}) { @authority.each { |rr| offset = data.length data = data + rr.data(self, offset) nscount = nscount + 1 } # foreach my $rr (@{$self->{"additional"}}) { @additional.each { |rr| offset = data.length data = data + rr.data(self, offset); arcount = arcount + 1; } # Fix up the header so the counts are correct. This overwrites # the user's settings, but the user should know what they are doing. @header.qdcount=( qdcount ); @header.ancount=( ancount ); @header.nscount=( nscount ); @header.arcount=( arcount ); # Replace the orginal header with corrected counts. return @header.data + data[headerlength, data.length-headerlength]; end |
#dn_comp(name, offset) ⇒ Object
compname = packet.dn_comp(“foo.example.com”, $offset)
Returns a domain name compressed for a particular packet object, to be stored beginning at the given offset within the packet data. The name will be added to a running list of compressed domain names for future use.
537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 |
# File 'lib/Net/DNS/Packet.rb', line 537 def dn_comp(name, offset) # should keep track of compressed names FOR THIS PACKET # If we see one already used, then we can add in the offset for that name # So, we need to store the offset in compnames name="" if name==nil compname=""; names=Net::DNS::name2labels(name); if ((names.length == 1 && names[0]=="")) names=[] else while (!names.empty?) dname = names.join("."); if (@compnames.has_key?(dname)) pointer = @compnames[dname]; # $compname .= pack("n", 0xc000 | $pointer); compname = compname + [(0xc000 | pointer)].pack("n"); break; end @compnames[dname] = offset; first = names.shift length = first.length; # croak "length of $first is larger than 63 octets" if $length>63; raise RuntimeError, "length of #{first} is larger than 63 octets" if length > 63 compname = compname + [length, first].pack("C a*"); offset = offset + length + 1; end end if names.empty? compname = compname + [0].pack("C") end return compname; end |
#each_address ⇒ Object
Iterators
809 810 811 812 813 814 |
# File 'lib/Net/DNS/Packet.rb', line 809 def each_address @answer.each do |elem| next unless elem.class == Net::DNS::RR::A yield elem.address end end |
#each_cname ⇒ Object
827 828 829 830 831 832 |
# File 'lib/Net/DNS/Packet.rb', line 827 def each_cname @answer.each do |elem| next unless elem.class == Net::DNS::RR::CNAME yield elem.cname end end |
#each_mx ⇒ Object
821 822 823 824 825 826 |
# File 'lib/Net/DNS/Packet.rb', line 821 def each_mx @answer.each do |elem| next unless elem.class == Net::DNS::RR::MX yield elem.preference,elem.exchange end end |
#each_nameserver ⇒ Object
815 816 817 818 819 820 |
# File 'lib/Net/DNS/Packet.rb', line 815 def each_nameserver @answer.each do |elem| next unless elem.class == Net::DNS::RR::NS yield elem.nsdname end end |
#each_ptr ⇒ Object
833 834 835 836 837 838 |
# File 'lib/Net/DNS/Packet.rb', line 833 def each_ptr @answer.each do |elem| next unless elem.class == Net::DNS::RR::PTR yield elem.ptrdname end end |
#inspect ⇒ Object
print packet.inspect
Returns a string representation of the packet.
373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 |
# File 'lib/Net/DNS/Packet.rb', line 373 def inspect retval = ""; if (@answerfrom != nil && @answerfrom != "") retval = retval + ";; Answer received from #{@answerfrom} (#{@answersize} bytes)\n;;\n"; end retval = retval + ";; HEADER SECTION\n"; retval = retval + @header.inspect; retval = retval + "\n"; section = (@header.opcode == "UPDATE") ? "ZONE" : "QUESTION"; retval = retval + ";; #{section} SECTION (#{@header.qdcount} record#{@header.qdcount == 1 ? '' : 's'})\n"; question.each { |qr| retval = retval + ";; #{qr.inspect}\n"; } retval = retval + "\n"; section = (@header.opcode == "UPDATE") ? "PREREQUISITE" : "ANSWER"; retval = retval + ";; #{section} SECTION (#{@header.ancount} record#{@header.ancount == 1 ? '' : 's'})\n"; @answer.each { |rr| retval = retval + rr.inspect + "\n"; } retval = retval + "\n"; section = (@header.opcode == "UPDATE") ? "UPDATE" : "AUTHORITY"; retval = retval + ";; #{section} SECTION (#{@header.nscount} record#{@header.nscount == 1 ? '' : 's'})\n"; @authority.each { |rr| retval = retval + rr.inspect + "\n"; } retval = retval + "\n"; retval = retval + ";; ADDITIONAL SECTION (#{@header.arcount} record#{@header.arcount == 1 ? '' : 's'})\n"; @additional.each { |rr| retval = retval + rr.inspect + "\n"; } return retval; end |
#pop(section) ⇒ Object
rr = packet.pop(“pre”)
rr = packet.pop("update")
rr = packet.pop("additional")
rr = packet.pop("question")
Removes RRs from the specified section of the packet.
492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 |
# File 'lib/Net/DNS/Packet.rb', line 492 def pop(section) return unless section section = section.to_s.downcase if ((section == "prerequisite") || (section == "prereq")) section = "pre"; end if (section == "answer" || section == "pre") ancount = @header.ancount; if (ancount) rr = @answer.pop; @header.ancount=(ancount - 1); end elsif (section == "authority" || section == "update") nscount = @header.nscount; if (nscount) rr = @authority.pop; @header.nscount=(nscount - 1); end elsif (section == "additional") adcount = @header.adcount; if (adcount) rr = @additional.pop; @header.adcount=(adcount - 1); end elsif (section == "question") qdcount = @header.qdcount; if (qdcount) rr = @question.pop; @header.qdcount=(qdcount - 1); end else raise ArgumentError, "Invalid section #{section}" end return rr; end |
#push(insection, rr) ⇒ Object
packet.push(“pre”, rr)
packet.push("update", rr)
packet.push("additional", rr)
packet.push("update", rr1, rr2, rr3)
packet.push("update", rr)
Adds RRs to the specified section of the packet.
421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 |
# File 'lib/Net/DNS/Packet.rb', line 421 def push(insection, rr) return if (insection == nil) section = insection.to_s.downcase if ((section == "prerequisite") || (section == "prereq")) section = "pre"; end if !rr.instance_of?Array rr = [rr] end if ((@header.opcode == "UPDATE") && ((section == "pre") || (section == "update")) ) zone_class = zone()[0].zclass rr.each { |r_rec| r_rec.rrclass=(zone_class) unless (r_rec.rrclass == "NONE" || r_rec.rrclass == "ANY") } end if (section == "answer" || section == "pre") # @answer.push(rr); @answer += rr ancount = @header.ancount; @header.ancount=(ancount + 1); # rr); elsif (section == "authority" || section == "update") # @authority.push(rr); @authority += rr nscount = @header.nscount; @header.nscount=(nscount + 1); # rr); elsif (section == "additional") # @additional.push(rr); @additional+=rr adcount = @header.adcount; @header.adcount=(adcount + 1); # rr); elsif (section == "question") # @question.push(rr); @question += rr qdcount = @header.qdcount; @header.qdcount=(qdcount + 1); # rr); else # Carp::carp(qq(invalid section "$section"\n)); return; end end |
#sign_tsig(*args) ⇒ Object
key_name = “tsig-key”
key = "awwLOtRfpGE+rRKF2+DEiw=="
update = Net::DNS::Update.new("example.com")
update.push("update", rr_add("foo.example.com A 10.1.2.3"))
update.sign_tsig(key_name, key)
response = res.send(update)
Signs a packet with a TSIG resource record (see RFC 2845). Uses the following defaults:
algorithm = HMAC-MD5.SIG-ALG.REG.INT
time_signed = current time
fudge = 300 seconds
If you wish to customize the TSIG record, you’ll have to create it yourself and call the appropriate Net::DNS::RR::TSIG methods. The following example creates a TSIG record and sets the fudge to 60 seconds:
key_name = "tsig-key"
key = "awwLOtRfpGE+rRKF2+DEiw=="
tsig = Net::DNS::RR.new("#{key_name} TSIG #{key}")
tsig.fudge(60)
query = Net::DNS::Packet.new("www.example.com")
query.sign_tsig(tsig)
response = res.send(query)
You shouldn’t modify a packet after signing it; otherwise authentication will probably fail.
674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 |
# File 'lib/Net/DNS/Packet.rb', line 674 def sign_tsig(*args) # if (@_ == 1 && ref($_[0])) { if (args.length == 1) tsig = args[0]; # elsif (@_ == 2) { else key_name, key = args; if ((key_name!=nil) && (key!=nil)) tsig = Net::DNS::RR.new_from_string("#{key_name} TSIG #{key}") end end push("additional", tsig) if tsig; return tsig; end |
#unique_push(section, rrs) ⇒ Object
packet.unique_push(“pre” => rr)
packet.unique_push("update" => rr)
packet.unique_push("additional" => rr)
packet.unique_push("update" => rr1, rr2, rr3)
packet.unique_push("update" => rr)
Adds RRs to the specified section of the packet provided that the RRs do not already exist in the packet.
474 475 476 477 478 479 480 481 482 483 484 |
# File 'lib/Net/DNS/Packet.rb', line 474 def unique_push(section, rrs) rrs.each { |rr| # next if $self->{'seen'}->{rr.string}++; if @seen[rr.inspect] != nil @seen[rr.inspect] = @seen[rr.inspect] + 1 else push(section, rr); @seen[rr.inspect] = 1 end } end |