ruby-ipqueue 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
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,7 @@
1
+ require 'mkmf'
2
+
3
+ dir_config('ipqueue')
4
+
5
+ if have_header('linux/netfilter.h') and have_header('libipq/libipq.h') and have_library('ipq', 'ipq_create_handle')
6
+ create_makefile('ipqueue')
7
+ 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
@@ -0,0 +1,5 @@
1
+ #!/bin/bash
2
+
3
+ iptables -t mangle -A FORWARD -j QUEUE
4
+ ./test.rb
5
+ iptables -t mangle -D FORWARD -j QUEUE
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
+