| Crates.io | ip2asn |
| lib.rs | ip2asn |
| version | 0.1.2 |
| created_at | 2025-07-20 21:59:05.269524+00 |
| updated_at | 2025-08-03 08:37:05.588978+00 |
| description | A high-performance, memory-efficient Rust crate for mapping IP addresses to Autonomous System (AS) information. |
| homepage | https://github.com/x123/ip2asn |
| repository | https://github.com/x123/ip2asn |
| max_upload_size | |
| id | 1761468 |
| size | 212,431 |
A high-performance, memory-efficient Rust crate for mapping IP addresses to Autonomous System (AS) information with sub-microsecond lookups.
ip_network_table).std::io::Read source (files,
in-memory buffers, etc.)..gz data sources out of the
box.fetch feature allows building the map
directly from a URL.AsnInfo struct is available via
lookup_owned() for safe, lifetime-free use in async or threaded contexts.serde feature allows AsnInfo to be
serialized and deserialized.strict mode to fail on any parsing
error and a flexible on_warning callback for custom logging.tokio, smol, etc.) or in non-async applications.Add ip2asn to your Cargo.toml:
[dependencies]
ip2asn = "0.1.1"
Then, use the Builder to load your data and perform lookups.
use ip2asn::{Builder, IpAsnMap};
use std::net::IpAddr;
fn main() -> Result<(), ip2asn::Error> {
// A small, in-memory TSV data source for the example.
let data = "31.13.64.0\t31.13.127.255\t32934\tUS\tFACEBOOK-AS";
// Build the map from a source that implements `io::Read`.
let map = Builder::new()
.with_source(data.as_bytes())?
.build()?;
// Perform a lookup.
let ip: IpAddr = "31.13.100.100".parse().unwrap();
if let Some(info) = map.lookup(ip) {
assert_eq!(info.network, "31.13.64.0/18".parse().unwrap());
assert_eq!(info.asn, 32934);
assert_eq!(info.country_code, "US");
assert_eq!(info.organization, "FACEBOOK-AS");
println!(
"{} -> AS{} {} ({}) in {}",
ip, info.asn, info.organization, info.country_code, info.network
);
}
Ok(())
}
For applications that start with an empty map and load data later, you can use
IpAsnMap::new() or Default::default().
use ip2asn::IpAsnMap;
let empty_map = IpAsnMap::new();
assert!(empty_map.lookup("8.8.8.8".parse().unwrap()).is_none());
The standard lookup method returns a view with a lifetime tied to the map.
For async code or situations where you need to store the result, use
lookup_owned.
use ip2asn::{Builder, AsnInfo}; // Note: AsnInfo is the owned struct
use std::net::IpAddr;
# fn main() -> Result<(), ip2asn::Error> {
# let data = "1.0.0.0\t1.0.0.255\t13335\tAU\tCLOUDFLARENET";
# let map = Builder::new().with_source(data.as_bytes())?.build()?;
let ip: IpAddr = "1.0.0.1".parse().unwrap();
// `lookup_owned` returns an `Option<AsnInfo>` with no lifetime.
if let Some(info) = map.lookup_owned(ip) {
// This `info` object can be sent across threads or stored.
assert_eq!(info.asn, 13335);
}
# Ok(())
# }
With the fetch feature enabled, you can build the map directly from a remote
data source.
[dependencies]
ip2asn = { version = "0.1.1", features = ["fetch"] }
use ip2asn::{Builder, IpAsnMap};
use std::net::IpAddr;
fn main() -> Result<(), ip2asn::Error> {
// This example requires a running web server providing the data.
// You can find a real-world data source from services like `iptoasn.com`.
let url = "https://iptoasn.com/data/ip2asn-combined.tsv.gz";
let map = Builder::new().from_url(url)?.build()?;
let ip: IpAddr = "1.0.0.1".parse().unwrap();
if let Some(info) = map.lookup(ip) {
assert_eq!(info.asn, 13335); // CLOUDFLARENET
}
Ok(())
}
Enable the serde feature to serialize and deserialize the AsnInfo struct.
[dependencies]
ip2asn = { version = "0.1.1", features = ["serde"] }
serde_json = "1.0"
# #[cfg(feature = "serde")]
# fn main() -> Result<(), Box<dyn std::error::Error>> {
# use ip2asn::{Builder, AsnInfo};
# let data = "1.0.0.0\t1.0.0.255\t13335\tAU\tCLOUDFLARENET";
# let map = Builder::new().with_source(data.as_bytes())?.build()?;
# let info = map.lookup_owned("1.0.0.1".parse()?).unwrap();
// Serialize the owned `AsnInfo` struct.
let serialized = serde_json::to_string(&info)?;
println!("{}", serialized);
// Deserialize it back.
let deserialized: AsnInfo = serde_json::from_str(&serialized)?;
assert_eq!(info, deserialized);
# Ok(())
# }
# #[cfg(not(feature = "serde"))]
# fn main() {}
By default, the builder skips lines that cannot be parsed. You can enable
strict mode to fail fast or use the on_warning callback for custom logging.
use ip2asn::{Builder, Warning};
use std::sync::{Arc, atomic::{AtomicUsize, Ordering}};
fn main() -> Result<(), ip2asn::Error> {
let malformed_data = "1.0.0.0\t1.0.0.255\t13335\tAU\tCLOUDFLARENET\nthis is not a valid line";
// Strict mode will return an error.
let result = Builder::new().with_source(malformed_data.as_bytes())?.strict().build();
assert!(result.is_err());
// The warning callback allows you to inspect and log issues.
let warning_count = Arc::new(AtomicUsize::new(0));
let count_clone = warning_count.clone();
let map = Builder::new()
.with_source(malformed_data.as_bytes())?
.on_warning(Box::new(move |warning: Warning| {
eprintln!("Builder warning: {warning:?}");
count_clone.fetch_add(1, Ordering::SeqCst);
}))
.build()?;
assert_eq!(warning_count.load(Ordering::SeqCst), 1);
Ok(())
}
ip2asn-cliThis workspace also includes ip2asn-cli, a command-line tool that uses the ip2asn library to perform lookups from your terminal.
You can install the CLI directly from this repository using cargo:
cargo install --path ip2asn-cli
The primary command is lookup, which takes one or more IP addresses as arguments. If no IPs are provided, it reads them from stdin.
# Look up a single IP
$ ip2asn-cli lookup 8.8.8.8
15169 | 8.8.8.8 | 8.8.8.0/24 | GOOGLE | US
# Look up multiple IPs and get JSON output
$ ip2asn-cli lookup --json 1.1.1.1 9.9.9.9
{"ip":"1.1.1.1","found":true,"info":{"network":"1.1.1.0/24","asn":13335,"country_code":"US","organization":"CLOUDFLARENET"}}
{"ip":"9.9.9.9","found":true,"info":{"network":"9.9.9.0/24","asn":19281,"country_code":"CH","organization":"QUAD9-AS-CH"}}
# Read from stdin
$ echo "208.67.222.222" | ip2asn-cli lookup
22822 | 208.67.222.222 | 208.67.222.0/24 | OPENDNS | US
On the first run, and subsequently whenever the cached data is more than 24 hours old, ip2asn-cli will automatically check for and download the latest IP-to-ASN dataset from iptoasn.com.
~/.cache/ip2asn/data.tsv.gzstderr, so they won't interfere with stdout parsing.ip2asn-cli update.You can configure the tool's behavior by creating a file at ~/.config/ip2asn/config.toml.
config.toml
# Set to false to disable the automatic 24-hour update check.
# The `update` subcommand will still work.
# Defaults to false.
auto_update = true
This project is licensed under the MIT License.