Subject: Re: bin/29339
To: None <darrenr@netbsd.org, gnats-admin@netbsd.org,>
From: Darren Reed <darrenr@netbsd.org>
List: netbsd-bugs
Date: 03/18/2006 11:00:44
The following reply was made to PR bin/29339; it has been noted by GNATS.

From: darrenr@netbsd.org (Darren Reed)
To: gcw@primenet.com.au
Cc: gnats-bugs@netbsd.org
Subject: Re: bin/29339
Date: Fri, 10 Mar 2006 09:57:40 +0000 (UTC)

 The problem is that the parser doesn't have any protocol information when
 it finishes with this line -
 map pppoe0 from 192.168.1.0/24 port = 4500 to any -> 0.0.0.0/32
 
 so it removes the port specification from the rule.  It doesn't know if
 it should be TCP or UDP or both.
 
 The patch below should resolve the problem.
 
 Darren
 
 Index: tools/ipnat_y.y
 ===================================================================
 RCS file: /devel/CVS/IP-Filter/tools/ipnat_y.y,v
 retrieving revision 1.30.2.21
 diff -c -r1.30.2.21 ipnat_y.y
 *** tools/ipnat_y.y	18 Dec 2005 14:47:23 -0000	1.30.2.21
 --- tools/ipnat_y.y	9 Mar 2006 11:59:05 -0000
 ***************
 *** 52,57 ****
 --- 52,58 ----
   static	int		natfd = -1;
   static	ioctlfunc_t	natioctlfunc = NULL;
   static	addfunc_t	nataddfunc = NULL;
 + static	int		suggest_port = 0;
   
   static	void	newnatrule __P((void));
   static	void	setnatproto __P((int));
 ***************
 *** 170,175 ****
 --- 171,179 ----
   					strncpy(nat->in_ifnames[1],
   						nat->in_ifnames[0],
   						sizeof(nat->in_ifnames[0]));
 + 				  if ((suggest_port == 1) &&
 + 				      (nat->in_flags & IPN_TCPUDP) == 0)
 + 					nat->in_flags |= IPN_TCPUDP;
   				  if ((nat->in_flags & IPN_TCPUDP) == 0)
   					setnatproto(nat->in_p);
   				  if (((nat->in_redir & NAT_MAPBLK) != 0) ||
 ***************
 *** 184,189 ****
 --- 188,196 ----
   					strncpy(nat->in_ifnames[1],
   						nat->in_ifnames[0],
   						sizeof(nat->in_ifnames[0]));
 + 				  if ((suggest_port == 1) &&
 + 				      (nat->in_flags & IPN_TCPUDP) == 0)
 + 					nat->in_flags |= IPN_TCPUDP;
   				  if (((nat->in_redir & NAT_MAPBLK) != 0) ||
   				      ((nat->in_flags & IPN_AUTOPORTMAP) != 0))
   					nat_setgroupmap(nat);
 ***************
 *** 222,228 ****
   				      (nat->in_pmin != 0 ||
   				       nat->in_pmax != 0 ||
   				       nat->in_pnext != 0))
 ! 						setnatproto(IPPROTO_TCP);
   				}
   	| rdrit ifnames rdrfrom IPNY_TLATE dip nport setproto rdroptions
   				{ nat->in_v = 4;
 --- 229,235 ----
   				      (nat->in_pmin != 0 ||
   				       nat->in_pmax != 0 ||
   				       nat->in_pnext != 0))
 ! 					setnatproto(IPPROTO_TCP);
   				}
   	| rdrit ifnames rdrfrom IPNY_TLATE dip nport setproto rdroptions
   				{ nat->in_v = 4;
 ***************
 *** 232,237 ****
 --- 239,247 ----
   				       nat->in_pmax != 0 ||
   				       nat->in_pnext != 0))
   					setnatproto(IPPROTO_TCP);
 + 				  if ((suggest_port == 1) &&
 + 				      (nat->in_flags & IPN_TCPUDP) == 0)
 + 					nat->in_flags |= IPN_TCPUDP;
   				  if (nat->in_ifnames[1][0] == '\0')
   					strncpy(nat->in_ifnames[1],
   						nat->in_ifnames[0],
 ***************
 *** 248,253 ****
 --- 258,266 ----
   				}
   	| rdrit ifnames rdrfrom IPNY_TLATE dip setproto rdroptions
   				{ nat->in_v = 4;
 + 				  if ((suggest_port == 1) &&
 + 				      (nat->in_flags & IPN_TCPUDP) == 0)
 + 					nat->in_flags |= IPN_TCPUDP;
   				  if (nat->in_ifnames[1][0] == '\0')
   					strncpy(nat->in_ifnames[1],
   						nat->in_ifnames[0],
 ***************
 *** 255,261 ****
   				}
   	;
   
 ! proxy:	| IPNY_PROXY IPNY_PORT portspec YY_STR '/' proto
   			{ strncpy(nat->in_plabel, $4, sizeof(nat->in_plabel));
   			  if (nat->in_dcmp == 0) {
   				nat->in_dport = htons($3);
 --- 268,274 ----
   				}
   	;
   
 ! proxy:	| IPNY_PROXY port portspec YY_STR '/' proto
   			{ strncpy(nat->in_plabel, $4, sizeof(nat->in_plabel));
   			  if (nat->in_dcmp == 0) {
   				nat->in_dport = htons($3);
 ***************
 *** 265,271 ****
   			  setnatproto($6);
   			  free($4);
   			}
 ! 	| IPNY_PROXY IPNY_PORT YY_STR YY_STR '/' proto
   			{ int pnum;
   			  strncpy(nat->in_plabel, $4, sizeof(nat->in_plabel));
   			  pnum = getportproto($3, $6);
 --- 278,284 ----
   			  setnatproto($6);
   			  free($4);
   			}
 ! 	| IPNY_PROXY port YY_STR YY_STR '/' proto
   			{ int pnum;
   			  strncpy(nat->in_plabel, $4, sizeof(nat->in_plabel));
   			  pnum = getportproto($3, $6);
 ***************
 *** 317,322 ****
 --- 330,338 ----
   					  nat->in_inmsk = $3.s_addr; }
   	;
   
 + port:	IPNY_PORT			{ suggest_port = 1; }
 + 	;
 + 
   portspec:
   	YY_NUMBER			{ if ($1 > 65535)	/* Unsigned */
   						yyerror("invalid port number");
 ***************
 *** 329,344 ****
   					}
   	;
   
 ! dport:	| IPNY_PORT portspec			{ nat->in_pmin = htons($2);
   						  nat->in_pmax = htons($2); }
 ! 	| IPNY_PORT portspec '-' portspec	{ nat->in_pmin = htons($2);
   						  nat->in_pmax = htons($4); }
 ! 	| IPNY_PORT portspec ':' portspec	{ nat->in_pmin = htons($2);
   						  nat->in_pmax = htons($4); }
   	;
   
 ! nport:	IPNY_PORT portspec		{ nat->in_pnext = htons($2); }
 ! 	| IPNY_PORT '=' portspec	{ nat->in_pnext = htons($3);
   					  nat->in_flags |= IPN_FIXEDDPORT;
   					}
   	;
 --- 345,360 ----
   					}
   	;
   
 ! dport:	| port portspec			{ nat->in_pmin = htons($2);
   						  nat->in_pmax = htons($2); }
 ! 	| port portspec '-' portspec	{ nat->in_pmin = htons($2);
   						  nat->in_pmax = htons($4); }
 ! 	| port portspec ':' portspec	{ nat->in_pmin = htons($2);
   						  nat->in_pmax = htons($4); }
   	;
   
 ! nport:	port portspec			{ nat->in_pnext = htons($2); }
 ! 	| port '=' portspec		{ nat->in_pnext = htons($3);
   					  nat->in_flags |= IPN_FIXEDDPORT;
   					}
   	;
 ***************
 *** 424,430 ****
   
   sobject:
   	saddr
 ! 	| saddr IPNY_PORT portstuff	{ nat->in_sport = $3.p1;
   					  nat->in_stop = $3.p2;
   					  nat->in_scmp = $3.pc; }
   	;
 --- 440,446 ----
   
   sobject:
   	saddr
 ! 	| saddr port portstuff	{ nat->in_sport = $3.p1;
   					  nat->in_stop = $3.p2;
   					  nat->in_scmp = $3.pc; }
   	;
 ***************
 *** 441,447 ****
   
   dobject:
   	daddr
 ! 	| daddr IPNY_PORT portstuff	{ nat->in_dport = $3.p1;
   					  nat->in_dtop = $3.p2;
   					  nat->in_dcmp = $3.pc;
   					  if (nat->in_redir == NAT_REDIRECT)
 --- 457,463 ----
   
   dobject:
   	daddr
 ! 	| daddr port portstuff	{ nat->in_dport = $3.p1;
   					  nat->in_dtop = $3.p2;
   					  nat->in_dcmp = $3.pc;
   					  if (nat->in_redir == NAT_REDIRECT)
 ***************
 *** 546,555 ****
   					}
   	;
   
 ! proto:	YY_NUMBER			{ $$ = $1; }
   	| IPNY_TCP			{ $$ = IPPROTO_TCP; }
   	| IPNY_UDP			{ $$ = IPPROTO_UDP; }
 ! 	| YY_STR			{ $$ = getproto($1); free($1); }
   	;
   
   hexnumber:
 --- 562,579 ----
   					}
   	;
   
 ! proto:	YY_NUMBER			{ $$ = $1;
 ! 					  if ($$ != IPPROTO_TCP &&
 ! 					      $$ != IPPROTO_UDP)
 ! 						suggest_port = 0;
 ! 					}
   	| IPNY_TCP			{ $$ = IPPROTO_TCP; }
   	| IPNY_UDP			{ $$ = IPPROTO_UDP; }
 ! 	| YY_STR			{ $$ = getproto($1); free($1);
 ! 					  if ($$ != IPPROTO_TCP &&
 ! 					      $$ != IPPROTO_UDP)
 ! 						suggest_port = 0;
 ! 					}
   	;
   
   hexnumber:
 ***************
 *** 717,722 ****
 --- 741,748 ----
   		nat->in_next = n;
   		nat = n;
   	}
 + 
 + 	suggest_port = 0;
   }