From c3a4cda12765188df38aa140faf0407136112bf7 Mon Sep 17 00:00:00 2001 From: HD Moore Date: Mon, 17 Mar 2008 04:46:42 +0000 Subject: [PATCH] Merged all of the scruby patches, fixed Dot11 support with regards to RadioTap headers. git-svn-id: file:///home/svn/framework3/trunk@5446 4d416f70-5f16-0410-b530-b9f4589650da --- lib/msf/core/exploit/capture.rb | 6 +- lib/scruby.rb | 4 - lib/scruby/const.rb | 108 +++++++- lib/scruby/dissector.rb | 423 +++++++++++++++++++++++++------- lib/scruby/field.rb | 275 ++++++++++++++++++--- lib/scruby/help.rb | 8 +- lib/scruby/layer.rb | 17 +- lib/scruby/unittest.rb | 164 +++++++++++-- 8 files changed, 842 insertions(+), 163 deletions(-) diff --git a/lib/msf/core/exploit/capture.rb b/lib/msf/core/exploit/capture.rb index b97c605dbb..e7f39555f8 100644 --- a/lib/msf/core/exploit/capture.rb +++ b/lib/msf/core/exploit/capture.rb @@ -99,7 +99,7 @@ module Exploit::Capture return if not pkt raw = pkt.raw_data off = 0 - + case pkt.datalink when 119 off = 144 @@ -128,8 +128,10 @@ module Exploit::Capture def each_packet return if not self.capture + + # print_status("Link type is #{capture.datalink}") + capture.each do |packet| - dec = Scruby.linklayer_dissector(capture.datalink, packet) if(dec) diff --git a/lib/scruby.rb b/lib/scruby.rb index 24cd9c9ecf..5eb0b90ee6 100755 --- a/lib/scruby.rb +++ b/lib/scruby.rb @@ -52,10 +52,6 @@ module Scruby end end - def method_missing(method, *args) - Scruby.method_missing(method, *args) - end - # Same as above, for fields def self.field(method, *args) diff --git a/lib/scruby/const.rb b/lib/scruby/const.rb index 44c8bb02f1..8e79d0760a 100755 --- a/lib/scruby/const.rb +++ b/lib/scruby/const.rb @@ -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,25 +37,111 @@ module Scruby TIMEOUT = 1 LOOPBACK_DEVICE_PREFIX = 'lo' + # If two layers are to be bound every time + BIND_ALWAYS = '' + # Constants for Ethernet ETHERTYPE_IPv4 = 0x800 - ETHERTYPE_ARP = 0x806 - ETHERTYPE_ALL = { ETHERTYPE_IPv4 => "IPv4", - ETHERTYPE_ARP => "ARP"} + 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 --git a/lib/scruby/dissector.rb b/lib/scruby/dissector.rb index 2e68d60efa..a66101dddb 100755 --- a/lib/scruby/dissector.rb +++ b/lib/scruby/dissector.rb @@ -37,21 +37,18 @@ module Scruby # Dissector for Ethernet class Ether -8 } ), + FlagsField('present', 0, 32, RADIOTAP_PRESENT), + StrLenField('radiotap', '', 'len') + ] + end + + end + + + # Dot11 dissectors + class Dot11 + [ + [BIND_ALWAYS, BIND_ALWAYS, Dot11] + ], + + '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] @@ -466,10 +693,17 @@ module Scruby 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 Pcap::DLT_IEEE802_11 + Dot11(pkt) + when Pcap::DLT_IEEE802_11_RADIO + RadioTap(pkt) + when Pcap::DLT_IEEE802_11_RADIO_AVS + RadioTap(pkt) when 101, IP(pkt) else @@ -494,6 +728,23 @@ Scruby packet dissectors/types: 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 --git a/lib/scruby/field.rb b/lib/scruby/field.rb index 5fab13066a..48df1b43b1 100755 --- a/lib/scruby/field.rb +++ b/lib/scruby/field.rb @@ -45,6 +45,9 @@ module Scruby # 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 @@ module Scruby 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 @@ module Scruby 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 @@ module Scruby 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 @@ module Scruby 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 @@ module Scruby @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 @@ -235,6 +255,7 @@ module Scruby def dissect(layer, string) + @@bitsdone ||= 0 # Cannot dissect if the wanted size is greater than the length of the string # e.g. "IP('A'*7)" should not set frag=65 return '' if (@@bitsdone + @size)/8 > string.length @@ -276,6 +297,9 @@ module Scruby end def to_net(value) + + @@bitsdone ||= 0 + # OR'ing this value the value the previous ones @@byte <<= @size @@byte |= value @@ -326,7 +350,7 @@ module Scruby # Same as ByteEnumField, displayed in hexadecimal form class XByteEnumField 0 + + return value.to_s + ' (' + out + ')' + end + + end + + # Field for one long (big endian/network order) + class LongField"1.2.3.4", :dst=>"www.google.com")/TCP()/"GET / HTTP 1.0\\r\\n\\r\\n" @@ -29,10 +29,10 @@ With Scruby, you can: - 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 --git a/lib/scruby/layer.rb b/lib/scruby/layer.rb index 988ef26c0e..f19d9eaf02 100755 --- a/lib/scruby/layer.rb +++ b/lib/scruby/layer.rb @@ -67,7 +67,7 @@ class Layer # 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 @@ class Layer 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 @@ class Layer 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 @@ class Layer 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 --git a/lib/scruby/unittest.rb b/lib/scruby/unittest.rb index 6afa600bd3..e0ae1ff642 100755 --- a/lib/scruby/unittest.rb +++ b/lib/scruby/unittest.rb @@ -16,6 +16,7 @@ def test(is, should) 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 @@ $test_nb = 1 puts "BEGIN" # Constructor arguments -test("IP(nil)", "") #1 +test("IP(nil)", "") test("IP('')", "") test("IP(:foobar)", "") test("IP(Hash.new)", "") test("IP(Array.new)", "") # All dissectors -test("Ether()", "") #6 +test("Ether()", "") +test("ARP()", "") test("IP()", "") -test("TCP()", "") -test("UDP()", "") test("ICMP()", "") test("Raw()", "") +test("TCP()", "") +test("UDP()", "") test("ClassicBSDLoopback()", "") test("OpenBSDLoopback()", "") +test("RIFF()", "") +test("ANI()", "") +test("Dot11()", "") +test("Dot11QoS()", "") +test("Dot11Beacon()", "") +test("Dot11Elt()", "") +test("Dot11ATIM()", "") +test("Dot11Disas()", "") +test("Dot11AssoReq()", "") +test("Dot11AssoResp()", "") +test("Dot11ReassoReq()", "") +test("Dot11ReassoResp()", "") +test("Dot11ProbeReq()", "") +test("Dot11ProbeResp()", "") +test("Dot11Auth()", "") +test("Dot11Deauth()", "") +test("Dot11WEP()", "") +test("LLC()", "") # All dissectors with arguments -test("Ether(:dst=>'11:11:11:11:11:11', :src=>'22:22:22:22:22:22', :type=>666)", "") #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')", "") -test("TCP(:sport=>100, :dport=>101, :seq=>102, :ack=>103, :dataofs=>109, :reserved=>104, :flags=>105, :window=>106, :chksum=>107, :urgptr=>108)", "") +test("Ether(:dst=>'11:11:11:11:11:11', :src=>'22:22:22:22:22:22', :type=>666)", "") +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')", "") +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')", "") +test("TCP(:sport=>100, :dport=>101, :seq=>102, :ack=>103, :dataofs=>109, :reserved=>104, :flags=>'SYN ACK', :window=>106, :chksum=>107, :urgptr=>108)", "") test("UDP(:sport=>100, :dport=>101, :len=>102, :chksum=>103)", "") test("ICMP(:type=>100, :code=>101, :chksum=>102, :id=>103, :seq=>104)", "") test("Raw(:load=>'foobar')", "") test("ClassicBSDLoopback(:header=>100)", "") test("OpenBSDLoopback(:header=>100)", "") +test("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)", "") +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')", "") +test("Dot11Elt(:ID=>1, :len=>2, :info=>'ab')", "") +test("LLC(:dsap=>1, :ssap=>1, :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().src", "127.0.0.1") 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().chksum", "0") 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 @@ test("ClassicBSDLoopback().header", "2") # Fields for OpenBSDLoopback test("OpenBSDLoopback().header", "2") -# Dissecting a string -test("Raw('foobar')", "") +# Fields for RIFF +test("RIFF().id", "RIFF") +test("RIFF().size", "0") +test("RIFF().headerid", "ACON") -# Ether packet #60 +# 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 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", "E\r\000\032\000g@hij\006\225\001\002\003\004\004\003\002\001foobar".inspect) # TCP packet @@ -128,14 +207,32 @@ test("(IP(:proto=>17)/UDP(:sport=>100, :dport=>101)/Raw(:load=>\"foobar\")).to_n # ICMP packet test("(IP(:proto=>1)/ICMP(:type=>0, :code=>101, :id=>103, :seq=>104)).to_net.inspect", "E\000\000\034\000\000\000\000@\001|\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{\")", "") +# Dissecting ARP +test('ARP("\000\001\b\000\006\004\000\002\021\"3DUf\300\250\000\001fUD3\"\021\300\250\000\002")', "") + # Dissecting IP test("IP(\"E\r\000\032\000g@hij\006\225\001\002\003\004\004\003\002\001foobar\")", "") # Dissecting TCP -test("TCP(\"\000d\000e\000\000\000f\000\000\000gS\003\000j\254s\000l\")", "") +test("TCP(\"\000d\000e\000\000\000f\000\000\000gS\003\000j\254s\000l\")", "") # Dissecting UDP test("UDP(\"\000d\000e\000\016\311\302foobar\")", "") @@ -143,7 +240,28 @@ test("UDP(\"\000d\000e\000\016\311\302foobar\")", "") -# Operations on layers # 71 +# Dissecting a string +test("Raw('foobar')", "") + +# Dissecting RIFF +test('RIFF("FOOBC\000\000\000BARZ")', "") + +# 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")', "") + +# Dissecting Dot11 +test('Dot11("\025\001\000\001\021\021\021\021\021\021")', "") + +# Dissecting Dot11Elt +test('Dot11Elt("\001\002ab")', "") + +# 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")', "") + +# Dissecting LLC +test('LLC("\001\001\001")', "") + +# Operations on layers $p=Ether()/"E\000\000.\000\000\000\000@\006|\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.last_layer", "") test("$p.get_layer(TCP)", "") # Dissecting a string byte after byte -test("IP('A')", "") # 76 +test("IP('A')", "") test("IP('A'*2)", "") test("IP('A'*3)", "") test("IP('A'*4)", "") -test("IP('A'*5)", "") # 80 +test("IP('A'*5)", "") test("IP('A'*6)", "") test("IP('A'*7)", "") test("IP('A'*8)", "") @@ -168,7 +286,7 @@ test("IP('A'*11)", "") test("IP('A'*13)", "") test("IP('A'*14)", "") -test("IP('A'*15)", "") # 90 +test("IP('A'*15)", "") test("IP('A'*16)", "") test("IP('A'*17)", "") test("IP('A'*18)", "")