Last active
November 29, 2017 04:21
-
-
Save sajattack/d91a1531769d9000023b257acbdd537f to your computer and use it in GitHub Desktop.
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
unsafe fn lookup_addr(addr: *const in_addr) -> Result<LookupAddr> { | |
// XXX better error handling | |
let ip_string = String::from_utf8(::file_read_all("/etc/net/ip")?).or(Err( | |
Error::new(syscall::EIO), | |
))?; | |
let ip: Vec<u8> = ip_string | |
.trim() | |
.split(".") | |
.map(|part| part.parse::<u8>().unwrap_or(0)) | |
.collect(); | |
let dns_string = String::from_utf8(::file_read_all("/etc/net/dns")?).or(Err( | |
Error::new(syscall::EIO), | |
))?; | |
let dns: Vec<u8> = dns_string | |
.trim() | |
.split(".") | |
.map(|part| part.parse::<u8>().unwrap_or(0)) | |
.collect(); | |
let addr_cstr = ::socket::inet_ntoa(addr); | |
let addr = ::cstr_to_slice(addr_cstr).to_vec(); | |
let mut name = addr.clone(); | |
name.reverse(); | |
for ch in b".IN-ADDR.ARPA"{ | |
name.push(*ch); | |
} | |
let _ = syscall::write(2, name.as_slice()); | |
let _ = syscall::write(2, "\n".as_bytes()); | |
if ip.len() == 4 && dns.len() == 4 { | |
let mut timespec = syscall::TimeSpec::default(); | |
syscall::clock_gettime(syscall::CLOCK_REALTIME, &mut timespec).unwrap(); | |
let tid = (timespec.tv_nsec >> 16) as u16; | |
let packet = Dns { | |
transaction_id: tid, | |
flags: 0x0100, | |
queries: vec![ | |
DnsQuery { | |
name: String::from_utf8(name).unwrap(), | |
q_type: 0x000C, | |
q_class: 0x0001, | |
}, | |
], | |
answers: vec![], | |
}; | |
let packet_data = packet.compile(); | |
let fd = ::RawFile::open( | |
format!("udp:{}.{}.{}.{}:0", ip[0], ip[1], ip[2], ip[3]).as_bytes(), | |
syscall::O_RDWR, | |
)?; | |
let timeout = syscall::TimeSpec { | |
tv_sec: 5, | |
tv_nsec: 0, | |
}; | |
let rt = fd.dup(b"read_timeout")?; | |
syscall::write(*rt, &timeout)?; | |
drop(rt); | |
let wt = fd.dup(b"write_timeout")?; | |
syscall::write(*wt, &timeout)?; | |
drop(wt); | |
let sendrecvfd = fd.dup( | |
format!("{}.{}.{}.{}:53", dns[0], dns[1], dns[2], dns[3]) | |
.as_bytes(), | |
)?; | |
syscall::write(*sendrecvfd, &packet_data)?; | |
let mut buf = [0; 65536]; | |
let count = syscall::read(*sendrecvfd, &mut buf)?; | |
drop(sendrecvfd); | |
drop(fd); | |
//never gets to here | |
let _ = syscall::write(2, "hello world\n".as_bytes()); | |
match Dns::parse(&buf[..count]) { | |
Ok(response) => { | |
let _ = syscall::write(2, format!("{:?}", response).as_bytes()); | |
let _ = syscall::write(2, "\n".as_bytes()); | |
let mut names = vec![]; | |
for answer in response.answers.iter() { | |
let _ = syscall::write(2, format!("{:?}", answer).as_bytes()); | |
let _ = syscall::write(2, "\n".as_bytes()); | |
let _ = syscall::write(2, answer.data.as_slice()); | |
let _ = syscall::write(2, "\n".as_bytes()); | |
if answer.a_type == 0x0001 && answer.a_class == 0x0001 | |
{ | |
let _ = syscall::write(2, answer.data.as_slice()); | |
let _ = syscall::write(2, "\n".as_bytes()); | |
} | |
} | |
Ok(LookupAddr(names.into_iter())) | |
} | |
Err(_err) => Err(Error::new(EINVAL)), | |
} | |
} else { | |
Err(Error::new(EINVAL)) | |
} | |
} | |
libc_fn!(unsafe gethostbyaddr(v: *const libc::c_void, length: socklen_t, format: libc::c_int) -> Result <*const hostent> { | |
let mut addr = mem::uninitialized(); | |
::socket::inet_aton(['8' as i8, '.' as i8, '8' as i8, '.' as i8, '4' as i8, '.' as i8, '4' as i8, '\0' as i8].as_ptr(), &mut addr); | |
match lookup_addr(&addr) { | |
Ok(s) => Ok(&HOST_ENTRY), | |
Err(err) => Err(err), | |
} | |
}); | |
//C | |
#include <stdio.h> | |
#include <errno.h> | |
#include <netdb.h> | |
int main() { | |
gethostbyaddr(); | |
if (errno!=0) { | |
printf("Error %d", errno); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment