From b6de2904f05cfb3334f36bee61052441c5809874 Mon Sep 17 00:00:00 2001 From: Ruben van Staveren Date: Fri, 20 Jun 2014 14:11:25 +0200 Subject: [PATCH 1/3] FreeBSD way of doing transparent proxy: work in progress --- common.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/common.c b/common.c index a297176..7af9ee1 100644 --- a/common.c +++ b/common.c @@ -120,8 +120,13 @@ int bind_peer(int fd, int fd_from) * got here */ res = getpeername(fd_from, from.ai_addr, &from.ai_addrlen); CHECK_RES_RETURN(res, "getpeername"); - res = setsockopt(fd, IPPROTO_IP, IP_TRANSPARENT, &trans, sizeof(trans)); - CHECK_RES_DIE(res, "setsockopt"); + if (from.ai_addr->sa_family==AF_INET) { /* IPv4 */ + res = setsockopt(fd, IPPROTO_IP, IP_BINDANY, &trans, sizeof(trans)); + CHECK_RES_RETURN(res, "setsockopt IP_BINDANY"); + } else { /* IPv6 */ + res = setsockopt(fd, IPPROTO_IPV6, IPV6_BINDANY, &trans, sizeof(trans)); + CHECK_RES_RETURN(res, "setsockopt IPV6_BINDANY"); + } res = bind(fd, from.ai_addr, from.ai_addrlen); CHECK_RES_RETURN(res, "bind"); @@ -143,6 +148,8 @@ int connect_addr(struct connection *cnx, int fd_from) fprintf(stderr, "connecting to %s family %d len %d\n", sprintaddr(buf, sizeof(buf), a), a->ai_addr->sa_family, a->ai_addrlen); + + /* XXX Needs to match ai_family from fd_from when being transparent! */ fd = socket(a->ai_family, SOCK_STREAM, 0); if (fd == -1) { log_message(LOG_ERR, "forward to %s failed:socket: %s\n", From dedb3672d785210ae80b44eab36ea65dd46461e8 Mon Sep 17 00:00:00 2001 From: Ruben van Staveren Date: Tue, 22 Jul 2014 19:36:29 +0200 Subject: [PATCH 2/3] Have USELIBWRAP redefineable --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 800af29..2e9de22 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ VERSION=$(shell ./genver.sh -r) USELIBCONFIG=1 # Use libconfig? (necessary to use configuration files) -USELIBWRAP= # Use libwrap? +USELIBWRAP?= # Use libwrap? USELIBCAP= # Use libcap? COV_TEST= # Perform test coverage? PREFIX=/usr/local From 7d23a5523670075f6077d94efc4e1a1d9a8ebedc Mon Sep 17 00:00:00 2001 From: Ruben van Staveren Date: Tue, 22 Jul 2014 19:36:40 +0200 Subject: [PATCH 3/3] When transparent, make sure both connections use the same address family --- common.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/common.c b/common.c index 7af9ee1..139481e 100644 --- a/common.c +++ b/common.c @@ -139,11 +139,22 @@ int bind_peer(int fd, int fd_from) * of new file descriptor. */ int connect_addr(struct connection *cnx, int fd_from) { - struct addrinfo *a; + struct addrinfo *a, from; + struct sockaddr_storage ss; char buf[NI_MAXHOST]; int fd, res; + memset(&from, 0, sizeof(from)); + from.ai_addr = (struct sockaddr*)&ss; + from.ai_addrlen = sizeof(ss); + + res = getpeername(fd_from, from.ai_addr, &from.ai_addrlen); + CHECK_RES_RETURN(res, "getpeername"); + for (a = cnx->proto->saddr; a; a = a->ai_next) { + /* When transparent, make sure both connections use the same address family */ + if (transparent && a->ai_family != from.ai_addr->sa_family) + continue; if (verbose) fprintf(stderr, "connecting to %s family %d len %d\n", sprintaddr(buf, sizeof(buf), a),