Upgrade the bundled Racket to version 1.0.7
git-svn-id: file:///home/svn/framework3/trunk@8003 4d416f70-5f16-0410-b530-b9f4589650daunstable
parent
5ac485eb48
commit
bb84e76e40
|
@ -24,10 +24,7 @@
|
|||
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
require 'racket/l2/ethernet'
|
||||
require 'racket/l2/llc'
|
||||
require 'racket/l2/snap'
|
||||
require 'racket/l2/vlan'
|
||||
require 'racket/l2/eightotwodotthree'
|
||||
|
||||
Dir.glob(File.join(File.dirname(__FILE__), 'l2/*.rb')).each { |f| require f }
|
||||
|
||||
# vim: set ts=2 et sw=2:
|
||||
|
|
|
@ -25,8 +25,9 @@
|
|||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# 802.3 Ethernet. Should always be followed by an LLC header
|
||||
module Racket
|
||||
module L2
|
||||
# 802.3 Ethernet. Should always be followed by an LLC header
|
||||
class EightOTwoDotThree < RacketPart
|
||||
# Destination MAC address
|
||||
hex_octets :dst_mac, 48
|
||||
|
@ -43,4 +44,5 @@ class EightOTwoDotThree < RacketPart
|
|||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
# vim: set ts=2 et sw=2:
|
||||
|
|
|
@ -25,10 +25,11 @@
|
|||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
module Racket
|
||||
module L2
|
||||
# Ethernet II (DIX v2.0)
|
||||
#
|
||||
# http://en.wikipedia.org/wiki/Ethernet_II_framing
|
||||
module Racket
|
||||
class Ethernet < RacketPart
|
||||
ETHERTYPE_IPV4 = 0x0800
|
||||
ETHERTYPE_ARP = 0x0806
|
||||
|
@ -57,4 +58,5 @@ class Ethernet < RacketPart
|
|||
rest :payload
|
||||
end
|
||||
end
|
||||
end
|
||||
#set ts=2 et sw=2: vim
|
||||
|
|
|
@ -25,8 +25,9 @@
|
|||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# Logical Link Control (http://en.wikipedia.org/wiki/Logical_Link_Control)
|
||||
module Racket
|
||||
module L2
|
||||
# Logical Link Control (http://en.wikipedia.org/wiki/Logical_Link_Control)
|
||||
class LLC < RacketPart
|
||||
LLC_IBM_SNA = 0x04
|
||||
LLC_IP = 0x06
|
||||
|
@ -45,4 +46,5 @@ class LLC < RacketPart
|
|||
rest :payload
|
||||
end
|
||||
end
|
||||
end
|
||||
# vim: set ts=2 et sw=2:
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
# $Id: misc.rb 142 2009-12-13 01:53:14Z jhart $
|
||||
#
|
||||
# Copyright (c) 2008, Jon Hart
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# * Neither the name of the <organization> nor the
|
||||
# names of its contributors may be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY Jon Hart ``AS IS'' AND ANY
|
||||
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL Jon Hart BE LIABLE FOR ANY
|
||||
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
module Racket
|
||||
module L2
|
||||
# Miscelaneous L2 helper methods
|
||||
module Misc
|
||||
|
||||
# given a string representing a MAC address, return the
|
||||
# human readable form
|
||||
def Misc.string2mac(string)
|
||||
string.unpack("C*").map { |i| i.to_s(16).ljust(2,"0") }.join(":")
|
||||
end
|
||||
|
||||
# given a MAC address, return the string representation
|
||||
def Misc.mac2string(mac)
|
||||
mac.split(":").map { |i| i.hex.chr }.join
|
||||
end
|
||||
|
||||
# given a MAC address, return the long representation
|
||||
def Misc.mac2long(addr)
|
||||
long = 0
|
||||
addr.split(':').map { |s| s.to_i(16) }.each do |o|
|
||||
long = (long << 8) ^ o
|
||||
end
|
||||
long
|
||||
end
|
||||
|
||||
# given a long representing a MAC address
|
||||
# print it out in human readable form of a given length,
|
||||
# defaulting to 6 (ethernet)
|
||||
def Misc.long2mac(long, len=6)
|
||||
long.to_s(16).rjust(len*2, '0').unpack("a2"*len).join(":")
|
||||
end
|
||||
|
||||
# Return a random MAC, defaults to 6 bytes (ethernet)
|
||||
def Misc.randommac(len=6)
|
||||
long2mac(rand(2**(8*len)), len)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
# vim: set ts=2 et sw=2:
|
|
@ -25,8 +25,9 @@
|
|||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# Subnetwork Access Protocl (http://en.wikipedia.org/wiki/Subnetwork_Access_Protocol)
|
||||
module Racket
|
||||
module L2
|
||||
# Subnetwork Access Protocl (http://en.wikipedia.org/wiki/Subnetwork_Access_Protocol)
|
||||
class SNAP < RacketPart
|
||||
# Organizational code
|
||||
unsigned :org, 24, { :default => 0x00000c }
|
||||
|
@ -35,4 +36,5 @@ class SNAP < RacketPart
|
|||
rest :payload
|
||||
end
|
||||
end
|
||||
end
|
||||
# vim: set ts=2 et sw=2:
|
||||
|
|
|
@ -25,8 +25,9 @@
|
|||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# IEEE 802.1Q VLAN tag (http://en.wikipedia.org/wiki/IEEE_802.1Q)
|
||||
module Racket
|
||||
module L2
|
||||
# IEEE 802.1Q VLAN tag (http://en.wikipedia.org/wiki/IEEE_802.1Q)
|
||||
class VLAN < RacketPart
|
||||
ETHERTYPE_IPV4 = 0x0800
|
||||
ETHERTYPE_ARP = 0x0806
|
||||
|
@ -45,7 +46,9 @@ class VLAN < RacketPart
|
|||
ETHERTYPE_ATAOE = 0x88A2
|
||||
ETHERTYPE_8021AE = 0x88E5
|
||||
|
||||
# Frame priority level
|
||||
unsigned :priority, 3
|
||||
# Canonical format indicator
|
||||
unsigned :cfi, 1
|
||||
# VLAN ID
|
||||
unsigned :id, 12
|
||||
|
@ -54,4 +57,5 @@ class VLAN < RacketPart
|
|||
rest :payload
|
||||
end
|
||||
end
|
||||
end
|
||||
# vim: set ts=2 et sw=2:
|
||||
|
|
|
@ -0,0 +1,124 @@
|
|||
# $Id: vtp.rb 127 2009-11-29 01:30:46Z jhart $
|
||||
#
|
||||
# Copyright (c) 2008, Jon Hart
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# * Neither the name of the <organization> nor the
|
||||
# names of its contributors may be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY Jon Hart ``AS IS'' AND ANY
|
||||
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL Jon Hart BE LIABLE FOR ANY
|
||||
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
module Racket
|
||||
module L2
|
||||
# VLAN Trunking Protocol (VTP)
|
||||
# http://en.wikipedia.org/wiki/VLAN_Trunking_Protocol
|
||||
# http://www.cisco.com/en/US/tech/tk389/tk689/technologies_tech_note09186a0080094c52.shtml
|
||||
# This is just a base class from which all VTP messages inherit and should never be used directly
|
||||
class VTPGeneric < RacketPart
|
||||
# VTP version (1-3)
|
||||
unsigned :version, 8
|
||||
# Message code (summary advertisement, subset advertisement, advertisement request, VTP join)
|
||||
unsigned :code, 8
|
||||
# Sometimes used, sometimes not, depends on the type
|
||||
unsigned :reserved, 8
|
||||
# Length of the management domain
|
||||
unsigned :domain_length, 8
|
||||
# management domain name, zero padded to 32 bytes
|
||||
text :domain, 256
|
||||
|
||||
# Adjust +domain_length+ and +domain+ accordingly prior to sending
|
||||
def fix!
|
||||
self.domain_length = self.domain.length
|
||||
self.domain = self.domain.ljust(32, "\x00")
|
||||
end
|
||||
end
|
||||
|
||||
# A raw VTP message
|
||||
class VTPRaw < VTPGeneric
|
||||
rest :payload
|
||||
end
|
||||
|
||||
class VTPSubsetAdvertisement < VTPGeneric
|
||||
# Configuration revision
|
||||
unsigned :revision, 32
|
||||
# all of the vlan info fields
|
||||
rest :payload
|
||||
|
||||
def add_vlan_info(status, type, id, mtu, index, name)
|
||||
name_length = name.length
|
||||
# zero pad name to a multiple of 4 bytes
|
||||
name = name.length % 4 == 0 ? name : name.ljust(name.length + (4 - (name.length % 4)), "\x00")
|
||||
length = 12 + name.length
|
||||
@vlan_info << [length, status, type, name_length, id, mtu, index, name]
|
||||
end
|
||||
|
||||
def fix!
|
||||
@vlan_info.each do |v|
|
||||
self.payload += v.pack("CCCCnnNa*")
|
||||
end
|
||||
super
|
||||
end
|
||||
|
||||
def initialize(*args)
|
||||
@vlan_info = []
|
||||
super(*args)
|
||||
self.code = 2
|
||||
end
|
||||
end
|
||||
|
||||
class VTPSummaryAdvertisement < VTPGeneric
|
||||
# Configuration revision number
|
||||
unsigned :revision, 32
|
||||
# Updater identity (IP)
|
||||
octets :updater, 32
|
||||
# update timestamp
|
||||
unsigned :timestamp, 96
|
||||
# MD5 digest of VTP password
|
||||
text :md5, 128
|
||||
rest :payload
|
||||
|
||||
def initialize(*args)
|
||||
super(*args)
|
||||
self.code = 1
|
||||
end
|
||||
end
|
||||
|
||||
class VTPAdvertisementRequest < VTPGeneric
|
||||
# This is used in cases in which there are several subset advertisements. If the first (n) subset advertisement has been received and the subsequent one (n+1) has not been received, the Catalyst only requests advertisements from the (n+1)th one.
|
||||
unsigned :start, 32
|
||||
rest :payload
|
||||
def initialize(*args)
|
||||
super(*args)
|
||||
self.code = 3
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
class VTPJoin < VTPGeneric
|
||||
def initialize(*args)
|
||||
super(*args)
|
||||
self.code = 4
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
# vim: set ts=2 et sw=2:
|
|
@ -24,11 +24,7 @@
|
|||
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
require 'racket/l3/ipv4'
|
||||
require 'racket/l3/ipv6'
|
||||
require 'racket/l3/arp'
|
||||
require 'racket/l3/stp'
|
||||
require 'racket/l3/cdp'
|
||||
require 'racket/l3/misc'
|
||||
|
||||
Dir.glob(File.join(File.dirname(__FILE__), 'l3/*.rb')).each { |f| require f }
|
||||
|
||||
# vim: set ts=2 et sw=2:
|
||||
|
|
|
@ -25,10 +25,10 @@
|
|||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# Address Resolution Protocol: ARP
|
||||
#
|
||||
# RFC826 (http://www.faqs.org/rfcs/rfc826.html)
|
||||
module Racket
|
||||
module L3
|
||||
# Address Resolution Protocol: ARP
|
||||
# RFC826 (http://www.faqs.org/rfcs/rfc826.html)
|
||||
class ARP < RacketPart
|
||||
ARPOP_REQUEST = 0x0001
|
||||
ARPOP_REPLY = 0x0002
|
||||
|
@ -59,4 +59,5 @@ class ARP < RacketPart
|
|||
rest :payload
|
||||
end
|
||||
end
|
||||
end
|
||||
# vim: set ts=2 et sw=2:
|
||||
|
|
|
@ -25,54 +25,61 @@
|
|||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
module Racket
|
||||
module L3
|
||||
# CDP -- Cisco Discovery Protocol
|
||||
# http://www.cisco.biz/univercd/cc/td/doc/product/lan/trsrb/frames.htm#xtocid12
|
||||
module Racket
|
||||
class CDP < RacketPart
|
||||
# CDP Version (generally 1)
|
||||
unsigned :version, 8, { :default => 1 }
|
||||
# Time-to-live of the data in this message
|
||||
unsigned :ttl, 8
|
||||
# Checksum
|
||||
unsigned :csum, 16
|
||||
unsigned :checksum, 16
|
||||
# Payload of this CDP message. Generally untouched.
|
||||
rest :payload
|
||||
|
||||
|
||||
def initialize(*args)
|
||||
super(*args)
|
||||
end
|
||||
|
||||
# Add a new field to this CDP message.
|
||||
def add_field(type, value)# {{{
|
||||
t = TLV.new(2,2)
|
||||
def add_field(type, value)
|
||||
t = Racket::Misc::TLV.new(2,2)
|
||||
t.type = type
|
||||
t.value = value
|
||||
t.length = 4 + value.length
|
||||
self.payload += t.encode
|
||||
end# }}}
|
||||
end
|
||||
|
||||
# Check the checksum for this IP datagram
|
||||
def checksum?# {{{
|
||||
self.csum == compute_checksum
|
||||
end# }}}
|
||||
def checksum?
|
||||
self.checksum == compute_checksum
|
||||
end
|
||||
|
||||
# Compute and set the checksum for this IP datagram
|
||||
def checksum!# {{{
|
||||
self.csum = compute_checksum
|
||||
end# }}}
|
||||
def checksum!
|
||||
self.checksum = compute_checksum
|
||||
end
|
||||
|
||||
# Fix this CDP message up for sending.
|
||||
def fix!# {{{
|
||||
def fix!
|
||||
self.checksum!
|
||||
end# }}}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Compute the checksum for this IP datagram
|
||||
def compute_checksum# {{{
|
||||
def compute_checksum
|
||||
pseudo = []
|
||||
pseudo << ((self.version << 8) | self.ttl)
|
||||
pseudo << 0
|
||||
pseudo << self.payload
|
||||
L3::Misc.checksum(pseudo.pack("nna*"))
|
||||
end# }}}
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
# vim: set ts=2 et sw=2:
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
# $Id: egp.rb 127 2009-11-29 01:30:46Z jhart $
|
||||
#
|
||||
# Copyright (c) 2008, Jon Hart
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# * Neither the name of the <organization> nor the
|
||||
# names of its contributors may be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY Jon Hart ``AS IS'' AND ANY
|
||||
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL Jon Hart BE LIABLE FOR ANY
|
||||
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
module Racket
|
||||
module L3
|
||||
# Exterior Gateway protocol (EGP)
|
||||
# http://tools.ietf.org/html/rfc904
|
||||
# XXX: TODO, add support for tacking on the various message types
|
||||
class EGP < RacketPart
|
||||
# EGP version
|
||||
unsigned :version, 8
|
||||
# Message type
|
||||
unsigned :type, 8
|
||||
# Message code (subtype)
|
||||
unsigned :code, 8
|
||||
# Message dependent status information
|
||||
unsigned :status, 8
|
||||
# Checksum
|
||||
unsigned :checksum, 16
|
||||
# assigned number identifying the particular autonomous system
|
||||
unsigned :asn, 16
|
||||
# Sequence number
|
||||
unsigned :sequence, 16
|
||||
# Payload
|
||||
rest :payload
|
||||
end
|
||||
end
|
||||
end
|
||||
# vim: set ts=2 et sw=2:
|
|
@ -25,10 +25,11 @@
|
|||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
module Racket
|
||||
module L3
|
||||
# Internet Protcol Version 4 (IPV4)
|
||||
#
|
||||
# RFC791 (http://www.ietf.org/rfc/rfc791.txt)
|
||||
module Racket
|
||||
class IPv4 < RacketPart
|
||||
# Version (defaults to 4)
|
||||
unsigned :version, 4, { :default => 4 }
|
||||
|
@ -49,10 +50,12 @@ class IPv4 < RacketPart
|
|||
# Protocol
|
||||
unsigned :protocol, 8
|
||||
# Checksum
|
||||
unsigned :csum, 16, "Checksum"
|
||||
# Source IP address
|
||||
unsigned :checksum, 16, "Checksum"
|
||||
# Source IP address, passed as four octets separated by periods
|
||||
# (192.168.1.2)
|
||||
octets :src_ip, 32
|
||||
# Destination IP address
|
||||
# Destination IP address, passed as four octets separated by periods
|
||||
# (192.168.1.2)
|
||||
octets :dst_ip, 32
|
||||
# Payload
|
||||
rest :payload
|
||||
|
@ -66,7 +69,7 @@ class IPv4 < RacketPart
|
|||
# All rejiggering will happen when the call to fix!
|
||||
# happens automagically
|
||||
def add_option(number, value)
|
||||
t = TLV.new(1,1)
|
||||
t = Misc::TLV.new(1,1)
|
||||
t.type = number
|
||||
t.value = value
|
||||
t.length = value.length + 2
|
||||
|
@ -75,12 +78,12 @@ class IPv4 < RacketPart
|
|||
|
||||
# Check the checksum for this IP datagram
|
||||
def checksum?
|
||||
self.csum == compute_checksum
|
||||
self.checksum == compute_checksum
|
||||
end
|
||||
|
||||
# Compute and set the checksum for this IP datagram
|
||||
def checksum!
|
||||
self.csum = compute_checksum
|
||||
self.checksum = compute_checksum
|
||||
end
|
||||
|
||||
# Perform all the niceties necessary prior to sending
|
||||
|
@ -125,4 +128,5 @@ private
|
|||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
# vim: set ts=2 et sw=2:
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
# $Id: ipv6.rb 14 2008-03-02 05:42:30Z warchild $
|
||||
#
|
||||
# Copyright (c) 2008, Jon Hart
|
||||
# Copyright (c) 2008, Jon Hart
|
||||
# All rights reserved.
|
||||
#
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
|
@ -13,7 +13,7 @@
|
|||
# * Neither the name of the <organization> nor the
|
||||
# names of its contributors may be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY Jon Hart ``AS IS'' AND ANY
|
||||
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
|
@ -25,10 +25,10 @@
|
|||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
module Racket
|
||||
module L3
|
||||
# Internet Protocol Version 6 (IPV6)
|
||||
# RFC2460
|
||||
# XXX: not tested, incomplete.
|
||||
module Racket
|
||||
class IPv6 < RacketPart
|
||||
# IP Version (defaults to 6)
|
||||
unsigned :version, 4, { :default => 6 }
|
||||
|
@ -41,14 +41,26 @@ class IPv6 < RacketPart
|
|||
# Next header type
|
||||
unsigned :nhead, 8
|
||||
# Hop limit
|
||||
unsigned :ttl, 8
|
||||
# Source IP address
|
||||
unsigned :ttl, 8, { :default => 200 }
|
||||
# Source IP address. Must be passed as an integer
|
||||
unsigned :src_ip, 128
|
||||
# Destination IP address
|
||||
# Destination IP address. Must be passed as an integer
|
||||
unsigned :dst_ip, 128
|
||||
# Payload
|
||||
rest :payload
|
||||
|
||||
def initialize(*args)
|
||||
@headers = []
|
||||
super
|
||||
@autofix = true
|
||||
end
|
||||
|
||||
# Adjust plen to match the payload
|
||||
def fix!
|
||||
self.plen = self.payload.length
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
# vim: set ts=2 et sw=2:
|
||||
|
||||
|
|
|
@ -25,8 +25,10 @@
|
|||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
require 'ipaddr'
|
||||
module Racket
|
||||
module L3
|
||||
# Miscelaneous L3 helper methods
|
||||
module Misc
|
||||
# given an IPv4 address packed as an integer
|
||||
# return the friendly "dotted quad"
|
||||
|
@ -39,37 +41,123 @@ module L3
|
|||
quad.join(".")
|
||||
end
|
||||
|
||||
def Misc.long2ipv6(long)
|
||||
def Misc.randomipv4
|
||||
Misc.long2ipv4(rand(2**32))
|
||||
end
|
||||
|
||||
# Compute link local address for a given mac address
|
||||
# From Daniele Bellucci
|
||||
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
|
||||
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
|
||||
|
||||
# Compress an IPv6 address
|
||||
# Inspired by Daniele Bellucci and jacked from ipaddr
|
||||
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
|
||||
|
||||
def Misc.randomipv6
|
||||
Misc.long2ipv6(rand(2**128))
|
||||
end
|
||||
|
||||
# given a string representing an IPv6
|
||||
# address, return the integer representation
|
||||
def Misc.ipv62long(ip)
|
||||
IPAddr.new(ip).to_i
|
||||
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
|
||||
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
|
||||
|
||||
#
|
||||
def Misc.soll_mcast_mac(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)
|
||||
'33:33:' + m.join(':')
|
||||
end
|
||||
|
||||
|
||||
# given a "dotted quad" representing an IPv4
|
||||
# address, return the integer representation
|
||||
def Misc.ipv42long(ip)
|
||||
quad = ip.split(/\./)
|
||||
quad.collect! {|s| s.to_i}
|
||||
# XXX: replace this with an inject
|
||||
quad[3] + (256 * quad[2]) + ((256**2) * quad[1]) + ((256**3) * quad[0])
|
||||
IPAddr.new(ip).to_i
|
||||
end
|
||||
|
||||
# Calculate the checksum. 16 bit one's complement of the one's
|
||||
# complement sum of all 16 bit words
|
||||
def Misc.checksum(data)
|
||||
num_shorts = data.length / 2
|
||||
csum = 0
|
||||
checksum = 0
|
||||
count = data.length
|
||||
|
||||
data.unpack("S#{num_shorts}").each { |x|
|
||||
csum += x
|
||||
checksum += x
|
||||
count -= 2
|
||||
}
|
||||
|
||||
if (count == 1)
|
||||
csum += data[data.length - 1]
|
||||
checksum += data[data.length - 1]
|
||||
end
|
||||
|
||||
csum = (csum >> 16) + (csum & 0xffff)
|
||||
csum = ~((csum >> 16) + csum) & 0xffff
|
||||
([csum].pack("S*")).unpack("n*")[0]
|
||||
checksum = (checksum >> 16) + (checksum & 0xffff)
|
||||
checksum = ~((checksum >> 16) + checksum) & 0xffff
|
||||
([checksum].pack("S*")).unpack("n*")[0]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -25,10 +25,11 @@
|
|||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
module Racket
|
||||
module L3
|
||||
# Spanning Tree Protocol
|
||||
#
|
||||
# http://en.wikipedia.org/wiki/Spanning_tree_protocol
|
||||
module Racket
|
||||
class STP < RacketPart
|
||||
# Protocol identifier
|
||||
unsigned :protocol, 16, { :default => 0 }
|
||||
|
@ -76,4 +77,5 @@ class STP < RacketPart
|
|||
rest :payload
|
||||
end
|
||||
end
|
||||
end
|
||||
# vim: set ts=2 et sw=2:
|
||||
|
|
|
@ -24,13 +24,7 @@
|
|||
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
require 'racket/l4/igmpv1'
|
||||
require 'racket/l4/igmpv2'
|
||||
require 'racket/l4/igrp'
|
||||
require 'racket/l4/gre'
|
||||
require 'racket/l4/icmp'
|
||||
require 'racket/l4/tcp'
|
||||
require 'racket/l4/udp'
|
||||
|
||||
Dir.glob(File.join(File.dirname(__FILE__), 'l4/*.rb')).each { |f| require f }
|
||||
|
||||
# vim: set ts=2 et sw=2:
|
||||
|
|
|
@ -25,8 +25,9 @@
|
|||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# XXX: currently broken. all of the "optional" fields must be made dynamic
|
||||
module Racket
|
||||
module L4
|
||||
# XXX: currently broken. all of the "optional" fields must be made dynamic
|
||||
class GRE < RacketPart
|
||||
# Is a checksum present?
|
||||
unsigned :checksum_present, 1
|
||||
|
@ -60,4 +61,5 @@ class GRE < RacketPart
|
|||
rest :payload
|
||||
end
|
||||
end
|
||||
end
|
||||
# vim: set ts=2 et sw=2:
|
||||
|
|
|
@ -25,11 +25,14 @@
|
|||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
module Racket
|
||||
module L4
|
||||
# Internet Control Message Protcol.
|
||||
#
|
||||
# RFC792 (http://www.faqs.org/rfcs/rfc792.html)
|
||||
module Racket
|
||||
class ICMP < RacketPart
|
||||
#
|
||||
# Generic ICMP class from which all ICMP variants spawn. This should never be used directly.
|
||||
class ICMPGeneric < RacketPart
|
||||
ICMP_TYPE_ECHO_REPLY = 0
|
||||
ICMP_TYPE_DESTINATION_UNREACHABLE = 3
|
||||
ICMP_TYPE_SOURCE_QUENCH = 4
|
||||
|
@ -51,22 +54,23 @@ class ICMP < RacketPart
|
|||
# Code
|
||||
unsigned :code, 8
|
||||
# Checksum
|
||||
unsigned :csum, 16
|
||||
# ID
|
||||
unsigned :id, 16
|
||||
# Sequence number
|
||||
unsigned :seq, 16
|
||||
# Payload
|
||||
rest :payload
|
||||
unsigned :checksum, 16
|
||||
rest :message
|
||||
|
||||
# check the checksum for this ICMP packet
|
||||
def checksum?
|
||||
self.csum == compute_checksum
|
||||
self.checksum == compute_checksum
|
||||
end
|
||||
|
||||
def initialize(*args)
|
||||
super(*args)
|
||||
@autofix = false
|
||||
end
|
||||
|
||||
|
||||
# compute and set the checksum for this ICMP packet
|
||||
def checksum!
|
||||
self.csum = compute_checksum
|
||||
self.checksum = compute_checksum
|
||||
end
|
||||
|
||||
# 'fix' this ICMP packet up for sending.
|
||||
|
@ -78,9 +82,214 @@ class ICMP < RacketPart
|
|||
private
|
||||
def compute_checksum
|
||||
# pseudo header used for checksum calculation as per RFC 768
|
||||
pseudo = [ self.type, self.code, 0, self.id, self.seq, self.payload ]
|
||||
L3::Misc.checksum(pseudo.pack("CCnnna*"))
|
||||
pseudo = [ self.type, self.code, 0, self.message ]
|
||||
L3::Misc.checksum(pseudo.pack("CCna*"))
|
||||
end
|
||||
end
|
||||
|
||||
# Send raw ICMP packets of your own design
|
||||
class ICMP < ICMPGeneric
|
||||
rest :payload
|
||||
end
|
||||
|
||||
# ICMP Echo. Generic class that ICMPEchoRequest and ICMPEchoReply inherit
|
||||
class ICMPEcho < ICMPGeneric
|
||||
# ID for tracking requests/replies
|
||||
unsigned :id, 16
|
||||
# sequence number for tracking request/replies
|
||||
unsigned :sequence, 16
|
||||
rest :payload
|
||||
|
||||
def initialize(*args)
|
||||
super(*args)
|
||||
self.type = 8
|
||||
self.code = 0
|
||||
end
|
||||
end
|
||||
|
||||
# ICMP Echo Request
|
||||
class ICMPEchoRequest < ICMPEcho
|
||||
rest :payload
|
||||
|
||||
def initialize(*args)
|
||||
super(*args)
|
||||
self.type = 8
|
||||
self.code = 0
|
||||
end
|
||||
end
|
||||
|
||||
# ICMP Echo Reply
|
||||
class ICMPEchoReply < ICMPEcho
|
||||
rest :payload
|
||||
|
||||
def initialize(*args)
|
||||
super(*args)
|
||||
self.type = 0
|
||||
self.code = 0
|
||||
end
|
||||
end
|
||||
|
||||
# ICMP Destination Unreachable Message
|
||||
class ICMPDestinationUnreachable < ICMPGeneric
|
||||
ICMP_CODE_NETWORK_UNREACHABLE = 0
|
||||
ICMP_CODE_HOST_UNREACHABLE = 1
|
||||
ICMP_CODE_PROTOCOL_UNREACHABLE = 2
|
||||
ICMP_CODE_PORT_UNREACHABLE = 3
|
||||
ICMP_CODE_FRAG_NEEDED_DF_SET = 4
|
||||
ICMP_CODE_SOURCE_ROUTE_FAILED = 5
|
||||
# This is never used according to the RFC
|
||||
unsigned :unused, 32
|
||||
# Internet header + 64 bits of original datagram
|
||||
rest :payload
|
||||
|
||||
def initialize(*args)
|
||||
super(*args)
|
||||
self.type = 3
|
||||
end
|
||||
end
|
||||
|
||||
# ICMP Time Exceeded Message
|
||||
class ICMPTimeExceeded < ICMPGeneric
|
||||
ICMP_CODE_TTL_EXCEEDED_IN_TRANSIT = 0
|
||||
ICMP_CODE_FRAG_REASSEMBLY_TIME_EXCEEDED = 1
|
||||
# This is never used according to the RFC
|
||||
unsigned :unused, 32
|
||||
# Internet header + 64 bits of original datagram
|
||||
rest :payload
|
||||
|
||||
def initialize(*args)
|
||||
super(*args)
|
||||
self.type = 11
|
||||
end
|
||||
end
|
||||
|
||||
# ICMP Parameter Problem Message
|
||||
class ICMPParameterProblem < ICMPGeneric
|
||||
# pointer to the octet where the error was detected
|
||||
unsigned :pointer, 8
|
||||
# This is never used according to the RFC
|
||||
unsigned :unused, 24
|
||||
# Internet header + 64 bits of original datagram
|
||||
rest :payload
|
||||
|
||||
def initialize(*args)
|
||||
super(*args)
|
||||
self.type = 12
|
||||
self.code = 0
|
||||
end
|
||||
end
|
||||
|
||||
# ICMP Source Quench Message
|
||||
class ICMPSourceQuench < ICMPGeneric
|
||||
# This is never used according to the RFC
|
||||
unsigned :unused, 32
|
||||
# Internet header + 64 bits of original datagram
|
||||
rest :payload
|
||||
|
||||
def initialize(*args)
|
||||
super(*args)
|
||||
self.type = 4
|
||||
self.code = 0
|
||||
end
|
||||
end
|
||||
|
||||
# ICMP Redirect Message
|
||||
class ICMPRedirect < ICMPGeneric
|
||||
ICMP_CODE_REDIRECT_NETWORK = 0
|
||||
ICMP_CODE_REDIRECT_HOST = 1
|
||||
ICMP_CODE_REDIRECT_TOS_NETWORK = 2
|
||||
ICMP_CODE_REDIRECT_TOS_HOST = 3
|
||||
|
||||
# Gateway internet address
|
||||
octets :gateway_ip, 32
|
||||
# Internet header + 64 bits of original datagram
|
||||
rest :payload
|
||||
|
||||
def initialize(*args)
|
||||
super(*args)
|
||||
self.type = 5
|
||||
self.code = 0
|
||||
end
|
||||
end
|
||||
|
||||
# Generic ICMP Timestamp Message from which ICMPTimestampRequest and
|
||||
# ICMPTimestampReply inherit
|
||||
class ICMPTimestamp < ICMPGeneric
|
||||
# an identifier to add in matching timestamp and replies
|
||||
unsigned :id, 16
|
||||
# a sequence number to aid in matching timestamp and replies
|
||||
unsigned :sequence, 16
|
||||
# time the sender last touched the message before sending it in number of milliseconds since midnight UT
|
||||
unsigned :originate_timestamp, 32
|
||||
# time the echoer first touched it on receipt in number of milliseconds since midnight UT
|
||||
unsigned :receive_timestamp, 32
|
||||
# time the echoers last touched the message on sending it in number of milliseconds since midnight UT
|
||||
unsigned :transmit_timestamp, 32
|
||||
# probably never used ...
|
||||
rest :payload
|
||||
|
||||
def initialize(*args)
|
||||
super(*args)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# ICMP Timestamp Request Message
|
||||
class ICMPTimestampRequest < ICMPTimestamp
|
||||
# probably never used ...
|
||||
rest :payload
|
||||
|
||||
def initialize(*args)
|
||||
super(*args)
|
||||
self.type = 13
|
||||
self.code = 0
|
||||
end
|
||||
end
|
||||
|
||||
# ICMP Timestamp Reply Message
|
||||
class ICMPTimestampReply < ICMPTimestamp
|
||||
# probably never used ...
|
||||
rest :payload
|
||||
|
||||
def initialize(*args)
|
||||
super(*args)
|
||||
self.type = 14
|
||||
self.code = 0
|
||||
end
|
||||
end
|
||||
|
||||
# ICMP Information Request Message
|
||||
class ICMPInformationRequest < ICMPGeneric
|
||||
# an identifier to add in matching timestamp and replies
|
||||
unsigned :id, 16
|
||||
# a sequence number to aid in matching timestamp and replies
|
||||
unsigned :sequence, 16
|
||||
# probably never used ...
|
||||
rest :payload
|
||||
|
||||
def initialize(*args)
|
||||
super(*args)
|
||||
self.type = 15
|
||||
self.code = 0
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# ICMP Information Reply Message
|
||||
class ICMPInformationReply < ICMPGeneric
|
||||
# an identifier to add in matching timestamp and replies
|
||||
unsigned :id, 16
|
||||
# a sequence number to aid in matching timestamp and replies
|
||||
unsigned :sequence, 16
|
||||
# probably never used ...
|
||||
rest :payload
|
||||
|
||||
def initialize(*args)
|
||||
super(*args)
|
||||
self.type = 16
|
||||
self.code = 0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
# vim: set ts=2 et sw=2:
|
||||
|
|
|
@ -0,0 +1,446 @@
|
|||
# $Id: icmpv6.rb 157 2009-12-14 15:27:32Z jhart $
|
||||
#
|
||||
# Copyright (c) 2008, Jon Hart
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# * Neither the name of the <organization> nor the
|
||||
# names of its contributors may be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY Jon Hart ``AS IS'' AND ANY
|
||||
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL Jon Hart BE LIABLE FOR ANY
|
||||
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
module Racket
|
||||
module L4
|
||||
# Internet Control Message Protcol, v6
|
||||
#
|
||||
# http://en.wikipedia.org/wiki/ICMPv6
|
||||
#
|
||||
# Generic ICMP class from which all ICMP variants spawn. This should never be used directly.
|
||||
class ICMPv6Generic < RacketPart
|
||||
ICMPv6_TYPE_ECHO_REPLY = 129
|
||||
ICMPv6_TYPE_DESTINATION_UNREACHABLE = 1
|
||||
ICMPv6_TYPE_PACKET_TOO_BIG = 2
|
||||
ICMPv6_TYPE_ECHO_REQUEST = 128
|
||||
ICMPv6_TYPE_TIME_EXCEEDED = 3
|
||||
ICMPv6_TYPE_PARAMETER_PROBLEM = 4
|
||||
ICMPv6_TYPE_MLD_QUERY = 130
|
||||
ICMPv6_TYPE_MLD_REPORT = 131
|
||||
ICMPv6_TYPE_MLD_DONE = 132
|
||||
ICMPv6_TYPE_ROUTER_SOLICITATION = 133
|
||||
ICMPv6_TYPE_ROUTER_ADVERTISEMENT = 134
|
||||
ICMPv6_TYPE_NEIGHBOR_SOLICITATION = 135
|
||||
ICMPv6_TYPE_NEIGHBOR_ADVERTISEMENT = 136
|
||||
ICMPv6_TYPE_REDIRECT = 137
|
||||
ICMPv6_TYPE_INFORMATION_REQUEST = 139
|
||||
ICMPv6_TYPE_INFORMATION_REPLY = 140
|
||||
|
||||
# Type
|
||||
unsigned :type, 8
|
||||
# Code
|
||||
unsigned :code, 8
|
||||
# Checksum
|
||||
unsigned :checksum, 16
|
||||
rest :message
|
||||
|
||||
# check the checksum for this ICMP packet
|
||||
def checksum?
|
||||
self.checksum == compute_checksum
|
||||
end
|
||||
|
||||
def initialize(*args)
|
||||
super(*args)
|
||||
@autofix = false
|
||||
end
|
||||
|
||||
# Add an ICMPv6 option. RFC claims that the value should be padded (with what?)
|
||||
# to land on a 64-bit boundary, however that doesn't always appear to be the case. so, yeah,
|
||||
# try to pad on your own or pick strings that are multiples of 8 characters
|
||||
def add_option(type, value)
|
||||
t = Misc::TLV.new(1,1)
|
||||
t.type = type
|
||||
t.length = (value.length + 2) / 8
|
||||
just = value.length + 2 + (8 - ((value.length + 2) % 8))
|
||||
t.value = (value.length + 2) % 8 == 0 ? value : value.ljust(just, "\x00")
|
||||
self.payload = t.encode + self.payload
|
||||
end
|
||||
|
||||
# ignorantly assume the first parts of the payload contain ICMPv6 options
|
||||
# and find a return an array of Racket::Misc::TLV representing the options
|
||||
def get_options
|
||||
p = self.payload
|
||||
options = []
|
||||
until ((o = Misc::TLV.new(1,1,8,true).decode(p)).nil?)
|
||||
options << o[0..2]
|
||||
p = o[3]
|
||||
end
|
||||
options
|
||||
end
|
||||
|
||||
# compute and set the checksum for this ICMP packet
|
||||
def checksum!(src_ip, dst_ip)
|
||||
self.checksum = compute_checksum(src_ip, dst_ip)
|
||||
end
|
||||
|
||||
# 'fix' this ICMP packet up for sending.
|
||||
# (really, just set the checksum)
|
||||
def fix!(src_ip, dst_ip)
|
||||
self.checksum!(src_ip, dst_ip)
|
||||
end
|
||||
|
||||
# get the source link layer address of this message, if found
|
||||
def slla
|
||||
addr = nil
|
||||
self.get_options.each do |o|
|
||||
type, length, value, rest = o.flatten
|
||||
if (type == 1)
|
||||
addr = L2::Misc.string2mac(value)
|
||||
end
|
||||
end
|
||||
addr
|
||||
end
|
||||
|
||||
# set the source link layer address of this message.
|
||||
# expects +addr+ in de:ad:ba:dc:af:e0 form
|
||||
def slla=(addr)
|
||||
self.add_option(1, L2::Misc.mac2string(addr))
|
||||
end
|
||||
|
||||
# get the target link layer address of this message, if found
|
||||
def tlla
|
||||
addr = nil
|
||||
self.get_options.each do |o|
|
||||
type, length, value, rest = o.flatten
|
||||
if (type == 2)
|
||||
addr = L2::Misc.string2mac(value)
|
||||
end
|
||||
end
|
||||
addr
|
||||
end
|
||||
|
||||
# set the target link layer address of this message
|
||||
# expects +addr+ in de:ad:ba:dc:af:e0 form
|
||||
def tlla=(addr)
|
||||
self.add_option(2, L2::Misc.mac2string(addr))
|
||||
end
|
||||
|
||||
private
|
||||
def compute_checksum(src_ip, dst_ip)
|
||||
s1 = src_ip >> 96
|
||||
s2 = (src_ip >> 64) & 0xFFFFFFFF
|
||||
s3 = (src_ip >> 32) & 0xFFFFFFFF
|
||||
s4 = src_ip & 0xFFFFFFFF
|
||||
|
||||
d1 = dst_ip >> 96
|
||||
d2 = (dst_ip >> 64) & 0xFFFFFFFF
|
||||
d3 = (dst_ip >> 32) & 0xFFFFFFFF
|
||||
d4 = dst_ip & 0xFFFFFFFF
|
||||
|
||||
# pseudo header used for checksum calculation as per RFC 768
|
||||
pseudo = [ s1, s2, s3, s4, d1, d2, d3, d4, self.length, 58, self.type, self.code, 0, self.message ]
|
||||
L3::Misc.checksum(pseudo.pack("NNNNNNNNNNCCna*"))
|
||||
end
|
||||
end
|
||||
# Send raw ICMP packets of your own design
|
||||
class ICMPv6 < ICMPv6Generic
|
||||
rest :payload
|
||||
end
|
||||
|
||||
# Generic ICMPv6 echo, used by ICMPv6EchoRequest and ICMPv6EchoReply
|
||||
class ICMPv6Echo < ICMPv6Generic
|
||||
# identifier to aid in matching echo requests/replies
|
||||
unsigned :id, 16
|
||||
# sequence number to aid in matching requests/replies
|
||||
unsigned :sequence, 16
|
||||
rest :payload
|
||||
|
||||
def initialize(*args)
|
||||
super(*args)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# ICMPv6Echo Request
|
||||
class ICMPv6EchoRequest < ICMPv6Echo
|
||||
rest :payload
|
||||
|
||||
def initialize(*args)
|
||||
super(*args)
|
||||
self.type = ICMPv6_TYPE_ECHO_REQUEST
|
||||
self.code = 0
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# ICMPv6Echo Reply
|
||||
class ICMPv6EchoReply < ICMPv6Echo
|
||||
rest :payload
|
||||
|
||||
def initialize(*args)
|
||||
super(*args)
|
||||
self.type = ICMPv6_TYPE_ECHO_REPLY
|
||||
self.code = 0
|
||||
end
|
||||
end
|
||||
|
||||
# ICMP Destination Unreachable Message
|
||||
class ICMPv6DestinationUnreachable < ICMPv6Generic
|
||||
ICMPv6_CODE_NO_ROUTE = 0
|
||||
ICMPv6_CODE_ADMIN_PROHIBITED = 1
|
||||
ICMPv6_CODE_BEYOND_SCOPE = 2
|
||||
ICMPv6_CODE_ADDRESS_UNREACHABLE = 3
|
||||
ICMPv6_CODE_PORT_UNREACHABLE = 4
|
||||
ICMPv6_CODE_FAILED_POLICY = 4
|
||||
ICMPv6_CODE_REJECT_ROUTE = 5
|
||||
# This is never used according to the RFC
|
||||
unsigned :unused, 32
|
||||
# Internet header + 64 bits of original datagram
|
||||
rest :payload
|
||||
|
||||
def initialize(*args)
|
||||
super(*args)
|
||||
self.type = ICMPv6_TYPE_DESTINATION_UNREACHABLE
|
||||
end
|
||||
end
|
||||
|
||||
class ICMPv6PacketTooBig < ICMPv6Generic
|
||||
# The Maximum Transmission Unit of the next-hop link
|
||||
unsigned :mtu, 32
|
||||
rest :payload
|
||||
|
||||
def initialize(*args)
|
||||
super(*args)
|
||||
self.type = ICMPv6_TYPE_PACKET_TOO_BIG
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# ICMP Time Exceeded Message
|
||||
class ICMPv6TimeExceeded < ICMPv6Generic
|
||||
ICMPv6_CODE_TTL_EXCEEDED_IN_TRANSIT = 0
|
||||
ICMPv6_CODE_FRAG_REASSEMBLY_TIME_EXCEEDED = 1
|
||||
# This is never used according to the RFC
|
||||
unsigned :unused, 32
|
||||
# As much of the original ICMPv6 packet without busting MTU
|
||||
rest :payload
|
||||
|
||||
def initialize(*args)
|
||||
super(*args)
|
||||
self.type = ICMPv6_TYPE_TIME_EXCEEDED
|
||||
end
|
||||
end
|
||||
|
||||
# ICMPv6 Parameter Problem Message
|
||||
class ICMPv6ParameterProblem < ICMPv6Generic
|
||||
ICMPv6_CODE_ERRONEOUS_HEADER = 0
|
||||
ICMPv6_CODE_UNRECOGNIZED_NEXT_HEADER = 1
|
||||
ICMPv6_CODE_UNRECOGNIZED_OPTION = 2
|
||||
# pointer to the octet where the error was detected
|
||||
unsigned :pointer, 32
|
||||
# As much of the original ICMPv6 packet without busting MTU
|
||||
rest :payload
|
||||
|
||||
def initialize(*args)
|
||||
super(*args)
|
||||
self.type = ICMPv6_TYPE_PARAMETER_PROBLEM
|
||||
end
|
||||
end
|
||||
|
||||
# ICMPv6 Multicast Listener Discovery (MLD)
|
||||
# http://www.faqs.org/rfcs/rfc2710.html
|
||||
class ICMPv6MulticastListener < ICMPv6Generic
|
||||
# maximum response delay
|
||||
unsigned :delay, 16
|
||||
# should be zero. never used.
|
||||
unsigned :reserved, 16
|
||||
# multicast address
|
||||
unsigned :address, 128
|
||||
rest :payload
|
||||
|
||||
def initialize(*args)
|
||||
super(*args)
|
||||
end
|
||||
end
|
||||
|
||||
class ICMPv6MulticastListenerQuery < ICMPv6MulticastListener
|
||||
rest :payload
|
||||
|
||||
def initialize(*args)
|
||||
super(*args)
|
||||
self.type = ICMPv6_TYPE_MLD_QUERY
|
||||
end
|
||||
end
|
||||
|
||||
class ICMPv6MulticastListenerReport < ICMPv6MulticastListener
|
||||
rest :payload
|
||||
|
||||
def initialize(*args)
|
||||
super(*args)
|
||||
self.type = ICMPv6_TYPE_MLD_REPORT
|
||||
end
|
||||
end
|
||||
|
||||
class ICMPv6MulticastListenerDone < ICMPv6MulticastListener
|
||||
rest :payload
|
||||
|
||||
def initialize(*args)
|
||||
super(*args)
|
||||
self.type = ICMPv6_TYPE_MLD_DONE
|
||||
end
|
||||
end
|
||||
|
||||
# http://tools.ietf.org/html/rfc4861
|
||||
class ICMPv6RouterSolicitation < ICMPv6Generic
|
||||
# should be 0, never used.
|
||||
unsigned :reserved, 32
|
||||
rest :payload
|
||||
|
||||
def initialize(*args)
|
||||
super(*args)
|
||||
self.type = ICMPv6_TYPE_ROUTER_SOLICITATION
|
||||
end
|
||||
end
|
||||
|
||||
# http://tools.ietf.org/html/rfc4861
|
||||
class ICMPv6RouterAdvertisement < ICMPv6Generic
|
||||
# default value that should be placed in the hop count field of the IP header
|
||||
# for outgoing IP packets
|
||||
unsigned :hop_limit, 8
|
||||
# boolean, managed address configuration?
|
||||
unsigned :managed_config, 1
|
||||
# boolean, other configuration?
|
||||
unsigned :other_config, 1
|
||||
# set to 0, never used.
|
||||
unsigned :reserved, 6
|
||||
# lifetime associated with the default router in seconds
|
||||
unsigned :lifetime, 16
|
||||
# time in milliseconds that a node assumes a neighbor is reachable after having received a reachability confirmation
|
||||
unsigned :reachable_time, 32
|
||||
# time in milliseconds between retransmitted neighbor solicitation messages
|
||||
unsigned :retrans_time, 32
|
||||
rest :payload
|
||||
|
||||
def initialize(*args)
|
||||
super(*args)
|
||||
self.type = ICMPv6_TYPE_ROUTER_ADVERTISEMENT
|
||||
end
|
||||
end
|
||||
|
||||
# http://tools.ietf.org/html/rfc4861
|
||||
class ICMPv6NeighborSolicitation < ICMPv6Generic
|
||||
# set to 0, never used.
|
||||
unsigned :reserved, 32
|
||||
# target address of the solicitation
|
||||
unsigned :address, 128
|
||||
rest :payload
|
||||
|
||||
def initialize(*args)
|
||||
super(*args)
|
||||
self.type = ICMPv6_TYPE_NEIGHBOR_SOLICITATION
|
||||
end
|
||||
end
|
||||
|
||||
# http://tools.ietf.org/html/rfc4861
|
||||
class ICMPv6NeighborAdvertisement < ICMPv6Generic
|
||||
# normally this would be router (1), solicited (1), override(1) and reserved (2), however
|
||||
# a bit-struct byte boundary bug bites us here
|
||||
unsigned :bigbustedfield, 32
|
||||
# for solicited adverts, the target address field in the solicitation that prompted this.
|
||||
# for unsolicited adverts, the address whose link-layer address has changed
|
||||
unsigned :address, 128
|
||||
rest :payload
|
||||
|
||||
# set solicited flag
|
||||
def solicited=(f)
|
||||
self.bigbustedfield = (f << 30) ^ self.bigbustedfield
|
||||
end
|
||||
|
||||
# set router flag
|
||||
def router=(f)
|
||||
self.bigbustedfield = (f << 31) ^ self.bigbustedfield
|
||||
end
|
||||
|
||||
# set override flag
|
||||
def override=(f)
|
||||
self.bigbustedfield = (f << 29) ^ self.bigbustedfield
|
||||
end
|
||||
|
||||
def initialize(*args)
|
||||
super(*args)
|
||||
self.type = ICMPv6_TYPE_NEIGHBOR_ADVERTISEMENT
|
||||
end
|
||||
end
|
||||
|
||||
# http://tools.ietf.org/html/rfc4861
|
||||
class ICMPv6Redirect < ICMPv6Generic
|
||||
# unused, should be 0
|
||||
unsigned :reserved, 32
|
||||
# the IP address that is a better first hop to use for the ICMP destination address
|
||||
unsigned :src_ip, 128
|
||||
# the IP address of the destination that is redirected to the target
|
||||
unsigned :dst_ip, 128
|
||||
rest :payload
|
||||
|
||||
def initialize(*args)
|
||||
super(*args)
|
||||
self.type = ICMPv6_TYPE_REDIRECT
|
||||
end
|
||||
end
|
||||
|
||||
# Generic class that IPv6NodeInformationRequest and Reply inherit from
|
||||
# http://tools.ietf.org/html/rfc4620
|
||||
class ICMPv6NodeInformation < ICMPv6Generic
|
||||
# type of information requested in a query or supplied in a reply
|
||||
unsigned :qtype, 16
|
||||
# qtype-specific flags that may be defined for certain qtypes and their replies
|
||||
unsigned :flags, 16
|
||||
# opaque field to help avoid spoofing and/or to aid in matching replies with queries
|
||||
text :nonce, 64
|
||||
rest :payload
|
||||
|
||||
def initialize(*args)
|
||||
super(*args)
|
||||
end
|
||||
end
|
||||
|
||||
# http://tools.ietf.org/html/rfc4620
|
||||
class ICMPv6NodeInformationRequest < ICMPv6NodeInformation
|
||||
ICMPv6_CODE_INFORMATION_REQUEST_IPv6 = 0
|
||||
ICMPv6_CODE_INFORMATION_REQUEST_NAME = 1
|
||||
ICMPv6_CODE_INFORMATION_REQUEST_IPv4 = 2
|
||||
|
||||
def initialize(*args)
|
||||
super(*args)
|
||||
self.type = ICMPv6_TYPE_INFORMATION_REQUEST
|
||||
end
|
||||
end
|
||||
|
||||
# http://tools.ietf.org/html/rfc4620
|
||||
class ICMPv6NodeInformationReply < ICMPv6NodeInformation
|
||||
ICMPv6_CODE_INFORMATION_REPLY_SUCCESS = 0
|
||||
ICMPv6_CODE_INFORMATION_REPLY_REFUSE = 1
|
||||
ICMPv6_CODE_INFORMATION_REPLY_UNKNOWN = 2
|
||||
|
||||
def initialize(*args)
|
||||
super(*args)
|
||||
self.type = ICMPv6_TYPE_INFORMATION_REPLY
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
# vim: set ts=2 et sw=2:
|
|
@ -25,20 +25,21 @@
|
|||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
module Racket
|
||||
module L4
|
||||
# Internet Group Management Protocol, Version 1
|
||||
#
|
||||
# RFC1112 (http://www.faqs.org/rfcs/rfc1112.html)
|
||||
#
|
||||
module Racket
|
||||
class IGMPv1 < RacketPart
|
||||
# Version (defaults to 1)
|
||||
unsigned :version, 4
|
||||
unsigned :version, 4, { :default => 1 }
|
||||
# Type
|
||||
unsigned :type, 4
|
||||
# Unused
|
||||
unsigned :unused, 8
|
||||
# Checksum
|
||||
unsigned :csum, 16
|
||||
unsigned :checksum, 16
|
||||
# Group Address
|
||||
octets :gaddr, 32
|
||||
# Payload
|
||||
|
@ -46,12 +47,12 @@ class IGMPv1 < RacketPart
|
|||
|
||||
# Check the checksum for this IGMP message
|
||||
def checksum?
|
||||
self.csum == 0 || (self.csum == compute_checksum)
|
||||
self.checksum == 0 || (self.checksum == compute_checksum)
|
||||
end
|
||||
|
||||
# Compute and set the checkum for this IGMP message
|
||||
def checksum!
|
||||
self.csum = compute_checksum
|
||||
self.checksum = compute_checksum
|
||||
end
|
||||
|
||||
# Do whatever 'fixing' is neccessary in preparation
|
||||
|
@ -74,4 +75,5 @@ private
|
|||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
# vim: set ts=2 et sw=2:
|
||||
|
|
|
@ -25,17 +25,18 @@
|
|||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
module Racket
|
||||
module L4
|
||||
# Internet Group Management Protocol, Version 2: IGMPv2
|
||||
#
|
||||
# RFC2236 (http://www.faqs.org/rfcs/rfc2236.html)
|
||||
module Racket
|
||||
class IGMPv2 < RacketPart
|
||||
# Type
|
||||
unsigned :type, 8
|
||||
# Max Response Time
|
||||
unsigned :time, 8
|
||||
# Checksum
|
||||
unsigned :csum, 16
|
||||
unsigned :checksum, 16
|
||||
# Group Address
|
||||
octets :gaddr, 32
|
||||
# Payload
|
||||
|
@ -43,12 +44,12 @@ class IGMPv2 < RacketPart
|
|||
|
||||
# Is the checksum of this IGMPv2 message correct
|
||||
def checksum?
|
||||
self.csum == 0 || (self.csum == compute_checksum)
|
||||
self.checksum == 0 || (self.checksum == compute_checksum)
|
||||
end
|
||||
|
||||
# Set the checksum of this IGMPv2 message
|
||||
def checksum!
|
||||
self.csum = compute_checksum
|
||||
self.checksum = compute_checksum
|
||||
end
|
||||
|
||||
# Do whatever 'fixing' is neccessary in preparation
|
||||
|
@ -71,4 +72,5 @@ private
|
|||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
# vim: set ts=2 et sw=2:
|
||||
|
|
|
@ -25,6 +25,8 @@
|
|||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
module Racket
|
||||
module L4
|
||||
# Internet Gateway Routing Protocol: IGRP
|
||||
#
|
||||
# http://www.cisco.com/warp/public/103/5.html
|
||||
|
@ -37,7 +39,6 @@
|
|||
# uchar reliability; /* percent packets successfully tx/rx */
|
||||
# uchar load; /* percent of channel occupied */
|
||||
# uchar hopcount; /* hop count */
|
||||
module Racket
|
||||
class IGRP < RacketPart
|
||||
IGRP_UPDATE = 1
|
||||
IGRP_REQUEST = 2
|
||||
|
@ -132,5 +133,6 @@ private
|
|||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# vim: set ts=2 et sw=2:
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
# $Id: misc.rb 169 2009-12-18 16:12:34Z jhart $
|
||||
#
|
||||
# Copyright (c) 2008, Jon Hart
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# * Neither the name of the <organization> nor the
|
||||
# names of its contributors may be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY Jon Hart ``AS IS'' AND ANY
|
||||
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL Jon Hart BE LIABLE FOR ANY
|
||||
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
#module Racket
|
||||
#module L4
|
||||
# # Miscelaneous L3 helper methods
|
||||
# module Misc
|
||||
# end
|
||||
#end
|
||||
#end
|
||||
# vim: set ts=2 et sw=2:
|
|
@ -0,0 +1,160 @@
|
|||
# $Id: sctp.rb 162 2009-12-18 05:12:18Z jhart $
|
||||
#
|
||||
# Copyright (c) 2008, Jon Hart
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# * Neither the name of the <organization> nor the
|
||||
# names of its contributors may be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY Jon Hart ``AS IS'' AND ANY
|
||||
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL Jon Hart BE LIABLE FOR ANY
|
||||
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
module Racket
|
||||
module L4
|
||||
# Stream Control Transmission Protocol
|
||||
# http://tools.ietf.org/html/rfc4960
|
||||
class SCTP < RacketPart
|
||||
# Source port
|
||||
unsigned :src_port, 16
|
||||
# Destination port
|
||||
unsigned :dst_port, 16
|
||||
# Verification tag
|
||||
unsigned :verification, 32
|
||||
# Checksum
|
||||
unsigned :checksum, 32
|
||||
rest :payload
|
||||
|
||||
# Add a new SCTP chunk (see http://tools.ietf.org/html/rfc4960)
|
||||
def add_chunk(type, flags, length, data)
|
||||
@chunks << [ type, flags, length, data ]
|
||||
end
|
||||
|
||||
def checksum?
|
||||
self.checksum == compute_checksum
|
||||
end
|
||||
|
||||
def checksum!
|
||||
self.checksum = compute_checksum
|
||||
end
|
||||
|
||||
# (really, just set the checksum)
|
||||
def fix!
|
||||
self.payload = ""
|
||||
@chunks.each do |c|
|
||||
self.payload += c.pack("CCna*")
|
||||
end
|
||||
self.checksum!
|
||||
end
|
||||
|
||||
def initialize(*args)
|
||||
@chunks = []
|
||||
super
|
||||
end
|
||||
|
||||
private
|
||||
def compute_checksum
|
||||
crc_c = [
|
||||
0x00000000, 0xF26B8303, 0xE13B70F7, 0x1350F3F4,
|
||||
0xC79A971F, 0x35F1141C, 0x26A1E7E8, 0xD4CA64EB,
|
||||
0x8AD958CF, 0x78B2DBCC, 0x6BE22838, 0x9989AB3B,
|
||||
0x4D43CFD0, 0xBF284CD3, 0xAC78BF27, 0x5E133C24,
|
||||
0x105EC76F, 0xE235446C, 0xF165B798, 0x030E349B,
|
||||
0xD7C45070, 0x25AFD373, 0x36FF2087, 0xC494A384,
|
||||
0x9A879FA0, 0x68EC1CA3, 0x7BBCEF57, 0x89D76C54,
|
||||
0x5D1D08BF, 0xAF768BBC, 0xBC267848, 0x4E4DFB4B,
|
||||
0x20BD8EDE, 0xD2D60DDD, 0xC186FE29, 0x33ED7D2A,
|
||||
0xE72719C1, 0x154C9AC2, 0x061C6936, 0xF477EA35,
|
||||
0xAA64D611, 0x580F5512, 0x4B5FA6E6, 0xB93425E5,
|
||||
0x6DFE410E, 0x9F95C20D, 0x8CC531F9, 0x7EAEB2FA,
|
||||
0x30E349B1, 0xC288CAB2, 0xD1D83946, 0x23B3BA45,
|
||||
0xF779DEAE, 0x05125DAD, 0x1642AE59, 0xE4292D5A,
|
||||
0xBA3A117E, 0x4851927D, 0x5B016189, 0xA96AE28A,
|
||||
0x7DA08661, 0x8FCB0562, 0x9C9BF696, 0x6EF07595,
|
||||
0x417B1DBC, 0xB3109EBF, 0xA0406D4B, 0x522BEE48,
|
||||
0x86E18AA3, 0x748A09A0, 0x67DAFA54, 0x95B17957,
|
||||
0xCBA24573, 0x39C9C670, 0x2A993584, 0xD8F2B687,
|
||||
0x0C38D26C, 0xFE53516F, 0xED03A29B, 0x1F682198,
|
||||
0x5125DAD3, 0xA34E59D0, 0xB01EAA24, 0x42752927,
|
||||
0x96BF4DCC, 0x64D4CECF, 0x77843D3B, 0x85EFBE38,
|
||||
0xDBFC821C, 0x2997011F, 0x3AC7F2EB, 0xC8AC71E8,
|
||||
0x1C661503, 0xEE0D9600, 0xFD5D65F4, 0x0F36E6F7,
|
||||
0x61C69362, 0x93AD1061, 0x80FDE395, 0x72966096,
|
||||
0xA65C047D, 0x5437877E, 0x4767748A, 0xB50CF789,
|
||||
0xEB1FCBAD, 0x197448AE, 0x0A24BB5A, 0xF84F3859,
|
||||
0x2C855CB2, 0xDEEEDFB1, 0xCDBE2C45, 0x3FD5AF46,
|
||||
0x7198540D, 0x83F3D70E, 0x90A324FA, 0x62C8A7F9,
|
||||
0xB602C312, 0x44694011, 0x5739B3E5, 0xA55230E6,
|
||||
0xFB410CC2, 0x092A8FC1, 0x1A7A7C35, 0xE811FF36,
|
||||
0x3CDB9BDD, 0xCEB018DE, 0xDDE0EB2A, 0x2F8B6829,
|
||||
0x82F63B78, 0x709DB87B, 0x63CD4B8F, 0x91A6C88C,
|
||||
0x456CAC67, 0xB7072F64, 0xA457DC90, 0x563C5F93,
|
||||
0x082F63B7, 0xFA44E0B4, 0xE9141340, 0x1B7F9043,
|
||||
0xCFB5F4A8, 0x3DDE77AB, 0x2E8E845F, 0xDCE5075C,
|
||||
0x92A8FC17, 0x60C37F14, 0x73938CE0, 0x81F80FE3,
|
||||
0x55326B08, 0xA759E80B, 0xB4091BFF, 0x466298FC,
|
||||
0x1871A4D8, 0xEA1A27DB, 0xF94AD42F, 0x0B21572C,
|
||||
0xDFEB33C7, 0x2D80B0C4, 0x3ED04330, 0xCCBBC033,
|
||||
0xA24BB5A6, 0x502036A5, 0x4370C551, 0xB11B4652,
|
||||
0x65D122B9, 0x97BAA1BA, 0x84EA524E, 0x7681D14D,
|
||||
0x2892ED69, 0xDAF96E6A, 0xC9A99D9E, 0x3BC21E9D,
|
||||
0xEF087A76, 0x1D63F975, 0x0E330A81, 0xFC588982,
|
||||
0xB21572C9, 0x407EF1CA, 0x532E023E, 0xA145813D,
|
||||
0x758FE5D6, 0x87E466D5, 0x94B49521, 0x66DF1622,
|
||||
0x38CC2A06, 0xCAA7A905, 0xD9F75AF1, 0x2B9CD9F2,
|
||||
0xFF56BD19, 0x0D3D3E1A, 0x1E6DCDEE, 0xEC064EED,
|
||||
0xC38D26C4, 0x31E6A5C7, 0x22B65633, 0xD0DDD530,
|
||||
0x0417B1DB, 0xF67C32D8, 0xE52CC12C, 0x1747422F,
|
||||
0x49547E0B, 0xBB3FFD08, 0xA86F0EFC, 0x5A048DFF,
|
||||
0x8ECEE914, 0x7CA56A17, 0x6FF599E3, 0x9D9E1AE0,
|
||||
0xD3D3E1AB, 0x21B862A8, 0x32E8915C, 0xC083125F,
|
||||
0x144976B4, 0xE622F5B7, 0xF5720643, 0x07198540,
|
||||
0x590AB964, 0xAB613A67, 0xB831C993, 0x4A5A4A90,
|
||||
0x9E902E7B, 0x6CFBAD78, 0x7FAB5E8C, 0x8DC0DD8F,
|
||||
0xE330A81A, 0x115B2B19, 0x020BD8ED, 0xF0605BEE,
|
||||
0x24AA3F05, 0xD6C1BC06, 0xC5914FF2, 0x37FACCF1,
|
||||
0x69E9F0D5, 0x9B8273D6, 0x88D28022, 0x7AB90321,
|
||||
0xAE7367CA, 0x5C18E4C9, 0x4F48173D, 0xBD23943E,
|
||||
0xF36E6F75, 0x0105EC76, 0x12551F82, 0xE03E9C81,
|
||||
0x34F4F86A, 0xC69F7B69, 0xD5CF889D, 0x27A40B9E,
|
||||
0x79B737BA, 0x8BDCB4B9, 0x988C474D, 0x6AE7C44E,
|
||||
0xBE2DA0A5, 0x4C4623A6, 0x5F16D052, 0xAD7D5351
|
||||
]
|
||||
|
||||
crc32 = ~0
|
||||
header = [ self.src_port, self.dst_port, self.verification, 0 ].pack("CCnn")
|
||||
(0..header.length-1).each do |b|
|
||||
crc32 = (crc32 >> 8) ^ crc_c[(crc32^header[b]) & 0xFF]
|
||||
end
|
||||
|
||||
result = ~crc32
|
||||
|
||||
byte0 = result & 0xff
|
||||
byte1 = (result >> 8) & 0xff
|
||||
byte2 = (result >> 16) & 0xff
|
||||
byte3 = (result >> 24) & 0xff
|
||||
|
||||
crc32 = ((byte0 << 24) |
|
||||
(byte1 << 16) |
|
||||
(byte2 << 8) |
|
||||
byte3)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
# vim: set ts=2 et sw=2:
|
|
@ -25,10 +25,11 @@
|
|||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
module Racket
|
||||
module L4
|
||||
# Transmission Control Protocol: TCP
|
||||
#
|
||||
# RFC793 (http://www.faqs.org/rfcs/rfc793.html)
|
||||
module Racket
|
||||
class TCP < RacketPart
|
||||
# Source port
|
||||
unsigned :src_port, 16
|
||||
|
@ -61,7 +62,7 @@ class TCP < RacketPart
|
|||
# Window size
|
||||
unsigned :window, 16
|
||||
# Checksum
|
||||
unsigned :csum, 16
|
||||
unsigned :checksum, 16
|
||||
# Urgent pointer
|
||||
unsigned :urg, 16
|
||||
# Payload
|
||||
|
@ -71,7 +72,7 @@ class TCP < RacketPart
|
|||
# All rejiggering will happen when the call to fix!
|
||||
# happens automagically.
|
||||
def add_option(number, value)
|
||||
t = TLV.new(1,1)
|
||||
t = Racket::Misc::TLV.new(1,1)
|
||||
t.type = number
|
||||
t.value = value
|
||||
t.length = value.length + 2
|
||||
|
@ -80,12 +81,12 @@ class TCP < RacketPart
|
|||
|
||||
# Check the checksum for this TCP packet
|
||||
def checksum?(ip_src, ip_dst)
|
||||
self.csum == compute_checksum(ip_src, ip_dst)
|
||||
self.checksum == compute_checksum(ip_src, ip_dst)
|
||||
end
|
||||
|
||||
# Compute and set the checksum for this TCP packet
|
||||
def checksum!(ip_src, ip_dst)
|
||||
self.csum = compute_checksum(ip_src, ip_dst)
|
||||
self.checksum = compute_checksum(ip_src, ip_dst)
|
||||
end
|
||||
|
||||
# Fix this packet up for proper sending. Sets the length
|
||||
|
@ -104,10 +105,7 @@ class TCP < RacketPart
|
|||
self.payload = newpayload + self.payload + next_payload
|
||||
self.offset = self.class.bit_length/32 + newpayload.length/4
|
||||
self.checksum!(ip_src, ip_dst)
|
||||
end
|
||||
|
||||
def payload_data
|
||||
self.payload[(self.offset * 4)-20, self.payload.length-((self.offset * 4)-20)] || ''
|
||||
self.payload = newpayload
|
||||
end
|
||||
|
||||
def initialize(*args)
|
||||
|
@ -139,4 +137,5 @@ private
|
|||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
# vim: set ts=2 et sw=2:
|
||||
|
|
|
@ -25,10 +25,11 @@
|
|||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
module Racket
|
||||
module L4
|
||||
# User Datagram Protocol: UDP
|
||||
#
|
||||
# RFC768 (http://www.faqs.org/rfcs/rfc768.html)
|
||||
module Racket
|
||||
class UDP < RacketPart
|
||||
# Source Port
|
||||
unsigned :src_port, 16
|
||||
|
@ -37,20 +38,20 @@ class UDP < RacketPart
|
|||
# Datagram Length
|
||||
unsigned :len, 16
|
||||
# Checksum
|
||||
unsigned :csum, 16
|
||||
unsigned :checksum, 16
|
||||
# Payload
|
||||
rest :payload
|
||||
|
||||
# Check the checksum for this UDP datagram
|
||||
def checksum?(src_ip, dst_ip)
|
||||
self.csum == 0 || (self.csum == compute_checksum(src_ip, dst_ip))
|
||||
self.checksum == 0 || (self.checksum == compute_checksum(src_ip, dst_ip))
|
||||
end
|
||||
|
||||
# Compute and set the checksum for this UDP datagram
|
||||
def checksum!(src_ip, dst_ip)
|
||||
# set the checksum to 0 for usage in the pseudo header...
|
||||
self.csum = 0
|
||||
self.csum = compute_checksum(src_ip, dst_ip)
|
||||
self.checksum = 0
|
||||
self.checksum = compute_checksum(src_ip, dst_ip)
|
||||
end
|
||||
|
||||
# Fix this packet up for proper sending. Sets the length
|
||||
|
@ -74,6 +75,7 @@ private
|
|||
L3::Misc.checksum((pseudo << header).flatten.pack("NNnnnnnna*"))
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
# vim: set ts=2 et sw=2:
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
# $Id: vrrp.rb 127 2009-11-29 01:30:46Z jhart $
|
||||
#
|
||||
# Copyright (c) 2008, Jon Hart
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# * Neither the name of the <organization> nor the
|
||||
# names of its contributors may be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY Jon Hart ``AS IS'' AND ANY
|
||||
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL Jon Hart BE LIABLE FOR ANY
|
||||
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
module Racket
|
||||
module L4
|
||||
# Virtual Router Redundancy Protocol (VRRP)
|
||||
# http://tools.ietf.org/html/rfc2338
|
||||
# http://tools.ietf.org/html/rfc3768
|
||||
class VRRP < RacketPart
|
||||
# Version
|
||||
unsigned :version, 4
|
||||
# VRRP packet type
|
||||
unsigned :type, 4
|
||||
# Virtual Router Identifier (VRID)
|
||||
unsigned :id, 8
|
||||
# the sending VRRP router's priority for the virtual router.
|
||||
# Higher values equal higher priority.
|
||||
unsigned :priority, 8
|
||||
# Total number of IPs contained in this VRRP message
|
||||
unsigned :num_ips, 8
|
||||
# Authentication type (0, 1, 2)
|
||||
unsigned :auth_type, 8
|
||||
# Advertisement interval
|
||||
unsigned :interval, 8
|
||||
# Checksum
|
||||
unsigned :checksum, 16
|
||||
rest :payload
|
||||
|
||||
# Add a new IP to this message
|
||||
def add_ip(ip)
|
||||
@ips << L3::Misc.ipv42long(ip)
|
||||
end
|
||||
|
||||
# Add authentication data
|
||||
def add_auth(authdata)
|
||||
@authdata = authdata[0,8].ljust(32, "\x00")
|
||||
end
|
||||
|
||||
# Validate the checksum
|
||||
def checksum?
|
||||
self.checksum == compute_checksum
|
||||
end
|
||||
|
||||
# compute and set the checksum
|
||||
def checksum!
|
||||
self.checksum = compute_checksum
|
||||
end
|
||||
|
||||
# (really, just set the checksum)
|
||||
def fix!
|
||||
self.payload = [@ips, @authdata].flatten.pack("N#{@ips.size}a*")
|
||||
self.num_ips = @ips.size
|
||||
self.checksum!
|
||||
end
|
||||
|
||||
def initialize(*args)
|
||||
@ips = []
|
||||
@authdata = ""
|
||||
super
|
||||
end
|
||||
|
||||
private
|
||||
def compute_checksum
|
||||
# pseudo header used for checksum calculation as per RFC 768
|
||||
pseudo = [ ((self.version << 4) | self.type), self.id, self.priority, self.num_ips, self.auth_type, self.interval, 0, self.payload ]
|
||||
L3::Misc.checksum(pseudo.pack("CCCCCCna*"))
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
# vim: set ts=2 et sw=2:
|
|
@ -24,11 +24,7 @@
|
|||
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
require 'racket/l5/bootp'
|
||||
require 'racket/l5/ntp'
|
||||
require 'racket/l5/dns'
|
||||
require 'racket/l5/hsrp'
|
||||
require 'racket/l5/raw'
|
||||
|
||||
Dir.glob(File.join(File.dirname(__FILE__), 'l5/*.rb')).each { |f| require f }
|
||||
|
||||
# vim: set ts=2 et sw=2:
|
||||
|
|
|
@ -25,10 +25,11 @@
|
|||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
module Racket
|
||||
module L5
|
||||
# Bootstrap Protocol -- BOOTP
|
||||
#
|
||||
# RFC951 (http://www.faqs.org/rfcs/rfc951.html)
|
||||
module Racket
|
||||
class BOOTP < RacketPart
|
||||
BOOTP_REQUEST = 1
|
||||
BOOTP_REPLY = 2
|
||||
|
@ -65,7 +66,7 @@ class BOOTP < RacketPart
|
|||
rest :payload
|
||||
|
||||
def add_option(number, value)
|
||||
o = TLV.new(1,1)
|
||||
o = Misc::TLV.new(1,1)
|
||||
o.type = number
|
||||
o.value = value
|
||||
o.length = value.length
|
||||
|
@ -99,6 +100,7 @@ class BOOTP < RacketPart
|
|||
@autofix = false
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
# vim: set ts=2 et sw=2:
|
||||
|
|
|
@ -25,8 +25,9 @@
|
|||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# Domain Name System
|
||||
module Racket
|
||||
module L5
|
||||
# Domain Name System
|
||||
class DNS < RacketPart
|
||||
# Transaction ID
|
||||
unsigned :tx_id, 16
|
||||
|
@ -91,9 +92,9 @@ class DNS < RacketPart
|
|||
|
||||
private
|
||||
def add_record(name, type, klass)
|
||||
q = VT.new(2,2)
|
||||
q = Misc::VT.new(2,2)
|
||||
name.split(/\./).each do |p|
|
||||
lv = LV.new(1)
|
||||
lv = Misc::LV.new(1)
|
||||
lv.values << p
|
||||
lv.lengths << p.length
|
||||
q.value << lv.encode
|
||||
|
@ -103,6 +104,7 @@ private
|
|||
q
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
# vim: set ts=2 et sw=2:
|
||||
|
|
|
@ -25,10 +25,11 @@
|
|||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
module Racket
|
||||
module L5
|
||||
# Hot Standby Router Protocol: HSRP
|
||||
#
|
||||
# RFC2281 (http://www.faqs.org/rfcs/rfc2281.html)
|
||||
module Racket
|
||||
class HSRP < RacketPart
|
||||
HSRP_HELLO = 0
|
||||
HSRP_COUP = 1
|
||||
|
@ -58,6 +59,7 @@ class HSRP < RacketPart
|
|||
unsigned :priority, 8
|
||||
# Standby group
|
||||
unsigned :group, 8
|
||||
# reserved, never used, should be 0
|
||||
unsigned :reserved, 8
|
||||
# Clear-text, 8-character reused password. Defaults to 'cisco'
|
||||
text :password, 64, { :default => 'cisco' }
|
||||
|
@ -67,4 +69,5 @@ class HSRP < RacketPart
|
|||
rest :payload
|
||||
end
|
||||
end
|
||||
end
|
||||
# vim: set ts=2 et sw=2:
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
# $Id: misc.rb 167 2009-12-18 05:26:57Z jhart $
|
||||
#
|
||||
# Copyright (c) 2008, Jon Hart
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# * Neither the name of the <organization> nor the
|
||||
# names of its contributors may be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY Jon Hart ``AS IS'' AND ANY
|
||||
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL Jon Hart BE LIABLE FOR ANY
|
||||
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
module Racket
|
||||
module L5
|
||||
# Miscelaneous L3 helper methods
|
||||
module Misc
|
||||
end
|
||||
end
|
||||
end
|
||||
# vim: set ts=2 et sw=2:
|
|
@ -26,6 +26,8 @@
|
|||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
module Racket
|
||||
module L5
|
||||
# Network time protocol
|
||||
class NTP < RacketPart
|
||||
# Leap Indicator
|
||||
unsigned :leap, 2
|
||||
|
@ -52,5 +54,6 @@ class NTP < RacketPart
|
|||
rest :payload
|
||||
end
|
||||
end
|
||||
end
|
||||
# vim: set ts=2 et sw=2:
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $Id: misc.rb 14 2008-03-02 05:42:30Z warchild $
|
||||
# $Id: misc.rb 125 2009-11-29 01:15:58Z jhart $
|
||||
#
|
||||
# Copyright (c) 2008, Jon Hart
|
||||
# All rights reserved.
|
||||
|
@ -24,46 +24,7 @@
|
|||
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
module Racket
|
||||
module Misc
|
||||
# Return a number that is at most size bits long
|
||||
def Misc.randbits(size)
|
||||
bits = 0
|
||||
srand Time.now.usec
|
||||
0.upto(size-1) {
|
||||
bits <<= 1
|
||||
bits |= rand(2)
|
||||
}
|
||||
bits
|
||||
end
|
||||
|
||||
# Return a byte that is at most size bytes long
|
||||
def Misc.randbytes(size)
|
||||
bytes = 0
|
||||
0.upto(size-1) {
|
||||
bytes <<= 8
|
||||
bytes |= randbits(8)
|
||||
}
|
||||
bytes
|
||||
end
|
||||
Dir.glob(File.join(File.dirname(__FILE__), 'misc/*.rb')).each { |f| require f }
|
||||
|
||||
# Return a string that is at most size characters long
|
||||
def Misc.randstring(size)
|
||||
s = ""
|
||||
0.upto(size-1) {
|
||||
s += sprintf("%c", randbytes(1))
|
||||
}
|
||||
s
|
||||
end
|
||||
|
||||
# given a long representing a MAC address
|
||||
# print it out in human readable form
|
||||
def Misc.macaddr(long)
|
||||
long.to_s(16).rjust(12, '0').unpack("a2a2a2a2a2a2").join(":")
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
# vim: set ts=2 et sw=2:
|
||||
|
|
|
@ -0,0 +1,108 @@
|
|||
# $Id: lv.rb 14 2008-03-02 05:42:30Z warchild $
|
||||
#
|
||||
# Copyright (c) 2008, Jon Hart
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# * Neither the name of the <organization> nor the
|
||||
# names of its contributors may be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY Jon Hart ``AS IS'' AND ANY
|
||||
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL Jon Hart BE LIABLE FOR ANY
|
||||
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
module Racket
|
||||
module Misc
|
||||
# Simple class to represent data structures that
|
||||
# consist of an arbitrary number of length value pairs.
|
||||
class LV
|
||||
# An array containing the values parsed from this LV
|
||||
attr_accessor :values
|
||||
# The lengths of the values parsed from this LV
|
||||
attr_accessor :lengths
|
||||
# everything else
|
||||
attr_accessor :rest
|
||||
|
||||
# Create a new LV object whose L sizes are specified in +args+
|
||||
def initialize(*args)
|
||||
@sizes = args
|
||||
@values = []
|
||||
@lengths = []
|
||||
end
|
||||
|
||||
|
||||
def decode(data)
|
||||
n = 0
|
||||
values = []
|
||||
lengths = []
|
||||
@sizes.each do |s|
|
||||
# XXX: raise an error here if there is not enough data to
|
||||
# unpack this next LV
|
||||
lengths[n] = data.unpack("#{punpack_string(s)}")[0]
|
||||
data = data.slice(s, data.length)
|
||||
values[n] = data.unpack("a#{lengths[n]}")[0]
|
||||
data = data.slice(lengths[n], data.length)
|
||||
n += 1
|
||||
end
|
||||
|
||||
# data now contains "rest"
|
||||
[lengths, values, data]
|
||||
end
|
||||
|
||||
def decode!(data)
|
||||
@lengths, @values, @rest = self.decode(data)
|
||||
end
|
||||
|
||||
def encode
|
||||
n = 0
|
||||
s = ""
|
||||
@lengths.each do |l|
|
||||
s << [l].pack("#{punpack_string(@sizes[n])}")
|
||||
s << [@values[n]].pack("a#{l}")
|
||||
n += 1
|
||||
end
|
||||
s
|
||||
end
|
||||
|
||||
def to_s
|
||||
encode
|
||||
end
|
||||
|
||||
def to_str
|
||||
encode
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def punpack_string(size)
|
||||
s = ""
|
||||
case size
|
||||
when 1
|
||||
s << "C"
|
||||
when 2
|
||||
s << "n"
|
||||
when 4
|
||||
s << "N"
|
||||
else
|
||||
raise ArgumentError, "Size #{s} not supported"
|
||||
end
|
||||
s
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
# vim: set ts=2 et sw=2:
|
|
@ -0,0 +1,61 @@
|
|||
# $Id: misc.rb 14 2008-03-02 05:42:30Z warchild $
|
||||
#
|
||||
# Copyright (c) 2008, Jon Hart
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# * Neither the name of the <organization> nor the
|
||||
# names of its contributors may be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY Jon Hart ``AS IS'' AND ANY
|
||||
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL Jon Hart BE LIABLE FOR ANY
|
||||
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
module Racket
|
||||
module Misc
|
||||
# Return a number that is at most size bits long
|
||||
def Misc.randbits(size)
|
||||
bits = 0
|
||||
srand Time.now.usec
|
||||
0.upto(size-1) {
|
||||
bits <<= 1
|
||||
bits |= rand(2)
|
||||
}
|
||||
bits
|
||||
end
|
||||
|
||||
# Return a byte that is at most size bytes long
|
||||
def Misc.randbytes(size)
|
||||
bytes = 0
|
||||
0.upto(size-1) {
|
||||
bytes <<= 8
|
||||
bytes |= randbits(8)
|
||||
}
|
||||
bytes
|
||||
end
|
||||
|
||||
# Return a string that is at most size characters long
|
||||
def Misc.randstring(size)
|
||||
s = ""
|
||||
0.upto(size-1) {
|
||||
s += sprintf("%c", randbytes(1))
|
||||
}
|
||||
s
|
||||
end
|
||||
end
|
||||
end
|
||||
# vim: set ts=2 et sw=2:
|
|
@ -0,0 +1,63 @@
|
|||
# $Id: orderedhash.rb 14 2008-03-02 05:42:30Z warchild $
|
||||
#
|
||||
# Copyright (c) 2008, Jon Hart
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# * Neither the name of the <organization> nor the
|
||||
# names of its contributors may be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY Jon Hart ``AS IS'' AND ANY
|
||||
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL Jon Hart BE LIABLE FOR ANY
|
||||
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
module Racket
|
||||
module Misc
|
||||
# Simple ordered hash.
|
||||
#
|
||||
# XXX: todo -- add a method for moving/shifting
|
||||
# members around
|
||||
class OrderedHash < Hash
|
||||
def initialize
|
||||
@keys = []
|
||||
end
|
||||
|
||||
def []=(key, val)
|
||||
@keys << key unless (self[key])
|
||||
super
|
||||
end
|
||||
|
||||
def delete(key)
|
||||
@keys.delete(key)
|
||||
super
|
||||
end
|
||||
|
||||
def each
|
||||
@keys.each { |k| yield k, self[k] }
|
||||
end
|
||||
|
||||
def each_key
|
||||
@keys.each { |k| yield k }
|
||||
end
|
||||
|
||||
def each_value
|
||||
@keys.each { |k| yield self[k] }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
# vim: set ts=2 et sw=2:
|
|
@ -0,0 +1,103 @@
|
|||
# $Id: tlv.rb 14 2008-03-02 05:42:30Z warchild $
|
||||
#
|
||||
# Copyright (c) 2008, Jon Hart
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# * Neither the name of the <organization> nor the
|
||||
# names of its contributors may be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY Jon Hart ``AS IS'' AND ANY
|
||||
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL Jon Hart BE LIABLE FOR ANY
|
||||
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
module Racket
|
||||
module Misc
|
||||
# Simple class for your average type, length, value datastructure.
|
||||
# Everything after the TLV is stuff into +rest+
|
||||
class TLV
|
||||
attr_accessor :type, :length, :value, :rest, :lbytes, :tlinclude
|
||||
|
||||
# Create a new TLV which requires +ts+ bytes for the type field
|
||||
# and +ls+ bytes for the length field, where (optionally) the value
|
||||
# in +length+ is a multiple of +lbytes+ and (optionally) whether or not
|
||||
# the length field indicates the total length of the TLV of just that of
|
||||
# the value
|
||||
def initialize(ts, ls, lbytes=1, tlinclude=false)
|
||||
@ts = ts
|
||||
@ls = ls
|
||||
@lbytes = lbytes
|
||||
@tlinclude = tlinclude
|
||||
end
|
||||
|
||||
# Given +data+, return the type, length, value and rest
|
||||
# values as dictated by this instance.
|
||||
def decode(data)
|
||||
s = "#{punpack_string(@ts)}#{punpack_string(@ls)}"
|
||||
type, length, tmp = data.unpack("#{s}a*")
|
||||
if (type.nil? or length.nil?)
|
||||
nil
|
||||
else
|
||||
elength = (length * lbytes) - (@tlinclude ? (@ls + @ts) : 0)
|
||||
value, rest = tmp.unpack("a#{elength}a*")
|
||||
if (value.empty? and length > 0)
|
||||
nil
|
||||
else
|
||||
[type, length, value, rest]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def decode!(data)
|
||||
@type, @length, @value, @rest = self.decode(data)
|
||||
end
|
||||
|
||||
# Return a string suitable for use elswhere.
|
||||
def encode
|
||||
s = "#{punpack_string(@ts)}#{punpack_string(@ls)}"
|
||||
[@type, @length, @value].pack("#{s}a*")
|
||||
end
|
||||
|
||||
def to_s
|
||||
encode
|
||||
end
|
||||
|
||||
def to_str
|
||||
encode
|
||||
end
|
||||
|
||||
private
|
||||
# XXX: make this handle arbitrarily sized fields
|
||||
def punpack_string(size)
|
||||
s = ""
|
||||
case size
|
||||
when 1
|
||||
s << "C"
|
||||
when 2
|
||||
s << "n"
|
||||
when 4
|
||||
s << "N"
|
||||
else
|
||||
raise ArgumentError, "Size #{s} is not a supported conversion size"
|
||||
end
|
||||
s
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
# vim: set ts=2 et sw=2:
|
|
@ -0,0 +1,114 @@
|
|||
# $Id: vt.rb 14 2008-03-02 05:42:30Z warchild $
|
||||
#
|
||||
# Copyright (c) 2008, Jon Hart
|
||||
# All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are met:
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution.
|
||||
# * Neither the name of the <organization> nor the
|
||||
# names of its contributors may be used to endorse or promote products
|
||||
# derived from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY Jon Hart ``AS IS'' AND ANY
|
||||
# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
# DISCLAIMED. IN NO EVENT SHALL Jon Hart BE LIABLE FOR ANY
|
||||
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
module Racket
|
||||
module Misc
|
||||
# Simple class to represent a datastructure that is made up of a
|
||||
# null terminted string followed by an arbitrary number of
|
||||
# arbitrarily sized values, followed by a "rest" field.
|
||||
class VT
|
||||
# the value for this VT object
|
||||
attr_accessor :value
|
||||
# the array of types for this VT object
|
||||
attr_accessor :types
|
||||
# everything else
|
||||
attr_accessor :rest
|
||||
|
||||
# Create a new VT which consists of a null terminated string
|
||||
# followed by some number of arbitrarily sized values, as
|
||||
# specified by +args+
|
||||
def initialize(*args)
|
||||
@lengths = args
|
||||
@types = []
|
||||
@value = ""
|
||||
end
|
||||
|
||||
# Given +data+, return the value and an array
|
||||
# of the types as dictated by this instance
|
||||
def decode(data)
|
||||
null = data.index(0x00)
|
||||
value = data.unpack("a#{null}")[0]
|
||||
data = data.slice(null+1, data.length)
|
||||
|
||||
n = 0
|
||||
types = []
|
||||
@lengths.each do |l|
|
||||
types[n] = data.unpack("#{punpack_string(l)}")[0]
|
||||
data = data.slice(l, data.length)
|
||||
n += 1
|
||||
end
|
||||
|
||||
[value, types, data]
|
||||
end
|
||||
|
||||
# Given +data+, set the +value+ and +types+ array
|
||||
# accordingly
|
||||
def decode!(data)
|
||||
@value, @types, @rest = self.decode(data)
|
||||
end
|
||||
|
||||
# Return a string suitable for use elsewhere
|
||||
def encode
|
||||
s = "#{@value}\000"
|
||||
|
||||
n = 0
|
||||
@lengths.each do |l|
|
||||
s << [@types[n]].pack("#{punpack_string(l)}")
|
||||
n += 1
|
||||
end
|
||||
s
|
||||
end
|
||||
|
||||
def to_s
|
||||
encode
|
||||
end
|
||||
|
||||
def to_str
|
||||
encode
|
||||
end
|
||||
|
||||
private
|
||||
# XXX: make this handle arbitrarily sized fields
|
||||
def punpack_string(size)
|
||||
s = ""
|
||||
case size
|
||||
when 1
|
||||
s << "C"
|
||||
when 2
|
||||
s << "n"
|
||||
when 4
|
||||
s << "N"
|
||||
else
|
||||
raise ArgumentError, "Size #{s} not supported"
|
||||
end
|
||||
s
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
# vim: set ts=2 et sw=2:
|
|
@ -27,18 +27,13 @@
|
|||
#
|
||||
|
||||
require 'socket'
|
||||
|
||||
require 'racket/racketpart'
|
||||
require 'racket/tlv'
|
||||
require 'racket/lv'
|
||||
require 'racket/vt'
|
||||
require 'racket/misc'
|
||||
require 'racket/l2'
|
||||
require 'racket/l3'
|
||||
require 'racket/l4'
|
||||
require 'racket/l5'
|
||||
|
||||
|
||||
module Racket
|
||||
class Racket
|
||||
|
||||
|
@ -47,11 +42,12 @@ class Racket
|
|||
|
||||
@@loaded_pcaprub = false
|
||||
begin
|
||||
require 'pcaprub'
|
||||
@@loaded_pcaprub = true
|
||||
require 'pcaprub'
|
||||
@@loaded_pcaprub = true
|
||||
rescue ::LoadError
|
||||
end
|
||||
|
||||
|
||||
def initialize(payload="")
|
||||
@layers = []
|
||||
@mtu = 1500
|
||||
|
@ -102,6 +98,7 @@ class Racket
|
|||
payload
|
||||
end
|
||||
|
||||
# return a pretty interpretation of this packet
|
||||
def pretty
|
||||
s = ""
|
||||
@layers.compact.each do |l|
|
||||
|
@ -125,10 +122,10 @@ class Racket
|
|||
# Write raw layer2 frames
|
||||
def send2
|
||||
if(not @@loaded_pcaprub)
|
||||
raise RuntimeError, "Could not initialize the pcaprub library"
|
||||
end
|
||||
|
||||
raise RuntimeError, "Could not initialize the pcaprub library (You need pcaprub from SVN (http://rubyforge.org/projects/pcaprub/))"
|
||||
end
|
||||
begin
|
||||
|
||||
p = Pcap::open_live(@iface, @mtu, false, @timeout)
|
||||
rescue Exception => e
|
||||
puts "Pcap: can't open device '#{@iface}' (#{e})"
|
||||
|
@ -137,7 +134,7 @@ class Racket
|
|||
|
||||
begin
|
||||
b = p.inject(pack)
|
||||
p.close
|
||||
#p.pcap_close
|
||||
return b
|
||||
rescue Exception => e
|
||||
puts "Pcap: error while sending packet on '#{@iface}' (#{e})"
|
||||
|
@ -148,16 +145,20 @@ class Racket
|
|||
def send3
|
||||
begin
|
||||
s = Socket.open(Socket::PF_INET, Socket::SOCK_RAW, Socket::IPPROTO_RAW)
|
||||
#s.setsockopt(Socket::SOL_IP, Socket::IP_HDRINCL, true)
|
||||
|
||||
if (Socket.const_defined?('SOL_IP'))
|
||||
s.setsockopt(Socket::SOL_IP, Socket::IP_HDRINCL, true)
|
||||
else
|
||||
# BSD
|
||||
s.setsockopt(Socket::IPPROTO_IP, Socket::IP_HDRINCL, true)
|
||||
end
|
||||
rescue Errno::EPERM
|
||||
$stderr.puts "Must run #{$0} as root."
|
||||
exit!
|
||||
raise ArgumentError, "Must run #{$0} as root."
|
||||
end
|
||||
|
||||
return s.send(pack, 0, Socket.pack_sockaddr_in(1024, @layers[3].dst_ip))
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# vim: set ts=2 et sw=2:
|
||||
|
|
|
@ -25,9 +25,11 @@
|
|||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
require 'rubygems'
|
||||
require 'bit-struct'
|
||||
|
||||
module Racket
|
||||
# Every Racket object is made up of numerous sub-parts, namely layers of the OSI stack.
|
||||
class RacketPart < BitStruct
|
||||
|
||||
# Boolean indicating whether or not this instance should be
|
||||
|
@ -42,9 +44,10 @@ class RacketPart < BitStruct
|
|||
|
||||
def initialize(*args)
|
||||
@autofix = true
|
||||
super
|
||||
super(*args)
|
||||
end
|
||||
|
||||
|
||||
# Print out all of the fields and all of their values
|
||||
def pretty
|
||||
s = ""
|
||||
|
|
Loading…
Reference in New Issue