Set the host-side IP address for the tap interface.
(&self, ip_addr: IpAddr, netmask: Option<IpAddr>)
| 296 | |
| 297 | /// Set the host-side IP address for the tap interface. |
| 298 | pub fn set_ip_addr(&self, ip_addr: IpAddr, netmask: Option<IpAddr>) -> Result<()> { |
| 299 | let sock = create_inet_socket(ip_addr).map_err(Error::NetUtil)?; |
| 300 | |
| 301 | let mut ifreq = self.get_ifreq(); |
| 302 | |
| 303 | match ip_addr { |
| 304 | IpAddr::V4(addr) => { |
| 305 | let addr = create_sockaddr(addr); |
| 306 | |
| 307 | ifreq.ifr_ifru.ifru_addr = addr; |
| 308 | |
| 309 | // SAFETY: ioctl is safe. Called with a valid sock fd, and we check the return. |
| 310 | unsafe { |
| 311 | Self::ioctl_with_ref(&sock, libc::SIOCSIFADDR as c_ulong, &ifreq)?; |
| 312 | } |
| 313 | |
| 314 | if let Some(IpAddr::V4(mask)) = netmask { |
| 315 | ifreq.ifr_ifru.ifru_netmask = create_sockaddr(mask); |
| 316 | |
| 317 | // SAFETY: ioctl is safe. Called with a valid sock fd, and we check the return. |
| 318 | unsafe { |
| 319 | Self::ioctl_with_ref(&sock, libc::SIOCSIFNETMASK as c_ulong, &ifreq)?; |
| 320 | } |
| 321 | } |
| 322 | |
| 323 | Ok(()) |
| 324 | } |
| 325 | IpAddr::V6(addr) => { |
| 326 | let ifindex = { |
| 327 | // SAFETY: ioctl is safe. Called with a valid sock fd, and we check the return. |
| 328 | unsafe { |
| 329 | Self::ioctl_with_ref(&sock, libc::SIOCGIFINDEX as c_ulong, &ifreq)?; |
| 330 | } |
| 331 | |
| 332 | // SAFETY: ifru_ivalue contains the ifindex and is set by the previous ioctl |
| 333 | unsafe { |
| 334 | match ifreq.ifr_ifru.ifru_ifindex { |
| 335 | 0 => { |
| 336 | let name = self.if_name.to_string_lossy().to_string(); |
| 337 | return Err(Error::InvalidIfname(name)); |
| 338 | } |
| 339 | i => i, |
| 340 | } |
| 341 | } |
| 342 | }; |
| 343 | |
| 344 | let prefixlen = match netmask { |
| 345 | Some(IpAddr::V6(netmask)) => ipv6_mask_to_prefix(netmask)?, |
| 346 | Some(IpAddr::V4(_)) => return Err(Error::InvalidNetmask), |
| 347 | None => 0, |
| 348 | }; |
| 349 | |
| 350 | let ifreq = libc::in6_ifreq { |
| 351 | // SAFETY: addr can be safely transmuted to in6_addr |
| 352 | ifr6_addr: unsafe { |
| 353 | std::mem::transmute::<[u8; 16], libc::in6_addr>(addr.octets()) |
| 354 | }, |
| 355 | ifr6_prefixlen: prefixlen as u32, |