Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F134724478
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
20 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/sys/netpfil/ipfw/ip_fw_log.c b/sys/netpfil/ipfw/ip_fw_log.c
index 389b04ccbace..3f3980b8ee65 100644
--- a/sys/netpfil/ipfw/ip_fw_log.c
+++ b/sys/netpfil/ipfw/ip_fw_log.c
@@ -1,688 +1,711 @@
/*-
* 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 <sys/cdefs.h>
/*
* 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 <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <sys/syslog.h>
#include <net/ethernet.h> /* for ETHERTYPE_IP */
#include <net/if.h>
#include <net/if_dl.h>
#include <net/if_var.h>
#include <net/if_private.h>
#include <net/vnet.h>
#include <net/route.h>
#include <net/route/route_var.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <netinet/ip_var.h>
#include <netinet/ip_fw.h>
#include <netinet/udp.h>
#include <netinet/tcp.h>
#include <netinet/ip6.h>
#include <netinet/icmp6.h>
#ifdef INET6
#include <netinet6/in6_var.h> /* ip6_sprintf() */
#endif
#include <netpfil/ipfw/ip_fw_private.h>
#ifdef MAC
#include <security/mac/mac_framework.h>
#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: {
- char buf[INET_ADDRSTRLEN];
- ipfw_insn_sa *sa = (ipfw_insn_sa *)cmd;
- int len;
- struct in_addr dummyaddr;
- if (sa->sa.sin_addr.s_addr == INADDR_ANY)
- dummyaddr.s_addr = htonl(tablearg);
- else
- dummyaddr.s_addr = sa->sa.sin_addr.s_addr;
-
- len = snprintf(SNPARGS(action2, 0), "Forward to %s",
- inet_ntoa_r(dummyaddr, buf));
-
- if (sa->sa.sin_port)
- snprintf(SNPARGS(action2, len), ":%d",
- sa->sa.sin_port);
+ 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);
}
- break;
+ /* FALLTHROUGH */
#ifdef INET6
- case O_FORWARD_IP6: {
- char buf[INET6_ADDRSTRLEN];
- ipfw_insn_sa6 *sa = (ipfw_insn_sa6 *)cmd;
- int len;
-
- len = snprintf(SNPARGS(action2, 0), "Forward to [%s]",
- ip6_sprintf(buf, &sa->sa.sin6_addr));
-
- if (sa->sa.sin6_port)
- snprintf(SNPARGS(action2, len), ":%u",
- sa->sa.sin6_port);
+ 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);
}
- break;
#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)
{
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));
break;
case O_PIPE:
case O_QUEUE:
*targ_value = TARG(cmd->arg1, pipe);
break;
case O_MARK:
*targ_value = TARG(cmd->arg1, 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;
#ifdef INET6
case O_FORWARD_IP6:
return (struct sockaddr *)&(((ipfw_insn_sa6 *)cmd)->sa);
#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);
/* 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 */
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Thu, Nov 6, 5:04 AM (5 m, 32 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
24815625
Default Alt Text
(20 KB)
Attached To
Mode
rG FreeBSD src repository
Attached
Detach File
Event Timeline
Log In to Comment