Hey everyone!

Here is a patch (quite a big one) to upgrade Scruby included into the Framework to version 0.3, which supports Dot11 dissectors shamelessly copied from Scapy.

New dissectors:
Dot11*
LLC
ARP

New fields:
Dot11*
FlagsField
FieldLenField
StrLenField

--
Sylvain SARMEJEANNE
diff -r -u metasploit/lib/scruby/const.rb metasploit_new/lib/scruby/const.rb
--- metasploit/lib/scruby/const.rb	2008-03-03 20:56:44.000000000 +0000
+++ metasploit_new/lib/scruby/const.rb	2008-03-09 22:59:17.000000000 +0000
@@ -13,11 +13,17 @@
 module Scruby
 
 	# Scruby version
-	SCRUBY_VERSION = '0.2.1-hdm-2'
+	SCRUBY_VERSION = '0.3-hdm'
 
 	# Completion for functions
 	FUNCTIONS_LIST = %w[sendp sniff ls lsc]
 
+	# Link types that are not implented in Pcap
+	DLT_OPENBSD = 12
+
+	# Pcap::DLT_IEEE802 is 6 but on my system, sniffing on ath0 return 105 as link type
+	DLT_IEEE80211 = 105
+
 	# History
 	RECORD_HISTORY = true
 
@@ -31,23 +37,111 @@
 	TIMEOUT = 1
 	LOOPBACK_DEVICE_PREFIX = 'lo'
 
+	# If two layers are to be bound every time
+	BIND_ALWAYS = ''
+
 	# Constants for Ethernet
 	ETHERTYPE_IPv4 = 0x800
-	ETHERTYPE_ALL = { ETHERTYPE_IPv4 => "IPv4"}
+	ETHERTYPE_ARP = 0x806
+	ETHERTYPE_ALL = { ETHERTYPE_IPv4 => 'IPv4',
+			  ETHERTYPE_ARP => 'ARP' }
+	ETHERADDR_ANY = '00:00:00:00:00:00'
+
+	# Constants for ARP
+	ARPTYPE_WHOAS = 1
+	ARPTYPE_ISAT = 2
+	ARPTYPE_RARP_REQ = 3
+	ARPTYPE_RARP_RES = 4
+	ARPTYPE_DYN_RARP_REQ = 5
+	ARPTYPE_DYN_RARP_REP = 6
+	ARPTYPE_DYN_RARP_ERR = 7
+	ARPTYPE_IN_ARP_REQ = 8
+	ARPTYPE_IN_ARP_REP = 9
+
+	ARPTYPE_ALL = { ARPTYPE_WHOAS => 'who-as',
+        	        ARPTYPE_ISAT => 'is-at',
+	                ARPTYPE_RARP_REQ => 'RARP-req',
+	                ARPTYPE_RARP_RES => 'RARP-rep',
+	                ARPTYPE_DYN_RARP_REQ => 'DynRARP-req',
+	                ARPTYPE_DYN_RARP_REP => 'DynRARP-rep',
+	                ARPTYPE_DYN_RARP_ERR => 'DynRARP-err',
+	                ARPTYPE_IN_ARP_REQ => 'InARP-req',
+        	        ARPTYPE_IN_ARP_REP => 'InARP-rep' }
+
+	ARPHWTYPE_ETHER = 1
+	ARPHWTYPE_FRAME_RELAY = 15
+	ARPHWTYPE_ALL = { ARPHWTYPE_ETHER => 'Ethernet',
+        	          ARPHWTYPE_FRAME_RELAY => 'FrameRelay' }
+
+	ARPHWLEN_TOKEN_RING = 1
+	ARPHWLEN_ETHER = 6
+	ARPHWLEN_ALL = { ARPHWLEN_TOKEN_RING => 'TokenRing',
+	                 ARPHWLEN_ETHER => 'Ethernet' }
+
+	ARPPROTOLEN_IPv4 = 4
+	ARPPROTOLEN_IPv6 = 16
+	ARPPROTOLEN_ALL = { ARPPROTOLEN_IPv4 => 'IPv4',
+	                    ARPPROTOLEN_IPv6 => 'IPv6' }
 
 	# Constants for BSD loopback interfaces
 	BSDLOOPBACKTYPE_IPv4 = 2
 
 	# Constants for IP
+	IPFLAGS = %w[MF DF evil]
+
 	IPPROTO_ICMP = 1
 	IPPROTO_TCP = 6
 	IPPROTO_UDP = 17
-	IPPROTO_ALL = { IPPROTO_ICMP => "ICMP",
-                	IPPROTO_TCP => "TCP",
-                	IPPROTO_UDP => "UDP" }
+	IPPROTO_ALL = { IPPROTO_ICMP => 'ICMP',
+                	IPPROTO_TCP => 'TCP',
+                	IPPROTO_UDP => 'UDP' }
+
+	# Constants for TCP
+	TCPFLAGS = %w[FIN SYN RST PSH ACK URG ECN RES]
 
 	# Constants for ICMP
-	ICMPTYPE_ECHO = 8
+	ICMPTYPE_ECHO_REQ = 8
+	ICMPTYPE_ALL = { ICMPTYPE_ECHO_REQ => 'echo request' }
+
+	# Constants for 802.11
+	DOT11TYPE_MANAGEMENT = 0
+	DOT11TYPE_CONTROL = 1
+	DOT11TYPE_DATA = 2
+	DOT11TYPE_RESERVED = 3
+
+	DOT11TYPE_ALL = { DOT11TYPE_MANAGEMENT => 'Management',
+	                  DOT11TYPE_CONTROL => 'Control',
+	                  DOT11TYPE_DATA => 'Data',
+	                  DOT11TYPE_RESERVED => 'Reserved' }
+
+	DOT11SUBTYPE_PS_POLL = 0b1010
+	DOT11SUBTYPE_RTS = 0b1011
+	DOT11SUBTYPE_CF_END = 0b1110
+	DOT11SUBTYPE_CF_END_CF_ACK = 0b1111
+
+	DOT11_FC_FLAGS = %w[to-DS from-DS MF retry pw-mgt MD wep order]
+
+	DOT11_CAPABILITIES = %w[res8 res9 short-slot res11 res12 DSSS-OFDM res14 res15 ESS IBSS CFP CFP-req privacy short-preamble PBCC agility]
+
+	DOT11_ID = {0 => 'SSID', 1 => 'Rates', 2 =>  'FHset', 3 => 'DSset', 4 => 'CFset', 5 => 'TIM', 6 => 'IBSSset', 16 => 'challenge', 42 => 'ERPinfo', 46 => 'QoS Capability', 47 => 'ERPinfo', 48 => 'RSNinfo', 50 => 'ESRates',221 => 'vendor',68 => 'reserved'}
+
+	DOT11_REASON = {0 => 'reserved',1 => 'unspec', 2 => 'auth-expired',
+	               3 => 'deauth-ST-leaving',
+	               4 => 'inactivity', 5 => 'AP-full', 6 => 'class2-from-nonauth',
+	               7 => 'class3-from-nonass', 8 => 'disas-ST-leaving',
+	               9 => 'ST-not-auth'}
+
+	DOT11_AUTH_ALGO = {0 => 'open', 1 => 'sharedkey'}
+
+	DOT11_STATUS = {0 => 'success', 1 => 'failure', 10 => 'cannot-support-all-cap',
+	               11 => 'inexist-asso', 12 => 'asso-denied', 13 => 'algo-unsupported',
+	               14 => 'bad-seq-num', 15 => 'challenge-failure',
+	               16 => 'timeout', 17 => 'AP-full', 18 => 'rate-unsupported'}
+
+	RADIOTAP_PRESENT = %w[TSFT Flags Rate Channel FHSS dBm_AntSignal dBm_AntNoise Lock_Quality TX_Attenuation dB_TX_Attenuation
+                      dBm_TX_Power Antenna dB_AntSignal dB_AntNoise
+                      b14 b15 b16 b17 b18 b19 b20 b21 b22 b23
+                      b24 b25 b26 b27 b28 b29 b30 Ext]
 
 	def self.aware_proto
 		@@aware_proto
diff -r -u metasploit/lib/scruby/dissector.rb metasploit_new/lib/scruby/dissector.rb
--- metasploit/lib/scruby/dissector.rb	2008-03-03 20:56:44.000000000 +0000
+++ metasploit_new/lib/scruby/dissector.rb	2008-03-10 22:18:42.000000000 +0000
@@ -37,39 +37,54 @@
 	# Dissector for Ethernet
 	class Ether<Layer
 		Scruby.register_dissector(self)
-		def method_missing(method, *args)
-			return Scruby.field(method, *args)
-		end
 
 		attr_accessor :dst, :src, :type
 
 		def init
 			@protocol = 'Ethernet'
-			@fields_desc =  [ MACField('dst', '00:00:00:00:00:00'),
-								MACField('src', '00:00:00:00:00:00'),
-								XShortField('type', ETHERTYPE_IPv4) ]
+			@fields_desc =  [ MACField('dst', ETHERADDR_ANY),
+								MACField('src', ETHERADDR_ANY),
+								XShortEnumField('type', ETHERTYPE_IPv4, ETHERTYPE_ALL) ]
 		end
 		
 	end
 
+	# Dissector for ARP
+	class ARP<Layer
+		Scruby.register_dissector(self)
+
+		attr_accessor :hwtype, :ptype, :hwlen, :plen, :op, :hwsrc, :psrc, :hwdst, :pdst
+
+		def init
+			@protocol = 'ARP'
+			@fields_desc = [ XShortEnumField('hwtype', ARPHWTYPE_ETHER, ARPHWTYPE_ALL),
+							XShortEnumField('ptype',  ETHERTYPE_IPv4, ETHERTYPE_ALL),
+							ByteEnumField('hwlen', ARPHWLEN_ETHER, ARPHWLEN_ALL),
+							ByteEnumField('plen', ARPPROTOLEN_IPv4, ARPPROTOLEN_ALL),
+							ShortEnumField('op', ARPTYPE_WHOAS, ARPTYPE_ALL),
+							MACField('hwsrc', ETHERADDR_ANY),
+							IPField('psrc','127.0.0.1'),
+							MACField('hwdst', ETHERADDR_ANY),
+							IPField('pdst', '127.0.0.1') ]
+end
+
+end
+
 	# Dissector for IPv4
 	class IP<Layer
 		Scruby.register_dissector(self)
-		def method_missing(method, *args)
-			return Scruby.field(method, *args)
-		end
-
+		
 		attr_accessor :version, :ihl, :tos, :len, :id, :flags, :frag
 		attr_accessor :ttl, :proto, :chksum, :src, :dst
 
 		def init
 			@protocol = 'IPv4'
-			@fields_desc = [ BitField("version", 4, 4),
-							BitField("ihl", 5, 4),
+			@fields_desc = [ BitField('version', 4, 4),
+							BitField('ihl', 5, 4),
 							XByteField('tos', 0),
 							ShortField('len', 20),
 							XShortField('id', 0),
-							BitField('flags', 0, 3),
+							FlagsField('flags', 0, 3, IPFLAGS),
 							BitField('frag', 0, 13),
 							ByteField('ttl', 64),
 							ByteEnumField('proto', IPPROTO_TCP, IPPROTO_ALL),
@@ -92,15 +107,12 @@
 	# Dissector for ICMP
 	class ICMP<Layer
 		Scruby.register_dissector(self)
-		def method_missing(method, *args)
-			return Scruby.field(method, *args)
-		end
-
+		
 		attr_accessor :type, :code, :chksum, :id, :seq
 
 		def init
 			@protocol = 'ICMP'
-			@fields_desc = [ ByteField('type', ICMPTYPE_ECHO),
+			@fields_desc = [ ByteEnumField('type', ICMPTYPE_ECHO_REQ, ICMPTYPE_ALL),
 							ByteField('code', 0),
 							XShortField('chksum', 0),
 							XShortField('id', 0),
@@ -118,10 +130,7 @@
 	# Dissector for Raw
 	class Raw<Layer
 		Scruby.register_dissector(self)
-		def method_missing(method, *args)
-			return Scruby.field(method, *args)
-		end
-
+		
 		attr_accessor :load
 
 		def init
@@ -134,9 +143,6 @@
 	# Dissector for TCP
 	class TCP<Layer
 		Scruby.register_dissector(self)
-		def method_missing(method, *args)
-			return Scruby.field(method, *args)
-		end
 
 		attr_accessor :sport, :dport, :seq, :ack, :dataofs, :reserved
 		attr_accessor :flags, :window, :chksum, :urgptr
@@ -147,9 +153,9 @@
 							ShortField('dport', 80),
 							IntField('seq', 0),
 							IntField('ack', 0),
-							BitField("dataofs", 5, 4),
-							BitField("reserved", 0, 4),
-							XByteField('flags', 0x2),
+							BitField('dataofs', 5, 4),
+							BitField('reserved', 0, 4),
+							FlagsField('flags', 0x2, 8, TCPFLAGS),
 							ShortField('window', 8192),
 							XShortField('chksum', 0),
 							ShortField('urgptr', 0) ]
@@ -183,10 +189,7 @@
 	# Dissector for UDP
 	class UDP<Layer
 		Scruby.register_dissector(self)
-		def method_missing(method, *args)
-			return Scruby.field(method, *args)
-		end
-
+		
 		attr_accessor :sport, :dport, :len, :chksum
 
 		def init
@@ -229,10 +232,7 @@
 	# Dissector for the classic BSD loopback header (NetBSD, FreeBSD and Mac OS X)
 	class ClassicBSDLoopback<Layer
 		Scruby.register_dissector(self)
-		def method_missing(method, *args)
-			return Scruby.field(method, *args)
-		end
-
+		
 		attr_accessor :header
 
 		def init
@@ -245,10 +245,7 @@
 	# Dissector for the OpenBSD loopback header
 	class OpenBSDLoopback<Layer
 		Scruby.register_dissector(self)
-		def method_missing(method, *args)
-			return Scruby.field(method, *args)
-		end
-
+		
 		attr_accessor :header
 
 		def init
@@ -262,10 +259,7 @@
 	# Dissector for the Prism header
 	class Prism<Layer
 		Scruby.register_dissector(self)
-		def method_missing(method, *args)
-			return Scruby.field(method, *args)
-		end
-
+		
 		attr_accessor :header
 
 		def init
@@ -318,43 +312,12 @@
 		end
 
 	end
-
-=begin
-	class Dot11<Layer
-		Scruby.register_dissector(self)
-		def method_missing(method, *args)
-			return Scruby.field(method, *args)
-		end
-
-		attr_accessor :header
-
-		def init
-			@protocol = '802.11'
-			@fields_desc = [
-				BitField("subtype", 0, 4),
-				BitEnumField("type", 0, 2, ["Management", "Control", "Data", "Reserved"]),
-				BitField("proto", 0, 2),
-				FlagsField("FCfield", 0, 8, ["to-DS", "from-DS", "MF", "retry", "pw-mgt", "MD", "wep", "order"]),
-				ShortField("ID",0),
-				MACField("addr1", ETHER_ANY),
-				Dot11Addr2MACField("addr2", ETHER_ANY),
-				Dot11Addr3MACField("addr3", ETHER_ANY),
-				Dot11SCField("SC", 0),
-				Dot11Addr4MACField("addr4", ETHER_ANY) 
-			]
-		end
-
-	end
-=end
 		
 	# Dissector for RIFF file format header
 	class RIFF<Layer
 		Scruby.register_dissector(self)
-		def method_missing(method, *args)
-			return Scruby.field(method, *args)
-		end
 
-		attr_accessor :id, :size
+		attr_accessor :id, :size, :headerid
 
 		def init
 			@protocol = 'RIFF chunk'
@@ -368,11 +331,8 @@
 	# Dissector for ANI header chunk  format
 	class ANI<Layer
 		Scruby.register_dissector(self)
-		def method_missing(method, *args)
-			return Scruby.field(method, *args)
-		end
-
-		attr_accessor :headersize, :frames, :steps, :width, :height, :bitcount, :planes
+		
+		attr_accessor :id, :size, :headersize, :frames, :steps, :width, :height, :bitcount, :planes
 		attr_accessor :displayrate, :reserved, :sequence, :icon
 
 		def init
@@ -394,14 +354,278 @@
 
 	end
 
+	# Dot11 dissectors
+	class Dot11<Layer
+		Scruby.register_dissector(self)
+
+		attr_accessor :subtype, :type, :proto, :FCfield, :ID, :addr1, :addr2, :addr3, :SC, :addr4
+
+		def init
+			@protocol = '802.11'
+			@fields_desc = [ BitField('subtype', 0, 4),
+							BitEnumField('type', DOT11TYPE_DATA, 2, DOT11TYPE_ALL),
+							BitField('proto', 0, 2),
+							FlagsField('FCfield', 0, 8, DOT11_FC_FLAGS),
+							ShortField('ID', 0),
+							MACField('addr1', ETHERADDR_ANY),
+							Dot11Addr2MACField('addr2', ETHERADDR_ANY),
+							Dot11Addr3MACField('addr3', ETHERADDR_ANY),
+							Dot11SCField('SC', 0),
+							Dot11Addr4MACField('addr4', ETHERADDR_ANY) ]
+		end
+
+	end
+
+	class Dot11QoS<Layer
+		Scruby.register_dissector(self)
+
+		attr_accessor :TID, :EOSP, :AckPolicy, :Reserved, :TXOP
+
+		def init
+			@protocol = '802.11 QoS'
+			@fields_desc = [ BitField('TID',0,4),
+							BitField('EOSP',0,1),
+							BitField('AckPolicy',0,2),
+							BitField('Reserved',0,1),
+							ByteField('TXOP',0) ]
+		end
+
+	end
+
+	class Dot11Beacon<Layer
+		Scruby.register_dissector(self)
+
+		attr_accessor :timestamp, :beacon_interval, :cap
+
+		def init
+			@protocol = '802.11 Beacon'
+			@fields_desc = [ LongField('timestamp', 0), # Bug: should be little endian
+							LEShortField('beacon_interval', 0x64),
+							FlagsField('cap', 0, 16, DOT11_CAPABILITIES) ]
+		end
+
+	end
+
+	class Dot11Elt<Layer
+		Scruby.register_dissector(self)
+
+		attr_accessor :ID, :len, :info
+
+		def init
+			@protocol = '802.11 Information Element'
+			@fields_desc = [ ByteEnumField('ID', 0, DOT11_ID),
+							FieldLenField('len', 0, 'info', 'C'),
+							StrLenField('info', '', 'len') ]
+		end
+
+	end
+
+	class Dot11ATIM<Layer
+		Scruby.register_dissector(self)
+
+		def init
+			@protocol = '802.11 ATIM'
+		end
+	end
+
+	class Dot11Disas<Layer
+		Scruby.register_dissector(self)
+
+		attr_accessor :reason
+
+		def init
+			@protocol = '802.11 Disassociation'
+			@fields_desc = [ LEShortEnumField('reason', 1, DOT11_REASON) ]
+		end
+
+	end
+
+	class Dot11AssoReq<Layer
+		Scruby.register_dissector(self)
+
+		attr_accessor :cap, :listen_interval
+
+		def init
+			@protocol = '802.11 Association Request'
+			@fields_desc = [ FlagsField('cap', 0, 16, DOT11_CAPABILITIES),
+							LEShortField('listen_interval', 0xc8) ]
+		end
+
+	end
+
+	class Dot11AssoResp<Layer
+		Scruby.register_dissector(self)
+
+		attr_accessor :cap, :status, :AID
+
+		def init
+			@protocol = '802.11 Association Response'
+			@fields_desc = [ FlagsField('cap', 0, 16, DOT11_CAPABILITIES),
+							LEShortField('status', 0),
+							LEShortField('AID', 0) ]
+		end
+
+	end
+
+	class Dot11ReassoReq<Layer
+		Scruby.register_dissector(self)
+
+		attr_accessor :cap, :current_AP, :listen_interval
+
+		def init
+			@protocol = '802.11 Reassociation Request'
+			@fields_desc = [ FlagsField('cap', 0, 16, DOT11_CAPABILITIES),
+							MACField('current_AP', ETHERADDR_ANY),
+							LEShortField('listen_interval', 0xc8) ]
+		end
+
+	end
+
+	class Dot11ReassoResp<Dot11AssoResp
+		Scruby.register_dissector(self)
+
+		def init
+			@protocol = '802.11 Reassociation Response'
+		end
+	end
+
+	class Dot11ProbeReq<Layer
+		Scruby.register_dissector(self)
+
+		def init
+			@protocol = '802.11 Probe Request'
+		end
+	end
+
+	class Dot11ProbeResp<Layer
+		Scruby.register_dissector(self)
+
+		attr_accessor :timestamp, :beacon_interval, :cap
+
+		def init
+			@protocol = '802.11 Probe Response'
+			@fields_desc = [ LongField('timestamp', 0), # Bug: should be little endian
+							LEShortField('beacon_interval', 0x64),
+							FlagsField('cap', 0, 16, DOT11_CAPABILITIES) ]
+		end
+
+	end
+
+	class Dot11Auth<Layer
+		Scruby.register_dissector(self)
+
+		attr_accessor :algo, :seqnum, :status
+
+		def init
+			@protocol = '802.11 Authentication'
+			@fields_desc = [ LEShortEnumField('algo', 0, DOT11_AUTH_ALGO),
+							LEShortField('seqnum', 0),
+							LEShortEnumField('status', 0, DOT11_STATUS) ]
+		end
+
+	end
+
+	class Dot11Deauth<Layer
+		Scruby.register_dissector(self)
+
+		attr_accessor :reason
+
+		def init
+			@protocol = '802.11 Deauthentication'
+			@fields_desc = [ LEShortEnumField('reason', 1, DOT11_REASON) ]
+		end
+
+	end
+
+	class Dot11WEP<Layer
+		Scruby.register_dissector(self)
+
+		attr_accessor :iv, :keyid, :wepdata, :icv
+
+		def init
+			@protocol = '802.11 WEP packet'
+			@fields_desc = [ StrFixedLenField('iv', "\0\0\0", 3),
+							ByteField('keyid', 0),
+							StrField('wepdata', ''), # Bug: 4 bytes remains
+							IntField('icv', 0) ]
+		end
+
+	end
+
+	class LLC<Layer
+		Scruby.register_dissector(self)
+
+		attr_accessor :dsap, :ssap, :ctrl
+
+		def init
+			@protocol = 'LLC'
+			@fields_desc = [ XByteField('dsap', 0),
+							XByteField('ssap', 0),
+							ByteField('ctrl', 0) ]
+		end
+
+	end
+
 	# Layer bounds
 	@@layer_bounds =
 	{
 		'Ether' => 
 		[
-			['type', ETHERTYPE_IPv4, IP]
+			['type', ETHERTYPE_IPv4, IP],
+			['type', ETHERTYPE_ARP, ARP]
+		],
+
+		'Prism' =>
+		[
+			[BIND_ALWAYS, BIND_ALWAYS, Dot11]
+		],
+
+		'Dot11' => [
+			['type', 2, LLC],
+			['subtype', 0, Dot11AssoReq],
+			['subtype', 1, Dot11AssoResp],
+			['subtype', 2, Dot11ReassoReq],
+			['subtype', 3, Dot11ReassoResp],
+			['subtype', 4, Dot11ProbeReq],
+			['subtype', 5, Dot11ProbeResp],
+			['subtype', 8, Dot11Beacon],
+			['subtype', 9, Dot11ATIM],
+			['subtype', 10, Dot11Disas],
+			['subtype', 11, Dot11Auth],
+			['subtype', 12, Dot11Deauth],
 		],
 
+		'Dot11QoS' => [
+			[BIND_ALWAYS, BIND_ALWAYS, LLC]
+		],
+		'Dot11Beacon' => [
+			[BIND_ALWAYS, BIND_ALWAYS, Dot11Elt]
+		],
+		'Dot11AssoReq' => [
+			[BIND_ALWAYS, BIND_ALWAYS, Dot11Elt]
+		],
+		'Dot11AssoResp' => [
+			[BIND_ALWAYS, BIND_ALWAYS, Dot11Elt]
+		],
+		'Dot11ReassoReq' => [
+			[BIND_ALWAYS, BIND_ALWAYS, Dot11Elt]
+		],
+		'Dot11ReassoResp' => [
+			[BIND_ALWAYS, BIND_ALWAYS, Dot11Elt]
+		],
+		'Dot11ProbeReq' => [
+			[BIND_ALWAYS, BIND_ALWAYS, Dot11Elt]
+		],
+		'Dot11ProbeResp' => [
+			[BIND_ALWAYS, BIND_ALWAYS, Dot11Elt]
+		],
+		'Dot11Auth' => [
+			[BIND_ALWAYS, BIND_ALWAYS, Dot11Elt]
+		],
+		'Dot11Elt' => [
+			[BIND_ALWAYS, BIND_ALWAYS, Dot11Elt]
+		],
+		
 		'ClassicBSDLoopback' => 
 		[
 			['header', BSDLOOPBACKTYPE_IPv4, IP]
@@ -431,10 +655,13 @@
 			Ether(pkt)
 		when Pcap::DLT_NULL
 			ClassicBSDLoopback(pkt)
-		when Pcap::DLT_RAW
+		when DLT_OPENBSD
 			OpenBSDLoopback(pkt)
 		when Pcap::DLT_PRISM_HEADER
 			Prism(pkt)
+		when Pcap::DLT_IEEE802
+		when DLT_IEEE80211
+			Dot11(pkt)
 		when 101,
 			IP(pkt)			
 		else
@@ -458,6 +685,23 @@
 	Raw
 	TCP
 	UDP
+	LLC
+	ARP
+	Prism
+	Dot11
+	Dot11Beacon
+        Dot11Elt
+        Dot11ATIM
+        Dot11Disas
+        Dot11AssoReq
+        Dot11AssoResp
+        Dot11ReassoReq
+        Dot11ReassoResp
+        Dot11ProbeReq
+        Dot11ProbeResp
+        Dot11Auth
+        Dot11Deauth
+        Dot11WEP
 
 Scapy (1.2.0.1) packet dissectors/types:
 ========================================
diff -r -u metasploit/lib/scruby/field.rb metasploit_new/lib/scruby/field.rb
--- metasploit/lib/scruby/field.rb	2008-03-03 20:56:44.000000000 +0000
+++ metasploit_new/lib/scruby/field.rb	2008-03-10 22:20:28.000000000 +0000
@@ -45,6 +45,9 @@
 		# Retrieves the field value from a string. This may be redefined by subclasses.
 		def dissect(layer, string)
 
+			# Preparing the packet for building
+			self.pre_build()
+
 			part = string.unpack(self.format + 'a*')
 
 			# Returning if nothing could be unpacked
@@ -73,7 +76,7 @@
 		end
 
 		# Converts from human to internal encoding
-		# e.g. allows TCP(:sport=>'http')
+		# e.g. allows TCP(:proto=>'ICMP')
 		def from_human(value)
 			return value
 		end
@@ -84,12 +87,23 @@
 			return value.to_s
 		end
 
-		# Same as tuhuman() but displays more information
+		# Same as to_human() but displays more information
 		# e.g. "6 (TCP)" instead of "6" for IP protocol
 		def to_human_complete(value)
 			return value.to_s
 		end
 
+		# Returns yes if the field is to be added to the dissectors, e.g. depending
+		# on the value of another field of the layer (see Dot11*)
+		def is_applicable?(layer)
+			return true
+		end
+
+		# Prepares the packet for building
+		# e.g. for StrLenField, retrieves the right format size from the associated FieldLenField
+		def pre_build
+		end
+
 	end
 
 	# Shortcut mixins for reducing code size
@@ -102,6 +116,24 @@
 			return sprintf('0x%x', value)
 		end	
 	end
+
+	# Shortcut mixins for reducing code size
+	module FieldHumanHexEnum
+		def to_human(value)
+			return sprintf('0x%x', value)
+		end
+
+		def to_human_complete(value)
+			# Checking if the value is in the enumeration keys
+			if @enum.keys.include?(value)
+				return sprintf('0x%x', value) + ' (' + @enum[value].to_s + ')'
+
+			# Otherwise, just returning the value
+			else
+				return sprintf('0x%x', value)
+			end
+		end	
+	end
 	
 	# Shortcut mixins for signed conversion
 	module SignedValue
@@ -147,7 +179,7 @@
 		end
 
 		def to_human_complete(value)
-
+			puts "ok"
 			# Checking if the value is in the enumeration keys
 			if @enum.keys.include?(value)
 				return value.to_s + ' (' + @enum[value].to_s + ')'
@@ -201,18 +233,6 @@
 			@format = 'A' + size.to_s
 		end
 
-		def to_net(value)
-			return value.to_s
-		end
-
-		def to_human(value)
-			return value.to_s.inspect
-		end
-
-		def to_human_complete(value)
-			return value.to_s.inspect
-		end
-
 	end
 
 	# Field for a set of bits
@@ -326,7 +346,7 @@
 
 	# Same as ByteEnumField, displayed in hexadecimal form
 	class XByteEnumField<ByteEnumField
-		include FieldHumanHex
+		include FieldHumanHexEnum
 	end
 
 	# Field for one short (big endian/network order)
@@ -350,7 +370,7 @@
 
 	# Same as ShortEnumField, displayed in hexadecimal form
 	class XShortEnumField<ShortEnumField
-		include FieldHumanHex
+		include FieldHumanHexEnum
 	end
 
 	# Field for a short (little endian order)
@@ -374,7 +394,7 @@
 
 	# Same as LEShortField, displayed in hexadecimal form
 	class XLEShortEnumField<LEShortEnumField
-		include FieldHumanHex
+		include FieldHumanHexEnum
 	end
 
 	# Field for one integer
@@ -406,7 +426,7 @@
 
 	# Same as LEIntField, displayed in hexadecimal form
 	class XIntEnumField<IntEnumField
-		include FieldHumanHex
+		include FieldHumanHexEnum
 	end
 
 	# Field for one integer with enumeration
@@ -446,7 +466,7 @@
 
 	# Same as LEIntField, displayed in hexadecimal form
 	class XLEIntEnumField<LEIntEnumField
-		include FieldHumanHex
+		include FieldHumanHexEnum
 	end
 
 	# Field for one integer (host order)
@@ -472,7 +492,7 @@
 
 	# Same as HostOrderIntEnumField, displayed in hexadecimal form
 	class XHostOrderIntEnumField<HostOrderIntEnumField
-		include FieldHumanHex
+		include FieldHumanHexEnum
 	end
 
 	# Field for a float (big endian/network order)
@@ -630,7 +650,7 @@
 			# Checking if the value is in the enumeration keys
 			if @enum.keys.include?(value)
 				return value.to_s + ' (' + @enum[value].to_s + ')'
-				# Otherwise, just returning the value
+			# Otherwise, just returning the value
 			else
 				return value.to_s
 			end
@@ -649,6 +669,194 @@
 
 	end
 
+	# Field for a set of flags (e.g. each bit has a label)
+	class FlagsField<BitField
+
+		def initialize(name, default_value, size, flags)
+			@name = name
+			@default_value = default_value
+			@format = 'B'
+			@flags = flags
+
+			# Number of bits in the field
+			@size = size
+
+			# Number of bits processed so far within the current byte (class/static variable)
+			@@bitsdone = 0
+
+			# Byte being processed (class/static variable)
+			@@byte = 0
+		end
+
+		def from_human(value)
+
+			return value if not value.is_a?(String)
+
+			# Run through the flags and set the corresponding bit if it matches
+			out = 0
+			@flags.length.times do |index|
+				out |= 2**index if value.include?(@flags[index])
+			end
+
+			return out
+		end
+
+		def to_human_complete(value)
+
+			loops = 0
+			out = ''
+
+			begin
+				bit = value & (2**loops)
+				out = @flags[loops] + ' ' + out if bit != 0
+				loops += 1
+			end until loops == @size
+
+			# Removing the last space
+			out = out[0, out.length - 1] if out.length > 0
+
+			return value.to_s + ' (' + out + ')'
+		end
+
+	end
+
+	# Field for one long (big endian/network order)
+	class LongField<Field
+		def init
+			@format = 'Q'
+		end
+	end
+
+	# Same as LongField, displayed in hexadecimal form
+	class XLongField<LongField
+		include FieldHumanHex
+	end
+
+	# Field for one long (big endian/network order) with enumeration
+	class LongEnumField<EnumField
+		def init
+			@format = 'n'
+		end
+	end
+
+	# Same as LongEnumField, displayed in hexadecimal form
+	class XLongEnumField<LongEnumField
+		include FieldHumanHexEnum
+	end
+
+	# Field that holds the length of a subsequent field
+	class FieldLenField<IntField
+
+		def initialize(name, default_value, length_of, format)
+			@name = name
+			@default_value = default_value
+			@format = format
+			@length_of = length_of
+
+			# Length of the other field (class/static variable)
+			@@length = {}
+
+			# Saving the size of the associated field
+			@@[EMAIL PROTECTED] = @default_value
+		end
+
+		def from_net(value)
+			# Saving the size of the associated field
+			@@[EMAIL PROTECTED] = value[0]
+			return value[0]
+		end
+
+		def to_net(value)
+			# Saving the size of the associated field
+			@@[EMAIL PROTECTED] = value.to_i
+			return [value].pack(@format)
+		end
+	end
+
+	# Field holding a string whose size is given by a previous FieldLenField
+	# NB : in Scapy, the third field is a lambda-function indicating how to compute the value.
+	# This is not implemented in Scruby yet.
+	class StrLenField<FieldLenField
+
+		def initialize(name, default_value, length_from)
+			@name = name
+			@default_value = default_value
+			@length_from = length_from
+			@size = @@length[name]
+			@format = 'a' + @size.to_s
+		end
+
+		def pre_build
+			@size = @@[EMAIL PROTECTED]
+			@format = 'a' + @size.to_s
+		end
+
+		def to_net(value)
+			@size = @@[EMAIL PROTECTED]
+			@format = 'a' + @size.to_s
+
+			# By default, value is ''
+			if value
+				return value[0, @size].to_s
+			else
+				return ''
+			end
+		end
+
+		def to_human(value)
+			return value.to_s.inspect
+		end
+
+		def to_human_complete(value)
+			return value.to_s.inspect
+		end
+
+	end
+
+	# NB for Dot11* fields: 
+	# These functions have different 'is_applicable?' methods, to build different
+	# kinds of packets with the same dissector, depending on its type.
+	# http://trac.secdev.org/scapy/ticket/4 (second point)
+	# http://sss-mag.com/pdf/802_11tut.pdf
+
+	# Field for a 802.11 address field
+	class Dot11AddrMACField<MACField
+	end
+
+	# Field for a 802.11 address field #2
+	class Dot11Addr2MACField<MACField
+		def is_applicable?(layer)
+			if layer.type == DOT11TYPE_CONTROL
+				should = [DOT11SUBTYPE_PS_POLL, DOT11SUBTYPE_RTS, DOT11SUBTYPE_CF_END, DOT11SUBTYPE_CF_END_CF_ACK]
+				return should.include?(layer.subtype)
+			else
+				return true
+			end
+		end
+	end
+
+	# Field for a 802.11 address field #3 
+	class Dot11Addr3MACField<MACField
+		def is_applicable?(layer)
+			return true if layer.type == DOT11TYPE_MANAGEMENT or layer.type == DOT11TYPE_DATA
+			return false
+		end
+	end
+
+	# Field for a 802.11 address field #4
+	class Dot11Addr4MACField<MACField
+		def is_applicable?(layer)
+			return true if layer.type == DOT11TYPE_DATA and layer.FCfield & 0x3 == 0x3
+			return false
+		end
+	end
+
+	# Field for a 802.11 SC field
+	class Dot11SCField<LEShortField
+		def is_applicable?(layer)
+			return layer.type != DOT11TYPE_CONTROL
+		end
+	end
 
 	# Grep out our field list here
 	self.constants.grep(/^([a-zA-Z0-9]+)Field$/).each do |f|
@@ -685,7 +893,6 @@
 ==============================================
 	ARPSourceMACField
 	BCDFloatField
-	BitEnumField
 	BitFieldLenField
 	CharEnumField
 	DHCPOptionsField
@@ -694,21 +901,13 @@
 	DNSRRField
 	DNSStrField
 	DestMACField
-	Dot11Addr2MACField
-	Dot11Addr3MACField
-	Dot11Addr4MACField
-	Dot11AddrMACField
-	Dot11SCField
-	FieldLenField
 	FieldListField
-	FlagsField
 	IPoptionsField
 	ISAKMPTransformSetField
 	LEFieldLenField
 	LELongField
 	LESignedIntField
 	LenField
-	LongField
 	NetBIOSNameField
 	PacketField
 	PacketLenField
@@ -720,7 +919,6 @@
 	SignedIntField
 	SourceIPField
 	SourceMACField
-	StrLenField
 	StrNullField
 	StrStopField
 	TCPOptionsField
diff -r -u metasploit/lib/scruby/help.rb metasploit_new/lib/scruby/help.rb
--- metasploit/lib/scruby/help.rb	2008-03-03 20:56:44.000000000 +0000
+++ metasploit_new/lib/scruby/help.rb	2008-03-09 22:42:06.000000000 +0000
@@ -17,9 +17,9 @@
 
   if command.nil?
     print <<EOF
-This is Scruby, a portable, customizable packet creation and sending/sniffing tool written in Ruby. It was tested on NetBSD and GNU/Linux, and should theoretically work on some other platforms such as FreeBSD, OpenBSD, Mac OS X and proprietary Unixes.
+This is Scruby, a portable, customizable packet creation and sending/sniffing tool written in Ruby. It was tested on NetBSD, GNU/Linux and MacOS X, and should theoretically work on some other platforms such as FreeBSD, OpenBSD and proprietary Unixes.
 
-See http://sylvainsarmejeanne.free.fr/projects/scruby for more information.
+See http://sylv1.tuxfamily.org/projects/scruby.html for more information.
 
 With Scruby, you can:
 - create custom packet: p=IP(:src=>"1.2.3.4", :dst=>"www.google.com")/TCP()/"GET / HTTP 1.0\\r\\n\\r\\n"
@@ -29,10 +29,10 @@
 - dissect a string to a recreate the packet: s=p.to_net;puts "string=\#{s.inspect}\\nresult=\#{IP(s)}"
 
 Available dissectors (type "ls 'MyDissector'" to have detailed information):
-#{DISSECTORS_LIST_S.inspect}
+#{Scruby.dissectors.keys.sort.join(", ")}
 
 Available functions (type "lsc 'myfunction'" to have detailed information):
-#{FUNCTIONS_LIST.inspect}
+#{(Scruby.methods - Object.methods).sort.join(", ")}
 EOF
   else
     # Executing the specific help function
diff -r -u metasploit/lib/scruby/layer.rb metasploit_new/lib/scruby/layer.rb
--- metasploit/lib/scruby/layer.rb	2008-03-03 20:56:44.000000000 +0000
+++ metasploit_new/lib/scruby/layer.rb	2008-03-09 23:04:53.000000000 +0000
@@ -67,7 +67,7 @@
 					# e.g. for ['type', ETHERTYPE_IPv4, IP], if the field "type"
 					# in the current Ethernet layer is 0x800, then the upper layer
 					# is (may be) IP.
-					if self.instance_variable_get("@#{triplet[0]}") == triplet[1]
+					if triplet[0] == BIND_ALWAYS or self.instance_variable_get("@#{triplet[0]}") == triplet[1]
 						# Adding this possibility
 						@guesses.push(triplet[2])
 						break
@@ -104,6 +104,11 @@
 		return Packet./(self, upper)
 	end
 
+	# To use 'MyField(foo, bar)' in dissectors, instead of Scruby.MyField(foo, bar)'
+	def method_missing(method, *args)
+		  return Scruby.field(method, *args)
+	end
+
 	# Converts an object to a string
 	def to_s
 
@@ -144,7 +149,9 @@
 		out = ''
 
 		@fields_desc.each do |field|
-			out += field.to_net(self.instance_variable_get("@#{field.name}"))
+			if field.is_applicable?(self)
+				out += field.to_net(self.instance_variable_get("@#{field.name}"))
+			end
 		end
 
 		return out
@@ -159,8 +166,10 @@
 	def dissect(string)
 
 		@fields_desc.each do |field|
-			string = field.dissect(self, string)
-			return "" if string.nil?
+			if field.is_applicable?(self)
+				string = field.dissect(self, string)
+			end
+			return '' if string.nil?
 		end
 
 		return string
diff -r -u metasploit/lib/scruby/unittest.rb metasploit_new/lib/scruby/unittest.rb
--- metasploit/lib/scruby/unittest.rb	2008-03-03 20:56:44.000000000 +0000
+++ metasploit_new/lib/scruby/unittest.rb	2008-03-09 22:43:41.000000000 +0000
@@ -16,6 +16,7 @@
   eval("module Scruby;require 'scruby';$r = #{is}.to_s == '#{should}';end;")
   if not $r
     puts "\n## test #{$test_nb} FALSE##"
+    puts is.to_s    
   else
     print "."
   end
@@ -30,39 +31,75 @@
 puts "BEGIN"
 
 # Constructor arguments
-test("IP(nil)", "<IP |>") #1
+test("IP(nil)", "<IP |>")
 test("IP('')", "<IP |>")
 test("IP(:foobar)", "<IP |>")
 test("IP(Hash.new)", "<IP |>")
 test("IP(Array.new)", "<IP |>")
 
 # All dissectors
-test("Ether()", "<Ether |>") #6
+test("Ether()", "<Ether |>")
+test("ARP()", "<ARP |>")
 test("IP()", "<IP |>")
-test("TCP()", "<TCP |>")
-test("UDP()", "<UDP |>")
 test("ICMP()", "<ICMP |>")
 test("Raw()", "<Raw |>")
+test("TCP()", "<TCP |>")
+test("UDP()", "<UDP |>")
 test("ClassicBSDLoopback()", "<ClassicBSDLoopback |>")
 test("OpenBSDLoopback()", "<OpenBSDLoopback |>")
+test("RIFF()", "<RIFF |>")
+test("ANI()", "<ANI |>")
+test("Dot11()", "<Dot11 |>")
+test("Dot11QoS()", "<Dot11QoS |>")
+test("Dot11Beacon()", "<Dot11Beacon |>")
+test("Dot11Elt()", "<Dot11Elt |>")
+test("Dot11ATIM()", "<Dot11ATIM |>")
+test("Dot11Disas()", "<Dot11Disas |>")
+test("Dot11AssoReq()", "<Dot11AssoReq |>")
+test("Dot11AssoResp()", "<Dot11AssoResp |>")
+test("Dot11ReassoReq()", "<Dot11ReassoReq |>")
+test("Dot11ReassoResp()", "<Dot11ReassoResp |>")
+test("Dot11ProbeReq()", "<Dot11ProbeReq |>")
+test("Dot11ProbeResp()", "<Dot11ProbeResp |>")
+test("Dot11Auth()", "<Dot11Auth |>")
+test("Dot11Deauth()", "<Dot11Deauth |>")
+test("Dot11WEP()", "<Dot11WEP |>")
+test("LLC()", "<LLC |>")
 
 # All dissectors with arguments
-test("Ether(:dst=>'11:11:11:11:11:11', :src=>'22:22:22:22:22:22', :type=>666)", "<Ether dst=11:11:11:11:11:11 src=22:22:22:22:22:22 type=0x29a |>") #14
-test("IP(:version=>3, :ihl=>4, :tos=>101, :len=>102, :id=>103, :flags=>2, :frag=>104, :ttl=>105, :proto=>106, :chksum=>107, :src=>'10.0.0.1', :dst=>'10.0.0.2')", "<IP version=3 ihl=4 tos=0x65 len=102 id=0x67 flags=2 frag=104 ttl=105 proto=106 chksum=0x6b src=\"10.0.0.1\" dst=\"10.0.0.2\" |>")
-test("TCP(:sport=>100, :dport=>101, :seq=>102, :ack=>103, :dataofs=>109, :reserved=>104, :flags=>105, :window=>106, :chksum=>107, :urgptr=>108)", "<TCP sport=100 dport=101 seq=102 ack=103 dataofs=109 reserved=104 flags=0x69 window=106 chksum=0x6b urgptr=108 |>")
+test("Ether(:dst=>'11:11:11:11:11:11', :src=>'22:22:22:22:22:22', :type=>666)", "<Ether dst=11:11:11:11:11:11 src=22:22:22:22:22:22 type=0x29a |>")
+test("ARP(:hwtype=>'FrameRelay', :ptype=>3, :hwlen=>1, :plen=>'IPv6', :op=>2, :hwsrc=>'11:22:33:44:55:66', :psrc=>'192.168.0.1', :hwdst=>'66:55:44:33:22:11', :pdst=>'192.168.0.2')", "<ARP hwtype=0xf ptype=0x3 hwlen=1 plen=16 op=2 hwsrc=11:22:33:44:55:66 psrc=\"192.168.0.1\" hwdst=66:55:44:33:22:11 pdst=\"192.168.0.2\" |>")
+test("IP(:version=>3, :ihl=>4, :tos=>101, :len=>102, :id=>103, :flags=>'DF', :frag=>104, :ttl=>105, :proto=>106, :chksum=>107, :src=>'10.0.0.1', :dst=>'10.0.0.2')", "<IP version=3 ihl=4 tos=0x65 len=102 id=0x67 flags=2 frag=104 ttl=105 proto=106 chksum=0x6b src=\"10.0.0.1\" dst=\"10.0.0.2\" |>")
+test("TCP(:sport=>100, :dport=>101, :seq=>102, :ack=>103, :dataofs=>109, :reserved=>104, :flags=>'SYN ACK', :window=>106, :chksum=>107, :urgptr=>108)", "<TCP sport=100 dport=101 seq=102 ack=103 dataofs=109 reserved=104 flags=18 window=106 chksum=0x6b urgptr=108 |>")
 test("UDP(:sport=>100, :dport=>101, :len=>102, :chksum=>103)", "<UDP sport=100 dport=101 len=102 chksum=0x67 |>")
 test("ICMP(:type=>100, :code=>101, :chksum=>102, :id=>103, :seq=>104)", "<ICMP type=100 code=101 chksum=0x66 id=0x67 seq=0x68 |>")
 test("Raw(:load=>'foobar')", "<Raw load=\"foobar\" |>")
 test("ClassicBSDLoopback(:header=>100)", "<ClassicBSDLoopback header=100 |>")
 test("OpenBSDLoopback(:header=>100)", "<OpenBSDLoopback header=100 |>")
+test("RIFF(:id=>'FOOB', :size=>66, :headerid=>'BARZ')", "<RIFF id=\"FOOB\" size=66 headerid=\"BARZ\" |>")
+test("ANI(:id=>'foob', :size=>12, :headersize=>21, :frames=>3, :steps=>1, :width=>2, :height=>3, :bitcount=>4, :planes=>5, :displayrate=>6, :icon=>1, :sequence=>1, :reserved=>1)", "<ANI id=\"foob\" size=12 headersize=21 frames=3 steps=1 width=2 height=3 bitcount=4 planes=5 displayrate=6 icon=1 sequence=1 reserved=1 |>")
+test("Dot11(:subtype=>1, :type=>1, :proto=>1, :FCfield=>1, :ID=>1, :addr1=>'11:11:11:11:11:11', :addr2=>'22:22:22:22:22:22', :addr3=>'33:33:33:33:33:33')", "<Dot11 subtype=1 type=1 proto=1 FCfield=1 ID=1 addr1=11:11:11:11:11:11 addr2=22:22:22:22:22:22 addr3=33:33:33:33:33:33 |>")
+test("Dot11Elt(:ID=>1, :len=>2, :info=>'ab')", "<Dot11Elt ID=1 len=2 info=\"ab\" |>")
+test("LLC(:dsap=>1, :ssap=>1, :ctrl=>1)", "<LLC dsap=0x1 ssap=0x1 ctrl=1 |>")
 
 # Fields for Ether
-test("Ether().dst", "00:00:00:00:00:00") #22
+test("Ether().dst", "00:00:00:00:00:00")
 test("Ether().src", "00:00:00:00:00:00")
 test("Ether().type", "2048")
 
+# Fields for ARP
+test("ARP().hwtype", "1")
+test("ARP().ptype", "2048")
+test("ARP().hwlen", "6")
+test("ARP().plen", "4")
+test("ARP().op", "1")
+test("ARP().hwsrc", "00:00:00:00:00:00")
+test("ARP().psrc", "127.0.0.1")
+test("ARP().hwdst", "00:00:00:00:00:00")
+test("ARP().pdst", "127.0.0.1")
+
 # Fields for IP
-test("IP().version", "4") #25
+test("IP().version", "4")
 test("IP().ihl", "5")
 test("IP().tos", "0")
 test("IP().len", "20")
@@ -76,7 +113,7 @@
 test("IP().dst", "127.0.0.1")
 
 # Fields for TCP
-test("TCP().sport", "1024") #37
+test("TCP().sport", "1024")
 test("TCP().dport", "80")
 test("TCP().seq", "0")
 test("TCP().ack", "0")
@@ -88,20 +125,20 @@
 test("TCP().urgptr", "0")
 
 # Fields for UDP
-test("UDP().sport", "53") #47
+test("UDP().sport", "53")
 test("UDP().dport", "53")
 test("UDP().len", "8")
 test("UDP().chksum", "0")
 
 # Fields for ICMP
-test("ICMP().type", "8") #51
+test("ICMP().type", "8")
 test("ICMP().code", "0")
 test("ICMP().chksum", "0")
 test("ICMP().id", "0")
 test("ICMP().seq", "0")
 
 # Fields for Raw
-test("Raw().load", "") #56
+test("Raw().load", "")
 
 # Fields for ClassicBSDLoopback
 test("ClassicBSDLoopback().header", "2")
@@ -109,14 +146,56 @@
 # Fields for OpenBSDLoopback
 test("OpenBSDLoopback().header", "2")
 
-# Dissecting a string
-test("Raw('foobar')", "<Raw load=\"foobar\" |>")
+# Fields for RIFF
+test("RIFF().id", "RIFF")
+test("RIFF().size", "0")
+test("RIFF().headerid", "ACON")
+
+# Fields for ANI
+test("ANI().id", "anih")
+test("ANI().size", "36")
+test("ANI().headersize", "36")
+test("ANI().frames", "2")
+test("ANI().steps", "0")
+test("ANI().width", "0")
+test("ANI().height", "0")
+test("ANI().bitcount", "0")
+test("ANI().planes", "0")
+test("ANI().displayrate", "0")
+test("ANI().icon", "0")
+test("ANI().sequence", "0")
+test("ANI().reserved", "0")
+
+# Fields for Dot11
+test("Dot11().subtype", "0")
+test("Dot11().type", "2")
+test("Dot11().proto", "0")
+test("Dot11().FCfield", "0")
+test("Dot11().ID", "0")
+test("Dot11().addr1", "00:00:00:00:00:00")
+test("Dot11().addr2", "00:00:00:00:00:00")
+test("Dot11().addr3", "00:00:00:00:00:00")
+test("Dot11().SC", "0")
+test("Dot11().addr4", "00:00:00:00:00:00")
+
+# Fields for Dot11Elt
+test("Dot11Elt().ID", "0")
+test("Dot11Elt().len", "0")
+test("Dot11Elt().info", "")
+
+# Fields for LLC
+test("LLC().dsap", "0")
+test("LLC().ssap", "0")
+test("LLC().ctrl", "0")
 
-# Ether packet #60
+# Ether packet
 test("Ether(:src=>'ba:98:76:54:32:10', :type=>123).to_net.inspect", "\000\000\000\000\000\000\272\230vT2\020\000{".inspect)
 test("Ether(:dst=>'01:23:45:67:89:ab', :src=>'ba:98:76:54:32:10', :type=>123).to_net.inspect", "\001#Eg\211\253\272\230vT2\020\000{".inspect)
 
-# IP packet #62
+# ARP packet
+test("(Ether(:type=>'ARP')/ARP(:hwtype=>'Ethernet', :ptype=>0x800, :hwlen=>6, :plen=>'IPv4', :op=>2, :hwsrc=>'11:22:33:44:55:66', :psrc=>'192.168.0.1', :hwdst=>'66:55:44:33:22:11', :pdst=>'192.168.0.2')).to_net.inspect", "\000\000\000\000\000\000\000\000\000\000\000\000\b\006\000\001\b\000\006\004\000\002\021\"3DUf\300\250\000\001fUD3\"\021\300\250\000\002".inspect)
+
+# IP packet
 test("(IP(:version=>4, :ihl=>5, :tos=>13, :id=>103, :flags=>2, :frag=>104, :ttl=>105, :proto=>106, :src=>'1.2.3.4', :dst=>'4.3.2.1')/Raw(:load=>\"foobar\")).to_net.inspect", "[EMAIL PROTECTED]".inspect)
 
 # TCP packet
@@ -128,14 +207,32 @@
 # ICMP packet
 test("(IP(:proto=>1)/ICMP(:type=>0, :code=>101, :id=>103, :seq=>104)).to_net.inspect", "[EMAIL PROTECTED]|\337\177\000\000\001\177\000\000\001\000e\376\313\000g\000h".inspect)
 
-# Dissecting Ether #66
+# RIFF packet
+test("RIFF(:id=>'FOOB', :size=>67, :headerid=>'BARZ').to_net.inspect", "FOOBC\000\000\000BARZ".inspect)
+
+# ANI packet
+test("ANI(:id=>'foob', :size=>12, :headersize=>21, :frames=>3, :steps=>1, :width=>2, :height=>3, :bitcount=>4, :planes=>5, :displayrate=>6, :icon=>1, :sequence=>1, :reserved=>1).to_net.inspect", "foob\f\000\000\000\025\000\000\000\003\000\000\000\001\000\000\000\002\000\000\000\003\000\000\000\004\000\000\000\005\000\000\000\006\000\000\000\300\000\000\001".inspect)
+
+# Dot11 packet
+test("Dot11(:subtype=>1, :type=>1, :proto=>1, :FCfield=>1, :ID=>1, :addr1=>'11:11:11:11:11:11', :addr2=>'22:22:22:22:22:22', :addr3=>'33:33:33:33:33:33').to_net.inspect", "\025\001\000\001\021\021\021\021\021\021".inspect)
+
+# Dot11Elt packet
+test("Dot11Elt(:ID=>1, :len=>2, :info=>'ab').to_net.inspect", "\001\002ab".inspect)
+
+# LLC
+test("LLC(:dsap=>1, :ssap=>1, :ctrl=>1).to_net.inspect", "\001\001\001".inspect)
+
+# Dissecting Ether
 test("Ether(\"\001#Eg\211\253\272\230vT2\020\000{\")", "<Ether dst=01:23:45:67:89:ab src=ba:98:76:54:32:10 type=0x7b |>")
 
+# Dissecting ARP
+test('ARP("\000\001\b\000\006\004\000\002\021\"3DUf\300\250\000\001fUD3\"\021\300\250\000\002")', "<ARP op=2 hwsrc=11:22:33:44:55:66 psrc=\"192.168.0.1\" hwdst=66:55:44:33:22:11 pdst=\"192.168.0.2\" |>")
+
 # Dissecting IP
 test("IP(\"[EMAIL PROTECTED]")", "<IP tos=0xd len=26 id=0x67 flags=2 frag=104 ttl=105 proto=106 chksum=0x695 src=\"1.2.3.4\" dst=\"4.3.2.1\" |><Raw load=\"foobar\" |>")
 
 # Dissecting TCP
-test("TCP(\"\000d\000e\000\000\000f\000\000\000gS\003\000j\254s\000l\")", "<TCP sport=100 dport=101 seq=102 ack=103 reserved=3 flags=0x3 window=106 chksum=0xac73 urgptr=108 |>")
+test("TCP(\"\000d\000e\000\000\000f\000\000\000gS\003\000j\254s\000l\")", "<TCP sport=100 dport=101 seq=102 ack=103 reserved=3 flags=3 window=106 chksum=0xac73 urgptr=108 |>")
 
 # Dissecting UDP
 test("UDP(\"\000d\000e\000\016\311\302foobar\")", "<UDP sport=100 dport=101 len=14 chksum=0xc9c2 |><Raw load=\"foobar\" |>")
@@ -143,7 +240,28 @@
 # Dissecting ICMP
 test("ICMP(\"\000e\376\313\000g\000h\")", "<ICMP type=0 code=101 chksum=0xfecb id=0x67 seq=0x68 |>")
 
-# Operations on layers # 71
+# Dissecting a string
+test("Raw('foobar')", "<Raw load=\"foobar\" |>")
+
+# Dissecting RIFF
+test('RIFF("FOOBC\000\000\000BARZ")', "<RIFF id=\"FOOB\" size=67 headerid=\"BARZ\" |>")
+
+# Dissecting ANI
+test('ANI("foob\f\000\000\000\025\000\000\000\003\000\000\000\001\000\000\000\002\000\000\000\003\000\000\000\004\000\000\000\005\000\000\000\006\000\000\000\300\000\000\001")', "<ANI id=\"foob\" size=12 headersize=21 frames=3 steps=1 width=2 height=3 bitcount=4 planes=5 displayrate=6 icon=1 sequence=1 reserved=1 |>")
+
+# Dissecting Dot11
+test('Dot11("\025\001\000\001\021\021\021\021\021\021")', "<Dot11 subtype=1 type=1 proto=1 FCfield=1 ID=1 addr1=11:11:11:11:11:11 |>")
+
+# Dissecting Dot11Elt
+test('Dot11Elt("\001\002ab")', "<Dot11Elt ID=1 len=2 info=\"ab\" |>")
+
+# Dissecting a real Dot11 string
+test('Dot11("\x80\x00\x00\x00\xff\xff\xff\xff\xff\xff\x00\x19}\x01Y\xc4\x00\x19}\x01Y\xc4\xf0\x1e\x8bA\x9f\t)\x0c\x00\x00d\x00\x11\x04\x00\x0cLivebox-6708\x01\x08\x82\x84\x8b\x96$0Hl\x03\x01\x01\x05\x04\x00\x03\x00\x00*\x01\x00/\x01\x002\x04\x0c\x12\x18`\xdd\x16\x00P\x02\x01\x01\x00\x00P\x02\x02\x01\x00\x00P\x02\x02\x01\x00\x00P\x02\x02\xdd\x18\x00P\x02\x02")', "<Dot11 subtype=8 type=0 addr1=ff:ff:ff:ff:ff:ff addr2=00:19:7d:01:59:c4 addr3=00:19:7d:01:59:c4 SC=7920 |><Dot11Beacon timestamp=13370394624395 cap=4356 |><Dot11Elt len=12 info=\"Livebox-6708\" |><Dot11Elt ID=1 len=8 info=\"\\202\\204\\213\\226$0Hl\" |><Dot11Elt ID=3 len=1 info=\"\\001\" |><Dot11Elt ID=5 len=4 info=\"\\000\\003\\000\\000\" |><Dot11Elt ID=42 len=1 info=\"\\000\" |><Dot11Elt ID=47 len=1 info=\"\\000\" |><Dot11Elt ID=50 len=4 info=\"\\f\\022\\030`\" |><Dot11Elt ID=221 len=22 info=\"\\000P\\002\\001\\001\\000\\000P\\002\\002\\001\\000\\000P\\002\\002\\001\\000\\000P\\002\\002\" |><Dot11Elt ID=221 len=24 info=\"\\000P\\002\\002\" |>")
+
+# Dissecting LLC
+test('LLC("\001\001\001")', "<LLC dsap=0x1 ssap=0x1 ctrl=1 |>")
+
+# Operations on layers
 $p=Ether()/"[EMAIL PROTECTED]|\310\177\000\000\001\177\000\000\001\004\000\000P\000\000\000\000\000\000\000\000P\002 \000VF\000\000foobar"
 $p.decode_payload_as(IP)
 
@@ -154,11 +272,11 @@
 test("$p.get_layer(TCP)", "<TCP chksum=0x5646 |><Raw load=\"foobar\" |>")
 
 # Dissecting a string byte after byte
-test("IP('A')", "<IP ihl=1 |>") # 76
+test("IP('A')", "<IP ihl=1 |>")
 test("IP('A'*2)", "<IP ihl=1 tos=0x41 |>")
 test("IP('A'*3)", "<IP ihl=1 tos=0x41 |>")
 test("IP('A'*4)", "<IP ihl=1 tos=0x41 len=16705 |>")
-test("IP('A'*5)", "<IP ihl=1 tos=0x41 len=16705 |>") # 80
+test("IP('A'*5)", "<IP ihl=1 tos=0x41 len=16705 |>")
 test("IP('A'*6)", "<IP ihl=1 tos=0x41 len=16705 id=0x4141 |>")
 test("IP('A'*7)", "<IP ihl=1 tos=0x41 len=16705 id=0x4141 flags=2 |>")
 test("IP('A'*8)", "<IP ihl=1 tos=0x41 len=16705 id=0x4141 flags=2 frag=321 |>")
@@ -168,7 +286,7 @@
 test("IP('A'*12)", "<IP ihl=1 tos=0x41 len=16705 id=0x4141 flags=2 frag=321 ttl=65 proto=65 chksum=0x4141 |>")
 test("IP('A'*13)", "<IP ihl=1 tos=0x41 len=16705 id=0x4141 flags=2 frag=321 ttl=65 proto=65 chksum=0x4141 |>")
 test("IP('A'*14)", "<IP ihl=1 tos=0x41 len=16705 id=0x4141 flags=2 frag=321 ttl=65 proto=65 chksum=0x4141 |>")
-test("IP('A'*15)", "<IP ihl=1 tos=0x41 len=16705 id=0x4141 flags=2 frag=321 ttl=65 proto=65 chksum=0x4141 |>") # 90
+test("IP('A'*15)", "<IP ihl=1 tos=0x41 len=16705 id=0x4141 flags=2 frag=321 ttl=65 proto=65 chksum=0x4141 |>")
 test("IP('A'*16)", "<IP ihl=1 tos=0x41 len=16705 id=0x4141 flags=2 frag=321 ttl=65 proto=65 chksum=0x4141 src=\"65.65.65.65\" |>")
 test("IP('A'*17)", "<IP ihl=1 tos=0x41 len=16705 id=0x4141 flags=2 frag=321 ttl=65 proto=65 chksum=0x4141 src=\"65.65.65.65\" |>")
 test("IP('A'*18)", "<IP ihl=1 tos=0x41 len=16705 id=0x4141 flags=2 frag=321 ttl=65 proto=65 chksum=0x4141 src=\"65.65.65.65\" |>")
diff -r -u metasploit/lib/scruby.rb metasploit_new/lib/scruby.rb
--- metasploit/lib/scruby.rb	2008-03-03 20:56:46.000000000 +0000
+++ metasploit_new/lib/scruby.rb	2008-03-09 22:50:03.000000000 +0000
@@ -52,10 +52,6 @@
 		end
 	end
 	
-	def method_missing(method, *args)
-		Scruby.method_missing(method, *args)
-	end
-
 	# Same as above, for fields
 	def self.field(method, *args)
 
_______________________________________________
Framework-Hackers mailing list
Framework-Hackers@spool.metasploit.com
http://spool.metasploit.com/mailman/listinfo/framework-hackers

Reply via email to