ruby-ipqueue 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +26 -0
- data/ext/ipqueue/extconf.rb +7 -0
- data/ext/ipqueue/ipqueue.c +208 -0
- data/lib/ipqueuepacket.rb +36 -0
- data/test/test.rb +13 -0
- data/test/test.sh +5 -0
- metadata +56 -0
data/Rakefile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'rake/packagetask'
|
3
|
+
require 'rake/gempackagetask'
|
4
|
+
|
5
|
+
PKG_VERSION = "0.1.3"
|
6
|
+
|
7
|
+
desc "Create gem"
|
8
|
+
spec = Gem::Specification.new do |s|
|
9
|
+
s.email = 'nullguid@gmail.com'
|
10
|
+
s.extensions = 'ext/ipqueue/extconf.rb'
|
11
|
+
s.homepage = 'http://ruby-ipqueue.rubyforge.org/'
|
12
|
+
s.name = 'ruby-ipqueue'
|
13
|
+
s.require_paths << 'ext'
|
14
|
+
s.requirements << 'libipq'
|
15
|
+
s.rubyforge_project = 'ruby-ipqueue'
|
16
|
+
s.summary = 'Rubyish interface to libipq'
|
17
|
+
s.description = 'Ruby-ipqueue provides ruby-way object-oriented interface to linux libipq packet mangling library'
|
18
|
+
s.version = PKG_VERSION
|
19
|
+
s.files = FileList['**/*'].to_a.select{|v| v !~ /pkg|CVS/}
|
20
|
+
end
|
21
|
+
|
22
|
+
Rake::GemPackageTask.new(spec) do |p|
|
23
|
+
p.gem_spec = spec
|
24
|
+
p.need_tar_gz = false
|
25
|
+
p.need_zip = false
|
26
|
+
end
|
@@ -0,0 +1,208 @@
|
|
1
|
+
#include <ruby.h>
|
2
|
+
#include <libipq/libipq.h>
|
3
|
+
#include <linux/netfilter.h>
|
4
|
+
|
5
|
+
/* FIXME - I don't know how to handle this */
|
6
|
+
#define IPQ_MESSAGE_OVERHEAD 256
|
7
|
+
|
8
|
+
static VALUE cIPQueue, cIPQueuePacket, eTimeout;
|
9
|
+
|
10
|
+
struct ipqueue_object
|
11
|
+
{
|
12
|
+
struct ipq_handle *handle;
|
13
|
+
size_t range;
|
14
|
+
unsigned char *buf;
|
15
|
+
size_t len;
|
16
|
+
};
|
17
|
+
|
18
|
+
static void fipq_destroy_ipqueue(struct ipqueue_object *ipqueue)
|
19
|
+
{
|
20
|
+
if(ipq_destroy_handle(ipqueue->handle) == -1)
|
21
|
+
rb_raise(rb_eRuntimeError, "%s: %s", ipq_errstr(), strerror(errno));
|
22
|
+
xfree(ipqueue->buf);
|
23
|
+
xfree(ipqueue);
|
24
|
+
}
|
25
|
+
|
26
|
+
static VALUE fipq_create_handle(klass, flags, protocol)
|
27
|
+
VALUE klass, flags, protocol;
|
28
|
+
{
|
29
|
+
VALUE obj;
|
30
|
+
struct ipq_handle *handle;
|
31
|
+
struct ipqueue_object *ipqueue;
|
32
|
+
|
33
|
+
handle = ipq_create_handle(NUM2INT(flags), NUM2INT(protocol));
|
34
|
+
|
35
|
+
if(!handle) {
|
36
|
+
rb_raise(rb_eRuntimeError, "%s: %s", ipq_errstr(), strerror(errno));
|
37
|
+
}
|
38
|
+
|
39
|
+
obj = Data_Make_Struct(klass, struct ipqueue_object, 0, fipq_destroy_ipqueue, ipqueue);
|
40
|
+
|
41
|
+
/* set default to copy only metainformation */
|
42
|
+
ipq_set_mode(handle, IPQ_COPY_META, 0);
|
43
|
+
|
44
|
+
ipqueue->handle = handle;
|
45
|
+
ipqueue->range = 0;
|
46
|
+
ipqueue->len = IPQ_MESSAGE_OVERHEAD;
|
47
|
+
ipqueue->buf = ALLOC_N(unsigned char, IPQ_MESSAGE_OVERHEAD);
|
48
|
+
|
49
|
+
return obj;
|
50
|
+
}
|
51
|
+
|
52
|
+
/* Assume IPQ_COPY_META when range is zero */
|
53
|
+
static VALUE fipq_set_range(obj, range)
|
54
|
+
VALUE obj, range;
|
55
|
+
{
|
56
|
+
struct ipqueue_object *ipqueue;
|
57
|
+
|
58
|
+
size_t c_range = NUM2INT(range);
|
59
|
+
|
60
|
+
if(c_range > 65535) {
|
61
|
+
rb_raise(rb_eArgError, "invalid range '%d', should be between 0 and 65535", c_range);
|
62
|
+
}
|
63
|
+
|
64
|
+
Data_Get_Struct(obj, struct ipqueue_object, ipqueue);
|
65
|
+
|
66
|
+
if(ipq_set_mode(ipqueue->handle, c_range ? IPQ_COPY_PACKET : IPQ_COPY_META, c_range) < 0)
|
67
|
+
rb_raise(rb_eRuntimeError, "%s: %s", ipq_errstr(), strerror(errno));
|
68
|
+
|
69
|
+
ipqueue->range = c_range;
|
70
|
+
|
71
|
+
ipqueue->len = c_range + IPQ_MESSAGE_OVERHEAD;
|
72
|
+
REALLOC_N(ipqueue->buf, unsigned char, ipqueue->len);
|
73
|
+
|
74
|
+
return Qnil;
|
75
|
+
}
|
76
|
+
|
77
|
+
static VALUE fipq_get_range(VALUE obj)
|
78
|
+
{
|
79
|
+
struct ipqueue_object *ipqueue;
|
80
|
+
Data_Get_Struct(obj, struct ipqueue_object, ipqueue);
|
81
|
+
|
82
|
+
return INT2FIX(ipqueue->range);
|
83
|
+
}
|
84
|
+
|
85
|
+
static VALUE create_ipqueuepacket(ipq_packet_msg_t *packet_msg, VALUE queue)
|
86
|
+
{
|
87
|
+
VALUE packet;
|
88
|
+
VALUE data[12];
|
89
|
+
|
90
|
+
/* queue, packet_id, mark, timestamp, hook, indev_name, outdev_name, hw_protocol, hw_type, hw_addr, payload */
|
91
|
+
data[0] = queue;
|
92
|
+
data[1] = INT2NUM(packet_msg->packet_id);
|
93
|
+
data[2] = INT2NUM(packet_msg->mark);
|
94
|
+
data[3] = INT2NUM(packet_msg->timestamp_sec);
|
95
|
+
data[4] = INT2NUM(packet_msg->timestamp_usec);
|
96
|
+
data[5] = INT2FIX(packet_msg->hook);
|
97
|
+
data[6] = rb_str_new2(packet_msg->indev_name);
|
98
|
+
data[7] = rb_str_new2(packet_msg->outdev_name);
|
99
|
+
data[8] = INT2FIX(packet_msg->hw_protocol);
|
100
|
+
data[9] = INT2FIX(packet_msg->hw_type);
|
101
|
+
data[10] = rb_str_new(packet_msg->hw_addr, packet_msg->hw_addrlen);
|
102
|
+
data[11] = rb_str_new(packet_msg->payload, packet_msg->data_len);
|
103
|
+
|
104
|
+
packet = rb_class_new_instance(12, data, cIPQueuePacket);
|
105
|
+
|
106
|
+
return packet;
|
107
|
+
}
|
108
|
+
|
109
|
+
static VALUE fipq_read(int argc, VALUE *argv, VALUE obj)
|
110
|
+
{
|
111
|
+
struct ipqueue_object *ipqueue;
|
112
|
+
int ret;
|
113
|
+
ipq_packet_msg_t *packet_msg;
|
114
|
+
|
115
|
+
VALUE timeout, payload, packet;
|
116
|
+
VALUE error[2];
|
117
|
+
|
118
|
+
if(rb_scan_args(argc, argv, "01", &timeout) == 0)
|
119
|
+
timeout = INT2NUM(0);
|
120
|
+
|
121
|
+
Data_Get_Struct(obj, struct ipqueue_object, ipqueue);
|
122
|
+
|
123
|
+
ret = ipq_read(ipqueue->handle, ipqueue->buf, ipqueue->len, NUM2INT(timeout));
|
124
|
+
|
125
|
+
if(ret < 0)
|
126
|
+
rb_raise(rb_eRuntimeError, "%s: %s", ipq_errstr(), strerror(errno));
|
127
|
+
if(ret == 0)
|
128
|
+
if(errno == EINTR)
|
129
|
+
rb_raise(rb_eSignal, "non-blocked signal caught");
|
130
|
+
else
|
131
|
+
rb_raise(eTimeout, "timeout exceeded");
|
132
|
+
|
133
|
+
/* dirty hack? */
|
134
|
+
if(ipq_message_type(ipqueue->buf) == NLMSG_ERROR) {
|
135
|
+
error[0] = rb_str_new2("netlink layer");
|
136
|
+
error[1] = INT2FIX(ipq_get_msgerr(ipqueue->buf));
|
137
|
+
rb_exc_raise(rb_class_new_instance(2, error, rb_eSystemCallError));
|
138
|
+
}
|
139
|
+
|
140
|
+
/* finally, we've got it */
|
141
|
+
packet_msg = ipq_get_packet(ipqueue->buf);
|
142
|
+
|
143
|
+
return create_ipqueuepacket(packet_msg, obj);
|
144
|
+
}
|
145
|
+
|
146
|
+
static VALUE fipq_accept(int argc, VALUE *argv, VALUE obj)
|
147
|
+
{
|
148
|
+
struct ipqueue_object *ipqueue;
|
149
|
+
VALUE packet_id, payload;
|
150
|
+
unsigned char *buf = NULL;
|
151
|
+
size_t data_len = 0;
|
152
|
+
|
153
|
+
if(rb_scan_args(argc, argv, "11", &packet_id, &payload) == 2) {
|
154
|
+
Check_Type(payload, T_STRING);
|
155
|
+
buf = RSTRING(payload)->ptr;
|
156
|
+
data_len = RSTRING(payload)->len;
|
157
|
+
}
|
158
|
+
|
159
|
+
Data_Get_Struct(obj, struct ipqueue_object, ipqueue);
|
160
|
+
|
161
|
+
if(ipq_set_verdict(ipqueue->handle, NUM2INT(packet_id), NF_ACCEPT, data_len, buf) < 0)
|
162
|
+
rb_raise(rb_eRuntimeError, "%s: %s", ipq_errstr(), strerror(errno));
|
163
|
+
|
164
|
+
return Qtrue;
|
165
|
+
}
|
166
|
+
|
167
|
+
static VALUE fipq_drop(obj, packet_id)
|
168
|
+
VALUE obj, packet_id;
|
169
|
+
{
|
170
|
+
struct ipqueue_object *ipqueue;
|
171
|
+
|
172
|
+
Data_Get_Struct(obj, struct ipqueue_object, ipqueue);
|
173
|
+
|
174
|
+
if(ipq_set_verdict(ipqueue->handle, NUM2INT(packet_id), NF_DROP, 0, NULL) < 0)
|
175
|
+
rb_raise(rb_eRuntimeError, "%s: %s", ipq_errstr(), strerror(errno));
|
176
|
+
|
177
|
+
return Qtrue;
|
178
|
+
}
|
179
|
+
|
180
|
+
void Init_ipqueue()
|
181
|
+
{
|
182
|
+
cIPQueue = rb_define_class("IPQueue", rb_cObject);
|
183
|
+
|
184
|
+
/* require our IPQueuePacket class */
|
185
|
+
rb_require("ipqueuepacket");
|
186
|
+
|
187
|
+
cIPQueuePacket = rb_const_get(cIPQueue, rb_intern("Packet"));
|
188
|
+
|
189
|
+
eTimeout = rb_define_class("Timeout", rb_eException);
|
190
|
+
|
191
|
+
rb_define_singleton_method(cIPQueue, "new", fipq_create_handle, 2);
|
192
|
+
|
193
|
+
rb_define_method(cIPQueue, "range=", fipq_set_range, 1);
|
194
|
+
rb_define_method(cIPQueue, "range", fipq_get_range, 0);
|
195
|
+
rb_define_method(cIPQueue, "read", fipq_read, -1);
|
196
|
+
|
197
|
+
rb_define_method(cIPQueue, "accept", fipq_accept, -1);
|
198
|
+
rb_define_method(cIPQueue, "drop", fipq_drop, 1);
|
199
|
+
|
200
|
+
#define rb_define_ipq_const(var) \
|
201
|
+
rb_define_const(cIPQueue, #var, INT2NUM(var))
|
202
|
+
|
203
|
+
rb_define_ipq_const(PF_INET);
|
204
|
+
rb_define_ipq_const(PF_INET6);
|
205
|
+
|
206
|
+
rb_define_ipq_const(IPQ_COPY_META);
|
207
|
+
rb_define_ipq_const(IPQ_COPY_PACKET);
|
208
|
+
}
|
@@ -0,0 +1,36 @@
|
|
1
|
+
class IPQueue::Packet
|
2
|
+
attr :packet_id
|
3
|
+
attr :mark
|
4
|
+
attr :timestamp_sec
|
5
|
+
attr :timestamp_usec
|
6
|
+
attr :indev_name
|
7
|
+
attr :outdev_name
|
8
|
+
attr :hw_protocol
|
9
|
+
attr :hw_type
|
10
|
+
attr :hw_addr
|
11
|
+
attr :payload
|
12
|
+
|
13
|
+
def initialize queue, packet_id, mark, timestamp_sec, timestamp_usec, hook, indev_name, outdev_name, hw_protocol, hw_type, hw_addr, payload
|
14
|
+
@queue = queue
|
15
|
+
@packet_id = packet_id
|
16
|
+
@mark = mark
|
17
|
+
@timestamp_sec = timestamp_sec
|
18
|
+
@timestamp_usec = timestamp_usec
|
19
|
+
@hook = hook
|
20
|
+
@indev_name = indev_name
|
21
|
+
@outdev_name = outdev_name
|
22
|
+
@hw_protocol = hw_protocol
|
23
|
+
@hw_type = hw_type
|
24
|
+
@hw_addr = hw_addr
|
25
|
+
@payload = payload
|
26
|
+
end
|
27
|
+
def accept(modify = false)
|
28
|
+
if modify then @queue.accept(@packet_id, @payload) else @queue.accept(@packet_id) end
|
29
|
+
end
|
30
|
+
def drop
|
31
|
+
@queue.drop(@packet_id)
|
32
|
+
end
|
33
|
+
def payload
|
34
|
+
return @payload
|
35
|
+
end
|
36
|
+
end
|
data/test/test.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
require 'ipqueue'
|
4
|
+
require 'ip-proto'
|
5
|
+
|
6
|
+
queue = IPQueue.new(0, IPQueue::PF_INET)
|
7
|
+
queue.range = 1024
|
8
|
+
while true do
|
9
|
+
packet = queue.read
|
10
|
+
packet.accept true
|
11
|
+
ippacket = IP::decode(packet.payload)
|
12
|
+
puts ippacket.inspect_detailed
|
13
|
+
end
|
data/test/test.sh
ADDED
metadata
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.0
|
3
|
+
specification_version: 1
|
4
|
+
name: ruby-ipqueue
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.1.3
|
7
|
+
date: 2007-01-29 00:00:00 +05:00
|
8
|
+
summary: Rubyish interface to libipq
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
- ext
|
12
|
+
email: nullguid@gmail.com
|
13
|
+
homepage: http://ruby-ipqueue.rubyforge.org/
|
14
|
+
rubyforge_project: ruby-ipqueue
|
15
|
+
description: Ruby-ipqueue provides ruby-way object-oriented interface to linux libipq packet mangling library
|
16
|
+
autorequire:
|
17
|
+
default_executable:
|
18
|
+
bindir: bin
|
19
|
+
has_rdoc: false
|
20
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
21
|
+
requirements:
|
22
|
+
- - ">"
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 0.0.0
|
25
|
+
version:
|
26
|
+
platform: ruby
|
27
|
+
signing_key:
|
28
|
+
cert_chain:
|
29
|
+
post_install_message:
|
30
|
+
authors: []
|
31
|
+
|
32
|
+
files:
|
33
|
+
- ext
|
34
|
+
- lib
|
35
|
+
- test
|
36
|
+
- Rakefile
|
37
|
+
- ext/ipqueue
|
38
|
+
- ext/ipqueue/extconf.rb
|
39
|
+
- ext/ipqueue/ipqueue.c
|
40
|
+
- lib/ipqueuepacket.rb
|
41
|
+
- test/test.rb
|
42
|
+
- test/test.sh
|
43
|
+
test_files: []
|
44
|
+
|
45
|
+
rdoc_options: []
|
46
|
+
|
47
|
+
extra_rdoc_files: []
|
48
|
+
|
49
|
+
executables: []
|
50
|
+
|
51
|
+
extensions:
|
52
|
+
- ext/ipqueue/extconf.rb
|
53
|
+
requirements:
|
54
|
+
- libipq
|
55
|
+
dependencies: []
|
56
|
+
|