I have four ideia for IPFW2

Patrick Tracanelli eksffa at freebsdbrasil.com.br
Mon Jul 14 14:35:52 PDT 2003


   > >The logs with more information, as ( tcpflags (syn,ack,fin,rst...),
ipoptions, iplen, iptos, ipttl...)
   > >This could more be called by one keyword (ex: logfull) in the IPFW.
   > >Sample:
   > >ipfw add deny logfull ...
   > >
   > >Or an sysctl variable :-)
   >
   >
   > I have ancient patches on my FreeBSD homepage for that. Maybe someday
   > I'll update them or even commit them.

Extended logging was really a desired feature Diego Linke and me used to
talk about; CJC's patches couldnt apply on recent -current but reading
it motivated and inspired us doing some changes.

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;

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!"
-------------- next part --------------
--- /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)

-------------- next part --------------
--- /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.
  *

-------------- next part --------------
--- /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);
 }



More information about the freebsd-ipfw mailing list