From 9267cf9bb401d1275e5377e19fb48dd44fb77e6d Mon Sep 17 00:00:00 2001 From: Adam Jacob Muller Date: Sun, 8 Feb 2015 20:20:02 -0500 Subject: [PATCH] add support for: %f - dest address %h - dest port %t - source address %v - source port format specifiers to pathspec --- log.c | 44 +++++++++++++++++++++++++++++---------- log.h | 3 ++- main.c | 8 ++++++-- pxyconn.c | 15 +++++++++++++- sys.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ sys.h | 2 ++ 6 files changed, 118 insertions(+), 15 deletions(-) diff --git a/log.c b/log.c index ef14442..5c70964 100644 --- a/log.c +++ b/log.c @@ -272,11 +272,15 @@ log_content_file_fini(void) */ #define PATH_BUF_INC 1024 static char * -log_content_format_pathspec(const char *logspec, char *srcaddr, char *dstaddr, +log_content_format_pathspec(const char *logspec, + char *src_str, char *src_host, char *src_serv, + char *dst_str, char *dst_host, char *dst_serv, char *exec_path, char *user, char *group) WUNRES MALLOC NONNULL(1,2,3); static char * -log_content_format_pathspec(const char *logspec, char *srcaddr, char *dstaddr, +log_content_format_pathspec(const char *logspec, + char *src_str, char *src_host, char *src_serv, + char *dst_str, char *dst_host, char *dst_serv, char *exec_path, char *user, char *group) { /* set up buffer to hold our generated file path */ @@ -316,12 +320,28 @@ log_content_format_pathspec(const char *logspec, char *srcaddr, char *dstaddr, elem_len = 1; break; case 'd': - elem = dstaddr; - elem_len = strlen(dstaddr); + elem = dst_str; + elem_len = strlen(dst_str); + break; + case 'f': + elem = dst_host; + elem_len = strlen(dst_host); + break; + case 'h': + elem = dst_serv; + elem_len = strlen(dst_serv); break; case 's': - elem = srcaddr; - elem_len = strlen(srcaddr); + elem = src_str; + elem_len = strlen(src_str); + break; + case 't': + elem = src_host; + elem_len = strlen(src_host); + break; + case 'v': + elem = src_serv; + elem_len = strlen(src_serv); break; case 'x': if (exec_path) { @@ -397,7 +417,8 @@ log_content_format_pathspec(const char *logspec, char *srcaddr, char *dstaddr, int log_content_open(log_content_ctx_t **pctx, opts_t *opts, - char *srcaddr, char *dstaddr, + char *src_str, char *src_host, char *src_serv, + char *dst_str, char *dst_host, char *dst_serv, char *exec_path, char *user, char *group) { log_content_ctx_t *ctx; @@ -431,7 +452,7 @@ log_content_open(log_content_ctx_t **pctx, opts_t *opts, goto errout; } if (asprintf(&ctx->u.dir.filename, "%s/%s-%s-%s.log", - opts->contentlog, timebuf, srcaddr, dstaddr) < 0) { + opts->contentlog, timebuf, src_str, dst_str) < 0) { log_err_printf("Failed to format filename: %s (%i)\n", strerror(errno), errno); goto errout; @@ -440,7 +461,8 @@ log_content_open(log_content_ctx_t **pctx, opts_t *opts, /* per-connection-file content log with logspec (-F) */ ctx->u.spec.filename = log_content_format_pathspec( opts->contentlog, - srcaddr, dstaddr, + src_str, src_host, src_serv, + dst_str, dst_host, dst_serv, exec_path, user, group); if (!ctx->u.spec.filename) { goto errout; @@ -449,11 +471,11 @@ log_content_open(log_content_ctx_t **pctx, opts_t *opts, /* single-file content log (-L) */ ctx->fd = content_fd; if (asprintf(&ctx->u.file.header_req, "%s -> %s", - srcaddr, dstaddr) < 0) { + src_str, dst_str) < 0) { goto errout; } if (asprintf(&ctx->u.file.header_resp, "%s -> %s", - dstaddr, srcaddr) < 0) { + dst_str, src_str) < 0) { free(ctx->u.file.header_req); goto errout; } diff --git a/log.h b/log.h index 92fbe5e..201aad9 100644 --- a/log.h +++ b/log.h @@ -59,7 +59,8 @@ extern logger_t *connect_log; typedef struct log_content_ctx log_content_ctx_t; int log_content_open(log_content_ctx_t **, opts_t *, char *, char *, - char *, char *, char *) NONNULL(1,2,3) WUNRES; + char *, char *, char *, char *, char *, char *, char *) + NONNULL(1,2,3) WUNRES; int log_content_submit(log_content_ctx_t *, logbuf_t *, int) NONNULL(1,2) WUNRES; int log_content_close(log_content_ctx_t **) NONNULL(1) WUNRES; diff --git a/main.c b/main.c index 617047f..3f870bc 100644 --- a/main.c +++ b/main.c @@ -149,8 +149,12 @@ main_usage(void) " -S logdir content log: full data to separate files in dir (excludes -L/-F)\n" " -F pathspec content log: full data to sep files with %% subst (excl. -L/-S):\n" " %%T - initial connection time as an ISO 8601 UTC timestamp\n" -" %%d - dest address:port\n" -" %%s - source address:port\n" +" %%d - [dest address]:port\n" +" %%f - dest address\n" +" %%h - dest port\n" +" %%s - [source address]:port\n" +" %%t - source address\n" +" %%v - source port\n" #ifdef HAVE_LOCAL_PROCINFO " %%x - base name of local process (requires -i)\n" " %%X - full path to local process (requires -i)\n" diff --git a/pxyconn.c b/pxyconn.c index 3cefc66..6ae4393 100644 --- a/pxyconn.c +++ b/pxyconn.c @@ -134,7 +134,11 @@ typedef struct pxy_conn_ctx { /* log strings from socket */ char *src_str; + char *src_host; + char *src_serv; char *dst_str; + char *dst_host; + char *dst_serv; /* log strings from HTTP request */ char *http_method; @@ -1702,6 +1706,12 @@ pxy_bev_eventcb(struct bufferevent *bev, short events, void *arg) ctx->dst_str = sys_sockaddr_str((struct sockaddr *) &ctx->addr, ctx->addrlen); + ctx->dst_host = sys_sockaddr_str_host((struct sockaddr *) + &ctx->addr, + ctx->addrlen); + ctx->dst_serv = sys_sockaddr_str_serv((struct sockaddr *) + &ctx->addr, + ctx->addrlen); if (!ctx->dst_str) { ctx->enomem = 1; pxy_conn_terminate_free(ctx); @@ -1736,7 +1746,8 @@ pxy_bev_eventcb(struct bufferevent *bev, short events, void *arg) } if (WANT_CONTENT_LOG(ctx)) { if (log_content_open(&ctx->logctx, ctx->opts, - ctx->src_str, ctx->dst_str, + ctx->src_str, ctx->src_host, ctx->src_serv, + ctx->dst_str, ctx->dst_host, ctx->dst_serv, #ifdef HAVE_LOCAL_PROCINFO ctx->lproc.exec_path, ctx->lproc.user, @@ -2169,6 +2180,8 @@ pxy_conn_setup(evutil_socket_t fd, /* prepare logging, part 1 */ if (WANT_CONNECT_LOG(ctx) || WANT_CONTENT_LOG(ctx)) { ctx->src_str = sys_sockaddr_str(peeraddr, peeraddrlen); + ctx->src_host = sys_sockaddr_str_host(peeraddr, peeraddrlen); + ctx->src_serv = sys_sockaddr_str_serv(peeraddr, peeraddrlen); if (!ctx->src_str) goto memout; #ifdef HAVE_LOCAL_PROCINFO diff --git a/sys.c b/sys.c index e3c9b9f..9155af1 100644 --- a/sys.c +++ b/sys.c @@ -334,6 +334,67 @@ sys_sockaddr_parse(struct sockaddr_storage *addr, socklen_t *addrlen, return af; } +/* + * Converts an IPv4/IPv6 sockaddr into a printable string representation. + * Returns an allocated buffer which must be freed by caller, or NULL on error. + */ +char * +sys_sockaddr_str_serv(struct sockaddr *addr, socklen_t addrlen) +{ + char host[INET6_ADDRSTRLEN], serv[6]; + char *buf; + int rv; + size_t bufsz; + + bufsz = sizeof(host) + sizeof(serv) + 3; + buf = malloc(bufsz); + if (!buf) { + log_err_printf("Cannot allocate memory\n"); + return NULL; + } + rv = getnameinfo(addr, addrlen, host, sizeof(host), serv, sizeof(serv), + NI_NUMERICHOST | NI_NUMERICSERV); + if (rv != 0) { + log_err_printf("Cannot get nameinfo for socket address: %s\n", + gai_strerror(rv)); + free(buf); + return NULL; + } + snprintf(buf, bufsz, "%s", serv); + return buf; +} + +/* + * Converts an IPv4/IPv6 sockaddr into a printable string representation. + * Returns an allocated buffer which must be freed by caller, or NULL on error. + */ +char * +sys_sockaddr_str_host(struct sockaddr *addr, socklen_t addrlen) +{ + char host[INET6_ADDRSTRLEN], serv[6]; + char *buf; + int rv; + size_t bufsz; + + bufsz = sizeof(host) + sizeof(serv) + 3; + buf = malloc(bufsz); + if (!buf) { + log_err_printf("Cannot allocate memory\n"); + return NULL; + } + rv = getnameinfo(addr, addrlen, host, sizeof(host), serv, sizeof(serv), + NI_NUMERICHOST | NI_NUMERICSERV); + if (rv != 0) { + log_err_printf("Cannot get nameinfo for socket address: %s\n", + gai_strerror(rv)); + free(buf); + return NULL; + } + snprintf(buf, bufsz, "%s", host); + return buf; +} + + /* * Converts an IPv4/IPv6 sockaddr into a printable string representation. * Returns an allocated buffer which must be freed by caller, or NULL on error. diff --git a/sys.h b/sys.h index 0af0368..6162c88 100644 --- a/sys.h +++ b/sys.h @@ -47,6 +47,8 @@ char * sys_group_str(gid_t) MALLOC; int sys_sockaddr_parse(struct sockaddr_storage *, socklen_t *, char *, char *, int, int) NONNULL(1,2,3,4) WUNRES; char * sys_sockaddr_str(struct sockaddr *, socklen_t) NONNULL(1) MALLOC; +char * sys_sockaddr_str_host(struct sockaddr *, socklen_t) NONNULL(1) MALLOC; +char * sys_sockaddr_str_serv(struct sockaddr *, socklen_t) NONNULL(1) MALLOC; int sys_isdir(const char *) NONNULL(1) WUNRES; int sys_mkpath(const char *, mode_t) NONNULL(1) WUNRES;