Module: Net::DNS::Names

Included in:
Packet, Question, RR
Defined in:
lib/net/dns/names/names.rb

Overview

:nodoc: all

Constant Summary collapse

INT16SZ =
2

Instance Method Summary collapse

Instance Method Details

#dn_comp(name, offset, compnames) ⇒ Object



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'lib/net/dns/names/names.rb', line 74

def dn_comp(name,offset,compnames)
  names = {}
  ptr = 0
  str = ""
  arr = names_array(name)
  arr.each do |entry|
    if compnames.has_key?(entry)
      ptr = 0xC000 | compnames[entry]
      str += [ptr].pack("n")
      offset += INT16SZ
      break
    else
      len = entry.unpack("C")[0]
      elem = entry[1..len]
      str += [len,elem].pack("Ca*")
      names.update({"#{entry}" => offset})
      offset += len
    end
  end
  return str,offset,names
end

#dn_expand(packet, offset) ⇒ Object

Expand a compressed name in a DNS Packet object. Please see RFC1025 for an explanation of how the compression in DNS packets works, how may it be useful and how should be handled.

This method accept two parameters: a raw packet data and an offset, which indicates the point in the packet in which the parsing has arrived.



17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/net/dns/names/names.rb', line 17

def dn_expand(packet,offset)
  name = ""
  packetlen = packet.size
  while true
    raise ExpandError, "offset is greater than packet lenght!" if packetlen < (offset+1)
    len = packet.unpack("@#{offset} C")[0]
    
    if len == 0
      offset += 1
      break
    elsif (len & 0xC0) == 0xC0
      raise ExpandError, "Packet ended before offset expand" if packetlen < (offset+INT16SZ)
      ptr = packet.unpack("@#{offset} n")[0]
      ptr &= 0x3FFF
      name2 = dn_expand(packet,ptr)[0]
      raise ExpandError, "Packet is malformed!" if name2 == nil
      name += name2
      offset += INT16SZ
      break
    else
      offset += 1
      raise ExpandError, "No expansion found" if packetlen < (offset+len)
      elem = packet[offset..offset+len-1]
      name += "#{elem}."
      offset += len
    end
  end
  return [name,offset] # name.chomp(".") if trailing dot has to be omitted
end

#names_array(name) ⇒ Object



60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/net/dns/names/names.rb', line 60

def names_array(name)
  arr = name.split(".")
  ar = []
  string = ""
  arr.size.times do |i|
    x = i+1
    elem = arr[-x]
    len = elem.size
    string = ((string.reverse)+([len,elem].pack("Ca*")).reverse).reverse
    ar.unshift(string)
  end
  return ar
end

#pack_name(name) ⇒ Object



47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/net/dns/names/names.rb', line 47

def pack_name(name)
  if name.size > 63
    raise ArgumentError, "Label data cannot exceed 63 chars"
  end
  arr = name.split(".")
  str = ""
  arr.each do |elem|
    str += [elem.size,elem].pack("Ca*")
  end
  str += [0].pack("C")
  str
end

#valid?(name) ⇒ Boolean

Returns:

  • (Boolean)


96
97
98
99
100
101
102
# File 'lib/net/dns/names/names.rb', line 96

def valid?(name)
  if name =~ /^([a-z0-9]([-a-z0-9]*[a-z0-9])?\.)+((a[cdefgilmnoqrstuwxz]|aero|arpa)|(b[abdefghijmnorstvwyz]|biz)|(c[acdfghiklmnorsuvxyz]|cat|com|coop)|d[ejkmoz]|(e[ceghrstu]|edu)|f[ijkmor]|(g[abdefghilmnpqrstuwy]|gov)|h[kmnrtu]|(i[delmnoqrst]|info|int)|(j[emop]|jobs)|k[eghimnprwyz]|l[abcikrstuvy]|(m[acdghklmnopqrstuvwxyz]|mil|mobi|museum)|(n[acefgilopruz]|name|net)|(om|org)|(p[aefghklmnrstwy]|pro)|qa|r[eouw]|s[abcdeghijklmnortvyz]|(t[cdfghjklmnoprtvwz]|travel)|u[agkmsyz]|v[aceginu]|w[fs]|y[etu]|z[amw])$/i
    return name
  else
    raise ArgumentError, "Invalid FQDN: #{name}"
  end
end