69 lines
3.5 KiB
Rust
69 lines
3.5 KiB
Rust
/*
|
|
Copyright 2023 0xf8.dev@proton.me
|
|
|
|
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
use argparse::{ArgumentParser, List};
|
|
use colored::Colorize;
|
|
|
|
#[tokio::main]
|
|
async fn main() {
|
|
let mut targets: Vec<String> = vec![];
|
|
|
|
// Argument parser
|
|
{
|
|
let mut args = ArgumentParser::new();
|
|
args.set_description("IP-API wrapper");
|
|
|
|
// Positional arg: targets
|
|
args.refer(&mut targets)
|
|
.add_argument("targets", List, "Targets")
|
|
.required();
|
|
|
|
args.parse_args_or_exit();
|
|
}
|
|
|
|
// Length check
|
|
if targets.len() == 0 {
|
|
eprintln!("Fatal: No targets given.");
|
|
std::process::exit(1);
|
|
}
|
|
|
|
let client = reqwest::Client::new();
|
|
|
|
for (i, target) in targets.into_iter().enumerate() {
|
|
if i > 0 { print!("\n") };
|
|
|
|
let req = client
|
|
.get(format!("http://ip-api.com/json/{target}?fields=18601977"))
|
|
.send()
|
|
.await
|
|
.unwrap();
|
|
let body = req.text().await.unwrap();
|
|
|
|
let data = json::parse(&body.to_owned()).unwrap();
|
|
|
|
println!("Target {}", target.bright_white().bold());
|
|
if !data["continent"].is_empty() { println!("Continent {}", data["continent"].as_str().unwrap().yellow()) }
|
|
if !data["country"].is_empty() { println!("Country {}", data["country"].as_str().unwrap().yellow()) }
|
|
if !data["regionName"].is_empty() { println!("Region {}", data["regionName"].as_str().unwrap().yellow()) }
|
|
if !data["city"].is_empty() { println!("City {}", data["city"].as_str().unwrap().blue()) }
|
|
if !data["district"].is_empty() { println!("District {}", data["district"].as_str().unwrap().blue()) }
|
|
if !data["zip"].is_empty() { println!("Zip {}", data["zip"].as_str().unwrap().blue()) }
|
|
if !data["isp"].is_empty() { println!("ISP {}", data["isp"].as_str().unwrap().green()) }
|
|
if !data["org"].is_empty() { println!("Org {}", data["org"].as_str().unwrap().green()) }
|
|
if !data["reverse"].is_empty() { println!("Hostname {}", data["reverse"].as_str().unwrap().green()) }
|
|
if !data["timezone"].is_empty() { println!("Timezone {}", data["timezone"].as_str().unwrap().cyan()) }
|
|
if !data["lat"].is_empty() { println!("Latitude {}", data["lat"].as_f64().unwrap().to_string().cyan()) }
|
|
if !data["lon"].is_empty() { println!("Longitude {}", data["lon"].as_f64().unwrap().to_string().cyan()) }
|
|
println!("Corporate {}", match data["hosting"].as_bool().unwrap() { true => { "Yes".bright_green() }, false => { "No".bright_red() } }.bold() );
|
|
println!("Cellular {}", match data["mobile"].as_bool().unwrap() { true => { "Yes".bright_green() }, false => { "No".bright_red() } }.bold() );
|
|
println!("Proxy/TOR {}", match data["proxy"].as_bool().unwrap() { true => { "Yes".bright_green() }, false => { "No".bright_red() } }.bold() );
|
|
}
|
|
}
|