socket.rs 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. use core::str::{self, FromStr};
  2. use core::mem;
  3. use core::ptr;
  4. use libc::{c_int, c_char, size_t, c_void, ssize_t};
  5. use ::types::{socklen_t, in_addr, sockaddr, sockaddr_in};
  6. use syscall::{self, O_RDWR};
  7. use syscall::error::{Error, EPROTOTYPE, EPROTONOSUPPORT, EAFNOSUPPORT, EINVAL, EOPNOTSUPP, ENOBUFS, ENOSPC};
  8. use core::slice;
  9. use byteorder::{BigEndian, ByteOrder};
  10. pub const AF_INET: c_int = 2;
  11. pub const SOCK_STREAM: c_int = 1;
  12. pub const SOCK_DGRAM: c_int = 2;
  13. static mut NTOA_ADDR: [c_char; 16] = [0; 16];
  14. libc_fn!(unsafe inet_aton(cp: *const c_char, inp: *mut in_addr) -> c_int {
  15. // TODO: octal/hex
  16. inet_pton(AF_INET, cp, inp as *mut c_void)
  17. });
  18. libc_fn!(unsafe inet_ntoa(addr: in_addr) -> *const c_char {
  19. inet_ntop(AF_INET, &addr as *const in_addr as *const c_void, NTOA_ADDR.as_mut_ptr(), 16)
  20. });
  21. libc_fn!(unsafe inet_pton(domain: c_int, src: *const c_char, dest: *mut c_void) -> Result<c_int> {
  22. if domain != AF_INET {
  23. Err(Error::new(EAFNOSUPPORT))
  24. } else {
  25. let s_addr = &mut ((*(dest as *mut in_addr)).s_addr);
  26. let mut octets = str::from_utf8_unchecked(::cstr_to_slice(src)).split('.');
  27. for i in 0..4 {
  28. if let Some(n) = octets.next().and_then(|x| u8::from_str(x).ok()) {
  29. s_addr[i] = n;
  30. } else {
  31. return Ok(0);
  32. }
  33. }
  34. if octets.next() == None {
  35. Ok(1) // Success
  36. } else {
  37. Ok(0)
  38. }
  39. }
  40. });
  41. libc_fn!(unsafe inet_ntop(domain: c_int, src: *const c_void, dest: *mut c_char, size: socklen_t) -> Result<*const c_char> {
  42. if domain != AF_INET {
  43. Err(Error::new(EAFNOSUPPORT))
  44. } else if size < 16 {
  45. Err(Error::new(ENOSPC))
  46. } else {
  47. let s_addr = (&*(src as *const in_addr)).s_addr;
  48. let addr = format!("{}.{}.{}.{}\0", s_addr[0], s_addr[1], s_addr[2], s_addr[3]);
  49. ptr::copy(addr.as_ptr() as *const c_char, dest, addr.len());
  50. Ok(dest)
  51. }
  52. });
  53. libc_fn!(unsafe socket(domain: c_int, type_: c_int, protocol: c_int) -> Result<c_int> {
  54. if domain != AF_INET {
  55. Err(Error::new(EAFNOSUPPORT))
  56. } else if protocol != 0 {
  57. Err(Error::new(EPROTONOSUPPORT))
  58. } else {
  59. let fd = match type_ {
  60. SOCK_STREAM => syscall::open("tcp:", O_RDWR),
  61. SOCK_DGRAM => syscall::open("udp:", O_RDWR),
  62. _ => Err(Error::new(EPROTOTYPE))
  63. }?;
  64. Ok(fd as c_int)
  65. }
  66. });
  67. libc_fn!(unsafe connect(socket: c_int, address: *const sockaddr, _address_len: socklen_t) -> Result<c_int> {
  68. // XXX with UDP, should recieve messages only from that peer after this
  69. // XXX Check address_len
  70. if (*address).sa_family as i32 != AF_INET {
  71. return Err(Error::new(EINVAL))
  72. };
  73. let address = &*(address as *const sockaddr_in);
  74. let s_addr =address.sin_addr.s_addr;
  75. let path = format!("{}.{}.{}.{}:{}", s_addr[0], s_addr[1], s_addr[2], s_addr[3], ntohs(address.sin_port));
  76. let fd = syscall::dup(socket as usize, path.as_bytes())?;
  77. let ret = syscall::dup2(fd, socket as usize, &vec![]);
  78. let _ = syscall::close(fd);
  79. ret?;
  80. Ok(0)
  81. });
  82. libc_fn!(unsafe bind(socket: c_int, address: *const sockaddr, _address_len: socklen_t) -> Result<c_int> {
  83. // XXX Check address_len
  84. if (*address).sa_family as i32 != AF_INET {
  85. return Err(Error::new(EINVAL))
  86. };
  87. let address = &*(address as *const sockaddr_in);
  88. let s_addr =address.sin_addr.s_addr;
  89. let path = format!("/{}.{}.{}.{}:{}", s_addr[0], s_addr[1], s_addr[2], s_addr[3], ntohs(address.sin_port));
  90. let fd = syscall::dup(socket as usize, path.as_bytes())?;
  91. let ret = syscall::dup2(fd, socket as usize, &vec![]);
  92. let _ = syscall::close(fd);
  93. ret?;
  94. Ok(0)
  95. });
  96. libc_fn!(unsafe listen(_socket: c_int, _backlog: c_int) -> Result<c_int> {
  97. // TODO
  98. Ok(0)
  99. });
  100. libc_fn!(unsafe recv(socket: c_int, buffer: *mut c_void, length: size_t, flags: c_int) -> Result<ssize_t> {
  101. // XXX flags
  102. if flags != 0 {
  103. Err(Error::new(EOPNOTSUPP))
  104. } else {
  105. let buf = slice::from_raw_parts_mut(buffer as *mut u8, length);
  106. Ok(syscall::read(socket as usize, buf)? as ssize_t)
  107. }
  108. });
  109. libc_fn!(unsafe send(socket: c_int, buffer: *const c_void, length: size_t, flags: c_int) -> Result<ssize_t> {
  110. if flags != 0 {
  111. Err(Error::new(EOPNOTSUPP))
  112. } else {
  113. let buf = slice::from_raw_parts(buffer as *const u8, length);
  114. Ok(syscall::write(socket as usize, buf)? as ssize_t)
  115. }
  116. });
  117. libc_fn!(unsafe recvfrom(socket: c_int, buffer: *mut c_void, length: size_t, flags: c_int, _address: *const sockaddr, _address_len: *const socklen_t) -> Result<ssize_t> {
  118. let fd = syscall::dup(socket as usize, b"listen")?;
  119. let mut path = [0; 4096];
  120. syscall::fpath(socket as usize, &mut path)?;
  121. // XXX process path and write to address
  122. let ret = recv(socket, buffer, length, flags);
  123. syscall::close(fd)?;
  124. Ok(ret)
  125. });
  126. libc_fn!(unsafe sendto(socket: c_int, message: *const c_void, length: size_t, flags: c_int, dest_addr: *const sockaddr, _dest_len: socklen_t) -> Result<ssize_t> {
  127. // XXX test dest_len
  128. if (*dest_addr).sa_family as i32 == AF_INET {
  129. let addr = &*(dest_addr as *const sockaddr_in);
  130. let s_addr = addr.sin_addr.s_addr;
  131. let url = format!("{}.{}.{}.{}:{}", s_addr[0], s_addr[1], s_addr[2], s_addr[3], ntohs(addr.sin_port));
  132. let fd = syscall::dup(socket as usize, url.as_bytes())?;
  133. let ret = send(fd as c_int, message, length, flags);
  134. syscall::close(fd)?;
  135. Ok(ret)
  136. } else {
  137. Err(Error::new(EOPNOTSUPP))
  138. }
  139. });
  140. libc_fn!(unsafe getpeername(socket: c_int, address: *mut sockaddr, address_len: *mut socklen_t) -> Result<c_int> {
  141. // XXX will need to be changed for other sockaddr types
  142. if *address_len < mem::size_of::<sockaddr_in>() {
  143. return Err(Error::new(ENOBUFS));
  144. }
  145. *address_len = mem::size_of::<sockaddr_in>();
  146. let addr = &mut *(address as *mut sockaddr_in);
  147. addr.sin_family = AF_INET as u16;
  148. let mut path = [0; 4096];
  149. syscall::fpath(socket as usize, &mut path)?;
  150. let start;
  151. let sep;
  152. let end;
  153. {
  154. let mut iter = path.iter();
  155. start = iter.position(|x| *x == b':').ok_or(Error::new(EINVAL))? + 1;
  156. sep = start + iter.position(|x| *x == b':').ok_or(Error::new(EINVAL))?;
  157. end = sep + 1 + iter.position(|x| *x == b'/').ok_or(Error::new(EINVAL))?;
  158. }
  159. path[sep] = b'\0';
  160. if inet_aton(&path[start] as *const u8 as *const c_char, &mut addr.sin_addr) == 1 {
  161. if let Ok(port) = u16::from_str(str::from_utf8_unchecked(&path[sep+1..end])) {
  162. addr.sin_port = htons(port);
  163. Ok(0)
  164. } else {
  165. Err(Error::new(EINVAL))
  166. }
  167. } else {
  168. Err(Error::new(EINVAL)) // ?
  169. }
  170. });
  171. libc_fn!(unsafe getsockname(socket: c_int, address: *mut sockaddr, address_len: *mut socklen_t) -> Result<c_int> {
  172. // XXX will need to be changed for other sockaddr types
  173. if *address_len < mem::size_of::<sockaddr_in>() {
  174. return Err(Error::new(ENOBUFS));
  175. }
  176. *address_len = mem::size_of::<sockaddr_in>();
  177. let addr = &mut *(address as *mut sockaddr_in);
  178. addr.sin_family = AF_INET as u16;
  179. let mut path = [0; 4096];
  180. syscall::fpath(socket as usize, &mut path)?;
  181. let start;
  182. let sep;
  183. let end;
  184. {
  185. let mut iter = path.iter();
  186. start = iter.position(|x| *x == b'/').ok_or(Error::new(EINVAL))? + 1;
  187. sep = start + iter.position(|x| *x == b':').ok_or(Error::new(EINVAL))?;
  188. end = sep + 1 + iter.position(|x| *x == b'\0').ok_or(Error::new(EINVAL))?;
  189. }
  190. path[sep] = b'\0';
  191. if inet_aton(&path[start] as *const u8 as *const c_char, &mut addr.sin_addr) == 1 {
  192. if let Ok(port) = u16::from_str(str::from_utf8_unchecked(&path[sep+1..end])) {
  193. addr.sin_port = htons(port);
  194. Ok(0)
  195. } else {
  196. Err(Error::new(EINVAL))
  197. }
  198. } else {
  199. Err(Error::new(EINVAL)) // ?
  200. }
  201. });
  202. libc_fn!(htonl(hostlong: u32) -> [u8; 4] {
  203. let mut netlong = [0; 4];
  204. BigEndian::write_u32(&mut netlong, hostlong);
  205. netlong
  206. });
  207. libc_fn!(htons(hostshort: u16) -> [u8; 2] {
  208. let mut netshort = [0; 2];
  209. BigEndian::write_u16(&mut netshort, hostshort);
  210. netshort
  211. });
  212. libc_fn!(ntohl(netlong: [u8; 4]) -> u32 {
  213. BigEndian::read_u32(&netlong)
  214. });
  215. libc_fn!(ntohs(netshort: [u8; 2]) -> u16 {
  216. BigEndian::read_u16(&netshort)
  217. });
  218. libc_fn!(setsockopt(socket: c_int, level: c_int, option_name: c_int, option_value: *const c_void, option_len: socklen_t) -> Result<c_int> {
  219. syscall::write(2, format!("unimplemented: setsockopt({}, {}, {}, {:?}, {})\n",
  220. socket, level, option_name, option_value, option_len).as_bytes()).unwrap();
  221. Err(Error::new(syscall::ENOSYS))
  222. });