### Install ip2asn-cli Source: https://github.com/x123/ip2asn/blob/master/ip2asn-cli/README.md Install the tool using the cargo package manager. ```sh cargo install ip2asn-cli ``` -------------------------------- ### Configure ip2asn-cli Source: https://github.com/x123/ip2asn/blob/master/ip2asn-cli/README.md Set configuration options in the config.toml file. ```toml # Set to false to disable the automatic 24-hour update check. # The `update` subcommand will still work. # Defaults to false. auto_update = true ``` -------------------------------- ### Serialize and Deserialize with Serde Source: https://github.com/x123/ip2asn/blob/master/README.md Enable the serde feature to convert AsnInfo to and from JSON. ```toml [dependencies] ip2asn = { version = "0.1.1", features = ["serde"] } serde_json = "1.0" ``` ```rust # #[cfg(feature = "serde")] # fn main() -> Result<(), Box> { # 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() {} ``` -------------------------------- ### Perform IP to ASN Lookup Source: https://github.com/x123/ip2asn/blob/master/README.md Use the Builder to load data from a source and perform IP address lookups. ```rust 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(()) } ``` -------------------------------- ### Add Dependency to Cargo.toml Source: https://github.com/x123/ip2asn/blob/master/README.md Include the ip2asn crate in your project dependencies. ```toml [dependencies] ip2asn = "0.1.2" ``` -------------------------------- ### Fetch Data from URL Source: https://github.com/x123/ip2asn/blob/master/README.md Enable the fetch feature to load data directly from a remote URL. ```toml [dependencies] ip2asn = { version = "0.1.1", features = ["fetch"] } ``` ```rust 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(()) } ``` -------------------------------- ### Define IpAsnMap and AsnInfo structures Source: https://github.com/x123/ip2asn/blob/master/docs/spec.md Core data structures for the crate, including the read-optimized map and the view/owned variants of ASN information. ```rust // In lib.rs /// A read-optimized, in-memory map for IP address to ASN lookups. /// Construction is handled by the `Builder`. pub struct IpAsnMap { /* private fields */ } /// A builder for configuring and loading an `IpAsnMap`. pub struct Builder { /* private fields */ } /// A lightweight, read-only view into the ASN information for an IP address. /// This struct is returned by the `lookup` method. #[derive(Debug, PartialEq, Eq)] pub struct AsnInfoView<'a> { pub network: IpNetwork, pub asn: u32, pub country_code: &'a str, pub organization: &'a str, } /// An owned, lifetime-free struct containing ASN information. /// This struct is returned by the `lookup_owned` method and is useful /// for async or multi-threaded applications. #[derive(Debug, Clone, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] pub struct AsnInfo { pub network: IpNetwork, pub asn: u32, pub country_code: String, pub organization: String, } /// The primary error type for the crate. #[derive(Debug)] pub enum Error { /* see section 5.2 */ } /// A non-fatal warning for a skipped line during parsing. #[derive(Debug)] pub enum Warning { /* see section 5.3 */ } ``` -------------------------------- ### Perform a basic IP lookup Source: https://github.com/x123/ip2asn/blob/master/ip2asn-cli/README.md Look up a single IP address directly from the command line. ```sh # Look up a single IP $ ip2asn 8.8.8.8 15169 | 8.8.8.8 | 8.8.8.0/24 | GOOGLE | US ``` -------------------------------- ### Builder API Source: https://github.com/x123/ip2asn/blob/master/docs/spec.md Methods for configuring and building an IpAsnMap instance. ```APIDOC ## Builder Methods ### with_file(path: &str) -> Result Loads data from a file path, handling gzip decompression automatically. ### with_url(url: &str) -> Result Loads data from a URL (requires `fetch` feature). Uses a blocking HTTP client. ### with_source(reader: R) -> Self Loads data from any source implementing `std::io::Read`. ### strict() -> Self Enables strict parsing mode; `build()` will return an `Err` on the first parse failure. ### build() -> Result Consumes the builder and constructs the `IpAsnMap`. ``` -------------------------------- ### Create an Empty Map Source: https://github.com/x123/ip2asn/blob/master/README.md Initialize an empty map for applications that populate data dynamically. ```rust use ip2asn::IpAsnMap; let empty_map = IpAsnMap::new(); assert!(empty_map.lookup("8.8.8.8".parse().unwrap()).is_none()); ``` -------------------------------- ### Perform IP Lookups Source: https://github.com/x123/ip2asn/blob/master/README.md Execute lookups for single or multiple IP addresses, with support for JSON formatting and stdin input. ```sh # 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 ``` -------------------------------- ### Configure Builder for data loading Source: https://github.com/x123/ip2asn/blob/master/docs/spec.md Builder API for loading ASN data from files, URLs, or generic readers with support for strict parsing and warning callbacks. ```rust // In impl Builder impl Builder { /// Creates a new builder with default, resilient settings. pub fn new() -> Self { /* ... */ } /// Loads data from a file path. /// Automatically handles gzip decompression by inspecting the file's magic bytes. pub fn with_file(self, path: &str) -> Result { /* ... */ } /// Loads data from a URL. Requires the `fetch` feature. /// Automatically handles gzip decompression. Uses a blocking HTTP client. #[cfg(feature = "fetch")] pub fn with_url(self, url: &str) -> Result { /* ... */ } /// Loads data from any source that implements `std::io::Read`. /// This method expects a plain, uncompressed text stream. pub fn with_source(self, reader: R) -> Self { /* ... */ } /// Enables strict parsing mode. /// If called, `build()` will return an `Err` on the first parse failure. pub fn strict(mut self) -> Self { /* ... */ } /// Sets a callback function to be invoked for each skipped line in resilient mode. pub fn on_warning(mut self, callback: F) -> Self { /* ... */ } /// Builds the `IpAsnMap`, consuming the builder. /// This is a potentially expensive operation. pub fn build(self) -> Result { /* ... */ } } ``` -------------------------------- ### Implement IpAsnMap lookup functionality Source: https://github.com/x123/ip2asn/blob/master/docs/spec.md Methods for performing longest-prefix matches on IP addresses, providing both borrowed and owned return types. ```rust // In impl IpAsnMap impl IpAsnMap { /// Creates a new, empty `IpAsnMap`. /// This is useful for applications that may load data later or start empty. pub fn new() -> Self { Self::default() } /// Performs a longest-prefix match for the given IP address. /// * // Returns `Some(AsnInfoView)` if a matching network is found, otherwise `None`. * // The lookup is extremely fast, suitable for high-throughput pipelines. pub fn lookup(&self, ip: std::net::IpAddr) -> Option { // ... } /// Performs a lookup and returns an owned `AsnInfo` struct. /// This is ideal for async contexts or when the result needs to be stored, /// as it avoids the lifetime constraints of `AsnInfoView`. pub fn lookup_owned(&self, ip: std::net::IpAddr) -> Option { self.lookup(ip).map(AsnInfo::from) } } impl Default for IpAsnMap { /// Creates a new, empty `IpAsnMap`. fn default() -> Self { // ... } } ``` -------------------------------- ### Output lookup results as JSON Source: https://github.com/x123/ip2asn/blob/master/ip2asn-cli/README.md Retrieve lookup information in JSON format for scripting purposes. ```sh $ ip2asn --json 1.1.1.1 {"ip":"1.1.1.1","found":true,"info":{"network":"1.1.1.0/24","asn":13335,"country_code":"US","organization":"CLOUDFLARENET"}} ``` -------------------------------- ### Perform advanced IP lookups Source: https://github.com/x123/ip2asn/blob/master/ip2asn-cli/README.md Look up multiple IP addresses via arguments or standard input. ```sh # Look up multiple IPs from arguments $ ip2asn 1.1.1.1 9.9.9.9 13335 | 1.1.1.1 | 1.1.1.0/24 | CLOUDFLARENET | US 19281 | 9.9.9.9 | 9.9.9.0/24 | QUAD9-AS-CH | CH # Read IPs from stdin $ echo "208.67.222.222" | ip2asn 22822 | 208.67.222.222 | 208.67.222.0/24 | OPENDNS | US ``` -------------------------------- ### Handle Parsing Errors and Warnings Source: https://github.com/x123/ip2asn/blob/master/README.md Configure strict mode to fail on errors or use a warning callback for custom logging. ```rust 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(()) } ``` -------------------------------- ### Manually update the dataset Source: https://github.com/x123/ip2asn/blob/master/ip2asn-cli/README.md Force an update of the IP-to-ASN dataset. ```sh $ ip2asn update ``` -------------------------------- ### IpAsnMap::lookup_owned Source: https://github.com/x123/ip2asn/blob/master/docs/spec.md Performs a lookup and returns an owned AsnInfo struct, suitable for async or multi-threaded contexts. ```APIDOC ## fn lookup_owned(&self, ip: std::net::IpAddr) -> Option ### Description Performs a lookup and returns an owned `AsnInfo` struct. This avoids lifetime constraints associated with `AsnInfoView`. ### Parameters - **ip** (std::net::IpAddr) - Required - The IP address to look up. ### Returns - **Option** - The owned ASN information associated with the IP address if found. ``` -------------------------------- ### Perform Async-Friendly Lookups Source: https://github.com/x123/ip2asn/blob/master/README.md Use lookup_owned to retrieve an AsnInfo struct that is not tied to the map's lifetime. ```rust 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` 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(()) # } ``` -------------------------------- ### IpAsnMap::lookup Source: https://github.com/x123/ip2asn/blob/master/docs/spec.md Performs a longest-prefix match for the given IP address to retrieve associated ASN information. ```APIDOC ## fn lookup(&self, ip: std::net::IpAddr) -> Option ### Description Performs a longest-prefix match for the given IP address. Returns `Some(AsnInfoView)` if a matching network is found, otherwise `None`. ### Parameters - **ip** (std::net::IpAddr) - Required - The IP address to look up. ### Returns - **Option** - The ASN information associated with the IP address if found. ``` -------------------------------- ### Define Warning Enum Source: https://github.com/x123/ip2asn/blob/master/docs/spec.md Represents non-fatal issues encountered during resilient mode processing. ```rust #[derive(Debug)] pub enum Warning { /// A line in the data source could not be parsed and was skipped. Parse { line_number: usize, line_content: String, message: String, }, /// A line contained a start IP and end IP of different families. IpFamilyMismatch { line_number: usize, line_content: String, }, // ... other non-fatal warnings as needed ... } ``` -------------------------------- ### Define Error Enum Source: https://github.com/x123/ip2asn/blob/master/docs/spec.md Represents fatal errors encountered during strict mode processing or I/O operations. ```rust #[derive(Debug)] pub enum Error { /// An error occurred during an I/O operation. Io(std::io::Error), /// A line in the data source was malformed (only in strict mode). Parse { line_number: usize, line_content: String, kind: ParseErrorKind, }, } #[derive(Debug)] pub enum ParseErrorKind { /// The line did not have the expected number of columns. IncorrectColumnCount { expected: usize, found: usize }, /// A field could not be parsed as a valid IP address. InvalidIpAddress { field: String, value: String }, /// The ASN field could not be parsed as a valid number. InvalidAsnNumber { value: String }, /// The start IP address was greater than the end IP address. InvalidRange { start_ip: IpAddr, end_ip: IpAddr }, /// The start and end IPs were of different families. IpFamilyMismatch, } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.