2 use std::sync::atomic::Ordering;
3 use std::io::BufReader;
4 use std::net::{IpAddr, SocketAddr};
5 use std::time::Instant;
8 use tokio::io::{stdin, lines};
10 use crate::printer::Printer;
11 use crate::datastore::{Store, AddressState, U64Setting, RegexSetting};
12 use crate::bgp_client::BGPClient;
14 use crate::{START_SHUTDOWN, scan_node};
18 pub fn read(store: &'static Store, printer: &'static Printer, bgp_client: Arc<BGPClient>) {
19 tokio::spawn(lines(BufReader::new(stdin())).for_each(move |line| {
22 printer.add_line(format!("Unparsable input: \"{}\"", line), true);
23 return future::ok(());
26 let mut line_iter = line.split(' ');
27 macro_rules! get_next_chunk {
29 match line_iter.next() {
35 macro_rules! try_parse_next_chunk {
37 match get_next_chunk!().parse::<$type>() {
43 match get_next_chunk!() {
44 "c" => store.set_u64(U64Setting::ConnsPerSec, try_parse_next_chunk!(u64)),
45 "t" => store.set_u64(U64Setting::RunTimeout, try_parse_next_chunk!(u64)),
46 "v" => store.set_u64(U64Setting::MinProtocolVersion, try_parse_next_chunk!(u64)),
47 "w" => store.set_u64(U64Setting::WasGoodTimeout, try_parse_next_chunk!(u64)),
49 if line.len() < 3 || !line.starts_with("s ") {
52 store.set_regex(RegexSetting::SubverRegex, match line[2..].parse::<Regex>() {
57 "a" => scan_node(Instant::now(), try_parse_next_chunk!(SocketAddr), true),
59 let ip = try_parse_next_chunk!(IpAddr);
60 printer.add_line(format!("ASN for {} is {}", ip, bgp_client.get_asn(ip)), false);
63 match AddressState::from_num(try_parse_next_chunk!(u8)) {
64 Some(state) => store.set_u64(U64Setting::RescanInterval(state), try_parse_next_chunk!(u64)),
69 START_SHUTDOWN.store(true, Ordering::SeqCst);
70 return future::err(std::io::Error::new(std::io::ErrorKind::Other, ""));
76 printer.add_line("Shutting down...".to_string(), true);