diff options
-rw-r--r-- | client.c | 26 | ||||
-rw-r--r-- | proc.c | 26 | ||||
-rw-r--r-- | uhttpd.h | 12 |
3 files changed, 54 insertions, 10 deletions
@@ -300,6 +300,21 @@ static void client_notify_state(struct ustream *s) return client_close(cl); } +static void set_addr(struct uh_addr *addr, void *src) +{ + struct sockaddr_in *sin = src; + struct sockaddr_in6 *sin6 = src; + + addr->family = sin->sin_family; + if (addr->family == AF_INET) { + addr->port = ntohs(sin->sin_port); + memcpy(&addr->in, &sin->sin_addr, sizeof(addr->in)); + } else { + addr->port = ntohs(sin6->sin6_port); + memcpy(&addr->in6, &sin6->sin6_addr, sizeof(addr->in6)); + } +} + void uh_accept_client(int fd) { static struct client *next_client; @@ -307,19 +322,22 @@ void uh_accept_client(int fd) unsigned int sl; int sfd; static int client_id = 0; + struct sockaddr_in6 addr; if (!next_client) next_client = calloc(1, sizeof(*next_client)); cl = next_client; - sl = sizeof(cl->peeraddr); - sfd = accept(fd, (struct sockaddr *) &cl->peeraddr, &sl); + sl = sizeof(addr); + sfd = accept(fd, (struct sockaddr *) &addr, &sl); if (sfd < 0) return; - sl = sizeof(cl->servaddr); - getsockname(fd, (struct sockaddr *) &cl->servaddr, &sl); + set_addr(&cl->peer_addr, &addr); + sl = sizeof(addr); + getsockname(fd, (struct sockaddr *) &addr, &sl); + set_addr(&cl->srv_addr, &addr); cl->us = &cl->sfd.stream; cl->us->string_data = true; cl->us->notify_read = client_ustream_read_cb; @@ -17,6 +17,7 @@ * limitations under the License. */ +#include <arpa/inet.h> #include <libubox/blobmsg.h> #include "uhttpd.h" @@ -81,10 +82,20 @@ enum extra_vars { VAR_PATH_INFO, VAR_USER, VAR_REDIRECT, + VAR_SERVER_NAME, + VAR_SERVER_ADDR, + VAR_SERVER_PORT, + VAR_REMOTE_NAME, + VAR_REMOTE_ADDR, + VAR_REMOTE_PORT, __VAR_MAX, }; +static char local_addr[INET6_ADDRSTRLEN], remote_addr[INET6_ADDRSTRLEN]; +static char local_port[6], remote_port[6]; +static char redirect_status[4]; + static struct env_var extra_vars[] = { [_VAR_GW] = { "GATEWAY_INTERFACE", "CGI/1.1" }, [_VAR_SOFTWARE] = { "SERVER_SOFTWARE", "uhttpd" }, @@ -97,7 +108,13 @@ static struct env_var extra_vars[] = { [VAR_METHOD] = { "REQUEST_METHOD" }, [VAR_PATH_INFO] = { "PATH_INFO" }, [VAR_USER] = { "REMOTE_USER" }, - [VAR_REDIRECT] = { "REDIRECT_STATUS" }, + [VAR_REDIRECT] = { "REDIRECT_STATUS", redirect_status }, + [VAR_SERVER_NAME] = { "SERVER_NAME", local_addr }, + [VAR_SERVER_ADDR] = { "SERVER_ADDR", local_addr }, + [VAR_SERVER_PORT] = { "SERVER_PORT", local_port }, + [VAR_REMOTE_NAME] = { "REMOTE_HOST", remote_addr }, + [VAR_REMOTE_ADDR] = { "REMOTE_ADDR", remote_addr }, + [VAR_REMOTE_PORT] = { "REMOTE_PORT", remote_port }, }; struct env_var *uh_get_process_vars(struct client *cl, struct path_info *pi) @@ -106,7 +123,6 @@ struct env_var *uh_get_process_vars(struct client *cl, struct path_info *pi) struct blob_attr *data = cl->hdr.head; struct env_var *vars = (void *) uh_buf; struct blob_attr *tb[__HDR_MAX]; - static char buf[4]; int len; int i; @@ -126,8 +142,10 @@ struct env_var *uh_get_process_vars(struct client *cl, struct path_info *pi) extra_vars[VAR_PATH_INFO].value = pi->info; extra_vars[VAR_USER].value = req->realm ? req->realm->user : NULL; - snprintf(buf, sizeof(buf), "%d", req->redirect_status); - extra_vars[VAR_REDIRECT].value = buf; + snprintf(redirect_status, sizeof(redirect_status), + "%d", req->redirect_status); + inet_ntop(cl->srv_addr.family, &cl->srv_addr.in, local_addr, sizeof(local_addr)); + inet_ntop(cl->peer_addr.family, &cl->peer_addr.in, remote_addr, sizeof(remote_addr)); blobmsg_parse(hdr_policy, __HDR_MAX, tb, blob_data(data), blob_len(data)); for (i = 0; i < ARRAY_SIZE(proc_header_env); i++) { @@ -136,6 +136,15 @@ struct dispatch_handler { void (*handle_request)(struct client *cl, const char *url, struct path_info *pi); }; +struct uh_addr { + uint8_t family; + uint16_t port; + union { + struct in_addr in; + struct in6_addr in6; + }; +}; + struct client { struct list_head list; int id; @@ -150,8 +159,7 @@ struct client { enum client_state state; struct http_request request; - struct sockaddr_in6 servaddr; - struct sockaddr_in6 peeraddr; + struct uh_addr srv_addr, peer_addr; struct blob_buf hdr; |