diff --git a/sys/netpfil/ipfw/ip_fw_log.c b/sys/netpfil/ipfw/ip_fw_log.c index 3f3980b8ee65..98b7a758c612 100644 --- a/sys/netpfil/ipfw/ip_fw_log.c +++ b/sys/netpfil/ipfw/ip_fw_log.c @@ -1,711 +1,731 @@ /*- * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2002-2009 Luigi Rizzo, Universita` di Pisa * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * 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. */ #include /* * Logging support for ipfw */ #include "opt_ipfw.h" #include "opt_inet.h" #ifndef INET #error IPFIREWALL requires INET. #endif /* INET */ #include "opt_inet6.h" #include #include #include #include #include #include #include #include /* for ETHERTYPE_IP */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef INET6 #include /* ip6_sprintf() */ #endif #include #ifdef MAC #include #endif /* * L3HDR maps an ipv4 pointer into a layer3 header pointer of type T * Other macros just cast void * into the appropriate type */ #define L3HDR(T, ip) ((T *)((u_int32_t *)(ip) + (ip)->ip_hl)) #define TCP(p) ((struct tcphdr *)(p)) #define SCTP(p) ((struct sctphdr *)(p)) #define UDP(p) ((struct udphdr *)(p)) #define ICMP(p) ((struct icmphdr *)(p)) #define ICMP6(p) ((struct icmp6_hdr *)(p)) #ifdef __APPLE__ #undef snprintf #define snprintf sprintf #define SNPARGS(buf, len) buf + len #define SNP(buf) buf #else /* !__APPLE__ */ #define SNPARGS(buf, len) buf + len, sizeof(buf) > len ? sizeof(buf) - len : 0 #define SNP(buf) buf, sizeof(buf) #endif /* !__APPLE__ */ #define TARG(k, f) IP_FW_ARG_TABLEARG(chain, k, f) static void ipfw_log_ipfw0(struct ip_fw_args *args, struct ip *ip) { if (args->flags & IPFW_ARGS_LENMASK) ipfw_bpf_tap(args->mem, IPFW_ARGS_LENGTH(args->flags)); else if (args->flags & IPFW_ARGS_ETHER) /* layer2, use orig hdr */ ipfw_bpf_mtap(args->m); else { /* Add fake header. Later we will store * more info in the header. */ if (ip->ip_v == 4) ipfw_bpf_mtap2("DDDDDDSSSSSS\x08\x00", ETHER_HDR_LEN, args->m); else if (ip->ip_v == 6) ipfw_bpf_mtap2("DDDDDDSSSSSS\x86\xdd", ETHER_HDR_LEN, args->m); else /* Obviously bogus EtherType. */ ipfw_bpf_mtap2("DDDDDDSSSSSS\xff\xff", ETHER_HDR_LEN, args->m); } } /* * XXX this function alone takes about 2Kbytes of code! */ static void ipfw_log_syslog(struct ip_fw_chain *chain, struct ip_fw *f, u_int hlen, struct ip_fw_args *args, u_short offset, uint32_t tablearg, struct ip *ip) { char *action; int limit_reached = 0; char action2[92], proto[128], fragment[32], mark_str[24]; fragment[0] = '\0'; proto[0] = '\0'; if (f == NULL) { /* bogus pkt */ if (V_verbose_limit != 0 && V_norule_counter >= V_verbose_limit) return; V_norule_counter++; if (V_norule_counter == V_verbose_limit) limit_reached = V_verbose_limit; action = "Refuse"; } else { /* O_LOG is the first action, find the real one */ ipfw_insn *cmd = ACTION_PTR(f); ipfw_insn_log *l = (ipfw_insn_log *)cmd; if (l->max_log != 0 && l->log_left == 0) return; l->log_left--; if (l->log_left == 0) limit_reached = l->max_log; cmd += F_LEN(cmd); /* point to first action */ if (cmd->opcode == O_ALTQ) { ipfw_insn_altq *altq = (ipfw_insn_altq *)cmd; snprintf(SNPARGS(action2, 0), "Altq %d", altq->qid); cmd += F_LEN(cmd); } if (cmd->opcode == O_PROB || cmd->opcode == O_TAG) cmd += F_LEN(cmd); action = action2; switch (cmd->opcode) { case O_DENY: action = "Deny"; break; case O_REJECT: if (cmd->arg1==ICMP_REJECT_RST) action = "Reset"; else if (cmd->arg1==ICMP_REJECT_ABORT) action = "Abort"; else if (cmd->arg1==ICMP_UNREACH_HOST) action = "Reject"; else snprintf(SNPARGS(action2, 0), "Unreach %d", cmd->arg1); break; case O_UNREACH6: if (cmd->arg1==ICMP6_UNREACH_RST) action = "Reset"; else if (cmd->arg1==ICMP6_UNREACH_ABORT) action = "Abort"; else snprintf(SNPARGS(action2, 0), "Unreach %d", cmd->arg1); break; case O_ACCEPT: action = "Accept"; break; case O_COUNT: action = "Count"; break; case O_DIVERT: snprintf(SNPARGS(action2, 0), "Divert %d", TARG(cmd->arg1, divert)); break; case O_TEE: snprintf(SNPARGS(action2, 0), "Tee %d", TARG(cmd->arg1, divert)); break; case O_SETDSCP: snprintf(SNPARGS(action2, 0), "SetDscp %d", TARG(cmd->arg1, dscp) & 0x3F); break; case O_SETFIB: snprintf(SNPARGS(action2, 0), "SetFib %d", TARG(cmd->arg1, fib) & 0x7FFF); break; case O_SKIPTO: snprintf(SNPARGS(action2, 0), "SkipTo %d", TARG(insntod(cmd, u32)->d[0], skipto)); break; case O_PIPE: snprintf(SNPARGS(action2, 0), "Pipe %d", TARG(cmd->arg1, pipe)); break; case O_QUEUE: snprintf(SNPARGS(action2, 0), "Queue %d", TARG(cmd->arg1, pipe)); break; case O_FORWARD_IP: if (IS_IP4_FLOW_ID(&args->f_id)) { char buf[INET_ADDRSTRLEN]; const struct sockaddr_in *sin = &insntod(cmd, sa)->sa; int len; /* handle fwd tablearg */ if (sin->sin_addr.s_addr == INADDR_ANY) { struct in_addr tmp; tmp.s_addr = htonl( TARG_VAL(chain, tablearg, nh4)); inet_ntoa_r(tmp, buf); } else inet_ntoa_r(sin->sin_addr, buf); len = snprintf(SNPARGS(action2, 0), "Forward to %s", buf); if (sin->sin_port != 0) snprintf(SNPARGS(action2, len), ":%d", sin->sin_port); } /* FALLTHROUGH */ #ifdef INET6 case O_FORWARD_IP6: if (IS_IP6_FLOW_ID(&args->f_id)) { char buf[INET6_ADDRSTRLEN]; struct sockaddr_in6 tmp; const struct sockaddr_in *sin = &insntod(cmd, sa)->sa; struct sockaddr_in6 *sin6 = &insntod(cmd, sa6)->sa; int len; if (cmd->opcode == O_FORWARD_IP && sin->sin_addr.s_addr == INADDR_ANY) { sin6 = &tmp; sin6->sin6_addr = TARG_VAL(chain, tablearg, nh6); sin6->sin6_scope_id = TARG_VAL(chain, tablearg, zoneid); sin6->sin6_port = sin->sin_port; } ip6_sprintf(buf, &sin6->sin6_addr); if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) && sin6->sin6_scope_id != 0) len = snprintf(SNPARGS(action2, 0), "Forward to [%s%%%u]", buf, sin6->sin6_scope_id); else len = snprintf(SNPARGS(action2, 0), "Forward to [%s]", buf); if (sin6->sin6_port != 0) snprintf(SNPARGS(action2, len), ":%u", sin6->sin6_port); } #endif break; case O_NETGRAPH: snprintf(SNPARGS(action2, 0), "Netgraph %d", cmd->arg1); break; case O_NGTEE: snprintf(SNPARGS(action2, 0), "Ngtee %d", cmd->arg1); break; case O_NAT: action = "Nat"; break; case O_REASS: action = "Reass"; break; case O_CALLRETURN: if (cmd->len & F_NOT) snprintf(SNPARGS(action2, 0), "Return %s", cmd->arg1 == RETURN_NEXT_RULENUM ? "next-rulenum": "next-rule"); else snprintf(SNPARGS(action2, 0), "Call %d", TARG(insntod(cmd, u32)->d[0], skipto)); break; case O_SETMARK: if (cmd->arg1 == IP_FW_TARG) snprintf(SNPARGS(action2, 0), "SetMark %#010x", TARG(cmd->arg1, mark)); else snprintf(SNPARGS(action2, 0), "SetMark %#010x", insntoc(cmd, u32)->d[0]); break; case O_EXTERNAL_ACTION: snprintf(SNPARGS(action2, 0), "Eaction %s", ((struct named_object *)SRV_OBJECT(chain, insntod(cmd, kidx)->kidx))->name); break; default: action = "UNKNOWN"; break; } } if (hlen == 0) { /* non-ip */ snprintf(SNPARGS(proto, 0), "MAC"); } else { int len; #ifdef INET6 char src[INET6_ADDRSTRLEN + 2], dst[INET6_ADDRSTRLEN + 2]; #else char src[INET_ADDRSTRLEN], dst[INET_ADDRSTRLEN]; #endif struct icmphdr *icmp; struct tcphdr *tcp; struct udphdr *udp; #ifdef INET6 struct ip6_hdr *ip6 = NULL; struct icmp6_hdr *icmp6; u_short ip6f_mf; #endif src[0] = '\0'; dst[0] = '\0'; #ifdef INET6 ip6f_mf = offset & IP6F_MORE_FRAG; offset &= IP6F_OFF_MASK; if (IS_IP6_FLOW_ID(&(args->f_id))) { char ip6buf[INET6_ADDRSTRLEN]; snprintf(src, sizeof(src), "[%s]", ip6_sprintf(ip6buf, &args->f_id.src_ip6)); snprintf(dst, sizeof(dst), "[%s]", ip6_sprintf(ip6buf, &args->f_id.dst_ip6)); ip6 = (struct ip6_hdr *)ip; tcp = (struct tcphdr *)(((char *)ip) + hlen); udp = (struct udphdr *)(((char *)ip) + hlen); } else #endif { tcp = L3HDR(struct tcphdr, ip); udp = L3HDR(struct udphdr, ip); inet_ntop(AF_INET, &ip->ip_src, src, sizeof(src)); inet_ntop(AF_INET, &ip->ip_dst, dst, sizeof(dst)); } switch (args->f_id.proto) { case IPPROTO_TCP: len = snprintf(SNPARGS(proto, 0), "TCP %s", src); if (offset == 0) snprintf(SNPARGS(proto, len), ":%d %s:%d", ntohs(tcp->th_sport), dst, ntohs(tcp->th_dport)); else snprintf(SNPARGS(proto, len), " %s", dst); break; case IPPROTO_UDP: case IPPROTO_UDPLITE: len = snprintf(SNPARGS(proto, 0), "UDP%s%s", args->f_id.proto == IPPROTO_UDP ? " ": "Lite ", src); if (offset == 0) snprintf(SNPARGS(proto, len), ":%d %s:%d", ntohs(udp->uh_sport), dst, ntohs(udp->uh_dport)); else snprintf(SNPARGS(proto, len), " %s", dst); break; case IPPROTO_ICMP: icmp = L3HDR(struct icmphdr, ip); if (offset == 0) len = snprintf(SNPARGS(proto, 0), "ICMP:%u.%u ", icmp->icmp_type, icmp->icmp_code); else len = snprintf(SNPARGS(proto, 0), "ICMP "); len += snprintf(SNPARGS(proto, len), "%s", src); snprintf(SNPARGS(proto, len), " %s", dst); break; #ifdef INET6 case IPPROTO_ICMPV6: icmp6 = (struct icmp6_hdr *)(((char *)ip) + hlen); if (offset == 0) len = snprintf(SNPARGS(proto, 0), "ICMPv6:%u.%u ", icmp6->icmp6_type, icmp6->icmp6_code); else len = snprintf(SNPARGS(proto, 0), "ICMPv6 "); len += snprintf(SNPARGS(proto, len), "%s", src); snprintf(SNPARGS(proto, len), " %s", dst); break; #endif default: len = snprintf(SNPARGS(proto, 0), "P:%d %s", args->f_id.proto, src); snprintf(SNPARGS(proto, len), " %s", dst); break; } #ifdef INET6 if (IS_IP6_FLOW_ID(&(args->f_id))) { if (offset || ip6f_mf) snprintf(SNPARGS(fragment, 0), " (frag %08x:%d@%d%s)", args->f_id.extra, ntohs(ip6->ip6_plen) - hlen, ntohs(offset) << 3, ip6f_mf ? "+" : ""); } else #endif { int ipoff, iplen; ipoff = ntohs(ip->ip_off); iplen = ntohs(ip->ip_len); if (ipoff & (IP_MF | IP_OFFMASK)) snprintf(SNPARGS(fragment, 0), " (frag %d:%d@%d%s)", ntohs(ip->ip_id), iplen - (ip->ip_hl << 2), offset << 3, (ipoff & IP_MF) ? "+" : ""); } } /* [fw]mark */ if (args->rule.pkt_mark) snprintf(SNPARGS(mark_str, 0), " mark:%#x", args->rule.pkt_mark); else mark_str[0] = '\0'; #ifdef __FreeBSD__ log(LOG_SECURITY | LOG_INFO, "ipfw: %d %s %s%s %s via %s%s\n", f ? f->rulenum : -1, action, proto, mark_str, args->flags & IPFW_ARGS_OUT ? "out" : "in", args->ifp->if_xname, fragment); #else log(LOG_SECURITY | LOG_INFO, "ipfw: %d %s %s%s [no if info]%s\n", f ? f->rulenum : -1, action, proto, mark_str, fragment); #endif if (limit_reached) log(LOG_SECURITY | LOG_NOTICE, "ipfw: limit %d reached on entry %d\n", limit_reached, f ? f->rulenum : -1); } static void ipfw_rtsocklog_fill_l3(struct ip_fw_args *args, char **buf, struct sockaddr **src, struct sockaddr **dst) { struct sockaddr_in *v4src, *v4dst; #ifdef INET6 struct sockaddr_in6 *v6src, *v6dst; if (IS_IP6_FLOW_ID(&(args->f_id))) { v6src = (struct sockaddr_in6 *)*buf; *buf += sizeof(*v6src); v6dst = (struct sockaddr_in6 *)*buf; *buf += sizeof(*v6dst); v6src->sin6_len = v6dst->sin6_len = sizeof(*v6src); v6src->sin6_family = v6dst->sin6_family = AF_INET6; v6src->sin6_addr = args->f_id.src_ip6; v6dst->sin6_addr = args->f_id.dst_ip6; *src = (struct sockaddr *)v6src; *dst = (struct sockaddr *)v6dst; } else #endif { v4src = (struct sockaddr_in *)*buf; *buf += sizeof(*v4src); v4dst = (struct sockaddr_in *)*buf; *buf += sizeof(*v4dst); v4src->sin_len = v4dst->sin_len = sizeof(*v4src); v4src->sin_family = v4dst->sin_family = AF_INET; v4src->sin_addr.s_addr = htonl(args->f_id.src_ip); v4dst->sin_addr.s_addr = htonl(args->f_id.dst_ip); *src = (struct sockaddr *)v4src; *dst = (struct sockaddr *)v4dst; } } static struct sockaddr * -ipfw_rtsocklog_handle_tablearg(struct ip_fw_chain *chain, ipfw_insn *cmd, - uint32_t tablearg, uint32_t *targ_value, char **buf) +ipfw_rtsocklog_handle_tablearg(struct ip_fw_chain *chain, + struct ip_fw_args *args, ipfw_insn *cmd, uint32_t tablearg, + uint32_t *targ_value, char **buf) { - struct sockaddr_in *v4nh = NULL; - /* handle tablearg now */ switch (cmd->opcode) { case O_DIVERT: case O_TEE: *targ_value = TARG(cmd->arg1, divert); break; case O_NETGRAPH: case O_NGTEE: *targ_value = TARG(cmd->arg1, netgraph); break; case O_SETDSCP: *targ_value = (TARG(cmd->arg1, dscp) & 0x3F); break; case O_SETFIB: *targ_value = (TARG(cmd->arg1, fib) & 0x7FFF); break; case O_SKIPTO: case O_CALLRETURN: if (cmd->opcode == O_CALLRETURN && (cmd->len & F_NOT)) break; - *targ_value = (TARG(insntod(cmd, u32)->d[0], skipto)); + *targ_value = TARG(insntod(cmd, u32)->d[0], skipto); break; case O_PIPE: case O_QUEUE: *targ_value = TARG(cmd->arg1, pipe); break; - case O_MARK: - *targ_value = TARG(cmd->arg1, mark); + case O_SETMARK: + if (cmd->arg1 == IP_FW_TARG) + *targ_value = TARG_VAL(chain, tablearg, mark); break; case O_FORWARD_IP: - v4nh = (struct sockaddr_in *)buf; - buf += sizeof(*v4nh); - *v4nh = ((ipfw_insn_sa *)cmd)->sa; - if (v4nh->sin_addr.s_addr == INADDR_ANY) - v4nh->sin_addr.s_addr = htonl(tablearg); - - return (struct sockaddr *)v4nh; + if (IS_IP4_FLOW_ID(&args->f_id)) { + struct sockaddr_in *nh = (struct sockaddr_in *)*buf; + + *buf += sizeof(*nh); + memcpy(nh, &insntod(cmd, sa)->sa, sizeof(*nh)); + if (nh->sin_addr.s_addr == INADDR_ANY) + nh->sin_addr.s_addr = htonl( + TARG_VAL(chain, tablearg, nh4)); + return ((struct sockaddr *)nh); + } + /* FALLTHROUGH */ #ifdef INET6 case O_FORWARD_IP6: - return (struct sockaddr *)&(((ipfw_insn_sa6 *)cmd)->sa); + if (IS_IP6_FLOW_ID(&args->f_id)) { + const struct sockaddr_in *sin = &insntod(cmd, sa)->sa; + struct sockaddr_in6 *nh = (struct sockaddr_in6 *)*buf; + + *buf += sizeof(*nh); + if (cmd->opcode == O_FORWARD_IP && + sin->sin_addr.s_addr == INADDR_ANY) { + nh->sin6_family = AF_INET6; + nh->sin6_len = sizeof(*nh); + nh->sin6_addr = TARG_VAL(chain, tablearg, nh6); + nh->sin6_port = sin->sin_port; + nh->sin6_scope_id = + TARG_VAL(chain, tablearg, zoneid); + } else + memcpy(nh, &insntod(cmd, sa6)->sa, sizeof(*nh)); + return ((struct sockaddr *)nh); + } #endif default: break; } return (NULL); } #define MAX_COMMENT_LEN 80 static size_t ipfw_copy_rule_comment(struct ip_fw *f, char *dst) { ipfw_insn *cmd; size_t rcomment_len = 0; int l, cmdlen; for (l = f->cmd_len, cmd = f->cmd; l > 0; l -= cmdlen, cmd += cmdlen) { cmdlen = F_LEN(cmd); if (cmd->opcode != O_NOP) { continue; } else if (cmd->len == 1) { return (0); } break; } if (l <= 0) { return (0); } rcomment_len = strnlen((char *)(cmd + 1), MAX_COMMENT_LEN - 1) + 1; strlcpy(dst, (char *)(cmd + 1), rcomment_len); return (rcomment_len); } static void ipfw_log_rtsock(struct ip_fw_chain *chain, struct ip_fw *f, u_int hlen, struct ip_fw_args *args, u_short offset, uint32_t tablearg, void *_eh) { struct sockaddr_dl *sdl_ipfwcmd; struct ether_header *eh = _eh; struct rt_addrinfo *info; uint32_t *targ_value; ipfwlog_rtsock_hdr_v2 *hdr; ipfw_insn *cmd; ipfw_insn_log *l; char *buf, *orig_buf; /* at least 4 x sizeof(struct sockaddr_dl) + rule comment (80) */ size_t buflen = 512; /* Should we log? O_LOG is the first one */ cmd = ACTION_PTR(f); l = (ipfw_insn_log *)cmd; if (l->max_log != 0 && l->log_left == 0) return; l->log_left--; if (V_fw_verbose != 0 && l->log_left == 0) { log(LOG_SECURITY | LOG_NOTICE, "ipfw: limit %d reached on entry %d\n", l->max_log, f ? f->rulenum : -1); } buf = orig_buf = malloc(buflen, M_TEMP, M_NOWAIT | M_ZERO); if (buf == NULL) return; info = (struct rt_addrinfo *)buf; buf += sizeof (*info); cmd = ipfw_get_action(f); sdl_ipfwcmd = (struct sockaddr_dl *)buf; sdl_ipfwcmd->sdl_family = AF_IPFWLOG; sdl_ipfwcmd->sdl_index = f->set; sdl_ipfwcmd->sdl_type = 2; /* version */ sdl_ipfwcmd->sdl_alen = sizeof(*hdr); hdr = (ipfwlog_rtsock_hdr_v2 *)(sdl_ipfwcmd->sdl_data); /* fill rule comment in if any */ sdl_ipfwcmd->sdl_nlen = ipfw_copy_rule_comment(f, hdr->comment); targ_value = &hdr->tablearg; hdr->rulenum = f->rulenum; hdr->mark = args->rule.pkt_mark; hdr->cmd = *cmd; sdl_ipfwcmd->sdl_len = sizeof(*sdl_ipfwcmd); if (sizeof(*hdr) + sdl_ipfwcmd->sdl_nlen > sizeof(sdl_ipfwcmd->sdl_data)) { sdl_ipfwcmd->sdl_len += sizeof(*hdr) + sdl_ipfwcmd->sdl_nlen - sizeof(sdl_ipfwcmd->sdl_data); } buf += sdl_ipfwcmd->sdl_len; /* fill L2 in if present */ if (args->flags & IPFW_ARGS_ETHER && eh != NULL) { sdl_ipfwcmd->sdl_slen = sizeof(eh->ether_shost); memcpy(hdr->ether_shost, eh->ether_shost, sdl_ipfwcmd->sdl_slen); memcpy(hdr->ether_dhost, eh->ether_dhost, sdl_ipfwcmd->sdl_slen); } info->rti_info[RTAX_DST] = (struct sockaddr *)sdl_ipfwcmd; /* Warn if we're about to stop sending messages */ if (l->max_log != 0 && l->log_left < (l->max_log >> 1)) { info->rti_flags |= RTF_PROTO1; } /* handle tablearg */ info->rti_info[RTAX_GENMASK] = ipfw_rtsocklog_handle_tablearg( - chain, cmd, tablearg, targ_value, &buf); + chain, args, cmd, tablearg, targ_value, &buf); /* L3 */ ipfw_rtsocklog_fill_l3(args, &buf, &info->rti_info[RTAX_GATEWAY], &info->rti_info[RTAX_NETMASK]); info->rti_ifp = args->ifp; rtsock_routemsg_info(RTM_IPFWLOG, info, RT_ALL_FIBS); free(orig_buf, M_TEMP); } /* * We enter here when we have a rule with O_LOG. */ void ipfw_log(struct ip_fw_chain *chain, struct ip_fw *f, u_int hlen, struct ip_fw_args *args, u_short offset, uint32_t tablearg, struct ip *ip, void *eh) { ipfw_insn *cmd; if (f == NULL || hlen == 0) return; /* O_LOG is the first action */ cmd = ACTION_PTR(f); if (cmd->arg1 == IPFW_LOG_DEFAULT) { if (V_fw_verbose == 0) { ipfw_log_ipfw0(args, ip); return; } ipfw_log_syslog(chain, f, hlen, args, offset, tablearg, ip); return; } if (cmd->arg1 & IPFW_LOG_SYSLOG) ipfw_log_syslog(chain, f, hlen, args, offset, tablearg, ip); if (cmd->arg1 & IPFW_LOG_RTSOCK) ipfw_log_rtsock(chain, f, hlen, args, offset, tablearg, eh); if (cmd->arg1 & IPFW_LOG_IPFW0) ipfw_log_ipfw0(args, ip); } /* end of file */