Class: Rex::Post::HWBridge::Extensions::Automotive::Automotive

Inherits:
Rex::Post::HWBridge::Extension show all
Includes:
UDSErrors
Defined in:
lib/rex/post/hwbridge/extensions/automotive/automotive.rb

Overview

Automotive extension - set of commands to be executed on automotive hw bridges

Constant Summary

Constants included from UDSErrors

UDSErrors::ERR_DESC, UDSErrors::ERR_MNEMONIC

Instance Attribute Summary collapse

Attributes inherited from Rex::Post::HWBridge::Extension

#client, #name

Instance Method Summary collapse

Constructor Details

#initialize(client) ⇒ Automotive

Returns a new instance of Automotive.


20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/rex/post/hwbridge/extensions/automotive/automotive.rb', line 20

def initialize(client)
  super(client, 'automotive')

  # Alias the following things on the client object so that they
  # can be directly referenced
  client.register_extension_aliases(
    [
      {
        'name' => 'automotive',
        'ext'  => self
      }
    ])
end

Instance Attribute Details

#active_busObject

Returns the value of attribute active_bus


137
138
139
# File 'lib/rex/post/hwbridge/extensions/automotive/automotive.rb', line 137

def active_bus
  @active_bus
end

#busesObject

Returns the value of attribute buses


137
138
139
# File 'lib/rex/post/hwbridge/extensions/automotive/automotive.rb', line 137

def buses
  @buses
end

Instance Method Details

#array2hex(arr) ⇒ Array

Pass an array of bytes and return an array of ASCII byte representation

Parameters:

  • arr (Array)

    Array of integers (bytes)

Returns:

  • (Array)

    Array of Hex string equivalents


79
80
81
82
# File 'lib/rex/post/hwbridge/extensions/automotive/automotive.rb', line 79

def array2hex(arr)
  # We give the flexibility of sending Integers or string hexes in the array
  arr.map { |b| "%02x" % (b.respond_to?("hex") ? b.hex : b ) }
end

#cansend(bus, id, data) ⇒ Object


114
115
116
# File 'lib/rex/post/hwbridge/extensions/automotive/automotive.rb', line 114

def cansend(bus, id, data)
  client.send_request("/automotive/#{bus}/cansend?id=#{id}&data=#{data}")
end

#check_for_errors(data) ⇒ Hash

Checks for Errors in ISO-TP responses. If an error is present Document the error with an additional “error” => { “ACRONYMN” => “Definition” }

Parameters:

  • data (Hash)

    client.send_request response

Returns:

  • (Hash)

    client.send_request response with “Error” if any exist


57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/rex/post/hwbridge/extensions/automotive/automotive.rb', line 57

def check_for_errors(data)
  if data && (data.key? "Packets")
    if data["Packets"].size == 1
      if data["Packets"][0]["DATA"].size > 3 && data["Packets"][0]["DATA"][1].hex == 0x7F
        if ERR_MNEMONIC.key? data["Packets"][0]["DATA"][3].hex
          err = data["Packets"][0]["DATA"][3].hex
          data["error"] = { ERR_MNEMONIC[err] => ERR_DESC[ERR_MNEMONIC[err]] }
        else
          data["error"] = { "UNK" => "An Unknown error detected" }
        end
      end
    end
  end
  data
end

#get_bus_config(bus) ⇒ Object


105
106
107
108
# File 'lib/rex/post/hwbridge/extensions/automotive/automotive.rb', line 105

def get_bus_config(bus)
  status = client.send_request("/automotive/#{bus}/config")
  status
end

#get_supported_busesObject


100
101
102
103
# File 'lib/rex/post/hwbridge/extensions/automotive/automotive.rb', line 100

def get_supported_buses
  self.buses = client.send_request("/automotive/supported_buses")
  self.buses
end

#get_supported_methods(bus) ⇒ Object


110
111
112
# File 'lib/rex/post/hwbridge/extensions/automotive/automotive.rb', line 110

def get_supported_methods(bus)
  client.send_request("/automotive/#{bus}/supported_methods")
end

#is_valid_bus?(bus) ⇒ Boolean

Checks to see if the specified bus is valid

Parameters:

  • bus (String)

    bus name

Returns:

  • (Boolean)

    return true if bus is valid


40
41
42
43
44
45
46
47
48
49
# File 'lib/rex/post/hwbridge/extensions/automotive/automotive.rb', line 40

def is_valid_bus?(bus)
  valid = false
  get_supported_buses if buses.nil?
  unless bus.blank?
    self.buses.each do |b|
      valid = true if b["bus_name"] == bus
    end
  end
  valid
end

#padd_packet(data, padding) ⇒ Array

Pad the end of a packet with a set byte until it is 8 bytes long

Parameters:

  • data (Array)

    Packet to padd

  • padding (Integer)

    Expected single byte 0x00 style argument

Returns:

  • (Array)

    Packet as data


90
91
92
93
94
# File 'lib/rex/post/hwbridge/extensions/automotive/automotive.rb', line 90

def padd_packet(data, padding)
  return data if padding.nil?
  return data if data.size > 7
  data + [ padding ] * (8 - data.size)
end

#send_isotp_and_wait_for_response(bus, src_id, dst_id, data, opt = {}) ⇒ Object


118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
# File 'lib/rex/post/hwbridge/extensions/automotive/automotive.rb', line 118

def send_isotp_and_wait_for_response(bus, src_id, dst_id, data, opt = {})
  # TODO: Implement sending ISO-TP > 8 bytes
  data = [ data ] if data.is_a? Integer
  if data.size < 8
    # Padding is handled differently after 0.0.3
    if Gem::Version.new(client.api_version) < Gem::Version.new('0.0.4')
      data = padd_packet(data, opt['PADDING']) if opt.key? 'PADDING'
    end
    data = array2hex(data).join
    request_str = "/automotive/#{bus}/isotpsend_and_wait?srcid=#{src_id}&dstid=#{dst_id}&data=#{data}"
    request_str += "&timeout=#{opt['TIMEOUT']}" if opt.key? "TIMEOUT"
    request_str += "&maxpkts=#{opt['MAXPKTS']}" if opt.key? "MAXPKTS"
    request_str += "&padding=#{opt['PADDING']}" if opt.key? "PADDING" # Won't hurt to use in older versions
    request_str += "&fc=#{opt['FC']}" if opt.key? "FC" # Force flow control
    return check_for_errors(client.send_request(request_str))
  end
  nil
end

#set_active_bus(bus) ⇒ Object


96
97
98
# File 'lib/rex/post/hwbridge/extensions/automotive/automotive.rb', line 96

def set_active_bus(bus)
  self.active_bus = bus
end