net_file/jsons/
json_pcap_parser.rs1use chrono::{DateTime, Utc};
2use serde_json::{json, Value};
3use unescape::unescape;
4
5use crate::jsons::json_parser::JsonParser;
6
7pub const PATH_SOURCE_LAYER: &str = "$.._source.layers";
8pub const PATH_FRAME_TIME: &str = "$..frame['frame.time']";
9pub const PATH_FRAME_TIME_EPOCH: &str = "$..frame['frame.time_epoch']";
10const L3_PATH: &str = "/l3";
11
12pub struct JsonPcapParser;
13
14impl JsonPcapParser {
15 pub fn filter_source_layer(json_binary: &[u8]) -> Value {
16 JsonParser::find(json_binary, PATH_SOURCE_LAYER)
17 }
18
19 pub fn find_frame_time(json_binary: &[u8]) -> DateTime<Utc> {
20 let value = JsonParser::find(json_binary, PATH_FRAME_TIME);
21 JsonParser::get_utc_frame_time(value)
22 }
23
24 pub fn find_utc_timestamp_millis(json_binary: &[u8]) -> i64 {
25 let value = JsonParser::find(json_binary, PATH_FRAME_TIME_EPOCH);
26 JsonParser::get_utc_timestamp_millis(value)
27 }
28
29 pub fn find_utc_timestamp_nanos(json_binary: &[u8]) -> i64 {
30 let value = JsonParser::find(json_binary, PATH_FRAME_TIME_EPOCH);
31 JsonParser::get_utc_timestamp_nanos(value)
32 }
33
34 pub fn split_into_layers(value_json: &Value) -> Value {
35 let mut new_json = json!({});
36 let object_json = new_json.as_object_mut().unwrap();
37
38 value_json
39 .as_object()
40 .unwrap()
41 .keys()
42 .map(|k| k.as_str())
43 .enumerate()
44 .for_each(|(index, field)| {
45 object_json.insert(
46 format!("l{}", index + 1),
47 json!({ field: &value_json[field] }),
48 );
49 });
50
51 new_json
52 }
53
54 fn extract_field_name(l3_value: &Value) -> &str {
55 l3_value
56 .as_object()
57 .unwrap()
58 .keys()
59 .map(|k| k.as_str())
60 .last()
61 .unwrap()
62 }
63
64 fn create_src_addr_path(field_name_prefix: &str, field_name_suffix: &str) -> String {
89 format!(
90 "/{}/{}.{}",
91 field_name_prefix, field_name_prefix, field_name_suffix
92 )
93 }
94
95 fn extract_ip_addr_l3(json_value: &Value, target: &str) -> Option<String> {
96 let l3_value = json_value.pointer(L3_PATH).unwrap();
97 let l3_field_name = Self::extract_field_name(l3_value);
98 let addr_path = Self::create_src_addr_path(l3_field_name, target);
99 let addr_value = l3_value.pointer(addr_path.as_str());
100
101 match addr_value {
102 None => None,
103 Some(addr_value) => unescape(addr_value.as_str().unwrap()),
104 }
105 }
106
107 pub fn extract_src_addr_l3(json_value: &Value) -> Option<String> {
108 Self::extract_ip_addr_l3(json_value, "src")
109 }
110
111 pub fn extract_dst_addr_l3(json_value: &Value) -> Option<String> {
112 Self::extract_ip_addr_l3(json_value, "dst")
113 }
114}
115
116#[cfg(test)]
117mod tests {
118 use std::str::from_utf8;
119 use crate::file::files::Files;
120 use crate::test_resources;
121
122 use super::*;
123
124 #[test]
125 fn expected_filter_source_layer() {
126 let pcap_buffer = Files::read_vector(test_resources!("captures/arp.json"));
127 let json_buffer = Files::read_vector(test_resources!("captures/arp_layer_extracted.json"));
128
129 let result = JsonPcapParser::filter_source_layer(&pcap_buffer);
130 let json = JsonParser::print(&result);
131
132 assert_eq!(json, from_utf8(&json_buffer).unwrap());
133 }
134
135 #[test]
136 fn expected_filter_source_layer_pretty() {
137 let pcap_buffer = Files::read_vector(test_resources!("captures/arp.json"));
138 let json_buffer =
139 Files::read_vector(test_resources!("captures/arp_layer_extracted_pretty.json"));
140
141 let result = JsonPcapParser::filter_source_layer(&pcap_buffer);
142 let json = JsonParser::pretty(&result);
143
144 assert_eq!(json, from_utf8(&json_buffer).unwrap());
145 }
146
147 #[test]
148 fn expected_extract_frame_time() {
149 let pcap_buffer =
150 Files::read_vector(test_resources!("captures/arp_layer_extracted_pretty.json"));
151
152 let result = JsonPcapParser::find_frame_time(&pcap_buffer);
153
154 assert_eq!(result.to_string(), "2013-09-18 04:49:07 UTC");
155 }
156
157 #[test]
158 fn expected_extract_utc_timestamp_millis() {
159 const EXPECTED_TIME: i64 = 1379479747000;
160 let pcap_buffer =
161 Files::read_vector(test_resources!("captures/arp_layer_extracted_pretty.json"));
162 let result = JsonPcapParser::find_utc_timestamp_millis(&pcap_buffer);
163
164 assert_eq!(EXPECTED_TIME, result);
165 }
166
167 #[test]
168 fn expected_extract_utc_timestamp_nanos() {
169 const EXPECTED_TIME: i64 = 1379479747000000000;
170 let pcap_buffer =
171 Files::read_vector(test_resources!("captures/arp_layer_extracted_pretty.json"));
172 let result = JsonPcapParser::find_utc_timestamp_nanos(&pcap_buffer);
173
174 assert_eq!(EXPECTED_TIME, result);
175 }
176
177 #[test]
178 fn expected_extract_utc_timestamp_nanos_2() {
179 const EXPECTED_TIME: i64 = 1688714981480935000;
180 let pcap_buffer =
181 Files::read_vector(test_resources!("captures/epoch_frame_time.json"));
182 let result = JsonPcapParser::find_utc_timestamp_nanos(&pcap_buffer);
183
184 assert_eq!(EXPECTED_TIME, result);
185 }
186
187 #[test]
188 fn expected_layered_json_into_layers() {
189 let pcap_buffer = Files::read_vector(test_resources!("captures/arp.json"));
190 let json_buffer = Files::read_vector(test_resources!("captures/arp_layers.json"));
191
192 let result = JsonParser::find(&pcap_buffer, "$.._source.layers");
193 let first_value = JsonParser::first(&result).unwrap();
194 let layered_json = JsonPcapParser::split_into_layers(&first_value);
195 let json = JsonParser::pretty(&layered_json);
196
197 assert_eq!(json, from_utf8(&json_buffer).unwrap());
198 }
199
200 #[test]
201 fn expected_extract_src_address_from_l3() {
202 let pcap_buffer = Files::read_vector(test_resources!("captures/dhcp_one_packet.json"));
203
204 let result = JsonParser::find(&pcap_buffer, "$.._source.layers");
205 let first_value = JsonParser::first(&result).unwrap();
206 let layered_json = JsonPcapParser::split_into_layers(&first_value);
207
208 let string = JsonPcapParser::extract_src_addr_l3(&layered_json).unwrap();
209
210 assert_eq!(string, "0.0.0.0");
211 }
212
213 #[test]
214 fn expected_extract_dst_address_from_l3() {
215 let pcap_buffer = Files::read_vector(test_resources!("captures/dhcp_one_packet.json"));
216
217 let result = JsonParser::find(&pcap_buffer, "$.._source.layers");
218 let first_value = JsonParser::first(&result).unwrap();
219 let layered_json = JsonPcapParser::split_into_layers(&first_value);
220
221 let string = JsonPcapParser::extract_dst_addr_l3(&layered_json).unwrap();
222
223 assert_eq!(string, "255.255.255.255");
224 }
225
226 #[test]
227 fn expected_none_when_path_invalid() {
228 let pcap_buffer = Files::read_vector(test_resources!("captures/dhcp_one_packet.json"));
229
230 let result = JsonParser::find(&pcap_buffer, "$.._source.layers");
231 let first_value = JsonParser::first(&result).unwrap();
232 let layered_json = JsonPcapParser::split_into_layers(&first_value);
233
234 let string = JsonPcapParser::extract_ip_addr_l3(&layered_json, "any");
235
236 assert_eq!(string, None);
237 }
238}