~jelford/hostname-lookup unlisted

hostname-lookup/src/main.rs -rw-r--r-- 2.4 KiB
fe856e57James Elford Tidied up the code, regenrated traces, made chk.sh fail for valgrind violations 9 months ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
use std::borrow::Cow;
use std::ffi::{CStr, CString};
use std::ptr;

fn do_libc_lookup(hostname: &str) {
    let mut addrinfo_ptr: *mut libc::addrinfo = ptr::null_mut();
    let addrinfo_ptr_ptr = &mut addrinfo_ptr as *mut *mut libc::addrinfo;

    let hints = libc::addrinfo {
        ai_flags: libc::AI_CANONNAME,
        ai_family: libc::AF_INET,
        ai_socktype: libc::SOCK_DGRAM,
        ai_protocol: 0,
        ai_addr: ptr::null_mut(),
        ai_addrlen: 0,
        ai_canonname: ptr::null_mut(),
        ai_next: ptr::null_mut(),
    };
    let hints_ptr = &hints as *const libc::addrinfo;

    let hostname = CString::new(hostname).expect("parsing hostname");
    let hostname_ptr = hostname.as_ptr();

    unsafe {
        let res = libc::getaddrinfo(hostname_ptr, ptr::null(), hints_ptr, addrinfo_ptr_ptr);

        match res {
            0 => (),
            libc::EAI_NODATA | libc::EAI_NONAME => {
                println!("No results");
                return;
            }
            _ => panic!("getaddrinfo({})", res),
        };

        // out_ptr now contains a linked list of results.

        let mut curr_out = addrinfo_ptr;

        while !curr_out.is_null() {
            let libc::addrinfo {
                ai_addr,
                ai_family,
                ai_canonname,
                ai_next,
                ..
            } = *curr_out;

            let (fam, ip) = match ai_family {
                libc::AF_INET => {
                    let adr = *(ai_addr as *const libc::sockaddr_in);
                    let ipaddr = adr.sin_addr.s_addr.to_ne_bytes();
                    let ip_str = ipaddr
                        .iter()
                        .map(u8::to_string)
                        .collect::<Vec<_>>()
                        .join(".");

                    ("ipv4", ip_str)
                }
                _ => continue,
            };

            let canonname = if !ai_canonname.is_null() {
                let canonname_cstr = CStr::from_ptr(ai_canonname);
                canonname_cstr.to_string_lossy()
            } else {
                Cow::from("<unknown canonical addr>")
            };

            println!("{} {}: {}", fam, ip, canonname);

            curr_out = ai_next;
        }

        libc::freeaddrinfo(addrinfo_ptr);
    };
}

fn main() {
    let args: Vec<String> = std::env::args().collect();
    let hostname = args.get(1).expect("hostname not given").to_owned();
    do_libc_lookup(&hostname);
}