Coverage Report

Created: 2026-09-28 07:39

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/suricata8/rust/src/detect/transforms/domain.rs
Line
Count
Source
1
/* Copyright (C) 2025 Open Information Security Foundation
2
 *
3
 * You can copy, redistribute or modify this Program under the terms of
4
 * the GNU General Public License version 2 as published by the Free
5
 * Software Foundation.
6
 *
7
 * This program is distributed in the hope that it will be useful,
8
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
 * GNU General Public License for more details.
11
 *
12
 * You should have received a copy of the GNU General Public License
13
 * version 2 along with this program; if not, write to the Free Software
14
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15
 * 02110-1301, USA.
16
 */
17
18
use crate::detect::SIGMATCH_NOOPT;
19
use suricata_sys::sys::{
20
    DetectEngineCtx, DetectEngineThreadCtx, InspectionBuffer, SCDetectHelperTransformRegister,
21
    SCDetectSignatureAddTransform, SCTransformTableElmt, Signature, SCInspectionBufferCheckAndExpand,
22
    SCInspectionBufferTruncate,
23
};
24
25
use std::os::raw::{c_int, c_void};
26
use std::ptr;
27
28
static mut G_TRANSFORM_DOMAIN_ID: c_int = 0;
29
static mut G_TRANSFORM_TLD_ID: c_int = 0;
30
31
4
unsafe extern "C" fn domain_setup(
32
4
    _de: *mut DetectEngineCtx, s: *mut Signature, _raw: *const std::os::raw::c_char,
33
4
) -> c_int {
34
4
    return SCDetectSignatureAddTransform(s, G_TRANSFORM_DOMAIN_ID, ptr::null_mut());
35
4
}
36
37
0
fn get_domain(input: &[u8], output: &mut [u8]) -> u32 {
38
0
    if let Some(domain) = psl::domain(input) {
39
0
        let domain = domain.as_bytes();
40
0
        let len = domain.len();
41
0
        output[0..len].copy_from_slice(domain);
42
0
        return domain.len() as u32;
43
0
    }
44
0
    0
45
0
}
46
47
0
unsafe extern "C" fn domain_transform(
48
0
    _det: *mut DetectEngineThreadCtx, buffer: *mut InspectionBuffer, _ctx: *mut c_void,
49
0
) {
50
0
    let input = (*buffer).inspect;
51
0
    let input_len = (*buffer).inspect_len;
52
0
    if input.is_null() || input_len == 0 {
53
0
        return;
54
0
    }
55
0
    let input = build_slice!(input, input_len as usize);
56
57
0
    let output = SCInspectionBufferCheckAndExpand(buffer, input_len);
58
0
    if output.is_null() {
59
        // allocation failure
60
0
        return;
61
0
    }
62
0
    let output = std::slice::from_raw_parts_mut(output, input_len as usize);
63
64
0
    let output_len = get_domain(input, output);
65
66
0
    SCInspectionBufferTruncate(buffer, output_len);
67
0
}
68
69
3
unsafe extern "C" fn tld_setup(
70
3
    _de: *mut DetectEngineCtx, s: *mut Signature, _raw: *const std::os::raw::c_char,
71
3
) -> c_int {
72
3
    return SCDetectSignatureAddTransform(s, G_TRANSFORM_TLD_ID, ptr::null_mut());
73
3
}
74
75
0
fn get_tld(input: &[u8], output: &mut [u8]) -> u32 {
76
0
    if let Some(domain) = psl::domain(input) {
77
0
        let tldb = domain.suffix().as_bytes();
78
0
        let len = tldb.len();
79
0
        let domain = tldb;
80
0
        output[0..len].copy_from_slice(domain);
81
0
        return domain.len() as u32;
82
0
    }
83
0
    0
84
0
}
85
86
0
unsafe extern "C" fn tld_transform(
87
0
    _det: *mut DetectEngineThreadCtx, buffer: *mut InspectionBuffer, _ctx: *mut c_void,
88
0
) {
89
0
    let input = (*buffer).inspect;
90
0
    let input_len = (*buffer).inspect_len;
91
0
    if input.is_null() || input_len == 0 {
92
0
        return;
93
0
    }
94
0
    let input = build_slice!(input, input_len as usize);
95
96
0
    let output = SCInspectionBufferCheckAndExpand(buffer, input_len);
97
0
    if output.is_null() {
98
        // allocation failure
99
0
        return;
100
0
    }
101
0
    let output = std::slice::from_raw_parts_mut(output, input_len as usize);
102
103
0
    let output_len = get_tld(input, output);
104
105
0
    SCInspectionBufferTruncate(buffer, output_len);
106
0
}
107
108
#[no_mangle]
109
39
pub unsafe extern "C" fn SCDetectTransformDomainRegister() {
110
39
    let kw = SCTransformTableElmt {
111
39
        name: b"domain\0".as_ptr() as *const libc::c_char,
112
39
        desc: b"modify buffer to extract the domain\0".as_ptr() as *const libc::c_char,
113
39
        url: b"/rules/transforms.html#domain\0".as_ptr() as *const libc::c_char,
114
39
        Setup: Some(domain_setup),
115
39
        flags: SIGMATCH_NOOPT,
116
39
        Transform: Some(domain_transform),
117
39
        Free: None,
118
39
        TransformValidate: None,
119
39
        TransformId: None,
120
39
    };
121
    unsafe {
122
39
        G_TRANSFORM_DOMAIN_ID = SCDetectHelperTransformRegister(&kw);
123
39
        if G_TRANSFORM_DOMAIN_ID < 0 {
124
0
            SCLogWarning!("Failed registering transform domain");
125
39
        }
126
    }
127
128
39
    let kw = SCTransformTableElmt {
129
39
        name: b"tld\0".as_ptr() as *const libc::c_char,
130
39
        desc: b"modify buffer to extract the tld\0".as_ptr() as *const libc::c_char,
131
39
        url: b"/rules/transforms.html#tld\0".as_ptr() as *const libc::c_char,
132
39
        Setup: Some(tld_setup),
133
39
        flags: SIGMATCH_NOOPT,
134
39
        Transform: Some(tld_transform),
135
39
        Free: None,
136
39
        TransformValidate: None,
137
39
        TransformId: None,
138
39
    };
139
    unsafe {
140
39
        G_TRANSFORM_TLD_ID = SCDetectHelperTransformRegister(&kw);
141
39
        if G_TRANSFORM_TLD_ID < 0 {
142
0
            SCLogWarning!("Failed registering transform tld");
143
39
        }
144
    }
145
39
}