Skip to content

Instantly share code, notes, and snippets.

@o0Ignition0o
Created July 30, 2018 19:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save o0Ignition0o/37666fa5924352b692b18513c6e7a264 to your computer and use it in GitHub Desktop.
Save o0Ignition0o/37666fa5924352b692b18513c6e7a264 to your computer and use it in GitHub Desktop.
is_ipv4
#![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