When running ipfw/natd it's now imposible to answer ident queries or even see pairs from-nat'ed/to (like in ipnat -l). Libalias should have additional API for searching nated connections, supplying: -destanation port -destanation addres -local (alias) port -local (alias) address -link_type (IPPROTO_*) is enough for finding link_alias structure in libalias, so information missing in indentd daemon (src addres & port) could be fetched and delivred. This could be easily done w/ unix sockets (PF_LOCAL) and udp (SOCK_DGRAM), it provides simple (fs based) access control and is fast. 'ipnat -l' could be implemented as dumping data to a file, based on socket query with only zeros, or so. This api could provide in future simple way of telling libalias to flush connections of given type, to/from given host, change timeouts, etc. Fix: I've included diffs to HEAD, where simple communication w/ running natd is shown. Files ask.c and ident.c should go into /usr/src/sbin/natd. Ask.c is sample program to use, it could be added with standard inentd, or better into oidentd's os/freebsd.c. --- libalias.patch begins here --- Index: alias.h =================================================================== RCS file: /home/ncvs/src/lib/libalias/alias.h,v retrieving revision 1.24 diff -u -d -r1.24 alias.h --- alias.h 1 Jun 2003 23:15:00 -0000 1.24 +++ alias.h 24 Jul 2003 00:33:03 -0000 @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $FreeBSD: src/lib/libalias/alias.h,v 1.24 2003/06/01 23:15:00 ru Exp $ + * $FreeBSD: src/lib/libalias/alias.h,v 1.12.2.8 2003/06/27 09:15:16 ru Exp $ */ /*- @@ -177,6 +177,23 @@ #define PKT_ALIAS_IGNORED 2 #define PKT_ALIAS_UNRESOLVED_FRAGMENT 3 #define PKT_ALIAS_FOUND_HEADER_FRAGMENT 4 + +struct answer { + struct in_addr src_addr; + struct in_addr alias_addr; + struct in_addr dst_addr; + struct in_addr proxy_addr; + u_short src_port; + u_short alias_port; + u_short dst_port; + u_short proxy_port; + int link_type; // as in alias_link + }; + +int +FindLinks ( struct answer *que, + struct answer *ans + ); #endif /* !_ALIAS_H_ */ Index: alias_db.c =================================================================== RCS file: /home/ncvs/src/lib/libalias/alias_db.c,v retrieving revision 1.53 diff -u -d -r1.53 alias_db.c --- alias_db.c 1 Jun 2003 23:15:00 -0000 1.53 +++ alias_db.c 24 Jul 2003 00:33:26 -0000 @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/lib/libalias/alias_db.c,v 1.53 2003/06/01 23:15:00 ru Exp $"); +__FBSDID("$FreeBSD: src/lib/libalias/alias_db.c,v 1.21.2.17 2003/06/27 09:15:16 ru Exp $"); /* Alias_db.c encapsulates all data structures used for storing @@ -313,6 +313,7 @@ #define LINK_PERMANENT 0x04 #define LINK_PARTIALLY_SPECIFIED 0x03 /* logical-or of first two bits */ #define LINK_UNFIREWALLED 0x08 +#define LINK_LAST_LINE_CRLF_TERMED 0x10 int timestamp; /* Time link was last accessed */ int expire_time; /* Expire time for link */ @@ -599,6 +600,7 @@ When this parameter is GET_ALIAS_PORT, it indicates to get a randomly selected port number. */ + alias_port_param = GET_ALIAS_PORT; if (alias_port_param == GET_ALIAS_PORT) { @@ -607,7 +609,9 @@ * by one of two methods below: */ max_trials = GET_NEW_PORT_MAX_ATTEMPTS; - + + packetAliasMode ^=PKT_ALIAS_SAME_PORTS; + if (packetAliasMode & PKT_ALIAS_SAME_PORTS) { /* @@ -1165,12 +1169,58 @@ return new_link; } +// ****MARK**** +// +int +FindLinks ( + struct answer *que, + struct answer *ans + ) +{ + u_int i,counter=0; + struct alias_link *link; + + for (i=0; i<LINK_TABLE_OUT_SIZE; i++) + LIST_FOREACH(link, &linkTableOut[i], list_out) + { + +// ok, fuck style(4) and do it w/ style +// +if (link->link_type == que->link_type) +if ((link->src_addr.s_addr == que->src_addr.s_addr ) + || ( que->src_addr.s_addr == INADDR_ANY )) +if ((link->src_port == que->src_port ) + || ( que->src_port == 0 )) +if ((link->alias_addr.s_addr == que->alias_addr.s_addr ) + || ( que->alias_addr.s_addr == INADDR_ANY )) +if ((link->alias_port == que->alias_port ) + || ( que->src_port == 0 )) +if ((link->dst_addr.s_addr == que->dst_addr.s_addr ) + || ( que->dst_addr.s_addr == INADDR_ANY )) +if ((link->dst_port == que->dst_port ) + || ( que->dst_port == 0 )) + { + ans->src_port =link->src_port; + ans->alias_port =link->alias_port; + ans->dst_port =link->dst_port; + + ans->src_addr.s_addr =link->src_addr.s_addr; + ans->alias_addr.s_addr =link->alias_addr.s_addr; + ans->dst_addr.s_addr =link->dst_addr.s_addr; + + counter++; + } +} + return counter; +} + + static struct alias_link * _FindLinkOut(struct in_addr src_addr, - struct in_addr dst_addr, - u_short src_port, - u_short dst_port, - int link_type, + struct in_addr dst_addr, + u_short src_port, + u_short dst_port, + int link_type, int replace_partial_links) { u_int i; @@ -2653,10 +2703,6 @@ Code to support firewall punching. This shouldn't really be in this file, but making variables global is evil too. ****************/ - -#ifndef IPFW2 -#define IPFW2 1 /* use new ipfw code */ -#endif /* Firewall include files */ #include <net/if.h> --- libalias.patch ends here --- --- natd.patch begins here --- Index: Makefile =================================================================== RCS file: /home/ncvs/src/sbin/natd/Makefile,v retrieving revision 1.8 diff -u -b -d -r1.8 Makefile --- Makefile 12 Apr 2002 19:11:09 -0000 1.8 +++ Makefile 24 Jul 2003 00:31:56 -0000 @@ -1,7 +1,7 @@ # $FreeBSD: src/sbin/natd/Makefile,v 1.8 2002/04/12 19:11:09 ru Exp $ PROG = natd -SRCS = natd.c icmp.c +SRCS = natd.c icmp.c ident.c WARNS= 0 LDADD = -lalias DPADD = ${LIBALIAS} Index: natd.c =================================================================== RCS file: /home/ncvs/src/sbin/natd/natd.c,v retrieving revision 1.42 diff -u -b -d -r1.42 natd.c --- natd.c 13 Jun 2003 22:15:42 -0000 1.42 +++ natd.c 24 Jul 2003 00:31:59 -0000 @@ -11,12 +11,13 @@ */ #include <sys/cdefs.h> -__FBSDID("$FreeBSD: src/sbin/natd/natd.c,v 1.42 2003/06/13 22:15:42 ru Exp $"); +__FBSDID("$FreeBSD: src/sbin/natd/natd.c,v 1.25.2.7 2003/06/27 10:05:32 ru Exp $"); #define SYSLOG_NAMES #include <sys/types.h> #include <sys/socket.h> +#include <sys/un.h> #include <sys/sysctl.h> #include <sys/time.h> @@ -34,6 +35,7 @@ #include <alias.h> #include <ctype.h> +#include <fcntl.h> #include <err.h> #include <errno.h> #include <netdb.h> @@ -122,6 +124,27 @@ static int logDropped; static int logFacility; static int logIpfwDenied; +static int doindenting; + +int OpenUniXSocket () +{ + + int sd, i; + struct sockaddr_un sockname; + + unlink(NATD_SERV_SOCK); + strcpy(sockname.sun_path, NATD_SERV_SOCK); + sockname.sun_family = AF_UNIX; + + if ((sd = socket(AF_UNIX, SOCK_DGRAM, 0)) == -1) + perror("natd: identd socket"), exit(1); + fcntl(sd, F_SETFL, O_NONBLOCK); + + if (bind(sd, (struct sockaddr*) &sockname, sizeof(sockname)) == -1) + perror("natd: identd bind"), exit(1); + + return sd; +} int main (int argc, char** argv) { @@ -132,6 +155,10 @@ struct sockaddr_in addr; fd_set readMask; int fdMax; + +static int InfoSockFd; + + /* * Initialize packet aliasing software. * Done already here to be able to alter option bits @@ -288,19 +315,30 @@ */ if (!verbose) DaemonMode (); + +/* + * Info socket: + */ + if (doindenting) + { + InfoSockFd=OpenUniXSocket(); + } /* * Catch signals to manage shutdown and * refresh of interface address. */ siginterrupt(SIGTERM, 1); siginterrupt(SIGHUP, 1); + signal (SIGTERM, InitiateShutdown); signal (SIGHUP, RefreshAddr); + /* * Set alias address if it has been given. */ if (aliasAddr.s_addr != INADDR_NONE) PacketAliasSetAddress (aliasAddr); + /* * We need largest descriptor number for select. */ @@ -319,14 +357,40 @@ if (routeSock > fdMax) fdMax = routeSock; + if (InfoSockFd > fdMax) + fdMax = InfoSockFd; + while (running) { + if (divertInOut != -1 && !ifName) { /* * When using only one socket, just call * DoAliasing repeatedly to process packets. */ + FD_ZERO (&readMask); + if (InfoSockFd != -1) + FD_SET (InfoSockFd, &readMask); + if (divertInOut != -1) + FD_SET (divertInOut, &readMask); + if (select (fdMax + 1, + &readMask, + NULL, + NULL, + NULL) == -1) { + + if (errno == EINTR) + continue; + } + + if (divertInOut != -1) + if (FD_ISSET (divertInOut, &readMask)) DoAliasing (divertInOut, DONT_KNOW); + + if (InfoSockFd != -1) + if (FD_ISSET (InfoSockFd, &readMask)) + DoIdentin(InfoSockFd); + continue; } /* @@ -344,6 +408,10 @@ if (divertInOut != -1) FD_SET (divertInOut, &readMask); + + if (InfoSockFd != -1) + FD_SET (InfoSockFd, &readMask); + /* * Routing info is processed always. */ @@ -377,13 +445,20 @@ if (routeSock != -1) if (FD_ISSET (routeSock, &readMask)) HandleRoutingInfo (routeSock); + + if (InfoSockFd != -1) + if (FD_ISSET (InfoSockFd, &readMask)); + DoIdentin(InfoSockFd); } if (background) unlink (PIDFILE); + if (doindenting) + unlink(NATD_SERV_SOCK); + return 0; -} + } static void DaemonMode () { @@ -398,7 +473,7 @@ fprintf (pidFile, "%d\n", getpid ()); fclose (pidFile); } -} + } static void ParseArgs (int argc, char** argv) { @@ -438,10 +513,10 @@ ParseOption (opt + 1, (len ? parmBuf : NULL)); } -} + } -static void DoAliasing (int fd, int direction) -{ + static void DoAliasing (int fd, int direction) + { int bytes; int origBytes; char buf[IP_MAXPACKET]; @@ -451,13 +526,16 @@ int addrSize; struct ip* ip; char msgBuf[80]; + struct in_addr in,as,out; + struct answer tmp; + if (assignAliasAddr) { SetAliasAddressFromIfName (ifName); assignAliasAddr = 0; } -/* + /* * Get packet from socket. */ addrSize = sizeof addr; @@ -559,7 +637,6 @@ printf (" "); PrintPacket (ip); printf ("\n"); - } /* * Put packet back for processing. @@ -587,6 +664,7 @@ Warn (msgBuf); } } + } } static void HandleRoutingInfo (int fd) @@ -836,7 +914,9 @@ LogDenied, LogFacility, PunchFW, - LogIpfwDenied + LogIpfwDenied, + DoIndenting + }; enum Param { @@ -1063,6 +1143,14 @@ "log packets converted by natd, but denied by ipfw", "log_ipfw_denied", NULL }, + + { DoIndenting, + 0, + YesNo, + "[yes|no]", + "help for [o]ident", + "doindenting", + NULL }, }; static void ParseOption (const char* option, const char* parms) @@ -1250,6 +1338,11 @@ case LogIpfwDenied: logIpfwDenied = yesNoValue;; break; + +case DoIndenting: + doindenting= yesNoValue;; + break; + } } Index: natd.h =================================================================== RCS file: /home/ncvs/src/sbin/natd/natd.h,v retrieving revision 1.4 diff -u -b -d -r1.4 natd.h --- natd.h 28 Aug 1999 00:13:46 -0000 1.4 +++ natd.h 24 Jul 2003 00:31:59 -0000 @@ -16,9 +16,18 @@ #define INPUT 1 #define OUTPUT 2 #define DONT_KNOW 3 +#define NATD_SERV_SOCK "/var/run/natd.socket" +#define PERMS 0666L + +struct d_gram +{ + struct answer ans; + struct answer que; + int count; + int found; +}; extern void Quit (const char* msg); extern void Warn (const char* msg); extern int SendNeedFragIcmp (int sock, struct ip* failedDgram, int mtu); - - +extern void DoIdentin(int fd); --- natd.patch ends here --- --- ident.c begins here --- #include <sys/types.h> #include <sys/errno.h> #include <sys/socket.h> #include <sys/un.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include <alias.h> #include "natd.h" void PrintMsg (struct answer *link) { printf("%12s:%05d", inet_ntoa(link->src_addr),ntohs(link->src_port)); printf(" %12s:%05d", inet_ntoa(link->alias_addr),ntohs(link->alias_port)); printf(" %12s:%05d\n", inet_ntoa(link->dst_addr),ntohs(link->dst_port)); } void DoIdentin(int fd) { ssize_t ile; socklen_t len; struct d_gram tmp; struct sockaddr_un sockname; int sd; len=sizeof (sockname); if (ile = recvfrom(fd, &tmp, sizeof(tmp), 0, (struct sockaddr*) &sockname, &len) == -1) if (errno != EAGAIN) perror("Fucked: recvfrom"), exit(1); // printf("Question from: (%d) %s\n", len, sockname.sun_path); PrintMsg(&tmp.que); if (tmp.count=FindLinks(&tmp.que,&tmp.ans) >0) PrintMsg(&tmp.ans); errno=0; ile = sendto (fd, &tmp, sizeof(tmp), 0, (struct sockaddr*) &sockname, len); // printf("\nAnswered (%d) %s\n", ile, sockname.sun_path); printf("%d\n",errno); } --- ident.c ends here --- --- ask.c begins here --- #include <sys/types.h> #include <sys/errno.h> #include <sys/socket.h> #include <sys/un.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdio.h> #include <string.h> #include <unistd.h> #include <alias.h> #include "natd.h" void sepuku () { printf("NOT FOUND!\n"); exit(1); } void PrintMsg (struct answer *link) { printf("%12s:%05d", inet_ntoa(link->src_addr),ntohs(link->src_port)); printf(" %12s:%05d", inet_ntoa(link->alias_addr),ntohs(link->alias_port)); printf(" %12s:%05d\n", inet_ntoa(link->dst_addr),ntohs(link->dst_port)); } void q_clean (struct d_gram* tmp) { tmp->que.src_addr.s_addr = INADDR_ANY; tmp->que.alias_addr.s_addr = INADDR_ANY; tmp->que.dst_addr.s_addr = INADDR_ANY; // = inet_addr("222.111.333.44"); tmp->que.dst_port=0; // =htons(port_nr); tmp->que.src_port=0; tmp->que.alias_port=0; tmp->que.link_type=IPPROTO_TCP; } int main (int argc, char *argv[]) { int fd,rec; struct d_gram tmp; struct sockaddr_un name; struct sockaddr_un my_name; size_t size; char tempname[18]="/tmp/dupa.XXXXXX"; q_clean(&tmp); if (argc==4) { tmp.que.dst_addr.s_addr = inet_addr(argv[1]); tmp.que.dst_port= htons(atoi(argv[2])); tmp.que.alias_port= htons(atoi(argv[3])); fd = socket (PF_UNIX, SOCK_DGRAM, 0); if (fd < 0) { perror ("socket"); exit (-1); } mkstemp(tempname); my_name.sun_family = AF_UNIX; strcpy (my_name.sun_path, tempname); size = strlen(my_name.sun_path) + sizeof (my_name.sun_family) + 1; unlink(tempname); if (bind (fd, (struct sockaddr *) &my_name, size) < 0) exit(-2); name.sun_family = AF_UNIX; strcpy (name.sun_path, NATD_SERV_SOCK); size = strlen (name.sun_path) + sizeof (name.sun_family) + 1; rec = sendto (fd, &tmp, sizeof tmp, 0, (struct sockaddr *) &name, size); if (rec > 0) { rec=recvfrom(fd, &tmp, sizeof(tmp), 0, (struct sockaddr *) &name, &size); if (tmp.count>0) { PrintMsg(&tmp.ans); } } close(fd); unlink(tempname); } else { printf("need 3 args: ip_dest port_dest port_src\n"); } return 0; } --- ask.c ends here ---
Class Changed From-To: sw-bug->change-request
Responsible Changed From-To: gnats-admin->freebsd-bugs Reassign misfiled PR.
Responsible Changed From-To: freebsd-bugs->fru I guess ru@ is Mr libalias.
Responsible Changed From-To: fru->ru Typo. Spotted by: ceri
Responsible Changed From-To: ru->freebsd-bugs ENOTIME.
For bugs matching the following criteria: Status: In Progress Changed: (is less than) 2014-06-01 Reset to default assignee and clear in-progress tags. Mail being skipped
Keyword: patch or patch-ready – in lieu of summary line prefix: [patch] * bulk change for the keyword * summary lines may be edited manually (not in bulk). Keyword descriptions and search interface: <https://bugs.freebsd.org/bugzilla/describekeywords.cgi>