add local/remote address env vars for cgi
authorFelix Fietkau <nbd@openwrt.org>
Wed, 2 Jan 2013 12:23:55 +0000 (13:23 +0100)
committerFelix Fietkau <nbd@openwrt.org>
Wed, 2 Jan 2013 12:23:55 +0000 (13:23 +0100)
client.c
proc.c
uhttpd.h

index a76d11e61ddd2eb4ae52c1b0acf3befaa69da5b8..1b9c52443b13a11393c4af1481b64852360f233a 100644 (file)
--- a/client.c
+++ b/client.c
@@ -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;
diff --git a/proc.c b/proc.c
index 4880727f6b01b4f1e02b54afd5cbb4152cea65ef..a4c919a745924ea13ebb609810d51c6e7a7fb862 100644 (file)
--- a/proc.c
+++ b/proc.c
@@ -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++) {
index 24ad83de82718e329353e3530735b7c35f5083c6..3cbe46f370fc20e60a81c27191214be928abecc5 100644 (file)
--- a/uhttpd.h
+++ b/uhttpd.h
@@ -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;