Vflow 1.0.3

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.
data/README ADDED
@@ -0,0 +1,95 @@
1
+ $Id: README,v 1.5 2004/12/13 11:13:18 jeffm Exp $
2
+
3
+ vflow is an attempt at a ruby replacement for the perl Cflow or python pyflowtool
4
+ modules. This is beta and should be safe for limited use it passes testing by the
5
+ vftest.rb script.
6
+
7
+ Installation
8
+ ============
9
+ To install do the following, when installing from gem,
10
+
11
+ gem install vflow
12
+
13
+ If installing manually from tar.gz file,
14
+
15
+ cd ext
16
+ ruby extconf.rb
17
+ make
18
+ make install
19
+
20
+ If your flow-tools headers and libraries are not in a common path you can use
21
+
22
+ --with-ft-include-dir=<include file directory>
23
+ and
24
+ --with-ft-lib-dir=<library directory>
25
+
26
+ as arguments to extconf.rb to specify the paths.
27
+
28
+ vftest.rb prints flow data from testdata/dummy_flow file
29
+ vfprofile.rb profiles vflow processing the dummy_flow file
30
+
31
+ The following methods are defined as part of vflow
32
+ new()
33
+ Creates and returns a vflow object
34
+ open(filename)
35
+ Open file of filename which has been created by flow-tools for reading.
36
+ If a block is given, the file will be automatically closed at the end of the block
37
+ close()
38
+ Close the current file
39
+ currentfile()
40
+ return the name of the current file being read from.
41
+ next()
42
+ Returns a vflowrec object containing the values of the next entry in the file.
43
+ each()
44
+ This loops over all entries from the current position calling the associated
45
+ block. See the example below.
46
+
47
+ Example 1
48
+ =========
49
+ require 'Vflow'
50
+ vf = Vflow.new()
51
+ vf.open('aflowfile')
52
+ vf.each() { |r|
53
+ # do something
54
+ }
55
+ vf.close()
56
+
57
+ Example 2
58
+ =========
59
+ require 'Vflow'
60
+ vf = Vflow.new()
61
+ vf.open('aflowfile') {
62
+ vf.each { |r|
63
+ #do something
64
+ }
65
+ }
66
+
67
+ To Do
68
+ =====
69
+ modify open() to take an array of filenames and automatically interate from
70
+ the end of one to the start of annother.
71
+ modify open() to take directory names and iterate over each file in the given
72
+ a directory.
73
+ add method to extract header info
74
+ add method to get flow version
75
+
76
+
77
+ Changes
78
+ =======
79
+ 0.3a
80
+ Patched Vflow.c so #open will take blocks (jeffw@globaldial.com)
81
+ Altered extconf.rb to use arbitrary paths for ft-lib (jeffw@globaldial.com)
82
+ Altered extconf.rb to give errors on missing libraries (jeffw@globaldial.com)
83
+ Altered extconf.rb to use flow-tools from path /usr/local/netflow automatically.
84
+ Created vflow.gemspec and gem file.
85
+
86
+ Thanks
87
+ ======
88
+ Thanks go to the following people,
89
+
90
+ jpietsch@amazon.com for complaining about it not working. So I know at least one other person is using
91
+ this library ;-).
92
+
93
+ jeffw@globaldial.com for his patch so #open could use blocks and altering extconf.rb to give error
94
+ messages and work with the flow-tools library and includes not being in the library path.
95
+
@@ -0,0 +1,72 @@
1
+ require 'rake/gempackagetask'
2
+ #require 'rake/contrib/rubyforgepublisher'
3
+ require 'rake/clean'
4
+ require 'rake/rdoctask'
5
+ require "benchmark"
6
+
7
+ PKG_NAME = "Vflow"
8
+ PKG_VERSION = "1.0.3"
9
+ PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
10
+ PKG_FILES = FileList[
11
+ '[A-Z]*',
12
+ 'lib/**/*.rb',
13
+ 'spec/**/*.rb',
14
+ 'tests/*.rb',
15
+ 'ext/*.c',
16
+ 'ext/*.h',
17
+ 'ext/*.rb'
18
+ ]
19
+ CLEAN.include(
20
+ "ext/*.o",
21
+ "ext/*.bundle",
22
+ "ext/*.so"
23
+ )
24
+ CLOBBER.include(
25
+ "doc/coverage"
26
+ )
27
+
28
+ task :default => [:compile]
29
+
30
+ desc 'Generate RDoc'
31
+ rd = Rake::RDocTask.new do |rdoc|
32
+ rdoc.rdoc_dir = 'doc/rdoc'
33
+ rdoc.options << '--title' << 'bcrypt-ruby' << '--line-numbers' << '--inline-source' << '--main' << 'README'
34
+ rdoc.template = ENV['TEMPLATE'] if ENV['TEMPLATE']
35
+ rdoc.rdoc_files.include('README')
36
+ end
37
+
38
+ spec = Gem::Specification.new do |s|
39
+ s.name = PKG_NAME
40
+ s.version = PKG_VERSION
41
+ s.summary = "Flowtools binding"
42
+ s.description = <<-EOF
43
+ Ruby bindings for VFlow
44
+ EOF
45
+
46
+ s.files = PKG_FILES.to_a
47
+ s.require_path = 'lib'
48
+
49
+ s.has_rdoc = true
50
+ s.rdoc_options = rd.options
51
+ s.extra_rdoc_files = rd.rdoc_files.to_a
52
+
53
+ s.extensions = FileList["ext/extconf.rb"].to_a
54
+
55
+ s.authors = ["HZ, gem packed by Antti"]
56
+ s.email = "hz@hz.com"
57
+ s.homepage = "http://rubyforge.org"
58
+ end
59
+
60
+ Rake::GemPackageTask.new(spec) do |pkg|
61
+ pkg.need_zip = true
62
+ pkg.need_tar = true
63
+ end
64
+
65
+ desc "Clean, then compile the extension."
66
+ task :compile => [:clean] do
67
+ Dir.chdir('./ext')
68
+ sh "ruby extconf.rb"
69
+ sh "make"
70
+ Dir.chdir('..')
71
+ end
72
+
@@ -0,0 +1,522 @@
1
+ /*
2
+ * $Id: Vflow.c,v 1.5 2004/12/13 11:13:18 jeffm Exp $
3
+ *
4
+ * Example script,
5
+ * vf = vflow.new()
6
+ * vf.open(afile)
7
+ * vf.find() { |r|
8
+ * # do something with entry.
9
+ * }
10
+ * vf.close()
11
+ *
12
+ *
13
+ */
14
+ #include "ruby.h"
15
+ #include <sys/types.h>
16
+ #include <fcntl.h>
17
+ #include <sys/stat.h>
18
+ #include <ftconfig.h>
19
+ #include <ftlib.h>
20
+ #include <strings.h>
21
+
22
+ typedef struct vf_data_struct {
23
+ char *current_file;
24
+ int fd;
25
+ struct ftio ftio_data;
26
+ struct ftver ftv;
27
+ struct fts3rec_offsets ftoffsets;
28
+ } vf_type;
29
+
30
+ static VALUE vf_info_free(void *p) {
31
+ xfree(((vf_type *)p)->current_file);
32
+ xfree(p);
33
+ }
34
+
35
+ /* Mapping acsii string to values.
36
+ * Should have been able to use
37
+ * struct ftxfield_table ftxfield_table[]
38
+ * from flow-tools lib/ftxfield.c but this is not
39
+ * in the same order as
40
+ * struct fts3rec_offsets
41
+ * in flow-tool's ftlib.h which make calculation
42
+ * for converstions difficult see
43
+ * vfr_init() and vfr_fts3rec_to_vfrec below
44
+ */
45
+ struct vfr_mapfields {
46
+ char *name;
47
+ u_int64 val;
48
+ VALUE (*getter)();
49
+ VALUE (*setter)();
50
+ };
51
+
52
+ // needed by libft.a
53
+ int debug = 0;
54
+
55
+ // Are these type identifiers?
56
+ VALUE vflow;
57
+ VALUE vflowrec;
58
+
59
+ /********* vflowrec ************
60
+ * vflowrec is a pure ruby object to hold
61
+ * the infomation normally held by
62
+ * struct fts3rec_all in flow-tools
63
+ */
64
+
65
+ /* private function to create a vfrec
66
+ * input:
67
+ * struct ftio
68
+ * struct fts3rec_offsets
69
+ *
70
+ * returns:
71
+ * ruby object vfrec
72
+ */
73
+
74
+ /*********** vflowrec ******/
75
+ typedef struct vfr_data_struct {
76
+ char *rec;
77
+ struct ftio ftio_data;
78
+ struct fts3rec_offsets offsets;
79
+ } vfr_type;
80
+
81
+ void vfr_copy_data(VALUE vfr_obj, char *r, struct ftio *fdata, struct fts3rec_offsets *o) {
82
+ vfr_type *info;
83
+ Data_Get_Struct(vfr_obj, vfr_type, info);
84
+ info->rec = xmalloc(fdata->rec_size);
85
+ memcpy(info->rec,r, fdata->rec_size);
86
+ memcpy(&info->ftio_data,fdata,sizeof(struct ftio));
87
+ memcpy(&info->offsets, o, sizeof(struct fts3rec_offsets));
88
+ }
89
+
90
+ static VALUE vfr_info_free(void *p) {
91
+ xfree(((vfr_type *)p)->rec);
92
+ xfree(p);
93
+ }
94
+
95
+ //initialize()
96
+ static VALUE vfr_init(VALUE rbself) {
97
+ return rbself;
98
+ }
99
+
100
+ static VALUE vfr_alloc(VALUE klass) {
101
+ vfr_type *info = xmalloc(sizeof(vfr_type));
102
+ VALUE vfr_info = Data_Wrap_Struct(klass, NULL, vfr_info_free, info);
103
+ return vfr_info;
104
+ }
105
+
106
+ // new()
107
+ static VALUE vfr_new(VALUE klass) {
108
+ VALUE obj = rb_funcall2(klass, rb_intern("allocate"), 0, 0);
109
+ rb_obj_call_init(obj, 0, NULL);
110
+ return obj;
111
+ }
112
+
113
+ #define VFR_EXTRACT8(INFO,XFIELD,NAME) Data_Get_Struct(rbself, vfr_type, INFO);\
114
+ if (!ftio_check_xfield(&INFO->ftio_data, XFIELD)) {\
115
+ return INT2NUM(*(u_int8*)(INFO->rec + (INFO->offsets).NAME));\
116
+ }\
117
+ return Qnil;\
118
+
119
+ #define VFR_EXTRACT16(INFO,XFIELD,NAME) Data_Get_Struct(rbself, vfr_type, INFO);\
120
+ if (!ftio_check_xfield(&INFO->ftio_data, XFIELD))\
121
+ return INT2NUM(*(u_int16*)(INFO->rec + (INFO->offsets).NAME));\
122
+ return Qnil;\
123
+
124
+ #define VFR_EXTRACT32(INFO,XFIELD,NAME) Data_Get_Struct(rbself, vfr_type, INFO);\
125
+ if (!ftio_check_xfield(&INFO->ftio_data, XFIELD)) {\
126
+ u_int64 tmp64 = *(u_int32*)(INFO->rec + (INFO->offsets).NAME);\
127
+ return INT2NUM(tmp64);\
128
+ }\
129
+ return Qnil;\
130
+
131
+ #define VFR_EXTRACTADDR(INFO,XFIELD,NAME) Data_Get_Struct(rbself, vfr_type, INFO);\
132
+ if (!ftio_check_xfield(&INFO->ftio_data, XFIELD)) {\
133
+ return INT2NUM(*(u_int32*)(INFO->rec + (INFO->offsets).NAME));\
134
+ }\
135
+ return Qnil;\
136
+
137
+
138
+ // vfr_unix_secs
139
+ static VALUE vfr_unix_secs(VALUE rbself) {
140
+ vfr_type *info;
141
+ VFR_EXTRACT32(info,FT_XFIELD_UNIX_SECS,unix_secs)
142
+ }
143
+
144
+ // vfr_unix_nsecs
145
+ static VALUE vfr_unix_nsecs(VALUE rbself) {
146
+ vfr_type *info;
147
+ VFR_EXTRACT32(info,FT_XFIELD_UNIX_NSECS,unix_nsecs);
148
+ }
149
+
150
+ // vfr_sysuptime
151
+ static VALUE vfr_sysuptime(VALUE rbself) {
152
+ vfr_type *info;
153
+ VFR_EXTRACT32(info,FT_XFIELD_SYSUPTIME,sysUpTime);
154
+ }
155
+
156
+ static VALUE vfr_exaddr(VALUE rbself) {
157
+ vfr_type *info;
158
+ VFR_EXTRACTADDR(info,FT_XFIELD_EXADDR,exaddr)
159
+ }
160
+
161
+ static VALUE vfr_srcaddr(VALUE rbself) {
162
+ vfr_type *info;
163
+ VFR_EXTRACTADDR(info,FT_XFIELD_SRCADDR,srcaddr)
164
+ }
165
+
166
+ static VALUE vfr_dstaddr(VALUE rbself) {
167
+ vfr_type *info;
168
+ VFR_EXTRACTADDR(info,FT_XFIELD_DSTADDR,dstaddr)
169
+ }
170
+ static VALUE vfr_nexthop(VALUE rbself) {
171
+ vfr_type *info;
172
+ VFR_EXTRACTADDR(info,FT_XFIELD_NEXTHOP,nexthop)
173
+ }
174
+
175
+ static VALUE vfr_input(VALUE rbself) {
176
+ vfr_type *info;
177
+ VFR_EXTRACT16(info, FT_XFIELD_INPUT,input)
178
+ }
179
+
180
+ static VALUE vfr_output(VALUE rbself) {
181
+ vfr_type *info;
182
+ VFR_EXTRACT16(info, FT_XFIELD_OUTPUT,output)
183
+ }
184
+
185
+ static VALUE vfr_dflows(VALUE rbself) {
186
+ vfr_type *info;
187
+ VFR_EXTRACT32(info, FT_XFIELD_DFLOWS, dFlows)
188
+ }
189
+
190
+ static VALUE vfr_dpkts(VALUE rbself) {
191
+ vfr_type *info;
192
+ VFR_EXTRACT32(info, FT_XFIELD_DPKTS, dPkts);
193
+ }
194
+
195
+ static VALUE vfr_doctets(VALUE rbself) {
196
+ vfr_type *info;
197
+ VFR_EXTRACT32(info, FT_XFIELD_DPKTS, dOctets);
198
+ }
199
+
200
+ static VALUE vfr_first(VALUE rbself) {
201
+ vfr_type *info;
202
+ VFR_EXTRACT32(info, FT_XFIELD_FIRST, First);
203
+ }
204
+
205
+ static VALUE vfr_last(VALUE rbself) {
206
+ vfr_type *info;
207
+ VFR_EXTRACT32(info, FT_XFIELD_LAST, Last);
208
+ }
209
+
210
+ static VALUE vfr_srcport(VALUE rbself) {
211
+ vfr_type *info;
212
+ VFR_EXTRACT16(info, FT_XFIELD_SRCPORT, srcport);
213
+ }
214
+
215
+ static VALUE vfr_dstport(VALUE rbself) {
216
+ vfr_type *info;
217
+ VFR_EXTRACT16(info, FT_XFIELD_DSTPORT, dstport);
218
+ }
219
+
220
+ static VALUE vfr_prot(VALUE rbself) {
221
+ vfr_type *info;
222
+ VFR_EXTRACT8(info, FT_XFIELD_PROT, prot);
223
+ }
224
+
225
+ static VALUE vfr_tos(VALUE rbself) {
226
+ vfr_type *info;
227
+ VFR_EXTRACT8(info, FT_XFIELD_TOS, tos);
228
+ }
229
+
230
+ static VALUE vfr_tcp_flags(VALUE rbself) {
231
+ vfr_type *info;
232
+ VFR_EXTRACT8(info, FT_XFIELD_TCP_FLAGS, tcp_flags);
233
+ }
234
+
235
+ static VALUE vfr_engine_type(VALUE rbself) {
236
+ vfr_type *info;
237
+ VFR_EXTRACT8(info, FT_XFIELD_ENGINE_TYPE, engine_type);
238
+ }
239
+
240
+ static VALUE vfr_engine_id(VALUE rbself) {
241
+ vfr_type *info;
242
+ VFR_EXTRACT8(info, FT_XFIELD_ENGINE_ID, engine_id);
243
+ }
244
+
245
+ static VALUE vfr_src_mask(VALUE rbself) {
246
+ vfr_type *info;
247
+ VFR_EXTRACT8(info, FT_XFIELD_SRC_MASK, src_mask);
248
+ }
249
+
250
+ static VALUE vfr_dst_mask(VALUE rbself) {
251
+ vfr_type *info;
252
+ VFR_EXTRACT8(info, FT_XFIELD_DST_MASK, dst_mask);
253
+ }
254
+
255
+ static VALUE vfr_src_as(VALUE rbself) {
256
+ vfr_type *info;
257
+ VFR_EXTRACT16(info, FT_XFIELD_SRC_AS, src_as);
258
+ }
259
+
260
+ static VALUE vfr_dst_as(VALUE rbself) {
261
+ vfr_type *info;
262
+ VFR_EXTRACT16(info, FT_XFIELD_DST_AS, dst_as);
263
+ }
264
+
265
+ static VALUE vfr_in_encaps(VALUE rbself) {
266
+ vfr_type *info;
267
+ VFR_EXTRACT8(info, FT_XFIELD_IN_ENCAPS, in_encaps);
268
+ }
269
+
270
+ static VALUE vfr_out_encaps(VALUE rbself) {
271
+ vfr_type *info;
272
+ VFR_EXTRACT8(info, FT_XFIELD_OUT_ENCAPS, out_encaps);
273
+ }
274
+
275
+ static VALUE vfr_peer_nexthop(VALUE rbself) {
276
+ vfr_type *info;
277
+ VFR_EXTRACTADDR(info, FT_XFIELD_PEER_NEXTHOP, peer_nexthop);
278
+ }
279
+
280
+ static VALUE vfr_router_sc(VALUE rbself) {
281
+ vfr_type *info;
282
+ VFR_EXTRACT32(info, FT_XFIELD_ROUTER_SC, router_sc);
283
+ }
284
+
285
+ static VALUE vfr_src_tag(VALUE rbself) {
286
+ vfr_type *info;
287
+ VFR_EXTRACT32(info, FT_XFIELD_SRC_TAG, src_tag);
288
+ }
289
+
290
+ static VALUE vfr_dst_tag(VALUE rbself) {
291
+ vfr_type *info;
292
+ VFR_EXTRACT32(info, FT_XFIELD_DST_TAG, dst_tag);
293
+ }
294
+
295
+ static VALUE vfr_extra_pkts(VALUE rbself) {
296
+ vfr_type *info;
297
+ VFR_EXTRACT32(info, FT_XFIELD_EXTRA_PKTS, extra_pkts);
298
+ }
299
+
300
+ static VALUE vfr_marked_tos(VALUE rbself) {
301
+ vfr_type *info;
302
+ VFR_EXTRACT8(info, FT_XFIELD_MARKED_TOS, marked_tos);
303
+ }
304
+
305
+ static VALUE vfr_start_time(VALUE rbself) {
306
+ vfr_type *info;
307
+
308
+ Data_Get_Struct(rbself, vfr_type, info);
309
+
310
+ if (!ftio_check_xfield(&info->ftio_data,
311
+ FT_XFIELD_SYSUPTIME |
312
+ FT_XFIELD_UNIX_SECS)) {
313
+ struct fttime ftt = ftltime(*(u_int32*)(info->rec + (info->offsets).sysUpTime),
314
+ *(u_int32*)(info->rec + (info->offsets).unix_secs),
315
+ *(u_int32*)(info->rec + (info->offsets).unix_nsecs),
316
+ *(u_int32*)(info->rec + (info->offsets).First));
317
+ return INT2NUM(ftt.secs);
318
+ }
319
+ return Qnil;
320
+ }
321
+
322
+ static VALUE vfr_end_time(VALUE rbself) {
323
+ vfr_type *info;
324
+
325
+ Data_Get_Struct(rbself, vfr_type, info);
326
+
327
+ if (!ftio_check_xfield(&info->ftio_data,
328
+ FT_XFIELD_SYSUPTIME |
329
+ FT_XFIELD_UNIX_SECS)) {
330
+ struct fttime ftt = ftltime(*(u_int32*)(info->rec + (info->offsets).sysUpTime),
331
+ *(u_int32*)(info->rec + (info->offsets).unix_secs),
332
+ *(u_int32*)(info->rec + (info->offsets).unix_nsecs),
333
+ *(u_int32*)(info->rec + (info->offsets).First));
334
+ return INT2NUM(ftt.secs);
335
+ }
336
+ return Qnil;
337
+ }
338
+
339
+
340
+ // declare methods to ruby
341
+ void Init_Vflowrec() {
342
+ vflowrec = rb_define_class("Vflowrec", rb_cObject);
343
+ #if HAVE_RB_DEFINE_ALLOC_FUNC
344
+ rb_define_alloc_func(vflowrec, vfr_alloc);
345
+ #else
346
+ rb_define_singleton_method(vflowrec, "allocate", vfr_alloc, 0);
347
+ #endif
348
+ rb_define_singleton_method(vflowrec, "new", vfr_new, 0);
349
+ rb_define_method(vflowrec, "initialize", vfr_init, 0);
350
+ rb_define_method(vflowrec, "unix_secs", vfr_unix_secs, 0);
351
+ rb_define_method(vflowrec, "unix_nsecs", vfr_unix_nsecs, 0);
352
+ rb_define_method(vflowrec, "sysuptime", vfr_sysuptime, 0);
353
+ rb_define_method(vflowrec, "exaddr", vfr_exaddr, 0);
354
+ rb_define_method(vflowrec, "srcaddr", vfr_srcaddr, 0);
355
+ rb_define_method(vflowrec, "dstaddr", vfr_dstaddr, 0);
356
+ rb_define_method(vflowrec, "nexthop", vfr_nexthop, 0);
357
+ rb_define_method(vflowrec, "input", vfr_input, 0);
358
+ rb_define_method(vflowrec, "output", vfr_output, 0);
359
+ rb_define_method(vflowrec, "dflows", vfr_dflows, 0);
360
+ rb_define_method(vflowrec, "dpkts", vfr_dpkts, 0);
361
+ rb_define_method(vflowrec, "doctets", vfr_doctets, 0);
362
+ rb_define_method(vflowrec, "first", vfr_first, 0);
363
+ rb_define_method(vflowrec, "last", vfr_last, 0);
364
+ rb_define_method(vflowrec, "srcport", vfr_srcport, 0);
365
+ rb_define_method(vflowrec, "dstport", vfr_dstport, 0);
366
+ rb_define_method(vflowrec, "prot", vfr_prot, 0);
367
+ rb_define_method(vflowrec, "tos", vfr_tos, 0);
368
+ rb_define_method(vflowrec, "tcp_flags", vfr_tcp_flags, 0);
369
+ rb_define_method(vflowrec, "engine_type", vfr_engine_type, 0);
370
+ rb_define_method(vflowrec, "engine_id", vfr_engine_id, 0);
371
+ rb_define_method(vflowrec, "src_mask", vfr_src_mask, 0);
372
+ rb_define_method(vflowrec, "dst_mask", vfr_dst_mask, 0);
373
+ rb_define_method(vflowrec, "src_as", vfr_src_as, 0);
374
+ rb_define_method(vflowrec, "dst_as", vfr_dst_as, 0);
375
+ rb_define_method(vflowrec, "in_encaps", vfr_in_encaps, 0);
376
+ rb_define_method(vflowrec, "out_encaps", vfr_out_encaps, 0);
377
+ rb_define_method(vflowrec, "peer_nexthop", vfr_peer_nexthop, 0);
378
+ rb_define_method(vflowrec, "router_sc", vfr_router_sc, 0);
379
+ rb_define_method(vflowrec, "src_tag", vfr_src_tag, 0);
380
+ rb_define_method(vflowrec, "dst_tag", vfr_dst_tag, 0);
381
+ rb_define_method(vflowrec, "extra_pkts", vfr_extra_pkts, 0);
382
+ rb_define_method(vflowrec, "marked_tos", vfr_marked_tos, 0);
383
+ rb_define_method(vflowrec, "start_time", vfr_start_time, 0);
384
+ rb_define_method(vflowrec, "end_time", vfr_end_time, 0);
385
+
386
+ }
387
+
388
+ /*********** vflow ********/
389
+ // initialize()
390
+ static VALUE vf_init(VALUE rbself) {
391
+ return rbself;
392
+ }
393
+
394
+ static VALUE vf_alloc(VALUE klass) {
395
+ VALUE vf_info;
396
+ vf_type *info = xmalloc(sizeof(vf_type));
397
+ info->current_file = NULL; /* set to sensible defaults */
398
+ vf_info = Data_Wrap_Struct(klass, NULL, vf_info_free, info);
399
+ return vf_info;
400
+ }
401
+
402
+ // new()
403
+ static VALUE vf_new(VALUE klass) {
404
+ VALUE obj = rb_funcall2(klass, rb_intern("allocate"), 0, 0);
405
+ rb_obj_call_init(obj, 0, NULL);
406
+ return obj;
407
+ }
408
+
409
+ // header() - return header of current file
410
+ static VALUE vf_header(VALUE rbself) {
411
+
412
+ }
413
+
414
+ // currentfile()
415
+ static VALUE vf_currentfile(VALUE rbself) {
416
+ vf_type *info;
417
+ Data_Get_Struct(rbself, vf_type, info);
418
+ return rb_str_new2(info->current_file);
419
+ }
420
+
421
+ // close one file
422
+ static VALUE vf_close(VALUE rbself) {
423
+ vf_type *info;
424
+
425
+ Data_Get_Struct(rbself, vf_type, info);
426
+ ftio_close(&info->ftio_data); // FIXME: should check return code
427
+ close(info->fd);
428
+ free(info->current_file);
429
+ info->fd = 0;
430
+ }
431
+
432
+ /* open(string)
433
+ * opens a single file for reading
434
+ */
435
+ static VALUE vf_open(VALUE rbself, VALUE file) {
436
+ struct stat statdata;
437
+ int fd;
438
+ vf_type *info;
439
+
440
+ Data_Get_Struct(rbself, vf_type, info);
441
+ if (rb_type(file) == T_STRING) {
442
+ info->current_file = STR2CSTR(file);
443
+
444
+ /* determine file type */
445
+ if ((fd = open(info->current_file, O_RDONLY, 0)) < 0)
446
+ rb_raise(rb_eIOError, "Cannot open file: %s", info->current_file);
447
+ info->fd = fd;
448
+ if (fstat(fd, & statdata) < 0)
449
+ rb_raise(rb_eIOError, "Cannot stat file: %s", info->current_file);
450
+
451
+ if (!S_ISREG(statdata.st_mode)) {
452
+ rb_raise(rb_eIOError, "File Type (0x%x) not handled for file %s",
453
+ statdata.st_mode, info->current_file);
454
+ }
455
+
456
+ if (ftio_init(&info->ftio_data, fd, FT_IO_FLAG_READ) < 0)
457
+ rb_raise(rb_eIOError, "ftio_init() error");
458
+
459
+ // store values needed to make calls to ftio_read and alike
460
+ ftio_get_ver(&info->ftio_data, &info->ftv);
461
+ fts3rec_compute_offsets(&info->ftoffsets, &info->ftv);
462
+
463
+ /* If we have a block, yield and close after */
464
+ if (rb_block_given_p())
465
+ return rb_ensure(rb_yield, rbself, vf_close, rbself);
466
+ else
467
+ return rbself;
468
+ }
469
+ rb_raise(rb_eTypeError,"Not a string");
470
+ }
471
+
472
+ // next() - return next entry in file
473
+ static VALUE vf_next(VALUE rbself) {
474
+ char *ent;
475
+ struct fts3rec_all cur;
476
+ vf_type *info;
477
+ VALUE vfr;
478
+
479
+ Data_Get_Struct(rbself, vf_type, info);
480
+
481
+ if ((ent = ftio_read(&info->ftio_data)) == NULL)
482
+ return Qnil;
483
+ // create flow record object
484
+ // return vfr_fts3rec_to_vfrec(ent, &info->ftio_data, &info->ftoffsets);
485
+ vfr = rb_funcall2(vflowrec,rb_intern("new"),0,0);
486
+ vfr_copy_data(vfr, ent, &info->ftio_data, &info->ftoffsets);
487
+ return vfr;
488
+ }
489
+
490
+
491
+ /* for each recoard call block
492
+ * Examples,
493
+ * each() {|flowrec| ....}
494
+ */
495
+ static VALUE vf_each(VALUE rbself) {
496
+ VALUE vfr_rec;
497
+
498
+ // debugging
499
+ //ftio_header_print(&info->ftio_data, stdout, 'f');
500
+ while ((vfr_rec = vf_next(rbself)) != Qnil) {
501
+ rb_yield(vfr_rec); // call block
502
+ }
503
+ return Qnil;
504
+ }
505
+
506
+
507
+ void Init_Vflow() {
508
+ Init_Vflowrec();
509
+ vflow = rb_define_class("Vflow", rb_cObject);
510
+ #if HAVE_RB_DEFINE_ALLOC_FUNC
511
+ rb_define_alloc_func(vflow, vf_alloc);
512
+ #else
513
+ rb_define_singleton_method(vflow, "allocate", vf_alloc, 0);
514
+ #endif
515
+ rb_define_singleton_method(vflow, "new", vf_new, 0);
516
+ rb_define_method(vflow, "initialize", vf_init, 0);
517
+ rb_define_method(vflow, "currentfile", vf_currentfile, 0);
518
+ rb_define_method(vflow, "open", vf_open, 1);
519
+ rb_define_method(vflow, "close", vf_close, 0);
520
+ rb_define_method(vflow, "next", vf_next, 0);
521
+ rb_define_method(vflow, "each", vf_each, 0);
522
+ }
@@ -0,0 +1,38 @@
1
+ require 'mkmf'
2
+
3
+ $CFLAGS="-O3 -pipe"
4
+
5
+ #default location for netflow flowtools library and includes
6
+ NETFLOW_DIR='/usr/local'
7
+
8
+ if File.directory?(NETFLOW_DIR)
9
+ dir_config("ft", "#{NETFLOW_DIR}/include/", "#{NETFLOW_DIR}/lib/")
10
+ $CFLAGS += " -I#{NETFLOW_DIR}/include/"
11
+ $LDFLAGS += " -L#{NETFLOW_DIR}/lib/"
12
+ end
13
+
14
+ # check for special include and lib dirs
15
+ incdir = with_config("ft-include-dir")
16
+ if incdir
17
+ $CFLAGS += " -I#{incdir}"
18
+ puts "Using include dir: #{incdir}"
19
+ end
20
+
21
+ libdir = with_config("ft-lib-dir")
22
+ if libdir
23
+ $LDFLAGS += " -L#{libdir}"
24
+ puts "Using lib dir: #{libdir}"
25
+ end
26
+
27
+ # check for our libraries
28
+ unless have_library("z")
29
+ puts "You must have libz!"
30
+ exit 1
31
+ end
32
+ unless have_library("ft")
33
+ puts "You must have libft!"
34
+ exit 1
35
+ end
36
+
37
+ # make the Makefile
38
+ create_makefile('Vflow')
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/ruby
2
+ #
3
+ # $Id: vfprofile.rb,v 1.1 2004/12/13 11:13:18 jeffm Exp $
4
+ #
5
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), "..","ext")
6
+ require 'Vflow'
7
+ require 'socket'
8
+ require 'profile'
9
+
10
+ TESTFILE='testdata/dummy_flow'
11
+
12
+ puts "+++ get new()"
13
+ x = Vflow.new()
14
+
15
+ puts "+++ open a file"
16
+ x.open(TESTFILE) do
17
+
18
+ puts "+++ each"
19
+ count = 0
20
+ total_pkts, total_flows, total_octets = 0,0,0
21
+ x.each() {|r|
22
+ count += 1
23
+ # do some realistic-ish calculations
24
+ r.dpkts and total_pkts += r.dpkts
25
+ r.dflows and total_flows += r.dflows
26
+ r.doctets and total_octets += r.doctets
27
+ }
28
+
29
+ puts "pkts: #{total_pkts} flows: #{total_flows} octets: #{total_octets}"
30
+ end
31
+
32
+ puts "=== End of Tests ===";
@@ -0,0 +1,73 @@
1
+ #!/usr/bin/ruby
2
+ #
3
+ # $Id: vftest.rb,v 1.6 2004/12/13 11:13:18 jeffm Exp $
4
+ #
5
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), "..","ext")
6
+ require 'Vflow'
7
+ require 'socket'
8
+
9
+ TESTFILE='testdata/dummy_flow'
10
+
11
+ def dumpvflowrec(r)
12
+ puts "=============="
13
+ puts "have #{r.class}"
14
+ puts "start_time: #{Time.at(r.start_time)} end_time: #{Time.at(r.end_time)}"
15
+ puts "unix_secs #{Time.at(r.unix_secs)} unix_nsecs #{r.unix_nsecs}"
16
+ puts "sysuptime #{r.sysuptime}"
17
+ puts "exaddr #{IPSocket.getaddress(r.exaddr)}"
18
+ print "srcaddr #{IPSocket.getaddress(r.srcaddr)} -> "
19
+ puts "dstaddr #{IPSocket.getaddress(r.dstaddr)}"
20
+ puts "nexthop #{IPSocket.getaddress(r.nexthop)}"
21
+ puts "input #{r.input} output #{r.output}"
22
+ puts "dflows #{r.dflows}"
23
+ puts "dpkts #{r.dpkts} doctets #{r.doctets}"
24
+ puts "first #{r.first} last #{r.last}"
25
+ puts "srcport #{r.srcport} dstport #{r.dstport}"
26
+ puts "prot #{r.prot} tos #{r.tos}"
27
+ puts "engine_type #{r.engine_type} engine_id #{r.engine_id}"
28
+ puts "src_mask #{r.src_mask} dst_mask #{r.dst_mask}"
29
+ puts "src_as #{r.src_as} dst_as #{r.dst_as}"
30
+ puts "in_encaps #{r.in_encaps}"
31
+ puts "out_encaps #{r.out_encaps}"
32
+ if r.peer_nexthop then
33
+ puts "peer_nexthop #{IPSocket.getaddress(r.peer_nexthop)}"
34
+ else
35
+ puts "peer_nexthop nil"
36
+ end
37
+ puts "router_sc #{r.router_sc}"
38
+ puts "src_tag #{r.src_tag} dst_tag #{r.dst_tag}"
39
+ puts "extra_pkts #{r.extra_pkts} marked_tos #{r.marked_tos}"
40
+ end
41
+
42
+ puts "+++ get new()"
43
+ x = Vflow.new()
44
+
45
+ puts "+++ open a file"
46
+ x.open(TESTFILE)
47
+
48
+ puts "+++ currentfile"
49
+ puts x.currentfile()
50
+
51
+ puts "+++ next"
52
+ dumpvflowrec(x.next)
53
+ puts "+++ next (again)"
54
+ dumpvflowrec(x.next)
55
+
56
+ puts "+++ each"
57
+ count = 0
58
+ x.each() {|r|
59
+ dumpvflowrec(r)
60
+ count += 1
61
+ puts count
62
+ }
63
+
64
+ puts "+++ close a file"
65
+ x.close()
66
+
67
+ print "---- bad call to open "
68
+ begin
69
+ x.open(1)
70
+ rescue TypeError => detail
71
+ puts "received expected error(TypeError) good"
72
+ end
73
+ puts "=== End of Tests ===";
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: Vflow
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.3
5
+ platform: ruby
6
+ authors:
7
+ - HZ, gem packed by Antti
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-02-11 00:00:00 +02:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Ruby bindings for VFlow
17
+ email: hz@hz.com
18
+ executables: []
19
+
20
+ extensions:
21
+ - ext/extconf.rb
22
+ extra_rdoc_files:
23
+ - README
24
+ files:
25
+ - Rakefile
26
+ - README
27
+ - tests/vftest.rb
28
+ - tests/vfprofile.rb
29
+ - ext/Vflow.c
30
+ - ext/extconf.rb
31
+ has_rdoc: true
32
+ homepage: http://rubyforge.org
33
+ post_install_message:
34
+ rdoc_options:
35
+ - --title
36
+ - bcrypt-ruby
37
+ - --line-numbers
38
+ - --inline-source
39
+ - --main
40
+ - README
41
+ require_paths:
42
+ - lib
43
+ required_ruby_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: "0"
48
+ version:
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: "0"
54
+ version:
55
+ requirements: []
56
+
57
+ rubyforge_project:
58
+ rubygems_version: 1.3.1
59
+ signing_key:
60
+ specification_version: 2
61
+ summary: Flowtools binding
62
+ test_files: []
63
+