rb-pcap 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,10 @@
1
+ rb-pcap
2
+ =======
3
+
4
+ A simple ruby wrapper for the pcap library.
5
+
6
+ Compiling
7
+ ---------
8
+
9
+ ruby extconf.rb
10
+ make
@@ -0,0 +1,6 @@
1
+ require 'mkmf'
2
+
3
+ dir_config('pcap')
4
+ fail "Couldn't find libpcap." unless have_library("pcap", "pcap_open_live", "pcap.h")
5
+
6
+ create_makefile("rb_pcap")
@@ -0,0 +1,29 @@
1
+ #include "rb_pcap.h"
2
+
3
+ void Init_rb_pcap() {
4
+ cCapture = rb_define_class("Capture", rb_cObject);
5
+ rb_include_module(cCapture, rb_mEnumerable);
6
+ rb_define_singleton_method(cCapture, "open", capture_open, -1);
7
+ rb_define_singleton_method(cCapture, "open_offline", capture_open_offline, 1);
8
+ rb_define_method(cCapture, "close", capture_close, 0);
9
+ rb_define_method(cCapture, "dispatch", capture_dispatch, -1);
10
+ rb_define_method(cCapture, "each", capture_loop, -1);
11
+ rb_define_method(cCapture, "each_packet", capture_loop, -1);
12
+ rb_define_method(cCapture, "filter=", capture_setfilter, 1);
13
+ rb_define_method(cCapture, "limit", capture_getlimit, 0);
14
+ rb_define_method(cCapture, "limit=", capture_setlimit, 1);
15
+ rb_define_method(cCapture, "dissector", capture_getdissector, 0);
16
+ rb_define_method(cCapture, "dissector=", capture_setdissector, 0);
17
+ rb_define_method(cCapture, "datalink", capture_datalink, 0);
18
+ rb_define_method(cCapture, "snapshot_length", capture_snapshot, 0);
19
+
20
+ cFilter = rb_define_class_under(cCapture, "Filter", rb_cObject);
21
+ rb_define_alloc_func(cFilter, filter_alloc);
22
+ rb_define_method(cFilter, "initialize", filter_init, -1);
23
+ rb_define_method(cFilter, "expression", filter_source, 0);
24
+ rb_define_method(cFilter, "=~", filter_match, 1);
25
+ rb_define_method(cFilter, "===", filter_match, 1);
26
+
27
+ eCaptureError = rb_define_class_under(cCapture, "CaptureError", rb_eStandardError);
28
+ eTruncatedPacket = rb_define_class_under(cCapture, "TruncatedPacket", eCaptureError);
29
+ }
@@ -0,0 +1,12 @@
1
+ #ifndef __RB_PCAP_H__
2
+ #define __RB_PCAP_H__
3
+
4
+ #include "rb_pcap_capture.h"
5
+ #include "rb_pcap_filter.h"
6
+
7
+ VALUE cCapture;
8
+ VALUE cFilter;
9
+ VALUE eCaptureError;
10
+ VALUE eTruncatedPacket;
11
+
12
+ #endif
@@ -0,0 +1,365 @@
1
+ #include "rb_pcap_capture.h"
2
+
3
+ void closed_capture()
4
+ {
5
+ rb_raise(rb_eRuntimeError, "device is already closed");
6
+ }
7
+
8
+ void free_capture(struct capture_object *cap)
9
+ {
10
+ if (cap->pcap != NULL) {
11
+ rb_thread_fd_close(pcap_fileno(cap->pcap));
12
+ pcap_close(cap->pcap);
13
+ cap->pcap = NULL;
14
+ }
15
+
16
+ free(cap);
17
+ }
18
+
19
+ VALUE capture_close(VALUE self)
20
+ {
21
+ struct capture_object *cap;
22
+
23
+ GetCapture(self, cap);
24
+
25
+ if (cap->dumper) {
26
+ pcap_dump_close(cap->dumper);
27
+ }
28
+
29
+ rb_thread_fd_close(pcap_fileno(cap->pcap));
30
+ pcap_close(cap->pcap);
31
+ cap->pcap = NULL;
32
+ return Qnil;
33
+ }
34
+
35
+ VALUE capture_setfilter(VALUE self, VALUE v_filter)
36
+ {
37
+ struct capture_object *cap;
38
+ struct bpf_program program;
39
+
40
+ GetCapture(self, cap);
41
+
42
+ if (IsKindOf(v_filter, cFilter)) {
43
+ struct filter_object *f;
44
+ GetFilter(v_filter, f);
45
+ program = f->program;
46
+ } else {
47
+ Check_Type(v_filter, T_STRING);
48
+ char *filter = RSTRING(v_filter)->ptr;
49
+
50
+ if (pcap_compile(cap->pcap, &program, filter, 1, cap->netmask) < 0) {
51
+ rb_raise(eCaptureError, "setfilter: %s", pcap_geterr(cap->pcap));
52
+ }
53
+ }
54
+
55
+ if (pcap_setfilter(cap->pcap, &program) < 0) {
56
+ rb_raise(eCaptureError, "setfilter: %s", pcap_geterr(cap->pcap));
57
+ }
58
+
59
+ return v_filter;
60
+ }
61
+
62
+
63
+ VALUE capture_setdissector(VALUE self, VALUE dissector)
64
+ {
65
+ if (!(IsKindOf(dissector, rb_cProc) || dissector == Qnil)) {
66
+ rb_raise(rb_eArgError, "dissector must be proc or nil");
67
+ }
68
+
69
+ struct capture_object *cap;
70
+ GetCapture(self, cap);
71
+
72
+ cap->dissector = dissector;
73
+
74
+ return dissector;
75
+ }
76
+
77
+ VALUE capture_open(int argc, VALUE *argv, VALUE class)
78
+ {
79
+ VALUE v_device, v_snaplen = Qnil, v_promisc = Qnil, v_to_ms = Qnil, v_filter = Qnil, v_limit = Qnil, v_dissector = Qnil, v_dump = Qnil;
80
+ char *device;
81
+ char *dump;
82
+ int snaplen, promisc, to_ms;
83
+ int rs;
84
+ VALUE self;
85
+ struct capture_object *cap;
86
+ pcap_t *pcap;
87
+ bpf_u_int32 net, netmask;
88
+
89
+ rs = rb_scan_args(argc, argv, "13", &v_device, &v_snaplen,&v_promisc, &v_to_ms);
90
+
91
+ if (IsKindOf(v_device, rb_cHash)) {
92
+ v_snaplen = rb_funcall(v_device, rb_intern("[]"), 1, ID2SYM(rb_intern("snapshot_length")));
93
+ v_to_ms = rb_funcall(v_device, rb_intern("[]"), 1, ID2SYM(rb_intern("timeout")));
94
+ v_promisc = rb_funcall(v_device, rb_intern("[]"), 1, ID2SYM(rb_intern("promiscuous")));
95
+ v_limit = rb_funcall(v_device, rb_intern("[]"), 1, ID2SYM(rb_intern("limit")));
96
+ v_filter = rb_funcall(v_device, rb_intern("[]"), 1, ID2SYM(rb_intern("filter")));
97
+ v_dissector = rb_funcall(v_device, rb_intern("[]"), 1, ID2SYM(rb_intern("dissector")));
98
+ v_dump = rb_funcall(v_device, rb_intern("[]"), 1, ID2SYM(rb_intern("dump")));
99
+ v_device = rb_funcall(v_device, rb_intern("[]"), 1, ID2SYM(rb_intern("device")));
100
+
101
+ if (v_device == Qnil) {
102
+ rb_raise(rb_eArgError, ":device must be specified");
103
+ }
104
+ }
105
+
106
+ Check_SafeStr(v_device);
107
+ device = RSTRING(v_device)->ptr;
108
+
109
+ if (v_snaplen != Qnil) {
110
+ Check_Type(v_snaplen, T_FIXNUM);
111
+ snaplen = FIX2INT(v_snaplen);
112
+ } else {
113
+ snaplen = DEFAULT_SNAPLEN;
114
+ }
115
+
116
+ if (snaplen < 0) {
117
+ rb_raise(rb_eArgError, "invalid snaplen");
118
+ }
119
+
120
+ if (v_promisc != Qnil) {
121
+ promisc = RTEST(v_promisc);
122
+ } else {
123
+ promisc = DEFAULT_PROMISC;
124
+ }
125
+
126
+ if (v_to_ms != Qnil) {
127
+ Check_Type(v_to_ms, T_FIXNUM);
128
+ to_ms = FIX2INT(v_to_ms);
129
+ } else {
130
+ to_ms = DEFAULT_TO_MS;
131
+ }
132
+
133
+ char pcap_errbuf[PCAP_ERRBUF_SIZE];
134
+
135
+ pcap = pcap_open_live(device, snaplen, promisc, to_ms, pcap_errbuf);
136
+
137
+ if (pcap == NULL) {
138
+ rb_raise(eCaptureError, "%s", pcap_errbuf);
139
+ }
140
+
141
+ if (pcap_lookupnet(device, &net, &netmask, pcap_errbuf) == -1) {
142
+ netmask = 0;
143
+ rb_warning("cannot lookup net: %s\n", pcap_errbuf);
144
+ }
145
+
146
+ self = Data_Make_Struct(class, struct capture_object, 0, free_capture, cap);
147
+ cap->pcap = pcap;
148
+ cap->netmask = netmask;
149
+ cap->dl_type = pcap_datalink(pcap);
150
+ capture_setdissector(self, v_dissector);
151
+
152
+ if (v_dump != Qnil) {
153
+ Check_Type(v_dump, T_STRING);
154
+ cap->dumper = pcap_dump_open(cap->pcap, RSTRING(v_dump)->ptr);
155
+ } else {
156
+ cap->dumper = NULL;
157
+ }
158
+
159
+ if (v_limit != Qnil) {
160
+ Check_Type(v_limit, T_FIXNUM);
161
+ cap->limit = FIX2INT(v_limit);
162
+ } else {
163
+ cap->limit = -1;
164
+ }
165
+
166
+ if (v_filter != Qnil) {
167
+ capture_setfilter(self, v_filter);
168
+ }
169
+
170
+ if (rb_block_given_p()) {
171
+ rb_yield(self);
172
+ capture_close(self);
173
+ return Qnil;
174
+ } else
175
+ return self;
176
+ }
177
+
178
+ VALUE capture_open_offline(VALUE class, VALUE fname)
179
+ {
180
+ VALUE self;
181
+ struct capture_object *cap;
182
+ pcap_t *pcap;
183
+
184
+ /* open offline */
185
+ Check_SafeStr(fname);
186
+ char pcap_errbuf[PCAP_ERRBUF_SIZE];
187
+ pcap = pcap_open_offline(RSTRING(fname)->ptr, pcap_errbuf);
188
+ if (pcap == NULL) {
189
+ rb_raise(eCaptureError, "%s", pcap_errbuf);
190
+ }
191
+
192
+ /* setup instance */
193
+ self = Data_Make_Struct(class, struct capture_object, 0, free_capture, cap);
194
+ cap->pcap = pcap;
195
+ cap->netmask = 0;
196
+ cap->dl_type = pcap_datalink(pcap);
197
+
198
+ return self;
199
+ }
200
+
201
+ void handler1(struct capture_object *cap, const struct pcap_pkthdr *pkthdr, const u_char *data)
202
+ {
203
+ if (cap->dissector != Qnil) {
204
+ VALUE dissected = rb_funcall(cap->dissector, rb_intern("call"), 1, rb_str_new((char *)data, pkthdr->caplen));
205
+
206
+ rb_yield_values(1, dissected); // not sure why rb_yield doesn't work here, but it wasn't for me
207
+ } else
208
+ rb_yield_values(1, rb_str_new((char *)data, pkthdr->caplen));
209
+ }
210
+
211
+
212
+ void handler2(struct capture_object *cap, const struct pcap_pkthdr *pkthdr, const u_char *data)
213
+ {
214
+ if (cap->dissector != Qnil) {
215
+ VALUE dissected = rb_funcall(cap->dissector, rb_intern("call"), 1, rb_str_new((char *)data, pkthdr->caplen));
216
+
217
+ rb_yield_values(2, dissected, rb_time_new(pkthdr->ts.tv_sec, pkthdr->ts.tv_usec));
218
+ } else
219
+ rb_yield_values(2, rb_str_new((char *)data, pkthdr->caplen), rb_time_new(pkthdr->ts.tv_sec, pkthdr->ts.tv_usec));
220
+ }
221
+
222
+ VALUE capture_dispatch(int argc, VALUE *argv, VALUE self)
223
+ {
224
+ VALUE v_cnt;
225
+ int cnt;
226
+ struct capture_object *cap;
227
+ int ret;
228
+
229
+ GetCapture(self, cap);
230
+
231
+ if (cap->dumper == NULL) {
232
+ rb_raise(rb_eRuntimeError, "No dump file specified, use each to retrieve packets.");
233
+ }
234
+
235
+ /*VALUE proc = rb_block_proc();
236
+ VALUE v_arity = rb_funcall(proc, rb_intern("arity"), 0);
237
+
238
+ int arity = FIX2INT(v_arity);
239
+
240
+ pcap_handler handler = (arity < 2) ? (pcap_handler)handler1 : (pcap_handler)handler2;
241
+ */
242
+
243
+ /* scan arg */
244
+ if (rb_scan_args(argc, argv, "01", &v_cnt) >= 1) {
245
+ FIXNUM_P(v_cnt);
246
+ cnt = FIX2INT(v_cnt);
247
+ } else {
248
+ cnt = -1;
249
+ }
250
+
251
+ TRAP_BEG;
252
+ ret = pcap_dispatch(cap->pcap, cnt, pcap_dump, (u_char *)cap->dumper);
253
+ TRAP_END;
254
+
255
+ if (ret == -1)
256
+ rb_raise(eCaptureError, "dispatch: %s", pcap_geterr(cap->pcap));
257
+
258
+ return INT2FIX(ret);
259
+ }
260
+
261
+ VALUE capture_loop(int argc, VALUE *argv, VALUE self)
262
+ {
263
+ VALUE v_cnt;
264
+ int cnt;
265
+ struct capture_object *cap;
266
+ int ret;
267
+
268
+ GetCapture(self, cap);
269
+
270
+ VALUE proc = rb_block_proc();
271
+ VALUE v_arity = rb_funcall(proc, rb_intern("arity"), 0);
272
+
273
+ int arity = FIX2INT(v_arity);
274
+
275
+ pcap_handler handler = (arity < 2) ? (pcap_handler)handler1 : (pcap_handler)handler2;
276
+
277
+ /* scan arg */
278
+ if (rb_scan_args(argc, argv, "01", &v_cnt) >= 1) {
279
+ FIXNUM_P(v_cnt);
280
+ cnt = FIX2INT(v_cnt);
281
+ } else
282
+ cnt = cap->limit;
283
+
284
+ if (pcap_file(cap->pcap) != NULL) {
285
+ TRAP_BEG;
286
+ ret = pcap_loop(cap->pcap, cnt, handler, (u_char *)cap);
287
+ TRAP_END;
288
+ } else {
289
+ int fd = pcap_fileno(cap->pcap);
290
+ fd_set rset;
291
+ struct timeval tm;
292
+
293
+ FD_ZERO(&rset);
294
+ tm.tv_sec = 0;
295
+ tm.tv_usec = 0;
296
+ for (;;) {
297
+ do {
298
+ FD_SET(fd, &rset);
299
+ if (select(fd+1, &rset, NULL, NULL, &tm) == 0) {
300
+ rb_thread_wait_fd(fd);
301
+ }
302
+ TRAP_BEG;
303
+ ret = pcap_read(cap->pcap, 1, handler, (u_char *)cap);
304
+ TRAP_END;
305
+ } while (ret == 0);
306
+ if (ret <= 0)
307
+ break;
308
+ if (cnt > 0) {
309
+ cnt -= ret;
310
+ if (cnt <= 0)
311
+ break;
312
+ }
313
+ }
314
+ }
315
+
316
+ return INT2FIX(ret);
317
+ }
318
+
319
+ VALUE capture_datalink(VALUE self)
320
+ {
321
+ struct capture_object *cap;
322
+
323
+ GetCapture(self, cap);
324
+
325
+ return INT2NUM(pcap_datalink(cap->pcap));
326
+ }
327
+
328
+ VALUE capture_snapshot(VALUE self)
329
+ {
330
+ struct capture_object *cap;
331
+
332
+ GetCapture(self, cap);
333
+
334
+ return INT2NUM(pcap_snapshot(cap->pcap));
335
+ }
336
+
337
+ VALUE capture_getlimit(VALUE self)
338
+ {
339
+ struct capture_object *cap;
340
+ GetCapture(self, cap);
341
+
342
+ return INT2FIX(cap->limit);
343
+ }
344
+
345
+
346
+ VALUE capture_setlimit(VALUE self, VALUE limit)
347
+ {
348
+ Check_Type(limit, T_FIXNUM);
349
+
350
+ struct capture_object *cap;
351
+ GetCapture(self, cap);
352
+
353
+ cap->limit = FIX2INT(limit);
354
+
355
+ return limit;
356
+ }
357
+
358
+ VALUE capture_getdissector(VALUE self)
359
+ {
360
+ struct capture_object *cap;
361
+ GetCapture(self, cap);
362
+
363
+ return cap->dissector;
364
+ }
365
+
@@ -0,0 +1,53 @@
1
+ #ifndef __RB_PCAP_CAPTURE_H__
2
+ #define __RB_PCAP_CAPTURE_H__
3
+
4
+ #include <ruby.h>
5
+ #include <rubysig.h>
6
+ #include <pcap.h>
7
+
8
+ #include "rb_pcap_filter.h"
9
+
10
+ #define DEFAULT_DATALINK DLT_EN10MB
11
+ #define DEFAULT_SNAPLEN 256
12
+ #define DEFAULT_PROMISC 1
13
+ #define DEFAULT_TO_MS 1000
14
+
15
+ extern VALUE eCaptureError;
16
+ extern VALUE eTruncatedPacket;
17
+ extern VALUE cCapture;
18
+
19
+ struct capture_object {
20
+ pcap_t *pcap;
21
+ pcap_dumper_t *dumper;
22
+ int limit;
23
+ bpf_u_int32 netmask;
24
+ int dl_type;
25
+ VALUE dissector;
26
+ };
27
+
28
+ #define GetFilter(obj, filter) Data_Get_Struct(obj, struct filter_object, filter)
29
+ #define GetPacket(obj, pkt) Data_Get_Struct(obj, struct packet_object, pkt)
30
+ #define GetCapture(obj, cap) { Data_Get_Struct(obj, struct capture_object, cap); if (cap->pcap == NULL) closed_capture(); }
31
+ #define Caplen(pkt, from) ((pkt)->hdr.pkthdr.caplen - (from))
32
+ #define CheckTruncate(pkt, from, need, emsg) ((from) + (need) > (pkt)->hdr.pkthdr.caplen ? rb_raise(eTruncatedPacket, (emsg)) : 0)
33
+ #define IsKindOf(v, class) RTEST(rb_obj_is_kind_of(v, class))
34
+ #define CheckClass(v, class) ((IsKindOf(v, class)) ? 0 : rb_raise(rb_eTypeError, "wrong type %s (expected %s)", rb_class2name(CLASS_OF(v)), rb_class2name(class)))
35
+
36
+ void closed_capture();
37
+ void free_capture(struct capture_object *cap);
38
+ VALUE capture_close(VALUE self);
39
+ VALUE capture_setfilter(VALUE self, VALUE v_filter);
40
+ VALUE capture_setdissector(VALUE self, VALUE dissector);
41
+ VALUE capture_open(int argc, VALUE *argv, VALUE class);
42
+ VALUE capture_open_offline(VALUE class, VALUE fname);
43
+ void handler1(struct capture_object *cap, const struct pcap_pkthdr *pkthdr, const u_char *data);
44
+ void handler2(struct capture_object *cap, const struct pcap_pkthdr *pkthdr, const u_char *data);
45
+ VALUE capture_dispatch(int argc, VALUE *argv, VALUE self);
46
+ VALUE capture_loop(int argc, VALUE *argv, VALUE self);
47
+ VALUE capture_datalink(VALUE self);
48
+ VALUE capture_snapshot(VALUE self);
49
+ VALUE capture_getlimit(VALUE self);
50
+ VALUE capture_setlimit(VALUE self, VALUE limit);
51
+ VALUE capture_getdissector(VALUE self);
52
+
53
+ #endif
@@ -0,0 +1,85 @@
1
+ #include "rb_pcap_filter.h"
2
+
3
+ void free_filter(struct filter_object *filter)
4
+ {
5
+ free(filter->expr);
6
+ free(filter);
7
+ }
8
+
9
+ VALUE filter_alloc(VALUE self)
10
+ {
11
+ struct filter_object *filter = (struct filter_object *)xmalloc(sizeof(struct filter_object));
12
+
13
+ filter->expr = NULL;
14
+
15
+ return Data_Wrap_Struct(self, NULL, free_filter, filter);
16
+ }
17
+
18
+ VALUE filter_init(int argc, VALUE* argv, VALUE self)
19
+ {
20
+ VALUE v_expr, v_optimize, v_netmask;
21
+ struct filter_object *filter;
22
+ char *expr;
23
+ int n, optimize, snaplen, linktype;
24
+ bpf_u_int32 netmask;
25
+
26
+ n = rb_scan_args(argc, argv, "12", &v_expr, &v_optimize, &v_netmask);
27
+
28
+ /* filter expression */
29
+ Check_Type(v_expr, T_STRING);
30
+ expr = STR2CSTR(v_expr);
31
+
32
+ snaplen = DEFAULT_SNAPLEN;
33
+ linktype = DEFAULT_DATALINK;
34
+
35
+ /* optimize flag */
36
+ optimize = 1;
37
+ if (n >= 3) {
38
+ optimize = RTEST(v_optimize);
39
+ }
40
+ /* netmask */
41
+ netmask = 0;
42
+ if (n >= 4) {
43
+ bpf_u_int32 mask = NUM2UINT(v_netmask);
44
+ netmask = htonl(mask);
45
+ }
46
+
47
+ GetFilter(self, filter);
48
+
49
+ if (pcap_compile_nopcap(snaplen, linktype, &filter->program, expr, optimize, netmask) == -1) {
50
+ rb_raise(eCaptureError, "pcap_compile_nopcap error");
51
+ }
52
+
53
+ filter->datalink = linktype;
54
+ filter->snaplen = snaplen;
55
+ filter->expr = strdup(expr);
56
+ filter->optimize = optimize ? Qtrue : Qfalse;
57
+ filter->netmask = INT2NUM(ntohl(netmask));
58
+
59
+ return self;
60
+ }
61
+
62
+ VALUE filter_source(VALUE self)
63
+ {
64
+ struct filter_object *filter;
65
+
66
+ GetFilter(self, filter);
67
+ return rb_str_new2(filter->expr);
68
+ }
69
+
70
+
71
+ VALUE filter_match(VALUE self, VALUE v_pkt)
72
+ {
73
+ struct filter_object *filter;
74
+ struct packet_object *pkt;
75
+
76
+ GetFilter(self, filter);
77
+
78
+ int v_pkt_len = RSTRING(v_pkt)->len;
79
+
80
+ if (bpf_filter(filter->program.bf_insns, (unsigned char *)StringValuePtr(v_pkt), v_pkt_len, v_pkt_len)) {
81
+ return Qtrue;
82
+ }
83
+
84
+ return Qfalse;
85
+ }
@@ -0,0 +1,28 @@
1
+ #ifndef __RB_PCAP_FILTER_H__
2
+ #define __RB_PCAP_FILTER_H__
3
+
4
+ #include <ruby.h>
5
+ #include <rubysig.h>
6
+ #include <pcap.h>
7
+
8
+ #include "rb_pcap_capture.h"
9
+
10
+ struct filter_object {
11
+ char *expr;
12
+ struct bpf_program program;
13
+ int datalink;
14
+ int snaplen;
15
+ VALUE optimize;
16
+ VALUE netmask;
17
+ };
18
+
19
+ extern VALUE cFilter;
20
+
21
+ void mark_filter(struct filter_object *filter);
22
+ void free_filter(struct filter_object *filter);
23
+ VALUE filter_alloc(VALUE self);
24
+ VALUE filter_init(int argc, VALUE *argv, VALUE class);
25
+ VALUE filter_source(VALUE self);
26
+ VALUE filter_match(VALUE self, VALUE v_pkt);
27
+
28
+ #endif
@@ -0,0 +1 @@
1
+ require 'rb_pcap'
metadata ADDED
@@ -0,0 +1,64 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rb-pcap
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Cory T. Cornelius
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-08-02 00:00:00 -04:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: See README.markdown for more information.
17
+ email:
18
+ - cory.t.cornelius@dartmouth.edu
19
+ executables: []
20
+
21
+ extensions:
22
+ - ext/extconf.rb
23
+ extra_rdoc_files: []
24
+
25
+ files:
26
+ - README.markdown
27
+ - lib/rb-pcap.rb
28
+ - ext/extconf.rb
29
+ - ext/rb_pcap_capture.c
30
+ - ext/rb_pcap_capture.h
31
+ - ext/rb_pcap_filter.c
32
+ - ext/rb_pcap_filter.h
33
+ - ext/rb_pcap.c
34
+ - ext/rb_pcap.h
35
+ has_rdoc: true
36
+ homepage: http://github.com/dxoigmn/rb-pcap
37
+ licenses: []
38
+
39
+ post_install_message:
40
+ rdoc_options: []
41
+
42
+ require_paths:
43
+ - lib
44
+ required_ruby_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: "0"
49
+ version:
50
+ required_rubygems_version: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: "0"
55
+ version:
56
+ requirements: []
57
+
58
+ rubyforge_project:
59
+ rubygems_version: 1.3.5
60
+ signing_key:
61
+ specification_version: 3
62
+ summary: Simple libpcap wrapper.
63
+ test_files: []
64
+