Page 1 of 1

webserver - how to get incoming http request IP address

Posted: Tue Jan 01, 2019 11:48 pm
by J00003
I am using the webserver component as documented here: https://docs.espressif.com/projects/esp ... erver.html, and have the basics working.
But am wondering how to retrieve the IP address of the far-end or client for an incoming http request. Is it available some how thru the session or transport context?
The docs and example code don't give any clues...
Thanks,

Re: webserver - how to get incoming http request IP address

Posted: Wed Jan 02, 2019 9:56 am
by ESP_Anurag
Hi,

You need to use the httpd_req_to_sockfd() function to obtain the sockfd of a client inside a request handler, then use getpeername() function (include <sys/socket.h>) to get the IP address from the sockfd.

Here is an example function that you can try invoking inside your request handler for printing the IP address:

Code: Select all

void print_client_ip(httpd_req_t *req)
{
    int sockfd = httpd_req_to_sockfd(req);
    char ipstr[INET6_ADDRSTRLEN];
    struct sockaddr_in6 addr;   // esp_http_server uses IPv6 addressing
    socklen_t addr_size = sizeof(addr);
    
    if (getpeername(sockfd, (struct sockaddr *)&addr, &addr_size) < 0) {
        ESP_LOGE(TAG, "Error getting client IP");
        return;
    }
    
    // Convert to IPv6 string
    inet_ntop(AF_INET, &addr.sin6_addr, ipstr, sizeof(ipstr));
    ESP_LOGI(TAG, "Client IP => %s", ipstr);
}
Now, you may prefer to print the IPv4 part of the address, in which case you can do (as described in this post http://bbs.esp32.com/viewtopic.php?t=8317):

Code: Select all

    // Convert to IPv4 string
    inet_ntop(AF_INET, &addr.sin6_addr.un.u32_addr[3], ipstr, sizeof(ipstr));
    ESP_LOGI(TAG, "Client IP => %s", ipstr);

Re: webserver - how to get incoming http request IP address

Posted: Thu Jan 03, 2019 12:42 am
by J00003
Thank you @ESP_Anurag, I'll give that a try.

Re: webserver - how to get incoming http request IP address

Posted: Tue Sep 07, 2021 12:25 pm
by Craige Hales
Thanks!
Pretty sure the IPv6 call should use AF_INET6:

Code: Select all

inet_ntop(AF_INET6, &addr.sin6_addr, ipstr, sizeof(ipstr));
I wanted to understand the [3] for the IPv4 call, here's some info:

https://datatracker.ietf.org/doc/html/r ... on-2.5.5.2 :
IPv4-Mapped IPv6 Address
A second type of IPv6 address that holds an embedded IPv4 address is
defined. This address type is used to represent the addresses of
IPv4 nodes as IPv6 addresses. The format of the "IPv4-mapped IPv6
address" is as follows:

Code: Select all

   |                80 bits               | 16 |      32 bits        |
   +--------------------------------------+--------------------------+
   |0000..............................0000|FFFF|    IPv4 address     |
   +--------------------------------------+----+---------------------+
which is what I see with AF_INET6:

Code: Select all

I (183749) file_server: Client IP => ::FFFF:192.168.4.121

Re: webserver - how to get incoming http request IP address

Posted: Thu Sep 07, 2023 10:46 pm
by sinmosh
@ESP_Anurag Thank you for the great hint!