--- /dev/null
+/* 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;
+}
#ifdef HAVE_RUST
#include "rust-dns-dns-gen.h"
+#include "rust-dns-lua-gen.h"
#endif
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)
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)
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);
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");
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");
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");