Module Name: src Committed By: christos Date: Sat Dec 10 05:43:11 UTC 2016
Modified Files: src/libexec/identd: Makefile identd.8 identd.c identd.h ipf.c pf.c Added Files: src/libexec/identd: npf.c Log Message: add npf support. To generate a diff of this commit: cvs rdiff -u -r1.13 -r1.14 src/libexec/identd/Makefile cvs rdiff -u -r1.20 -r1.21 src/libexec/identd/identd.8 cvs rdiff -u -r1.34 -r1.35 src/libexec/identd/identd.c cvs rdiff -u -r1.10 -r1.11 src/libexec/identd/identd.h cvs rdiff -u -r1.2 -r1.3 src/libexec/identd/ipf.c src/libexec/identd/pf.c cvs rdiff -u -r0 -r1.1 src/libexec/identd/npf.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/libexec/identd/Makefile diff -u src/libexec/identd/Makefile:1.13 src/libexec/identd/Makefile:1.14 --- src/libexec/identd/Makefile:1.13 Sat Sep 15 13:45:35 2012 +++ src/libexec/identd/Makefile Sat Dec 10 00:43:11 2016 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.13 2012/09/15 17:45:35 plunky Exp $ +# $NetBSD: Makefile,v 1.14 2016/12/10 05:43:11 christos Exp $ .include <bsd.own.mk> @@ -18,4 +18,12 @@ SRCS+= pf.c CPPFLAGS+=-DWITH_PF .endif +# Build with npf support? +.if (${MKNPF} != "no") +SRCS+= npf.c +CPPFLAGS+=-DWITH_NPF +LDADD+=-lnpf +DPADD+=${LIBNPF} +.endif + .include <bsd.prog.mk> Index: src/libexec/identd/identd.8 diff -u src/libexec/identd/identd.8:1.20 src/libexec/identd/identd.8:1.21 --- src/libexec/identd/identd.8:1.20 Mon Apr 4 14:43:55 2005 +++ src/libexec/identd/identd.8 Sat Dec 10 00:43:11 2016 @@ -1,9 +1,9 @@ -.\" $NetBSD: identd.8,v 1.20 2005/04/04 18:43:55 peter Exp $ +.\" $NetBSD: identd.8,v 1.21 2016/12/10 05:43:11 christos Exp $ .\" .\" This software is in the public domain. .\" Written by Peter Postma <pe...@netbsd.org> .\" -.Dd April 4, 2005 +.Dd December 9, 2016 .Dt IDENTD 8 .Os .Sh NAME @@ -124,9 +124,10 @@ The .Ar filter argument specifies which packet filter should be used to lookup the connections, currently -.Sq pf +.Sq ipfilter , +.Sq npf , and -.Sq ipfilter +.Sq pf are supported packet filters. Note that .Nm @@ -231,10 +232,11 @@ When forwarding is enabled with the flag then .Nm will need access to either -.Pa /etc/pf -(pf) or -.Pa /etc/ipnat -(ipfilter). +.Pa /dev/ipnat +(ipfilter), +.Pa /dev/pf +(pf), or +.Pa /dev/npf. Since it's not a good idea to run .Nm under root, you'll need to adjust group owner/permissions to the device(s) Index: src/libexec/identd/identd.c diff -u src/libexec/identd/identd.c:1.34 src/libexec/identd/identd.c:1.35 --- src/libexec/identd/identd.c:1.34 Wed Mar 14 22:02:21 2012 +++ src/libexec/identd/identd.c Sat Dec 10 00:43:11 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: identd.c,v 1.34 2012/03/15 02:02:21 joerg Exp $ */ +/* $NetBSD: identd.c,v 1.35 2016/12/10 05:43:11 christos Exp $ */ /* * identd.c - TCP/IP Ident protocol server. @@ -8,7 +8,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: identd.c,v 1.34 2012/03/15 02:02:21 joerg Exp $"); +__RCSID("$NetBSD: identd.c,v 1.35 2016/12/10 05:43:11 christos Exp $"); #include <sys/param.h> #include <sys/socket.h> @@ -65,16 +65,19 @@ __dead static void timeout_handler(int) __dead static void fatal(const char *); __dead static void die(const char *, ...) __printflike(1, 2); -static int bflag, eflag, fflag, iflag, Iflag; +static int bflag, dflag, eflag, fflag, iflag, Iflag; static int lflag, Lflag, nflag, Nflag, rflag; /* NAT lookup function pointer. */ -static int (*nat_lookup)(struct sockaddr_storage *, struct sockaddr *, int *); +typedef int (*nat_lookup_t)(const struct sockaddr_storage *, + struct sockaddr_storage *, in_port_t *); + +static nat_lookup_t nat_lookup; /* Packet filters. */ static const struct { const char *name; - int (*fn)(struct sockaddr_storage *, struct sockaddr *, int *); + nat_lookup_t fn; } filters[] = { #ifdef WITH_PF { "pf", pf_natlookup }, @@ -82,6 +85,9 @@ static const struct { #ifdef WITH_IPF { "ipfilter", ipf_natlookup }, #endif +#ifdef WITH_NPF + { "npf", npf_natlookup }, +#endif { NULL, NULL } }; @@ -109,7 +115,7 @@ main(int argc, char *argv[]) filter = proxy = NULL; address = charset = fmt = NULL; uid = gid = 0; - bflag = eflag = fflag = iflag = Iflag = 0; + bflag = dflag = eflag = fflag = iflag = Iflag = 0; lflag = Lflag = nflag = Nflag = rflag = 0; /* Started from a tty? then run as daemon. */ @@ -118,7 +124,7 @@ main(int argc, char *argv[]) /* Parse command line arguments. */ while ((ch = getopt(argc, argv, - "46a:bceF:f:g:IiL:lm:Nno:P:p:rt:u:")) != -1) { + "46a:bcdeF:f:g:IiL:lm:Nno:P:p:rt:u:")) != -1) { switch (ch) { case '4': IPv4or6 = AF_INET; @@ -135,6 +141,9 @@ main(int argc, char *argv[]) case 'c': charset = optarg; break; + case 'd': + dflag++; + break; case 'e': eflag = 1; break; @@ -255,7 +264,7 @@ main(int argc, char *argv[]) int fd, nfds, rv; struct pollfd *rfds; - if (daemon(0, 0) < 0) + if (!dflag && daemon(0, 0) < 0) die("daemon: %s", strerror(errno)); rfds = malloc(*socks * sizeof(struct pollfd)); @@ -424,16 +433,16 @@ idhandle(int fd, const char *charset, co if (ident_getuid(ss, sizeof(ss), proxy, &uid) == -1) { /* Lookup failed, try to forward if enabled. */ if (nat_lookup != NULL) { - struct sockaddr nat_addr; - int nat_lport; + struct sockaddr_storage nat_addr; + in_port_t nat_lport; (void)memset(&nat_addr, 0, sizeof(nat_addr)); - if ((*nat_lookup)(ss, &nat_addr, &nat_lport) && - forward(fd, &nat_addr, nat_lport, fport, lport)) { + forward(fd, (struct sockaddr *)&nat_addr, + nat_lport, fport, lport)) { maybe_syslog(LOG_INFO, "Succesfully forwarded the request to %s", - gethost(&nat_addr)); + gethost((struct sockaddr *)&nat_addr)); return 0; } } @@ -812,7 +821,7 @@ forward(int fd, struct sockaddr *nat_add * Send the ident query to the NAT host, but use as local port * the port of the NAT host. */ - (void)snprintf(buf, sizeof(buf), "%d , %d\r\n", nat_lport, fport); + (void)snprintf(buf, sizeof(buf), "%d , %d\r\n", fport, nat_lport); if (send(sock, buf, strlen(buf), 0) < 0) { maybe_syslog(LOG_ERR, "send: %m"); (void)close(sock); @@ -830,6 +839,8 @@ forward(int fd, struct sockaddr *nat_add return 0; } reply[n] = '\0'; + if (dflag) + maybe_syslog(LOG_ERR, "Replied %s", reply); (void)close(sock); /* Extract everything after the port specs from the ident reply. */ Index: src/libexec/identd/identd.h diff -u src/libexec/identd/identd.h:1.10 src/libexec/identd/identd.h:1.11 --- src/libexec/identd/identd.h:1.10 Wed Oct 14 11:53:50 2015 +++ src/libexec/identd/identd.h Sat Dec 10 00:43:11 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: identd.h,v 1.10 2015/10/14 15:53:50 christos Exp $ */ +/* $NetBSD: identd.h,v 1.11 2016/12/10 05:43:11 christos Exp $ */ /* * identd.h - TCP/IP Ident protocol server. @@ -12,16 +12,25 @@ #define satosin(sa) ((struct sockaddr_in *)(sa)) #define satosin6(sa) ((struct sockaddr_in6 *)(sa)) +#define csatosin(sa) ((const struct sockaddr_in *)(sa)) +#define csatosin6(sa) ((const struct sockaddr_in6 *)(sa)) #define in_hosteq(s,t) ((s).s_addr == (t).s_addr) void maybe_syslog(int, const char *, ...) __sysloglike(2, 3); #ifdef WITH_PF -int pf_natlookup(struct sockaddr_storage *, struct sockaddr *, int *); +int pf_natlookup(const struct sockaddr_storage *, struct sockaddr_storage *, + in_port_t *); #endif #ifdef WITH_IPF -int ipf_natlookup(struct sockaddr_storage *, struct sockaddr *, int *); +int ipf_natlookup(const struct sockaddr_storage *, struct sockaddr_storage *, + in_port_t *); +#endif + +#ifdef WITH_NPF +int npf_natlookup(const struct sockaddr_storage *, struct sockaddr_storage *, + in_port_t *); #endif #endif /* !_IDENTD_H_ */ Index: src/libexec/identd/ipf.c diff -u src/libexec/identd/ipf.c:1.2 src/libexec/identd/ipf.c:1.3 --- src/libexec/identd/ipf.c:1.2 Tue Jun 14 08:18:24 2005 +++ src/libexec/identd/ipf.c Sat Dec 10 00:43:11 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: ipf.c,v 1.2 2005/06/14 12:18:24 peter Exp $ */ +/* $NetBSD: ipf.c,v 1.3 2016/12/10 05:43:11 christos Exp $ */ /* * ipf.c - NAT lookup code for IP Filter. @@ -8,7 +8,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: ipf.c,v 1.2 2005/06/14 12:18:24 peter Exp $"); +__RCSID("$NetBSD: ipf.c,v 1.3 2016/12/10 05:43:11 christos Exp $"); #include <sys/types.h> #include <sys/socket.h> @@ -31,8 +31,8 @@ __RCSID("$NetBSD: ipf.c,v 1.2 2005/06/14 #include "identd.h" int -ipf_natlookup(struct sockaddr_storage *ss, struct sockaddr *nat_addr, - int *nat_lport) +ipf_natlookup(const struct sockaddr_storage *ss, + struct sockaddr_storage *nat_addr, in_port_t *nat_lport) { natlookup_t nl; ipfobj_t obj; @@ -50,12 +50,12 @@ ipf_natlookup(struct sockaddr_storage *s /* Build the ipf natlook structure. */ switch (ss[0].ss_family) { case AF_INET: - (void)memcpy(&nl.nl_realip, &satosin(&ss[0])->sin_addr, + (void)memcpy(&nl.nl_realip, &csatosin(&ss[0])->sin_addr, sizeof(struct in_addr)); - (void)memcpy(&nl.nl_outip, &satosin(&ss[1])->sin_addr, + (void)memcpy(&nl.nl_outip, &csatosin(&ss[1])->sin_addr, sizeof(struct in_addr)); - nl.nl_realport = ntohs(satosin(&ss[0])->sin_port); - nl.nl_outport = ntohs(satosin(&ss[1])->sin_port); + nl.nl_realport = ntohs(csatosin(&ss[0])->sin_port); + nl.nl_outport = ntohs(csatosin(&ss[1])->sin_port); nl.nl_flags = IPN_TCP | IPN_IN; break; case AF_INET6: Index: src/libexec/identd/pf.c diff -u src/libexec/identd/pf.c:1.2 src/libexec/identd/pf.c:1.3 --- src/libexec/identd/pf.c:1.2 Tue Jun 14 08:18:24 2005 +++ src/libexec/identd/pf.c Sat Dec 10 00:43:11 2016 @@ -1,4 +1,4 @@ -/* $NetBSD: pf.c,v 1.2 2005/06/14 12:18:24 peter Exp $ */ +/* $NetBSD: pf.c,v 1.3 2016/12/10 05:43:11 christos Exp $ */ /* * pf.c - NAT lookup code for pf. @@ -8,7 +8,7 @@ */ #include <sys/cdefs.h> -__RCSID("$NetBSD: pf.c,v 1.2 2005/06/14 12:18:24 peter Exp $"); +__RCSID("$NetBSD: pf.c,v 1.3 2016/12/10 05:43:11 christos Exp $"); #include <sys/types.h> #include <sys/socket.h> @@ -27,8 +27,8 @@ __RCSID("$NetBSD: pf.c,v 1.2 2005/06/14 #include "identd.h" int -pf_natlookup(struct sockaddr_storage *ss, struct sockaddr *nat_addr, - int *nat_lport) +pf_natlookup(const struct sockaddr_storage *ss, + struct sockaddr_storage *nat_addr, in_port_t *nat_lport) { struct pfioc_natlook nl; int dev; @@ -38,23 +38,23 @@ pf_natlookup(struct sockaddr_storage *ss /* Build the pf natlook structure. */ switch (ss[0].ss_family) { case AF_INET: - (void)memcpy(&nl.daddr.v4, &satosin(&ss[0])->sin_addr, + (void)memcpy(&nl.daddr.v4, &csatosin(&ss[0])->sin_addr, sizeof(struct in_addr)); - (void)memcpy(&nl.saddr.v4, &satosin(&ss[1])->sin_addr, + (void)memcpy(&nl.saddr.v4, &csatosin(&ss[1])->sin_addr, sizeof(struct in_addr)); - nl.dport = satosin(&ss[0])->sin_port; - nl.sport = satosin(&ss[1])->sin_port; + nl.dport = csatosin(&ss[0])->sin_port; + nl.sport = csatosin(&ss[1])->sin_port; nl.af = AF_INET; nl.proto = IPPROTO_TCP; nl.direction = PF_IN; break; case AF_INET6: - (void)memcpy(&nl.daddr.v6, &satosin6(&ss[0])->sin6_addr, + (void)memcpy(&nl.daddr.v6, &csatosin6(&ss[0])->sin6_addr, sizeof(struct in6_addr)); - (void)memcpy(&nl.saddr.v6, &satosin6(&ss[1])->sin6_addr, + (void)memcpy(&nl.saddr.v6, &csatosin6(&ss[1])->sin6_addr, sizeof(struct in6_addr)); - nl.dport = satosin6(&ss[0])->sin6_port; - nl.sport = satosin6(&ss[1])->sin6_port; + nl.dport = csatosin6(&ss[0])->sin6_port; + nl.sport = csatosin6(&ss[1])->sin6_port; nl.af = AF_INET6; nl.proto = IPPROTO_TCP; nl.direction = PF_IN; Added files: Index: src/libexec/identd/npf.c diff -u /dev/null src/libexec/identd/npf.c:1.1 --- /dev/null Sat Dec 10 00:43:11 2016 +++ src/libexec/identd/npf.c Sat Dec 10 00:43:11 2016 @@ -0,0 +1,114 @@ +/* $NetBSD: npf.c,v 1.1 2016/12/10 05:43:11 christos Exp $ */ + +/*- + * Copyright (c) 2016 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Christos Zoulas. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__RCSID("$NetBSD: npf.c,v 1.1 2016/12/10 05:43:11 christos Exp $"); + +#include <sys/types.h> +#include <sys/socket.h> +#include <sys/ioctl.h> +#include <sys/fcntl.h> + +#include <net/if.h> +#include <netinet/in.h> + +#include <npf.h> +#include <stdlib.h> +#include <string.h> +#include <errno.h> +#include <syslog.h> +#include <unistd.h> + +#include "identd.h" + +int +npf_natlookup(const struct sockaddr_storage *ss, + struct sockaddr_storage *nat_addr, in_port_t *nat_lport) +{ + npf_addr_t *addr[2]; + in_port_t port[2]; + int dev, af; + + /* copy the source into nat_addr so it is writable */ + memcpy(nat_addr, &ss[0], sizeof(ss[0])); + + switch (af = ss[0].ss_family) { + case AF_INET: + addr[0] = (void *)&satosin(nat_addr)->sin_addr; + addr[1] = __UNCONST(&csatosin(&ss[1])->sin_addr); + port[0] = csatosin(&ss[0])->sin_port; + port[1] = csatosin(&ss[1])->sin_port; + break; + case AF_INET6: + addr[0] = (void *)&satosin6(&nat_addr)->sin6_addr; + addr[1] = __UNCONST(&csatosin6(&ss[0])->sin6_addr); + port[0] = csatosin6(&ss[0])->sin6_port; + port[1] = csatosin6(&ss[1])->sin6_port; + break; + default: + errno = EAFNOSUPPORT; + maybe_syslog(LOG_ERR, "NAT lookup for %d: %m" , af); + return 0; + } + + /* Open the /dev/pf device and do the lookup. */ + if ((dev = open("/dev/npf", O_RDWR)) == -1) { + maybe_syslog(LOG_ERR, "Cannot open /dev/npf: %m"); + return 0; + } + if (npf_nat_lookup(dev, af, addr, port, IPPROTO_TCP, PFIL_IN) == -1) { + maybe_syslog(LOG_ERR, "NAT lookup failure: %m"); + (void)close(dev); + return 0; + } + (void)close(dev); + + /* + * The originating address is already set into nat_addr so fill + * in the rest, family, port (ident), len.... + */ + switch (af) { + case AF_INET: + satosin(nat_addr)->sin_port = htons(113); + satosin(nat_addr)->sin_len = sizeof(struct sockaddr_in); + satosin(nat_addr)->sin_family = AF_INET; + break; + case AF_INET6: + satosin6(nat_addr)->sin6_port = htons(113); + satosin6(nat_addr)->sin6_len = sizeof(struct sockaddr_in6); + satosin6(nat_addr)->sin6_family = AF_INET6; + break; + } + /* Put the originating port into nat_lport. */ + *nat_lport = ntohs(port[0]); + + return 1; +}