Created
July 30, 2018 19:46
-
-
Save o0Ignition0o/37666fa5924352b692b18513c6e7a264 to your computer and use it in GitHub Desktop.
is_ipv4
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#![crate_type = "staticlib"] | |
#![feature(test)] | |
extern crate test; | |
extern crate libc; | |
use std::slice; | |
fn is_valid_ipv4_addr<'a>(addr: &'a [char]) -> bool { | |
let mut maybe_octet: Option<u8> = None; | |
let mut dots: u8 = 0; | |
for c in addr { | |
match (c, maybe_octet) { | |
('.', None) => { | |
// ip address cannot start with a '.' | |
return false; | |
} | |
('.', Some(_)) => { | |
dots = dots + 1; | |
maybe_octet = None; | |
} | |
(maybe_digit, None) => { | |
if let Some(digit) = maybe_digit.to_digit(10) { | |
maybe_octet = Some(digit as u8); | |
} else { | |
return false; | |
}; | |
} | |
(maybe_digit, Some(octet)) => { | |
if let Some(digit) = maybe_digit.to_digit(10) { | |
if let Some(times_ten) = octet.checked_mul(10) { | |
if let Some(plus_c) = times_ten.checked_add(digit as u8) { | |
maybe_octet = Some(plus_c); | |
} else { | |
// Addition overflowed | |
return false; | |
} | |
} else { | |
// Multiplication overflowed | |
return false; | |
} | |
} else { | |
return false; | |
}; | |
} | |
} | |
} | |
dots == 3 && maybe_octet.is_some() | |
} | |
#[no_mangle] | |
#[allow(non_snake_case)] | |
pub extern "C" fn rust_net_is_valid_ipv4_addr<'a>(addr: &'a u8, addrLen: i32) -> bool { | |
let address = | |
unsafe { slice::from_raw_parts(std::mem::transmute::<&u8, &char>(addr), addrLen as usize) }; | |
is_valid_ipv4_addr(address) | |
} | |
#[cfg(test)] | |
mod tests { | |
use is_valid_ipv4_addr; | |
use libc; | |
use test::{black_box, Bencher}; | |
#[test] | |
fn test_with_localhost() { | |
let ip: [char; 9] = ['1', '2', '7', '.', '0', '.', '0', '.', '1']; | |
assert!(is_valid_ipv4_addr(&ip)); | |
} | |
#[test] | |
fn test_with_zeroes() { | |
let ip: [char; 7] = ['0', '.', '0', '.', '0', '.', '0']; | |
assert!(is_valid_ipv4_addr(&ip)); | |
} | |
#[test] | |
fn test_with_max() { | |
let ip: [char; 15] = [ | |
'2', '5', '5', '.', '2', '5', '5', '.', '2', '5', '5', '.', '2', '5', '5', | |
]; | |
assert!(is_valid_ipv4_addr(&ip)); | |
} | |
#[test] | |
fn test_with_too_high_ip() { | |
let ip: [char; 15] = [ | |
'2', '5', '6', '.', '2', '5', '5', '.', '2', '5', '5', '.', '2', '5', '5', | |
]; | |
assert!(!is_valid_ipv4_addr(&ip)); | |
} | |
#[test] | |
fn test_with_ip_starting_with_a_dot() { | |
let ip: [char; 16] = [ | |
'.', '2', '5', '6', '.', '2', '5', '5', '.', '2', '5', '5', '.', '2', '5', '5', | |
]; | |
assert!(!is_valid_ipv4_addr(&ip)); | |
} | |
#[test] | |
fn test_with_ip_starting_with_4_digits() { | |
let ip: [char; 16] = [ | |
'1', '1', '1', '1', '.', '2', '5', '5', '.', '2', '5', '5', '.', '2', '5', '5', | |
]; | |
assert!(!is_valid_ipv4_addr(&ip)); | |
} | |
#[test] | |
fn test_with_too_long_ip() { | |
let ip: [char; 19] = [ | |
'2', '5', '5', '.', '2', '5', '5', '.', '2', '5', '5', '.', '2', '5', '5', '.', '2', | |
'5', '5', | |
]; | |
assert!(!is_valid_ipv4_addr(&ip)); | |
} | |
#[bench] | |
fn bench_is_valid_ipv4_address(bench: &mut Bencher) { | |
let ip: [char; 15] = [ | |
'1', '9', '2', '.', '1', '6', '8', '.', '1', '0', '1', '.', '1', '1', '7', | |
]; | |
bench.iter(|| black_box(is_valid_ipv4_addr(&ip))); | |
} | |
#[bench] | |
fn bench_localhost_is_valid_ipv4_address(bench: &mut Bencher) { | |
let ip: [char; 9] = ['1', '2', '7', '.', '0', '.', '0', '.', '1']; | |
bench.iter(|| black_box(is_valid_ipv4_addr(&ip))); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment