diff --git a/CHANGELOG.md b/CHANGELOG.md index 94663ace555..89a2aa4c669 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Added set_promiscuous function in EthDriver (#246) - Added set_promiscuous, is_promiscuous functions in WifiDriver (#246) - Blocking and buffered StdIo (#541) - i.e. easy reading/input from `std::io::stdin` +- Added source_ipv4, source_ipv6 function in EspHttpRawConnection (#538) ### Fixed - The alloc::Vec version stomps the scan state from Done to Idle. (#459) diff --git a/src/http/server.rs b/src/http/server.rs index bdd02d18e6a..310dc0e77a0 100644 --- a/src/http/server.rs +++ b/src/http/server.rs @@ -35,6 +35,10 @@ use core::cell::UnsafeCell; use core::fmt::Debug; use core::marker::PhantomData; +#[cfg(esp_idf_lwip_ipv4)] +use core::net::Ipv4Addr; +#[cfg(esp_idf_lwip_ipv6)] +use core::net::Ipv6Addr; use core::sync::atomic::{AtomicBool, Ordering}; use core::time::*; use core::{ffi, ptr}; @@ -799,6 +803,62 @@ impl EspHttpRawConnection<'_> { Ok(()) } + + /// Retrieves the source IPv4 of the request. + /// + /// The IPv4 is retrieved using the underlying session socket. + #[cfg(esp_idf_lwip_ipv4)] + pub fn source_ipv4(&self) -> Result { + unsafe { + let sockfd = httpd_req_to_sockfd(self.handle()); + + if sockfd == -1 { + return Err(EspError::from_infallible::()); + } + + let mut addr = sockaddr_in { + sin_len: core::mem::size_of::() as _, + sin_family: AF_INET as _, + ..Default::default() + }; + + esp!(lwip_getpeername( + sockfd, + &mut addr as *mut _ as *mut _, + &mut core::mem::size_of::() as *mut _ as *mut _, + ))?; + + Ok(Ipv4Addr::from(addr.sin_addr.s_addr)) + } + } + + /// Retrieves the source IPv6 of the request. + /// + /// The IPv6 is retrieved using the underlying session socket. + #[cfg(esp_idf_lwip_ipv6)] + pub fn source_ipv6(&self) -> Result { + unsafe { + let sockfd = httpd_req_to_sockfd(self.handle()); + + if sockfd == -1 { + return Err(EspError::from_infallible::()); + } + + let mut addr = sockaddr_in6 { + sin6_len: core::mem::size_of::() as _, + sin6_family: AF_INET6 as _, + ..Default::default() + }; + + esp!(lwip_getpeername( + sockfd, + &mut addr as *mut _ as *mut _, + &mut core::mem::size_of::() as *mut _ as *mut _, + ))?; + + Ok(Ipv6Addr::from(addr.sin6_addr.un.u8_addr)) + } + } } impl RawHandle for EspHttpRawConnection<'_> {