Bug 54891 - [libalias] [patch] libalias(3)/natd(8) and exporting connection-info for identd
Summary: [libalias] [patch] libalias(3)/natd(8) and exporting connection-info for identd
Status: Open
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: 4.8-STABLE
Hardware: Any Any
: Normal Affects Only Me
Assignee: freebsd-bugs (Nobody)
URL:
Keywords: patch
Depends on:
Blocks:
 
Reported: 2003-07-27 04:20 UTC by Krzysztof Drewicz
Modified: 2022-10-17 12:35 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Krzysztof Drewicz 2003-07-27 04:20:16 UTC
 	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 ---
Comment 1 Ceri Davies freebsd_committer freebsd_triage 2003-07-28 20:08:08 UTC
Class Changed
From-To: sw-bug->change-request



Comment 2 Ceri Davies freebsd_committer freebsd_triage 2003-07-28 20:08:08 UTC
Responsible Changed
From-To: gnats-admin->freebsd-bugs

Reassign misfiled PR.
Comment 3 Bruce M Simpson freebsd_committer freebsd_triage 2003-11-25 16:42:29 UTC
Responsible Changed
From-To: freebsd-bugs->fru

I guess ru@ is Mr libalias.
Comment 4 Bruce M Simpson freebsd_committer freebsd_triage 2003-11-25 16:47:48 UTC
Responsible Changed
From-To: fru->ru

Typo. 

Spotted by:	ceri
Comment 5 ru freebsd_committer freebsd_triage 2004-04-17 07:19:16 UTC
Responsible Changed
From-To: ru->freebsd-bugs

ENOTIME.
Comment 6 Eitan Adler freebsd_committer freebsd_triage 2017-12-31 07:58:49 UTC
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
Comment 7 Graham Perrin freebsd_committer freebsd_triage 2022-10-17 12:35:07 UTC
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>