Mostly working codebase, still hanging on some instances, depends on latest svn of lorcon2. See #427

git-svn-id: file:///home/svn/framework3/trunk@7292 4d416f70-5f16-0410-b530-b9f4589650da
unstable
HD Moore 2009-10-27 20:13:20 +00:00
parent 5234fe8ff8
commit 7b22b2cc04
3 changed files with 85 additions and 68 deletions

View File

@ -133,7 +133,7 @@ static VALUE Lorcon_create(int argc, VALUE *argv, VALUE self) {
rb_scan_args(argc, argv, "1", &rbintf);
intf = STR2CSTR(rbintf);
}
if (driver == NULL) {
if ((dri = lorcon_auto_driver(intf)) == NULL) {
rb_raise(rb_eRuntimeError,
@ -151,7 +151,8 @@ static VALUE Lorcon_create(int argc, VALUE *argv, VALUE self) {
obj = Data_Make_Struct(cDevice, struct rldev, 0, Lorcon_free, rld);
rld->context = lorcon_create(intf, dri);
lorcon_set_timeout(rld->context, 100);
if (rld->context == NULL) {
rb_raise(rb_eRuntimeError,
"LORCON could not create context");
@ -442,13 +443,13 @@ static VALUE Lorcon_packet_get_datalength(VALUE self) {
return INT2FIX(rlp->packet->length_data);
}
VALUE new_lorcon_packet(struct lorcon_packet *packet) {
VALUE new_lorcon_packet(struct lorcon_packet **packet) {
struct rlpack *rlp;
VALUE obj;
obj = Data_Make_Struct(cPacket, struct rlpack, 0, Lorcon_packet_free, rlp);
rlp->packet = packet;
rlp->packet = *packet;
rb_obj_call_init(obj, 0, 0);
return(obj);
}
@ -459,14 +460,10 @@ static VALUE Lorcon_inject_packet(VALUE self, VALUE packet) {
lorcon_packet_t *pack = NULL;
int ret;
if (rb_obj_is_kind_of(packet, cPacket) == 0) {
rb_raise(rb_eTypeError, "wrong type expected %s", rb_class2name(cPacket));
return Qnil;
}
return Qnil;
Data_Get_Struct(self, struct rldev, rld);
Data_Get_Struct(packet, struct rlpack, rlp);
@ -509,13 +506,56 @@ static VALUE Lorcon_set_channel(VALUE self, VALUE channel) {
return INT2FIX(lorcon_set_channel(rld->context, NUM2INT(channel)));
}
static void rblorcon_pcap_handler(rblorconjob_t *job, struct pcap_pkthdr *hdr, u_char *pkt){
job->pkt = (unsigned char *)pkt;
job->hdr = *hdr;
}
static VALUE Lorcon_capture_next(VALUE self) {
struct rldev *rld;
int ret = 0;
struct lorcon_packet *packet;
char eb[PCAP_ERRBUF_SIZE];
unsigned char *raw;
pcap_t *pd;
rblorconjob_t job;
Data_Get_Struct(self, struct rldev, rld);
pd = lorcon_get_pcap(rld->context);
pcap_setnonblock(pd, 1, eb);
#ifndef RUBY_19
TRAP_BEG;
#endif
ret = pcap_dispatch(pd, 1, (pcap_handler) rblorcon_pcap_handler, (u_char *)&job);
#ifndef RUBY_19
TRAP_END;
#endif
if (ret == 0)
return(Qnil);
if (ret < 0 || job.hdr.caplen <= 0)
return INT2FIX(ret);
raw = malloc(job.hdr.caplen);
if(! raw) return Qnil;
memcpy(raw, job.pkt, job.hdr.caplen);
packet = lorcon_packet_from_pcap(rld->context, &job.hdr, raw);
lorcon_packet_set_freedata(packet, 1);
return new_lorcon_packet(&packet);
}
static VALUE Lorcon_capture_loop(int argc, VALUE *argv, VALUE self) {
struct rldev *rld;
int count = 0;
int ret = 0;
int p = 0;
struct lorcon_packet *packet;
VALUE v_cnt;
VALUE ret;
int fd;
Data_Get_Struct(self, struct rldev, rld);
@ -527,40 +567,23 @@ static VALUE Lorcon_capture_loop(int argc, VALUE *argv, VALUE self) {
}
fd = lorcon_get_selectable_fd(rld->context);
if (fd < 0) {
rb_raise(rb_eRuntimeError,
"LORCON context could not provide a pollable descriptor "
"and we need one for the threaded dispatch loop");
}
while (p < count || count <= 0) {
rb_thread_wait_fd(fd);
#ifndef RUBY_19
TRAP_BEG;
#endif
ret = lorcon_next_ex(rld->context, &packet);
#ifndef RUBY_19
TRAP_END;
#endif
/* timeout */
if (ret == 0)
continue;
if (ret < 0 || packet == NULL)
return INT2FIX(ret);
rb_yield(new_lorcon_packet(packet));
p++;
ret = Lorcon_capture_next(self);
if(TYPE(ret) == T_FIXNUM) return(ret);
if(ret == Qnil) {
rb_thread_wait_fd(fd);
} else {
rb_yield(ret);
p++;
}
}
return INT2FIX(ret);
return INT2FIX(p);
}
void Init_Lorcon2() {
mLorcon = rb_define_module("Lorcon");

View File

@ -8,6 +8,7 @@
#include <sys/socket.h>
#include <lorcon2/lorcon.h>
#include <pcap.h>
struct rldev {
struct lorcon *context;
@ -21,4 +22,10 @@ struct rlpack {
int dir, len;
};
typedef struct rblorconjob {
struct pcap_pkthdr hdr;
unsigned char *pkt;
} rblorconjob_t;
#endif

View File

@ -4,6 +4,7 @@ $:.unshift(File.dirname(__FILE__))
require "Lorcon2"
require "pp"
=begin
$stdout.puts "Checking LORCON version"
pp Lorcon.version
@ -19,9 +20,10 @@ pp Lorcon.find_driver("mac80211")
$stdout.puts "\nAuto-detecting driver for interface wlan0"
pp Lorcon.auto_driver("mon0")
=end
#tx = Lorcon::Device.new('kismet0', 'tuntap')
tx = Lorcon::Device.new('mon0')
tx = Lorcon::Device.new('wlan2')
$stdout.puts "\nCreated LORCON context"
if tx.openinjmon()
@ -30,34 +32,19 @@ else
$stdout.puts "\nFAILED to open " + tx.capiface + " as INJMON: " + tx.error
end
tx.channel = 11
scan_patterns = ["^GET ([^ ?]+)"]
@pkts = 0
tx.each_packet { |pkt|
d3 = pkt.dot3
if d3 != nil then
p3pfu = PacketFu::Packet.parse(d3)
scan_patterns.each {|sig| hit = p3pfu.payload.scan(/#{sig}/i) || nil
printf "#{Time.now}: %s HTTP GET %s [%s] SEQ %u\n" % [p3pfu.ip_saddr, p3pfu.ip_daddr, sig, p3pfu.tcp_seq] unless hit.size.zero?
}
Thread.new do
while(true)
select(nil, nil, nil, 5)
puts "count: #{@pkts}"
end
end
# tx.filter = "port 80"
tx.each_packet { |pkt|
if(pkt.dot3)
p pkt.dot3
end
@pkts += 1
}
# tx.fmode = "INJECT"
# tx.channel = 11
# tx.txrate = 2
# tx.modulation = "DSSS"
#
# sa = Time.now.to_f
# tx.write(packet, 500, 0)
# ea = Time.now.to_f - sa
#
# sb = Time.now.to_f
# 500.times { tx.write(packet, 1, 0) }
# eb = Time.now.to_f - sb
#
# $stdout.puts "Sent 500 packets (C) in #{ea.to_s} seconds"
# $stdout.puts "Sent 500 packets (Ruby) in #{eb.to_s} seconds"