lwes 0.1.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,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