Changeset View
Changeset View
Standalone View
Standalone View
sys/netpfil/ipfw/ip_fw2.c
Show First 20 Lines • Show All 376 Lines • ▼ Show 20 Lines | |||||
{ | { | ||||
if (ifp == NULL) /* no iface with this packet, match fails */ | if (ifp == NULL) /* no iface with this packet, match fails */ | ||||
return (0); | return (0); | ||||
/* Check by name or by IP address */ | /* Check by name or by IP address */ | ||||
if (cmd->name[0] != '\0') { /* match by name */ | if (cmd->name[0] != '\0') { /* match by name */ | ||||
if (cmd->name[0] == '\1') /* use tablearg to match */ | if (cmd->name[0] == '\1') /* use tablearg to match */ | ||||
return ipfw_lookup_table_extended(chain, cmd->p.kidx, 0, | return ipfw_lookup_table(chain, cmd->p.kidx, 0, | ||||
&ifp->if_index, tablearg); | &ifp->if_index, tablearg); | ||||
/* Check name */ | /* Check name */ | ||||
if (cmd->p.glob) { | if (cmd->p.glob) { | ||||
if (fnmatch(cmd->name, ifp->if_xname, 0) == 0) | if (fnmatch(cmd->name, ifp->if_xname, 0) == 0) | ||||
return(1); | return(1); | ||||
} else { | } else { | ||||
if (strncmp(ifp->if_xname, cmd->name, IFNAMSIZ) == 0) | if (strncmp(ifp->if_xname, cmd->name, IFNAMSIZ) == 0) | ||||
return(1); | return(1); | ||||
▲ Show 20 Lines • Show All 1,056 Lines • ▼ Show 20 Lines | #endif | ||||
break; | break; | ||||
case O_IP_SRC: | case O_IP_SRC: | ||||
match = is_ipv4 && | match = is_ipv4 && | ||||
(((ipfw_insn_ip *)cmd)->addr.s_addr == | (((ipfw_insn_ip *)cmd)->addr.s_addr == | ||||
src_ip.s_addr); | src_ip.s_addr); | ||||
break; | break; | ||||
case O_IP_SRC_LOOKUP: | |||||
case O_IP_DST_LOOKUP: | case O_IP_DST_LOOKUP: | ||||
if (is_ipv4) { | { | ||||
uint32_t key = | void *pkey; | ||||
(cmd->opcode == O_IP_DST_LOOKUP) ? | uint32_t vidx, key; | ||||
dst_ip.s_addr : src_ip.s_addr; | uint16_t keylen; | ||||
uint32_t v = 0; | |||||
if (cmdlen > F_INSN_SIZE(ipfw_insn_u32)) { | if (cmdlen > F_INSN_SIZE(ipfw_insn_u32)) { | ||||
/* generic lookup. The key must be | /* Determine lookup key type */ | ||||
* in 32bit big-endian format. | vidx = ((ipfw_insn_u32 *)cmd)->d[1]; | ||||
*/ | if (vidx != 4 /* uid */ && | ||||
v = ((ipfw_insn_u32 *)cmd)->d[1]; | vidx != 5 /* jail */ && | ||||
if (v == 0) | is_ipv6 == 0 && is_ipv4 == 0) | ||||
key = dst_ip.s_addr; | |||||
else if (v == 1) | |||||
key = src_ip.s_addr; | |||||
else if (v == 6) /* dscp */ | |||||
key = (ip->ip_tos >> 2) & 0x3f; | |||||
else if (offset != 0) | |||||
break; | break; | ||||
else if (proto != IPPROTO_TCP && | /* Determine key length */ | ||||
proto != IPPROTO_UDP) | if (vidx == 0 /* dst-ip */ || | ||||
vidx == 1 /* src-ip */) | |||||
keylen = is_ipv6 ? | |||||
sizeof(struct in6_addr): | |||||
sizeof(in_addr_t); | |||||
else { | |||||
keylen = sizeof(key); | |||||
pkey = &key; | |||||
} | |||||
if (vidx == 0 /* dst-ip */) | |||||
pkey = is_ipv4 ? (void *)&dst_ip: | |||||
(void *)&args->f_id.dst_ip6; | |||||
else if (vidx == 1 /* src-ip */) | |||||
pkey = is_ipv4 ? (void *)&src_ip: | |||||
(void *)&args->f_id.src_ip6; | |||||
else if (vidx == 6 /* dscp */) { | |||||
if (is_ipv4) | |||||
key = ip->ip_tos >> 2; | |||||
else { | |||||
key = args->f_id.flow_id6; | |||||
key = (key & 0x0f) << 2 | | |||||
(key & 0xf000) >> 14; | |||||
} | |||||
key &= 0x3f; | |||||
} else if (vidx == 2 /* dst-port */ || | |||||
vidx == 3 /* src-port */) { | |||||
/* Skip fragments */ | |||||
if (offset != 0) | |||||
break; | break; | ||||
else if (v == 2) | /* Skip proto without ports */ | ||||
if (proto != IPPROTO_TCP && | |||||
proto != IPPROTO_UDP && | |||||
proto != IPPROTO_SCTP) | |||||
break; | |||||
if (vidx == 2 /* dst-port */) | |||||
key = dst_port; | key = dst_port; | ||||
else if (v == 3) | else | ||||
key = src_port; | key = src_port; | ||||
} | |||||
#ifndef USERSPACE | #ifndef USERSPACE | ||||
else if (v == 4 || v == 5) { | else if (vidx == 4 /* uid */ || | ||||
vidx == 5 /* jail */) { | |||||
check_uidgid( | check_uidgid( | ||||
(ipfw_insn_u32 *)cmd, | (ipfw_insn_u32 *)cmd, | ||||
args, &ucred_lookup, | args, &ucred_lookup, | ||||
#ifdef __FreeBSD__ | #ifdef __FreeBSD__ | ||||
&ucred_cache); | &ucred_cache); | ||||
if (v == 4 /* O_UID */) | if (vidx == 4 /* uid */) | ||||
key = ucred_cache->cr_uid; | key = ucred_cache->cr_uid; | ||||
else if (v == 5 /* O_JAIL */) | else if (vidx == 5 /* jail */) | ||||
key = ucred_cache->cr_prison->pr_id; | key = ucred_cache->cr_prison->pr_id; | ||||
#else /* !__FreeBSD__ */ | #else /* !__FreeBSD__ */ | ||||
(void *)&ucred_cache); | (void *)&ucred_cache); | ||||
if (v ==4 /* O_UID */) | if (vidx == 4 /* uid */) | ||||
key = ucred_cache.uid; | key = ucred_cache.uid; | ||||
else if (v == 5 /* O_JAIL */) | else if (vidx == 5 /* jail */) | ||||
key = ucred_cache.xid; | key = ucred_cache.xid; | ||||
#endif /* !__FreeBSD__ */ | #endif /* !__FreeBSD__ */ | ||||
} | } | ||||
#endif /* !USERSPACE */ | #endif /* !USERSPACE */ | ||||
else | else | ||||
break; | break; | ||||
} | |||||
match = ipfw_lookup_table(chain, | match = ipfw_lookup_table(chain, | ||||
cmd->arg1, key, &v); | cmd->arg1, keylen, pkey, &vidx); | ||||
if (!match) | if (!match) | ||||
break; | break; | ||||
if (cmdlen == F_INSN_SIZE(ipfw_insn_u32)) | tablearg = vidx; | ||||
match = | break; | ||||
((ipfw_insn_u32 *)cmd)->d[0] == v; | } | ||||
/* cmdlen =< F_INSN_SIZE(ipfw_insn_u32) */ | |||||
/* FALLTHROUGH */ | |||||
} | |||||
case O_IP_SRC_LOOKUP: | |||||
{ | |||||
void *pkey; | |||||
uint32_t vidx; | |||||
uint16_t keylen; | |||||
if (is_ipv4) { | |||||
keylen = sizeof(in_addr_t); | |||||
if (cmd->opcode == O_IP_DST_LOOKUP) | |||||
pkey = &dst_ip; | |||||
else | else | ||||
tablearg = v; | pkey = &src_ip; | ||||
} else if (is_ipv6) { | } else if (is_ipv6) { | ||||
uint32_t v = 0; | keylen = sizeof(struct in6_addr); | ||||
void *pkey = (cmd->opcode == O_IP_DST_LOOKUP) ? | if (cmd->opcode == O_IP_DST_LOOKUP) | ||||
&args->f_id.dst_ip6: &args->f_id.src_ip6; | pkey = &args->f_id.dst_ip6; | ||||
match = ipfw_lookup_table_extended(chain, | else | ||||
cmd->arg1, | pkey = &args->f_id.src_ip6; | ||||
sizeof(struct in6_addr), | } else | ||||
pkey, &v); | break; | ||||
if (cmdlen == F_INSN_SIZE(ipfw_insn_u32)) | match = ipfw_lookup_table(chain, cmd->arg1, | ||||
match = ((ipfw_insn_u32 *)cmd)->d[0] == v; | keylen, pkey, &vidx); | ||||
if (match) | if (!match) | ||||
tablearg = v; | break; | ||||
if (cmdlen == F_INSN_SIZE(ipfw_insn_u32)) { | |||||
match = ((ipfw_insn_u32 *)cmd)->d[0] == | |||||
TARG_VAL(chain, vidx, tag); | |||||
if (!match) | |||||
break; | |||||
} | } | ||||
tablearg = vidx; | |||||
break; | break; | ||||
} | |||||
case O_IP_FLOW_LOOKUP: | case O_IP_FLOW_LOOKUP: | ||||
{ | { | ||||
uint32_t v = 0; | uint32_t v = 0; | ||||
match = ipfw_lookup_table_extended(chain, | match = ipfw_lookup_table(chain, | ||||
cmd->arg1, 0, &args->f_id, &v); | cmd->arg1, 0, &args->f_id, &v); | ||||
if (cmdlen == F_INSN_SIZE(ipfw_insn_u32)) | if (cmdlen == F_INSN_SIZE(ipfw_insn_u32)) | ||||
match = ((ipfw_insn_u32 *)cmd)->d[0] == v; | match = ((ipfw_insn_u32 *)cmd)->d[0] == | ||||
TARG_VAL(chain, v, tag); | |||||
if (match) | if (match) | ||||
tablearg = v; | tablearg = v; | ||||
} | } | ||||
break; | break; | ||||
case O_IP_SRC_MASK: | case O_IP_SRC_MASK: | ||||
case O_IP_DST_MASK: | case O_IP_DST_MASK: | ||||
if (is_ipv4) { | if (is_ipv4) { | ||||
uint32_t a = | uint32_t a = | ||||
▲ Show 20 Lines • Show All 1,401 Lines • Show Last 20 Lines |