2009-10-22 15:46:01 +00:00
|
|
|
#include "Lorcon2.h"
|
|
|
|
#include "ruby.h"
|
2009-10-26 21:09:40 +00:00
|
|
|
|
|
|
|
#ifndef RUBY_19
|
2009-10-23 15:58:09 +00:00
|
|
|
#include "rubysig.h"
|
2009-10-26 21:09:40 +00:00
|
|
|
#endif
|
2009-10-22 15:46:01 +00:00
|
|
|
|
|
|
|
/*
|
|
|
|
self.license = GPLv2;
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
This is a derivative of the tx.c sample included with lorcon:
|
|
|
|
http://802.11ninja.net/lorcon/
|
|
|
|
|
|
|
|
lorcon is free software; you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
lorcon is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
|
|
along with lorcon; if not, write to the Free Software
|
|
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
|
|
|
|
Copyright (c) 2005 dragorn and Joshua Wright
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
Lots of code borrowed from Tom Wambold's pylorcon:
|
|
|
|
http://pylorcon.googlecode.com/ - tom5760[at]gmail.com
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
2014-03-13 14:47:52 +00:00
|
|
|
All ruby-lorcon/rubyisms are by Rapid7, Inc. (C) 2006-2007
|
2009-10-22 15:46:01 +00:00
|
|
|
http://metasploit.com/ - msfdev[at]metasploit.com
|
|
|
|
*/
|
|
|
|
|
|
|
|
VALUE mLorcon;
|
|
|
|
VALUE cDevice;
|
|
|
|
VALUE cPacket;
|
|
|
|
|
|
|
|
VALUE Lorcon_get_version(VALUE self) {
|
|
|
|
return INT2NUM(lorcon_get_version());
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE Lorcon_list_drivers(VALUE self) {
|
|
|
|
VALUE list;
|
|
|
|
VALUE hash;
|
|
|
|
|
|
|
|
lorcon_driver_t *drvlist, *dri;
|
|
|
|
|
|
|
|
list = rb_hash_new();
|
|
|
|
|
|
|
|
dri = drvlist = lorcon_list_drivers();
|
|
|
|
|
|
|
|
if (dri == NULL)
|
|
|
|
return Qnil;
|
|
|
|
|
|
|
|
while (dri) {
|
|
|
|
hash = rb_hash_new();
|
|
|
|
rb_hash_aset(hash, rb_str_new2("name"), rb_str_new2(dri->name));
|
|
|
|
rb_hash_aset(hash, rb_str_new2("description"), rb_str_new2(dri->details));
|
|
|
|
rb_hash_aset(list, rb_str_new2(dri->name),hash);
|
|
|
|
dri = dri->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
lorcon_free_driver_list(drvlist);
|
|
|
|
|
|
|
|
return(list);
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE Lorcon_find_driver(VALUE self, VALUE driver) {
|
|
|
|
VALUE hash;
|
|
|
|
lorcon_driver_t *dri;
|
2009-10-26 21:09:40 +00:00
|
|
|
char *drivert = RSTRING_PTR(driver);
|
2009-10-22 15:46:01 +00:00
|
|
|
|
|
|
|
dri = lorcon_find_driver(drivert);
|
|
|
|
|
|
|
|
if (dri == NULL)
|
|
|
|
return Qnil;
|
|
|
|
|
|
|
|
hash = rb_hash_new();
|
|
|
|
|
|
|
|
rb_hash_aset(hash, rb_str_new2("name"), rb_str_new2(dri->name));
|
|
|
|
rb_hash_aset(hash, rb_str_new2("description"), rb_str_new2(dri->details));
|
|
|
|
|
|
|
|
lorcon_free_driver_list(dri);
|
|
|
|
|
|
|
|
return(hash);
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE Lorcon_auto_driver(VALUE self, VALUE interface) {
|
|
|
|
VALUE hash;
|
|
|
|
lorcon_driver_t *dri;
|
2009-10-26 21:09:40 +00:00
|
|
|
char *intf = RSTRING_PTR(interface);
|
2009-10-22 15:46:01 +00:00
|
|
|
|
|
|
|
dri = lorcon_auto_driver(intf);
|
|
|
|
|
|
|
|
if (dri == NULL)
|
|
|
|
return Qnil;
|
|
|
|
|
|
|
|
hash = rb_hash_new();
|
|
|
|
rb_hash_aset(hash, rb_str_new2("name"), rb_str_new2(dri->name));
|
|
|
|
rb_hash_aset(hash, rb_str_new2("description"), rb_str_new2(dri->details));
|
|
|
|
|
|
|
|
lorcon_free_driver_list(dri);
|
|
|
|
|
|
|
|
return hash;
|
|
|
|
}
|
|
|
|
|
|
|
|
void Lorcon_free(struct rldev *rld) {
|
|
|
|
if (rld->context != NULL)
|
|
|
|
lorcon_free(rld->context);
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE Lorcon_create(int argc, VALUE *argv, VALUE self) {
|
|
|
|
struct rldev *rld;
|
|
|
|
char *intf = NULL, *driver = NULL;
|
|
|
|
VALUE rbdriver, rbintf, obj;
|
|
|
|
lorcon_driver_t *dri;
|
|
|
|
|
|
|
|
if (argc == 2) {
|
|
|
|
rb_scan_args(argc, argv, "2", &rbintf, &rbdriver);
|
2012-03-23 00:08:42 +00:00
|
|
|
intf = StringValuePtr(rbintf);
|
|
|
|
driver = StringValuePtr(rbdriver);
|
2009-10-22 15:46:01 +00:00
|
|
|
} else {
|
|
|
|
rb_scan_args(argc, argv, "1", &rbintf);
|
2012-03-23 00:08:42 +00:00
|
|
|
intf = StringValuePtr(rbintf);
|
2009-10-22 15:46:01 +00:00
|
|
|
}
|
2009-10-27 20:13:20 +00:00
|
|
|
|
2009-10-22 15:46:01 +00:00
|
|
|
if (driver == NULL) {
|
|
|
|
if ((dri = lorcon_auto_driver(intf)) == NULL) {
|
|
|
|
rb_raise(rb_eRuntimeError,
|
|
|
|
"LORCON could not detect a driver and none specified");
|
|
|
|
return (Qnil);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if ((dri = lorcon_find_driver(driver)) == NULL) {
|
|
|
|
rb_raise(rb_eArgError,
|
|
|
|
"LORCON could not recognize the specified driver");
|
|
|
|
return (Qnil);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
obj = Data_Make_Struct(cDevice, struct rldev, 0, Lorcon_free, rld);
|
|
|
|
|
|
|
|
rld->context = lorcon_create(intf, dri);
|
2012-03-27 20:29:28 +00:00
|
|
|
|
|
|
|
// Obsolete: XXX
|
|
|
|
// lorcon_set_timeout(rld->context, 100);
|
2009-10-27 20:13:20 +00:00
|
|
|
|
2009-10-22 15:46:01 +00:00
|
|
|
if (rld->context == NULL) {
|
|
|
|
rb_raise(rb_eRuntimeError,
|
|
|
|
"LORCON could not create context");
|
|
|
|
return (Qnil);
|
|
|
|
}
|
|
|
|
|
|
|
|
lorcon_free_driver_list(dri);
|
|
|
|
|
|
|
|
rb_obj_call_init(obj, 0, 0);
|
|
|
|
return(obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static VALUE Lorcon_open_inject(VALUE self) {
|
|
|
|
struct rldev *rld;
|
|
|
|
|
|
|
|
Data_Get_Struct(self, struct rldev, rld);
|
|
|
|
|
|
|
|
if (lorcon_open_inject(rld->context) < 0)
|
|
|
|
return Qfalse;
|
|
|
|
|
|
|
|
return Qtrue;
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE Lorcon_open_monitor(VALUE self) {
|
|
|
|
struct rldev *rld;
|
|
|
|
|
|
|
|
Data_Get_Struct(self, struct rldev, rld);
|
|
|
|
|
|
|
|
if (lorcon_open_monitor(rld->context) < 0)
|
|
|
|
return Qfalse;
|
|
|
|
|
|
|
|
return Qtrue;
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE Lorcon_open_injmon(VALUE self) {
|
|
|
|
struct rldev *rld;
|
|
|
|
|
|
|
|
Data_Get_Struct(self, struct rldev, rld);
|
|
|
|
|
|
|
|
if (lorcon_open_injmon(rld->context) < 0)
|
|
|
|
return Qfalse;
|
|
|
|
|
|
|
|
return Qtrue;
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE Lorcon_get_error(VALUE self) {
|
|
|
|
struct rldev *rld;
|
|
|
|
|
|
|
|
Data_Get_Struct(self, struct rldev, rld);
|
|
|
|
|
|
|
|
return rb_str_new2(lorcon_get_error(rld->context));
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE Lorcon_get_capiface(VALUE self) {
|
|
|
|
struct rldev *rld;
|
|
|
|
Data_Get_Struct(self, struct rldev, rld);
|
|
|
|
|
|
|
|
return rb_str_new2(lorcon_get_capiface(rld->context));
|
|
|
|
}
|
|
|
|
|
|
|
|
void Lorcon_packet_free(struct rlpack *rlp) {
|
2009-10-26 22:36:24 +00:00
|
|
|
if (rlp->packet != NULL) {
|
2009-10-22 15:46:01 +00:00
|
|
|
lorcon_packet_free(rlp->packet);
|
2009-10-26 22:36:24 +00:00
|
|
|
rlp->packet = NULL;
|
|
|
|
free(rlp);
|
|
|
|
}
|
2009-10-22 15:46:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE Lorcon_packet_create(int argc, VALUE *argv, VALUE self) {
|
|
|
|
struct rlpack *rlp;
|
|
|
|
VALUE obj;
|
|
|
|
|
|
|
|
obj = Data_Make_Struct(cPacket, struct rlpack, 0, Lorcon_packet_free, rlp);
|
|
|
|
|
|
|
|
rlp->packet = (struct lorcon_packet *) malloc(sizeof(struct lorcon_packet));
|
|
|
|
memset(rlp->packet, 0, sizeof(struct lorcon_packet));
|
|
|
|
|
|
|
|
rlp->bssid = NULL;
|
|
|
|
rlp->dot3 = NULL;
|
|
|
|
rlp->len = 0;
|
|
|
|
rlp->dir = 0;
|
|
|
|
|
|
|
|
rb_obj_call_init(obj, 0, 0);
|
|
|
|
return(obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE Lorcon_packet_get_channel(VALUE self) {
|
|
|
|
struct rlpack *rlp;
|
|
|
|
Data_Get_Struct(self, struct rlpack, rlp);
|
|
|
|
|
|
|
|
return INT2FIX(rlp->packet->channel);
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE Lorcon_packet_set_channel(VALUE self, VALUE channel) {
|
|
|
|
struct rlpack *rlp;
|
|
|
|
|
|
|
|
Data_Get_Struct(self, struct rlpack, rlp);
|
|
|
|
|
|
|
|
lorcon_packet_set_channel(rlp->packet, NUM2INT(channel));
|
|
|
|
|
|
|
|
return channel;
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE Lorcon_packet_get_dlt(VALUE self) {
|
|
|
|
struct rlpack *rlp;
|
|
|
|
Data_Get_Struct(self, struct rlpack, rlp);
|
|
|
|
|
|
|
|
return INT2FIX(rlp->packet->dlt);
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE Lorcon_packet_get_bssid(VALUE self) {
|
|
|
|
struct rlpack *rlp;
|
|
|
|
struct lorcon_dot11_extra *extra;
|
|
|
|
Data_Get_Struct(self, struct rlpack, rlp);
|
|
|
|
|
|
|
|
if (rlp->packet->extra_info == NULL ||
|
|
|
|
rlp->packet->extra_type != LORCON_PACKET_EXTRA_80211)
|
|
|
|
return Qnil;
|
|
|
|
|
|
|
|
extra = (struct lorcon_dot11_extra *) rlp->packet->extra_info;
|
|
|
|
|
|
|
|
if (extra->bssid_mac == NULL)
|
|
|
|
return Qnil;
|
|
|
|
|
2009-10-26 21:09:40 +00:00
|
|
|
return rb_str_new((char *)extra->bssid_mac, 6);
|
2009-10-22 15:46:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE Lorcon_packet_get_source(VALUE self) {
|
|
|
|
struct rlpack *rlp;
|
|
|
|
struct lorcon_dot11_extra *extra;
|
|
|
|
Data_Get_Struct(self, struct rlpack, rlp);
|
|
|
|
|
|
|
|
if (rlp->packet->extra_info == NULL ||
|
|
|
|
rlp->packet->extra_type != LORCON_PACKET_EXTRA_80211)
|
|
|
|
return Qnil;
|
|
|
|
|
|
|
|
extra = (struct lorcon_dot11_extra *) rlp->packet->extra_info;
|
|
|
|
|
|
|
|
if (extra->source_mac == NULL)
|
|
|
|
return Qnil;
|
|
|
|
|
2009-10-26 21:09:40 +00:00
|
|
|
return rb_str_new((char *)extra->source_mac, 6);
|
2009-10-22 15:46:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE Lorcon_packet_get_dest(VALUE self) {
|
|
|
|
struct rlpack *rlp;
|
|
|
|
struct lorcon_dot11_extra *extra;
|
|
|
|
Data_Get_Struct(self, struct rlpack, rlp);
|
|
|
|
|
|
|
|
if (rlp->packet->extra_info == NULL ||
|
|
|
|
rlp->packet->extra_type != LORCON_PACKET_EXTRA_80211)
|
|
|
|
return Qnil;
|
|
|
|
|
|
|
|
extra = (struct lorcon_dot11_extra *) rlp->packet->extra_info;
|
|
|
|
|
|
|
|
if (extra->dest_mac == NULL)
|
|
|
|
return Qnil;
|
|
|
|
|
2009-10-26 21:09:40 +00:00
|
|
|
return rb_str_new((char *)extra->dest_mac, 6);
|
2009-10-22 15:46:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE Lorcon_packet_get_rawdata(VALUE self) {
|
|
|
|
struct rlpack *rlp;
|
|
|
|
Data_Get_Struct(self, struct rlpack, rlp);
|
|
|
|
|
|
|
|
if (rlp->packet->packet_raw == NULL)
|
|
|
|
return Qnil;
|
|
|
|
|
2009-10-26 21:09:40 +00:00
|
|
|
return rb_str_new((char *)rlp->packet->packet_raw, rlp->packet->length);
|
2009-10-22 15:46:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE Lorcon_packet_get_headerdata(VALUE self) {
|
|
|
|
struct rlpack *rlp;
|
|
|
|
Data_Get_Struct(self, struct rlpack, rlp);
|
|
|
|
|
|
|
|
if (rlp->packet->packet_header == NULL)
|
|
|
|
return Qnil;
|
|
|
|
|
2009-10-26 21:09:40 +00:00
|
|
|
return rb_str_new((char *)rlp->packet->packet_header, rlp->packet->length_header);
|
2009-10-22 15:46:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE Lorcon_packet_get_data(VALUE self) {
|
|
|
|
struct rlpack *rlp;
|
|
|
|
Data_Get_Struct(self, struct rlpack, rlp);
|
|
|
|
|
|
|
|
if (rlp->packet->packet_data == NULL)
|
|
|
|
return Qnil;
|
|
|
|
|
2009-10-26 21:09:40 +00:00
|
|
|
return rb_str_new((char *)rlp->packet->packet_data, rlp->packet->length_data);
|
2009-10-22 15:46:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
static VALUE Lorcon_packet_getdot3(VALUE self) {
|
|
|
|
struct rlpack *rlp;
|
|
|
|
u_char *pdata;
|
|
|
|
int len;
|
|
|
|
VALUE ret;
|
2012-03-23 00:08:42 +00:00
|
|
|
|
|
|
|
Data_Get_Struct(self, struct rlpack, rlp);
|
2009-10-22 15:46:01 +00:00
|
|
|
|
|
|
|
if (rlp->packet->packet_data == NULL)
|
|
|
|
return Qnil;
|
|
|
|
|
|
|
|
len = lorcon_packet_to_dot3(rlp->packet, &pdata);
|
|
|
|
|
2009-10-26 21:09:40 +00:00
|
|
|
ret = rb_str_new((char *)pdata, len);
|
2009-10-22 15:46:01 +00:00
|
|
|
|
|
|
|
free(pdata);
|
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE Lorcon_packet_prepdot3(VALUE self, VALUE dot3) {
|
|
|
|
struct rlpack *rlp;
|
|
|
|
Data_Get_Struct(self, struct rlpack, rlp);
|
|
|
|
|
2009-10-26 21:09:40 +00:00
|
|
|
rlp->dot3 = (unsigned char *) RSTRING_PTR(dot3);
|
|
|
|
rlp->len = RSTRING_LEN(dot3);
|
2009-10-22 15:46:01 +00:00
|
|
|
|
|
|
|
return dot3;
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE Lorcon_packet_prepbssid(VALUE self, VALUE bssid) {
|
|
|
|
struct rlpack *rlp;
|
|
|
|
Data_Get_Struct(self, struct rlpack, rlp);
|
|
|
|
|
2009-10-26 21:09:40 +00:00
|
|
|
rlp->bssid = (unsigned char *)RSTRING_PTR(bssid);
|
2009-10-22 15:46:01 +00:00
|
|
|
|
|
|
|
return bssid;
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE Lorcon_packet_prepdir(VALUE self, VALUE dir) {
|
|
|
|
struct rlpack *rlp;
|
|
|
|
Data_Get_Struct(self, struct rlpack, rlp);
|
|
|
|
|
|
|
|
rlp->dir = NUM2INT(dir);
|
|
|
|
|
|
|
|
return dir;
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE Lorcon_packet_getdir(VALUE self) {
|
|
|
|
struct rlpack *rlp;
|
|
|
|
struct lorcon_dot11_extra *extra;
|
|
|
|
Data_Get_Struct(self, struct rlpack, rlp);
|
|
|
|
|
|
|
|
if (rlp->dir != 0)
|
|
|
|
return INT2FIX(rlp->dir);
|
|
|
|
|
|
|
|
if (rlp->packet == NULL)
|
|
|
|
return Qnil;
|
|
|
|
|
|
|
|
if (rlp->packet->extra_info == NULL ||
|
|
|
|
rlp->packet->extra_type != LORCON_PACKET_EXTRA_80211)
|
|
|
|
return Qnil;
|
|
|
|
|
|
|
|
extra = (struct lorcon_dot11_extra *) rlp->packet->extra_info;
|
|
|
|
|
|
|
|
if (extra->from_ds && !extra->to_ds)
|
|
|
|
return INT2FIX(LORCON_DOT11_DIR_FROMDS);
|
|
|
|
else if (!extra->from_ds && extra->to_ds)
|
|
|
|
return INT2FIX(LORCON_DOT11_DIR_TODS);
|
|
|
|
else if (!extra->from_ds && !extra->to_ds)
|
|
|
|
return INT2FIX(LORCON_DOT11_DIR_ADHOCDS);
|
|
|
|
else if (extra->from_ds && extra->to_ds)
|
|
|
|
return INT2FIX(LORCON_DOT11_DIR_INTRADS);
|
|
|
|
|
|
|
|
return Qnil;
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE Lorcon_packet_get_rawlength(VALUE self) {
|
|
|
|
struct rlpack *rlp;
|
|
|
|
Data_Get_Struct(self, struct rlpack, rlp);
|
|
|
|
|
|
|
|
return INT2FIX(rlp->packet->length);
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE Lorcon_packet_get_headerlength(VALUE self) {
|
|
|
|
struct rlpack *rlp;
|
|
|
|
Data_Get_Struct(self, struct rlpack, rlp);
|
|
|
|
|
|
|
|
return INT2FIX(rlp->packet->length_header);
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE Lorcon_packet_get_datalength(VALUE self) {
|
|
|
|
struct rlpack *rlp;
|
|
|
|
Data_Get_Struct(self, struct rlpack, rlp);
|
|
|
|
|
|
|
|
return INT2FIX(rlp->packet->length_data);
|
|
|
|
}
|
|
|
|
|
2009-10-27 20:13:20 +00:00
|
|
|
VALUE new_lorcon_packet(struct lorcon_packet **packet) {
|
2009-10-22 15:46:01 +00:00
|
|
|
struct rlpack *rlp;
|
|
|
|
VALUE obj;
|
|
|
|
|
|
|
|
obj = Data_Make_Struct(cPacket, struct rlpack, 0, Lorcon_packet_free, rlp);
|
|
|
|
|
2009-10-27 20:13:20 +00:00
|
|
|
rlp->packet = *packet;
|
2009-10-22 15:46:01 +00:00
|
|
|
rb_obj_call_init(obj, 0, 0);
|
|
|
|
return(obj);
|
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE Lorcon_inject_packet(VALUE self, VALUE packet) {
|
|
|
|
struct rldev *rld;
|
|
|
|
struct rlpack *rlp;
|
|
|
|
lorcon_packet_t *pack = NULL;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
if (rb_obj_is_kind_of(packet, cPacket) == 0) {
|
2009-10-23 14:40:47 +00:00
|
|
|
rb_raise(rb_eTypeError, "wrong type expected %s", rb_class2name(cPacket));
|
2009-10-22 15:46:01 +00:00
|
|
|
return Qnil;
|
|
|
|
}
|
2009-10-23 14:40:47 +00:00
|
|
|
|
2009-10-22 15:46:01 +00:00
|
|
|
Data_Get_Struct(self, struct rldev, rld);
|
|
|
|
Data_Get_Struct(packet, struct rlpack, rlp);
|
|
|
|
|
|
|
|
if (rlp->bssid != NULL && rlp->dot3 != NULL) {
|
|
|
|
pack = lorcon_packet_from_dot3(rlp->bssid, rlp->dir, rlp->dot3, rlp->len);
|
|
|
|
ret = lorcon_inject(rld->context, pack);
|
|
|
|
lorcon_packet_free(pack);
|
|
|
|
} else {
|
|
|
|
ret = lorcon_inject(rld->context, rlp->packet);
|
|
|
|
}
|
|
|
|
|
|
|
|
return INT2FIX(ret);
|
|
|
|
}
|
|
|
|
|
2009-10-23 14:40:47 +00:00
|
|
|
static VALUE Lorcon_write_raw(VALUE self, VALUE rpacket) {
|
|
|
|
struct rldev *rld;
|
|
|
|
int ret;
|
|
|
|
|
|
|
|
Data_Get_Struct(self, struct rldev, rld);
|
|
|
|
|
|
|
|
if(TYPE(rpacket) != T_STRING) {
|
|
|
|
rb_raise(rb_eArgError, "packet data must be a string");
|
|
|
|
return Qnil;
|
|
|
|
}
|
|
|
|
|
2009-10-26 21:09:40 +00:00
|
|
|
ret = lorcon_send_bytes(rld->context, RSTRING_LEN(rpacket), (unsigned char *)RSTRING_PTR(rpacket));
|
2009-10-23 14:40:47 +00:00
|
|
|
return INT2FIX(ret);
|
|
|
|
}
|
|
|
|
|
2009-10-22 15:46:01 +00:00
|
|
|
static VALUE Lorcon_set_filter(VALUE self, VALUE filter) {
|
|
|
|
struct rldev *rld;
|
|
|
|
Data_Get_Struct(self, struct rldev, rld);
|
2009-10-26 21:09:40 +00:00
|
|
|
return INT2FIX(lorcon_set_filter(rld->context, RSTRING_PTR(filter)));
|
2009-10-22 15:46:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static VALUE Lorcon_set_channel(VALUE self, VALUE channel) {
|
|
|
|
struct rldev *rld;
|
|
|
|
Data_Get_Struct(self, struct rldev, rld);
|
|
|
|
return INT2FIX(lorcon_set_channel(rld->context, NUM2INT(channel)));
|
|
|
|
}
|
|
|
|
|
2012-03-23 00:08:42 +00:00
|
|
|
static VALUE Lorcon_get_channel(VALUE self) {
|
|
|
|
struct rldev *rld;
|
|
|
|
Data_Get_Struct(self, struct rldev, rld);
|
|
|
|
return INT2FIX(lorcon_get_channel(rld->context));
|
|
|
|
}
|
2009-10-27 20:13:20 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
unsigned char *raw;
|
|
|
|
pcap_t *pd;
|
|
|
|
rblorconjob_t job;
|
|
|
|
Data_Get_Struct(self, struct rldev, rld);
|
|
|
|
|
|
|
|
pd = lorcon_get_pcap(rld->context);
|
|
|
|
|
|
|
|
#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);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-10-22 15:46:01 +00:00
|
|
|
static VALUE Lorcon_capture_loop(int argc, VALUE *argv, VALUE self) {
|
|
|
|
struct rldev *rld;
|
2009-10-26 21:09:40 +00:00
|
|
|
int count = 0;
|
|
|
|
int p = 0;
|
2009-10-22 15:46:01 +00:00
|
|
|
VALUE v_cnt;
|
2009-10-27 20:13:20 +00:00
|
|
|
VALUE ret;
|
2009-10-22 15:46:01 +00:00
|
|
|
int fd;
|
2009-10-23 15:58:09 +00:00
|
|
|
|
2009-10-22 15:46:01 +00:00
|
|
|
Data_Get_Struct(self, struct rldev, rld);
|
|
|
|
|
|
|
|
if (rb_scan_args(argc, argv, "01", &v_cnt) >= 1) {
|
|
|
|
count = FIX2INT(v_cnt);
|
|
|
|
} else {
|
|
|
|
count = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
fd = lorcon_get_selectable_fd(rld->context);
|
2009-10-28 00:19:17 +00:00
|
|
|
if(fd < 0 ) {
|
|
|
|
rb_raise(rb_eRuntimeError,
|
|
|
|
"LORCON context could not provide a pollable descriptor "
|
|
|
|
"and we need one for the threaded dispatch loop");
|
|
|
|
}
|
2009-10-27 20:13:20 +00:00
|
|
|
|
2009-10-22 15:46:01 +00:00
|
|
|
while (p < count || count <= 0) {
|
2009-10-27 20:13:20 +00:00
|
|
|
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++;
|
|
|
|
}
|
2009-10-22 15:46:01 +00:00
|
|
|
}
|
2009-10-27 20:13:20 +00:00
|
|
|
|
|
|
|
return INT2FIX(p);
|
2009-10-22 15:46:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void Init_Lorcon2() {
|
|
|
|
mLorcon = rb_define_module("Lorcon");
|
|
|
|
|
|
|
|
cPacket = rb_define_class_under(mLorcon, "Packet", rb_cObject);
|
|
|
|
|
|
|
|
rb_define_const(cPacket, "LORCON_FROM_DS", INT2NUM(LORCON_DOT11_DIR_FROMDS));
|
|
|
|
rb_define_const(cPacket, "LORCON_TO_DS", INT2NUM(LORCON_DOT11_DIR_TODS));
|
|
|
|
rb_define_const(cPacket, "LORCON_INTRA_DS", INT2NUM(LORCON_DOT11_DIR_INTRADS));
|
|
|
|
rb_define_const(cPacket, "LORCON_ADHOC_DS", INT2NUM(LORCON_DOT11_DIR_ADHOCDS));
|
|
|
|
|
|
|
|
rb_define_singleton_method(cPacket, "new", Lorcon_packet_create, -1);
|
|
|
|
rb_define_method(cPacket, "bssid", Lorcon_packet_get_bssid, 0);
|
|
|
|
rb_define_method(cPacket, "source", Lorcon_packet_get_source, 0);
|
|
|
|
rb_define_method(cPacket, "dest", Lorcon_packet_get_dest, 0);
|
|
|
|
|
|
|
|
rb_define_method(cPacket, "channel", Lorcon_packet_get_channel, 0);
|
|
|
|
rb_define_method(cPacket, "channel=", Lorcon_packet_set_channel, 1);
|
|
|
|
rb_define_method(cPacket, "dlt", Lorcon_packet_get_dlt, 0);
|
|
|
|
|
|
|
|
rb_define_method(cPacket, "rawdata", Lorcon_packet_get_rawdata, 0);
|
|
|
|
rb_define_method(cPacket, "headerdata", Lorcon_packet_get_headerdata, 0);
|
|
|
|
rb_define_method(cPacket, "data", Lorcon_packet_get_data, 0);
|
|
|
|
|
|
|
|
rb_define_method(cPacket, "dot3", Lorcon_packet_getdot3, 0);
|
|
|
|
|
|
|
|
rb_define_method(cPacket, "dot3=", Lorcon_packet_prepdot3, 1);
|
|
|
|
rb_define_method(cPacket, "bssid=", Lorcon_packet_prepbssid, 1);
|
|
|
|
rb_define_method(cPacket, "direction=", Lorcon_packet_prepdir, 1);
|
|
|
|
rb_define_method(cPacket, "direction", Lorcon_packet_getdir, 0);
|
|
|
|
|
|
|
|
rb_define_method(cPacket, "size", Lorcon_packet_get_rawlength, 0);
|
|
|
|
rb_define_method(cPacket, "linesize", Lorcon_packet_get_rawlength, 0);
|
|
|
|
rb_define_method(cPacket, "headersize", Lorcon_packet_get_headerlength, 0);
|
|
|
|
rb_define_method(cPacket, "datasize", Lorcon_packet_get_datalength, 0);
|
|
|
|
|
|
|
|
cDevice = rb_define_class_under(mLorcon, "Device", rb_cObject);
|
|
|
|
rb_define_singleton_method(cDevice, "new", Lorcon_create, -1);
|
|
|
|
rb_define_method(cDevice, "openinject", Lorcon_open_inject, 0);
|
|
|
|
rb_define_method(cDevice, "openmonitor", Lorcon_open_monitor, 0);
|
|
|
|
rb_define_method(cDevice, "openinjmon", Lorcon_open_injmon, 0);
|
|
|
|
rb_define_method(cDevice, "error", Lorcon_get_error, 0);
|
|
|
|
rb_define_method(cDevice, "capiface", Lorcon_get_capiface, 0);
|
|
|
|
|
|
|
|
rb_define_method(cDevice, "filter=", Lorcon_set_filter, 1);
|
2009-10-23 04:32:26 +00:00
|
|
|
rb_define_method(cDevice, "channel=", Lorcon_set_channel, 1);
|
2012-03-23 00:08:42 +00:00
|
|
|
rb_define_method(cDevice, "channel", Lorcon_get_channel, 0);
|
2009-10-22 15:46:01 +00:00
|
|
|
|
|
|
|
rb_define_method(cDevice, "loop", Lorcon_capture_loop, -1);
|
|
|
|
rb_define_method(cDevice, "each", Lorcon_capture_loop, -1);
|
|
|
|
rb_define_method(cDevice, "each_packet", Lorcon_capture_loop, -1);
|
2009-10-23 14:40:47 +00:00
|
|
|
rb_define_method(cDevice, "write", Lorcon_write_raw, 1);
|
2009-10-22 15:46:01 +00:00
|
|
|
rb_define_method(cDevice, "inject", Lorcon_inject_packet, 1);
|
|
|
|
rb_define_module_function(mLorcon, "drivers", Lorcon_list_drivers, 0);
|
|
|
|
rb_define_module_function(mLorcon, "version", Lorcon_get_version, 0);
|
|
|
|
rb_define_module_function(mLorcon, "find_driver", Lorcon_find_driver, 1);
|
|
|
|
rb_define_module_function(mLorcon, "auto_driver", Lorcon_auto_driver, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
|