rust: lua support for DNS based Rust

Uses Rust wrappers around Lua to populate Lua
data structures.
pull/2746/head
Jason Ish 9 years ago
parent 9d687025e2
commit b588b49779

@ -24,7 +24,7 @@ use json::*;
use dns::dns::*;
use log::*;
fn dns_rrtype_string(rrtype: u16) -> String {
pub fn dns_rrtype_string(rrtype: u16) -> String {
match rrtype {
DNS_RTYPE_A => "A",
DNS_RTYPE_CNAME => "CNAME",
@ -51,7 +51,7 @@ fn dns_rcode_string(flags: u16) -> String {
}
/// Format bytes as an IP address string.
fn dns_print_addr(addr: &Vec<u8>) -> std::string::String {
pub fn dns_print_addr(addr: &Vec<u8>) -> std::string::String {
if addr.len() == 4 {
return format!("{}.{}.{}.{}", addr[0], addr[1], addr[2], addr[3]);
}

@ -0,0 +1,203 @@
/* Copyright (C) 2017 Open Information Security Foundation
*
* You can copy, redistribute or modify this Program under the terms of
* the GNU General Public License version 2 as published by the Free
* Software Foundation.
*
* This program 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
* version 2 along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
use std::os::raw::c_int;
use lua::*;
use dns::dns::*;
use dns::log::*;
#[no_mangle]
pub extern "C" fn rs_dns_lua_get_tx_id(clua: &mut CLuaState,
tx: &mut DNSTransaction)
{
let lua = LuaState{
lua: clua,
};
lua.pushinteger(tx.tx_id() as i64);
}
#[no_mangle]
pub extern "C" fn rs_dns_lua_get_rrname(clua: &mut CLuaState,
tx: &mut DNSTransaction)
-> c_int
{
let lua = LuaState{
lua: clua,
};
for request in &tx.request {
for query in &request.queries {
lua.pushstring(query.name());
return 1;
}
}
for response in &tx.response {
for query in &response.queries {
lua.pushstring(query.name());
return 1;
}
}
return 0;
}
#[no_mangle]
pub extern "C" fn rs_dns_lua_get_query_table(clua: &mut CLuaState,
tx: &mut DNSTransaction)
-> c_int
{
let lua = LuaState{
lua: clua,
};
let mut i: i64 = 0;
for request in &tx.request {
if request.queries.len() == 0 {
break;
}
lua.newtable();
for query in &request.queries {
lua.pushinteger(i);
i += 1;
lua.newtable();
lua.pushstring("type");
lua.pushstring(&dns_rrtype_string(query.rrtype));
lua.settable(-3);
lua.pushstring("rrname");
lua.pushstring(query.name());
lua.settable(-3);
lua.settable(-3);
}
return 1;
}
return 0;
}
#[no_mangle]
pub extern "C" fn rs_dns_lua_get_answer_table(clua: &mut CLuaState,
tx: &mut DNSTransaction)
-> c_int
{
let lua = LuaState{
lua: clua,
};
let mut i: i64 = 0;
for response in &tx.response {
if response.answers.len() == 0 {
break;
}
lua.newtable();
for answer in &response.answers {
lua.pushinteger(i);
i += 1;
lua.newtable();
lua.pushstring("type");
lua.pushstring(&dns_rrtype_string(answer.rrtype));
lua.settable(-3);
lua.pushstring("ttl");
lua.pushinteger(answer.ttl as i64);
lua.settable(-3);
lua.pushstring("rrname");
lua.pushstring(answer.name());
lua.settable(-3);
if answer.data.len() > 0 {
lua.pushstring("addr");
match answer.rrtype {
DNS_RTYPE_A | DNS_RTYPE_AAAA => {
lua.pushstring(&dns_print_addr(&answer.data));
}
_ => {
lua.pushstring(answer.data_to_string());
}
}
lua.settable(-3);
}
lua.settable(-3);
}
return 1;
}
return 0;
}
#[no_mangle]
pub extern "C" fn rs_dns_lua_get_authority_table(clua: &mut CLuaState,
tx: &mut DNSTransaction)
-> c_int
{
let lua = LuaState{
lua: clua,
};
let mut i: i64 = 0;
for response in &tx.response {
if response.authorities.len() == 0 {
break;
}
lua.newtable();
for answer in &response.authorities {
lua.pushinteger(i);
i += 1;
lua.newtable();
lua.pushstring("type");
lua.pushstring(&dns_rrtype_string(answer.rrtype));
lua.settable(-3);
lua.pushstring("ttl");
lua.pushinteger(answer.ttl as i64);
lua.settable(-3);
lua.pushstring("rrname");
lua.pushstring(answer.name());
lua.settable(-3);
lua.settable(-3);
}
return 1;
}
return 0;
}

@ -18,3 +18,6 @@
pub mod parser;
pub mod dns;
pub mod log;
#[cfg(feature = "lua")]
pub mod lua;

@ -60,6 +60,7 @@
#ifdef HAVE_RUST
#include "rust-dns-dns-gen.h"
#include "rust-dns-lua-gen.h"
#endif
static int DnsGetDnsRrname(lua_State *luastate)
@ -68,31 +69,10 @@ static int DnsGetDnsRrname(lua_State *luastate)
return LuaCallbackError(luastate, "error: protocol not dns");
#ifdef HAVE_RUST
RSDNSTransaction *tx = LuaStateGetTX(luastate);
if (tx == NULL)
if (tx == NULL) {
return LuaCallbackError(luastate, "internal error: no tx");
for (uint16_t i = 0;; i++) {
uint32_t buf_len;
uint8_t *buf;
if (!rs_dns_tx_get_query_name(tx, i, &buf, &buf_len)) {
break;
}
char *rrname = BytesToString(buf, buf_len);
if (rrname != NULL) {
size_t input_len = strlen(rrname);
/* sanity check */
if (input_len > (size_t)(2 * buf_len)) {
SCFree(rrname);
return LuaCallbackError(luastate, "invalid length");
}
int ret = LuaPushStringBuffer(luastate, (uint8_t *)rrname,
input_len);
SCFree(rrname);
return ret;
}
}
return rs_dns_lua_get_rrname(luastate, tx);
#else
DNSTransaction *tx = LuaStateGetTX(luastate);
if (tx == NULL)
@ -126,10 +106,10 @@ static int DnsGetTxid(lua_State *luastate)
return LuaCallbackError(luastate, "error: protocol not dns");
#ifdef HAVE_RUST
RSDNSTransaction *tx = LuaStateGetTX(luastate);
if (tx == NULL)
if (tx == NULL) {
return LuaCallbackError(luastate, "internal error: no tx");
uint16_t tx_id = rs_dns_tx_get_tx_id(tx);
lua_pushinteger(luastate, tx_id);
}
rs_dns_lua_get_tx_id(luastate, tx);
#else
DNSTransaction *tx = LuaStateGetTX(luastate);
if (tx == NULL)
@ -173,12 +153,11 @@ static int DnsGetRecursionDesired(lua_State *luastate)
return LuaCallbackError(luastate, "error: protocol not dns");
#ifdef HAVE_RUST
RSDNSTransaction *tx = LuaStateGetTX(luastate);
if (tx == NULL)
if (tx == NULL) {
return LuaCallbackError(luastate, "internal error: no tx");
}
uint16_t flags = rs_dns_tx_get_response_flags(tx);
int recursion_desired = flags & 0x0080 ? 1 : 0;
lua_pushboolean(luastate, recursion_desired);
#else
DNSTransaction *tx = LuaStateGetTX(luastate);
@ -192,59 +171,15 @@ static int DnsGetRecursionDesired(lua_State *luastate)
static int DnsGetQueryTable(lua_State *luastate)
{
#ifdef HAVE_RUST
if (!(LuaStateNeedProto(luastate, ALPROTO_DNS)))
return LuaCallbackError(luastate, "error: protocol not dns");
#ifdef HAVE_RUST
RSDNSTransaction *tx = LuaStateGetTX(luastate);
if (tx == NULL)
if (tx == NULL) {
return LuaCallbackError(luastate, "internal error: no tx");
lua_newtable(luastate);
uint8_t *name;
uint32_t name_len;
for (uint16_t i = 0;; i++) {
if (!rs_dns_tx_get_query_name(tx, i, &name, &name_len)) {
break;
}
lua_pushinteger(luastate, i);
lua_newtable(luastate);
uint16_t rrtype;
if (rs_dns_tx_get_query_rrtype(tx, i, &rrtype)) {
char s_rrtype[16] = "";
DNSCreateTypeString(rrtype, s_rrtype, sizeof(s_rrtype));
lua_pushstring(luastate, "type");
lua_pushstring(luastate, s_rrtype);
lua_settable(luastate, -3);
}
char *s = BytesToString(name, name_len);
if (s != NULL) {
size_t slen = strlen(s);
if (slen > name_len * 2) {
SCFree(s);
return LuaCallbackError(luastate, "invalid length");
}
lua_pushstring(luastate, "rrname");
LuaPushStringBuffer(luastate, (uint8_t *)s, slen);
lua_settable(luastate, -3);
SCFree(s);
}
lua_pushinteger(luastate, i++);
}
return 1;
return rs_dns_lua_get_query_table(luastate, tx);
#else
if (!(LuaStateNeedProto(luastate, ALPROTO_DNS)))
return LuaCallbackError(luastate, "error: protocol not dns");
DNSTransaction *tx = LuaStateGetTX(luastate);
if (tx == NULL)
return LuaCallbackError(luastate, "internal error: no tx");
@ -290,13 +225,12 @@ static int DnsGetQueryTable(lua_State *luastate)
static int DnsGetAnswerTable(lua_State *luastate)
{
#ifdef HAVE_RUST
SCLogNotice("DnsGetAnswerTable not implemented for Rust DNS.");
return 1;
#else
if (!(LuaStateNeedProto(luastate, ALPROTO_DNS)))
return LuaCallbackError(luastate, "error: protocol not dns");
#ifdef HAVE_RUST
RSDNSTransaction *tx = LuaStateGetTX(luastate);
return rs_dns_lua_get_answer_table(luastate, tx);
#else
DNSTransaction *tx = LuaStateGetTX(luastate);
if (tx == NULL)
return LuaCallbackError(luastate, "internal error: no tx");
@ -359,13 +293,12 @@ static int DnsGetAnswerTable(lua_State *luastate)
static int DnsGetAuthorityTable(lua_State *luastate)
{
#ifdef HAVE_RUST
SCLogNotice("DnsGetAuthorityTable not implemented for Rust DNS");
return 1;
#else
if (!(LuaStateNeedProto(luastate, ALPROTO_DNS)))
return LuaCallbackError(luastate, "error: protocol not dns");
#ifdef HAVE_RUST
RSDNSTransaction *tx = LuaStateGetTX(luastate);
return rs_dns_lua_get_authority_table(luastate, tx);
#else
DNSTransaction *tx = LuaStateGetTX(luastate);
if (tx == NULL)
return LuaCallbackError(luastate, "internal error: no tx");

Loading…
Cancel
Save