///|
fn parse_timeout_arg(
args : Array[String],
index : Int,
default_value : Int,
) -> Int? {
if args.length() <= index {
Some(default_value)
} else {
try @string.parse_int(args[index][:]) catch {
_ => {
println("Invalid timeout. Expected a decimal integer.")
return None
}
} noraise {
value => Some(value)
}
}
}
///|
fn read_frame_u16_be(frame : Bytes, offset : Int) -> Int {
(frame[offset].to_int() << 8) + frame[offset + 1].to_int()
}
///|
fn run_snmp_get(args : Array[String]) -> Unit {
guard args.length() >= 1 else {
println("snmp-get [community] [timeout-ms]")
println(" Example: snmp-get 192.168.3.10 public 3000")
return
}
let device_ip = @frame.IPv4Address::from_text(args[0][:]) catch {
err => {
println("Invalid device IP: \{to_repr(err)}")
return
}
}
let community = if args.length() >= 2 { args[1] } else { "public" }
let timeout_ms = match parse_timeout_arg(args, 2, 3000) {
Some(value) => value
None => return
}
println(
provider_harness_helper_handoff_text(
"snmp-get",
"SNMP helper",
"@udpnet.UdpSocket::open",
[
"device_ip=" + device_ip.to_text(),
"community=" + community,
"timeout_ms=" + timeout_ms.to_string(),
],
),
)
}
///|
fn run_lldp_capture(args : Array[String]) -> Unit {
guard args.length() >= 2 && args[0] == "--iface" else {
println("lldp-capture --iface [timeout-ms] [source-mac]")
println(
" Example: lldp-capture --iface \"I226-V #2\" 35000 74:90:50:10:E9:07",
)
return
}
let timeout_ms = match parse_timeout_arg(args, 2, 35000) {
Some(value) => value
None => return
}
let expected_source = if args.length() >= 4 {
Some(
@frame.MacAddress::from_hex(args[3][:]) catch {
err => {
println("Invalid source MAC: \{to_repr(err)}")
return
}
},
)
} else {
None
}
let fields : Array[String] = [
"interface=" + args[1],
"timeout_ms=" + timeout_ms.to_string(),
]
match expected_source {
Some(mac) => fields.push("source_mac=" + mac.to_hex())
None => ()
}
println(
provider_harness_helper_handoff_text(
"lldp-capture", "LLDP raw Ethernet helper", "@rawnet.RawSocket::open", fields,
),
)
}
///|
fn run_dhcp_discover_live(args : Array[String]) -> Unit {
guard args.length() >= 2 && args[0] == "--iface" else {
println(
"dhcp-discover-live --iface [timeout-ms] [hostname] [xid] [bind-ip]",
)
println(
" Example: dhcp-discover-live --iface \"I226-V #2\" 5000 codex-profinet",
)
return
}
let timeout_ms = match parse_timeout_arg(args, 2, 5000) {
Some(value) => value
None => return
}
let hostname = if args.length() >= 4 { args[3] } else { "codex-profinet" }
let xid_field = if args.length() >= 5 {
match parse_number_arg(args[4], "xid") {
Some(value) => "xid=" + value.to_string()
None => return
}
} else {
"xid=auto_from_provider_harness"
}
let bind_ip = if args.length() >= 6 {
@frame.IPv4Address::from_text(args[5][:]) catch {
err => {
println("Invalid bind IP: \{to_repr(err)}")
return
}
}
} else {
@frame.IPv4Address::from_text("0.0.0.0") catch {
err => {
println("Invalid default bind IP: \{to_repr(err)}")
return
}
}
}
println(
provider_harness_helper_handoff_text(
"dhcp-discover-live",
"DHCP helper",
"@rawnet.RawSocket::open + @udpnet.UdpSocket::open",
[
"interface=" + args[1],
"timeout_ms=" + timeout_ms.to_string(),
"hostname=" + hostname,
xid_field,
"bind_ip=" + bind_ip.to_text(),
],
),
)
}