This patch makes pcap.next non-blocking from a Ruby thread perspective. It does eat more CPU if there are no select() loops in the calling Ruby parent, but this isnt too common and never an issue for MSF
git-svn-id: file:///home/svn/framework3/trunk@5534 4d416f70-5f16-0410-b530-b9f4589650daunstable
parent
13859c23d9
commit
8c244f4422
|
@ -8,8 +8,10 @@ if /i386-mswin32/ =~ RUBY_PLATFORM
|
|||
$CFLAGS = "-DWIN32 -I#{pcap_includedir}"
|
||||
$LDFLAGS = "/link /LIBPATH:#{pcap_libdir}"
|
||||
have_library("wpcap", "pcap_open_live")
|
||||
have_library("wpcap", "pcap_setnonblock")
|
||||
else
|
||||
have_library("pcap", "pcap_open_live")
|
||||
have_library("pcap", "pcap_setnonblock")
|
||||
end
|
||||
|
||||
create_makefile("pcaprub")
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
static VALUE rb_cPcap;
|
||||
|
||||
#define PCAPRUB_VERSION "0.7-dev"
|
||||
#define PCAPRUB_VERSION "0.8-dev"
|
||||
|
||||
#define OFFLINE 1
|
||||
#define LIVE 2
|
||||
|
@ -21,6 +21,13 @@ typedef struct rbpcap {
|
|||
char type;
|
||||
} rbpcap_t;
|
||||
|
||||
|
||||
typedef struct rbpcapjob {
|
||||
struct pcap_pkthdr hdr;
|
||||
char *pkt;
|
||||
int wtf;
|
||||
} rbpcapjob_t;
|
||||
|
||||
static VALUE
|
||||
rbpcap_s_version(VALUE class)
|
||||
{
|
||||
|
@ -259,25 +266,35 @@ rbpcap_inject(VALUE self, VALUE payload)
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void rbpcap_handler(rbpcapjob_t *job, struct pcap_pkthdr *hdr, u_char *pkt){
|
||||
job->pkt = pkt;
|
||||
job->hdr = *hdr;
|
||||
}
|
||||
|
||||
static VALUE
|
||||
rbpcap_next(VALUE self)
|
||||
{
|
||||
char *pkt;
|
||||
rbpcap_t *rbp;
|
||||
struct pcap_pkthdr pkthdr;
|
||||
|
||||
rbpcapjob_t job;
|
||||
char eb[PCAP_ERRBUF_SIZE];
|
||||
int ret;
|
||||
|
||||
Data_Get_Struct(self, rbpcap_t, rbp);
|
||||
|
||||
if(! rbpcap_ready(rbp)) return self;
|
||||
|
||||
memset(&pkthdr, 0, sizeof(pkthdr));
|
||||
pcap_setnonblock(rbp->pd, 1, eb);
|
||||
|
||||
TRAP_BEG;
|
||||
pkt = (char *)pcap_next(rbp->pd, &pkthdr);
|
||||
|
||||
while(! (ret = pcap_dispatch(rbp->pd, 1, (pcap_handler) rbpcap_handler, (u_char *)&job))) {
|
||||
rb_thread_schedule();
|
||||
}
|
||||
|
||||
TRAP_END;
|
||||
|
||||
if(pkthdr.caplen > 0)
|
||||
return rb_str_new(pkt, pkthdr.caplen);
|
||||
|
||||
if(job.hdr.caplen > 0)
|
||||
return rb_str_new(job.pkt, job.hdr.caplen);
|
||||
|
||||
return Qnil;
|
||||
}
|
||||
|
|
|
@ -79,5 +79,17 @@ class Pcap::UnitTest < Test::Unit::TestCase
|
|||
r = o.stats
|
||||
assert_equal(Hash, r.class)
|
||||
end
|
||||
|
||||
|
||||
def test_pcap_next
|
||||
=begin
|
||||
d = Pcap.lookupdev
|
||||
o = Pcap.open_live(d, 1344, true, 1)
|
||||
@c = 0
|
||||
t = Thread.new { while(true); @c += 1; end; }
|
||||
x = o.next
|
||||
t.kill
|
||||
=end
|
||||
true
|
||||
end
|
||||
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue