Lines Matching +full:ulp +full:- +full:0

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
4 * Copyright (c) 2002-2009 Luigi Rizzo, Universita` di Pisa
144 VNET_DEFINE(unsigned int, fw_tables_sets) = 0; /* Don't use set-aware tables */
149 VNET_DEFINE(int, skipto_cache) = 0;
158 * Each rule belongs to one of 32 different sets (0..31).
178 VNET_DEFINE(int, ipfw_vnet_ready) = 0;
180 VNET_DEFINE(int, ipfw_nat_ready) = 0;
196 SYSCTL_NODE(_net_inet_ip, OID_AUTO, fw, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
199 CTLFLAG_VNET | CTLFLAG_RW | CTLFLAG_SECURE3, &VNET_NAME(fw_one_pass), 0,
200 …"Only do a single pass through ipfw when using dummynet(4), ipfw_nat or other divert(4)-like inter…
202 CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(autoinc_step), 0,
203 "Rule number auto-increment step");
205 CTLFLAG_VNET | CTLFLAG_RW | CTLFLAG_SECURE3, &VNET_NAME(fw_verbose), 0,
208 CTLFLAG_VNET | CTLFLAG_RW, &VNET_NAME(verbose_limit), 0,
211 CTLFLAG_VNET | CTLFLAG_RD, &VNET_NAME(skipto_cache), 0,
212 "Status of linear skipto cache: 1 - enabled, 0 - disabled.");
214 &dummy_def, 0,
218 0, 0, sysctl_ipfw_table_num, "IU",
222 0, 0, sysctl_ipfw_tables_sets, "IU",
223 "Use per-set namespace for tables");
225 &default_to_accept, 0,
229 CTLFLAG_VNET | CTLFLAG_RD, &VNET_NAME(layer3_chain.n_rules), 0,
234 SYSCTL_NODE(_net_inet6_ip6, OID_AUTO, fw, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
238 &VNET_NAME(fw_deny_unknown_exthdrs), 0,
242 &VNET_NAME(fw_permit_single_frag6), 0,
255 #define L3HDR(T, ip) ((T *)((u_int32_t *)(ip) + (ip)->ip_hl))
265 int type = icmp->icmp_type; in icmptype_match()
267 return (type <= ICMP_MAXTYPE && (cmd->d[0] & (1<<type)) ); in icmptype_match()
276 int type = icmp->icmp_type; in is_icmp_query()
285 * low and high half of cmd->arg1 or cmd->d[0].
289 * (want_set & ~bits) == 0 && (want_clear & ~bits) == want_clear
300 if ( ((cmd->arg1 & 0xff) & bits) != 0) in flags_match()
301 return 0; /* some bits we want set were clear */ in flags_match()
302 want_clear = (cmd->arg1 >> 8) & 0xff; in flags_match()
304 return 0; /* some bits we want clear were set */ in flags_match()
311 int optlen, bits = 0; in ipopts_match()
313 int x = (ip->ip_hl << 2) - sizeof (struct ip); in ipopts_match()
315 for (; x > 0; x -= optlen, cp += optlen) { in ipopts_match()
324 if (optlen <= 0 || optlen > x) in ipopts_match()
325 return 0; /* invalid or truncated */ in ipopts_match()
358 int optlen, bits = 0; in tcpopts_parse()
359 int cnt = (tcp->th_off << 2) - sizeof(struct tcphdr); in tcpopts_parse()
361 for (; cnt > 0; cnt -= optlen, cp += optlen) { in tcpopts_parse()
362 int opt = cp[0]; in tcpopts_parse()
398 if (optlen > 2 && (optlen - 2) % TCPOLEN_SACK == 0) in tcpopts_parse()
424 return (0); in iface_match()
427 if (cmd->name[0] != '\0') { /* match by name */ in iface_match()
428 if (cmd->name[0] == '\1') /* use tablearg to match */ in iface_match()
429 return ipfw_lookup_table(chain, cmd->p.kidx, 0, in iface_match()
430 &ifp->if_index, tablearg); in iface_match()
432 if (cmd->p.glob) { in iface_match()
433 if (fnmatch(cmd->name, ifp->if_xname, 0) == 0) in iface_match()
436 if (strncmp(ifp->if_xname, cmd->name, IFNAMSIZ) == 0) in iface_match()
445 CK_STAILQ_FOREACH(ia, &ifp->if_addrhead, ifa_link) { in iface_match()
446 if (ia->ifa_addr->sa_family != AF_INET) in iface_match()
448 if (cmd->p.ip.s_addr == ((struct sockaddr_in *) in iface_match()
449 (ia->ifa_addr))->sin_addr.s_addr) in iface_match()
454 return(0); /* no match, fail ... */ in iface_match()
467 * commonly known as "anti-spoofing" or Unicast Reverse Path
468 * Forwarding (Unicast RFP) in Cisco-ese. The name of the knobs
471 * ip verify unicast reverse-path
472 * ip verify unicast source reachable-via any
482 return 0; in verify_path()
486 nh = fib4_lookup(fib, src, 0, NHR_NONE, 0); in verify_path()
488 return (0); in verify_path()
492 * We should use rt->rt_ifa->ifa_ifp, instead of rt->rt_ifp, in verify_path()
497 if (ifp != NULL && ifp != nh->nh_aifp) in verify_path()
498 return (0); in verify_path()
501 if (ifp == NULL && (nh->nh_flags & NHF_DEFAULT) != 0) in verify_path()
502 return (0); in verify_path()
505 if (ifp == NULL && (nh->nh_flags & (NHF_REJECT|NHF_BLACKHOLE)) != 0) in verify_path()
506 return (0); in verify_path()
515 * is given by vtag. The T-bit is set in the ABORT chunk if and only if
516 * reflected is not 0.
536 M_SETFIB(m, id->fib); in ipfw_send_abort()
546 switch (id->addr_type) { in ipfw_send_abort()
562 m->m_data += max_linkhdr; in ipfw_send_abort()
563 m->m_flags |= M_SKIP_FIREWALL; in ipfw_send_abort()
564 m->m_pkthdr.len = m->m_len = tlen; in ipfw_send_abort()
565 m->m_pkthdr.rcvif = NULL; in ipfw_send_abort()
566 bzero(m->m_data, tlen); in ipfw_send_abort()
568 switch (id->addr_type) { in ipfw_send_abort()
572 ip->ip_v = 4; in ipfw_send_abort()
573 ip->ip_hl = sizeof(struct ip) >> 2; in ipfw_send_abort()
574 ip->ip_tos = IPTOS_LOWDELAY; in ipfw_send_abort()
575 ip->ip_len = htons(tlen); in ipfw_send_abort()
576 ip->ip_id = htons(0); in ipfw_send_abort()
577 ip->ip_off = htons(0); in ipfw_send_abort()
578 ip->ip_ttl = V_ip_defttl; in ipfw_send_abort()
579 ip->ip_p = IPPROTO_SCTP; in ipfw_send_abort()
580 ip->ip_sum = 0; in ipfw_send_abort()
581 ip->ip_src.s_addr = htonl(id->dst_ip); in ipfw_send_abort()
582 ip->ip_dst.s_addr = htonl(id->src_ip); in ipfw_send_abort()
590 ip6->ip6_vfc = IPV6_VERSION; in ipfw_send_abort()
591 ip6->ip6_plen = htons(plen); in ipfw_send_abort()
592 ip6->ip6_nxt = IPPROTO_SCTP; in ipfw_send_abort()
593 ip6->ip6_hlim = IPV6_DEFHLIM; in ipfw_send_abort()
594 ip6->ip6_src = id->dst_ip6; in ipfw_send_abort()
595 ip6->ip6_dst = id->src_ip6; in ipfw_send_abort()
602 sctp->src_port = htons(id->dst_port); in ipfw_send_abort()
603 sctp->dest_port = htons(id->src_port); in ipfw_send_abort()
604 sctp->v_tag = htonl(vtag); in ipfw_send_abort()
605 sctp->checksum = htonl(0); in ipfw_send_abort()
608 chunk->chunk_type = SCTP_ABORT_ASSOCIATION; in ipfw_send_abort()
609 chunk->chunk_flags = 0; in ipfw_send_abort()
610 if (reflected != 0) { in ipfw_send_abort()
611 chunk->chunk_flags |= SCTP_HAD_NO_TCB; in ipfw_send_abort()
613 chunk->chunk_length = htons(sizeof(struct sctp_chunkhdr)); in ipfw_send_abort()
615 sctp->checksum = sctp_calculate_cksum(m, hlen); in ipfw_send_abort()
644 M_SETFIB(m, id->fib); in ipfw_send_pkt()
654 switch (id->addr_type) { in ipfw_send_pkt()
670 m->m_data += max_linkhdr; in ipfw_send_pkt()
671 m->m_flags |= M_SKIP_FIREWALL; in ipfw_send_pkt()
672 m->m_pkthdr.len = m->m_len = len; in ipfw_send_pkt()
673 m->m_pkthdr.rcvif = NULL; in ipfw_send_pkt()
674 bzero(m->m_data, len); in ipfw_send_pkt()
676 switch (id->addr_type) { in ipfw_send_pkt()
681 h->ip_p = IPPROTO_TCP; in ipfw_send_pkt()
682 h->ip_len = htons(sizeof(struct tcphdr)); in ipfw_send_pkt()
684 h->ip_src.s_addr = htonl(id->src_ip); in ipfw_send_pkt()
685 h->ip_dst.s_addr = htonl(id->dst_ip); in ipfw_send_pkt()
687 h->ip_src.s_addr = htonl(id->dst_ip); in ipfw_send_pkt()
688 h->ip_dst.s_addr = htonl(id->src_ip); in ipfw_send_pkt()
698 h6->ip6_nxt = IPPROTO_TCP; in ipfw_send_pkt()
699 h6->ip6_plen = htons(sizeof(struct tcphdr)); in ipfw_send_pkt()
701 h6->ip6_src = id->src_ip6; in ipfw_send_pkt()
702 h6->ip6_dst = id->dst_ip6; in ipfw_send_pkt()
704 h6->ip6_src = id->dst_ip6; in ipfw_send_pkt()
705 h6->ip6_dst = id->src_ip6; in ipfw_send_pkt()
714 th->th_sport = htons(id->src_port); in ipfw_send_pkt()
715 th->th_dport = htons(id->dst_port); in ipfw_send_pkt()
717 th->th_sport = htons(id->dst_port); in ipfw_send_pkt()
718 th->th_dport = htons(id->src_port); in ipfw_send_pkt()
720 th->th_off = sizeof(struct tcphdr) >> 2; in ipfw_send_pkt()
724 th->th_seq = htonl(ack); in ipfw_send_pkt()
729 th->th_ack = htonl(seq); in ipfw_send_pkt()
734 * Keepalive - use caller provided sequence numbers in ipfw_send_pkt()
736 th->th_seq = htonl(seq); in ipfw_send_pkt()
737 th->th_ack = htonl(ack); in ipfw_send_pkt()
741 switch (id->addr_type) { in ipfw_send_pkt()
743 th->th_sum = in_cksum(m, len); in ipfw_send_pkt()
746 h->ip_v = 4; in ipfw_send_pkt()
747 h->ip_hl = sizeof(*h) >> 2; in ipfw_send_pkt()
748 h->ip_tos = IPTOS_LOWDELAY; in ipfw_send_pkt()
749 h->ip_off = htons(0); in ipfw_send_pkt()
750 h->ip_len = htons(len); in ipfw_send_pkt()
751 h->ip_ttl = V_ip_defttl; in ipfw_send_pkt()
752 h->ip_sum = 0; in ipfw_send_pkt()
756 th->th_sum = in6_cksum(m, IPPROTO_TCP, sizeof(*h6), in ipfw_send_pkt()
760 h6->ip6_vfc |= IPV6_VERSION; in ipfw_send_pkt()
761 h6->ip6_hlim = IPV6_DEFHLIM; in ipfw_send_pkt()
776 return (type <= ICMP6_MAXTYPE && (cmd->d[type/32] & (1<<(type%32)) ) ); in icmp6type_match()
783 for (i=0; i <= cmd->o.arg1; ++i) in flow6id_match()
784 if (curr_flow == cmd->d[i]) in flow6id_match()
786 return 0; in flow6id_match()
791 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
792 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
802 return (0); in ipfw_localip6()
809 if (!IN6_IS_ADDR_LINKLOCAL(&ia->ia_addr.sin6_addr)) in ipfw_localip6()
811 if (IN6_ARE_MASKED_ADDR_EQUAL(&ia->ia_addr.sin6_addr, in ipfw_localip6()
818 return (0); in ipfw_localip6()
829 nh = fib6_lookup(fib, src, 0, NHR_NONE, 0); in verify_path6()
831 return (0); in verify_path6()
834 if (ifp != NULL && ifp != nh->nh_aifp) in verify_path6()
835 return (0); in verify_path6()
838 if (ifp == NULL && (nh->nh_flags & NHF_DEFAULT) != 0) in verify_path6()
839 return (0); in verify_path6()
842 if (ifp == NULL && (nh->nh_flags & (NHF_REJECT|NHF_BLACKHOLE)) != 0) in verify_path6()
843 return (0); in verify_path6()
860 return (0); in is_icmp6_query()
895 m = args->m; in send_reject6()
896 if (code == ICMP6_UNREACH_RST && args->f_id.proto == IPPROTO_TCP) { in send_reject6()
900 if ((tcp_get_flags(tcp) & TH_RST) == 0) { in send_reject6()
902 m0 = ipfw_send_pkt(args->m, &(args->f_id), in send_reject6()
903 ntohl(tcp->th_seq), ntohl(tcp->th_ack), in send_reject6()
906 ip6_output(m0, NULL, NULL, 0, NULL, NULL, in send_reject6()
911 args->f_id.proto == IPPROTO_SCTP) { in send_reject6()
919 v_tag = ntohl(sctp->v_tag); in send_reject6()
921 if (m->m_len >= hlen + sizeof(struct sctphdr) + in send_reject6()
926 switch (chunk->chunk_type) { in send_reject6()
930 * a zero v-tag. in send_reject6()
932 if (v_tag != 0) { in send_reject6()
933 v_tag = 0; in send_reject6()
937 if (m->m_pkthdr.len > in send_reject6()
939 ntohs(chunk->chunk_length) + 3) { in send_reject6()
943 if ((m->m_len >= hlen + sizeof(struct sctphdr) + in send_reject6()
949 v_tag = ntohl(init->initiate_tag); in send_reject6()
950 reflected = 0; in send_reject6()
960 v_tag = 0; in send_reject6()
964 if (v_tag == 0) { in send_reject6()
967 m0 = ipfw_send_abort(args->m, &(args->f_id), v_tag, in send_reject6()
971 ip6_output(m0, NULL, NULL, 0, NULL, NULL, NULL); in send_reject6()
975 #if 0 in send_reject6()
984 if (args->L3offset) in send_reject6()
985 m_adj(m, args->L3offset); in send_reject6()
987 icmp6_error(m, ICMP6_DST_UNREACH, code, 0); in send_reject6()
991 args->m = NULL; in send_reject6()
1003 #if 0 in send_reject()
1010 if (args->L3offset) in send_reject()
1011 m_adj(m, args->L3offset); in send_reject()
1015 icmp_error(args->m, ICMP_UNREACH, code, 0L, mtu); in send_reject()
1016 } else if (code == ICMP_REJECT_RST && args->f_id.proto == IPPROTO_TCP) { in send_reject()
1018 L3HDR(struct tcphdr, mtod(args->m, struct ip *)); in send_reject()
1019 if ( (tcp_get_flags(tcp) & TH_RST) == 0) { in send_reject()
1021 m = ipfw_send_pkt(args->m, &(args->f_id), in send_reject()
1022 ntohl(tcp->th_seq), ntohl(tcp->th_ack), in send_reject()
1025 ip_output(m, NULL, NULL, 0, NULL, NULL); in send_reject()
1027 FREE_PKT(args->m); in send_reject()
1029 args->f_id.proto == IPPROTO_SCTP) { in send_reject()
1037 sctp = L3HDR(struct sctphdr, mtod(args->m, struct ip *)); in send_reject()
1039 v_tag = ntohl(sctp->v_tag); in send_reject()
1040 if (iplen >= (ip->ip_hl << 2) + sizeof(struct sctphdr) + in send_reject()
1044 switch (chunk->chunk_type) { in send_reject()
1048 * a zero v-tag. in send_reject()
1050 if (v_tag != 0) { in send_reject()
1051 v_tag = 0; in send_reject()
1056 (ip->ip_hl << 2) + sizeof(struct sctphdr) + in send_reject()
1057 ntohs(chunk->chunk_length) + 3) { in send_reject()
1061 if ((iplen >= (ip->ip_hl << 2) + in send_reject()
1066 v_tag = ntohl(init->initiate_tag); in send_reject()
1067 reflected = 0; in send_reject()
1077 v_tag = 0; in send_reject()
1081 if (v_tag == 0) { in send_reject()
1084 m = ipfw_send_abort(args->m, &(args->f_id), v_tag, in send_reject()
1088 ip_output(m, NULL, NULL, 0, NULL, NULL); in send_reject()
1089 FREE_PKT(args->m); in send_reject()
1091 FREE_PKT(args->m); in send_reject()
1092 args->m = NULL; in send_reject()
1098 * so we cache the results. ugid_lookupp is 0 if we have not
1099 * yet done a lookup, 1 if we succeeded, and -1 if we tried
1110 return 0; // not supported in userspace in check_uidgid()
1116 (struct bsd_ucred *)uc, ugid_lookupp, ((struct mbuf *)inp)->m_skb); in check_uidgid()
1125 id = &args->f_id; in check_uidgid()
1126 inp = args->inp; in check_uidgid()
1133 if (inp && *ugid_lookupp == 0) { in check_uidgid()
1135 if (inp->inp_socket != NULL) { in check_uidgid()
1136 *uc = crhold(inp->inp_cred); in check_uidgid()
1139 *ugid_lookupp = -1; in check_uidgid()
1146 if (*ugid_lookupp == -1) in check_uidgid()
1147 return (0); in check_uidgid()
1148 if (id->proto == IPPROTO_TCP) { in check_uidgid()
1149 lookupflags = 0; in check_uidgid()
1151 } else if (id->proto == IPPROTO_UDP) { in check_uidgid()
1154 } else if (id->proto == IPPROTO_UDPLITE) { in check_uidgid()
1158 return 0; in check_uidgid()
1160 match = 0; in check_uidgid()
1161 if (*ugid_lookupp == 0) { in check_uidgid()
1162 if (id->addr_type == 6) { in check_uidgid()
1164 if (args->flags & IPFW_ARGS_IN) in check_uidgid()
1166 &id->src_ip6, htons(id->src_port), in check_uidgid()
1167 &id->dst_ip6, htons(id->dst_port), in check_uidgid()
1168 lookupflags, NULL, args->m); in check_uidgid()
1171 &id->dst_ip6, htons(id->dst_port), in check_uidgid()
1172 &id->src_ip6, htons(id->src_port), in check_uidgid()
1173 lookupflags, args->ifp, args->m); in check_uidgid()
1175 *ugid_lookupp = -1; in check_uidgid()
1176 return (0); in check_uidgid()
1179 src_ip.s_addr = htonl(id->src_ip); in check_uidgid()
1180 dst_ip.s_addr = htonl(id->dst_ip); in check_uidgid()
1181 if (args->flags & IPFW_ARGS_IN) in check_uidgid()
1183 src_ip, htons(id->src_port), in check_uidgid()
1184 dst_ip, htons(id->dst_port), in check_uidgid()
1185 lookupflags, NULL, args->m); in check_uidgid()
1188 dst_ip, htons(id->dst_port), in check_uidgid()
1189 src_ip, htons(id->src_port), in check_uidgid()
1190 lookupflags, args->ifp, args->m); in check_uidgid()
1194 *uc = crhold(pcb->inp_cred); in check_uidgid()
1198 if (*ugid_lookupp == 0) { in check_uidgid()
1200 * We tried and failed, set the variable to -1 in check_uidgid()
1203 *ugid_lookupp = -1; in check_uidgid()
1204 return (0); in check_uidgid()
1207 if (insn->o.opcode == O_UID) in check_uidgid()
1208 match = ((*uc)->cr_uid == (uid_t)insn->d[0]); in check_uidgid()
1209 else if (insn->o.opcode == O_GID) in check_uidgid()
1210 match = groupmember((gid_t)insn->d[0], *uc); in check_uidgid()
1211 else if (insn->o.opcode == O_JAIL) in check_uidgid()
1212 match = ((*uc)->cr_prison->pr_id == (int)insn->d[0]); in check_uidgid()
1227 args->rule.chain_id = chain->id; in set_match()
1228 args->rule.slot = slot + 1; /* we use 0 as a marker */ in set_match()
1229 args->rule.rule_id = 1 + chain->map[slot]->id; in set_match()
1230 args->rule.rulenum = chain->map[slot]->rulenum; in set_match()
1231 args->flags |= IPFW_ARGS_REF; in set_match()
1244 if (!jump_backwards && i <= f->rulenum) in jump_lookup_pos()
1245 i = f->rulenum + 1; in jump_lookup_pos()
1247 if (V_skipto_cache == 0) in jump_lookup_pos()
1248 f_pos = ipfw_find_rule(chain, i, 0); in jump_lookup_pos()
1254 i = IPFW_DEFAULT_RULE - 1; in jump_lookup_pos()
1255 f_pos = chain->idxmap[i]; in jump_lookup_pos()
1272 * If possible use cached f_pos (in f->cache.pos), in jump()
1273 * whose version is written in f->cache.id (horrible hacks in jump()
1283 cache.raw_value = f->cache.raw_value; in jump()
1284 if (cache.id == chain->id) in jump()
1290 cache.id = chain->id; in jump()
1291 f->cache.raw_value = cache.raw_value; in jump()
1293 if (f->cache.id == chain->id) { in jump()
1296 return (f->cache.pos); in jump()
1301 f->cache.pos = f_pos; in jump()
1304 f->cache.id = chain->id; in jump()
1317 switch (IPFW_TVALUE_TYPE(&cmd->o)) { in tvalue_match()
1353 return (tvalue == cmd->value); in tvalue_match()
1364 * args->m (in/out) The packet; we set to NULL when/if we nuke it.
1366 * args->L3offset Number of bytes bypassed if we came from L2.
1368 * args->ifp Incoming or outgoing interface.
1369 * args->divert_rule (in/out)
1371 * upon return, non-zero port number for divert or tee.
1373 * args->rule Pointer to the last matching rule (in/out)
1374 * args->next_hop Socket we are forwarding to (out).
1375 * args->next_hop6 IPv6 next hop we are forwarding to (out).
1376 * args->f_id Addresses grabbed from the packet (out)
1377 * args->rule.info a cookie depending on rule action
1385 * IP_FW_DUMMYNET to dummynet, pipe in args->cookie
1386 * IP_FW_NETGRAPH into netgraph, cookie args->cookie
1387 * args->rule contains the matching rule,
1388 * args->rule.info has additional information.
1404 * m | args->m Pointer to the mbuf, as received from the caller. in ipfw_chk()
1410 * args->mem Pointer to contigous memory chunk. in ipfw_chk()
1430 uint32_t f_pos = 0; /* index of current rule in the array */ in ipfw_chk()
1431 int ucred_lookup = 0; in ipfw_chk()
1432 int retval = 0; in ipfw_chk()
1438 u_int hlen = 0; /* hlen >0 means we have an IP pkt */ in ipfw_chk()
1441 * offset The offset of a fragment. offset != 0 means that in ipfw_chk()
1443 * offset == 0 means that (if this is an IPv4 packet) in ipfw_chk()
1445 * For IPv6 offset|ip6f_mf == 0 means there is no Fragment Header in ipfw_chk()
1451 u_short offset = 0; in ipfw_chk()
1452 u_short ip6f_mf = 0; in ipfw_chk()
1458 * proto The protocol. Set to 0 for non-ip packets, in ipfw_chk()
1460 * proto != 0 means that we have an IPv4 packet. in ipfw_chk()
1471 int iplen = 0; in ipfw_chk()
1479 * We store in ulp a pointer to the upper layer protocol header. in ipfw_chk()
1482 * ulp is NULL if not found. in ipfw_chk()
1484 void *ulp = NULL; /* upper layer protocol pointer. */ in ipfw_chk() local
1487 int is_ipv6 = 0; in ipfw_chk()
1489 uint8_t icmp6_type = 0; in ipfw_chk()
1491 uint16_t ext_hd = 0; /* bits vector for extension header filtering */ in ipfw_chk()
1494 int is_ipv4 = 0; in ipfw_chk()
1496 int done = 0; /* flag to exit the outer loop */ in ipfw_chk()
1503 if ((mem = (args->flags & IPFW_ARGS_LENMASK))) { in ipfw_chk()
1504 if (args->flags & IPFW_ARGS_ETHER) { in ipfw_chk()
1505 eh = (struct ether_header *)args->mem; in ipfw_chk()
1506 if (eh->ether_type == htons(ETHERTYPE_VLAN)) in ipfw_chk()
1513 ip = (struct ip *)args->mem; in ipfw_chk()
1515 pktlen = IPFW_ARGS_LENGTH(args->flags); in ipfw_chk()
1516 args->f_id.fib = args->ifp->if_fib; /* best guess */ in ipfw_chk()
1518 m = args->m; in ipfw_chk()
1519 if (m->m_flags & M_SKIP_FIREWALL || (! V_ipfw_vnet_ready)) in ipfw_chk()
1521 if (args->flags & IPFW_ARGS_ETHER) { in ipfw_chk()
1523 if (m->m_len < min(m->m_pkthdr.len, max_protohdr) && in ipfw_chk()
1524 (args->m = m = m_pullup(m, min(m->m_pkthdr.len, in ipfw_chk()
1533 pktlen = m->m_pkthdr.len; in ipfw_chk()
1534 args->f_id.fib = M_GETFIB(m); /* mbuf not altered */ in ipfw_chk()
1537 dst_ip.s_addr = 0; /* make sure it is initialized */ in ipfw_chk()
1538 src_ip.s_addr = 0; /* make sure it is initialized */ in ipfw_chk()
1539 src_port = dst_port = 0; in ipfw_chk()
1549 #define EHLEN (eh != NULL ? ((char *)ip - (char *)eh) : 0) in ipfw_chk()
1558 p = (char *)args->mem + (_len) + EHLEN; \ in ipfw_chk()
1560 if (__predict_false((m)->m_len < x)) { \ in ipfw_chk()
1561 args->m = m = m_pullup(m, x); \ in ipfw_chk()
1569 } while (0) in ipfw_chk()
1586 args->m = m; \ in ipfw_chk()
1588 } while (0) in ipfw_chk()
1592 (eh == NULL || eh->ether_type == htons(ETHERTYPE_IPV6)) && in ipfw_chk()
1593 ip->ip_v == 6) { in ipfw_chk()
1597 args->flags |= IPFW_ARGS_IP6; in ipfw_chk()
1599 proto = ip6->ip6_nxt; in ipfw_chk()
1601 while (ulp == NULL && offset == 0) { in ipfw_chk()
1604 PULLUP_TO(hlen, ulp, struct icmp6_hdr); in ipfw_chk()
1606 icmp6_type = ICMP6(ulp)->icmp6_type; in ipfw_chk()
1611 PULLUP_TO(hlen, ulp, struct tcphdr); in ipfw_chk()
1612 dst_port = TCP(ulp)->th_dport; in ipfw_chk()
1613 src_port = TCP(ulp)->th_sport; in ipfw_chk()
1615 args->f_id._flags = tcp_get_flags(TCP(ulp)); in ipfw_chk()
1622 PULLUP_LEN(hlen, ulp, in ipfw_chk()
1627 PULLUP_LEN(hlen, ulp, pktlen - hlen); in ipfw_chk()
1629 PULLUP_LEN(hlen, ulp, in ipfw_chk()
1631 src_port = SCTP(ulp)->src_port; in ipfw_chk()
1632 dst_port = SCTP(ulp)->dest_port; in ipfw_chk()
1637 PULLUP_TO(hlen, ulp, struct udphdr); in ipfw_chk()
1638 dst_port = UDP(ulp)->uh_dport; in ipfw_chk()
1639 src_port = UDP(ulp)->uh_sport; in ipfw_chk()
1643 PULLUP_TO(hlen, ulp, struct ip6_hbh); in ipfw_chk()
1645 hlen += (((struct ip6_hbh *)ulp)->ip6h_len + 1) << 3; in ipfw_chk()
1646 proto = ((struct ip6_hbh *)ulp)->ip6h_nxt; in ipfw_chk()
1647 ulp = NULL; in ipfw_chk()
1651 PULLUP_TO(hlen, ulp, struct ip6_rthdr); in ipfw_chk()
1652 switch (((struct ip6_rthdr *)ulp)->ip6r_type) { in ipfw_chk()
1653 case 0: in ipfw_chk()
1661 printf("IPFW2: IPV6 - Unknown " in ipfw_chk()
1664 ulp)->ip6r_type); in ipfw_chk()
1670 hlen += (((struct ip6_rthdr *)ulp)->ip6r_len + 1) << 3; in ipfw_chk()
1671 proto = ((struct ip6_rthdr *)ulp)->ip6r_nxt; in ipfw_chk()
1672 ulp = NULL; in ipfw_chk()
1676 PULLUP_TO(hlen, ulp, struct ip6_frag); in ipfw_chk()
1679 proto = ((struct ip6_frag *)ulp)->ip6f_nxt; in ipfw_chk()
1680 offset = ((struct ip6_frag *)ulp)->ip6f_offlg & in ipfw_chk()
1682 ip6f_mf = ((struct ip6_frag *)ulp)->ip6f_offlg & in ipfw_chk()
1684 if (V_fw_permit_single_frag6 == 0 && in ipfw_chk()
1685 offset == 0 && ip6f_mf == 0) { in ipfw_chk()
1687 printf("IPFW2: IPV6 - Invalid " in ipfw_chk()
1693 args->f_id.extra = in ipfw_chk()
1694 ntohl(((struct ip6_frag *)ulp)->ip6f_ident); in ipfw_chk()
1695 ulp = NULL; in ipfw_chk()
1699 PULLUP_TO(hlen, ulp, struct ip6_hbh); in ipfw_chk()
1701 hlen += (((struct ip6_hbh *)ulp)->ip6h_len + 1) << 3; in ipfw_chk()
1702 proto = ((struct ip6_hbh *)ulp)->ip6h_nxt; in ipfw_chk()
1703 ulp = NULL; in ipfw_chk()
1707 PULLUP_TO(hlen, ulp, struct ip6_ext); in ipfw_chk()
1709 hlen += (((struct ip6_ext *)ulp)->ip6e_len + 2) << 2; in ipfw_chk()
1710 proto = ((struct ip6_ext *)ulp)->ip6e_nxt; in ipfw_chk()
1711 ulp = NULL; in ipfw_chk()
1715 PULLUP_TO(hlen, ulp, uint32_t); /* SPI, Seq# */ in ipfw_chk()
1724 * already been pulled up. If ip6e_len!=0 in ipfw_chk()
1727 ulp = ip; /* non-NULL to get out of loop. */ in ipfw_chk()
1732 PULLUP_TO(hlen, ulp, struct ip6_ext); in ipfw_chk()
1737 PULLUP_TO(hlen, ulp, struct pim); in ipfw_chk()
1742 PULLUP_TO(hlen, ulp, struct grehdr); in ipfw_chk()
1746 PULLUP_TO(hlen, ulp, offsetof( in ipfw_chk()
1749 ((struct carp_header *)ulp)->carp_type) in ipfw_chk()
1754 PULLUP_TO(hlen, ulp, struct ip6_hdr); in ipfw_chk()
1758 PULLUP_TO(hlen, ulp, struct ip); in ipfw_chk()
1762 PULLUP_LEN(hlen, ulp, in ipfw_chk()
1768 PULLUP_TO(hlen, ulp, struct pfsync_header); in ipfw_chk()
1773 printf("IPFW2: IPV6 - Unknown " in ipfw_chk()
1778 PULLUP_TO(hlen, ulp, struct ip6_ext); in ipfw_chk()
1784 args->f_id.addr_type = 6; in ipfw_chk()
1785 args->f_id.src_ip6 = ip6->ip6_src; in ipfw_chk()
1786 args->f_id.dst_ip6 = ip6->ip6_dst; in ipfw_chk()
1787 args->f_id.flow_id6 = ntohl(ip6->ip6_flow); in ipfw_chk()
1788 iplen = ntohs(ip6->ip6_plen) + sizeof(*ip6); in ipfw_chk()
1790 (eh == NULL || eh->ether_type == htons(ETHERTYPE_IP)) && in ipfw_chk()
1791 ip->ip_v == 4) { in ipfw_chk()
1793 args->flags |= IPFW_ARGS_IP4; in ipfw_chk()
1794 hlen = ip->ip_hl << 2; in ipfw_chk()
1799 proto = ip->ip_p; in ipfw_chk()
1800 src_ip = ip->ip_src; in ipfw_chk()
1801 dst_ip = ip->ip_dst; in ipfw_chk()
1802 offset = ntohs(ip->ip_off) & IP_OFFMASK; in ipfw_chk()
1803 iplen = ntohs(ip->ip_len); in ipfw_chk()
1805 if (offset == 0) { in ipfw_chk()
1808 PULLUP_TO(hlen, ulp, struct tcphdr); in ipfw_chk()
1809 dst_port = TCP(ulp)->th_dport; in ipfw_chk()
1810 src_port = TCP(ulp)->th_sport; in ipfw_chk()
1812 args->f_id._flags = tcp_get_flags(TCP(ulp)); in ipfw_chk()
1819 PULLUP_LEN(hlen, ulp, in ipfw_chk()
1824 PULLUP_LEN(hlen, ulp, pktlen - hlen); in ipfw_chk()
1826 PULLUP_LEN(hlen, ulp, in ipfw_chk()
1828 src_port = SCTP(ulp)->src_port; in ipfw_chk()
1829 dst_port = SCTP(ulp)->dest_port; in ipfw_chk()
1834 PULLUP_TO(hlen, ulp, struct udphdr); in ipfw_chk()
1835 dst_port = UDP(ulp)->uh_dport; in ipfw_chk()
1836 src_port = UDP(ulp)->uh_sport; in ipfw_chk()
1840 PULLUP_TO(hlen, ulp, struct icmphdr); in ipfw_chk()
1841 //args->f_id.flags = ICMP(ulp)->icmp_type; in ipfw_chk()
1855 args->f_id.addr_type = 4; in ipfw_chk()
1856 args->f_id.src_ip = ntohl(src_ip.s_addr); in ipfw_chk()
1857 args->f_id.dst_ip = ntohl(dst_ip.s_addr); in ipfw_chk()
1859 proto = 0; in ipfw_chk()
1860 dst_ip.s_addr = src_ip.s_addr = 0; in ipfw_chk()
1862 args->f_id.addr_type = 1; /* XXX */ in ipfw_chk()
1868 args->f_id.proto = proto; in ipfw_chk()
1869 args->f_id.src_port = src_port = ntohs(src_port); in ipfw_chk()
1870 args->f_id.dst_port = dst_port = ntohs(dst_port); in ipfw_chk()
1877 if (args->flags & IPFW_ARGS_REF) { in ipfw_chk()
1880 * match on rule args->rule aka args->rule_id (PIPE, QUEUE, in ipfw_chk()
1885 f_pos = (args->rule.chain_id == chain->id) ? in ipfw_chk()
1886 args->rule.slot : in ipfw_chk()
1887 ipfw_find_rule(chain, args->rule.rulenum, in ipfw_chk()
1888 args->rule.rule_id); in ipfw_chk()
1890 f_pos = 0; in ipfw_chk()
1893 if (args->flags & IPFW_ARGS_IN) { in ipfw_chk()
1894 iif = args->ifp; in ipfw_chk()
1897 MPASS(args->flags & IPFW_ARGS_OUT); in ipfw_chk()
1899 oif = args->ifp; in ipfw_chk()
1905 * need to break out of one or both loops, or re-enter one of in ipfw_chk()
1914 * We break the inner loop by setting l=0 and possibly in ipfw_chk()
1915 * cmdlen=0 if we don't want to advance cmd. in ipfw_chk()
1917 * We can restart the inner loop by setting l>0 and f_pos, f, cmd in ipfw_chk()
1920 for (; f_pos < chain->n_rules; f_pos++) { in ipfw_chk()
1922 uint32_t tablearg = 0; in ipfw_chk()
1926 f = chain->map[f_pos]; in ipfw_chk()
1927 if (V_set_disable & (1 << f->set) ) in ipfw_chk()
1930 skip_or = 0; in ipfw_chk()
1931 for (l = f->cmd_len, cmd = f->cmd ; l > 0 ; in ipfw_chk()
1932 l -= cmdlen, cmd += cmdlen) { in ipfw_chk()
1951 if ((cmd->len & F_OR) == 0) in ipfw_chk()
1952 skip_or = 0; /* next one is good */ in ipfw_chk()
1955 match = 0; /* set to 1 if we succeed */ in ipfw_chk()
1957 switch (cmd->opcode) { in ipfw_chk()
1971 cmd->opcode); in ipfw_chk()
1978 * We only check offset == 0 && proto != 0, in ipfw_chk()
1982 if (offset != 0) in ipfw_chk()
2008 match = iface_match(args->ifp, in ipfw_chk()
2013 if (args->flags & IPFW_ARGS_ETHER) { in ipfw_chk()
2015 ((ipfw_insn_mac *)cmd)->addr; in ipfw_chk()
2017 ((ipfw_insn_mac *)cmd)->mask; in ipfw_chk()
2021 ( want[0] == (hdr[0] & mask[0]) && in ipfw_chk()
2028 if (args->flags & IPFW_ARGS_ETHER) { in ipfw_chk()
2030 ((ipfw_insn_u16 *)cmd)->ports; in ipfw_chk()
2033 for (i = cmdlen - 1; !match && i>0; in ipfw_chk()
2034 i--, p += 2) in ipfw_chk()
2036 (ntohs(eh->ether_type) >= in ipfw_chk()
2037 p[0] && in ipfw_chk()
2038 ntohs(eh->ether_type) <= in ipfw_chk()
2051 ((ntohs(ip->ip_off) & ~IP_OFFMASK) in ipfw_chk()
2052 >> 8) | (offset != 0)); in ipfw_chk()
2058 match = (cmd->arg1 == 0x1 && in ipfw_chk()
2059 (offset != 0)); in ipfw_chk()
2068 match = (args->flags & IPFW_ARGS_ETHER); in ipfw_chk()
2072 if ((args->flags & IPFW_ARGS_REF) == 0) in ipfw_chk()
2075 * For diverted packets, args->rule.info in ipfw_chk()
2079 match = ((args->rule.info & IPFW_IS_MASK) == in ipfw_chk()
2081 ((args->rule.info & IPFW_INFO_IN) ? in ipfw_chk()
2082 1: 2) & cmd->arg1); in ipfw_chk()
2087 * We do not allow an arg of 0 so the in ipfw_chk()
2090 match = (proto == cmd->arg1); in ipfw_chk()
2095 (((ipfw_insn_ip *)cmd)->addr.s_addr == in ipfw_chk()
2103 uint16_t keylen = 0; /* zero if can't match the packet */ in ipfw_chk()
2120 pkey = &args->f_id.dst_ip6; in ipfw_chk()
2122 pkey = &args->f_id.src_ip6; in ipfw_chk()
2127 key = ip->ip_tos >> 2; in ipfw_chk()
2134 key &= 0x3f; in ipfw_chk()
2136 key &= insntod(cmd, table)->value; in ipfw_chk()
2143 if (is_ipv6 == 0 && is_ipv4 == 0) { in ipfw_chk()
2147 if (offset != 0) { in ipfw_chk()
2162 key &= insntod(cmd, table)->value; in ipfw_chk()
2168 if ((args->flags & IPFW_ARGS_ETHER) == 0) in ipfw_chk()
2172 eh->ether_dhost : eh->ether_shost; in ipfw_chk()
2183 key = ucred_cache->cr_uid; in ipfw_chk()
2185 key = ucred_cache->cr_prison->pr_id; in ipfw_chk()
2195 key &= insntod(cmd, table)->value; in ipfw_chk()
2200 key = args->rule.pkt_mark; in ipfw_chk()
2202 key &= insntod(cmd, table)->value; in ipfw_chk()
2207 key = f->rulenum; in ipfw_chk()
2209 key &= insntod(cmd, table)->value; in ipfw_chk()
2215 if (keylen == 0) in ipfw_chk()
2218 insntod(cmd, kidx)->kidx, keylen, in ipfw_chk()
2235 if (cmd->opcode == O_IP_DST_LOOKUP) in ipfw_chk()
2241 if (cmd->opcode == O_IP_DST_LOOKUP) in ipfw_chk()
2242 pkey = &args->f_id.dst_ip6; in ipfw_chk()
2244 pkey = &args->f_id.src_ip6; in ipfw_chk()
2248 insntod(cmd, kidx)->kidx, in ipfw_chk()
2270 if ((args->flags & IPFW_ARGS_ETHER) == 0) in ipfw_chk()
2273 if (cmd->opcode == O_MAC_DST_LOOKUP) in ipfw_chk()
2274 pkey = eh->ether_dhost; in ipfw_chk()
2276 pkey = eh->ether_shost; in ipfw_chk()
2279 insntod(cmd, kidx)->kidx, in ipfw_chk()
2295 uint32_t vidx = 0; in ipfw_chk()
2298 insntod(cmd, kidx)->kidx, 0, in ipfw_chk()
2299 &args->f_id, &vidx); in ipfw_chk()
2314 (cmd->opcode == O_IP_DST_MASK) ? in ipfw_chk()
2316 uint32_t *p = ((ipfw_insn_u32 *)cmd)->d; in ipfw_chk()
2317 int i = cmdlen-1; in ipfw_chk()
2319 for (; !match && i>0; i-= 2, p+= 2) in ipfw_chk()
2320 match = (p[0] == (a & p[1])); in ipfw_chk()
2333 ipfw_localip6(&args->f_id.src_ip6); in ipfw_chk()
2342 cmd->opcode == O_IP_DST_SET ? in ipfw_chk()
2343 args->f_id.dst_ip : in ipfw_chk()
2344 args->f_id.src_ip; in ipfw_chk()
2346 if (addr < d[0]) in ipfw_chk()
2348 addr -= d[0]; /* subtract base */ in ipfw_chk()
2349 match = (addr < cmd->arg1) && in ipfw_chk()
2351 (1<<(addr & 0x1f)) ); in ipfw_chk()
2357 (((ipfw_insn_ip *)cmd)->addr.s_addr == in ipfw_chk()
2370 ipfw_localip6(&args->f_id.dst_ip6); in ipfw_chk()
2377 * offset == 0 && proto != 0 is enough in ipfw_chk()
2384 proto == IPPROTO_SCTP) && offset == 0) { in ipfw_chk()
2386 (cmd->opcode == O_IP_SRCPORT) ? in ipfw_chk()
2389 ((ipfw_insn_u16 *)cmd)->ports; in ipfw_chk()
2392 for (i = cmdlen - 1; !match && i>0; in ipfw_chk()
2393 i--, p += 2) in ipfw_chk()
2394 match = (x>=p[0] && x<=p[1]); in ipfw_chk()
2399 match = (offset == 0 && proto==IPPROTO_ICMP && in ipfw_chk()
2400 icmptype_match(ICMP(ulp), (ipfw_insn_u32 *)cmd) ); in ipfw_chk()
2405 match = is_ipv6 && offset == 0 && in ipfw_chk()
2408 ICMP6(ulp)->icmp6_type, in ipfw_chk()
2420 cmd->arg1 == ip->ip_v); in ipfw_chk()
2433 if (cmd->opcode == O_IPLEN) in ipfw_chk()
2435 else if (cmd->opcode == O_IPTTL) in ipfw_chk()
2436 x = ip->ip_ttl; in ipfw_chk()
2438 x = ntohs(ip->ip_id); in ipfw_chk()
2440 match = (cmd->arg1 == x); in ipfw_chk()
2444 p = ((ipfw_insn_u16 *)cmd)->ports; in ipfw_chk()
2445 i = cmdlen - 1; in ipfw_chk()
2446 for (; !match && i>0; i--, p += 2) in ipfw_chk()
2447 match = (x >= p[0] && x <= p[1]); in ipfw_chk()
2453 (cmd->arg1 == (ip->ip_tos & 0xe0)) ); in ipfw_chk()
2458 flags_match(cmd, ip->ip_tos)); in ipfw_chk()
2466 p = ((ipfw_insn_u32 *)cmd)->d; in ipfw_chk()
2469 x = ip->ip_tos >> 2; in ipfw_chk()
2473 x &= 0x3f; in ipfw_chk()
2479 match = *(p + 1) & (1 << (x - 32)); in ipfw_chk()
2486 if (proto == IPPROTO_TCP && offset == 0) { in ipfw_chk()
2496 if (ip6->ip6_plen == 0) { in ipfw_chk()
2504 x = iplen - hlen; in ipfw_chk()
2507 x = iplen - (ip->ip_hl << 2); in ipfw_chk()
2508 tcp = TCP(ulp); in ipfw_chk()
2509 x -= tcp->th_off << 2; in ipfw_chk()
2511 match = (cmd->arg1 == x); in ipfw_chk()
2515 p = ((ipfw_insn_u16 *)cmd)->ports; in ipfw_chk()
2516 i = cmdlen - 1; in ipfw_chk()
2517 for (; !match && i>0; i--, p += 2) in ipfw_chk()
2518 match = (x >= p[0] && x <= p[1]); in ipfw_chk()
2528 match = (proto == IPPROTO_TCP && offset == 0 && in ipfw_chk()
2529 flags_match(cmd, tcp_get_flags(TCP(ulp)))); in ipfw_chk()
2533 if (proto == IPPROTO_TCP && offset == 0 && ulp){ in ipfw_chk()
2534 PULLUP_LEN_LOCKED(hlen, ulp, in ipfw_chk()
2535 (TCP(ulp)->th_off << 2)); in ipfw_chk()
2536 match = tcpopts_match(TCP(ulp), cmd); in ipfw_chk()
2541 match = (proto == IPPROTO_TCP && offset == 0 && in ipfw_chk()
2542 ((ipfw_insn_u32 *)cmd)->d[0] == in ipfw_chk()
2543 TCP(ulp)->th_seq); in ipfw_chk()
2547 match = (proto == IPPROTO_TCP && offset == 0 && in ipfw_chk()
2548 ((ipfw_insn_u32 *)cmd)->d[0] == in ipfw_chk()
2549 TCP(ulp)->th_ack); in ipfw_chk()
2554 (args->f_id._flags & TH_SYN) != 0 && in ipfw_chk()
2555 ulp != NULL) { in ipfw_chk()
2559 PULLUP_LEN_LOCKED(hlen, ulp, in ipfw_chk()
2560 (TCP(ulp)->th_off << 2)); in ipfw_chk()
2561 if ((tcpopts_parse(TCP(ulp), &mss) & in ipfw_chk()
2562 IP_FW_TCPOPT_MSS) == 0) in ipfw_chk()
2565 match = (cmd->arg1 == mss); in ipfw_chk()
2569 p = ((ipfw_insn_u16 *)cmd)->ports; in ipfw_chk()
2570 i = cmdlen - 1; in ipfw_chk()
2571 for (; !match && i > 0; i--, p += 2) in ipfw_chk()
2572 match = (mss >= p[0] && in ipfw_chk()
2578 if (proto == IPPROTO_TCP && offset == 0) { in ipfw_chk()
2583 x = ntohs(TCP(ulp)->th_win); in ipfw_chk()
2585 match = (cmd->arg1 == x); in ipfw_chk()
2589 p = ((ipfw_insn_u16 *)cmd)->ports; in ipfw_chk()
2590 i = cmdlen - 1; in ipfw_chk()
2591 for (; !match && i > 0; i--, p += 2) in ipfw_chk()
2592 match = (x >= p[0] && x <= p[1]); in ipfw_chk()
2599 match = (proto == IPPROTO_TCP && offset == 0 && in ipfw_chk()
2600 (tcp_get_flags(TCP(ulp)) & in ipfw_chk()
2611 * packet filtering system - pf(4). in ipfw_chk()
2617 if (at != NULL && at->qid != 0) in ipfw_chk()
2630 at->qid = altq->qid; in ipfw_chk()
2631 at->hdr = ip; in ipfw_chk()
2642 match = (random()<((ipfw_insn_u32 *)cmd)->d[0]); in ipfw_chk()
2647 match = (args->flags & IPFW_ARGS_OUT || in ipfw_chk()
2651 verify_path6(&(args->f_id.src_ip6), in ipfw_chk()
2652 iif, args->f_id.fib) : in ipfw_chk()
2654 verify_path(src_ip, iif, args->f_id.fib))); in ipfw_chk()
2659 match = (hlen > 0 && ((oif != NULL) || ( in ipfw_chk()
2662 verify_path6(&(args->f_id.src_ip6), in ipfw_chk()
2663 NULL, args->f_id.fib) : in ipfw_chk()
2665 verify_path(src_ip, NULL, args->f_id.fib)))); in ipfw_chk()
2670 if (oif == NULL && hlen > 0 && in ipfw_chk()
2674 in6_localaddr(&(args->f_id.src_ip6))) in ipfw_chk()
2680 &(args->f_id.src_ip6), iif, in ipfw_chk()
2681 args->f_id.fib) : in ipfw_chk()
2684 args->f_id.fib); in ipfw_chk()
2698 IN6_ARE_ADDR_EQUAL(&args->f_id.src_ip6, in ipfw_chk()
2699 &((ipfw_insn_ip6 *)cmd)->addr6); in ipfw_chk()
2704 IN6_ARE_ADDR_EQUAL(&args->f_id.dst_ip6, in ipfw_chk()
2705 &((ipfw_insn_ip6 *)cmd)->addr6); in ipfw_chk()
2710 int i = cmdlen - 1; in ipfw_chk()
2713 &((ipfw_insn_ip6 *)cmd)->addr6; in ipfw_chk()
2715 for (; !match && i > 0; d += 2, in ipfw_chk()
2716 i -= F_INSN_SIZE(struct in6_addr) in ipfw_chk()
2718 p = (cmd->opcode == in ipfw_chk()
2720 args->f_id.src_ip6: in ipfw_chk()
2721 args->f_id.dst_ip6; in ipfw_chk()
2724 IN6_ARE_ADDR_EQUAL(&d[0], in ipfw_chk()
2732 flow6id_match(args->f_id.flow_id6, in ipfw_chk()
2738 (ext_hd & ((ipfw_insn *) cmd)->arg1); in ipfw_chk()
2752 uint32_t tag = TARG(cmd->arg1, tag); in ipfw_chk()
2764 if (cmd->len & F_NOT) { /* `untag' action */ in ipfw_chk()
2767 match = 0; in ipfw_chk()
2771 tag, 0, M_NOWAIT); in ipfw_chk()
2781 if (args->f_id.fib == cmd->arg1) in ipfw_chk()
2787 struct inpcb *inp = args->inp; in ipfw_chk()
2819 &args->f_id.src_ip6, in ipfw_chk()
2821 &args->f_id.dst_ip6, in ipfw_chk()
2828 if (inp->inp_socket) { in ipfw_chk()
2830 inp->inp_socket->so_user_cookie; in ipfw_chk()
2843 uint32_t tag = TARG(cmd->arg1, tag); in ipfw_chk()
2858 if (mtag->m_tag_cookie != MTAG_IPFW) in ipfw_chk()
2861 p = ((ipfw_insn_u16 *)cmd)->ports; in ipfw_chk()
2862 i = cmdlen - 1; in ipfw_chk()
2863 for(; !match && i > 0; i--, p += 2) in ipfw_chk()
2865 mtag->m_tag_id >= p[0] && in ipfw_chk()
2866 mtag->m_tag_id <= p[1]; in ipfw_chk()
2873 if (cmd->arg1 == IP_FW_TARG) in ipfw_chk()
2876 mark = insntoc(cmd, u32)->d[0]; in ipfw_chk()
2878 (args->rule.pkt_mark & in ipfw_chk()
2879 insntoc(cmd, u32)->d[1]) == in ipfw_chk()
2880 (mark & insntoc(cmd, u32)->d[1]); in ipfw_chk()
2890 * (but there are exceptions -- see below). in ipfw_chk()
2894 * but we need to set l=0, done=1) in ipfw_chk()
2899 * (setting l=0), or to the SKIPTO target (setting in ipfw_chk()
2914 * break loops with l=0, done=1) in ipfw_chk()
2925 * l=0, cmdlen=0. in ipfw_chk()
2940 (ipfw_insn_limit *)cmd, args, ulp, in ipfw_chk()
2944 l = 0; /* exit inner loop */ in ipfw_chk()
2954 * keep-state or check-state occurrence, in ipfw_chk()
2962 (q = ipfw_dyn_lookup_state(args, ulp, in ipfw_chk()
2973 l = f->cmd_len - f->act_ofs; in ipfw_chk()
2974 cmdlen = 0; in ipfw_chk()
2982 if (cmd->opcode == O_CHECK_STATE) in ipfw_chk()
2983 l = 0; /* exit inner loop */ in ipfw_chk()
2988 match = 0; /* skip to the next rule */ in ipfw_chk()
2989 l = 0; /* exit inner loop */ in ipfw_chk()
2993 retval = 0; /* accept */ in ipfw_chk()
2994 l = 0; /* exit inner loop */ in ipfw_chk()
3001 args->rule.info = TARG(cmd->arg1, pipe); in ipfw_chk()
3002 if (cmd->opcode == O_PIPE) in ipfw_chk()
3003 args->rule.info |= IPFW_IS_PIPE; in ipfw_chk()
3005 args->rule.info |= IPFW_ONEPASS; in ipfw_chk()
3007 l = 0; /* exit inner loop */ in ipfw_chk()
3013 if (args->flags & IPFW_ARGS_ETHER) in ipfw_chk()
3016 l = 0; /* exit inner loop */ in ipfw_chk()
3018 retval = (cmd->opcode == O_DIVERT) ? in ipfw_chk()
3021 args->rule.info = TARG(cmd->arg1, divert); in ipfw_chk()
3026 l = 0; /* exit inner loop */ in ipfw_chk()
3032 insntod(cmd, u32)->d[0], tablearg, false); in ipfw_chk()
3034 * Skip disabled rules, and re-enter in ipfw_chk()
3039 for (; f_pos < chain->n_rules - 1 && in ipfw_chk()
3041 (1 << chain->map[f_pos]->set)); in ipfw_chk()
3044 /* Re-enter the inner loop at the skipto rule. */ in ipfw_chk()
3045 f = chain->map[f_pos]; in ipfw_chk()
3046 l = f->cmd_len; in ipfw_chk()
3047 cmd = f->cmd; in ipfw_chk()
3049 cmdlen = 0; in ipfw_chk()
3050 skip_or = 0; in ipfw_chk()
3068 #define IS_CALL ((cmd->len & F_NOT) == 0) in ipfw_chk()
3069 #define IS_RETURN ((cmd->len & F_NOT) != 0) in ipfw_chk()
3071 * Hand-rolled version of m_tag_locate() with in ipfw_chk()
3077 if (mtag->m_tag_cookie == in ipfw_chk()
3085 * of stack. If it doesn't match chain->id, in ipfw_chk()
3093 if (stack[0] != chain->id) { in ipfw_chk()
3094 stack[0] = chain->id; in ipfw_chk()
3095 mtag->m_tag_id = 0; in ipfw_chk()
3104 mtag->m_tag_id == 0)) { in ipfw_chk()
3105 l = 0; /* exit inner loop */ in ipfw_chk()
3111 mtag = m_tag_alloc(MTAG_IPFW_CALL, 0, in ipfw_chk()
3117 stack[0] = chain->id; in ipfw_chk()
3125 f->rulenum); in ipfw_chk()
3126 l = 0; /* exit inner loop */ in ipfw_chk()
3132 if (IS_CALL && mtag->m_tag_id >= in ipfw_chk()
3133 IPFW_CALLSTACK_SIZE - 1) { in ipfw_chk()
3136 f->rulenum); in ipfw_chk()
3137 l = 0; /* exit inner loop */ in ipfw_chk()
3147 stack[++mtag->m_tag_id] = f_pos; in ipfw_chk()
3149 insntod(cmd, u32)->d[0], in ipfw_chk()
3152 jmpto = stack[mtag->m_tag_id--]; in ipfw_chk()
3153 if (cmd->arg1 == RETURN_NEXT_RULE) in ipfw_chk()
3157 chain->map[ in ipfw_chk()
3158 jmpto]->rulenum + 1, 0); in ipfw_chk()
3162 * Skip disabled rules, and re-enter in ipfw_chk()
3167 MPASS(f_pos < chain->n_rules - 1); in ipfw_chk()
3168 for (; f_pos < chain->n_rules - 1 && in ipfw_chk()
3170 (1 << chain->map[f_pos]->set)); f_pos++) in ipfw_chk()
3173 * Re-enter the inner loop at the dest in ipfw_chk()
3176 f = chain->map[f_pos]; in ipfw_chk()
3177 l = f->cmd_len; in ipfw_chk()
3178 cmd = f->cmd; in ipfw_chk()
3179 cmdlen = 0; in ipfw_chk()
3180 skip_or = 0; in ipfw_chk()
3193 if (hlen > 0 && is_ipv4 && offset == 0 && in ipfw_chk()
3195 is_icmp_query(ICMP(ulp))) && in ipfw_chk()
3196 !(m->m_flags & (M_BCAST|M_MCAST)) && in ipfw_chk()
3199 ("o_reject - need_send_reject was set previously")); in ipfw_chk()
3200 if ((reject_code = cmd->arg1) == ICMP_UNREACH_NEEDFRAG && in ipfw_chk()
3201 cmd->len == F_INSN_SIZE(ipfw_insn_u16)) { in ipfw_chk()
3203 ((ipfw_insn_u16 *)cmd)->ports[0]; in ipfw_chk()
3205 reject_mtu = 0; in ipfw_chk()
3212 if (hlen > 0 && is_ipv6 && in ipfw_chk()
3213 ((offset & IP6F_OFF_MASK) == 0) && in ipfw_chk()
3216 !(m->m_flags & (M_BCAST|M_MCAST)) && in ipfw_chk()
3218 &args->f_id.dst_ip6)) { in ipfw_chk()
3220 ("o_unreach6 - need_send_reject was set previously")); in ipfw_chk()
3221 reject_code = cmd->arg1; in ipfw_chk()
3222 if (cmd->opcode == O_REJECT) { in ipfw_chk()
3232 l = 0; /* exit inner loop */ in ipfw_chk()
3237 if (args->flags & IPFW_ARGS_ETHER) in ipfw_chk()
3243 sa = &(((ipfw_insn_sa *)cmd)->sa); in ipfw_chk()
3244 if (sa->sin_addr.s_addr == INADDR_ANY) { in ipfw_chk()
3257 args->flags |= IPFW_ARGS_NH6; in ipfw_chk()
3258 nh6 = &args->hopstore6; in ipfw_chk()
3259 nh6->sin6_addr = TARG_VAL( in ipfw_chk()
3261 nh6->sin6_port = sa->sin_port; in ipfw_chk()
3262 nh6->sin6_scope_id = TARG_VAL( in ipfw_chk()
3267 args->flags |= IPFW_ARGS_NH4; in ipfw_chk()
3268 args->hopstore.sin_port = in ipfw_chk()
3269 sa->sin_port; in ipfw_chk()
3270 sa = &args->hopstore; in ipfw_chk()
3271 sa->sin_family = AF_INET; in ipfw_chk()
3272 sa->sin_len = sizeof(*sa); in ipfw_chk()
3273 sa->sin_addr.s_addr = htonl( in ipfw_chk()
3278 args->flags |= IPFW_ARGS_NH4PTR; in ipfw_chk()
3279 args->next_hop = sa; in ipfw_chk()
3283 l = 0; /* exit inner loop */ in ipfw_chk()
3289 if (args->flags & IPFW_ARGS_ETHER) in ipfw_chk()
3295 sin6 = &(((ipfw_insn_sa6 *)cmd)->sa); in ipfw_chk()
3296 args->flags |= IPFW_ARGS_NH6PTR; in ipfw_chk()
3297 args->next_hop6 = sin6; in ipfw_chk()
3300 l = 0; /* exit inner loop */ in ipfw_chk()
3308 args->rule.info = TARG(cmd->arg1, netgraph); in ipfw_chk()
3310 args->rule.info |= IPFW_ONEPASS; in ipfw_chk()
3311 retval = (cmd->opcode == O_NETGRAPH) ? in ipfw_chk()
3313 l = 0; /* exit inner loop */ in ipfw_chk()
3321 fib = TARG(cmd->arg1, fib) & 0x7FFF; in ipfw_chk()
3323 fib = 0; in ipfw_chk()
3325 args->f_id.fib = fib; /* XXX */ in ipfw_chk()
3326 l = 0; /* exit inner loop */ in ipfw_chk()
3333 code = TARG(cmd->arg1, dscp) & 0x3F; in ipfw_chk()
3334 l = 0; /* exit inner loop */ in ipfw_chk()
3339 ip->ip_tos = (code << 2) | in ipfw_chk()
3340 (ip->ip_tos & 0x03); in ipfw_chk()
3341 ip->ip_sum = cksum_adjust(ip->ip_sum, in ipfw_chk()
3345 args->f_id.flow_id6 = in ipfw_chk()
3346 ntohl(*(uint32_t *)ip) & ~0x0FC00000; in ipfw_chk()
3347 args->f_id.flow_id6 |= code << 22; in ipfw_chk()
3350 htonl(args->f_id.flow_id6); in ipfw_chk()
3359 l = 0; /* exit inner loop */ in ipfw_chk()
3373 args->rule.info = 0; in ipfw_chk()
3376 if (cmd->arg1 == IP_FW_NAT44_GLOBAL) { in ipfw_chk()
3380 t = ((ipfw_insn_nat *)cmd)->nat; in ipfw_chk()
3382 nat_id = TARG(cmd->arg1, nat); in ipfw_chk()
3383 t = (*lookup_nat_ptr)(&chain->nat, nat_id); in ipfw_chk()
3389 if (cmd->arg1 != IP_FW_TARG) in ipfw_chk()
3390 ((ipfw_insn_nat *)cmd)->nat = t; in ipfw_chk()
3398 l = 0; /* in any case exit inner loop */ in ipfw_chk()
3402 ip_off = ntohs(ip->ip_off); in ipfw_chk()
3405 if ((ip_off & (IP_MF | IP_OFFMASK)) == 0) in ipfw_chk()
3408 args->m = m = ip_reass(m); in ipfw_chk()
3419 hlen = ip->ip_hl << 2; in ipfw_chk()
3420 ip->ip_sum = 0; in ipfw_chk()
3422 ip->ip_sum = in_cksum_hdr(ip); in ipfw_chk()
3424 ip->ip_sum = in_cksum(m, hlen); in ipfw_chk()
3426 args->rule.info = 0; in ipfw_chk()
3434 l = 0; /* exit inner loop */ in ipfw_chk()
3435 args->rule.pkt_mark = ( in ipfw_chk()
3436 (cmd->arg1 == IP_FW_TARG) ? in ipfw_chk()
3438 insntoc(cmd, u32)->d[0]); in ipfw_chk()
3445 l = 0; /* in any case exit inner loop */ in ipfw_chk()
3453 if (retval == 0 && done == 0) { in ipfw_chk()
3468 f->rulenum, cmd->opcode); in ipfw_chk()
3471 * if we get here with l=0, then match is irrelevant. in ipfw_chk()
3474 if (cmd->len & F_NOT) in ipfw_chk()
3478 if (cmd->len & F_OR) in ipfw_chk()
3481 if (!(cmd->len & F_OR)) /* not an OR block, */ in ipfw_chk()
3497 struct ip_fw *rule = chain->map[f_pos]; in ipfw_chk()
3503 (uintptr_t)&args->f_id.src_ip6, in ipfw_chk()
3505 (uintptr_t)&args->f_id.dst_ip6, in ipfw_chk()
3546 error = sysctl_handle_int(oidp, &ntables, 0, req); in sysctl_ipfw_table_num()
3548 if ((error != 0) || (req->newptr == NULL)) in sysctl_ipfw_table_num()
3555 * Switches table namespace between global and per-set.
3565 error = sysctl_handle_int(oidp, &sets, 0, req); in sysctl_ipfw_tables_sets()
3567 if ((error != 0) || (req->newptr == NULL)) in sysctl_ipfw_tables_sets()
3613 if (V_fw_verbose == 0) in ipfw_init()
3615 else if (V_verbose_limit == 0) in ipfw_init()
3621 /* Check user-supplied table count for validness */ in ipfw_init()
3656 first = IS_DEFAULT_VNET(curvnet) ? 1 : 0; in vnet_ipfw_init()
3668 LIST_INIT(&chain->nat); in vnet_ipfw_init()
3680 free(chain->map, M_IPFW); in vnet_ipfw_init()
3690 rule->flags |= IPFW_RULE_NOOPT; in vnet_ipfw_init()
3691 rule->cmd_len = 1; in vnet_ipfw_init()
3692 rule->cmd[0].len = 1; in vnet_ipfw_init()
3693 rule->cmd[0].opcode = default_to_accept ? O_ACCEPT : O_DENY; in vnet_ipfw_init()
3694 chain->default_rule = rule; in vnet_ipfw_init()
3695 ipfw_add_protected_rule(chain, rule, 0); in vnet_ipfw_init()
3708 * ipfw[6]_hook return 0 on success, ENOENT on failure, in vnet_ipfw_init()
3712 * changes in the underlying (per-vnet) variables trigger in vnet_ipfw_init()
3732 V_ipfw_vnet_ready = 0; /* tell new callers to go away */ in vnet_ipfw_uninit()
3741 last = IS_DEFAULT_VNET(curvnet) ? 1 : 0; in vnet_ipfw_uninit()
3746 ipfw_dyn_uninit(0); /* run the callout_drain */ in vnet_ipfw_uninit()
3752 for (i = 0; i < chain->n_rules; i++) in vnet_ipfw_uninit()
3753 ipfw_reap_add(chain, &reap, chain->map[i]); in vnet_ipfw_uninit()
3754 free(chain->map, M_IPFW); in vnet_ipfw_uninit()
3768 return (0); in vnet_ipfw_uninit()
3783 int err = 0; in ipfw_modevent()
3809 0
3814 #define IPFW_MODEVENT_ORDER (SI_ORDER_ANY - 255) /* On boot slot in here. */