summaryrefslogtreecommitdiffstats
path: root/rust/src/dns/lua.rs
diff options
context:
space:
mode:
Diffstat (limited to 'rust/src/dns/lua.rs')
-rw-r--r--rust/src/dns/lua.rs234
1 files changed, 234 insertions, 0 deletions
diff --git a/rust/src/dns/lua.rs b/rust/src/dns/lua.rs
new file mode 100644
index 0000000..b9935f8
--- /dev/null
+++ b/rust/src/dns/lua.rs
@@ -0,0 +1,234 @@
+/* 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 crate::dns::dns::*;
+use crate::dns::log::*;
+use crate::lua::*;
+
+#[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 };
+
+ if let Some(request) = &tx.request {
+ if let Some(query) = request.queries.first() {
+ lua.pushstring(&String::from_utf8_lossy(&query.name));
+ return 1;
+ }
+ } else if let Some(response) = &tx.response {
+ if let Some(query) = response.queries.first() {
+ lua.pushstring(&String::from_utf8_lossy(&query.name));
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+#[no_mangle]
+pub extern "C" fn rs_dns_lua_get_rcode(clua: &mut CLuaState, tx: &mut DNSTransaction) -> c_int {
+ let lua = LuaState { lua: clua };
+
+ let rcode = tx.rcode();
+ if rcode > 0 {
+ lua.pushstring(&dns_rcode_string(rcode));
+ 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;
+
+ // Create table now to be consistent with C that always returns
+ // table even in the absence of any authorities.
+ lua.newtable();
+
+ // We first look in the request for queries. However, if there is
+ // no request, check the response for queries.
+ if let Some(request) = &tx.request {
+ 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(&String::from_utf8_lossy(&query.name));
+ lua.settable(-3);
+
+ lua.settable(-3);
+ }
+ } else if let Some(response) = &tx.response {
+ for query in &response.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(&String::from_utf8_lossy(&query.name));
+ lua.settable(-3);
+
+ lua.settable(-3);
+ }
+ }
+
+ // Again, always return 1 to be consistent with C, even if the
+ // table is empty.
+ return 1;
+}
+
+#[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;
+
+ // Create table now to be consistent with C that always returns
+ // table even in the absence of any authorities.
+ lua.newtable();
+
+ if let Some(response) = &tx.response {
+ 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(&String::from_utf8_lossy(&answer.name));
+ lua.settable(-3);
+
+ // All rdata types are pushed to "addr" for backwards compatibility
+ match answer.data {
+ DNSRData::A(ref bytes) | DNSRData::AAAA(ref bytes) => {
+ if !bytes.is_empty() {
+ lua.pushstring("addr");
+ lua.pushstring(&dns_print_addr(bytes));
+ lua.settable(-3);
+ }
+ }
+ DNSRData::CNAME(ref bytes)
+ | DNSRData::MX(ref bytes)
+ | DNSRData::NS(ref bytes)
+ | DNSRData::TXT(ref bytes)
+ | DNSRData::NULL(ref bytes)
+ | DNSRData::PTR(ref bytes)
+ | DNSRData::Unknown(ref bytes) => {
+ if !bytes.is_empty() {
+ lua.pushstring("addr");
+ lua.pushstring(&String::from_utf8_lossy(bytes));
+ lua.settable(-3);
+ }
+ }
+ DNSRData::SOA(ref soa) => {
+ if !soa.mname.is_empty() {
+ lua.pushstring("addr");
+ lua.pushstring(&String::from_utf8_lossy(&soa.mname));
+ lua.settable(-3);
+ }
+ }
+ DNSRData::SSHFP(ref sshfp) => {
+ lua.pushstring("addr");
+ lua.pushstring(&String::from_utf8_lossy(&sshfp.fingerprint));
+ lua.settable(-3);
+ }
+ DNSRData::SRV(ref srv) => {
+ lua.pushstring("addr");
+ lua.pushstring(&String::from_utf8_lossy(&srv.target));
+ lua.settable(-3);
+ }
+ }
+ lua.settable(-3);
+ }
+ }
+
+ // Again, always return 1 to be consistent with C, even if the
+ // table is empty.
+ return 1;
+}
+
+#[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;
+
+ // Create table now to be consistent with C that always returns
+ // table even in the absence of any authorities.
+ lua.newtable();
+
+ if let Some(response) = &tx.response {
+ 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(&String::from_utf8_lossy(&answer.name));
+ lua.settable(-3);
+
+ lua.settable(-3);
+ }
+ }
+
+ // Again, always return 1 to be consistent with C, even if the
+ // table is empty.
+ return 1;
+}