Module | Racket::L3::Misc |
In: |
lib/racket/l3/misc.rb
(CVS)
|
Miscelaneous L3 helper methods
Calculate the checksum. 16 bit one‘s complement of the one‘s complement sum of all 16 bit words
# File lib/racket/l3/misc.rb, line 144 def Misc.checksum(data) num_shorts = data.length / 2 checksum = 0 count = data.length data.unpack("S#{num_shorts}").each { |x| checksum += x count -= 2 } if (count == 1) checksum += data[data.length - 1] end checksum = (checksum >> 16) + (checksum & 0xffff) checksum = ~((checksum >> 16) + checksum) & 0xffff ([checksum].pack("S*")).unpack("n*")[0] end
Compress an IPv6 address Inspired by Daniele Bellucci and jacked from ipaddr
# File lib/racket/l3/misc.rb, line 75 def Misc.compressipv6(ipv6) ipv6.gsub!(/\b0{1,3}([\da-f]+)\b/i, '\1') loop do break if ipv6.sub!(/\A0:0:0:0:0:0:0:0\Z/, '::') break if ipv6.sub!(/\b0:0:0:0:0:0:0\b/, ':') break if ipv6.sub!(/\b0:0:0:0:0:0\b/, ':') break if ipv6.sub!(/\b0:0:0:0:0\b/, ':') break if ipv6.sub!(/\b0:0:0:0\b/, ':') break if ipv6.sub!(/\b0:0:0\b/, ':') break if ipv6.sub!(/\b0:0\b/, ':') break end ipv6.sub!(/:{3,}/, '::') if /\A::(ffff:)?([\da-f]{1,4}):([\da-f]{1,4})\Z/i =~ ipv6 ipv6 = sprintf('::%s%d.%d.%d.%d', $1, $2.hex / 256, $2.hex % 256, $3.hex / 256, $3.hex % 256) end ipv6 end
Compute link local address for a given mac address From Daniele Bellucci
# File lib/racket/l3/misc.rb, line 50 def Misc.linklocaladdr(mac) mac = mac.split(":") mac[0] = (mac[0].to_i(16) ^ (1 << 1)).to_s(16) ["fe80", "", mac[0,2].join, mac[2,2].join("ff:fe"), mac[4,2].join].join(":") end
Given a long, convert it to an IPv6 address, optionally compressing the address returned
# File lib/racket/l3/misc.rb, line 58 def Misc.long2ipv6(long, compress=true) ipv6 = [] ipv6[0] = long >> 112 ipv6[1] = (long >> 96) & (0xFFFF) ipv6[2] = (long >> 80) & (0xFFFF) ipv6[3] = (long >> 64) & (0xFFFF) ipv6[4] = (long >> 48) & (0xFFFF) ipv6[5] = (long >> 32) & (0xFFFF) ipv6[6] = (long >> 16) & (0xFFFF) ipv6[7] = long & (0xFFFF) ipv6 = ipv6.map { |o| o.to_s(16) }.join(":") compress ? Misc.compressipv6(ipv6) : ipv6 end
In addition to the regular multicast addresses, each unicast address has a special multicast address called its solicited-node address. This address is created through a special mapping from the device’s unicast address. Solicited-node addresses are used by the IPv6 Neighbor Discovery (ND) protocol to provide more efficient address resolution than the ARP technique used in IPv4. From Daniele Bellucci
# File lib/racket/l3/misc.rb, line 114 def Misc.soll_mcast_addr6(addr) h = addr.split(':')[-2, 2] m = [] m << 'ff' m << (h[0].to_i(16) & 0xff).to_s(16) m << ((h[1].to_i(16) & (0xff << 8)) >> 8).to_s(16) m << (h[1].to_i(16) & 0xff).to_s(16) 'ff02::1:' + [m[0,2].join, m[2,2].join].join(':') end