diff --git a/rust/Cargo.lock b/rust/Cargo.lock index 2c201289c..d20bd25c8 100644 --- a/rust/Cargo.lock +++ b/rust/Cargo.lock @@ -984,7 +984,7 @@ checksum = "e5766087c2235fec47fafa4cfecc81e494ee679d0fd4a59887ea0919bfb0e4fc" dependencies = [ "cfg-if", "libc", - "socket2 0.5.7", + "socket2 0.5.8", "windows-sys 0.48.0", ] @@ -1556,7 +1556,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.5.7", + "socket2 0.4.10", "tokio", "tower-service", "tracing", @@ -1630,7 +1630,7 @@ dependencies = [ "http-body 1.0.1", "hyper 1.5.1", "pin-project-lite", - "socket2 0.5.7", + "socket2 0.5.8", "tokio", "tower-service", "tracing", @@ -3453,7 +3453,7 @@ dependencies = [ "serde_json", "sha1", "sha2", - "socket2 0.5.7", + "socket2 0.5.8", "sysinfo", "thiserror", "time", @@ -3788,9 +3788,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.5.7" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" +checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" dependencies = [ "libc", "windows-sys 0.52.0", @@ -4106,7 +4106,7 @@ dependencies = [ "parking_lot", "pin-project-lite", "signal-hook-registry", - "socket2 0.5.7", + "socket2 0.5.8", "tokio-macros", "windows-sys 0.52.0", ] diff --git a/rust/Cargo.toml b/rust/Cargo.toml index c215b4e75..db20b46ab 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -66,7 +66,7 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0.96" sha1 = "0.10.5" sha2 = "0.10.7" -socket2 = "0.5.7" +socket2 = "0.5.8" sysinfo = "0.30.5" thiserror = "1.0.62" time = { version = "0", features = ["parsing"] } diff --git a/rust/examples/forge_icmp_v6.nasl b/rust/examples/forge_icmp_v6.nasl new file mode 100644 index 000000000..3047a07fc --- /dev/null +++ b/rust/examples/forge_icmp_v6.nasl @@ -0,0 +1,41 @@ +# SPDX-FileCopyrightText: 2023 Greenbone AG +# +# SPDX-License-Identifier: GPL-2.0-or-later WITH x11vnc-openssl-exception + +if(description) { + script_oid("1.2.3"); + exit(0); +} + +include("misc_func.inc"); + +# ICMPv6 +IP6_v = 0x60; +IP6_P = 0x3a;#ICMPv6 +IP6_HLIM = 0x40; +ICMP_ID = rand() % 65536; + +ori = "5858::1"; +dst = "5858::1"; + +ip6_packet = forge_ip_v6_packet( ip6_v: 6, # IP6_v, + ip6_p: IP6_P, + ip6_plen:40, + ip6_hlim:IP6_HLIM, + ip6_src: ori, + ip6_dst: dst ); + +dump_ip_v6_packet(ip6_packet); + +d = "123456"; +icmp = forge_icmp_v6_packet( ip6:ip6_packet, + icmp_type:128, + icmp_code:1, + icmp_seq:2, + icmp_id:ICMP_ID, + icmp_cksum: 0 + ); +dump_icmp_v6_packet(icmpv6); +filter = string("icmp6"); +ret = send_v6packet( icmp, pcap_active:TRUE, pcap_filter:filter, pcap_timeout: 2); +display(ret); diff --git a/rust/examples/forge_tcp_v6.nasl b/rust/examples/forge_tcp_v6.nasl new file mode 100644 index 000000000..1f7a942bc --- /dev/null +++ b/rust/examples/forge_tcp_v6.nasl @@ -0,0 +1,56 @@ +# SPDX-FileCopyrightText: 2023 Greenbone AG +# +# SPDX-License-Identifier: GPL-2.0-or-later WITH x11vnc-openssl-exception + +# This script forges an IPv6 packet with a TCP segment including data. Sends it and captures the packet. +# For running with openvas-nasl and scannerctl, run the following commands respectively +# sudo openvas-nasl -X -d -i $PLUGINSPATH ~/my_nasl/forge_tcp_v6.nasl -t 5858::2 +# sudo target/debug/scannerctl execute script ~/my_nasl/forge_tcp_v6.nasl -t 5858::2 +# +# Set the correct IPv6 addresses and routes in the origin and destination hosts with the right address on each. +# sudo ip addr add 5858::1/64 dev wlp6s0 +# sudo ip -6 route add 5858::1 dev wlp6s0 + +if(description) { + script_oid("1.2.3"); + exit(0); +} + +include("misc_func.inc"); + + +src = "5858::1"; +dst = "5858::2"; +sport = 63321; +dport = 63322; + +filter = string("tcp and src ", src, " and dst ", dst); + +ip6 = forge_ip_v6_packet( ip6_v: 6, # IP6_v, + ip6_p: 6, #IP6_P, + ip6_plen:40, + ip6_hlim:IP6_HLIM, + ip6_src: src, + ip6_dst: dst); + + +tcp = forge_tcp_v6_packet(ip6 : ip6, + th_ack : 0, + th_dport : dport, + th_flags : TH_SYN, + #th_seq : tcp_seq + 1024, + th_sport : sport, + th_x2 : 0, + th_off : 5, + th_win : 1024, + th_urp : 0, + tcp_opt : 3, + tcp_opt_val : 7, + data: "123456", + update_ip_len: TRUE + ); + +dump_tcp_v6_packet(tcp); + +res = send_v6packet(tcp, pcap_filter: filter, pcap_timeout: 20, pcap_active: TRUE); +display(res); diff --git a/rust/src/nasl/builtin/raw_ip/packet_forgery.rs b/rust/src/nasl/builtin/raw_ip/packet_forgery.rs index 1a117291a..11706dab1 100644 --- a/rust/src/nasl/builtin/raw_ip/packet_forgery.rs +++ b/rust/src/nasl/builtin/raw_ip/packet_forgery.rs @@ -26,10 +26,12 @@ use pnet::packet::{ ethernet::EthernetPacket, icmp::*, icmpv6::{ + echo_request::MutableEchoRequestPacket, ndp::{ MutableNeighborAdvertPacket, MutableNeighborSolicitPacket, MutableRouterAdvertPacket, + MutableRouterSolicitPacket, }, - Icmpv6Packet, Icmpv6Types, + Icmpv6Types, }, ip::{IpNextHeaderProtocol, IpNextHeaderProtocols}, ipv4::{checksum, Ipv4Packet, MutableIpv4Packet}, @@ -291,7 +293,7 @@ fn forge_ip_packet(register: &Register, configs: &Context) -> Result Result { +fn set_ip_elements(register: &Register) -> Result { let mut buf = match register.named("ip") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { @@ -381,7 +383,7 @@ fn set_ip_elements(register: &Register, _configs: &Context) -> Result Result { +fn get_ip_element(register: &Register) -> Result { let buf = match register.named("ip") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { @@ -469,7 +471,7 @@ fn dump_ip_packet(register: &Register) -> Result { /// - length: is the length of the option data /// - value: is the option data #[nasl_function] -fn insert_ip_options(register: &Register, _configs: &Context) -> Result { +fn insert_ip_options(register: &Register) -> Result { let buf = match register.named("ip") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { @@ -563,7 +565,7 @@ fn insert_ip_options(register: &Register, _configs: &Context) -> Result Result { +fn forge_tcp_packet(register: &Register) -> Result { let mut ip_buf = match register.named("ip") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { @@ -678,7 +680,7 @@ fn forge_tcp_packet(register: &Register, _configs: &Context) -> Result Result { +fn get_tcp_element(register: &Register) -> Result { let buf = match register.named("tcp") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { @@ -722,7 +724,7 @@ fn get_tcp_element(register: &Register, _configs: &Context) -> Result Result { +fn get_tcp_option(register: &Register) -> Result { let buf = match register.named("tcp") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { @@ -797,7 +799,7 @@ fn get_tcp_option(register: &Register, _configs: &Context) -> Result Result { +fn set_tcp_elements(register: &Register) -> Result { let buf = match register.named("tcp") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { @@ -934,7 +936,7 @@ fn set_tcp_elements(register: &Register, _configs: &Context) -> Result Result { +fn insert_tcp_options(register: &Register) -> Result { let buf = match register.named("tcp") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { @@ -1112,7 +1114,6 @@ fn insert_tcp_options(register: &Register, _configs: &Context) -> Result String { fn print_tcp_packet(tcp: &Option) -> Result<(), FnError> { match tcp { Some(pkt) => { - let th_flags = format_flags(&pkt); + let th_flags = format_flags(pkt); println!("------\n"); println!("\tth_sport = {}", pkt.get_source()); println!("\tth_dport = {}", pkt.get_destination()); @@ -1167,12 +1168,10 @@ fn print_tcp_packet(tcp: &Option) -> Result<(), FnError> println!("\tth_sum = {}", pkt.get_checksum()); println!("\tth_urp = {}", pkt.get_urgent_ptr()); println!("\tTCP Options:"); - display_opts(&pkt); + display_opts(pkt); Ok(()) } - None => Err(ArgumentError::WrongArgument( - "Invalid TPC packet".to_string(), - ).into()), + None => Err(ArgumentError::WrongArgument("Invalid TPC packet".to_string()).into()), } } @@ -1192,9 +1191,9 @@ fn dump_tcp_packet(register: &Register) -> Result { let ip = match packet::ipv4::Ipv4Packet::new(data) { Some(ip) => ip, None => { - return Err(ArgumentError::WrongArgument( - "Invalid TCP packet".to_string(), - ).into()); + return Err( + ArgumentError::WrongArgument("Invalid TCP packet".to_string()).into(), + ); } }; let pkt = packet::tcp::TcpPacket::new(ip.payload()); @@ -1202,9 +1201,7 @@ fn dump_tcp_packet(register: &Register) -> Result { display_packet(data); } _ => { - return Err(ArgumentError::WrongArgument( - "Invalid ip packet".to_string(), - ).into()); + return Err(ArgumentError::WrongArgument("Invalid ip packet".to_string()).into()); } } } @@ -1224,7 +1221,7 @@ fn dump_tcp_packet(register: &Register) -> Result { /// Returns the modified IP datagram or NULL on error. #[nasl_function] -fn forge_udp_packet(register: &Register, _configs: &Context) -> Result { +fn forge_udp_packet(register: &Register) -> Result { let mut ip_buf = match register.named("ip") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => return Err(FnError::missing_argument("ip")), @@ -1303,7 +1300,7 @@ fn forge_udp_packet(register: &Register, _configs: &Context) -> Result Result { +fn set_udp_elements(register: &Register) -> Result { let buf = match register.named("udp") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { @@ -1403,10 +1400,7 @@ fn set_udp_elements(register: &Register, _configs: &Context) -> Result, - data: &[u8], -) -> Result { +fn dump_udp(datagram: &Option, data: &[u8]) -> Result { match datagram { Some(pkt) => { println!("------\n"); @@ -1418,8 +1412,7 @@ fn dump_udp( display_packet(data); } None => { - return Err(ArgumentError::WrongArgument( - "Invalid UDP packet".to_string()).into()); + return Err(ArgumentError::WrongArgument("Invalid UDP packet".to_string()).into()); } } Ok(NaslValue::Null) @@ -1487,7 +1480,7 @@ fn get_udp_element_from_datagram( /// - uh_sum /// - data #[nasl_function] -fn get_udp_element(register: &Register, _configs: &Context) -> Result { +fn get_udp_element(register: &Register) -> Result { let buf = match register.named("udp") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { @@ -1523,7 +1516,7 @@ fn get_udp_element(register: &Register, _configs: &Context) -> Result Result { +fn forge_icmp_packet(register: &Register) -> Result { let mut ip_buf = match register.named("ip") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { @@ -1615,7 +1608,7 @@ fn forge_icmp_packet(register: &Register, _configs: &Context) -> Result Result { +fn get_icmp_element(register: &Register) -> Result { let buf = match register.named("icmp") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { @@ -1801,7 +1794,7 @@ pub mod igmp { /// - type: IGMP type. 0 by default. /// - update_ip_len: If this flag is set, NASL will recompute the size field of the IP datagram. Default: True. #[nasl_function] -fn forge_igmp_packet(register: &Register, _configs: &Context) -> Result { +fn forge_igmp_packet(register: &Register) -> Result { let mut ip_buf = match register.named("ip") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { @@ -1929,7 +1922,7 @@ fn nasl_tcp_ping(register: &Register, configs: &Context) -> Result Result Result Result { -// nasl_send_capture(register, configs) +// nasl_send_capture(register, configs) //} /// Read the next packet. @@ -2276,16 +2269,14 @@ fn nasl_send_capture(register: &Register, configs: &Context) -> Result Result { +fn forge_ip_v6_packet(register: &Register, configs: &Context) -> Result { let dst_addr = get_host_ip(configs)?; if dst_addr.is_ipv4() { return Err(FnError::wrong_unnamed_argument( "IPv6", - "forge_ip_v6_packet: No valid dst_addr could be determined via call to get_host_ip()")); + "forge_ip_v6_packet: No valid dst_addr could be determined via call to get_host_ip()", + )); } let data = match register.named("data") { @@ -2297,9 +2288,8 @@ fn forge_ip_v6_packet( let total_length = 40 + data.len(); let mut buf = vec![0; total_length]; - let mut pkt = packet::ipv6::MutableIpv6Packet::new(&mut buf).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; + let mut pkt = packet::ipv6::MutableIpv6Packet::new(&mut buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; pkt.set_payload_length(data.len() as u16); @@ -2345,9 +2335,8 @@ fn forge_ip_v6_packet( } Err(e) => { return Err( - ArgumentError::WrongArgument(format!( - "Invalid ip_src: {}", e - )).into()); + ArgumentError::WrongArgument(format!("Invalid ip_src: {}", e)).into(), + ); } }; x.to_string() @@ -2362,10 +2351,9 @@ fn forge_ip_v6_packet( pkt.set_destination(ip); } Err(e) => { - return Err(ArgumentError::WrongArgument(format!( - "Invalid ip_dst: {}", - e - )).into()); + return Err( + ArgumentError::WrongArgument(format!("Invalid ip_dst: {}", e)).into(), + ); } }; x.to_string() @@ -2376,10 +2364,7 @@ fn forge_ip_v6_packet( pkt.set_destination(ip); } Err(e) => { - return Err(ArgumentError::WrongArgument(format!( - "Invalid ip: {}", - e - )).into()); + return Err(ArgumentError::WrongArgument(format!("Invalid ip: {}", e)).into()); } }; dst_addr.to_string() @@ -2406,19 +2391,16 @@ fn forge_ip_v6_packet( /// - ip6_src /// - ip6_dst #[nasl_function] -fn get_ip_v6_element( - register: &Register, -) -> Result { +fn get_ip_v6_element(register: &Register) -> Result { let buf = match register.named("ip6") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { - return Err(FnError::missing_argument("ip6").into()); + return Err(FnError::missing_argument("ip6")); } }; - let pkt = packet::ipv6::Ipv6Packet::new(&buf).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; + let pkt = packet::ipv6::Ipv6Packet::new(&buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; match register.named("element") { Some(ContextType::Value(NaslValue::String(e))) => match e.as_str() { @@ -2431,11 +2413,9 @@ fn get_ip_v6_element( ))), "ip6_src" => Ok(NaslValue::String(pkt.get_source().to_string())), "ip6_dst" => Ok(NaslValue::String(pkt.get_destination().to_string())), - _ => Err(ArgumentError::WrongArgument( - "Invalid element".to_string(), - ).into()), + _ => Err(ArgumentError::WrongArgument("Invalid element".to_string()).into()), }, - _ => Err(FnError::missing_argument("element").into()), + _ => Err(FnError::missing_argument("element")), } } @@ -2449,20 +2429,16 @@ fn get_ip_v6_element( /// - ip6_hlim /// - ip6_src #[nasl_function] -fn set_ip_v6_elements( - register: &Register, -) -> Result { +fn set_ip_v6_elements(register: &Register) -> Result { let mut buf = match register.named("ip6") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { - return Err(FnError::missing_argument("ip").into()); + return Err(FnError::missing_argument("ip")); } }; - let mut pkt = packet::ipv6::MutableIpv6Packet::new(&mut buf).ok_or_else(|| { - error( - "No possible to create a packet from buffer".to_string()) - })?; + let mut pkt = packet::ipv6::MutableIpv6Packet::new(&mut buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; let ip6_plen = match register.named("ip6_plen") { Some(ContextType::Value(NaslValue::Number(x))) => *x as u16, @@ -2482,10 +2458,7 @@ fn set_ip_v6_elements( pkt.set_source(ip); } Err(e) => { - return Err(ArgumentError::WrongArgument(format!( - "Invalid ip_src: {}", - e - )).into()); + return Err(ArgumentError::WrongArgument(format!("Invalid ip_src: {}", e)).into()); } }; }; @@ -2504,9 +2477,7 @@ fn set_ip_v6_elements( /// Return the modified datagram. /// #[nasl_function] -fn insert_ip_v6_options( - register: &Register, -) -> Result { +fn insert_ip_v6_options(register: &Register) -> Result { let buf = match register.named("ip6") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { @@ -2574,9 +2545,8 @@ fn insert_ip_v6_options( opt_buf.len(), )?; - let mut new_pkt = MutableIpv6Packet::new(&mut new_buf).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; + let mut new_pkt = MutableIpv6Packet::new(&mut new_buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; new_pkt.set_payload_length((hl / 4) as u16); Ok(NaslValue::Data(new_pkt.packet().to_vec())) @@ -2590,16 +2560,15 @@ fn dump_ip_v6_packet(register: &Register) -> Result { return Err(ArgumentError::MissingPositionals { expected: 1, got: 0, - }.into()); + } + .into()); } for ip in positional.iter() { match ip { NaslValue::Data(data) => { let pkt = packet::ipv6::Ipv6Packet::new(data).ok_or_else(|| { - error( - "No possible to create a packet from buffer".to_string(), - ) + error("No possible to create a packet from buffer".to_string()) })?; println!("------\n"); println!("\tip6_v : {:?}", pkt.get_version()); @@ -2627,15 +2596,12 @@ fn dump_ip_v6_packet(register: &Register) -> Result { ), }; - println!("\tip6_src : {}", pkt.get_source().to_string()); + println!("\tip6_src : {:?}", pkt.get_source().to_string()); println!("\tip6_dst : {:?}", pkt.get_destination().to_string()); display_packet(data); } _ => { - return Err(FnError::wrong_unnamed_argument( - "Data", - "Invalid ip packet", - )); + return Err(FnError::wrong_unnamed_argument("Data", "Invalid ip packet")); } } } @@ -2663,9 +2629,7 @@ fn dump_ip_v6_packet(register: &Register) -> Result { /// /// The modified IP datagram or NULL on error. #[nasl_function] -fn forge_tcp_v6_packet( - register: &Register, -) -> Result { +fn forge_tcp_v6_packet(register: &Register) -> Result { let mut ip_buf = match register.named("ip6") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { @@ -2684,9 +2648,8 @@ fn forge_tcp_v6_packet( //tcp length + data length let total_length = 20 + data.len(); let mut buf = vec![0; total_length]; - let mut tcp_seg = packet::tcp::MutableTcpPacket::new(&mut buf).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; + let mut tcp_seg = packet::tcp::MutableTcpPacket::new(&mut buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; if !data.is_empty() { tcp_seg.set_payload(&data); @@ -2733,26 +2696,22 @@ fn forge_tcp_v6_packet( let chksum = match register.named("th_sum") { Some(ContextType::Value(NaslValue::Number(x))) if *x != 0 => (*x as u16).to_be(), _ => { - let pkt = packet::ipv6::Ipv6Packet::new(&ip_buf).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; - let tcp_aux = TcpPacket::new(tcp_seg.packet()).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; + let pkt = packet::ipv6::Ipv6Packet::new(&ip_buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; + let tcp_aux = TcpPacket::new(tcp_seg.packet()) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; pnet::packet::tcp::ipv6_checksum(&tcp_aux, &pkt.get_source(), &pkt.get_destination()) } }; - let mut tcp_seg = packet::tcp::MutableTcpPacket::new(&mut buf).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; + let mut tcp_seg = packet::tcp::MutableTcpPacket::new(&mut buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; tcp_seg.set_checksum(chksum); ip_buf.append(&mut buf); let l = ip_buf.len(); - let mut pkt = packet::ipv6::MutableIpv6Packet::new(&mut ip_buf).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; + let mut pkt = packet::ipv6::MutableIpv6Packet::new(&mut ip_buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; pkt.set_payload_length(l as u16); match register.named("update_ip_len") { Some(ContextType::Value(NaslValue::Boolean(l))) if !(*l) => { @@ -2783,9 +2742,7 @@ fn forge_tcp_v6_packet( /// /// Returns an TCP element from a IP datagram. #[nasl_function] -fn get_tcp_v6_element( - register: &Register, -) -> Result { +fn get_tcp_v6_element(register: &Register) -> Result { let buf = match register.named("tcp") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { @@ -2793,13 +2750,11 @@ fn get_tcp_v6_element( } }; - let ip = packet::ipv6::Ipv6Packet::new(&buf).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; + let ip = packet::ipv6::Ipv6Packet::new(&buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; - let tcp = packet::tcp::TcpPacket::new(ip.payload()).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; + let tcp = packet::tcp::TcpPacket::new(ip.payload()) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; match register.named("element") { Some(ContextType::Value(NaslValue::String(el))) => match el.as_str() { @@ -2831,10 +2786,8 @@ fn get_tcp_v6_element( /// - 8: TCPOPT_TIMESTAMP, 8 bytes value for timestamp and echo timestamp, 4 bytes each one. /// /// The returned option depends on the given *option* parameter. It is either an int for option 2, 3 and 4 or an array containing the two values for option 8. -fn get_tcp_v6_option( - register: &Register, - _configs: &Context, -) -> Result { +#[nasl_function] +fn get_tcp_v6_option(register: &Register, _configs: &Context) -> Result { let buf = match register.named("tcp") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { @@ -2842,12 +2795,10 @@ fn get_tcp_v6_option( } }; - let ip = packet::ipv6::Ipv6Packet::new(&buf).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; - let tcp = packet::tcp::TcpPacket::new(ip.payload()).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; + let ip = packet::ipv6::Ipv6Packet::new(&buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; + let tcp = packet::tcp::TcpPacket::new(ip.payload()) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; let mut max_seg: i64 = 0; let mut window: i64 = 0; @@ -2889,9 +2840,7 @@ fn get_tcp_v6_option( 3 => Ok(NaslValue::Number(window)), 4 => Ok(NaslValue::Number(sack_permitted)), 8 => Ok(NaslValue::Array(timestamps)), - _ => Err(ArgumentError::WrongArgument( - "Invalid option".to_string(), - ).into()), + _ => Err(ArgumentError::WrongArgument("Invalid option".to_string()).into()), }, _ => Err(FnError::missing_argument("option")), } @@ -2912,10 +2861,8 @@ fn get_tcp_v6_option( /// - th_win: is the TCP window size. NASL will convert it into network order if necessary. 0 by default. /// - th_x2: is a reserved field and should probably be left unchanged. 0 by default. /// - update_ip_len: is a flag (TRUE by default). If set, NASL will recompute the size field of the IP datagram. -fn set_tcp_v6_elements( - register: &Register, - _configs: &Context, -) -> Result { +#[nasl_function] +fn set_tcp_v6_elements(register: &Register, _configs: &Context) -> Result { let buf = match register.named("tcp") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { @@ -2923,9 +2870,8 @@ fn set_tcp_v6_elements( } }; - let ip = packet::ipv6::Ipv6Packet::new(&buf).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; + let ip = packet::ipv6::Ipv6Packet::new(&buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; let iph_len = ip.get_payload_length() as usize * 4; // the header length is given in 32-bits words let data = match register.named("data") { @@ -2946,9 +2892,8 @@ fn set_tcp_v6_elements( new_buf = vec![0u8; tcp_total_length]; //new_buf[..20].copy_from_slice(&ori_tcp_buf[..20]); safe_copy_from_slice(&mut new_buf[..], 0, 20, &ori_tcp_buf, 0, 20)?; - ori_tcp = packet::tcp::MutableTcpPacket::new(&mut new_buf).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; + ori_tcp = packet::tcp::MutableTcpPacket::new(&mut new_buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; ori_tcp.set_payload(&data); } else { // Copy the original tcp buffer into the new buffer @@ -2963,9 +2908,8 @@ fn set_tcp_v6_elements( 0, ori_tcp_buf.len(), )?; - ori_tcp = packet::tcp::MutableTcpPacket::new(&mut new_buf).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; + ori_tcp = packet::tcp::MutableTcpPacket::new(&mut new_buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; } if let Some(ContextType::Value(NaslValue::Number(x))) = register.named("th_sport") { @@ -3001,12 +2945,10 @@ fn set_tcp_v6_elements( let chksum = match register.named("th_sum") { Some(ContextType::Value(NaslValue::Number(x))) if *x != 0 => (*x as u16).to_be(), _ => { - let pkt = packet::ipv4::Ipv4Packet::new(&buf).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; - let tcp_aux = TcpPacket::new(ori_tcp.packet()).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; + let pkt = packet::ipv4::Ipv4Packet::new(&buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; + let tcp_aux = TcpPacket::new(ori_tcp.packet()) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; pnet::packet::tcp::ipv4_checksum(&tcp_aux, &pkt.get_source(), &pkt.get_destination()) } }; @@ -3025,9 +2967,8 @@ fn set_tcp_v6_elements( new_ip_buf.append(&mut fin_tcp_buf.to_vec()); let l = new_ip_buf.len(); - let mut pkt = packet::ipv6::MutableIpv6Packet::new(&mut new_ip_buf).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; + let mut pkt = packet::ipv6::MutableIpv6Packet::new(&mut new_ip_buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; // pnet will panic if the total length set in the ip datagram field does not much with the total length. // Therefore, the total length is set to the right one before setting the payload. @@ -3053,22 +2994,17 @@ fn set_tcp_v6_elements( /// - 3: TCPOPT_WINDOW, with values between 0 and 14 /// - 4: TCPOPT_SACK_PERMITTED, no value required. /// - 8: TCPOPT_TIMESTAMP, 8 bytes value for timestamp and echo timestamp, 4 bytes each one. -fn insert_tcp_v6_options( - register: &Register, - _configs: &Context, -) -> Result { +#[nasl_function] +fn insert_tcp_v6_options(register: &Register, _configs: &Context) -> Result { let buf = match register.named("tcp") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { - return Err(error( - "insert_tcp_options: missing field".to_string(), - )); + return Err(error("insert_tcp_options: missing field".to_string())); } }; - let ip = packet::ipv4::Ipv4Packet::new(&buf).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; + let ip = packet::ipv4::Ipv4Packet::new(&buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; let iph_len = ip.get_header_length() as usize * 4; // the header length is given in 32-bits words let ori_tcp_buf = <&[u8]>::clone(&ip.payload()).to_owned(); let mut ori_tcp: packet::tcp::MutableTcpPacket; @@ -3079,9 +3015,8 @@ fn insert_tcp_v6_options( Some(ContextType::Value(NaslValue::String(d))) => d.as_bytes().to_vec(), Some(ContextType::Value(NaslValue::Number(d))) => d.to_be_bytes().to_vec(), _ => { - let tcp = TcpPacket::new(&ori_tcp_buf).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; + let tcp = TcpPacket::new(&ori_tcp_buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; tcp.payload().to_vec() } }; @@ -3107,7 +3042,8 @@ fn insert_tcp_v6_options( } else { return Err(ArgumentError::WrongArgument( "Invalid value for tcp option TCPOPT_MAXSEG".to_string(), - ).into()); + ) + .into()); } } Some(NaslValue::Number(o)) if *o == 3 => { @@ -3118,7 +3054,8 @@ fn insert_tcp_v6_options( } else { return Err(ArgumentError::WrongArgument( "Invalid value for tcp option TCPOPT_WINDOW".to_string(), - ).into()); + ) + .into()); } } @@ -3136,19 +3073,22 @@ fn insert_tcp_v6_options( } else { return Err(ArgumentError::WrongArgument( "Invalid value for tcp option TCPOPT_TIMESTAMP".to_string(), - ).into()); + ) + .into()); } } else { return Err(ArgumentError::WrongArgument( "Invalid value for tcp option TCPOPT_TIMESTAMP".to_string(), - ).into()); + ) + .into()); } } None => break, _ => { return Err(ArgumentError::WrongArgument( "insert_tcp_options: invalid tcp option".to_string(), - ).into()); + ) + .into()); } } } @@ -3173,9 +3113,8 @@ fn insert_tcp_v6_options( //new_buf[..20].copy_from_slice(&ori_tcp_buf[..20]); safe_copy_from_slice(&mut new_buf[..], 0, 20, &ori_tcp_buf, 0, 20)?; - ori_tcp = packet::tcp::MutableTcpPacket::new(&mut new_buf).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; + ori_tcp = packet::tcp::MutableTcpPacket::new(&mut new_buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; // At this point, opts len is a 4bytes multiple and the ofset is expressed in 32bits words ori_tcp.set_data_offset(5 + opts_len as u8 / 4); @@ -3190,12 +3129,10 @@ fn insert_tcp_v6_options( let chksum = match register.named("th_sum") { Some(ContextType::Value(NaslValue::Number(x))) if *x != 0 => (*x as u16).to_be(), _ => { - let pkt = packet::ipv4::Ipv4Packet::new(&buf).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; - let tcp_aux = TcpPacket::new(ori_tcp.packet()).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; + let pkt = packet::ipv4::Ipv4Packet::new(&buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; + let tcp_aux = TcpPacket::new(ori_tcp.packet()) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; pnet::packet::tcp::ipv4_checksum(&tcp_aux, &pkt.get_source(), &pkt.get_destination()) } }; @@ -3213,9 +3150,8 @@ fn insert_tcp_v6_options( new_ip_buf.append(&mut fin_tcp_buf.to_vec()); let l = new_ip_buf.len(); - let mut pkt = packet::ipv4::MutableIpv4Packet::new(&mut new_ip_buf).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; + let mut pkt = packet::ipv4::MutableIpv4Packet::new(&mut new_ip_buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; // pnet will panic if the total length set in the ip datagram field does not much with the total length. // Therefore, the total length is set to the right one before setting the payload. @@ -3238,7 +3174,8 @@ fn insert_tcp_v6_options( } /// Receive a list of IPv6 datagrams and print their TCP part in a readable format in the screen. -fn dump_tcp_v6_packet(register: &Register, _: &Context) -> Result { +#[nasl_function] +fn dump_tcp_v6_packet(register: &Register) -> Result { let positional = register.positional(); if positional.is_empty() { return Err(error( @@ -3264,10 +3201,7 @@ fn dump_tcp_v6_packet(register: &Register, _: &Context) -> Result { - return Err(FnError::wrong_unnamed_argument( - "Data", - "Invalid ip packet", - )); + return Err(FnError::wrong_unnamed_argument("Data", "Invalid ip packet")); } } } @@ -3287,7 +3221,8 @@ fn dump_tcp_v6_packet(register: &Register, _: &Context) -> Result Result { +#[nasl_function] +fn forge_udp_v6_packet(register: &Register) -> Result { let mut ip_buf = match register.named("ip6") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => return Err(FnError::missing_argument("ip6")), @@ -3304,9 +3239,8 @@ fn forge_udp_v6_packet(register: &Register, _: &Context) -> Result Result (*x as u16).to_be(), _ => { - let pkt = packet::ipv6::Ipv6Packet::new(&ip_buf).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; - let udp_aux = UdpPacket::new(udp_datagram.packet()).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; + let pkt = packet::ipv6::Ipv6Packet::new(&ip_buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; + let udp_aux = UdpPacket::new(udp_datagram.packet()) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; pnet::packet::udp::ipv6_checksum(&udp_aux, &pkt.get_source(), &pkt.get_destination()) } }; - let mut udp_datagram = packet::udp::MutableUdpPacket::new(&mut buf).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; + let mut udp_datagram = packet::udp::MutableUdpPacket::new(&mut buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; udp_datagram.set_checksum(chksum); ip_buf.append(&mut buf); let l = ip_buf.len(); - let mut pkt = packet::ipv6::MutableIpv6Packet::new(&mut ip_buf).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; + let mut pkt = packet::ipv6::MutableIpv6Packet::new(&mut ip_buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; pkt.set_payload_length(l as u16); match register.named("update_ip_len") { Some(ContextType::Value(NaslValue::Boolean(l))) if !(*l) => { @@ -3370,10 +3300,8 @@ fn forge_udp_v6_packet(register: &Register, _: &Context) -> Result Result { +#[nasl_function] +fn get_udp_v6_element(register: &Register, _configs: &Context) -> Result { let buf = match register.named("udp") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { @@ -3381,12 +3309,10 @@ fn get_udp_v6_element( } }; - let ip = packet::ipv6::Ipv6Packet::new(&buf).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; - let udp = packet::udp::UdpPacket::new(ip.payload()).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; + let ip = packet::ipv6::Ipv6Packet::new(&buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; + let udp = packet::udp::UdpPacket::new(ip.payload()) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; get_udp_element_from_datagram(udp, register) } @@ -3399,10 +3325,8 @@ fn get_udp_v6_element( /// - uh_sport: is the source port. NASL will convert it into network order if necessary. 0 by default. /// - uh_sum: is the UDP checksum. Although it is not compulsory, the right value is computed by default. /// - uh_ulen: is the data length. By default it is set to the length the data argument plus the size of the UDP header. -fn set_udp_v6_elements( - register: &Register, - _configs: &Context, -) -> Result { +#[nasl_function] +fn set_udp_v6_elements(register: &Register) -> Result { let buf = match register.named("udp") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { @@ -3410,9 +3334,8 @@ fn set_udp_v6_elements( } }; - let ip = packet::ipv6::Ipv6Packet::new(&buf).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; + let ip = packet::ipv6::Ipv6Packet::new(&buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; let iph_len = ip.get_payload_length() as usize * 4; // the header length is given in 32-bits words let data = match register.named("data") { @@ -3434,9 +3357,8 @@ fn set_udp_v6_elements( //new_buf[..8].copy_from_slice(&ori_udp_buf[..8]); safe_copy_from_slice(&mut new_buf[..], 0, 8, &ori_udp_buf, 0, 8)?; - ori_udp = packet::udp::MutableUdpPacket::new(&mut new_buf).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; + ori_udp = packet::udp::MutableUdpPacket::new(&mut new_buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; ori_udp.set_payload(&data); } else { // Copy the original udp buffer into the new buffer @@ -3451,9 +3373,8 @@ fn set_udp_v6_elements( 0, ori_udp_buf.len(), )?; - ori_udp = packet::udp::MutableUdpPacket::new(&mut new_buf).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; + ori_udp = packet::udp::MutableUdpPacket::new(&mut new_buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; } if let Some(ContextType::Value(NaslValue::Number(x))) = register.named("uh_sport") { @@ -3471,12 +3392,10 @@ fn set_udp_v6_elements( let chksum = match register.named("uh_sum") { Some(ContextType::Value(NaslValue::Number(x))) if *x != 0 => (*x as u16).to_be(), _ => { - let pkt = packet::ipv6::Ipv6Packet::new(&buf).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; - let udp_aux = UdpPacket::new(ori_udp.packet()).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; + let pkt = packet::ipv6::Ipv6Packet::new(&buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; + let udp_aux = UdpPacket::new(ori_udp.packet()) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; pnet::packet::udp::ipv6_checksum(&udp_aux, &pkt.get_source(), &pkt.get_destination()) } }; @@ -3494,9 +3413,8 @@ fn set_udp_v6_elements( new_ip_buf.append(&mut fin_udp_buf.to_vec()); let l = new_ip_buf.len(); - let mut pkt = packet::ipv6::MutableIpv6Packet::new(&mut new_ip_buf).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; + let mut pkt = packet::ipv6::MutableIpv6Packet::new(&mut new_ip_buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; pkt.set_payload_length(l as u16); pkt.set_payload(&fin_udp_buf); @@ -3505,7 +3423,8 @@ fn set_udp_v6_elements( } /// Receive a list of IPv4 datagrams and print their UDP part in a readable format in the screen. -fn dump_udp_v6_packet(register: &Register, _: &Context) -> Result { +#[nasl_function] +fn dump_udp_v6_packet(register: &Register) -> Result { let positional = register.positional(); if positional.is_empty() { return Err(error( @@ -3519,9 +3438,9 @@ fn dump_udp_v6_packet(register: &Register, _: &Context) -> Result ip, None => { - return Err(ArgumentError::WrongArgument( - "Invalid UDP packet".to_string(), - ).into()); + return Err( + ArgumentError::WrongArgument("Invalid UDP packet".to_string()).into(), + ); } }; @@ -3529,9 +3448,7 @@ fn dump_udp_v6_packet(register: &Register, _: &Context) -> Result { - return Err(ArgumentError::WrongArgument( - "Invalid UDP packet".to_string(), - ).into()); + return Err(ArgumentError::WrongArgument("Invalid UDP packet".to_string()).into()); } } } @@ -3555,27 +3472,24 @@ fn dump_udp_v6_packet(register: &Register, _: &Context) -> Result Result { +fn forge_icmp_v6_packet(register: &Register) -> Result { let mut ip_buf = match register.named("ip6") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { - return Err(FnError::missing_argument("icmp6")); + return Err(FnError::missing_argument("ip6")); } }; let original_ip_len = ip_buf.len(); // to extract the max hop limit, ip6_dst. - let pkt_aux = packet::ipv6::Ipv6Packet::new(&ip_buf).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; + let pkt_aux = packet::ipv6::Ipv6Packet::new(&ip_buf) + .ok_or_else(|| error("No possible to create a ipv6 packet from buffer".to_string()))?; - let data = match register.named("data") { + let data: Vec = match register.named("data") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), Some(ContextType::Value(NaslValue::String(d))) => d.as_bytes().to_vec(), Some(ContextType::Value(NaslValue::Number(d))) => d.to_be_bytes().to_vec(), - _ => Vec::::new(), + _ => vec![], }; let icmp_code = match register.named("icmp_code") { @@ -3590,29 +3504,24 @@ fn forge_icmp_v6_packet( let icmp_type = match register.named("icmp_type") { Some(ContextType::Value(NaslValue::Number(x))) => { if *x < 0 || *x > 255 { - return Err(error(format!( - "forge_icmp_v6_packet: illegal type {}", - x - ))); + return Err(error(format!("forge_icmp_v6_packet: illegal type {}", x))); } packet::icmpv6::Icmpv6Type::new(*x as u8) } _ => { - return Err(error( - "forge_icmp_v6_packet: illegal type".to_string(), - )); + return Err(error("forge_icmp_v6_packet: illegal type".to_string())); } }; match icmp_type { Icmpv6Types::EchoRequest => { - icmp_pkt_size = 8; - total_length = 8 + data.len(); + icmp_pkt_size = MutableEchoRequestPacket::minimum_packet_size(); + total_length = icmp_pkt_size + data.len(); icmp_buf = vec![0; total_length]; let mut icmp_pkt = packet::icmpv6::MutableIcmpv6Packet::new(&mut icmp_buf).ok_or_else(|| { error( - "No possible to create a packet from buffer".to_string(), + "EchoRequest: No possible to create an icmp packet from buffer".to_string(), ) })?; @@ -3635,14 +3544,12 @@ fn forge_icmp_v6_packet( } } Icmpv6Types::RouterSolicit => { - icmp_pkt_size = 8; + icmp_pkt_size = MutableRouterSolicitPacket::minimum_packet_size(); total_length = icmp_pkt_size + data.len(); icmp_buf = vec![0; total_length]; let mut icmp_pkt = packet::icmpv6::ndp::MutableRouterSolicitPacket::new(&mut icmp_buf) .ok_or_else(|| { - error( - "No possible to create a packet from buffer".to_string(), - ) + error("RouterSolicit: No possible to create a packet from buffer".to_string()) })?; icmp_pkt.set_icmpv6_type(icmp_type); @@ -3658,7 +3565,7 @@ fn forge_icmp_v6_packet( total_length = icmp_pkt_size + data.len(); icmp_buf = vec![0; total_length]; let mut icmp_pkt = MutableRouterAdvertPacket::new(&mut icmp_buf).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) + error("RouterAdvert: No possible to create a packet from buffer".to_string()) })?; icmp_pkt.set_icmpv6_type(icmp_type); @@ -3697,9 +3604,7 @@ fn forge_icmp_v6_packet( icmp_buf = vec![0; total_length]; let mut icmp_pkt = MutableNeighborSolicitPacket::new(&mut icmp_buf).ok_or_else(|| { - error( - "No possible to create a packet from buffer".to_string(), - ) + error("NeighborSolicit: No possible to create a packet from buffer".to_string()) })?; icmp_pkt.set_icmpv6_type(icmp_type); @@ -3724,9 +3629,7 @@ fn forge_icmp_v6_packet( icmp_buf = vec![0; total_length]; let mut icmp_pkt = MutableNeighborAdvertPacket::new(&mut icmp_buf).ok_or_else(|| { - error( - "No possible to create a packet from buffer".to_string(), - ) + error("NeighborAdvert: No possible to create a packet from buffer".to_string()) })?; icmp_pkt.set_icmpv6_type(icmp_type); @@ -3755,9 +3658,7 @@ fn forge_icmp_v6_packet( icmp_buf = vec![0; total_length]; let mut icmp_pkt = packet::icmpv6::MutableIcmpv6Packet::new(&mut icmp_buf).ok_or_else(|| { - error( - "No possible to create a packet from buffer".to_string(), - ) + error("No possible to create a icmp packet from buffer".to_string()) })?; icmp_pkt.set_icmpv6_type(icmp_type); @@ -3787,27 +3688,40 @@ fn forge_icmp_v6_packet( )?; } - ip_buf.append(&mut icmp_buf); - let l = ip_buf.len(); - let mut pkt = packet::ipv6::MutableIpv6Packet::new(&mut ip_buf).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; - - let chksum = match register.named("icmp_cksum") { - Some(ContextType::Value(NaslValue::Number(x))) if *x != 0 => (*x as u16).to_be(), - _ => { - let icmp_aux = Icmpv6Packet::new(&icmp_buf).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; - pnet::packet::icmpv6::checksum(&icmp_aux, &pkt.get_source(), &pkt.get_destination()) - } - }; + let chksum: u16; + { + let mut ip_buf_aux = ip_buf.clone(); + ip_buf_aux.append(&mut icmp_buf.clone()); + chksum = match register.named("icmp_cksum") { + Some(ContextType::Value(NaslValue::Number(x))) if *x != 0 => (*x as u16).to_be(), + _ => { + let pkt = packet::ipv6::Ipv6Packet::new(&ip_buf_aux).ok_or_else(|| { + error("No possible to create a packet from buffer".to_string()) + })?; + let icmp_aux = packet::icmpv6::Icmpv6Packet::new(&icmp_buf).ok_or_else(|| { + error( + "No possible to create a packet from buffer for chksum calculation" + .to_string(), + ) + })?; + pnet::packet::icmpv6::checksum(&icmp_aux, &pkt.get_source(), &pkt.get_destination()) + } + }; + } + dbg!(&chksum); let mut icmp_pkt = packet::icmpv6::MutableIcmpv6Packet::new(&mut icmp_buf).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) + error( + "No possible to create a packet from buffer while setting the checksum".to_string(), + ) })?; + icmp_pkt.set_checksum(chksum); + ip_buf.append(&mut icmp_buf.clone()); + let l = icmp_buf.len(); + let mut pkt = packet::ipv6::MutableIpv6Packet::new(&mut ip_buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; pkt.set_payload_length(l as u16); match register.named("update_ip_len") { @@ -3832,9 +3746,7 @@ fn forge_icmp_v6_packet( /// - icmp_chsum /// - icmp_data #[nasl_function] -fn get_icmp_v6_element( - register: &Register, -) -> Result { +fn get_icmp_v6_element(register: &Register) -> Result { let buf = match register.named("icmp") { Some(ContextType::Value(NaslValue::Data(d))) => d.clone(), _ => { @@ -3842,12 +3754,10 @@ fn get_icmp_v6_element( } }; - let ip = packet::ipv6::Ipv6Packet::new(&buf).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; - let icmp = packet::icmpv6::Icmpv6Packet::new(ip.payload()).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; + let ip = packet::ipv6::Ipv6Packet::new(&buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; + let icmp = packet::icmpv6::Icmpv6Packet::new(ip.payload()) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; match register.named("element") { Some(ContextType::Value(NaslValue::String(el))) => match el.as_str() { @@ -3906,12 +3816,10 @@ fn dump_icmp_v6_packet(register: &Register) -> Result { } }; - let ip = packet::ipv6::Ipv6Packet::new(&buf).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; - let icmp = packet::icmp::IcmpPacket::new(ip.payload()).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; + let ip = packet::ipv6::Ipv6Packet::new(&buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; + let icmp = packet::icmp::IcmpPacket::new(ip.payload()) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; let mut icmp_seq = 0; if icmp.payload().len() >= 4 { @@ -3950,8 +3858,7 @@ fn dump_icmp_v6_packet(register: &Register) -> Result { } #[nasl_function] -fn forge_igmp_v6_packet( -) -> Result { +fn forge_igmp_v6_packet() -> Result { // TODO: not implemented. Multicast management on IPv6 networks is handled by Multicast // Listener Discovery (MLD) which is a part of ICMPv6 in contrast to IGMP's bare IP encapsulation. // Currently, pnet does not support MDL. @@ -3963,10 +3870,7 @@ fn forge_igmp_v6_packet( /// Its argument is: /// - port: port for the ping #[nasl_function] -fn nasl_tcp_v6_ping( - register: &Register, - configs: &Context -) -> Result { +fn nasl_tcp_v6_ping(register: &Register, configs: &Context) -> Result { let rnd_tcp_port = || -> u16 { (random_impl().unwrap_or(0) % 65535 + 1024) as u16 }; let sports_ori: Vec = vec![ @@ -3987,11 +3891,8 @@ fn nasl_tcp_v6_ping( } let soc = new_raw_ipv6_socket()?; - if let Err(e) = soc.set_header_included(true) { - return Err(error(format!( - "Not possible to create a raw socket: {}", - e - )).into()); + if let Err(e) = soc.set_header_included_v4(true) { + return Err(error(format!("Not possible to create a raw socket: {}", e))); }; // Get the iface name, to set the capture device. @@ -4002,11 +3903,7 @@ fn nasl_tcp_v6_ping( let port = match register.named("port") { Some(ContextType::Value(NaslValue::Number(x))) => *x, None => 0, //TODO: implement plug_get_host_open_port() - _ => { - return Err(ArgumentError::WrongArgument( - "Invalid length value".to_string(), - ).into()) - } + _ => return Err(ArgumentError::WrongArgument("Invalid length value".to_string()).into()), }; if islocalhost(target_ip) { @@ -4023,9 +3920,8 @@ fn nasl_tcp_v6_ping( let filter = format!("ip and src host {}", target_ip); let mut ip_buf = [0u8; 40]; - let mut ip = MutableIpv6Packet::new(&mut ip_buf).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; + let mut ip = MutableIpv6Packet::new(&mut ip_buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; ip.set_flow_label(0); ip.set_traffic_class(0); @@ -4041,9 +3937,8 @@ fn nasl_tcp_v6_ping( ip.set_destination(ipv6_dst); let mut tcp_buf = [0u8; 20]; - let mut tcp = MutableTcpPacket::new(&mut tcp_buf).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; + let mut tcp = MutableTcpPacket::new(&mut tcp_buf) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; tcp.set_flags(0x02); //TH_SYN tcp.set_sequence(random_impl()? as u32); tcp.set_acknowledgement(0); @@ -4103,10 +3998,7 @@ fn nasl_tcp_v6_ping( /// - pcap_timeout: time to wait for the answers in seconds, 5 by default /// - allow_broadcast: default FALSE #[nasl_function] -fn nasl_send_v6packet( - register: &Register, - configs: &Context, -) -> Result { +fn nasl_send_v6packet(register: &Register, configs: &Context) -> Result { let use_pcap = match register.named("pcap_active") { Some(ContextType::Value(NaslValue::Boolean(x))) => *x, None => true, @@ -4115,7 +4007,8 @@ fn nasl_send_v6packet( "pcap_active", "Boolean", "Invalid pcap_active value", - ).into()) + ) + .into()) } }; @@ -4127,7 +4020,8 @@ fn nasl_send_v6packet( "pcap_filter", "String", "Invalid pcap_filter value", - ).into()) + ) + .into()) } }; @@ -4139,7 +4033,8 @@ fn nasl_send_v6packet( "pcap_timeout", "Number", "Invalid timeout value", - ).into()) + ) + .into()) } }; @@ -4154,29 +4049,23 @@ fn nasl_send_v6packet( return Err(error(format!( "send_v6packet: Not possible to create a raw socket: {}", e - )).into()); + ))); }; let _dflt_packet_sz = match register.named("length") { Some(ContextType::Value(NaslValue::Number(x))) => *x, None => 0, _ => { - return Err(ArgumentError::wrong_argument( - "length", - "Number", - "Invalid length value", - ).into()) + return Err( + ArgumentError::wrong_argument("length", "Number", "Invalid length value").into(), + ) } }; // Get the iface name, to set the capture device. let target_ip = get_host_ip(configs)?; - print!("\nAAAAAAAAAAA target_ip {:?}\n", target_ip); - let local_ip = get_source_ip(target_ip, 50000u16)?; - println!("\nAAAAAAAAAAA local_ip {:?}\n", local_ip); let iface = get_interface_by_local_ip(local_ip)?; - println!("\nAAAAAAAAAAA iface {:?}\n", iface); let mut capture_dev = match Capture::from_device(iface) { Ok(c) => match c.promisc(true).timeout(timeout).open() { @@ -4186,21 +4075,14 @@ fn nasl_send_v6packet( Err(e) => return custom_error!("send_packet: {}", e), }; - print!("\nAAAAAAAAAAA antes de pkt\n"); for pkt in positional.iter() { - print!("AAAAAAAAAAA 1"); let packet_raw = match pkt { NaslValue::Data(data) => data as &[u8], - _ => { - return Err(FnError::wrong_unnamed_argument( - "Data", - "Invalid packet", - )) - } + _ => return Err(FnError::wrong_unnamed_argument("Data", "Invalid packet")), }; - let packet = packet::ipv6::Ipv6Packet::new(packet_raw).ok_or_else(|| { - error("No possible to create a packet from buffer".to_string()) - })?; + + let packet = packet::ipv6::Ipv6Packet::new(packet_raw) + .ok_or_else(|| error("No possible to create a packet from buffer".to_string()))?; // No broadcast destination and dst ip address inside the IP packet // differs from target IP, is consider a malicious or buggy script. @@ -4211,13 +4093,12 @@ fn nasl_send_v6packet( )); } - let sock_str = format!("{}:{}", &packet.get_destination().to_string().as_str(), 0); + let sock_str = format!("[{}]:{}", &packet.get_destination().to_string().as_str(), 0); + let sockaddr = match SocketAddr::from_str(&sock_str) { Ok(addr) => socket2::SockAddr::from(addr), Err(e) => { - return Err(error( - format!("send_packet: {}", e) - ).into()); + return Err(error(format!("send_packet: {}", e))); } }; @@ -4226,9 +4107,7 @@ fn nasl_send_v6packet( debug!("Sent {} bytes", b); } Err(e) => { - return Err(error( - format!("send_packet: {}", e) - ).into()); + return Err(error(format!("send_packet: {}", e))); } } diff --git a/rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs b/rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs index 94e67ae83..df38e31f7 100644 --- a/rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs +++ b/rust/src/nasl/builtin/raw_ip/raw_ip_utils.rs @@ -74,7 +74,7 @@ pub fn get_interface_by_local_ip(local_address: IpAddr) -> Result Result { match dst { SocketAddr::V4(_) => UdpSocket::bind("0.0.0.0:0"), - SocketAddr::V6(_) => UdpSocket::bind(" 0:0:0:0:0:0:0:0:0"), + SocketAddr::V6(_) => UdpSocket::bind("[0:0:0:0:0:0:0:0]:0"), } .map_err(RawIpError::FailedToBind) } diff --git a/rust/src/nasl/builtin/raw_ip/tests/packet_forgery.rs b/rust/src/nasl/builtin/raw_ip/tests/packet_forgery.rs index cf3a20b53..7ac9f2952 100644 --- a/rust/src/nasl/builtin/raw_ip/tests/packet_forgery.rs +++ b/rust/src/nasl/builtin/raw_ip/tests/packet_forgery.rs @@ -297,4 +297,31 @@ mod tests { let _r = safe_copy_from_slice(&mut a, 0, 2, &b, 0, 2); assert_eq!(a, [b'a', b'b', 3u8, 4u8]); } + + #[test] + fn forge_icmp_v6_packet() { + let mut t = setup(); + t.ok( + r#"ip6_packet = forge_ip_v6_packet( ip6_v: 6, # IP6_v, + ip6_p: 0x3a, #ICMPv6 + ip6_plen:40, + ip6_hlim:IP6_HLIM, + ip6_src: "5858::1", + ip6_dst: "5858::2");"#, + vec![6, 0, 0, 58, 40, 58, 58, 0, 0, 0, 0, 0, 1, 58,58, 0, 0, 0, 0, 0, 2], + ); + t.ok( + r#"icmp = forge_icmp_v6_packet( ip6:ip6_packet, + icmp_type:128, + icmp_code:1, + icmp_seq:2, + icmp_id: 1, + icmp_cksum: 0 + );"#, + vec![ + 6, 0, 0, 58, 40, 58, 58, 0, 0, 0, 0, 0, 1, 58, 58, 0, 0, 0, 0, 0, 2, + 128, 1, 64, 38, 140, 227, 2, 0 + ], + ); + } }