lwes 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,27 @@
1
+ #include "lwes_ruby.h"
2
+
3
+ static VALUE mLWES;
4
+
5
+ /* initialize the extension, Ruby automatically picks this up */
6
+ void Init_lwes_ext(void)
7
+ {
8
+ mLWES = rb_define_module("LWES");
9
+
10
+ #define LWES_TYPE_CONST(name) \
11
+ rb_define_const(mLWES, #name, INT2FIX(LWES_TYPE_##name))
12
+ LWES_TYPE_CONST(U_INT_16);
13
+ LWES_TYPE_CONST(INT_16);
14
+ LWES_TYPE_CONST(U_INT_32);
15
+ LWES_TYPE_CONST(INT_32);
16
+ LWES_TYPE_CONST(U_INT_64);
17
+ LWES_TYPE_CONST(INT_64);
18
+ LWES_TYPE_CONST(BOOLEAN);
19
+ LWES_TYPE_CONST(IP_ADDR);
20
+ LWES_TYPE_CONST(STRING);
21
+ LWES_TYPE_CONST(UNDEFINED);
22
+ #undef LWES_TYPE_CONST
23
+
24
+ lwesrb_init_numeric();
25
+ lwesrb_init_emitter();
26
+ lwesrb_init_type_db();
27
+ }
@@ -0,0 +1,40 @@
1
+ #ifndef LWES_RUBY_H
2
+ #define LWES_RUBY_H
3
+
4
+ #include <lwes.h>
5
+ #include <ruby.h>
6
+ #include <assert.h>
7
+ #include <stdint.h>
8
+
9
+ #define LWESRB_MKSYM(SYM) sym_##SYM = ID2SYM(rb_intern(#SYM))
10
+
11
+ struct lwes_event_type_db * lwesrb_get_type_db(VALUE self);
12
+
13
+ void lwesrb_init_type_db(void);
14
+
15
+ void lwesrb_init_emitter(void);
16
+
17
+ void lwesrb_init_numeric(void);
18
+
19
+ int lwesrb_event_set_numeric(
20
+ struct lwes_event *event,
21
+ LWES_CONST_SHORT_STRING name,
22
+ VALUE array);
23
+
24
+ int lwesrb_event_set_num(
25
+ struct lwes_event *event,
26
+ LWES_CONST_SHORT_STRING name,
27
+ LWES_TYPE type,
28
+ VALUE val);
29
+
30
+ #ifndef RSTRING_PTR
31
+ # define RSTRING_PTR(s) (RSTRING(s)->ptr)
32
+ # define RSTRING_LEN(s) (RSTRING(s)->len)
33
+ #endif
34
+
35
+ #ifndef RARRAY_PTR
36
+ # define RARRAY_PTR(s) (RARRAY(s)->ptr)
37
+ # define RARRAY_LEN(s) (RARRAY(s)->len)
38
+ #endif
39
+
40
+ #endif /* LWES_RUBY_H */
@@ -0,0 +1,207 @@
1
+ #include "lwes_ruby.h"
2
+ #include <arpa/inet.h>
3
+
4
+ static ID
5
+ sym_int16, sym_uint16,
6
+ sym_int32, sym_uint32,
7
+ sym_int64, sym_uint64,
8
+ sym_ip_addr;
9
+
10
+ static int set_uint16(
11
+ struct lwes_event *event, LWES_CONST_SHORT_STRING name, VALUE val)
12
+ {
13
+ int32_t tmp = NUM2INT(val);
14
+
15
+ if (tmp < 0)
16
+ rb_raise(rb_eRangeError, ":uint16 negative: %d", tmp);
17
+ if (tmp > UINT16_MAX)
18
+ rb_raise(rb_eRangeError, ":uint16 too large: %d", tmp);
19
+
20
+ return lwes_event_set_U_INT_16(event, name, (LWES_U_INT_16)tmp);
21
+ }
22
+
23
+ static int set_int16(
24
+ struct lwes_event *event, LWES_CONST_SHORT_STRING name, VALUE val)
25
+ {
26
+ int tmp = NUM2INT(val);
27
+
28
+ if (tmp > INT16_MAX)
29
+ rb_raise(rb_eRangeError, ":int16 too large: %i", tmp);
30
+ if (tmp < INT16_MIN)
31
+ rb_raise(rb_eRangeError, ":int16 too small: %i", tmp);
32
+
33
+ return lwes_event_set_INT_16(event, name, (LWES_INT_16)tmp);
34
+ }
35
+
36
+ static int set_uint32(
37
+ struct lwes_event *event, LWES_CONST_SHORT_STRING name, VALUE val)
38
+ {
39
+ LONG_LONG tmp = NUM2LL(val);
40
+
41
+ if (tmp < 0)
42
+ rb_raise(rb_eRangeError, ":uint32 negative: %lli", tmp);
43
+ if (tmp > UINT32_MAX)
44
+ rb_raise(rb_eRangeError, ":uint32 too large: %lli", tmp);
45
+
46
+ return lwes_event_set_U_INT_32(event, name, (LWES_U_INT_32)tmp);
47
+ }
48
+
49
+ static int set_int32(
50
+ struct lwes_event *event, LWES_CONST_SHORT_STRING name, VALUE val)
51
+ {
52
+ LONG_LONG tmp = NUM2LL(val);
53
+
54
+ if (tmp > INT32_MAX)
55
+ rb_raise(rb_eRangeError, ":int32 too large: %lli", tmp);
56
+ if (tmp < INT32_MIN)
57
+ rb_raise(rb_eRangeError, ":int32 too small: %lli", tmp);
58
+
59
+ return lwes_event_set_INT_32(event, name, (LWES_INT_32)tmp);
60
+ }
61
+
62
+ static int set_uint64(
63
+ struct lwes_event *event, LWES_CONST_SHORT_STRING name, VALUE val)
64
+ {
65
+ unsigned LONG_LONG tmp = NUM2ULL(val); /* can raise RangeError */
66
+ ID type = TYPE(val);
67
+
68
+ if ((type == T_FIXNUM && FIX2LONG(val) < 0) ||
69
+ (type == T_BIGNUM && RTEST(rb_funcall(val, '<', 1, INT2FIX(0)))))
70
+ rb_raise(rb_eRangeError, ":uint64 negative: %s",
71
+ RSTRING_PTR(rb_inspect(val)));
72
+
73
+ return lwes_event_set_U_INT_64(event, name, (LWES_U_INT_64)tmp);
74
+ }
75
+
76
+ static int set_int64(
77
+ struct lwes_event *event, LWES_CONST_SHORT_STRING name, VALUE val)
78
+ {
79
+ LONG_LONG tmp = NUM2LL(val); /* can raise RangeError */
80
+
81
+ return lwes_event_set_INT_64(event, name, (LWES_INT_64)tmp);
82
+ }
83
+
84
+ static int set_ip_addr(
85
+ struct lwes_event *event, LWES_CONST_SHORT_STRING name, VALUE val)
86
+ {
87
+ switch (TYPE(val)) {
88
+ case T_STRING:
89
+ {
90
+ LWES_CONST_SHORT_STRING addr = RSTRING_PTR(val);
91
+ return lwes_event_set_IP_ADDR_w_string(event, name, addr);
92
+ }
93
+ case T_FIXNUM:
94
+ case T_BIGNUM:
95
+ {
96
+ LWES_IP_ADDR *addr = ALLOC(LWES_IP_ADDR); /* never fails */
97
+ int rv;
98
+
99
+ addr->s_addr = htonl(NUM2UINT(val));
100
+ rv = lwes_event_set_IP_ADDR(event, name, *addr);
101
+
102
+ if (rv < 0)
103
+ xfree(addr);
104
+ return rv;
105
+ }
106
+ default:
107
+ rb_raise(rb_eTypeError,
108
+ ":ip_addr address must be String or Integer: %s",
109
+ RSTRING_PTR(rb_inspect(val)));
110
+ }
111
+ }
112
+
113
+ /* simple type => function dispatch map */
114
+ static struct _type_fn_map {
115
+ ID type;
116
+ int (*fn)(struct lwes_event *, LWES_CONST_SHORT_STRING, VALUE);
117
+ } type_fn_map[] = {
118
+ #define SYMFN(T) { (ID)&sym_##T, set_##T }
119
+ SYMFN(uint16),
120
+ SYMFN(int16),
121
+ SYMFN(uint32),
122
+ SYMFN(int32),
123
+ SYMFN(uint64),
124
+ SYMFN(int64),
125
+ SYMFN(ip_addr),
126
+ #undef SYMFN
127
+ };
128
+
129
+ int lwesrb_event_set_num(
130
+ struct lwes_event *event,
131
+ LWES_CONST_SHORT_STRING name,
132
+ LWES_TYPE type,
133
+ VALUE val)
134
+ {
135
+ switch (type) {
136
+ case LWES_TYPE_U_INT_16: return set_uint16(event, name, val);
137
+ case LWES_TYPE_INT_16: return set_int16(event, name, val);
138
+ case LWES_TYPE_U_INT_32: return set_uint32(event, name, val);
139
+ case LWES_TYPE_INT_32: return set_int32(event, name, val);
140
+ case LWES_TYPE_U_INT_64: return set_uint64(event, name, val);
141
+ case LWES_TYPE_INT_64: return set_int64(event, name, val);
142
+ case LWES_TYPE_IP_ADDR: return set_ip_addr(event, name, val);
143
+ default:
144
+ rb_raise(rb_eRuntimeError,
145
+ "unknown LWES attribute type: 0x%02x", type);
146
+ }
147
+ assert("you should never get here (set_field)");
148
+ return -1;
149
+ }
150
+
151
+ /*
152
+ * array contains two elements:
153
+ * [ symbolic_type, number ]
154
+ * returns the return value of the underlying lwes_event_set_* call
155
+ */
156
+ int lwesrb_event_set_numeric(
157
+ struct lwes_event *event,
158
+ LWES_CONST_SHORT_STRING name,
159
+ VALUE array)
160
+ {
161
+ int i;
162
+ struct _type_fn_map *head;
163
+ VALUE *ary;
164
+ ID type;
165
+
166
+ assert(TYPE(array) == T_ARRAY && "need array here");
167
+
168
+ if (RARRAY_LEN(array) != 2)
169
+ rb_raise(rb_eArgError, "expected a two element array");
170
+
171
+ ary = RARRAY_PTR(array);
172
+ type = ary[0];
173
+
174
+ i = sizeof(type_fn_map) / sizeof(type_fn_map[0]);
175
+ for (head = type_fn_map; --i >= 0; head++) {
176
+ if (head->type == type)
177
+ return head->fn(event, name, ary[1]);
178
+ }
179
+
180
+ rb_raise(rb_eArgError,
181
+ "unknown type: %s",
182
+ RSTRING_PTR(rb_inspect(type)));
183
+
184
+ return -1;
185
+ }
186
+
187
+ void lwesrb_init_numeric(void)
188
+ {
189
+ int i;
190
+
191
+ LWESRB_MKSYM(int16);
192
+ LWESRB_MKSYM(uint16);
193
+ LWESRB_MKSYM(int32);
194
+ LWESRB_MKSYM(uint32);
195
+ LWESRB_MKSYM(int64);
196
+ LWESRB_MKSYM(uint64);
197
+ LWESRB_MKSYM(ip_addr);
198
+
199
+ /*
200
+ * we needed to have constants for compilation, so we set the
201
+ * address of the IDs and then dereference + reassign them
202
+ * at initialization time:
203
+ */
204
+ i = sizeof(type_fn_map) / sizeof(type_fn_map[0]);
205
+ while (--i >= 0)
206
+ type_fn_map[i].type = *(ID *)type_fn_map[i].type;
207
+ }
@@ -0,0 +1,147 @@
1
+ #include "lwes_ruby.h"
2
+
3
+ static VALUE cLWES_TypeDB;
4
+
5
+ struct _tdb {
6
+ struct lwes_event_type_db *db;
7
+ };
8
+
9
+ static void tdb_free(void *ptr)
10
+ {
11
+ struct _tdb *tdb = ptr;
12
+
13
+ if (tdb->db)
14
+ lwes_event_type_db_destroy(tdb->db);
15
+ tdb->db = NULL;
16
+ }
17
+
18
+ static VALUE tdb_alloc(VALUE klass)
19
+ {
20
+ struct _tdb *tdb;
21
+
22
+ return Data_Make_Struct(klass, struct _tdb, NULL, tdb_free, tdb);
23
+ }
24
+
25
+ static VALUE tdb_init(VALUE self, VALUE path)
26
+ {
27
+ struct _tdb *tdb;
28
+
29
+ Data_Get_Struct(self, struct _tdb, tdb);
30
+ if (tdb->db)
31
+ rb_raise(rb_eRuntimeError, "ESF already initialized");
32
+
33
+ tdb->db = lwes_event_type_db_create(RSTRING_PTR(path));
34
+ if (!tdb->db)
35
+ rb_raise(rb_eRuntimeError,
36
+ "failed to create type DB for LWES file %s",
37
+ RSTRING_PTR(path));
38
+
39
+ return Qnil;
40
+ }
41
+
42
+ static VALUE attr_sym(struct lwes_event_attribute *attr)
43
+ {
44
+ switch (attr->type) {
45
+ case LWES_TYPE_U_INT_16:
46
+ case LWES_TYPE_INT_16:
47
+ case LWES_TYPE_U_INT_32:
48
+ case LWES_TYPE_INT_32:
49
+ case LWES_TYPE_U_INT_64:
50
+ case LWES_TYPE_INT_64:
51
+ case LWES_TYPE_BOOLEAN:
52
+ case LWES_TYPE_IP_ADDR:
53
+ case LWES_TYPE_STRING:
54
+ return INT2NUM(attr->type);
55
+ case LWES_TYPE_UNDEFINED:
56
+ default:
57
+ rb_raise(rb_eRuntimeError,
58
+ "unknown LWES attribute type: 0x%02x", attr->type);
59
+ }
60
+
61
+ return Qfalse;
62
+ }
63
+
64
+ static VALUE event_def_ary(struct lwes_hash *hash)
65
+ {
66
+ struct lwes_hash_enumeration e;
67
+ VALUE rv = rb_ary_new();
68
+
69
+ if (!lwes_hash_keys(hash, &e))
70
+ rb_raise(rb_eRuntimeError, "couldn't get event attributes");
71
+ while (lwes_hash_enumeration_has_more_elements(&e)) {
72
+ LWES_SHORT_STRING key = lwes_hash_enumeration_next_element(&e);
73
+ struct lwes_event_attribute *attr;
74
+ VALUE pair;
75
+
76
+ if (!key)
77
+ rb_raise(rb_eRuntimeError,
78
+ "LWES event type iteration key fail");
79
+
80
+ attr = (struct lwes_event_attribute *)lwes_hash_get(hash, key);
81
+ if (!attr)
82
+ rb_raise(rb_eRuntimeError,
83
+ "LWES event type iteration value fail");
84
+
85
+ pair = rb_ary_new3(2, ID2SYM(rb_intern(key)), attr_sym(attr));
86
+ rb_ary_push(rv, pair);
87
+ }
88
+
89
+ return rv;
90
+ }
91
+
92
+ struct lwes_event_type_db * lwesrb_get_type_db(VALUE self)
93
+ {
94
+ struct _tdb *tdb;
95
+
96
+ Data_Get_Struct(self, struct _tdb, tdb);
97
+ if (!tdb->db)
98
+ rb_raise(rb_eRuntimeError,
99
+ "couldn't get lwes_type_db from %s",
100
+ RSTRING_PTR(rb_inspect(self)));
101
+
102
+ return tdb->db;
103
+ }
104
+
105
+ static VALUE tdb_to_hash(VALUE self)
106
+ {
107
+ struct _tdb *tdb;
108
+ VALUE rv = rb_hash_new();
109
+ struct lwes_hash *events;
110
+ struct lwes_hash_enumeration e;
111
+
112
+ Data_Get_Struct(self, struct _tdb, tdb);
113
+ assert(tdb->db && tdb->db->events && "tdb not initialized");
114
+ events = tdb->db->events;
115
+
116
+ if (!lwes_hash_keys(events, &e))
117
+ rb_raise(rb_eRuntimeError, "couldn't get type_db events");
118
+
119
+ while (lwes_hash_enumeration_has_more_elements(&e)) {
120
+ struct lwes_hash *hash;
121
+ ID event_key;
122
+ LWES_SHORT_STRING key = lwes_hash_enumeration_next_element(&e);
123
+
124
+ if (!key)
125
+ rb_raise(rb_eRuntimeError,
126
+ "LWES type DB rv iteration key fail");
127
+
128
+ hash = (struct lwes_hash*)lwes_hash_get(events, key);
129
+ if (!hash)
130
+ rb_raise(rb_eRuntimeError,
131
+ "LWES type DB rv iteration value fail");
132
+
133
+ event_key = ID2SYM(rb_intern(key));
134
+ rb_hash_aset(rv, event_key, event_def_ary(hash));
135
+ }
136
+
137
+ return rv;
138
+ }
139
+
140
+ void lwesrb_init_type_db(void)
141
+ {
142
+ VALUE mLWES = rb_define_module("LWES");
143
+ cLWES_TypeDB = rb_define_class_under(mLWES, "TypeDB", rb_cObject);
144
+ rb_define_method(cLWES_TypeDB, "initialize", tdb_init, 1);
145
+ rb_define_method(cLWES_TypeDB, "to_hash", tdb_to_hash, 0);
146
+ rb_define_alloc_func(cLWES_TypeDB, tdb_alloc);
147
+ }
@@ -0,0 +1,6 @@
1
+ module LWES
2
+ autoload :TypeDB, "lwes/type_db"
3
+ autoload :Struct, "lwes/struct"
4
+ autoload :Emitter, "lwes/emitter"
5
+ end
6
+ require "lwes_ext"
@@ -0,0 +1,19 @@
1
+ module LWES
2
+ class Emitter
3
+
4
+ # creates a new Emitter object which may be used for the lifetime
5
+ # of the process:
6
+ #
7
+ # LWES::Emitter.new(:address => '224.1.1.11',
8
+ # :iface => '0.0.0.0',
9
+ # :port => 12345,
10
+ # :heartbeat => false, # Integer for frequency
11
+ # :ttl => 60, # nil for no ttl)
12
+ #
13
+ def initialize(options = {}, &block)
14
+ options[:iface] ||= '0.0.0.0'
15
+ _create(options)
16
+ block_given?
17
+ end
18
+ end
19
+ end