From owner-freebsd-ipfw@FreeBSD.ORG Tue Jul 15 00:41:19 2003 Return-Path: Delivered-To: freebsd-ipfw@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id EAEC637B401 for ; Tue, 15 Jul 2003 00:41:19 -0700 (PDT) Received: from xorpc.icir.org (xorpc.icir.org [192.150.187.68]) by mx1.FreeBSD.org (Postfix) with ESMTP id 1D20C43F75 for ; Tue, 15 Jul 2003 00:41:19 -0700 (PDT) (envelope-from rizzo@xorpc.icir.org) Received: from xorpc.icir.org (localhost [127.0.0.1]) by xorpc.icir.org (8.12.8p1/8.12.3) with ESMTP id h6F7fIkN006205; Tue, 15 Jul 2003 00:41:18 -0700 (PDT) (envelope-from rizzo@xorpc.icir.org) Received: (from rizzo@localhost) by xorpc.icir.org (8.12.8p1/8.12.3/Submit) id h6F7fD0w006204; Tue, 15 Jul 2003 00:41:13 -0700 (PDT) (envelope-from rizzo) Date: Tue, 15 Jul 2003 00:41:13 -0700 From: Luigi Rizzo To: Patrick Tracanelli Message-ID: <20030715004113.A99565@xorpc.icir.org> References: <3F132237.4010604@freebsdbrasil.com.br> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5.1i In-Reply-To: <3F132237.4010604@freebsdbrasil.com.br>; from eksffa@freebsdbrasil.com.br on Mon, Jul 14, 2003 at 06:35:51PM -0300 cc: freebsd-ipfw@freebsd.org cc: Diego Linke - GAMK Subject: Re: I have four ideia for IPFW2 X-BeenThere: freebsd-ipfw@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: IPFW Technical Discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 15 Jul 2003 07:41:20 -0000 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 > #include > #include > @@ -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"