broccoli 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,16 @@
1
+ require 'mkmf'
2
+
3
+ if ex = find_executable("broccoli-config")
4
+ $CFLAGS << " " + `#{ex} --cflags`.chomp
5
+ $LDFLAGS << " " + `#{ex} --libs`.chomp
6
+ else
7
+ raise "You need to have 'broccoli-config' in your path!"
8
+ end
9
+
10
+ if have_header("broccoli.h") and
11
+ # check the broccoli library for the existence
12
+ # of the new event registration function
13
+ have_library("broccoli", "bro_event_registry_add_compact") and
14
+ have_library("ssl")
15
+ create_makefile("broccoli")
16
+ end
@@ -0,0 +1,3 @@
1
+
2
+ File.delete 'mkmf.log' if File.exists? 'mkmf.log'
3
+ File.delete 'Makefile' if File.exists? 'Makefile'
@@ -0,0 +1,5 @@
1
+ bc = `which broccoli-config`
2
+ unless bc.length > 0
3
+ puts "You need to have broccoli-config in your path!"
4
+ exit(-1)
5
+ end
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'broccoli_ext'
4
+ include Broccoli_ext
5
+
6
+ peer = bro_conf_get_str("PeerName")
7
+ puts "Peer: #{peer}"
8
+
9
+ ret, port = bro_conf_get_int("PeerPort")
10
+ if(ret)
11
+ puts "PeerPort: #{ret}"
12
+ end
@@ -0,0 +1,174 @@
1
+ # Please don't try to read too much into this file. It's mostly my
2
+ # internal test file while I'm building the C binding.
3
+ #
4
+ # Check out the examples directory for better examples that use the ruby
5
+ # library I've built overtop the C bindings.
6
+
7
+ require './broccoli_ext'
8
+ include Broccoli_ext
9
+ Broccoli_ext::bro_debug_calltrace=false
10
+ Broccoli_ext::bro_debug_messages=false
11
+
12
+ STDOUT.sync = true
13
+
14
+ #a= Broccoli_ext::BroString.new
15
+ #a.str_val="asdf"
16
+
17
+ host_str = "127.0.0.1:12345"
18
+
19
+ bc = bro_conn_new_str(host_str, BRO_CFLAG_NONE)
20
+ puts "Connection? #{bc}"
21
+ #puts " Connected" unless bro_conn_connect(bc).zero?
22
+
23
+ ###
24
+ # Test BroString Creation
25
+ ###
26
+
27
+ module SWIG
28
+ class TYPE_p_bro_conn
29
+ def method_missing(meth, *args)
30
+ return bro_conn_data_get(self, meth.id2name)
31
+ end
32
+ end
33
+
34
+ class TYPE_p_bro_record
35
+ # I need to build a full record typemapper to deal with this correctly.
36
+
37
+ def method_missing(meth, *args)
38
+ #return bro_record_get_named_val(self, meth.id2name, BRO_TYPE_STRING)
39
+ end
40
+
41
+ def [](position)
42
+ #return bro_record_get_nth_val(self, position, BRO_TYPE_STRING)
43
+ end
44
+ end
45
+ end
46
+
47
+
48
+
49
+ ###
50
+ # Test Record Creation
51
+ ###
52
+ #rec = bro_record_new()
53
+ #puts "Ruby: Inserting data into the record"
54
+ ##time = bro_util_current_time()
55
+ ##puts "Ruby: Current time: #{time}"
56
+ #bro_record_add_val(rec, "seq", BRO_TYPE_IPADDR, 213054988)
57
+ #puts "Ruby: Getting the data back out"
58
+ ##puts bro_record_get_named_val(rec, "seq", BRO_TYPE_COUNT);
59
+ #puts " " + bro_record_get_nth_val(rec, 0, BRO_TYPE_IPADDR).to_s
60
+
61
+
62
+
63
+ ###
64
+ # Test Callback creation
65
+ ###
66
+
67
+ # Ideal :)
68
+ #bro_ruby_typemap_new("pong", [8,19,0])
69
+ #build_typemap("pong", [:conn,:record])
70
+
71
+ #while 1
72
+ # ev = bro_event_new("ping")
73
+ # bro_event_free(ev)
74
+ # #GC.start
75
+ #end
76
+
77
+ bro_pong_record = Proc.new do |conn, rec|
78
+ now = bro_util_current_time()
79
+ puts "Pong_record callback"
80
+ puts rec
81
+
82
+ seq = bro_record_get_nth_val(rec, 0, BRO_TYPE_COUNT)
83
+ src_time = bro_record_get_nth_val(rec, 1, BRO_TYPE_TIME)
84
+ dst_time = bro_record_get_nth_val(rec, 2, BRO_TYPE_TIME)
85
+
86
+ puts "pong event from #{host_str}: seq=#{seq}, time=#{dst_time-src_time}/#{now-src_time} s"
87
+ end
88
+
89
+ bro_pong = Proc.new do |conn, src_time, dst_time, seq|
90
+ puts "Pong callback!"
91
+ now = bro_util_current_time()
92
+ puts "pong event from #{host_str}: seq=#{seq}, time=#{dst_time-src_time}/#{now-src_time} s"
93
+ end
94
+
95
+ new_connection = Proc.new do |conn|
96
+ puts "Saw a connection!"
97
+ end
98
+
99
+ dns_request = Proc.new do |conn, msg, query, qtype, qclass|
100
+ #$count = $count+1
101
+ #puts "msg: #{msg}"
102
+ #puts "query: #{query}"
103
+ #puts "qtype: #{qtype}"
104
+ #puts "qclass: #{qclass}"
105
+ #puts "service: #{conn.blah}"
106
+ #puts "Query output class: #{query.class}"
107
+ #answers = bro_record_get_nth_val(msg, 11, BRO_TYPE_COUNT).to_s
108
+ #puts "Number of dns answers: #{answers}"
109
+ #puts "Query: #{query} - Query type: #{qtype} - Query class: #{qclass}"
110
+ end
111
+
112
+ #puts "Registering callback..."
113
+ #bro_event_registry_add(bc, "dns_A_reply", dns_reply)
114
+
115
+ bro_event_registry_add(bc, "dns_request", ["dns_request", [19, 19, 8, 3, 3], dns_request])
116
+
117
+ #bro_event_registry_add(bc, "pong", ["pong", {"pong", [19]}, bro_pong_record])
118
+ #bro_event_registry_add(bc, "pong", ["pong", {"pong", [6,6,3]}, bro_pong])
119
+
120
+ #bro_event_registry_add(bc, "wootback", [[8], wootback])
121
+
122
+ #bro_event_registry_add(bc, "new_connection", ["new_connection", {"new_connection", [19]}, new_connection])
123
+ #bro_event_registry_add(bc, "return_memory", return_memory)
124
+
125
+ #puts "Done Registering callback..."
126
+ puts "Connected" if bro_conn_connect(bc)
127
+
128
+ while(1)
129
+ #puts "Checking input"
130
+ $count = 0
131
+ bro_conn_process_input(bc)
132
+ puts "*" * ($count/2)
133
+
134
+ sleep 0.5
135
+
136
+ GC.start
137
+ end
138
+ exit
139
+
140
+ ###
141
+ # Testing record creation and event sending
142
+ ###
143
+ record = false
144
+ (1..100).each do |seq|
145
+ bro_conn_process_input(bc)
146
+ #puts "Creating event"
147
+ ev = bro_event_new("ping")
148
+ timestamp = bro_util_current_time()
149
+ if(record)
150
+ rec = bro_record_new()
151
+ bro_record_add_val(rec, "seq", BRO_TYPE_COUNT, seq)
152
+ bro_record_add_val(rec, "src_time", BRO_TYPE_TIME, timestamp)
153
+ bro_event_add_val(ev, BRO_TYPE_RECORD, rec)
154
+ else
155
+ bro_event_add_val(ev, BRO_TYPE_TIME, timestamp)
156
+ bro_event_add_val(ev, BRO_TYPE_COUNT, seq)
157
+ end
158
+
159
+ puts "Sending ping..."
160
+ bro_event_send(bc, ev)
161
+ # May not need to call this anymore either
162
+ #bro_event_free(ev)
163
+ sleep 1
164
+ #GC.start
165
+ end
166
+
167
+ #while(1) do
168
+ # ev = bro_event_new "show_memory"
169
+ # puts "Sending event"
170
+ # puts bro_event_send(bc, ev)
171
+ # sleep 1
172
+ # puts "Processing input..."
173
+ # puts bro_conn_process_input(bc)
174
+ #end
@@ -0,0 +1,78 @@
1
+ # This gives a nice interface for retrieving fields from connections
2
+ module SWIG
3
+ class TYPE_p_bro_conn
4
+ def method_missing(meth, *args)
5
+ return Broccoli::bro_conn_data_get(self, meth.id2name)
6
+ end
7
+ end
8
+ end
9
+
10
+ module Bro
11
+ class Connection
12
+ include Broccoli
13
+
14
+ def initialize(hp, flags=nil)
15
+ flags ||= (BRO_CFLAG_RECONNECT | BRO_CFLAG_ALWAYS_QUEUE)
16
+ @bc = bro_conn_new_str(hp, flags)
17
+ @io_object = nil
18
+ @event_blocks = []
19
+ end
20
+
21
+ def disconnect
22
+ bro_conn_delete(@bc)
23
+ end
24
+
25
+ def connect
26
+ bro_conn_connect(@bc)
27
+ end
28
+
29
+ def connected?
30
+ bro_conn_alive?(@bc)
31
+ end
32
+
33
+ def process_input
34
+ bro_conn_process_input(@bc)
35
+ end
36
+
37
+ def queue_length
38
+ bro_event_queue_length(@bc)
39
+ end
40
+
41
+ def queue_length_max
42
+ bro_event_queue_length_max(@bc)
43
+ end
44
+
45
+ def queue_flush
46
+ bro_event_queue_flush(@bc)
47
+ end
48
+
49
+ def send(event)
50
+ # .ev is the real event pointer
51
+ bro_event_send(@bc, event.ev)
52
+ end
53
+
54
+ def wait
55
+ unless @io_object
56
+ fd = bro_conn_get_fd(@bc)
57
+ return false if fd < 0
58
+ @io_object = IO.new(fd)
59
+ @io_object.sync = true # don't buffer
60
+ end
61
+ # block until there is data
62
+ if @io_object.closed?
63
+ puts "ERROR: connection lost!"
64
+ exit -1
65
+ else
66
+ IO.select([@io_object])
67
+ end
68
+ end
69
+
70
+ def event_handler(event, &callback)
71
+ bro_event_registry_add_compact(@bc, event, callback)
72
+ # Re-request all events if we're already connected.
73
+ bro_event_registry_request(@bc) if connected?
74
+ end
75
+ alias :event_handler_for :event_handler
76
+
77
+ end
78
+ end
data/lib/Bro/event.rb ADDED
@@ -0,0 +1,34 @@
1
+ module Bro
2
+
3
+ class Event
4
+ include Broccoli
5
+ attr_reader :ev
6
+
7
+ def initialize(name)
8
+ @ev = bro_event_new(name)
9
+ # Kill the BroEvent when the ruby object is garbage collected
10
+ ObjectSpace.define_finalizer(self, Event.create_finalizer(@ev))
11
+ end
12
+
13
+ # Insert a value into an event.
14
+ def insert(value, type, type_name=nil)
15
+ value = value.rec if type == :record
16
+ bro_event_add_val(@ev, [Bro::TYPES[type], type_name, value])
17
+ end
18
+
19
+ private
20
+
21
+ # Free the underlying C event data structure. User's are likely
22
+ # never going to need this call.
23
+ def free
24
+ bro_event_free(@ev)
25
+ end
26
+
27
+ # When the garbage collector comes around, make sure the C structure
28
+ # is freed.
29
+ def self.create_finalizer(event)
30
+ proc { bro_event_free(event) }
31
+ end
32
+ end
33
+
34
+ end
data/lib/Bro/record.rb ADDED
@@ -0,0 +1,71 @@
1
+ # This gives a nice interface for retrieving fields from records
2
+ module SWIG
3
+ class TYPE_p_bro_record
4
+ include Broccoli
5
+
6
+ # .id is a method for all ruby objects. Move it out of the way for records.
7
+ alias :orig_id :id
8
+ def id
9
+ return method_missing(:id)
10
+ end
11
+
12
+ # Retrieve record value by name
13
+ def method_missing(meth, *args)
14
+ bro_record_get_named_val(self, meth.id2name)
15
+ end
16
+
17
+ # Retrieve record value by position
18
+ def [](pos)
19
+ bro_record_get_nth_val(self, pos.to_i)
20
+ end
21
+ end
22
+ end
23
+
24
+
25
+ module Bro
26
+ class Record
27
+ include Broccoli
28
+ attr_accessor :rec
29
+
30
+ def initialize
31
+ @rec = bro_record_new()
32
+ # Kill the BroRecord when the ruby object is garbage collected
33
+ ObjectSpace.define_finalizer(self, Record.create_finalizer(@rec))
34
+ end
35
+
36
+ # .id is a method for all ruby objects. Move it out of the way for records.
37
+ alias :orig_id :id
38
+ def id
39
+ return method_missing(:id)
40
+ end
41
+
42
+ # Forward any missing methods on to the actual record object
43
+ def method_missing(meth)
44
+ @rec.send(meth)
45
+ end
46
+
47
+ def insert(name, value, type, type_name=nil)
48
+ value = value.rec if type == :record
49
+ bro_record_add_val(@rec, name.to_s, [Bro::TYPES[type], type_name, value])
50
+ end
51
+
52
+ def insert_at(pos, value, type, type_name=nil)
53
+ value = value.rec if type == :record
54
+ bro_record_set_nth_val(@rec, pos, [Bro::TYPES[type], type_name, value])
55
+ end
56
+ alias :insert_at_position :insert_at
57
+
58
+ private
59
+
60
+ def free
61
+ bro_record_free(@rec)
62
+ end
63
+
64
+ # When the garbage collector comes around,
65
+ # make sure the C structure is freed.
66
+ def self.create_finalizer(record)
67
+ proc { bro_record_free(record) }
68
+ end
69
+ end
70
+
71
+ end
data/lib/bro.rb ADDED
@@ -0,0 +1,87 @@
1
+ require 'broccoli'
2
+ require 'time'
3
+
4
+ require 'bro/connection'
5
+ require 'bro/event'
6
+ require 'bro/record'
7
+
8
+ module Bro
9
+ include Broccoli
10
+
11
+ TYPES = {:unknown => BRO_TYPE_UNKNOWN, # not really sure how this should be handled.
12
+ :bool => BRO_TYPE_BOOL,
13
+ :int => BRO_TYPE_INT,
14
+ :count => BRO_TYPE_COUNT,
15
+ :counter => BRO_TYPE_COUNTER,
16
+ :double => BRO_TYPE_DOUBLE,
17
+ :time => BRO_TYPE_TIME,
18
+ :interval => BRO_TYPE_INTERVAL,
19
+ :string => BRO_TYPE_STRING,
20
+ :enum => BRO_TYPE_ENUM,
21
+ :timer => BRO_TYPE_TIMER,
22
+ :port => BRO_TYPE_PORT,
23
+ :addr => BRO_TYPE_IPADDR,
24
+ :net => BRO_TYPE_NET,
25
+ :subnet => BRO_TYPE_SUBNET,
26
+ :record => BRO_TYPE_RECORD,
27
+ # These are not handled by the ruby binding.
28
+ :packet => BRO_TYPE_PACKET,
29
+ :max => BRO_TYPE_MAX,
30
+ # All types below are NOT handled by broccoli.
31
+ :pattern => BRO_TYPE_PATTERN,
32
+ :any => BRO_TYPE_ANY,
33
+ :table => BRO_TYPE_TABLE,
34
+ :union => BRO_TYPE_UNION,
35
+ :list => BRO_TYPE_LIST,
36
+ :func => BRO_TYPE_FUNC,
37
+ :file => BRO_TYPE_FILE,
38
+ :vector => BRO_TYPE_VECTOR,
39
+ :error => BRO_TYPE_ERROR
40
+ }
41
+
42
+ def Bro.current_time_f
43
+ Broccoli::bro_util_current_time
44
+ end
45
+
46
+ def Bro.current_time
47
+ Time.at( current_time_f() )
48
+ end
49
+
50
+ def Bro.debug_calltrace=(v)
51
+ Broccoli::bro_debug_calltrace=v
52
+ end
53
+
54
+ def Bro.debug_messages=(v)
55
+ Broccoli::bro_debug_messages=v
56
+ end
57
+ end
58
+
59
+ class Broccoli::BroPort
60
+ @@protocols = {0=>'ip', 1=>'icmp', 2=>'igmp', 3=>'ggp', 4=>'ipv4',
61
+ 6=>'tcp', 7=>'st', 8=>'egp', 9=>'pigp', 10=>'rccmon',
62
+ 11=>'nvpii', 12=>'pup', 13=>'argus', 14=>'emcon',
63
+ 15=>'xnet', 16=>'chaos', 17=>'udp', 18=>'mux', 19=>'meas',
64
+ 20=>'hmp', 21=>'prm', 22=>'idp', 23=>'trunk1', 24=>'trunk2',
65
+ 25=>'leaf1', 26=>'leaf2', 27=>'rdp', 28=>'irtp', 29=>'tp',
66
+ 30=>'blt', 31=>'nsp', 32=>'inp', 33=>'sep', 34=>'3pc',
67
+ 35=>'idpr', 36=>'xtp', 37=>'ddp', 38=>'cmtp', 39=>'tpxx',
68
+ 40=>'il', 41=>'ipv6', 42=>'sdrp', 43=>'routing',
69
+ 44=>'fragment', 45=>'idrp', 46=>'rsvp', 47=>'gre', 48=>'mhrp',
70
+ 49=>'bha', 50=>'esp', 51=>'ah', 52=>'inlsp', 53=>'swipe',
71
+ 54=>'nhrp', 58=>'icmpv6', 59=>'nonext', 60=>'dstopts',
72
+ 61=>'ahip', 62=>'cftp', 63=>'hello', 64=>'satexpak',
73
+ 65=>'kryptolan', 66=>'rvd', 67=>'ippc', 68=>'adfs',
74
+ 69=>'satmon', 70=>'visa', 71=>'ipcv', 72=>'cpnx', 73=>'cphb',
75
+ 74=>'wsn', 75=>'pvp', 76=>'brsatmon', 77=>'nd', 78=>'wbmon',
76
+ 79=>'wbexpak', 80=>'eon', 81=>'vmtp', 82=>'svmtp',
77
+ 83=>'vines', 84=>'ttp', 85=>'igp', 86=>'dgp', 87=>'tcf',
78
+ 88=>'igrp', 89=>'ospfigp', 90=>'srpc', 91=>'larp', 92=>'mtp',
79
+ 93=>'ax25', 94=>'ipeip', 95=>'micp', 96=>'sccsp',
80
+ 97=>'etherip', 98=>'encap', 99=>'apes', 100=>'gmtp',
81
+ 103=>'pim', 108=>'ipcomp', 113=>'pgm', 254=>'divert',
82
+ 255=>'raw'}
83
+ def to_s
84
+ #"#{port_num}/#{@@protocols[port_proto]}"
85
+ port_num.to_s
86
+ end
87
+ end