Class: Racket::Racket

Inherits:
Object
  • Object
show all
Defined in:
lib/racket/racket.rb

Constant Summary collapse

@@loaded_pcaprub =
false

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(payload = "") ⇒ Racket

Returns a new instance of Racket.



51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/racket/racket.rb', line 51

def initialize(payload="")
  @layers = []
  @mtu = 1500
  @timeout = 10
  @payload = payload
  1.upto(7) do |l|
    self.class.send(:define_method, "layer#{l}", lambda { @layers[l] })
    self.class.send(:define_method, "l#{l}", lambda { @layers[l] })
    self.class.send(:define_method, "layer#{l}=", lambda { |x| @layers[l] = x; })
    self.class.send(:define_method, "l#{l}=", lambda { |x| @layers[l] = x; })
  end
end

Instance Attribute Details

#ifaceObject

Returns the value of attribute iface.



40
41
42
# File 'lib/racket/racket.rb', line 40

def iface
  @iface
end

#layersObject

Returns the value of attribute layers.



41
42
43
# File 'lib/racket/racket.rb', line 41

def layers
  @layers
end

#mtuObject

Returns the value of attribute mtu.



40
41
42
# File 'lib/racket/racket.rb', line 40

def mtu
  @mtu
end

#payloadObject

Returns the value of attribute payload.



41
42
43
# File 'lib/racket/racket.rb', line 41

def payload
  @payload
end

#timeoutObject

Returns the value of attribute timeout.



40
41
42
# File 'lib/racket/racket.rb', line 40

def timeout
  @timeout
end

Instance Method Details

#packObject

Assemble all the pieces of this Racket as a string, ready for sending.



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/racket/racket.rb', line 65

def pack
  last_payload = ""
  orig_payload = ""
  @layers.compact.reverse.each do |l|
    # save the original payload
    orig_payload = l.payload
    # tack on the last payload in
    # case fix needs it...
    l.payload += last_payload
    if (l.autofix?)
      l.fix!
    end

    if (l.payload == orig_payload + last_payload)
      # payload was not modified by fix, so reset it to what
      # it used to be
      l.payload = orig_payload
    else
      # payload was modified by fix.  chop off what we added.
      # XXX: this assumes that what we added is still at the end.  
      # XXX: this is not always true
      l.payload = l.payload.slice(0, l.payload.length - last_payload.length)
    end

    # save this layer for the next guy
    last_payload += l
    
  end
  
  payload = ""
  @layers.compact.each do |l|
    payload += l
  end
  payload
end

#prettyObject

return a pretty interpretation of this packet



102
103
104
105
106
107
108
109
110
# File 'lib/racket/racket.rb', line 102

def pretty
  s = ""
  @layers.compact.each do |l|
    s << "#{l.class}: "
    s << l.pretty
    s << "\n"
  end
  s
end

#send2Object

Write raw layer2 frames



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/racket/racket.rb', line 123

def send2
  if(not @@loaded_pcaprub)
    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})"
    return
  end

  begin
    b = p.inject(pack)
    #p.pcap_close
    return b
  rescue Exception => e
    puts "Pcap: error while sending packet on '#{@iface}' (#{e})"
  end
end

#send3Object

Write raw layer3 frames



145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/racket/racket.rb', line 145

def send3
  begin
    s = Socket.open(Socket::PF_INET, Socket::SOCK_RAW, Socket::IPPROTO_RAW)

    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
    raise ArgumentError, "Must run #{$0} as root."
  end

  return s.send(pack, 0, Socket.pack_sockaddr_in(1024, @layers[3].dst_ip))
end

#sendpacketObject

Attempt to figure out which of send2 or send3 needs to be called.



114
115
116
117
118
119
120
# File 'lib/racket/racket.rb', line 114

def sendpacket
  if (@layers[2])
    send2
  else
    send3
  end
end