Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add source_ipv4, source_ipv6 functions in EspHttpRawConnection #539

Merged
merged 14 commits into from
Jan 1, 2025
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Allow using esp timer with skip_unhandled_events (#526)
- OTA - Implements a new type `EspFirmwareInfoLoad` that has a reduced memory consumption (#531)
- Added set_promiscuous function in EthDriver (#246)
- Add source_ip4, source_ip6 function in EspHttpRawConnection (#538)

### Fixed
- The alloc::Vec version stomps the scan state from Done to Idle. (#459)
Expand Down
106 changes: 106 additions & 0 deletions src/http/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -799,6 +803,108 @@ 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_ip4(&self) -> Result<Ipv4Addr, EspError> {
unsafe {
let sockfd = httpd_req_to_sockfd(self.handle());

if sockfd == -1 {
return Err(EspError::from(-1).unwrap());
indexds marked this conversation as resolved.
Show resolved Hide resolved
}

let mut addr = sockaddr_in {
sin_len: core::mem::size_of::<sockaddr_in>() as u8,
sin_family: AF_INET as u8,
..Default::default()
};

let mut addr_len = core::mem::size_of::<sockaddr_in>() as socklen_t;

esp!(lwip_getpeername(
sockfd,
&mut addr as *mut _ as *mut sockaddr,
&mut addr_len,
))?;

//"255.255.255.255\0" = 16 bytes
indexds marked this conversation as resolved.
Show resolved Hide resolved
let mut ip_string: [ffi::c_char; 16] = [0; 16];

if lwip_inet_ntop(
AF_INET as _,
&addr.sin_addr as *const _ as *const _,
&mut ip_string as *mut [ffi::c_char] as *mut ffi::c_char,
ip_string.len() as _,
)
.is_null()
{
return Err(EspError::from(-1).unwrap());
}

let ip: Ipv4Addr =
CStr::from_ptr(&ip_string as *const [ffi::c_char] as *const ffi::c_char)
.to_str()
.map_err(|_| EspError::from(-1).unwrap())?
.parse()
.map_err(|_| EspError::from(-1).unwrap())?;

Ok(ip)
}
}

/// Retrieves the source IPv6 of the request.
///
/// The IPv6 is retrieved using the underlying session socket.
#[cfg(esp_idf_lwip_ipv6)]
pub fn source_ip6(&self) -> Result<Ipv6Addr, EspError> {
unsafe {
let sockfd = httpd_req_to_sockfd(self.handle());

if sockfd == -1 {
return Err(EspError::from(-1).unwrap());
}

let mut addr = sockaddr_in6 {
sin6_len: core::mem::size_of::<sockaddr_in6>() as u8,
sin6_family: AF_INET6 as u8,
..Default::default()
};

let mut addr_len = core::mem::size_of::<sockaddr_in6>() as socklen_t;

esp!(lwip_getpeername(
sockfd,
&mut addr as *mut _ as *mut sockaddr,
&mut addr_len,
))?;

// IPv6 address = 39 bytes + null terminator
let mut ip_string: [ffi::c_char; 40] = [0; 40];
indexds marked this conversation as resolved.
Show resolved Hide resolved

if lwip_inet_ntop(
AF_INET6 as _,
&addr.sin6_addr as *const _ as *const _,
&mut ip_string as *mut [ffi::c_char] as *mut ffi::c_char,
ip_string.len() as _,
)
.is_null()
{
return Err(EspError::from(-1).unwrap());
}

let ip: Ipv6Addr =
CStr::from_ptr(&ip_string as *const [ffi::c_char] as *const ffi::c_char)
.to_str()
.map_err(|_| EspError::from(-1).unwrap())?
.parse()
.map_err(|_| EspError::from(-1).unwrap())?;

Ok(ip)
}
}
}

impl RawHandle for EspHttpRawConnection<'_> {
Expand Down
Loading