Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 15 Jul 2003 00:41:13 -0700
From:      Luigi Rizzo <rizzo@icir.org>
To:        Patrick Tracanelli <eksffa@freebsdbrasil.com.br>
Cc:        Diego Linke - GAMK <gamk@gamk.com.br>
Subject:   Re: I have four ideia for IPFW2
Message-ID:  <20030715004113.A99565@xorpc.icir.org>
In-Reply-To: <3F132237.4010604@freebsdbrasil.com.br>; from eksffa@freebsdbrasil.com.br on Mon, Jul 14, 2003 at 06:35:51PM -0300
References:  <3F132237.4010604@freebsdbrasil.com.br>

next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, Jul 14, 2003 at 06:35:51PM -0300, Patrick Tracanelli wrote:
...
> The following patches add an "extended" keyword to ipfw2 logging
> statements; more detailed logging seemed to be more interesting for some
> rules than for others, so just enabling or not, via sysctl sounded too
> mandatory. A good idea was to allow usual logging or detailed ones to be
> a per-rule definition;

There is already room in the O_LOG command header so we do not need
to modify ip_fw[2].h to add a field in the structure (helps with
binary compatibility). In fact, this would allow different levels of
verbosity in the logs.

	cheers
	luigi

> Expected syntax adds "extended" keyword between log and logamount, say,
> "... log extended logamount 2000 tcp from...", where extended stated
> rules like:
> 
> 00400   39   1911 allow log extended logamount 800 tcp from me to
> 200.210.70.0/24 out xmit wi0 setup // extended log ging to wired network
> keep-state
> 
> 00450  368 199919 allow log extended ip from { not me or
> 200.230.121.0/24 or 200.210.42.0/24 } to me in recv wi0 //lets analise
> incoming trash from wireless to me
> 00470    0      0 allow log extended logamount 20000 ip from any to any
> via ath0 // ext. log. experiental multimode unwired net
> 00500 1000 120379 allow ip from any to any
> 65535    0      0 deny ip from any to any
> 
>     Will produce logging as:
> 
> Jul 14 17:55:36 redfield-claire kernel: ipfw: 450 Accept UDP
> 128.32.136.12:53 200.210.42.5:49476 in via wi0 (ttl 50, id 59167, len 189)
> 
> Jul 14 17:55:36 redfield-claire kernel: ipfw: 400 Accept TCP
> 200.210.42.5:49578 200.210.70.4:25 out via wi0 [iptos lowdelay (0x10)] 
> [ipoptions lsrr,rr (0x05) ttl 64, id 0, len 60]
> [tcpflags syn (0x02) tcpoptions window,windowts,window,windowtstimestamp 
> (0x0a)] ack number 0 seq number 1506862975
> 
> Jul 14 17:55:36 redfield-claire kernel: ipfw: 400 Accept TCP
> 200.210.70.4:25 200.210.42.5:49578 in via wi0 [iptos  (0x00)] [ipoptions 
> lsrr,rr (0x05) ttl 63, id 47927, len 44] [tcpflags syn,ack (0x12) 
> tcpoptions window,windowsack (0x06)] ack number 1523640191 seq number 
> 3568599789
> 
> -- 
> Atenciosamente,
> 
> Patrick Tracanelli
> patrick @ freebsdbrasil.com.br
> "Long live Hanin Elias, Kim Deal!"

> --- /usr/src/sbin/ipfw/ipfw2.c	Mon Jul 14 15:57:41 2003
> +++ /usr/local/freebsdbrasil/cvs_root//usr/src/sbin/ipfw/ipfw2.c	Mon Jul 14 17:08:48 2003
> @@ -15,11 +15,11 @@
>   *
>   * This software is provided ``AS IS'' without any warranties of any kind.
>   *
>   * NEW command line interface for IP firewall facility
>   *
> - * $FreeBSD: /repoman/r/ncvs/src/sbin/ipfw/ipfw2.c,v 1.35 2003/07/14 18:57:41 luigi Exp $
> + * $FreeBSD: /usr/local/www/cvsroot/FreeBSD/src/sbin/ipfw/ipfw2.c,v 1.35 2003/07/14 18:57:41 luigi Exp $
>   */
>  
>  #include <sys/param.h>
>  #include <sys/mbuf.h>
>  #include <sys/socket.h>
> @@ -1012,17 +1012,19 @@
>  		default:
>  			printf("** unrecognized action %d len %d",
>  				cmd->opcode, cmd->len);
>  		}
>  	}
> -	if (logptr) {
> -		if (logptr->max_log > 0)
> -			printf(" log logamount %d", logptr->max_log);
> -		else
> -			printf(" log");
> -	}
>  
> +	/* Extended logging */
> +        if (logptr) {
> +                if (logptr->max_log > 0)
> +                        printf(" log%s logamount %d", logptr->extended == 1 ? " extended" : " ", logptr->max_log);
> +                else
> +                        printf(" log%s",logptr->extended == 1 ? " extended" : "");
> +        }
> + 
>  	/*
>  	 * then print the body.
>  	 */
>  	if (rule->_pad & 1) {	/* empty rules before options */
>  		if (!do_compact)
> @@ -2880,11 +2882,11 @@
>  		errx(EX_DATAERR, "invalid action %s\n", av[-1]);
>  	}
>  	action = next_cmd(action);
>  
>  	/*
> -	 * [log [logamount N]]	-- log, optional
> +	 * [log [extended] [logamount N]]	-- log, optional
>  	 *
>  	 * If exists, it goes first in the cmdbuf, but then it is
>  	 * skipped in the copy section to the end of the buffer.
>  	 */
>  	if (ac && !strncmp(*av, "log", strlen(*av))) {
> @@ -2892,10 +2894,19 @@
>  		int l;
>  
>  		cmd->len = F_INSN_SIZE(ipfw_insn_log);
>  		cmd->opcode = O_LOG;
>  		av++; ac--;
> +
> +		/* Extended logging */
> +                if (ac && !strncmp(*av, "extended", strlen(*av))) {
> +                        c->extended = 1;
> +                        ac--; av++;
> +                }
> +
> +
> +
>  		if (ac && !strncmp(*av, "logamount", strlen(*av))) {
>  			ac--; av++;
>  			NEED1("logamount requires argument");
>  			l = atoi(*av);
>  			if (l < 0)
> 

> --- /usr/src/sys/netinet/ip_fw.h	Fri Jul 11 07:02:08 2003
> +++ /usr/local/freebsdbrasil/cvs_root/usr/src/sys/netinet/ip_fw.h	Mon Jul 14 16:56:43 2003
> @@ -261,11 +261,11 @@
>   */
>  typedef struct  _ipfw_insn_log {
>          ipfw_insn o;
>  	u_int32_t max_log;	/* how many do we log -- 0 = all */
>  	u_int32_t log_left;	/* how many left to log 	*/
> +	u_int32_t extended;	/* Extended logging */
>  } ipfw_insn_log;
>  
>  /*
>   * Here we have the structure representing an ipfw rule.
>   *
> 

> --- /usr/src/sys/netinet/ip_fw2.c	Sat Jul 12 02:54:17 2003
> +++ /usr/local/freebsdbrasil/cvs_root/usr/src/sys/netinet/ip_fw2.c	Mon Jul 14 16:55:45 2003
> @@ -20,15 +20,21 @@
>   * 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.
>   *
> - * $FreeBSD: /repoman/r/ncvs/src/sys/netinet/ip_fw2.c,v 1.36 2003/07/12 05:54:17 luigi Exp $
> + * $FreeBSD: /usr/local/www/cvsroot/FreeBSD/src/sys/netinet/ip_fw2.c,v 1.36 2003/07/12 05:54:17 luigi Exp $
>   */
>  
> -#define        DEB(x)
> -#define        DDB(x) x
> +#define	DEB(x)
> +#define	DDB(x) x
> +
> +/* Extended logging */
> +#define	GFLAGS_LEN	35
> +#define	GIOPTS_LEN	28
> +#define	GITOS_LEN	28
> +#define	GTOPTS_LEN	55
>  
>  /*
>   * Implement IP packet firewall (new version)
>   */
>  
> @@ -111,10 +117,61 @@
>  MALLOC_DEFINE(M_IPFW, "IpFw/IpAcct", "IpFw/IpAcct chain's");
>  
>  static int fw_debug = 1;
>  static int autoinc_step = 100; /* bounded to 1..1000 in add_rule() */
>  
> +/* Extended logging */
> +
> +struct _s_x {
> +        char *s;
> +        int x;
> +};
> +
> +static struct _s_x f_tcpflags[] = {
> +        { "syn", TH_SYN },
> +        { "fin", TH_FIN },  
> +        { "ack", TH_ACK },
> +        { "psh", TH_PUSH },
> +        { "rst", TH_RST },
> +        { "urg", TH_URG },
> +        { "tcp flag", 0 },
> +        { NULL, 0 }
> +};
> +
> + static struct _s_x f_ipopts[] = {
> +        { "ssrr",       IP_FW_IPOPT_SSRR},
> +        { "lsrr",       IP_FW_IPOPT_LSRR},
> +        { "rr",         IP_FW_IPOPT_RR},
> +        { "ts",         IP_FW_IPOPT_TS},
> +        { "ip option",  0 },
> +        { NULL, 0 }
> +}; 
> +
> +static struct _s_x f_iptos[] = {
> +        { "lowdelay",   IPTOS_LOWDELAY},
> +        { "throughput", IPTOS_THROUGHPUT},
> +        { "reliability", IPTOS_RELIABILITY},
> +        { "mincost",    IPTOS_MINCOST},
> +        { "congestion", IPTOS_CE},
> +        { "ecntransport", IPTOS_ECT},
> +        { "ip tos option", 0},
> +        { NULL, 0 }
> +};
> +
> +static struct _s_x f_tcpopts[] = {
> +        { "mss",        IP_FW_TCPOPT_MSS },
> +        { "maxseg",     IP_FW_TCPOPT_MSS },
> +        { "window",     IP_FW_TCPOPT_WINDOW },
> +        { "sack",       IP_FW_TCPOPT_SACK },
> +        { "ts",         IP_FW_TCPOPT_TS },
> +        { "timestamp",  IP_FW_TCPOPT_TS },
> +        { "cc",         IP_FW_TCPOPT_CC },
> +        { "tcp option", 0 },
> +        { NULL, 0 }
> +};
> +
> +
>  #ifdef SYSCTL_NODE
>  SYSCTL_NODE(_net_inet_ip, OID_AUTO, fw, CTLFLAG_RW, 0, "Firewall");
>  SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, enable,
>      CTLFLAG_RW | CTLFLAG_SECURE3,
>      &fw_enable, 0, "Enable ipfw");
> @@ -455,17 +512,18 @@
>  
>  /*
>   * We enter here when we have a rule with O_LOG.
>   * XXX this function alone takes about 2Kbytes of code!
>   */
> +
>  static void
>  ipfw_log(struct ip_fw *f, u_int hlen, struct ether_header *eh,
>  	struct mbuf *m, struct ifnet *oif)
>  {
>  	char *action;
> -	int limit_reached = 0;
> -	char action2[40], proto[48], fragment[28];
> +	int limit_reached = 0, extended = 0;
> +	char action2[40], proto[48], fragment[28], ipvals[200];
>  
>  	fragment[0] = '\0';
>  	proto[0] = '\0';
>  
>  	if (f == NULL) {	/* bogus pkt */
> @@ -486,10 +544,13 @@
>  			limit_reached = l->max_log;
>  		cmd += F_LEN(cmd);	/* point to first action */
>  		if (cmd->opcode == O_PROB)
>  			cmd += F_LEN(cmd);
>  
> +		/* Extended logging rule */
> +		extended = l->extended;
> + 
>  		action = action2;
>  		switch (cmd->opcode) {
>  		case O_DENY:
>  			action = "Deny";
>  			break;
> @@ -571,11 +632,11 @@
>  		switch (ip->ip_p) {
>  		case IPPROTO_TCP:
>  			len = snprintf(SNPARGS(proto, 0), "TCP %s",
>  			    inet_ntoa(ip->ip_src));
>  			if (offset == 0)
> -				snprintf(SNPARGS(proto, len), ":%d %s:%d",
> +				len += snprintf(SNPARGS(proto, len), ":%d %s:%d",
>  				    ntohs(tcp->th_sport),
>  				    inet_ntoa(ip->ip_dst),
>  				    ntohs(tcp->th_dport));
>  			else
>  				snprintf(SNPARGS(proto, len), " %s",
> @@ -619,24 +680,78 @@
>  		if (ip_off & (IP_MF | IP_OFFMASK))
>  			snprintf(SNPARGS(fragment, 0), " (frag %d:%d@%d%s)",
>  			     ntohs(ip->ip_id), ip_len - (ip->ip_hl << 2),
>  			     offset << 3,
>  			     (ip_off & IP_MF) ? "+" : "");
> +
> +		if (extended == 1) {
> +			int	i;
> +			char g_flags[GFLAGS_LEN]="", g_ipopts[GIOPTS_LEN]="", g_iptos[GITOS_LEN]="", g_tcpopts[GTOPTS_LEN]="", comma[1]="";
> +
> +			u_char set = tcp->th_flags & 0xff;
> +			u_char setopt = ip->ip_hl & 0xff;
> +			u_char settos = ip->ip_tos & 0xff;
> +			u_char settcpopt = tcp->th_off & 0xff;
> +	
> +			if (ip->ip_p == 6) { 
> +				for (i=0; f_tcpflags[i].x != 0; i++) 
> +				{
> +					if (set & f_tcpflags[i].x) 
> +					{
> +						snprintf(g_flags, GFLAGS_LEN-1, "%s%s%s", g_flags, comma, f_tcpflags[i].s);
> +						comma[0] = ',';
> +					} 
> +				}
> +				comma[0] = NULL; /* reset comma */
> +				for (i=0; f_ipopts[i].x != 0; i++)
> +				{
> +					if (setopt & f_ipopts[i].x)
> +					{
> +						snprintf(g_ipopts, GIOPTS_LEN-1, "%s%s%s", g_ipopts, comma, f_ipopts[i].s);
> +						comma[0] = ',';
> +					}
> +				}
> +				comma[0] = NULL; /* once again */
> +				for (i=0; f_iptos[i].x != 0; i++)
> +				{
> +					if (settos & f_iptos[i].x)
> +					{
> +						snprintf(g_iptos, GITOS_LEN-1, "%s%s%s", g_iptos, comma, f_iptos[i].s);
> +						comma[0] = ',';
> +					}
> +				}
> +				comma[0] = NULL;
> +				for (i=0; f_tcpopts[i].x != 0; i++)
> +				{
> +					if (settcpopt & f_tcpopts[i].x)
> +					{
> +						snprintf(g_tcpopts, GTOPTS_LEN-1, "%s%s%s", g_tcpopts, comma, f_tcpopts[i].s);
> +						comma[0] = ',';
> +					}
> +				}
> +				snprintf(SNPARGS(ipvals, 0), " [iptos %s (0x%02x)] [ipoptions %s (0x%02x) ttl %u, id %u, len %u] [tcpflags %s (0x%02x) tcpoptions %s (0x%02x)] ack number %u seq number %u",
> +					g_iptos, ip->ip_tos, g_ipopts, ip->ip_hl, ip->ip_ttl, ntohs(ip->ip_id), ip_len,
> +						g_flags, tcp->th_flags, g_tcpopts, tcp->th_off, tcp->th_ack, tcp->th_seq);
> +			} else {
> +				snprintf(SNPARGS(ipvals, 0), " (ttl %u, id %u, len %u)", ip->ip_ttl, ntohs(ip->ip_id), ip_len);
> +			}
> +		} else
> +			ipvals[0] = '\0';
>  	}
>  	if (oif || m->m_pkthdr.rcvif)
>  		log(LOG_SECURITY | LOG_INFO,
> -		    "ipfw: %d %s %s %s via %s%d%s\n",
> +		    "ipfw: %d %s %s %s via %s%d%s%s\n",
>  		    f ? f->rulenum : -1,
>  		    action, proto, oif ? "out" : "in",
>  		    oif ? oif->if_name : m->m_pkthdr.rcvif->if_name,
>  		    oif ? oif->if_unit : m->m_pkthdr.rcvif->if_unit,
> -		    fragment);
> +		    fragment, ipvals);
>  	else
>  		log(LOG_SECURITY | LOG_INFO,
> -		    "ipfw: %d %s %s [no if info]%s\n",
> +		    "ipfw: %d %s %s [no if info]%s%s\n",
>  		    f ? f->rulenum : -1,
> -		    action, proto, fragment);
> +		    action, proto, fragment, ipvals);
>  	if (limit_reached)
>  		log(LOG_SECURITY | LOG_NOTICE,
>  		    "ipfw: limit %d reached on entry %d\n",
>  		    limit_reached, f ? f->rulenum : -1);
>  }
> 

> _______________________________________________
> freebsd-ipfw@freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-ipfw
> To unsubscribe, send any mail to "freebsd-ipfw-unsubscribe@freebsd.org"



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030715004113.A99565>