I have four ideia for IPFW2
Luigi Rizzo
rizzo at icir.org
Tue Jul 15 00:41:20 PDT 2003
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 at freebsd.org mailing list
> http://lists.freebsd.org/mailman/listinfo/freebsd-ipfw
> To unsubscribe, send any mail to "freebsd-ipfw-unsubscribe at freebsd.org"
More information about the freebsd-ipfw
mailing list