Skip to content

Instantly share code, notes, and snippets.

@sajattack
Last active November 29, 2017 04:21
Show Gist options
  • Save sajattack/d91a1531769d9000023b257acbdd537f to your computer and use it in GitHub Desktop.
Save sajattack/d91a1531769d9000023b257acbdd537f to your computer and use it in GitHub Desktop.
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