1631#else 1632 if (pfsync_state_in_use(cur)) 1633#endif 1634 return; 1635#endif 1636#ifdef __FreeBSD__ 1637 KASSERT(cur->timeout == PFTM_UNLINKED, 1638 ("pf_free_state: cur->timeout != PFTM_UNLINKED")); 1639#else 1640 KASSERT(cur->timeout == PFTM_UNLINKED); 1641#endif 1642 if (--cur->rule.ptr->states_cur <= 0 && 1643 cur->rule.ptr->src_nodes <= 0) 1644 pf_rm_rule(NULL, cur->rule.ptr); 1645 if (cur->nat_rule.ptr != NULL) 1646 if (--cur->nat_rule.ptr->states_cur <= 0 && 1647 cur->nat_rule.ptr->src_nodes <= 0) 1648 pf_rm_rule(NULL, cur->nat_rule.ptr); 1649 if (cur->anchor.ptr != NULL) 1650 if (--cur->anchor.ptr->states_cur <= 0) 1651 pf_rm_rule(NULL, cur->anchor.ptr); 1652 pf_normalize_tcp_cleanup(cur); 1653 pfi_kif_unref(cur->kif, PFI_KIF_REF_STATE); 1654#ifdef __FreeBSD__ 1655 TAILQ_REMOVE(&V_state_list, cur, entry_list); 1656#else 1657 TAILQ_REMOVE(&state_list, cur, entry_list); 1658#endif 1659 if (cur->tag) 1660 pf_tag_unref(cur->tag); 1661#ifdef __FreeBSD__ 1662 pool_put(&V_pf_state_pl, cur); 1663 V_pf_status.fcounters[FCNT_STATE_REMOVALS]++; 1664 V_pf_status.states--; 1665#else 1666 pool_put(&pf_state_pl, cur); 1667 pf_status.fcounters[FCNT_STATE_REMOVALS]++; 1668 pf_status.states--; 1669#endif 1670} 1671 1672#ifdef __FreeBSD__ 1673int 1674pf_purge_expired_states(u_int32_t maxcheck, int waslocked) 1675#else 1676void 1677pf_purge_expired_states(u_int32_t maxcheck) 1678#endif 1679{ 1680 static struct pf_state *cur = NULL; 1681 struct pf_state *next; 1682#ifdef __FreeBSD__ 1683 int locked = waslocked; 1684#else 1685 int locked = 0; 1686#endif 1687 1688 while (maxcheck--) { 1689 /* wrap to start of list when we hit the end */ 1690 if (cur == NULL) { 1691#ifdef __FreeBSD__ 1692 cur = TAILQ_FIRST(&V_state_list); 1693#else 1694 cur = TAILQ_FIRST(&state_list); 1695#endif 1696 if (cur == NULL) 1697 break; /* list empty */ 1698 } 1699 1700 /* get next state, as cur may get deleted */ 1701 next = TAILQ_NEXT(cur, entry_list); 1702 1703 if (cur->timeout == PFTM_UNLINKED) { 1704 /* free unlinked state */ 1705 if (! locked) { 1706#ifdef __FreeBSD__ 1707 if (!sx_try_upgrade(&V_pf_consistency_lock)) 1708 return (0); 1709#else 1710 rw_enter_write(&pf_consistency_lock); 1711#endif 1712 locked = 1; 1713 } 1714 pf_free_state(cur); 1715 } else if (pf_state_expires(cur) <= time_second) { 1716 /* unlink and free expired state */ 1717 pf_unlink_state(cur); 1718 if (! locked) { 1719#ifdef __FreeBSD__ 1720 if (!sx_try_upgrade(&V_pf_consistency_lock)) 1721 return (0); 1722#else 1723 rw_enter_write(&pf_consistency_lock); 1724#endif 1725 locked = 1; 1726 } 1727 pf_free_state(cur); 1728 } 1729 cur = next; 1730 } 1731 1732#ifdef __FreeBSD__ 1733 if (!waslocked && locked) 1734 sx_downgrade(&V_pf_consistency_lock); 1735 1736 return (1); 1737#else 1738 if (locked) 1739 rw_exit_write(&pf_consistency_lock); 1740#endif 1741} 1742 1743int 1744pf_tbladdr_setup(struct pf_ruleset *rs, struct pf_addr_wrap *aw) 1745{ 1746 if (aw->type != PF_ADDR_TABLE) 1747 return (0); 1748 if ((aw->p.tbl = pfr_attach_table(rs, aw->v.tblname, 1)) == NULL) 1749 return (1); 1750 return (0); 1751} 1752 1753void 1754pf_tbladdr_remove(struct pf_addr_wrap *aw) 1755{ 1756 if (aw->type != PF_ADDR_TABLE || aw->p.tbl == NULL) 1757 return; 1758 pfr_detach_table(aw->p.tbl); 1759 aw->p.tbl = NULL; 1760} 1761 1762void 1763pf_tbladdr_copyout(struct pf_addr_wrap *aw) 1764{ 1765 struct pfr_ktable *kt = aw->p.tbl; 1766 1767 if (aw->type != PF_ADDR_TABLE || kt == NULL) 1768 return; 1769 if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL) 1770 kt = kt->pfrkt_root; 1771 aw->p.tbl = NULL; 1772 aw->p.tblcnt = (kt->pfrkt_flags & PFR_TFLAG_ACTIVE) ? 1773 kt->pfrkt_cnt : -1; 1774} 1775 1776void 1777pf_print_host(struct pf_addr *addr, u_int16_t p, sa_family_t af) 1778{ 1779 switch (af) { 1780#ifdef INET 1781 case AF_INET: { 1782 u_int32_t a = ntohl(addr->addr32[0]); 1783 printf("%u.%u.%u.%u", (a>>24)&255, (a>>16)&255, 1784 (a>>8)&255, a&255); 1785 if (p) { 1786 p = ntohs(p); 1787 printf(":%u", p); 1788 } 1789 break; 1790 } 1791#endif /* INET */ 1792#ifdef INET6 1793 case AF_INET6: { 1794 u_int16_t b; 1795 u_int8_t i, curstart, curend, maxstart, maxend; 1796 curstart = curend = maxstart = maxend = 255; 1797 for (i = 0; i < 8; i++) { 1798 if (!addr->addr16[i]) { 1799 if (curstart == 255) 1800 curstart = i; 1801 curend = i; 1802 } else { 1803 if ((curend - curstart) > 1804 (maxend - maxstart)) { 1805 maxstart = curstart; 1806 maxend = curend; 1807 } 1808 curstart = curend = 255; 1809 } 1810 } 1811 if ((curend - curstart) > 1812 (maxend - maxstart)) { 1813 maxstart = curstart; 1814 maxend = curend; 1815 } 1816 for (i = 0; i < 8; i++) { 1817 if (i >= maxstart && i <= maxend) { 1818 if (i == 0) 1819 printf(":"); 1820 if (i == maxend) 1821 printf(":"); 1822 } else { 1823 b = ntohs(addr->addr16[i]); 1824 printf("%x", b); 1825 if (i < 7) 1826 printf(":"); 1827 } 1828 } 1829 if (p) { 1830 p = ntohs(p); 1831 printf("[%u]", p); 1832 } 1833 break; 1834 } 1835#endif /* INET6 */ 1836 } 1837} 1838 1839void 1840pf_print_state(struct pf_state *s) 1841{ 1842 pf_print_state_parts(s, NULL, NULL); 1843} 1844 1845void 1846pf_print_state_parts(struct pf_state *s, 1847 struct pf_state_key *skwp, struct pf_state_key *sksp) 1848{ 1849 struct pf_state_key *skw, *sks; 1850 u_int8_t proto, dir; 1851 1852 /* Do our best to fill these, but they're skipped if NULL */ 1853 skw = skwp ? skwp : (s ? s->key[PF_SK_WIRE] : NULL); 1854 sks = sksp ? sksp : (s ? s->key[PF_SK_STACK] : NULL); 1855 proto = skw ? skw->proto : (sks ? sks->proto : 0); 1856 dir = s ? s->direction : 0; 1857 1858 switch (proto) { 1859 case IPPROTO_IPV4: 1860 printf("IPv4"); 1861 break; 1862 case IPPROTO_IPV6: 1863 printf("IPv6"); 1864 break; 1865 case IPPROTO_TCP: 1866 printf("TCP"); 1867 break; 1868 case IPPROTO_UDP: 1869 printf("UDP"); 1870 break; 1871 case IPPROTO_ICMP: 1872 printf("ICMP"); 1873 break; 1874 case IPPROTO_ICMPV6: 1875 printf("ICMPv6"); 1876 break; 1877 default: 1878 printf("%u", skw->proto); 1879 break; 1880 } 1881 switch (dir) { 1882 case PF_IN: 1883 printf(" in"); 1884 break; 1885 case PF_OUT: 1886 printf(" out"); 1887 break; 1888 } 1889 if (skw) { 1890 printf(" wire: "); 1891 pf_print_host(&skw->addr[0], skw->port[0], skw->af); 1892 printf(" "); 1893 pf_print_host(&skw->addr[1], skw->port[1], skw->af); 1894 } 1895 if (sks) { 1896 printf(" stack: "); 1897 if (sks != skw) { 1898 pf_print_host(&sks->addr[0], sks->port[0], sks->af); 1899 printf(" "); 1900 pf_print_host(&sks->addr[1], sks->port[1], sks->af); 1901 } else 1902 printf("-"); 1903 } 1904 if (s) { 1905 if (proto == IPPROTO_TCP) { 1906 printf(" [lo=%u high=%u win=%u modulator=%u", 1907 s->src.seqlo, s->src.seqhi, 1908 s->src.max_win, s->src.seqdiff); 1909 if (s->src.wscale && s->dst.wscale) 1910 printf(" wscale=%u", 1911 s->src.wscale & PF_WSCALE_MASK); 1912 printf("]"); 1913 printf(" [lo=%u high=%u win=%u modulator=%u", 1914 s->dst.seqlo, s->dst.seqhi, 1915 s->dst.max_win, s->dst.seqdiff); 1916 if (s->src.wscale && s->dst.wscale) 1917 printf(" wscale=%u", 1918 s->dst.wscale & PF_WSCALE_MASK); 1919 printf("]"); 1920 } 1921 printf(" %u:%u", s->src.state, s->dst.state); 1922 } 1923} 1924 1925void 1926pf_print_flags(u_int8_t f) 1927{ 1928 if (f) 1929 printf(" "); 1930 if (f & TH_FIN) 1931 printf("F"); 1932 if (f & TH_SYN) 1933 printf("S"); 1934 if (f & TH_RST) 1935 printf("R"); 1936 if (f & TH_PUSH) 1937 printf("P"); 1938 if (f & TH_ACK) 1939 printf("A"); 1940 if (f & TH_URG) 1941 printf("U"); 1942 if (f & TH_ECE) 1943 printf("E"); 1944 if (f & TH_CWR) 1945 printf("W"); 1946} 1947 1948#define PF_SET_SKIP_STEPS(i) \ 1949 do { \ 1950 while (head[i] != cur) { \ 1951 head[i]->skip[i].ptr = cur; \ 1952 head[i] = TAILQ_NEXT(head[i], entries); \ 1953 } \ 1954 } while (0) 1955 1956void 1957pf_calc_skip_steps(struct pf_rulequeue *rules) 1958{ 1959 struct pf_rule *cur, *prev, *head[PF_SKIP_COUNT]; 1960 int i; 1961 1962 cur = TAILQ_FIRST(rules); 1963 prev = cur; 1964 for (i = 0; i < PF_SKIP_COUNT; ++i) 1965 head[i] = cur; 1966 while (cur != NULL) { 1967 1968 if (cur->kif != prev->kif || cur->ifnot != prev->ifnot) 1969 PF_SET_SKIP_STEPS(PF_SKIP_IFP); 1970 if (cur->direction != prev->direction) 1971 PF_SET_SKIP_STEPS(PF_SKIP_DIR); 1972 if (cur->af != prev->af) 1973 PF_SET_SKIP_STEPS(PF_SKIP_AF); 1974 if (cur->proto != prev->proto) 1975 PF_SET_SKIP_STEPS(PF_SKIP_PROTO); 1976 if (cur->src.neg != prev->src.neg || 1977 pf_addr_wrap_neq(&cur->src.addr, &prev->src.addr)) 1978 PF_SET_SKIP_STEPS(PF_SKIP_SRC_ADDR); 1979 if (cur->src.port[0] != prev->src.port[0] || 1980 cur->src.port[1] != prev->src.port[1] || 1981 cur->src.port_op != prev->src.port_op) 1982 PF_SET_SKIP_STEPS(PF_SKIP_SRC_PORT); 1983 if (cur->dst.neg != prev->dst.neg || 1984 pf_addr_wrap_neq(&cur->dst.addr, &prev->dst.addr)) 1985 PF_SET_SKIP_STEPS(PF_SKIP_DST_ADDR); 1986 if (cur->dst.port[0] != prev->dst.port[0] || 1987 cur->dst.port[1] != prev->dst.port[1] || 1988 cur->dst.port_op != prev->dst.port_op) 1989 PF_SET_SKIP_STEPS(PF_SKIP_DST_PORT); 1990 1991 prev = cur; 1992 cur = TAILQ_NEXT(cur, entries); 1993 } 1994 for (i = 0; i < PF_SKIP_COUNT; ++i) 1995 PF_SET_SKIP_STEPS(i); 1996} 1997 1998int 1999pf_addr_wrap_neq(struct pf_addr_wrap *aw1, struct pf_addr_wrap *aw2) 2000{ 2001 if (aw1->type != aw2->type) 2002 return (1); 2003 switch (aw1->type) { 2004 case PF_ADDR_ADDRMASK: 2005 case PF_ADDR_RANGE: 2006 if (PF_ANEQ(&aw1->v.a.addr, &aw2->v.a.addr, 0)) 2007 return (1); 2008 if (PF_ANEQ(&aw1->v.a.mask, &aw2->v.a.mask, 0)) 2009 return (1); 2010 return (0); 2011 case PF_ADDR_DYNIFTL: 2012 return (aw1->p.dyn->pfid_kt != aw2->p.dyn->pfid_kt); 2013 case PF_ADDR_NOROUTE: 2014 case PF_ADDR_URPFFAILED: 2015 return (0); 2016 case PF_ADDR_TABLE: 2017 return (aw1->p.tbl != aw2->p.tbl); 2018 case PF_ADDR_RTLABEL: 2019 return (aw1->v.rtlabel != aw2->v.rtlabel); 2020 default: 2021 printf("invalid address type: %d\n", aw1->type); 2022 return (1); 2023 } 2024} 2025 2026u_int16_t 2027pf_cksum_fixup(u_int16_t cksum, u_int16_t old, u_int16_t new, u_int8_t udp) 2028{ 2029 u_int32_t l; 2030 2031 if (udp && !cksum) 2032 return (0x0000); 2033 l = cksum + old - new; 2034 l = (l >> 16) + (l & 65535); 2035 l = l & 65535; 2036 if (udp && !l) 2037 return (0xFFFF); 2038 return (l); 2039} 2040 2041void 2042pf_change_ap(struct pf_addr *a, u_int16_t *p, u_int16_t *ic, u_int16_t *pc, 2043 struct pf_addr *an, u_int16_t pn, u_int8_t u, sa_family_t af) 2044{ 2045 struct pf_addr ao; 2046 u_int16_t po = *p; 2047 2048 PF_ACPY(&ao, a, af); 2049 PF_ACPY(a, an, af); 2050 2051 *p = pn; 2052 2053 switch (af) { 2054#ifdef INET 2055 case AF_INET: 2056 *ic = pf_cksum_fixup(pf_cksum_fixup(*ic, 2057 ao.addr16[0], an->addr16[0], 0), 2058 ao.addr16[1], an->addr16[1], 0); 2059 *p = pn; 2060 *pc = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(*pc, 2061 ao.addr16[0], an->addr16[0], u), 2062 ao.addr16[1], an->addr16[1], u), 2063 po, pn, u); 2064 break; 2065#endif /* INET */ 2066#ifdef INET6 2067 case AF_INET6: 2068 *pc = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup( 2069 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup( 2070 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(*pc, 2071 ao.addr16[0], an->addr16[0], u), 2072 ao.addr16[1], an->addr16[1], u), 2073 ao.addr16[2], an->addr16[2], u), 2074 ao.addr16[3], an->addr16[3], u), 2075 ao.addr16[4], an->addr16[4], u), 2076 ao.addr16[5], an->addr16[5], u), 2077 ao.addr16[6], an->addr16[6], u), 2078 ao.addr16[7], an->addr16[7], u), 2079 po, pn, u); 2080 break; 2081#endif /* INET6 */ 2082 } 2083} 2084 2085 2086/* Changes a u_int32_t. Uses a void * so there are no align restrictions */ 2087void 2088pf_change_a(void *a, u_int16_t *c, u_int32_t an, u_int8_t u) 2089{ 2090 u_int32_t ao; 2091 2092 memcpy(&ao, a, sizeof(ao)); 2093 memcpy(a, &an, sizeof(u_int32_t)); 2094 *c = pf_cksum_fixup(pf_cksum_fixup(*c, ao / 65536, an / 65536, u), 2095 ao % 65536, an % 65536, u); 2096} 2097 2098#ifdef INET6 2099void 2100pf_change_a6(struct pf_addr *a, u_int16_t *c, struct pf_addr *an, u_int8_t u) 2101{ 2102 struct pf_addr ao; 2103 2104 PF_ACPY(&ao, a, AF_INET6); 2105 PF_ACPY(a, an, AF_INET6); 2106 2107 *c = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup( 2108 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup( 2109 pf_cksum_fixup(pf_cksum_fixup(*c, 2110 ao.addr16[0], an->addr16[0], u), 2111 ao.addr16[1], an->addr16[1], u), 2112 ao.addr16[2], an->addr16[2], u), 2113 ao.addr16[3], an->addr16[3], u), 2114 ao.addr16[4], an->addr16[4], u), 2115 ao.addr16[5], an->addr16[5], u), 2116 ao.addr16[6], an->addr16[6], u), 2117 ao.addr16[7], an->addr16[7], u); 2118} 2119#endif /* INET6 */ 2120 2121void 2122pf_change_icmp(struct pf_addr *ia, u_int16_t *ip, struct pf_addr *oa, 2123 struct pf_addr *na, u_int16_t np, u_int16_t *pc, u_int16_t *h2c, 2124 u_int16_t *ic, u_int16_t *hc, u_int8_t u, sa_family_t af) 2125{ 2126 struct pf_addr oia, ooa; 2127 2128 PF_ACPY(&oia, ia, af); 2129 if (oa) 2130 PF_ACPY(&ooa, oa, af); 2131 2132 /* Change inner protocol port, fix inner protocol checksum. */ 2133 if (ip != NULL) { 2134 u_int16_t oip = *ip; 2135 u_int32_t opc; 2136 2137 if (pc != NULL) 2138 opc = *pc; 2139 *ip = np; 2140 if (pc != NULL) 2141 *pc = pf_cksum_fixup(*pc, oip, *ip, u); 2142 *ic = pf_cksum_fixup(*ic, oip, *ip, 0); 2143 if (pc != NULL) 2144 *ic = pf_cksum_fixup(*ic, opc, *pc, 0); 2145 } 2146 /* Change inner ip address, fix inner ip and icmp checksums. */ 2147 PF_ACPY(ia, na, af); 2148 switch (af) { 2149#ifdef INET 2150 case AF_INET: { 2151 u_int32_t oh2c = *h2c; 2152 2153 *h2c = pf_cksum_fixup(pf_cksum_fixup(*h2c, 2154 oia.addr16[0], ia->addr16[0], 0), 2155 oia.addr16[1], ia->addr16[1], 0); 2156 *ic = pf_cksum_fixup(pf_cksum_fixup(*ic, 2157 oia.addr16[0], ia->addr16[0], 0), 2158 oia.addr16[1], ia->addr16[1], 0); 2159 *ic = pf_cksum_fixup(*ic, oh2c, *h2c, 0); 2160 break; 2161 } 2162#endif /* INET */ 2163#ifdef INET6 2164 case AF_INET6: 2165 *ic = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup( 2166 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup( 2167 pf_cksum_fixup(pf_cksum_fixup(*ic, 2168 oia.addr16[0], ia->addr16[0], u), 2169 oia.addr16[1], ia->addr16[1], u), 2170 oia.addr16[2], ia->addr16[2], u), 2171 oia.addr16[3], ia->addr16[3], u), 2172 oia.addr16[4], ia->addr16[4], u), 2173 oia.addr16[5], ia->addr16[5], u), 2174 oia.addr16[6], ia->addr16[6], u), 2175 oia.addr16[7], ia->addr16[7], u); 2176 break; 2177#endif /* INET6 */ 2178 } 2179 /* Outer ip address, fix outer ip or icmpv6 checksum, if necessary. */ 2180 if (oa) { 2181 PF_ACPY(oa, na, af); 2182 switch (af) { 2183#ifdef INET 2184 case AF_INET: 2185 *hc = pf_cksum_fixup(pf_cksum_fixup(*hc, 2186 ooa.addr16[0], oa->addr16[0], 0), 2187 ooa.addr16[1], oa->addr16[1], 0); 2188 break; 2189#endif /* INET */ 2190#ifdef INET6 2191 case AF_INET6: 2192 *ic = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup( 2193 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup( 2194 pf_cksum_fixup(pf_cksum_fixup(*ic, 2195 ooa.addr16[0], oa->addr16[0], u), 2196 ooa.addr16[1], oa->addr16[1], u), 2197 ooa.addr16[2], oa->addr16[2], u), 2198 ooa.addr16[3], oa->addr16[3], u), 2199 ooa.addr16[4], oa->addr16[4], u), 2200 ooa.addr16[5], oa->addr16[5], u), 2201 ooa.addr16[6], oa->addr16[6], u), 2202 ooa.addr16[7], oa->addr16[7], u); 2203 break; 2204#endif /* INET6 */ 2205 } 2206 } 2207} 2208 2209 2210/* 2211 * Need to modulate the sequence numbers in the TCP SACK option 2212 * (credits to Krzysztof Pfaff for report and patch) 2213 */ 2214int 2215pf_modulate_sack(struct mbuf *m, int off, struct pf_pdesc *pd, 2216 struct tcphdr *th, struct pf_state_peer *dst) 2217{ 2218 int hlen = (th->th_off << 2) - sizeof(*th), thoptlen = hlen; 2219#ifdef __FreeBSD__ 2220 u_int8_t opts[TCP_MAXOLEN], *opt = opts; 2221#else 2222 u_int8_t opts[MAX_TCPOPTLEN], *opt = opts; 2223#endif 2224 int copyback = 0, i, olen; 2225 struct sackblk sack; 2226 2227#define TCPOLEN_SACKLEN (TCPOLEN_SACK + 2) 2228 if (hlen < TCPOLEN_SACKLEN || 2229 !pf_pull_hdr(m, off + sizeof(*th), opts, hlen, NULL, NULL, pd->af)) 2230 return 0; 2231 2232 while (hlen >= TCPOLEN_SACKLEN) { 2233 olen = opt[1]; 2234 switch (*opt) { 2235 case TCPOPT_EOL: /* FALLTHROUGH */ 2236 case TCPOPT_NOP: 2237 opt++; 2238 hlen--; 2239 break; 2240 case TCPOPT_SACK: 2241 if (olen > hlen) 2242 olen = hlen; 2243 if (olen >= TCPOLEN_SACKLEN) { 2244 for (i = 2; i + TCPOLEN_SACK <= olen; 2245 i += TCPOLEN_SACK) { 2246 memcpy(&sack, &opt[i], sizeof(sack)); 2247 pf_change_a(&sack.start, &th->th_sum, 2248 htonl(ntohl(sack.start) - 2249 dst->seqdiff), 0); 2250 pf_change_a(&sack.end, &th->th_sum, 2251 htonl(ntohl(sack.end) - 2252 dst->seqdiff), 0); 2253 memcpy(&opt[i], &sack, sizeof(sack)); 2254 } 2255 copyback = 1; 2256 } 2257 /* FALLTHROUGH */ 2258 default: 2259 if (olen < 2) 2260 olen = 2; 2261 hlen -= olen; 2262 opt += olen; 2263 } 2264 } 2265 2266 if (copyback) 2267#ifdef __FreeBSD__ 2268 m_copyback(m, off + sizeof(*th), thoptlen, (caddr_t)opts); 2269#else 2270 m_copyback(m, off + sizeof(*th), thoptlen, opts); 2271#endif 2272 return (copyback); 2273} 2274 2275void 2276#ifdef __FreeBSD__ 2277pf_send_tcp(struct mbuf *replyto, const struct pf_rule *r, sa_family_t af, 2278#else 2279pf_send_tcp(const struct pf_rule *r, sa_family_t af, 2280#endif 2281 const struct pf_addr *saddr, const struct pf_addr *daddr, 2282 u_int16_t sport, u_int16_t dport, u_int32_t seq, u_int32_t ack, 2283 u_int8_t flags, u_int16_t win, u_int16_t mss, u_int8_t ttl, int tag, 2284 u_int16_t rtag, struct ether_header *eh, struct ifnet *ifp) 2285{ 2286 struct mbuf *m; 2287 int len, tlen; 2288#ifdef INET 2289 struct ip *h; 2290#endif /* INET */ 2291#ifdef INET6 2292 struct ip6_hdr *h6; 2293#endif /* INET6 */ 2294 struct tcphdr *th; 2295 char *opt; 2296#ifdef __FreeBSD__ 2297 struct pf_mtag *pf_mtag; 2298 2299 KASSERT( 2300#ifdef INET 2301 af == AF_INET 2302#else 2303 0 2304#endif 2305 || 2306#ifdef INET6 2307 af == AF_INET6 2308#else 2309 0 2310#endif 2311 , ("Unsupported AF %d", af)); 2312 len = 0; 2313 th = NULL; 2314#ifdef INET 2315 h = NULL; 2316#endif 2317#ifdef INET6 2318 h6 = NULL; 2319#endif 2320#endif /* __FreeBSD__ */ 2321 2322 /* maximum segment size tcp option */ 2323 tlen = sizeof(struct tcphdr); 2324 if (mss) 2325 tlen += 4; 2326 2327 switch (af) { 2328#ifdef INET 2329 case AF_INET: 2330 len = sizeof(struct ip) + tlen; 2331 break; 2332#endif /* INET */ 2333#ifdef INET6 2334 case AF_INET6: 2335 len = sizeof(struct ip6_hdr) + tlen; 2336 break; 2337#endif /* INET6 */ 2338 } 2339 2340 /* create outgoing mbuf */ 2341 m = m_gethdr(M_DONTWAIT, MT_HEADER); 2342 if (m == NULL) 2343 return; 2344#ifdef __FreeBSD__ 2345#ifdef MAC 2346 mac_netinet_firewall_send(m); 2347#endif 2348 if ((pf_mtag = pf_get_mtag(m)) == NULL) { 2349 m_freem(m); 2350 return; 2351 } 2352#endif 2353 if (tag) 2354#ifdef __FreeBSD__ 2355 m->m_flags |= M_SKIP_FIREWALL; 2356 pf_mtag->tag = rtag; 2357#else 2358 m->m_pkthdr.pf.flags |= PF_TAG_GENERATED; 2359 m->m_pkthdr.pf.tag = rtag; 2360#endif 2361 2362 if (r != NULL && r->rtableid >= 0) 2363#ifdef __FreeBSD__ 2364 { 2365 M_SETFIB(m, r->rtableid); 2366 pf_mtag->rtableid = r->rtableid; 2367#else 2368 m->m_pkthdr.pf.rtableid = r->rtableid; 2369#endif 2370#ifdef __FreeBSD__ 2371 } 2372#endif 2373 2374#ifdef ALTQ 2375 if (r != NULL && r->qid) { 2376#ifdef __FreeBSD__ 2377 pf_mtag->qid = r->qid; 2378 2379 /* add hints for ecn */ 2380 pf_mtag->hdr = mtod(m, struct ip *); 2381#else 2382 m->m_pkthdr.pf.qid = r->qid; 2383 /* add hints for ecn */ 2384 m->m_pkthdr.pf.hdr = mtod(m, struct ip *); 2385#endif 2386 } 2387#endif /* ALTQ */ 2388 m->m_data += max_linkhdr; 2389 m->m_pkthdr.len = m->m_len = len; 2390 m->m_pkthdr.rcvif = NULL; 2391 bzero(m->m_data, len); 2392 switch (af) { 2393#ifdef INET 2394 case AF_INET: 2395 h = mtod(m, struct ip *); 2396 2397 /* IP header fields included in the TCP checksum */ 2398 h->ip_p = IPPROTO_TCP; 2399 h->ip_len = htons(tlen); 2400 h->ip_src.s_addr = saddr->v4.s_addr; 2401 h->ip_dst.s_addr = daddr->v4.s_addr; 2402 2403 th = (struct tcphdr *)((caddr_t)h + sizeof(struct ip)); 2404 break; 2405#endif /* INET */ 2406#ifdef INET6 2407 case AF_INET6: 2408 h6 = mtod(m, struct ip6_hdr *); 2409 2410 /* IP header fields included in the TCP checksum */ 2411 h6->ip6_nxt = IPPROTO_TCP; 2412 h6->ip6_plen = htons(tlen); 2413 memcpy(&h6->ip6_src, &saddr->v6, sizeof(struct in6_addr)); 2414 memcpy(&h6->ip6_dst, &daddr->v6, sizeof(struct in6_addr)); 2415 2416 th = (struct tcphdr *)((caddr_t)h6 + sizeof(struct ip6_hdr)); 2417 break; 2418#endif /* INET6 */ 2419 } 2420 2421 /* TCP header */ 2422 th->th_sport = sport; 2423 th->th_dport = dport; 2424 th->th_seq = htonl(seq); 2425 th->th_ack = htonl(ack); 2426 th->th_off = tlen >> 2; 2427 th->th_flags = flags; 2428 th->th_win = htons(win); 2429 2430 if (mss) { 2431 opt = (char *)(th + 1); 2432 opt[0] = TCPOPT_MAXSEG; 2433 opt[1] = 4; 2434 HTONS(mss); 2435 bcopy((caddr_t)&mss, (caddr_t)(opt + 2), 2); 2436 } 2437 2438 switch (af) { 2439#ifdef INET 2440 case AF_INET: 2441 /* TCP checksum */ 2442 th->th_sum = in_cksum(m, len); 2443 2444 /* Finish the IP header */ 2445 h->ip_v = 4; 2446 h->ip_hl = sizeof(*h) >> 2; 2447 h->ip_tos = IPTOS_LOWDELAY; 2448#ifdef __FreeBSD__ 2449 h->ip_off = V_path_mtu_discovery ? IP_DF : 0; 2450 h->ip_len = len; 2451 h->ip_ttl = ttl ? ttl : V_ip_defttl; 2452#else 2453 h->ip_len = htons(len); 2454 h->ip_off = htons(ip_mtudisc ? IP_DF : 0); 2455 h->ip_ttl = ttl ? ttl : ip_defttl; 2456#endif 2457 h->ip_sum = 0; 2458 if (eh == NULL) { 2459#ifdef __FreeBSD__ 2460 PF_UNLOCK(); 2461 ip_output(m, (void *)NULL, (void *)NULL, 0, 2462 (void *)NULL, (void *)NULL); 2463 PF_LOCK(); 2464#else /* ! __FreeBSD__ */ 2465 ip_output(m, (void *)NULL, (void *)NULL, 0, 2466 (void *)NULL, (void *)NULL); 2467#endif 2468 } else { 2469 struct route ro; 2470 struct rtentry rt; 2471 struct ether_header *e = (void *)ro.ro_dst.sa_data; 2472 2473 if (ifp == NULL) { 2474 m_freem(m); 2475 return; 2476 } 2477 rt.rt_ifp = ifp; 2478 ro.ro_rt = &rt; 2479 ro.ro_dst.sa_len = sizeof(ro.ro_dst); 2480 ro.ro_dst.sa_family = pseudo_AF_HDRCMPLT; 2481 bcopy(eh->ether_dhost, e->ether_shost, ETHER_ADDR_LEN); 2482 bcopy(eh->ether_shost, e->ether_dhost, ETHER_ADDR_LEN); 2483 e->ether_type = eh->ether_type; 2484#ifdef __FreeBSD__ 2485 PF_UNLOCK(); 2486 /* XXX_IMPORT: later */ 2487 ip_output(m, (void *)NULL, &ro, 0, 2488 (void *)NULL, (void *)NULL); 2489 PF_LOCK(); 2490#else /* ! __FreeBSD__ */ 2491 ip_output(m, (void *)NULL, &ro, IP_ROUTETOETHER, 2492 (void *)NULL, (void *)NULL); 2493#endif 2494 } 2495 break; 2496#endif /* INET */ 2497#ifdef INET6 2498 case AF_INET6: 2499 /* TCP checksum */ 2500 th->th_sum = in6_cksum(m, IPPROTO_TCP, 2501 sizeof(struct ip6_hdr), tlen); 2502 2503 h6->ip6_vfc |= IPV6_VERSION; 2504 h6->ip6_hlim = IPV6_DEFHLIM; 2505 2506#ifdef __FreeBSD__ 2507 PF_UNLOCK(); 2508 ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL); 2509 PF_LOCK(); 2510#else 2511 ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL); 2512#endif 2513 break; 2514#endif /* INET6 */ 2515 } 2516} 2517 2518static void 2519pf_send_icmp(struct mbuf *m, u_int8_t type, u_int8_t code, sa_family_t af, 2520 struct pf_rule *r) 2521{ 2522 struct mbuf *m0; 2523#ifdef __FreeBSD__ 2524#ifdef INET 2525 struct ip *ip; 2526#endif 2527 struct pf_mtag *pf_mtag; 2528#endif 2529 2530#ifdef __FreeBSD__ 2531 m0 = m_copypacket(m, M_DONTWAIT); 2532 if (m0 == NULL) 2533 return; 2534#else 2535 if ((m0 = m_copy(m, 0, M_COPYALL)) == NULL) 2536 return; 2537#endif 2538 2539#ifdef __FreeBSD__ 2540 if ((pf_mtag = pf_get_mtag(m0)) == NULL) 2541 return; 2542 /* XXX: revisit */ 2543 m0->m_flags |= M_SKIP_FIREWALL; 2544#else 2545 m0->m_pkthdr.pf.flags |= PF_TAG_GENERATED; 2546#endif 2547 2548 if (r->rtableid >= 0) 2549#ifdef __FreeBSD__ 2550 { 2551 M_SETFIB(m0, r->rtableid); 2552 pf_mtag->rtableid = r->rtableid; 2553#else 2554 m0->m_pkthdr.pf.rtableid = r->rtableid; 2555#endif 2556#ifdef __FreeBSD__ 2557 } 2558#endif 2559 2560#ifdef ALTQ 2561 if (r->qid) { 2562#ifdef __FreeBSD__ 2563 pf_mtag->qid = r->qid; 2564 /* add hints for ecn */ 2565 pf_mtag->hdr = mtod(m0, struct ip *); 2566#else 2567 m0->m_pkthdr.pf.qid = r->qid; 2568 /* add hints for ecn */ 2569 m0->m_pkthdr.pf.hdr = mtod(m0, struct ip *); 2570#endif 2571 } 2572#endif /* ALTQ */ 2573 2574 switch (af) { 2575#ifdef INET 2576 case AF_INET: 2577#ifdef __FreeBSD__ 2578 /* icmp_error() expects host byte ordering */ 2579 ip = mtod(m0, struct ip *); 2580 NTOHS(ip->ip_len); 2581 NTOHS(ip->ip_off); 2582 PF_UNLOCK(); 2583 icmp_error(m0, type, code, 0, 0); 2584 PF_LOCK(); 2585#else 2586 icmp_error(m0, type, code, 0, 0); 2587#endif 2588 break; 2589#endif /* INET */ 2590#ifdef INET6 2591 case AF_INET6: 2592#ifdef __FreeBSD__ 2593 PF_UNLOCK(); 2594#endif 2595 icmp6_error(m0, type, code, 0); 2596#ifdef __FreeBSD__ 2597 PF_LOCK(); 2598#endif 2599 break; 2600#endif /* INET6 */ 2601 } 2602} 2603 2604/* 2605 * Return 1 if the addresses a and b match (with mask m), otherwise return 0. 2606 * If n is 0, they match if they are equal. If n is != 0, they match if they 2607 * are different. 2608 */ 2609int 2610pf_match_addr(u_int8_t n, struct pf_addr *a, struct pf_addr *m, 2611 struct pf_addr *b, sa_family_t af) 2612{ 2613 int match = 0; 2614 2615 switch (af) { 2616#ifdef INET 2617 case AF_INET: 2618 if ((a->addr32[0] & m->addr32[0]) == 2619 (b->addr32[0] & m->addr32[0])) 2620 match++; 2621 break; 2622#endif /* INET */ 2623#ifdef INET6 2624 case AF_INET6: 2625 if (((a->addr32[0] & m->addr32[0]) == 2626 (b->addr32[0] & m->addr32[0])) && 2627 ((a->addr32[1] & m->addr32[1]) == 2628 (b->addr32[1] & m->addr32[1])) && 2629 ((a->addr32[2] & m->addr32[2]) == 2630 (b->addr32[2] & m->addr32[2])) && 2631 ((a->addr32[3] & m->addr32[3]) == 2632 (b->addr32[3] & m->addr32[3]))) 2633 match++; 2634 break; 2635#endif /* INET6 */ 2636 } 2637 if (match) { 2638 if (n) 2639 return (0); 2640 else 2641 return (1); 2642 } else { 2643 if (n) 2644 return (1); 2645 else 2646 return (0); 2647 } 2648} 2649 2650/* 2651 * Return 1 if b <= a <= e, otherwise return 0. 2652 */ 2653int 2654pf_match_addr_range(struct pf_addr *b, struct pf_addr *e, 2655 struct pf_addr *a, sa_family_t af) 2656{ 2657 switch (af) { 2658#ifdef INET 2659 case AF_INET: 2660 if ((a->addr32[0] < b->addr32[0]) || 2661 (a->addr32[0] > e->addr32[0])) 2662 return (0); 2663 break; 2664#endif /* INET */ 2665#ifdef INET6 2666 case AF_INET6: { 2667 int i; 2668 2669 /* check a >= b */ 2670 for (i = 0; i < 4; ++i) 2671 if (a->addr32[i] > b->addr32[i]) 2672 break; 2673 else if (a->addr32[i] < b->addr32[i]) 2674 return (0); 2675 /* check a <= e */ 2676 for (i = 0; i < 4; ++i) 2677 if (a->addr32[i] < e->addr32[i]) 2678 break; 2679 else if (a->addr32[i] > e->addr32[i]) 2680 return (0); 2681 break; 2682 } 2683#endif /* INET6 */ 2684 } 2685 return (1); 2686} 2687 2688int 2689pf_match(u_int8_t op, u_int32_t a1, u_int32_t a2, u_int32_t p) 2690{ 2691 switch (op) { 2692 case PF_OP_IRG: 2693 return ((p > a1) && (p < a2)); 2694 case PF_OP_XRG: 2695 return ((p < a1) || (p > a2)); 2696 case PF_OP_RRG: 2697 return ((p >= a1) && (p <= a2)); 2698 case PF_OP_EQ: 2699 return (p == a1); 2700 case PF_OP_NE: 2701 return (p != a1); 2702 case PF_OP_LT: 2703 return (p < a1); 2704 case PF_OP_LE: 2705 return (p <= a1); 2706 case PF_OP_GT: 2707 return (p > a1); 2708 case PF_OP_GE: 2709 return (p >= a1); 2710 } 2711 return (0); /* never reached */ 2712} 2713 2714int 2715pf_match_port(u_int8_t op, u_int16_t a1, u_int16_t a2, u_int16_t p) 2716{ 2717 NTOHS(a1); 2718 NTOHS(a2); 2719 NTOHS(p); 2720 return (pf_match(op, a1, a2, p)); 2721} 2722 2723int 2724pf_match_uid(u_int8_t op, uid_t a1, uid_t a2, uid_t u) 2725{ 2726 if (u == UID_MAX && op != PF_OP_EQ && op != PF_OP_NE) 2727 return (0); 2728 return (pf_match(op, a1, a2, u)); 2729} 2730 2731int 2732pf_match_gid(u_int8_t op, gid_t a1, gid_t a2, gid_t g) 2733{ 2734 if (g == GID_MAX && op != PF_OP_EQ && op != PF_OP_NE) 2735 return (0); 2736 return (pf_match(op, a1, a2, g)); 2737} 2738 2739int 2740#ifdef __FreeBSD__ 2741pf_match_tag(struct mbuf *m, struct pf_rule *r, int *tag, 2742 struct pf_mtag *pf_mtag) 2743#else 2744pf_match_tag(struct mbuf *m, struct pf_rule *r, int *tag) 2745#endif 2746{ 2747 if (*tag == -1) 2748#ifdef __FreeBSD__ 2749 *tag = pf_mtag->tag; 2750#else 2751 *tag = m->m_pkthdr.pf.tag; 2752#endif 2753 2754 return ((!r->match_tag_not && r->match_tag == *tag) || 2755 (r->match_tag_not && r->match_tag != *tag)); 2756} 2757 2758int 2759#ifdef __FreeBSD__ 2760pf_tag_packet(struct mbuf *m, int tag, int rtableid, 2761 struct pf_mtag *pf_mtag) 2762#else 2763pf_tag_packet(struct mbuf *m, int tag, int rtableid) 2764#endif 2765{ 2766 if (tag <= 0 && rtableid < 0) 2767 return (0); 2768 2769 if (tag > 0) 2770#ifdef __FreeBSD__ 2771 pf_mtag->tag = tag; 2772#else 2773 m->m_pkthdr.pf.tag = tag; 2774#endif 2775 if (rtableid >= 0) 2776#ifdef __FreeBSD__ 2777 { 2778 M_SETFIB(m, rtableid); 2779 } 2780#else 2781 m->m_pkthdr.pf.rtableid = rtableid; 2782#endif 2783 2784 return (0); 2785} 2786 2787void 2788pf_step_into_anchor(int *depth, struct pf_ruleset **rs, int n, 2789 struct pf_rule **r, struct pf_rule **a, int *match) 2790{ 2791 struct pf_anchor_stackframe *f; 2792 2793 (*r)->anchor->match = 0; 2794 if (match) 2795 *match = 0; 2796#ifdef __FreeBSD__ 2797 if (*depth >= sizeof(V_pf_anchor_stack) / 2798 sizeof(V_pf_anchor_stack[0])) { 2799#else 2800 if (*depth >= sizeof(pf_anchor_stack) / 2801 sizeof(pf_anchor_stack[0])) { 2802#endif 2803 printf("pf_step_into_anchor: stack overflow\n"); 2804 *r = TAILQ_NEXT(*r, entries); 2805 return; 2806 } else if (*depth == 0 && a != NULL) 2807 *a = *r; 2808#ifdef __FreeBSD__ 2809 f = V_pf_anchor_stack + (*depth)++; 2810#else 2811 f = pf_anchor_stack + (*depth)++; 2812#endif 2813 f->rs = *rs; 2814 f->r = *r; 2815 if ((*r)->anchor_wildcard) { 2816 f->parent = &(*r)->anchor->children; 2817 if ((f->child = RB_MIN(pf_anchor_node, f->parent)) == 2818 NULL) { 2819 *r = NULL; 2820 return; 2821 } 2822 *rs = &f->child->ruleset; 2823 } else { 2824 f->parent = NULL; 2825 f->child = NULL; 2826 *rs = &(*r)->anchor->ruleset; 2827 } 2828 *r = TAILQ_FIRST((*rs)->rules[n].active.ptr); 2829} 2830 2831int 2832pf_step_out_of_anchor(int *depth, struct pf_ruleset **rs, int n, 2833 struct pf_rule **r, struct pf_rule **a, int *match) 2834{ 2835 struct pf_anchor_stackframe *f; 2836 int quick = 0; 2837 2838 do { 2839 if (*depth <= 0) 2840 break; 2841#ifdef __FreeBSD__ 2842 f = V_pf_anchor_stack + *depth - 1; 2843#else 2844 f = pf_anchor_stack + *depth - 1; 2845#endif 2846 if (f->parent != NULL && f->child != NULL) { 2847 if (f->child->match || 2848 (match != NULL && *match)) { 2849 f->r->anchor->match = 1; 2850 *match = 0; 2851 } 2852 f->child = RB_NEXT(pf_anchor_node, f->parent, f->child); 2853 if (f->child != NULL) { 2854 *rs = &f->child->ruleset; 2855 *r = TAILQ_FIRST((*rs)->rules[n].active.ptr); 2856 if (*r == NULL) 2857 continue; 2858 else 2859 break; 2860 } 2861 } 2862 (*depth)--; 2863 if (*depth == 0 && a != NULL) 2864 *a = NULL; 2865 *rs = f->rs; 2866 if (f->r->anchor->match || (match != NULL && *match)) 2867 quick = f->r->quick; 2868 *r = TAILQ_NEXT(f->r, entries); 2869 } while (*r == NULL); 2870 2871 return (quick); 2872} 2873 2874#ifdef INET6 2875void 2876pf_poolmask(struct pf_addr *naddr, struct pf_addr *raddr, 2877 struct pf_addr *rmask, struct pf_addr *saddr, sa_family_t af) 2878{ 2879 switch (af) { 2880#ifdef INET 2881 case AF_INET: 2882 naddr->addr32[0] = (raddr->addr32[0] & rmask->addr32[0]) | 2883 ((rmask->addr32[0] ^ 0xffffffff ) & saddr->addr32[0]); 2884 break; 2885#endif /* INET */ 2886 case AF_INET6: 2887 naddr->addr32[0] = (raddr->addr32[0] & rmask->addr32[0]) | 2888 ((rmask->addr32[0] ^ 0xffffffff ) & saddr->addr32[0]); 2889 naddr->addr32[1] = (raddr->addr32[1] & rmask->addr32[1]) | 2890 ((rmask->addr32[1] ^ 0xffffffff ) & saddr->addr32[1]); 2891 naddr->addr32[2] = (raddr->addr32[2] & rmask->addr32[2]) | 2892 ((rmask->addr32[2] ^ 0xffffffff ) & saddr->addr32[2]); 2893 naddr->addr32[3] = (raddr->addr32[3] & rmask->addr32[3]) | 2894 ((rmask->addr32[3] ^ 0xffffffff ) & saddr->addr32[3]); 2895 break; 2896 } 2897} 2898 2899void 2900pf_addr_inc(struct pf_addr *addr, sa_family_t af) 2901{ 2902 switch (af) { 2903#ifdef INET 2904 case AF_INET: 2905 addr->addr32[0] = htonl(ntohl(addr->addr32[0]) + 1); 2906 break; 2907#endif /* INET */ 2908 case AF_INET6: 2909 if (addr->addr32[3] == 0xffffffff) { 2910 addr->addr32[3] = 0; 2911 if (addr->addr32[2] == 0xffffffff) { 2912 addr->addr32[2] = 0; 2913 if (addr->addr32[1] == 0xffffffff) { 2914 addr->addr32[1] = 0; 2915 addr->addr32[0] = 2916 htonl(ntohl(addr->addr32[0]) + 1); 2917 } else 2918 addr->addr32[1] = 2919 htonl(ntohl(addr->addr32[1]) + 1); 2920 } else 2921 addr->addr32[2] = 2922 htonl(ntohl(addr->addr32[2]) + 1); 2923 } else 2924 addr->addr32[3] = 2925 htonl(ntohl(addr->addr32[3]) + 1); 2926 break; 2927 } 2928} 2929#endif /* INET6 */ 2930 2931int 2932#ifdef __FreeBSD__ 2933pf_socket_lookup(int direction, struct pf_pdesc *pd, struct inpcb *inp_arg) 2934#else 2935pf_socket_lookup(int direction, struct pf_pdesc *pd) 2936#endif 2937{ 2938 struct pf_addr *saddr, *daddr; 2939 u_int16_t sport, dport; 2940#ifdef __FreeBSD__ 2941 struct inpcbinfo *pi; 2942#else 2943 struct inpcbtable *tb; 2944#endif 2945 struct inpcb *inp; 2946 2947 if (pd == NULL) 2948 return (-1); 2949 pd->lookup.uid = UID_MAX; 2950 pd->lookup.gid = GID_MAX; 2951 pd->lookup.pid = NO_PID; 2952 2953#ifdef __FreeBSD__ 2954 if (inp_arg != NULL) { 2955 INP_LOCK_ASSERT(inp_arg); 2956 pd->lookup.uid = inp_arg->inp_cred->cr_uid; 2957 pd->lookup.gid = inp_arg->inp_cred->cr_groups[0]; 2958 return (1); 2959 } 2960#endif 2961 2962 switch (pd->proto) { 2963 case IPPROTO_TCP: 2964 if (pd->hdr.tcp == NULL) 2965 return (-1); 2966 sport = pd->hdr.tcp->th_sport; 2967 dport = pd->hdr.tcp->th_dport; 2968#ifdef __FreeBSD__ 2969 pi = &V_tcbinfo; 2970#else 2971 tb = &tcbtable; 2972#endif 2973 break; 2974 case IPPROTO_UDP: 2975 if (pd->hdr.udp == NULL) 2976 return (-1); 2977 sport = pd->hdr.udp->uh_sport; 2978 dport = pd->hdr.udp->uh_dport; 2979#ifdef __FreeBSD__ 2980 pi = &V_udbinfo; 2981#else 2982 tb = &udbtable; 2983#endif 2984 break; 2985 default: 2986 return (-1); 2987 } 2988 if (direction == PF_IN) { 2989 saddr = pd->src; 2990 daddr = pd->dst; 2991 } else { 2992 u_int16_t p; 2993 2994 p = sport; 2995 sport = dport; 2996 dport = p; 2997 saddr = pd->dst; 2998 daddr = pd->src; 2999 } 3000 switch (pd->af) { 3001#ifdef INET 3002 case AF_INET: 3003#ifdef __FreeBSD__ 3004 /* 3005 * XXXRW: would be nice if we had an mbuf here so that we 3006 * could use in_pcblookup_mbuf(). 3007 */ 3008 inp = in_pcblookup(pi, saddr->v4, sport, daddr->v4, 3009 dport, INPLOOKUP_RLOCKPCB, NULL); 3010 if (inp == NULL) { 3011 inp = in_pcblookup(pi, saddr->v4, sport, 3012 daddr->v4, dport, INPLOOKUP_WILDCARD | 3013 INPLOOKUP_RLOCKPCB, NULL); 3014 if (inp == NULL) 3015 return (-1); 3016 } 3017#else 3018 inp = in_pcbhashlookup(tb, saddr->v4, sport, daddr->v4, dport); 3019 if (inp == NULL) { 3020 inp = in_pcblookup_listen(tb, daddr->v4, dport, 0, 3021 NULL); 3022 if (inp == NULL) 3023 return (-1); 3024 } 3025#endif 3026 break; 3027#endif /* INET */ 3028#ifdef INET6 3029 case AF_INET6: 3030#ifdef __FreeBSD__ 3031 /* 3032 * XXXRW: would be nice if we had an mbuf here so that we 3033 * could use in6_pcblookup_mbuf(). 3034 */ 3035 inp = in6_pcblookup(pi, &saddr->v6, sport, 3036 &daddr->v6, dport, INPLOOKUP_RLOCKPCB, NULL); 3037 if (inp == NULL) { 3038 inp = in6_pcblookup(pi, &saddr->v6, sport, 3039 &daddr->v6, dport, INPLOOKUP_WILDCARD | 3040 INPLOOKUP_RLOCKPCB, NULL); 3041 if (inp == NULL) 3042 return (-1); 3043 } 3044#else 3045 inp = in6_pcbhashlookup(tb, &saddr->v6, sport, &daddr->v6, 3046 dport); 3047 if (inp == NULL) { 3048 inp = in6_pcblookup_listen(tb, &daddr->v6, dport, 0, 3049 NULL); 3050 if (inp == NULL) 3051 return (-1); 3052 } 3053#endif 3054 break; 3055#endif /* INET6 */ 3056 3057 default: 3058 return (-1); 3059 } 3060#ifdef __FreeBSD__ 3061 INP_RLOCK_ASSERT(inp); 3062 pd->lookup.uid = inp->inp_cred->cr_uid; 3063 pd->lookup.gid = inp->inp_cred->cr_groups[0]; 3064 INP_RUNLOCK(inp); 3065#else 3066 pd->lookup.uid = inp->inp_socket->so_euid; 3067 pd->lookup.gid = inp->inp_socket->so_egid; 3068 pd->lookup.pid = inp->inp_socket->so_cpid; 3069#endif 3070 return (1); 3071} 3072 3073u_int8_t 3074pf_get_wscale(struct mbuf *m, int off, u_int16_t th_off, sa_family_t af) 3075{ 3076 int hlen; 3077 u_int8_t hdr[60]; 3078 u_int8_t *opt, optlen; 3079 u_int8_t wscale = 0; 3080 3081 hlen = th_off << 2; /* hlen <= sizeof(hdr) */ 3082 if (hlen <= sizeof(struct tcphdr)) 3083 return (0); 3084 if (!pf_pull_hdr(m, off, hdr, hlen, NULL, NULL, af)) 3085 return (0); 3086 opt = hdr + sizeof(struct tcphdr); 3087 hlen -= sizeof(struct tcphdr); 3088 while (hlen >= 3) { 3089 switch (*opt) { 3090 case TCPOPT_EOL: 3091 case TCPOPT_NOP: 3092 ++opt; 3093 --hlen; 3094 break; 3095 case TCPOPT_WINDOW: 3096 wscale = opt[2]; 3097 if (wscale > TCP_MAX_WINSHIFT) 3098 wscale = TCP_MAX_WINSHIFT; 3099 wscale |= PF_WSCALE_FLAG; 3100 /* FALLTHROUGH */ 3101 default: 3102 optlen = opt[1]; 3103 if (optlen < 2) 3104 optlen = 2; 3105 hlen -= optlen; 3106 opt += optlen; 3107 break; 3108 } 3109 } 3110 return (wscale); 3111} 3112 3113u_int16_t 3114pf_get_mss(struct mbuf *m, int off, u_int16_t th_off, sa_family_t af) 3115{ 3116 int hlen; 3117 u_int8_t hdr[60]; 3118 u_int8_t *opt, optlen; 3119#ifdef __FreeBSD__ 3120 u_int16_t mss = V_tcp_mssdflt; 3121#else 3122 u_int16_t mss = tcp_mssdflt; 3123#endif 3124 3125 hlen = th_off << 2; /* hlen <= sizeof(hdr) */ 3126 if (hlen <= sizeof(struct tcphdr)) 3127 return (0); 3128 if (!pf_pull_hdr(m, off, hdr, hlen, NULL, NULL, af)) 3129 return (0); 3130 opt = hdr + sizeof(struct tcphdr); 3131 hlen -= sizeof(struct tcphdr); 3132 while (hlen >= TCPOLEN_MAXSEG) { 3133 switch (*opt) { 3134 case TCPOPT_EOL: 3135 case TCPOPT_NOP: 3136 ++opt; 3137 --hlen; 3138 break; 3139 case TCPOPT_MAXSEG: 3140 bcopy((caddr_t)(opt + 2), (caddr_t)&mss, 2); 3141 NTOHS(mss); 3142 /* FALLTHROUGH */ 3143 default: 3144 optlen = opt[1]; 3145 if (optlen < 2) 3146 optlen = 2; 3147 hlen -= optlen; 3148 opt += optlen; 3149 break; 3150 } 3151 } 3152 return (mss); 3153} 3154 3155u_int16_t 3156pf_calc_mss(struct pf_addr *addr, sa_family_t af, u_int16_t offer) 3157{ 3158#ifdef INET 3159 struct sockaddr_in *dst; 3160 struct route ro; 3161#endif /* INET */ 3162#ifdef INET6 3163 struct sockaddr_in6 *dst6; 3164 struct route_in6 ro6; 3165#endif /* INET6 */ 3166 struct rtentry *rt = NULL; 3167#ifdef __FreeBSD__ 3168 int hlen = 0; 3169 u_int16_t mss = V_tcp_mssdflt; 3170#else 3171 int hlen; 3172 u_int16_t mss = tcp_mssdflt; 3173#endif 3174 3175 switch (af) { 3176#ifdef INET 3177 case AF_INET: 3178 hlen = sizeof(struct ip); 3179 bzero(&ro, sizeof(ro)); 3180 dst = (struct sockaddr_in *)&ro.ro_dst; 3181 dst->sin_family = AF_INET; 3182 dst->sin_len = sizeof(*dst); 3183 dst->sin_addr = addr->v4; 3184#ifdef __FreeBSD__ 3185#ifdef RTF_PRCLONING 3186 rtalloc_ign(&ro, (RTF_CLONING | RTF_PRCLONING)); 3187#else /* !RTF_PRCLONING */ 3188 in_rtalloc_ign(&ro, 0, 0); 3189#endif 3190#else /* ! __FreeBSD__ */ 3191 rtalloc_noclone(&ro, NO_CLONING); 3192#endif 3193 rt = ro.ro_rt; 3194 break; 3195#endif /* INET */ 3196#ifdef INET6 3197 case AF_INET6: 3198 hlen = sizeof(struct ip6_hdr); 3199 bzero(&ro6, sizeof(ro6)); 3200 dst6 = (struct sockaddr_in6 *)&ro6.ro_dst; 3201 dst6->sin6_family = AF_INET6; 3202 dst6->sin6_len = sizeof(*dst6); 3203 dst6->sin6_addr = addr->v6; 3204#ifdef __FreeBSD__ 3205#ifdef RTF_PRCLONING 3206 rtalloc_ign((struct route *)&ro6, 3207 (RTF_CLONING | RTF_PRCLONING)); 3208#else /* !RTF_PRCLONING */ 3209 rtalloc_ign((struct route *)&ro6, 0); 3210#endif 3211#else /* ! __FreeBSD__ */ 3212 rtalloc_noclone((struct route *)&ro6, NO_CLONING); 3213#endif 3214 rt = ro6.ro_rt; 3215 break; 3216#endif /* INET6 */ 3217 } 3218 3219 if (rt && rt->rt_ifp) { 3220 mss = rt->rt_ifp->if_mtu - hlen - sizeof(struct tcphdr); 3221#ifdef __FreeBSD__ 3222 mss = max(V_tcp_mssdflt, mss); 3223#else 3224 mss = max(tcp_mssdflt, mss); 3225#endif 3226 RTFREE(rt); 3227 } 3228 mss = min(mss, offer); 3229 mss = max(mss, 64); /* sanity - at least max opt space */ 3230 return (mss); 3231} 3232 3233void 3234pf_set_rt_ifp(struct pf_state *s, struct pf_addr *saddr) 3235{ 3236 struct pf_rule *r = s->rule.ptr; 3237 struct pf_src_node *sn = NULL; 3238 3239 s->rt_kif = NULL; 3240 if (!r->rt || r->rt == PF_FASTROUTE) 3241 return; 3242 switch (s->key[PF_SK_WIRE]->af) { 3243#ifdef INET 3244 case AF_INET: 3245 pf_map_addr(AF_INET, r, saddr, &s->rt_addr, NULL, &sn); 3246 s->rt_kif = r->rpool.cur->kif; 3247 break; 3248#endif /* INET */ 3249#ifdef INET6 3250 case AF_INET6: 3251 pf_map_addr(AF_INET6, r, saddr, &s->rt_addr, NULL, &sn); 3252 s->rt_kif = r->rpool.cur->kif; 3253 break; 3254#endif /* INET6 */ 3255 } 3256} 3257 3258u_int32_t 3259pf_tcp_iss(struct pf_pdesc *pd) 3260{ 3261 MD5_CTX ctx; 3262 u_int32_t digest[4]; 3263 3264#ifdef __FreeBSD__ 3265 if (V_pf_tcp_secret_init == 0) { 3266 read_random(&V_pf_tcp_secret, sizeof(V_pf_tcp_secret)); 3267 MD5Init(&V_pf_tcp_secret_ctx); 3268 MD5Update(&V_pf_tcp_secret_ctx, V_pf_tcp_secret, 3269 sizeof(V_pf_tcp_secret)); 3270 V_pf_tcp_secret_init = 1; 3271 } 3272 3273 ctx = V_pf_tcp_secret_ctx; 3274#else 3275 if (pf_tcp_secret_init == 0) { 3276 arc4random_buf(pf_tcp_secret, sizeof(pf_tcp_secret)); 3277 MD5Init(&pf_tcp_secret_ctx); 3278 MD5Update(&pf_tcp_secret_ctx, pf_tcp_secret, 3279 sizeof(pf_tcp_secret)); 3280 pf_tcp_secret_init = 1; 3281 } 3282 3283 ctx = pf_tcp_secret_ctx; 3284#endif 3285 3286 MD5Update(&ctx, (char *)&pd->hdr.tcp->th_sport, sizeof(u_short)); 3287 MD5Update(&ctx, (char *)&pd->hdr.tcp->th_dport, sizeof(u_short)); 3288 if (pd->af == AF_INET6) { 3289 MD5Update(&ctx, (char *)&pd->src->v6, sizeof(struct in6_addr)); 3290 MD5Update(&ctx, (char *)&pd->dst->v6, sizeof(struct in6_addr)); 3291 } else { 3292 MD5Update(&ctx, (char *)&pd->src->v4, sizeof(struct in_addr)); 3293 MD5Update(&ctx, (char *)&pd->dst->v4, sizeof(struct in_addr)); 3294 } 3295 MD5Final((u_char *)digest, &ctx); 3296#ifdef __FreeBSD__ 3297 V_pf_tcp_iss_off += 4096; 3298#define ISN_RANDOM_INCREMENT (4096 - 1) 3299 return (digest[0] + (arc4random() & ISN_RANDOM_INCREMENT) + 3300 V_pf_tcp_iss_off); 3301#undef ISN_RANDOM_INCREMENT 3302#else 3303 pf_tcp_iss_off += 4096; 3304 return (digest[0] + tcp_iss + pf_tcp_iss_off); 3305#endif 3306} 3307 3308int 3309pf_test_rule(struct pf_rule **rm, struct pf_state **sm, int direction, 3310 struct pfi_kif *kif, struct mbuf *m, int off, void *h, 3311 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm, 3312#ifdef __FreeBSD__ 3313 struct ifqueue *ifq, struct inpcb *inp) 3314#else 3315 struct ifqueue *ifq) 3316#endif 3317{ 3318 struct pf_rule *nr = NULL; 3319 struct pf_addr *saddr = pd->src, *daddr = pd->dst; 3320 sa_family_t af = pd->af; 3321 struct pf_rule *r, *a = NULL; 3322 struct pf_ruleset *ruleset = NULL; 3323 struct pf_src_node *nsn = NULL; 3324 struct tcphdr *th = pd->hdr.tcp; 3325 struct pf_state_key *skw = NULL, *sks = NULL; 3326 struct pf_state_key *sk = NULL, *nk = NULL; 3327 u_short reason; 3328 int rewrite = 0, hdrlen = 0; 3329 int tag = -1, rtableid = -1; 3330 int asd = 0; 3331 int match = 0; 3332 int state_icmp = 0; 3333#ifdef __FreeBSD__ 3334 u_int16_t sport = 0, dport = 0; 3335 u_int16_t bproto_sum = 0, bip_sum = 0; 3336#else 3337 u_int16_t sport, dport; 3338 u_int16_t bproto_sum = 0, bip_sum; 3339#endif 3340 u_int8_t icmptype = 0, icmpcode = 0; 3341 3342 3343 if (direction == PF_IN && pf_check_congestion(ifq)) { 3344 REASON_SET(&reason, PFRES_CONGEST); 3345 return (PF_DROP); 3346 } 3347 3348#ifdef __FreeBSD__ 3349 if (inp != NULL) 3350 pd->lookup.done = pf_socket_lookup(direction, pd, inp); 3351 else if (V_debug_pfugidhack) { 3352 PF_UNLOCK(); 3353 DPFPRINTF(PF_DEBUG_MISC, ("pf: unlocked lookup\n")); 3354 pd->lookup.done = pf_socket_lookup(direction, pd, inp); 3355 PF_LOCK(); 3356 } 3357#endif 3358 3359 switch (pd->proto) { 3360 case IPPROTO_TCP: 3361 sport = th->th_sport; 3362 dport = th->th_dport; 3363 hdrlen = sizeof(*th); 3364 break; 3365 case IPPROTO_UDP: 3366 sport = pd->hdr.udp->uh_sport; 3367 dport = pd->hdr.udp->uh_dport; 3368 hdrlen = sizeof(*pd->hdr.udp); 3369 break; 3370#ifdef INET 3371 case IPPROTO_ICMP: 3372 if (pd->af != AF_INET) 3373 break; 3374 sport = dport = pd->hdr.icmp->icmp_id; 3375 hdrlen = sizeof(*pd->hdr.icmp); 3376 icmptype = pd->hdr.icmp->icmp_type; 3377 icmpcode = pd->hdr.icmp->icmp_code; 3378 3379 if (icmptype == ICMP_UNREACH || 3380 icmptype == ICMP_SOURCEQUENCH || 3381 icmptype == ICMP_REDIRECT || 3382 icmptype == ICMP_TIMXCEED || 3383 icmptype == ICMP_PARAMPROB) 3384 state_icmp++; 3385 break; 3386#endif /* INET */ 3387#ifdef INET6 3388 case IPPROTO_ICMPV6: 3389 if (af != AF_INET6) 3390 break; 3391 sport = dport = pd->hdr.icmp6->icmp6_id; 3392 hdrlen = sizeof(*pd->hdr.icmp6); 3393 icmptype = pd->hdr.icmp6->icmp6_type; 3394 icmpcode = pd->hdr.icmp6->icmp6_code; 3395 3396 if (icmptype == ICMP6_DST_UNREACH || 3397 icmptype == ICMP6_PACKET_TOO_BIG || 3398 icmptype == ICMP6_TIME_EXCEEDED || 3399 icmptype == ICMP6_PARAM_PROB) 3400 state_icmp++; 3401 break; 3402#endif /* INET6 */ 3403 default: 3404 sport = dport = hdrlen = 0; 3405 break; 3406 } 3407 3408 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); 3409 3410 /* check packet for BINAT/NAT/RDR */ 3411 if ((nr = pf_get_translation(pd, m, off, direction, kif, &nsn, 3412 &skw, &sks, &sk, &nk, saddr, daddr, sport, dport)) != NULL) { 3413 if (nk == NULL || sk == NULL) { 3414 REASON_SET(&reason, PFRES_MEMORY); 3415 goto cleanup; 3416 } 3417 3418 if (pd->ip_sum) 3419 bip_sum = *pd->ip_sum; 3420 3421 switch (pd->proto) { 3422 case IPPROTO_TCP: 3423 bproto_sum = th->th_sum; 3424 pd->proto_sum = &th->th_sum; 3425 3426 if (PF_ANEQ(saddr, &nk->addr[pd->sidx], af) || 3427 nk->port[pd->sidx] != sport) { 3428 pf_change_ap(saddr, &th->th_sport, pd->ip_sum, 3429 &th->th_sum, &nk->addr[pd->sidx], 3430 nk->port[pd->sidx], 0, af); 3431 pd->sport = &th->th_sport; 3432 sport = th->th_sport; 3433 } 3434 3435 if (PF_ANEQ(daddr, &nk->addr[pd->didx], af) || 3436 nk->port[pd->didx] != dport) { 3437 pf_change_ap(daddr, &th->th_dport, pd->ip_sum, 3438 &th->th_sum, &nk->addr[pd->didx], 3439 nk->port[pd->didx], 0, af); 3440 dport = th->th_dport; 3441 pd->dport = &th->th_dport; 3442 } 3443 rewrite++; 3444 break; 3445 case IPPROTO_UDP: 3446 bproto_sum = pd->hdr.udp->uh_sum; 3447 pd->proto_sum = &pd->hdr.udp->uh_sum; 3448 3449 if (PF_ANEQ(saddr, &nk->addr[pd->sidx], af) || 3450 nk->port[pd->sidx] != sport) { 3451 pf_change_ap(saddr, &pd->hdr.udp->uh_sport, 3452 pd->ip_sum, &pd->hdr.udp->uh_sum, 3453 &nk->addr[pd->sidx], 3454 nk->port[pd->sidx], 1, af); 3455 sport = pd->hdr.udp->uh_sport; 3456 pd->sport = &pd->hdr.udp->uh_sport; 3457 } 3458 3459 if (PF_ANEQ(daddr, &nk->addr[pd->didx], af) || 3460 nk->port[pd->didx] != dport) { 3461 pf_change_ap(daddr, &pd->hdr.udp->uh_dport, 3462 pd->ip_sum, &pd->hdr.udp->uh_sum, 3463 &nk->addr[pd->didx], 3464 nk->port[pd->didx], 1, af); 3465 dport = pd->hdr.udp->uh_dport; 3466 pd->dport = &pd->hdr.udp->uh_dport; 3467 } 3468 rewrite++; 3469 break; 3470#ifdef INET 3471 case IPPROTO_ICMP: 3472 nk->port[0] = nk->port[1]; 3473 if (PF_ANEQ(saddr, &nk->addr[pd->sidx], AF_INET)) 3474 pf_change_a(&saddr->v4.s_addr, pd->ip_sum, 3475 nk->addr[pd->sidx].v4.s_addr, 0); 3476 3477 if (PF_ANEQ(daddr, &nk->addr[pd->didx], AF_INET)) 3478 pf_change_a(&daddr->v4.s_addr, pd->ip_sum, 3479 nk->addr[pd->didx].v4.s_addr, 0); 3480 3481 if (nk->port[1] != pd->hdr.icmp->icmp_id) { 3482 pd->hdr.icmp->icmp_cksum = pf_cksum_fixup( 3483 pd->hdr.icmp->icmp_cksum, sport, 3484 nk->port[1], 0); 3485 pd->hdr.icmp->icmp_id = nk->port[1]; 3486 pd->sport = &pd->hdr.icmp->icmp_id; 3487 } 3488 m_copyback(m, off, ICMP_MINLEN, (caddr_t)pd->hdr.icmp); 3489 break; 3490#endif /* INET */ 3491#ifdef INET6 3492 case IPPROTO_ICMPV6: 3493 nk->port[0] = nk->port[1]; 3494 if (PF_ANEQ(saddr, &nk->addr[pd->sidx], AF_INET6)) 3495 pf_change_a6(saddr, &pd->hdr.icmp6->icmp6_cksum, 3496 &nk->addr[pd->sidx], 0); 3497 3498 if (PF_ANEQ(daddr, &nk->addr[pd->didx], AF_INET6)) 3499 pf_change_a6(daddr, &pd->hdr.icmp6->icmp6_cksum, 3500 &nk->addr[pd->didx], 0); 3501 rewrite++; 3502 break; 3503#endif /* INET */ 3504 default: 3505 switch (af) { 3506#ifdef INET 3507 case AF_INET: 3508 if (PF_ANEQ(saddr, 3509 &nk->addr[pd->sidx], AF_INET)) 3510 pf_change_a(&saddr->v4.s_addr, 3511 pd->ip_sum, 3512 nk->addr[pd->sidx].v4.s_addr, 0); 3513 3514 if (PF_ANEQ(daddr, 3515 &nk->addr[pd->didx], AF_INET)) 3516 pf_change_a(&daddr->v4.s_addr, 3517 pd->ip_sum, 3518 nk->addr[pd->didx].v4.s_addr, 0); 3519 break; 3520#endif /* INET */ 3521#ifdef INET6 3522 case AF_INET6: 3523 if (PF_ANEQ(saddr, 3524 &nk->addr[pd->sidx], AF_INET6)) 3525 PF_ACPY(saddr, &nk->addr[pd->sidx], af); 3526 3527 if (PF_ANEQ(daddr, 3528 &nk->addr[pd->didx], AF_INET6)) 3529 PF_ACPY(saddr, &nk->addr[pd->didx], af); 3530 break; 3531#endif /* INET */ 3532 } 3533 break; 3534 } 3535 if (nr->natpass) 3536 r = NULL; 3537 pd->nat_rule = nr; 3538 } 3539 3540 while (r != NULL) { 3541 r->evaluations++; 3542 if (pfi_kif_match(r->kif, kif) == r->ifnot) 3543 r = r->skip[PF_SKIP_IFP].ptr; 3544 else if (r->direction && r->direction != direction) 3545 r = r->skip[PF_SKIP_DIR].ptr; 3546 else if (r->af && r->af != af) 3547 r = r->skip[PF_SKIP_AF].ptr; 3548 else if (r->proto && r->proto != pd->proto) 3549 r = r->skip[PF_SKIP_PROTO].ptr; 3550 else if (PF_MISMATCHAW(&r->src.addr, saddr, af, 3551 r->src.neg, kif)) 3552 r = r->skip[PF_SKIP_SRC_ADDR].ptr; 3553 /* tcp/udp only. port_op always 0 in other cases */ 3554 else if (r->src.port_op && !pf_match_port(r->src.port_op, 3555 r->src.port[0], r->src.port[1], sport)) 3556 r = r->skip[PF_SKIP_SRC_PORT].ptr; 3557 else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, 3558 r->dst.neg, NULL)) 3559 r = r->skip[PF_SKIP_DST_ADDR].ptr; 3560 /* tcp/udp only. port_op always 0 in other cases */ 3561 else if (r->dst.port_op && !pf_match_port(r->dst.port_op, 3562 r->dst.port[0], r->dst.port[1], dport)) 3563 r = r->skip[PF_SKIP_DST_PORT].ptr; 3564 /* icmp only. type always 0 in other cases */ 3565 else if (r->type && r->type != icmptype + 1) 3566 r = TAILQ_NEXT(r, entries); 3567 /* icmp only. type always 0 in other cases */ 3568 else if (r->code && r->code != icmpcode + 1) 3569 r = TAILQ_NEXT(r, entries); 3570 else if (r->tos && !(r->tos == pd->tos)) 3571 r = TAILQ_NEXT(r, entries); 3572 else if (r->rule_flag & PFRULE_FRAGMENT) 3573 r = TAILQ_NEXT(r, entries); 3574 else if (pd->proto == IPPROTO_TCP && 3575 (r->flagset & th->th_flags) != r->flags) 3576 r = TAILQ_NEXT(r, entries); 3577 /* tcp/udp only. uid.op always 0 in other cases */ 3578 else if (r->uid.op && (pd->lookup.done || (pd->lookup.done = 3579#ifdef __FreeBSD__ 3580 pf_socket_lookup(direction, pd, inp), 1)) && 3581#else 3582 pf_socket_lookup(direction, pd), 1)) && 3583#endif 3584 !pf_match_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1], 3585 pd->lookup.uid)) 3586 r = TAILQ_NEXT(r, entries); 3587 /* tcp/udp only. gid.op always 0 in other cases */ 3588 else if (r->gid.op && (pd->lookup.done || (pd->lookup.done = 3589#ifdef __FreeBSD__ 3590 pf_socket_lookup(direction, pd, inp), 1)) && 3591#else 3592 pf_socket_lookup(direction, pd), 1)) && 3593#endif 3594 !pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1], 3595 pd->lookup.gid)) 3596 r = TAILQ_NEXT(r, entries); 3597 else if (r->prob && 3598#ifdef __FreeBSD__ 3599 r->prob <= arc4random()) 3600#else 3601 r->prob <= arc4random_uniform(UINT_MAX - 1) + 1) 3602#endif 3603 r = TAILQ_NEXT(r, entries); 3604#ifdef __FreeBSD__ 3605 else if (r->match_tag && !pf_match_tag(m, r, &tag, pd->pf_mtag)) 3606#else 3607 else if (r->match_tag && !pf_match_tag(m, r, &tag)) 3608#endif 3609 r = TAILQ_NEXT(r, entries); 3610 else if (r->os_fingerprint != PF_OSFP_ANY && 3611 (pd->proto != IPPROTO_TCP || !pf_osfp_match( 3612 pf_osfp_fingerprint(pd, m, off, th), 3613 r->os_fingerprint))) 3614 r = TAILQ_NEXT(r, entries); 3615 else { 3616 if (r->tag) 3617 tag = r->tag; 3618 if (r->rtableid >= 0) 3619 rtableid = r->rtableid; 3620 if (r->anchor == NULL) { 3621 match = 1; 3622 *rm = r; 3623 *am = a; 3624 *rsm = ruleset; 3625 if ((*rm)->quick) 3626 break; 3627 r = TAILQ_NEXT(r, entries); 3628 } else 3629 pf_step_into_anchor(&asd, &ruleset, 3630 PF_RULESET_FILTER, &r, &a, &match); 3631 } 3632 if (r == NULL && pf_step_out_of_anchor(&asd, &ruleset, 3633 PF_RULESET_FILTER, &r, &a, &match)) 3634 break; 3635 } 3636 r = *rm; 3637 a = *am; 3638 ruleset = *rsm; 3639 3640 REASON_SET(&reason, PFRES_MATCH); 3641 3642 if (r->log || (nr != NULL && nr->log)) { 3643 if (rewrite) 3644 m_copyback(m, off, hdrlen, pd->hdr.any); 3645 PFLOG_PACKET(kif, h, m, af, direction, reason, r->log ? r : nr, 3646 a, ruleset, pd); 3647 } 3648 3649 if ((r->action == PF_DROP) && 3650 ((r->rule_flag & PFRULE_RETURNRST) || 3651 (r->rule_flag & PFRULE_RETURNICMP) || 3652 (r->rule_flag & PFRULE_RETURN))) { 3653 /* undo NAT changes, if they have taken place */ 3654 if (nr != NULL) { 3655 PF_ACPY(saddr, &sk->addr[pd->sidx], af); 3656 PF_ACPY(daddr, &sk->addr[pd->didx], af); 3657 if (pd->sport) 3658 *pd->sport = sk->port[pd->sidx]; 3659 if (pd->dport) 3660 *pd->dport = sk->port[pd->didx]; 3661 if (pd->proto_sum) 3662 *pd->proto_sum = bproto_sum; 3663 if (pd->ip_sum) 3664 *pd->ip_sum = bip_sum; 3665 m_copyback(m, off, hdrlen, pd->hdr.any); 3666 } 3667 if (pd->proto == IPPROTO_TCP && 3668 ((r->rule_flag & PFRULE_RETURNRST) || 3669 (r->rule_flag & PFRULE_RETURN)) && 3670 !(th->th_flags & TH_RST)) { 3671 u_int32_t ack = ntohl(th->th_seq) + pd->p_len; 3672 int len = 0; 3673#ifdef INET 3674 struct ip *h4; 3675#endif 3676#ifdef INET6 3677 struct ip6_hdr *h6; 3678#endif 3679 3680 switch (af) { 3681#ifdef INET 3682 case AF_INET: 3683 h4 = mtod(m, struct ip *); 3684 len = ntohs(h4->ip_len) - off; 3685 break; 3686#endif 3687#ifdef INET6 3688 case AF_INET6: 3689 h6 = mtod(m, struct ip6_hdr *); 3690 len = ntohs(h6->ip6_plen) - (off - sizeof(*h6)); 3691 break; 3692#endif 3693 } 3694 3695 if (pf_check_proto_cksum(m, off, len, IPPROTO_TCP, af)) 3696 REASON_SET(&reason, PFRES_PROTCKSUM); 3697 else { 3698 if (th->th_flags & TH_SYN) 3699 ack++; 3700 if (th->th_flags & TH_FIN) 3701 ack++; 3702#ifdef __FreeBSD__ 3703 pf_send_tcp(m, r, af, pd->dst, 3704#else 3705 pf_send_tcp(r, af, pd->dst, 3706#endif 3707 pd->src, th->th_dport, th->th_sport, 3708 ntohl(th->th_ack), ack, TH_RST|TH_ACK, 0, 0, 3709 r->return_ttl, 1, 0, pd->eh, kif->pfik_ifp); 3710 } 3711 } else if (pd->proto != IPPROTO_ICMP && af == AF_INET && 3712 r->return_icmp) 3713 pf_send_icmp(m, r->return_icmp >> 8, 3714 r->return_icmp & 255, af, r); 3715 else if (pd->proto != IPPROTO_ICMPV6 && af == AF_INET6 && 3716 r->return_icmp6) 3717 pf_send_icmp(m, r->return_icmp6 >> 8, 3718 r->return_icmp6 & 255, af, r); 3719 } 3720 3721 if (r->action == PF_DROP) 3722 goto cleanup; 3723 3724#ifdef __FreeBSD__ 3725 if (pf_tag_packet(m, tag, rtableid, pd->pf_mtag)) { 3726#else 3727 if (pf_tag_packet(m, tag, rtableid)) { 3728#endif 3729 REASON_SET(&reason, PFRES_MEMORY); 3730 goto cleanup; 3731 } 3732 3733 if (!state_icmp && (r->keep_state || nr != NULL || 3734 (pd->flags & PFDESC_TCP_NORM))) { 3735 int action; 3736 action = pf_create_state(r, nr, a, pd, nsn, skw, sks, nk, sk, m, 3737 off, sport, dport, &rewrite, kif, sm, tag, bproto_sum, 3738 bip_sum, hdrlen); 3739 if (action != PF_PASS) 3740 return (action); 3741 } else { 3742#ifdef __FreeBSD__ 3743 if (sk != NULL) 3744 pool_put(&V_pf_state_key_pl, sk); 3745 if (nk != NULL) 3746 pool_put(&V_pf_state_key_pl, nk); 3747#else 3748 if (sk != NULL) 3749 pool_put(&pf_state_key_pl, sk); 3750 if (nk != NULL) 3751 pool_put(&pf_state_key_pl, nk); 3752#endif 3753 } 3754 3755 /* copy back packet headers if we performed NAT operations */ 3756 if (rewrite) 3757 m_copyback(m, off, hdrlen, pd->hdr.any); 3758 3759#if NPFSYNC > 0 3760 if (*sm != NULL && !ISSET((*sm)->state_flags, PFSTATE_NOSYNC) && 3761#ifdef __FreeBSD__ 3762 direction == PF_OUT && pfsync_up_ptr != NULL && pfsync_up_ptr()) { 3763#else 3764 direction == PF_OUT && pfsync_up()) { 3765#endif 3766 /* 3767 * We want the state created, but we dont 3768 * want to send this in case a partner 3769 * firewall has to know about it to allow 3770 * replies through it. 3771 */ 3772#ifdef __FreeBSD__ 3773 if (pfsync_defer_ptr != NULL) 3774 pfsync_defer_ptr(*sm, m); 3775#else 3776 if (pfsync_defer(*sm, m)) 3777#endif 3778 return (PF_DEFER); 3779 } 3780#endif 3781 3782 return (PF_PASS); 3783 3784cleanup: 3785#ifdef __FreeBSD__ 3786 if (sk != NULL) 3787 pool_put(&V_pf_state_key_pl, sk); 3788 if (nk != NULL) 3789 pool_put(&V_pf_state_key_pl, nk); 3790#else 3791 if (sk != NULL) 3792 pool_put(&pf_state_key_pl, sk); 3793 if (nk != NULL) 3794 pool_put(&pf_state_key_pl, nk); 3795#endif 3796 return (PF_DROP); 3797} 3798 3799static __inline int 3800pf_create_state(struct pf_rule *r, struct pf_rule *nr, struct pf_rule *a, 3801 struct pf_pdesc *pd, struct pf_src_node *nsn, struct pf_state_key *skw, 3802 struct pf_state_key *sks, struct pf_state_key *nk, struct pf_state_key *sk, 3803 struct mbuf *m, int off, u_int16_t sport, u_int16_t dport, int *rewrite, 3804 struct pfi_kif *kif, struct pf_state **sm, int tag, u_int16_t bproto_sum, 3805 u_int16_t bip_sum, int hdrlen) 3806{ 3807 struct pf_state *s = NULL; 3808 struct pf_src_node *sn = NULL; 3809 struct tcphdr *th = pd->hdr.tcp; 3810#ifdef __FreeBSD__ 3811 u_int16_t mss = V_tcp_mssdflt; 3812#else 3813 u_int16_t mss = tcp_mssdflt; 3814#endif 3815 u_short reason; 3816 3817 /* check maximums */ 3818 if (r->max_states && (r->states_cur >= r->max_states)) { 3819#ifdef __FreeBSD__ 3820 V_pf_status.lcounters[LCNT_STATES]++; 3821#else 3822 pf_status.lcounters[LCNT_STATES]++; 3823#endif 3824 REASON_SET(&reason, PFRES_MAXSTATES); 3825 return (PF_DROP); 3826 } 3827 /* src node for filter rule */ 3828 if ((r->rule_flag & PFRULE_SRCTRACK || 3829 r->rpool.opts & PF_POOL_STICKYADDR) && 3830 pf_insert_src_node(&sn, r, pd->src, pd->af) != 0) { 3831 REASON_SET(&reason, PFRES_SRCLIMIT); 3832 goto csfailed; 3833 } 3834 /* src node for translation rule */ 3835 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) && 3836 pf_insert_src_node(&nsn, nr, &sk->addr[pd->sidx], pd->af)) { 3837 REASON_SET(&reason, PFRES_SRCLIMIT); 3838 goto csfailed; 3839 } 3840#ifdef __FreeBSD__ 3841 s = pool_get(&V_pf_state_pl, PR_NOWAIT | PR_ZERO); 3842#else 3843 s = pool_get(&pf_state_pl, PR_NOWAIT | PR_ZERO); 3844#endif 3845 if (s == NULL) { 3846 REASON_SET(&reason, PFRES_MEMORY); 3847 goto csfailed; 3848 } 3849 s->rule.ptr = r; 3850 s->nat_rule.ptr = nr; 3851 s->anchor.ptr = a; 3852 STATE_INC_COUNTERS(s); 3853 if (r->allow_opts) 3854 s->state_flags |= PFSTATE_ALLOWOPTS; 3855 if (r->rule_flag & PFRULE_STATESLOPPY) 3856 s->state_flags |= PFSTATE_SLOPPY; 3857 if (r->rule_flag & PFRULE_PFLOW) 3858 s->state_flags |= PFSTATE_PFLOW; 3859 s->log = r->log & PF_LOG_ALL; 3860 s->sync_state = PFSYNC_S_NONE; 3861 if (nr != NULL) 3862 s->log |= nr->log & PF_LOG_ALL; 3863 switch (pd->proto) { 3864 case IPPROTO_TCP: 3865 s->src.seqlo = ntohl(th->th_seq); 3866 s->src.seqhi = s->src.seqlo + pd->p_len + 1; 3867 if ((th->th_flags & (TH_SYN|TH_ACK)) == TH_SYN && 3868 r->keep_state == PF_STATE_MODULATE) { 3869 /* Generate sequence number modulator */ 3870 if ((s->src.seqdiff = pf_tcp_iss(pd) - s->src.seqlo) == 3871 0) 3872 s->src.seqdiff = 1; 3873 pf_change_a(&th->th_seq, &th->th_sum, 3874 htonl(s->src.seqlo + s->src.seqdiff), 0); 3875 *rewrite = 1; 3876 } else 3877 s->src.seqdiff = 0; 3878 if (th->th_flags & TH_SYN) { 3879 s->src.seqhi++; 3880 s->src.wscale = pf_get_wscale(m, off, 3881 th->th_off, pd->af); 3882 } 3883 s->src.max_win = MAX(ntohs(th->th_win), 1); 3884 if (s->src.wscale & PF_WSCALE_MASK) { 3885 /* Remove scale factor from initial window */ 3886 int win = s->src.max_win; 3887 win += 1 << (s->src.wscale & PF_WSCALE_MASK); 3888 s->src.max_win = (win - 1) >> 3889 (s->src.wscale & PF_WSCALE_MASK); 3890 } 3891 if (th->th_flags & TH_FIN) 3892 s->src.seqhi++; 3893 s->dst.seqhi = 1; 3894 s->dst.max_win = 1; 3895 s->src.state = TCPS_SYN_SENT; 3896 s->dst.state = TCPS_CLOSED; 3897 s->timeout = PFTM_TCP_FIRST_PACKET; 3898 break; 3899 case IPPROTO_UDP: 3900 s->src.state = PFUDPS_SINGLE; 3901 s->dst.state = PFUDPS_NO_TRAFFIC; 3902 s->timeout = PFTM_UDP_FIRST_PACKET; 3903 break; 3904 case IPPROTO_ICMP: 3905#ifdef INET6 3906 case IPPROTO_ICMPV6: 3907#endif 3908 s->timeout = PFTM_ICMP_FIRST_PACKET; 3909 break; 3910 default: 3911 s->src.state = PFOTHERS_SINGLE; 3912 s->dst.state = PFOTHERS_NO_TRAFFIC; 3913 s->timeout = PFTM_OTHER_FIRST_PACKET; 3914 } 3915 3916 s->creation = time_second; 3917 s->expire = time_second; 3918 3919 if (sn != NULL) { 3920 s->src_node = sn; 3921 s->src_node->states++; 3922 } 3923 if (nsn != NULL) { 3924 /* XXX We only modify one side for now. */ 3925 PF_ACPY(&nsn->raddr, &nk->addr[1], pd->af); 3926 s->nat_src_node = nsn; 3927 s->nat_src_node->states++; 3928 } 3929 if (pd->proto == IPPROTO_TCP) { 3930 if ((pd->flags & PFDESC_TCP_NORM) && pf_normalize_tcp_init(m, 3931 off, pd, th, &s->src, &s->dst)) { 3932 REASON_SET(&reason, PFRES_MEMORY); 3933 pf_src_tree_remove_state(s); 3934 STATE_DEC_COUNTERS(s); 3935#ifdef __FreeBSD__ 3936 pool_put(&V_pf_state_pl, s); 3937#else 3938 pool_put(&pf_state_pl, s); 3939#endif 3940 return (PF_DROP); 3941 } 3942 if ((pd->flags & PFDESC_TCP_NORM) && s->src.scrub && 3943 pf_normalize_tcp_stateful(m, off, pd, &reason, th, s, 3944 &s->src, &s->dst, rewrite)) { 3945 /* This really shouldn't happen!!! */ 3946 DPFPRINTF(PF_DEBUG_URGENT, 3947 ("pf_normalize_tcp_stateful failed on first pkt")); 3948 pf_normalize_tcp_cleanup(s); 3949 pf_src_tree_remove_state(s); 3950 STATE_DEC_COUNTERS(s); 3951#ifdef __FreeBSD__ 3952 pool_put(&V_pf_state_pl, s); 3953#else 3954 pool_put(&pf_state_pl, s); 3955#endif 3956 return (PF_DROP); 3957 } 3958 } 3959 s->direction = pd->dir; 3960 3961 if (sk == NULL && pf_state_key_setup(pd, nr, &skw, &sks, &sk, &nk, 3962 pd->src, pd->dst, sport, dport)) 3963 goto csfailed; 3964 3965 if (pf_state_insert(BOUND_IFACE(r, kif), skw, sks, s)) { 3966 if (pd->proto == IPPROTO_TCP) 3967 pf_normalize_tcp_cleanup(s); 3968 REASON_SET(&reason, PFRES_STATEINS); 3969 pf_src_tree_remove_state(s); 3970 STATE_DEC_COUNTERS(s); 3971#ifdef __FreeBSD__ 3972 pool_put(&V_pf_state_pl, s); 3973#else 3974 pool_put(&pf_state_pl, s); 3975#endif 3976 return (PF_DROP); 3977 } else 3978 *sm = s; 3979 3980 pf_set_rt_ifp(s, pd->src); /* needs s->state_key set */ 3981 if (tag > 0) { 3982 pf_tag_ref(tag); 3983 s->tag = tag; 3984 } 3985 if (pd->proto == IPPROTO_TCP && (th->th_flags & (TH_SYN|TH_ACK)) == 3986 TH_SYN && r->keep_state == PF_STATE_SYNPROXY) { 3987 s->src.state = PF_TCPS_PROXY_SRC; 3988 /* undo NAT changes, if they have taken place */ 3989 if (nr != NULL) { 3990 struct pf_state_key *skt = s->key[PF_SK_WIRE]; 3991 if (pd->dir == PF_OUT) 3992 skt = s->key[PF_SK_STACK]; 3993 PF_ACPY(pd->src, &skt->addr[pd->sidx], pd->af); 3994 PF_ACPY(pd->dst, &skt->addr[pd->didx], pd->af); 3995 if (pd->sport) 3996 *pd->sport = skt->port[pd->sidx]; 3997 if (pd->dport) 3998 *pd->dport = skt->port[pd->didx]; 3999 if (pd->proto_sum) 4000 *pd->proto_sum = bproto_sum; 4001 if (pd->ip_sum) 4002 *pd->ip_sum = bip_sum; 4003 m_copyback(m, off, hdrlen, pd->hdr.any); 4004 } 4005 s->src.seqhi = htonl(arc4random()); 4006 /* Find mss option */ 4007 mss = pf_get_mss(m, off, th->th_off, pd->af); 4008 mss = pf_calc_mss(pd->src, pd->af, mss); 4009 mss = pf_calc_mss(pd->dst, pd->af, mss); 4010 s->src.mss = mss; 4011#ifdef __FreeBSD__ 4012 pf_send_tcp(NULL, r, pd->af, pd->dst, pd->src, th->th_dport, 4013#else 4014 pf_send_tcp(r, pd->af, pd->dst, pd->src, th->th_dport, 4015#endif 4016 th->th_sport, s->src.seqhi, ntohl(th->th_seq) + 1, 4017 TH_SYN|TH_ACK, 0, s->src.mss, 0, 1, 0, NULL, NULL); 4018 REASON_SET(&reason, PFRES_SYNPROXY); 4019 return (PF_SYNPROXY_DROP); 4020 } 4021 4022 return (PF_PASS); 4023 4024csfailed: 4025#ifdef __FreeBSD__ 4026 if (sk != NULL) 4027 pool_put(&V_pf_state_key_pl, sk); 4028 if (nk != NULL) 4029 pool_put(&V_pf_state_key_pl, nk); 4030#else 4031 if (sk != NULL) 4032 pool_put(&pf_state_key_pl, sk); 4033 if (nk != NULL) 4034 pool_put(&pf_state_key_pl, nk); 4035#endif 4036 4037 if (sn != NULL && sn->states == 0 && sn->expire == 0) { 4038#ifdef __FreeBSD__ 4039 RB_REMOVE(pf_src_tree, &V_tree_src_tracking, sn); 4040 V_pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 4041 V_pf_status.src_nodes--; 4042 pool_put(&V_pf_src_tree_pl, sn); 4043#else 4044 RB_REMOVE(pf_src_tree, &tree_src_tracking, sn); 4045 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 4046 pf_status.src_nodes--; 4047 pool_put(&pf_src_tree_pl, sn); 4048#endif 4049 } 4050 if (nsn != sn && nsn != NULL && nsn->states == 0 && nsn->expire == 0) { 4051#ifdef __FreeBSD__ 4052 RB_REMOVE(pf_src_tree, &V_tree_src_tracking, nsn); 4053 V_pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 4054 V_pf_status.src_nodes--; 4055 pool_put(&V_pf_src_tree_pl, nsn); 4056#else 4057 RB_REMOVE(pf_src_tree, &tree_src_tracking, nsn); 4058 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 4059 pf_status.src_nodes--; 4060 pool_put(&pf_src_tree_pl, nsn); 4061#endif 4062 } 4063 return (PF_DROP); 4064} 4065 4066int 4067pf_test_fragment(struct pf_rule **rm, int direction, struct pfi_kif *kif, 4068 struct mbuf *m, void *h, struct pf_pdesc *pd, struct pf_rule **am, 4069 struct pf_ruleset **rsm) 4070{ 4071 struct pf_rule *r, *a = NULL; 4072 struct pf_ruleset *ruleset = NULL; 4073 sa_family_t af = pd->af; 4074 u_short reason; 4075 int tag = -1; 4076 int asd = 0; 4077 int match = 0; 4078 4079 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); 4080 while (r != NULL) { 4081 r->evaluations++; 4082 if (pfi_kif_match(r->kif, kif) == r->ifnot) 4083 r = r->skip[PF_SKIP_IFP].ptr; 4084 else if (r->direction && r->direction != direction) 4085 r = r->skip[PF_SKIP_DIR].ptr; 4086 else if (r->af && r->af != af) 4087 r = r->skip[PF_SKIP_AF].ptr; 4088 else if (r->proto && r->proto != pd->proto) 4089 r = r->skip[PF_SKIP_PROTO].ptr; 4090 else if (PF_MISMATCHAW(&r->src.addr, pd->src, af, 4091 r->src.neg, kif)) 4092 r = r->skip[PF_SKIP_SRC_ADDR].ptr; 4093 else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af, 4094 r->dst.neg, NULL)) 4095 r = r->skip[PF_SKIP_DST_ADDR].ptr; 4096 else if (r->tos && !(r->tos == pd->tos)) 4097 r = TAILQ_NEXT(r, entries); 4098 else if (r->os_fingerprint != PF_OSFP_ANY) 4099 r = TAILQ_NEXT(r, entries); 4100 else if (pd->proto == IPPROTO_UDP && 4101 (r->src.port_op || r->dst.port_op)) 4102 r = TAILQ_NEXT(r, entries); 4103 else if (pd->proto == IPPROTO_TCP && 4104 (r->src.port_op || r->dst.port_op || r->flagset)) 4105 r = TAILQ_NEXT(r, entries); 4106 else if ((pd->proto == IPPROTO_ICMP || 4107 pd->proto == IPPROTO_ICMPV6) && 4108 (r->type || r->code)) 4109 r = TAILQ_NEXT(r, entries); 4110 else if (r->prob && r->prob <= 4111 (arc4random() % (UINT_MAX - 1) + 1)) 4112 r = TAILQ_NEXT(r, entries); 4113#ifdef __FreeBSD__ 4114 else if (r->match_tag && !pf_match_tag(m, r, &tag, pd->pf_mtag)) 4115#else 4116 else if (r->match_tag && !pf_match_tag(m, r, &tag)) 4117#endif 4118 r = TAILQ_NEXT(r, entries); 4119 else { 4120 if (r->anchor == NULL) { 4121 match = 1; 4122 *rm = r; 4123 *am = a; 4124 *rsm = ruleset; 4125 if ((*rm)->quick) 4126 break; 4127 r = TAILQ_NEXT(r, entries); 4128 } else 4129 pf_step_into_anchor(&asd, &ruleset, 4130 PF_RULESET_FILTER, &r, &a, &match); 4131 } 4132 if (r == NULL && pf_step_out_of_anchor(&asd, &ruleset, 4133 PF_RULESET_FILTER, &r, &a, &match)) 4134 break; 4135 } 4136 r = *rm; 4137 a = *am; 4138 ruleset = *rsm; 4139 4140 REASON_SET(&reason, PFRES_MATCH); 4141 4142 if (r->log) 4143 PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset, 4144 pd); 4145 4146 if (r->action != PF_PASS) 4147 return (PF_DROP); 4148 4149#ifdef __FreeBSD__ 4150 if (pf_tag_packet(m, tag, -1, pd->pf_mtag)) { 4151#else 4152 if (pf_tag_packet(m, tag, -1)) { 4153#endif 4154 REASON_SET(&reason, PFRES_MEMORY); 4155 return (PF_DROP); 4156 } 4157 4158 return (PF_PASS); 4159} 4160 4161int 4162pf_tcp_track_full(struct pf_state_peer *src, struct pf_state_peer *dst, 4163 struct pf_state **state, struct pfi_kif *kif, struct mbuf *m, int off, 4164 struct pf_pdesc *pd, u_short *reason, int *copyback) 4165{ 4166 struct tcphdr *th = pd->hdr.tcp; 4167 u_int16_t win = ntohs(th->th_win); 4168 u_int32_t ack, end, seq, orig_seq; 4169 u_int8_t sws, dws; 4170 int ackskew; 4171 4172 if (src->wscale && dst->wscale && !(th->th_flags & TH_SYN)) { 4173 sws = src->wscale & PF_WSCALE_MASK; 4174 dws = dst->wscale & PF_WSCALE_MASK; 4175 } else 4176 sws = dws = 0; 4177 4178 /* 4179 * Sequence tracking algorithm from Guido van Rooij's paper: 4180 * http://www.madison-gurkha.com/publications/tcp_filtering/ 4181 * tcp_filtering.ps 4182 */ 4183 4184 orig_seq = seq = ntohl(th->th_seq); 4185 if (src->seqlo == 0) { 4186 /* First packet from this end. Set its state */ 4187 4188 if ((pd->flags & PFDESC_TCP_NORM || dst->scrub) && 4189 src->scrub == NULL) { 4190 if (pf_normalize_tcp_init(m, off, pd, th, src, dst)) { 4191 REASON_SET(reason, PFRES_MEMORY); 4192 return (PF_DROP); 4193 } 4194 } 4195 4196 /* Deferred generation of sequence number modulator */ 4197 if (dst->seqdiff && !src->seqdiff) { 4198 /* use random iss for the TCP server */ 4199 while ((src->seqdiff = arc4random() - seq) == 0) 4200 ; 4201 ack = ntohl(th->th_ack) - dst->seqdiff; 4202 pf_change_a(&th->th_seq, &th->th_sum, htonl(seq + 4203 src->seqdiff), 0); 4204 pf_change_a(&th->th_ack, &th->th_sum, htonl(ack), 0); 4205 *copyback = 1; 4206 } else { 4207 ack = ntohl(th->th_ack); 4208 } 4209 4210 end = seq + pd->p_len; 4211 if (th->th_flags & TH_SYN) { 4212 end++; 4213 if (dst->wscale & PF_WSCALE_FLAG) { 4214 src->wscale = pf_get_wscale(m, off, th->th_off, 4215 pd->af); 4216 if (src->wscale & PF_WSCALE_FLAG) { 4217 /* Remove scale factor from initial 4218 * window */ 4219 sws = src->wscale & PF_WSCALE_MASK; 4220 win = ((u_int32_t)win + (1 << sws) - 1) 4221 >> sws; 4222 dws = dst->wscale & PF_WSCALE_MASK; 4223 } else { 4224 /* fixup other window */ 4225 dst->max_win <<= dst->wscale & 4226 PF_WSCALE_MASK; 4227 /* in case of a retrans SYN|ACK */ 4228 dst->wscale = 0; 4229 } 4230 } 4231 } 4232 if (th->th_flags & TH_FIN) 4233 end++; 4234 4235 src->seqlo = seq; 4236 if (src->state < TCPS_SYN_SENT) 4237 src->state = TCPS_SYN_SENT; 4238 4239 /* 4240 * May need to slide the window (seqhi may have been set by 4241 * the crappy stack check or if we picked up the connection 4242 * after establishment) 4243 */ 4244 if (src->seqhi == 1 || 4245 SEQ_GEQ(end + MAX(1, dst->max_win << dws), src->seqhi)) 4246 src->seqhi = end + MAX(1, dst->max_win << dws); 4247 if (win > src->max_win) 4248 src->max_win = win; 4249 4250 } else { 4251 ack = ntohl(th->th_ack) - dst->seqdiff; 4252 if (src->seqdiff) { 4253 /* Modulate sequence numbers */ 4254 pf_change_a(&th->th_seq, &th->th_sum, htonl(seq + 4255 src->seqdiff), 0); 4256 pf_change_a(&th->th_ack, &th->th_sum, htonl(ack), 0); 4257 *copyback = 1; 4258 } 4259 end = seq + pd->p_len; 4260 if (th->th_flags & TH_SYN) 4261 end++; 4262 if (th->th_flags & TH_FIN) 4263 end++; 4264 } 4265 4266 if ((th->th_flags & TH_ACK) == 0) { 4267 /* Let it pass through the ack skew check */ 4268 ack = dst->seqlo; 4269 } else if ((ack == 0 && 4270 (th->th_flags & (TH_ACK|TH_RST)) == (TH_ACK|TH_RST)) || 4271 /* broken tcp stacks do not set ack */ 4272 (dst->state < TCPS_SYN_SENT)) { 4273 /* 4274 * Many stacks (ours included) will set the ACK number in an 4275 * FIN|ACK if the SYN times out -- no sequence to ACK. 4276 */ 4277 ack = dst->seqlo; 4278 } 4279 4280 if (seq == end) { 4281 /* Ease sequencing restrictions on no data packets */ 4282 seq = src->seqlo; 4283 end = seq; 4284 } 4285 4286 ackskew = dst->seqlo - ack; 4287 4288 4289 /* 4290 * Need to demodulate the sequence numbers in any TCP SACK options 4291 * (Selective ACK). We could optionally validate the SACK values 4292 * against the current ACK window, either forwards or backwards, but 4293 * I'm not confident that SACK has been implemented properly 4294 * everywhere. It wouldn't surprise me if several stacks accidently 4295 * SACK too far backwards of previously ACKed data. There really aren't 4296 * any security implications of bad SACKing unless the target stack 4297 * doesn't validate the option length correctly. Someone trying to 4298 * spoof into a TCP connection won't bother blindly sending SACK 4299 * options anyway. 4300 */ 4301 if (dst->seqdiff && (th->th_off << 2) > sizeof(struct tcphdr)) { 4302 if (pf_modulate_sack(m, off, pd, th, dst)) 4303 *copyback = 1; 4304 } 4305 4306 4307#define MAXACKWINDOW (0xffff + 1500) /* 1500 is an arbitrary fudge factor */ 4308 if (SEQ_GEQ(src->seqhi, end) && 4309 /* Last octet inside other's window space */ 4310 SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) && 4311 /* Retrans: not more than one window back */ 4312 (ackskew >= -MAXACKWINDOW) && 4313 /* Acking not more than one reassembled fragment backwards */ 4314 (ackskew <= (MAXACKWINDOW << sws)) && 4315 /* Acking not more than one window forward */ 4316 ((th->th_flags & TH_RST) == 0 || orig_seq == src->seqlo || 4317 (orig_seq == src->seqlo + 1) || (orig_seq + 1 == src->seqlo) || 4318 (pd->flags & PFDESC_IP_REAS) == 0)) { 4319 /* Require an exact/+1 sequence match on resets when possible */ 4320 4321 if (dst->scrub || src->scrub) { 4322 if (pf_normalize_tcp_stateful(m, off, pd, reason, th, 4323 *state, src, dst, copyback)) 4324 return (PF_DROP); 4325 } 4326 4327 /* update max window */ 4328 if (src->max_win < win) 4329 src->max_win = win; 4330 /* synchronize sequencing */ 4331 if (SEQ_GT(end, src->seqlo)) 4332 src->seqlo = end; 4333 /* slide the window of what the other end can send */ 4334 if (SEQ_GEQ(ack + (win << sws), dst->seqhi)) 4335 dst->seqhi = ack + MAX((win << sws), 1); 4336 4337 4338 /* update states */ 4339 if (th->th_flags & TH_SYN) 4340 if (src->state < TCPS_SYN_SENT) 4341 src->state = TCPS_SYN_SENT; 4342 if (th->th_flags & TH_FIN) 4343 if (src->state < TCPS_CLOSING) 4344 src->state = TCPS_CLOSING; 4345 if (th->th_flags & TH_ACK) { 4346 if (dst->state == TCPS_SYN_SENT) { 4347 dst->state = TCPS_ESTABLISHED; 4348 if (src->state == TCPS_ESTABLISHED && 4349 (*state)->src_node != NULL && 4350 pf_src_connlimit(state)) { 4351 REASON_SET(reason, PFRES_SRCLIMIT); 4352 return (PF_DROP); 4353 } 4354 } else if (dst->state == TCPS_CLOSING) 4355 dst->state = TCPS_FIN_WAIT_2; 4356 } 4357 if (th->th_flags & TH_RST) 4358 src->state = dst->state = TCPS_TIME_WAIT; 4359 4360 /* update expire time */ 4361 (*state)->expire = time_second; 4362 if (src->state >= TCPS_FIN_WAIT_2 && 4363 dst->state >= TCPS_FIN_WAIT_2) 4364 (*state)->timeout = PFTM_TCP_CLOSED; 4365 else if (src->state >= TCPS_CLOSING && 4366 dst->state >= TCPS_CLOSING) 4367 (*state)->timeout = PFTM_TCP_FIN_WAIT; 4368 else if (src->state < TCPS_ESTABLISHED || 4369 dst->state < TCPS_ESTABLISHED) 4370 (*state)->timeout = PFTM_TCP_OPENING; 4371 else if (src->state >= TCPS_CLOSING || 4372 dst->state >= TCPS_CLOSING) 4373 (*state)->timeout = PFTM_TCP_CLOSING; 4374 else 4375 (*state)->timeout = PFTM_TCP_ESTABLISHED; 4376 4377 /* Fall through to PASS packet */ 4378 4379 } else if ((dst->state < TCPS_SYN_SENT || 4380 dst->state >= TCPS_FIN_WAIT_2 || 4381 src->state >= TCPS_FIN_WAIT_2) && 4382 SEQ_GEQ(src->seqhi + MAXACKWINDOW, end) && 4383 /* Within a window forward of the originating packet */ 4384 SEQ_GEQ(seq, src->seqlo - MAXACKWINDOW)) { 4385 /* Within a window backward of the originating packet */ 4386 4387 /* 4388 * This currently handles three situations: 4389 * 1) Stupid stacks will shotgun SYNs before their peer 4390 * replies. 4391 * 2) When PF catches an already established stream (the 4392 * firewall rebooted, the state table was flushed, routes 4393 * changed...) 4394 * 3) Packets get funky immediately after the connection 4395 * closes (this should catch Solaris spurious ACK|FINs 4396 * that web servers like to spew after a close) 4397 * 4398 * This must be a little more careful than the above code 4399 * since packet floods will also be caught here. We don't 4400 * update the TTL here to mitigate the damage of a packet 4401 * flood and so the same code can handle awkward establishment 4402 * and a loosened connection close. 4403 * In the establishment case, a correct peer response will 4404 * validate the connection, go through the normal state code 4405 * and keep updating the state TTL. 4406 */ 4407 4408#ifdef __FreeBSD__ 4409 if (V_pf_status.debug >= PF_DEBUG_MISC) { 4410#else 4411 if (pf_status.debug >= PF_DEBUG_MISC) { 4412#endif 4413 printf("pf: loose state match: "); 4414 pf_print_state(*state); 4415 pf_print_flags(th->th_flags); 4416 printf(" seq=%u (%u) ack=%u len=%u ackskew=%d " 4417 "pkts=%llu:%llu dir=%s,%s\n", seq, orig_seq, ack, 4418#ifdef __FreeBSD__ 4419 pd->p_len, ackskew, (unsigned long long)(*state)->packets[0], 4420 (unsigned long long)(*state)->packets[1], 4421#else 4422 pd->p_len, ackskew, (*state)->packets[0], 4423 (*state)->packets[1], 4424#endif 4425 pd->dir == PF_IN ? "in" : "out", 4426 pd->dir == (*state)->direction ? "fwd" : "rev"); 4427 } 4428 4429 if (dst->scrub || src->scrub) { 4430 if (pf_normalize_tcp_stateful(m, off, pd, reason, th, 4431 *state, src, dst, copyback)) 4432 return (PF_DROP); 4433 } 4434 4435 /* update max window */ 4436 if (src->max_win < win) 4437 src->max_win = win; 4438 /* synchronize sequencing */ 4439 if (SEQ_GT(end, src->seqlo)) 4440 src->seqlo = end; 4441 /* slide the window of what the other end can send */ 4442 if (SEQ_GEQ(ack + (win << sws), dst->seqhi)) 4443 dst->seqhi = ack + MAX((win << sws), 1); 4444 4445 /* 4446 * Cannot set dst->seqhi here since this could be a shotgunned 4447 * SYN and not an already established connection. 4448 */ 4449 4450 if (th->th_flags & TH_FIN) 4451 if (src->state < TCPS_CLOSING) 4452 src->state = TCPS_CLOSING; 4453 if (th->th_flags & TH_RST) 4454 src->state = dst->state = TCPS_TIME_WAIT; 4455 4456 /* Fall through to PASS packet */ 4457 4458 } else { 4459 if ((*state)->dst.state == TCPS_SYN_SENT && 4460 (*state)->src.state == TCPS_SYN_SENT) { 4461 /* Send RST for state mismatches during handshake */ 4462 if (!(th->th_flags & TH_RST)) 4463#ifdef __FreeBSD__ 4464 pf_send_tcp(NULL, (*state)->rule.ptr, pd->af, 4465#else 4466 pf_send_tcp((*state)->rule.ptr, pd->af, 4467#endif 4468 pd->dst, pd->src, th->th_dport, 4469 th->th_sport, ntohl(th->th_ack), 0, 4470 TH_RST, 0, 0, 4471 (*state)->rule.ptr->return_ttl, 1, 0, 4472 pd->eh, kif->pfik_ifp); 4473 src->seqlo = 0; 4474 src->seqhi = 1; 4475 src->max_win = 1; 4476#ifdef __FreeBSD__ 4477 } else if (V_pf_status.debug >= PF_DEBUG_MISC) { 4478#else 4479 } else if (pf_status.debug >= PF_DEBUG_MISC) { 4480#endif 4481 printf("pf: BAD state: "); 4482 pf_print_state(*state); 4483 pf_print_flags(th->th_flags); 4484 printf(" seq=%u (%u) ack=%u len=%u ackskew=%d " 4485 "pkts=%llu:%llu dir=%s,%s\n", 4486 seq, orig_seq, ack, pd->p_len, ackskew, 4487#ifdef __FreeBSD__ 4488 (unsigned long long)(*state)->packets[0], 4489 (unsigned long long)(*state)->packets[1], 4490#else 4491 (*state)->packets[0], (*state)->packets[1], 4492#endif 4493 pd->dir == PF_IN ? "in" : "out", 4494 pd->dir == (*state)->direction ? "fwd" : "rev"); 4495 printf("pf: State failure on: %c %c %c %c | %c %c\n", 4496 SEQ_GEQ(src->seqhi, end) ? ' ' : '1', 4497 SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) ? 4498 ' ': '2', 4499 (ackskew >= -MAXACKWINDOW) ? ' ' : '3', 4500 (ackskew <= (MAXACKWINDOW << sws)) ? ' ' : '4', 4501 SEQ_GEQ(src->seqhi + MAXACKWINDOW, end) ?' ' :'5', 4502 SEQ_GEQ(seq, src->seqlo - MAXACKWINDOW) ?' ' :'6'); 4503 } 4504 REASON_SET(reason, PFRES_BADSTATE); 4505 return (PF_DROP); 4506 } 4507 4508 return (PF_PASS); 4509} 4510 4511int 4512pf_tcp_track_sloppy(struct pf_state_peer *src, struct pf_state_peer *dst, 4513 struct pf_state **state, struct pf_pdesc *pd, u_short *reason) 4514{ 4515 struct tcphdr *th = pd->hdr.tcp; 4516 4517 if (th->th_flags & TH_SYN) 4518 if (src->state < TCPS_SYN_SENT) 4519 src->state = TCPS_SYN_SENT; 4520 if (th->th_flags & TH_FIN) 4521 if (src->state < TCPS_CLOSING) 4522 src->state = TCPS_CLOSING; 4523 if (th->th_flags & TH_ACK) { 4524 if (dst->state == TCPS_SYN_SENT) { 4525 dst->state = TCPS_ESTABLISHED; 4526 if (src->state == TCPS_ESTABLISHED && 4527 (*state)->src_node != NULL && 4528 pf_src_connlimit(state)) { 4529 REASON_SET(reason, PFRES_SRCLIMIT); 4530 return (PF_DROP); 4531 } 4532 } else if (dst->state == TCPS_CLOSING) { 4533 dst->state = TCPS_FIN_WAIT_2; 4534 } else if (src->state == TCPS_SYN_SENT && 4535 dst->state < TCPS_SYN_SENT) { 4536 /* 4537 * Handle a special sloppy case where we only see one 4538 * half of the connection. If there is a ACK after 4539 * the initial SYN without ever seeing a packet from 4540 * the destination, set the connection to established. 4541 */ 4542 dst->state = src->state = TCPS_ESTABLISHED; 4543 if ((*state)->src_node != NULL && 4544 pf_src_connlimit(state)) { 4545 REASON_SET(reason, PFRES_SRCLIMIT); 4546 return (PF_DROP); 4547 } 4548 } else if (src->state == TCPS_CLOSING && 4549 dst->state == TCPS_ESTABLISHED && 4550 dst->seqlo == 0) { 4551 /* 4552 * Handle the closing of half connections where we 4553 * don't see the full bidirectional FIN/ACK+ACK 4554 * handshake. 4555 */ 4556 dst->state = TCPS_CLOSING; 4557 } 4558 } 4559 if (th->th_flags & TH_RST) 4560 src->state = dst->state = TCPS_TIME_WAIT; 4561 4562 /* update expire time */ 4563 (*state)->expire = time_second; 4564 if (src->state >= TCPS_FIN_WAIT_2 && 4565 dst->state >= TCPS_FIN_WAIT_2) 4566 (*state)->timeout = PFTM_TCP_CLOSED; 4567 else if (src->state >= TCPS_CLOSING && 4568 dst->state >= TCPS_CLOSING) 4569 (*state)->timeout = PFTM_TCP_FIN_WAIT; 4570 else if (src->state < TCPS_ESTABLISHED || 4571 dst->state < TCPS_ESTABLISHED) 4572 (*state)->timeout = PFTM_TCP_OPENING; 4573 else if (src->state >= TCPS_CLOSING || 4574 dst->state >= TCPS_CLOSING) 4575 (*state)->timeout = PFTM_TCP_CLOSING; 4576 else 4577 (*state)->timeout = PFTM_TCP_ESTABLISHED; 4578 4579 return (PF_PASS); 4580} 4581 4582int 4583pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif, 4584 struct mbuf *m, int off, void *h, struct pf_pdesc *pd, 4585 u_short *reason) 4586{ 4587 struct pf_state_key_cmp key; 4588 struct tcphdr *th = pd->hdr.tcp; 4589 int copyback = 0; 4590 struct pf_state_peer *src, *dst; 4591 struct pf_state_key *sk; 4592 4593 key.af = pd->af; 4594 key.proto = IPPROTO_TCP; 4595 if (direction == PF_IN) { /* wire side, straight */ 4596 PF_ACPY(&key.addr[0], pd->src, key.af); 4597 PF_ACPY(&key.addr[1], pd->dst, key.af); 4598 key.port[0] = th->th_sport; 4599 key.port[1] = th->th_dport; 4600 } else { /* stack side, reverse */ 4601 PF_ACPY(&key.addr[1], pd->src, key.af); 4602 PF_ACPY(&key.addr[0], pd->dst, key.af); 4603 key.port[1] = th->th_sport; 4604 key.port[0] = th->th_dport; 4605 } 4606 4607#ifdef __FreeBSD__ 4608 STATE_LOOKUP(kif, &key, direction, *state, m, pd->pf_mtag); 4609#else 4610 STATE_LOOKUP(kif, &key, direction, *state, m); 4611#endif 4612 4613 if (direction == (*state)->direction) { 4614 src = &(*state)->src; 4615 dst = &(*state)->dst; 4616 } else { 4617 src = &(*state)->dst; 4618 dst = &(*state)->src; 4619 } 4620 4621 sk = (*state)->key[pd->didx]; 4622 4623 if ((*state)->src.state == PF_TCPS_PROXY_SRC) { 4624 if (direction != (*state)->direction) { 4625 REASON_SET(reason, PFRES_SYNPROXY); 4626 return (PF_SYNPROXY_DROP); 4627 } 4628 if (th->th_flags & TH_SYN) { 4629 if (ntohl(th->th_seq) != (*state)->src.seqlo) { 4630 REASON_SET(reason, PFRES_SYNPROXY); 4631 return (PF_DROP); 4632 } 4633#ifdef __FreeBSD__ 4634 pf_send_tcp(NULL, (*state)->rule.ptr, pd->af, pd->dst, 4635#else 4636 pf_send_tcp((*state)->rule.ptr, pd->af, pd->dst, 4637#endif 4638 pd->src, th->th_dport, th->th_sport, 4639 (*state)->src.seqhi, ntohl(th->th_seq) + 1, 4640 TH_SYN|TH_ACK, 0, (*state)->src.mss, 0, 1, 4641 0, NULL, NULL); 4642 REASON_SET(reason, PFRES_SYNPROXY); 4643 return (PF_SYNPROXY_DROP); 4644 } else if (!(th->th_flags & TH_ACK) || 4645 (ntohl(th->th_ack) != (*state)->src.seqhi + 1) || 4646 (ntohl(th->th_seq) != (*state)->src.seqlo + 1)) { 4647 REASON_SET(reason, PFRES_SYNPROXY); 4648 return (PF_DROP); 4649 } else if ((*state)->src_node != NULL && 4650 pf_src_connlimit(state)) { 4651 REASON_SET(reason, PFRES_SRCLIMIT); 4652 return (PF_DROP); 4653 } else 4654 (*state)->src.state = PF_TCPS_PROXY_DST; 4655 } 4656 if ((*state)->src.state == PF_TCPS_PROXY_DST) { 4657 if (direction == (*state)->direction) { 4658 if (((th->th_flags & (TH_SYN|TH_ACK)) != TH_ACK) || 4659 (ntohl(th->th_ack) != (*state)->src.seqhi + 1) || 4660 (ntohl(th->th_seq) != (*state)->src.seqlo + 1)) { 4661 REASON_SET(reason, PFRES_SYNPROXY); 4662 return (PF_DROP); 4663 } 4664 (*state)->src.max_win = MAX(ntohs(th->th_win), 1); 4665 if ((*state)->dst.seqhi == 1) 4666 (*state)->dst.seqhi = htonl(arc4random()); 4667#ifdef __FreeBSD__ 4668 pf_send_tcp(NULL, (*state)->rule.ptr, pd->af, 4669#else 4670 pf_send_tcp((*state)->rule.ptr, pd->af, 4671#endif 4672 &sk->addr[pd->sidx], &sk->addr[pd->didx], 4673 sk->port[pd->sidx], sk->port[pd->didx], 4674 (*state)->dst.seqhi, 0, TH_SYN, 0, 4675 (*state)->src.mss, 0, 0, (*state)->tag, NULL, NULL); 4676 REASON_SET(reason, PFRES_SYNPROXY); 4677 return (PF_SYNPROXY_DROP); 4678 } else if (((th->th_flags & (TH_SYN|TH_ACK)) != 4679 (TH_SYN|TH_ACK)) || 4680 (ntohl(th->th_ack) != (*state)->dst.seqhi + 1)) { 4681 REASON_SET(reason, PFRES_SYNPROXY); 4682 return (PF_DROP); 4683 } else { 4684 (*state)->dst.max_win = MAX(ntohs(th->th_win), 1); 4685 (*state)->dst.seqlo = ntohl(th->th_seq); 4686#ifdef __FreeBSD__ 4687 pf_send_tcp(NULL, (*state)->rule.ptr, pd->af, pd->dst, 4688#else 4689 pf_send_tcp((*state)->rule.ptr, pd->af, pd->dst, 4690#endif 4691 pd->src, th->th_dport, th->th_sport, 4692 ntohl(th->th_ack), ntohl(th->th_seq) + 1, 4693 TH_ACK, (*state)->src.max_win, 0, 0, 0, 4694 (*state)->tag, NULL, NULL); 4695#ifdef __FreeBSD__ 4696 pf_send_tcp(NULL, (*state)->rule.ptr, pd->af, 4697#else 4698 pf_send_tcp((*state)->rule.ptr, pd->af, 4699#endif 4700 &sk->addr[pd->sidx], &sk->addr[pd->didx], 4701 sk->port[pd->sidx], sk->port[pd->didx], 4702 (*state)->src.seqhi + 1, (*state)->src.seqlo + 1, 4703 TH_ACK, (*state)->dst.max_win, 0, 0, 1, 4704 0, NULL, NULL); 4705 (*state)->src.seqdiff = (*state)->dst.seqhi - 4706 (*state)->src.seqlo; 4707 (*state)->dst.seqdiff = (*state)->src.seqhi - 4708 (*state)->dst.seqlo; 4709 (*state)->src.seqhi = (*state)->src.seqlo + 4710 (*state)->dst.max_win; 4711 (*state)->dst.seqhi = (*state)->dst.seqlo + 4712 (*state)->src.max_win; 4713 (*state)->src.wscale = (*state)->dst.wscale = 0; 4714 (*state)->src.state = (*state)->dst.state = 4715 TCPS_ESTABLISHED; 4716 REASON_SET(reason, PFRES_SYNPROXY); 4717 return (PF_SYNPROXY_DROP); 4718 } 4719 } 4720 4721 if (((th->th_flags & (TH_SYN|TH_ACK)) == TH_SYN) && 4722 dst->state >= TCPS_FIN_WAIT_2 && 4723 src->state >= TCPS_FIN_WAIT_2) { 4724#ifdef __FreeBSD__ 4725 if (V_pf_status.debug >= PF_DEBUG_MISC) { 4726#else 4727 if (pf_status.debug >= PF_DEBUG_MISC) { 4728#endif 4729 printf("pf: state reuse "); 4730 pf_print_state(*state); 4731 pf_print_flags(th->th_flags); 4732 printf("\n"); 4733 } 4734 /* XXX make sure it's the same direction ?? */ 4735 (*state)->src.state = (*state)->dst.state = TCPS_CLOSED; 4736 pf_unlink_state(*state); 4737 *state = NULL; 4738 return (PF_DROP); 4739 } 4740 4741 if ((*state)->state_flags & PFSTATE_SLOPPY) { 4742 if (pf_tcp_track_sloppy(src, dst, state, pd, reason) == PF_DROP) 4743 return (PF_DROP); 4744 } else { 4745 if (pf_tcp_track_full(src, dst, state, kif, m, off, pd, reason, 4746 ©back) == PF_DROP) 4747 return (PF_DROP); 4748 } 4749 4750 /* translate source/destination address, if necessary */ 4751 if ((*state)->key[PF_SK_WIRE] != (*state)->key[PF_SK_STACK]) { 4752 struct pf_state_key *nk = (*state)->key[pd->didx]; 4753 4754 if (PF_ANEQ(pd->src, &nk->addr[pd->sidx], pd->af) || 4755 nk->port[pd->sidx] != th->th_sport) 4756 pf_change_ap(pd->src, &th->th_sport, pd->ip_sum, 4757 &th->th_sum, &nk->addr[pd->sidx], 4758 nk->port[pd->sidx], 0, pd->af); 4759 4760 if (PF_ANEQ(pd->dst, &nk->addr[pd->didx], pd->af) || 4761 nk->port[pd->didx] != th->th_dport) 4762 pf_change_ap(pd->dst, &th->th_dport, pd->ip_sum, 4763 &th->th_sum, &nk->addr[pd->didx], 4764 nk->port[pd->didx], 0, pd->af); 4765 copyback = 1; 4766 } 4767 4768 /* Copyback sequence modulation or stateful scrub changes if needed */ 4769 if (copyback) 4770#ifdef __FreeBSD__ 4771 m_copyback(m, off, sizeof(*th), (caddr_t)th); 4772#else 4773 m_copyback(m, off, sizeof(*th), th); 4774#endif 4775 4776 return (PF_PASS); 4777} 4778 4779int 4780pf_test_state_udp(struct pf_state **state, int direction, struct pfi_kif *kif, 4781 struct mbuf *m, int off, void *h, struct pf_pdesc *pd) 4782{ 4783 struct pf_state_peer *src, *dst; 4784 struct pf_state_key_cmp key; 4785 struct udphdr *uh = pd->hdr.udp; 4786 4787 key.af = pd->af; 4788 key.proto = IPPROTO_UDP; 4789 if (direction == PF_IN) { /* wire side, straight */ 4790 PF_ACPY(&key.addr[0], pd->src, key.af); 4791 PF_ACPY(&key.addr[1], pd->dst, key.af); 4792 key.port[0] = uh->uh_sport; 4793 key.port[1] = uh->uh_dport; 4794 } else { /* stack side, reverse */ 4795 PF_ACPY(&key.addr[1], pd->src, key.af); 4796 PF_ACPY(&key.addr[0], pd->dst, key.af); 4797 key.port[1] = uh->uh_sport; 4798 key.port[0] = uh->uh_dport; 4799 } 4800 4801#ifdef __FreeBSD__ 4802 STATE_LOOKUP(kif, &key, direction, *state, m, pd->pf_mtag); 4803#else 4804 STATE_LOOKUP(kif, &key, direction, *state, m); 4805#endif 4806 4807 if (direction == (*state)->direction) { 4808 src = &(*state)->src; 4809 dst = &(*state)->dst; 4810 } else { 4811 src = &(*state)->dst; 4812 dst = &(*state)->src; 4813 } 4814 4815 /* update states */ 4816 if (src->state < PFUDPS_SINGLE) 4817 src->state = PFUDPS_SINGLE; 4818 if (dst->state == PFUDPS_SINGLE) 4819 dst->state = PFUDPS_MULTIPLE; 4820 4821 /* update expire time */ 4822 (*state)->expire = time_second; 4823 if (src->state == PFUDPS_MULTIPLE && dst->state == PFUDPS_MULTIPLE) 4824 (*state)->timeout = PFTM_UDP_MULTIPLE; 4825 else 4826 (*state)->timeout = PFTM_UDP_SINGLE; 4827 4828 /* translate source/destination address, if necessary */ 4829 if ((*state)->key[PF_SK_WIRE] != (*state)->key[PF_SK_STACK]) { 4830 struct pf_state_key *nk = (*state)->key[pd->didx]; 4831 4832 if (PF_ANEQ(pd->src, &nk->addr[pd->sidx], pd->af) || 4833 nk->port[pd->sidx] != uh->uh_sport) 4834 pf_change_ap(pd->src, &uh->uh_sport, pd->ip_sum, 4835 &uh->uh_sum, &nk->addr[pd->sidx], 4836 nk->port[pd->sidx], 1, pd->af); 4837 4838 if (PF_ANEQ(pd->dst, &nk->addr[pd->didx], pd->af) || 4839 nk->port[pd->didx] != uh->uh_dport) 4840 pf_change_ap(pd->dst, &uh->uh_dport, pd->ip_sum, 4841 &uh->uh_sum, &nk->addr[pd->didx], 4842 nk->port[pd->didx], 1, pd->af); 4843#ifdef __FreeBSD__ 4844 m_copyback(m, off, sizeof(*uh), (caddr_t)uh); 4845#else 4846 m_copyback(m, off, sizeof(*uh), uh); 4847#endif 4848 } 4849 4850 return (PF_PASS); 4851} 4852 4853int 4854pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, 4855 struct mbuf *m, int off, void *h, struct pf_pdesc *pd, u_short *reason) 4856{ 4857 struct pf_addr *saddr = pd->src, *daddr = pd->dst; 4858#ifdef __FreeBSD__ 4859 u_int16_t icmpid = 0, *icmpsum; 4860#else 4861 u_int16_t icmpid, *icmpsum; 4862#endif 4863 u_int8_t icmptype; 4864 int state_icmp = 0; 4865 struct pf_state_key_cmp key; 4866 4867 switch (pd->proto) { 4868#ifdef INET 4869 case IPPROTO_ICMP: 4870 icmptype = pd->hdr.icmp->icmp_type; 4871 icmpid = pd->hdr.icmp->icmp_id; 4872 icmpsum = &pd->hdr.icmp->icmp_cksum; 4873 4874 if (icmptype == ICMP_UNREACH || 4875 icmptype == ICMP_SOURCEQUENCH || 4876 icmptype == ICMP_REDIRECT || 4877 icmptype == ICMP_TIMXCEED || 4878 icmptype == ICMP_PARAMPROB) 4879 state_icmp++; 4880 break; 4881#endif /* INET */ 4882#ifdef INET6 4883 case IPPROTO_ICMPV6: 4884 icmptype = pd->hdr.icmp6->icmp6_type; 4885 icmpid = pd->hdr.icmp6->icmp6_id; 4886 icmpsum = &pd->hdr.icmp6->icmp6_cksum; 4887 4888 if (icmptype == ICMP6_DST_UNREACH || 4889 icmptype == ICMP6_PACKET_TOO_BIG || 4890 icmptype == ICMP6_TIME_EXCEEDED || 4891 icmptype == ICMP6_PARAM_PROB) 4892 state_icmp++; 4893 break; 4894#endif /* INET6 */ 4895 } 4896 4897 if (!state_icmp) { 4898 4899 /* 4900 * ICMP query/reply message not related to a TCP/UDP packet. 4901 * Search for an ICMP state. 4902 */ 4903 key.af = pd->af; 4904 key.proto = pd->proto; 4905 key.port[0] = key.port[1] = icmpid; 4906 if (direction == PF_IN) { /* wire side, straight */ 4907 PF_ACPY(&key.addr[0], pd->src, key.af); 4908 PF_ACPY(&key.addr[1], pd->dst, key.af); 4909 } else { /* stack side, reverse */ 4910 PF_ACPY(&key.addr[1], pd->src, key.af); 4911 PF_ACPY(&key.addr[0], pd->dst, key.af); 4912 } 4913 4914#ifdef __FreeBSD__ 4915 STATE_LOOKUP(kif, &key, direction, *state, m, pd->pf_mtag); 4916#else 4917 STATE_LOOKUP(kif, &key, direction, *state, m); 4918#endif 4919 4920 (*state)->expire = time_second; 4921 (*state)->timeout = PFTM_ICMP_ERROR_REPLY; 4922 4923 /* translate source/destination address, if necessary */ 4924 if ((*state)->key[PF_SK_WIRE] != (*state)->key[PF_SK_STACK]) { 4925 struct pf_state_key *nk = (*state)->key[pd->didx]; 4926 4927 switch (pd->af) { 4928#ifdef INET 4929 case AF_INET: 4930 if (PF_ANEQ(pd->src, 4931 &nk->addr[pd->sidx], AF_INET)) 4932 pf_change_a(&saddr->v4.s_addr, 4933 pd->ip_sum, 4934 nk->addr[pd->sidx].v4.s_addr, 0); 4935 4936 if (PF_ANEQ(pd->dst, &nk->addr[pd->didx], 4937 AF_INET)) 4938 pf_change_a(&daddr->v4.s_addr, 4939 pd->ip_sum, 4940 nk->addr[pd->didx].v4.s_addr, 0); 4941 4942 if (nk->port[0] != 4943 pd->hdr.icmp->icmp_id) { 4944 pd->hdr.icmp->icmp_cksum = 4945 pf_cksum_fixup( 4946 pd->hdr.icmp->icmp_cksum, icmpid, 4947 nk->port[pd->sidx], 0); 4948 pd->hdr.icmp->icmp_id = 4949 nk->port[pd->sidx]; 4950 } 4951 4952 m_copyback(m, off, ICMP_MINLEN, 4953#ifdef __FreeBSD__ 4954 (caddr_t) 4955#endif 4956 pd->hdr.icmp); 4957 break; 4958#endif /* INET */ 4959#ifdef INET6 4960 case AF_INET6: 4961 if (PF_ANEQ(pd->src, 4962 &nk->addr[pd->sidx], AF_INET6)) 4963 pf_change_a6(saddr, 4964 &pd->hdr.icmp6->icmp6_cksum, 4965 &nk->addr[pd->sidx], 0); 4966 4967 if (PF_ANEQ(pd->dst, 4968 &nk->addr[pd->didx], AF_INET6)) 4969 pf_change_a6(daddr, 4970 &pd->hdr.icmp6->icmp6_cksum, 4971 &nk->addr[pd->didx], 0); 4972 4973 m_copyback(m, off, 4974 sizeof(struct icmp6_hdr), 4975#ifdef __FreeBSD__ 4976 (caddr_t) 4977#endif 4978 pd->hdr.icmp6); 4979 break; 4980#endif /* INET6 */ 4981 } 4982 } 4983 return (PF_PASS); 4984 4985 } else { 4986 /* 4987 * ICMP error message in response to a TCP/UDP packet. 4988 * Extract the inner TCP/UDP header and search for that state. 4989 */ 4990 4991 struct pf_pdesc pd2; 4992#ifdef __FreeBSD__ 4993 bzero(&pd2, sizeof pd2); 4994#endif 4995#ifdef INET 4996 struct ip h2; 4997#endif /* INET */ 4998#ifdef INET6 4999 struct ip6_hdr h2_6; 5000 int terminal = 0; 5001#endif /* INET6 */ 5002#ifdef __FreeBSD__ 5003 int ipoff2 = 0; 5004 int off2 = 0; 5005#else 5006 int ipoff2; 5007 int off2; 5008#endif 5009 5010 pd2.af = pd->af; 5011 /* Payload packet is from the opposite direction. */ 5012 pd2.sidx = (direction == PF_IN) ? 1 : 0; 5013 pd2.didx = (direction == PF_IN) ? 0 : 1; 5014 switch (pd->af) { 5015#ifdef INET 5016 case AF_INET: 5017 /* offset of h2 in mbuf chain */ 5018 ipoff2 = off + ICMP_MINLEN; 5019 5020 if (!pf_pull_hdr(m, ipoff2, &h2, sizeof(h2), 5021 NULL, reason, pd2.af)) { 5022 DPFPRINTF(PF_DEBUG_MISC, 5023 ("pf: ICMP error message too short " 5024 "(ip)\n")); 5025 return (PF_DROP); 5026 } 5027 /* 5028 * ICMP error messages don't refer to non-first 5029 * fragments 5030 */ 5031 if (h2.ip_off & htons(IP_OFFMASK)) { 5032 REASON_SET(reason, PFRES_FRAG); 5033 return (PF_DROP); 5034 } 5035 5036 /* offset of protocol header that follows h2 */ 5037 off2 = ipoff2 + (h2.ip_hl << 2); 5038 5039 pd2.proto = h2.ip_p; 5040 pd2.src = (struct pf_addr *)&h2.ip_src; 5041 pd2.dst = (struct pf_addr *)&h2.ip_dst; 5042 pd2.ip_sum = &h2.ip_sum; 5043 break; 5044#endif /* INET */ 5045#ifdef INET6 5046 case AF_INET6: 5047 ipoff2 = off + sizeof(struct icmp6_hdr); 5048 5049 if (!pf_pull_hdr(m, ipoff2, &h2_6, sizeof(h2_6), 5050 NULL, reason, pd2.af)) { 5051 DPFPRINTF(PF_DEBUG_MISC, 5052 ("pf: ICMP error message too short " 5053 "(ip6)\n")); 5054 return (PF_DROP); 5055 } 5056 pd2.proto = h2_6.ip6_nxt; 5057 pd2.src = (struct pf_addr *)&h2_6.ip6_src; 5058 pd2.dst = (struct pf_addr *)&h2_6.ip6_dst; 5059 pd2.ip_sum = NULL; 5060 off2 = ipoff2 + sizeof(h2_6); 5061 do { 5062 switch (pd2.proto) { 5063 case IPPROTO_FRAGMENT: 5064 /* 5065 * ICMPv6 error messages for 5066 * non-first fragments 5067 */ 5068 REASON_SET(reason, PFRES_FRAG); 5069 return (PF_DROP); 5070 case IPPROTO_AH: 5071 case IPPROTO_HOPOPTS: 5072 case IPPROTO_ROUTING: 5073 case IPPROTO_DSTOPTS: { 5074 /* get next header and header length */ 5075 struct ip6_ext opt6; 5076 5077 if (!pf_pull_hdr(m, off2, &opt6, 5078 sizeof(opt6), NULL, reason, 5079 pd2.af)) { 5080 DPFPRINTF(PF_DEBUG_MISC, 5081 ("pf: ICMPv6 short opt\n")); 5082 return (PF_DROP); 5083 } 5084 if (pd2.proto == IPPROTO_AH) 5085 off2 += (opt6.ip6e_len + 2) * 4; 5086 else 5087 off2 += (opt6.ip6e_len + 1) * 8; 5088 pd2.proto = opt6.ip6e_nxt; 5089 /* goto the next header */ 5090 break; 5091 } 5092 default: 5093 terminal++; 5094 break; 5095 } 5096 } while (!terminal); 5097 break; 5098#endif /* INET6 */ 5099 } 5100 5101 switch (pd2.proto) { 5102 case IPPROTO_TCP: { 5103 struct tcphdr th; 5104 u_int32_t seq; 5105 struct pf_state_peer *src, *dst; 5106 u_int8_t dws; 5107 int copyback = 0; 5108 5109 /* 5110 * Only the first 8 bytes of the TCP header can be 5111 * expected. Don't access any TCP header fields after 5112 * th_seq, an ackskew test is not possible. 5113 */ 5114 if (!pf_pull_hdr(m, off2, &th, 8, NULL, reason, 5115 pd2.af)) { 5116 DPFPRINTF(PF_DEBUG_MISC, 5117 ("pf: ICMP error message too short " 5118 "(tcp)\n")); 5119 return (PF_DROP); 5120 } 5121 5122 key.af = pd2.af; 5123 key.proto = IPPROTO_TCP; 5124 PF_ACPY(&key.addr[pd2.sidx], pd2.src, key.af); 5125 PF_ACPY(&key.addr[pd2.didx], pd2.dst, key.af); 5126 key.port[pd2.sidx] = th.th_sport; 5127 key.port[pd2.didx] = th.th_dport; 5128 5129#ifdef __FreeBSD__ 5130 STATE_LOOKUP(kif, &key, direction, *state, m, pd->pf_mtag); 5131#else 5132 STATE_LOOKUP(kif, &key, direction, *state, m); 5133#endif 5134 5135 if (direction == (*state)->direction) { 5136 src = &(*state)->dst; 5137 dst = &(*state)->src; 5138 } else { 5139 src = &(*state)->src; 5140 dst = &(*state)->dst; 5141 } 5142 5143 if (src->wscale && dst->wscale) 5144 dws = dst->wscale & PF_WSCALE_MASK; 5145 else 5146 dws = 0; 5147 5148 /* Demodulate sequence number */ 5149 seq = ntohl(th.th_seq) - src->seqdiff; 5150 if (src->seqdiff) { 5151 pf_change_a(&th.th_seq, icmpsum, 5152 htonl(seq), 0); 5153 copyback = 1; 5154 } 5155 5156 if (!((*state)->state_flags & PFSTATE_SLOPPY) && 5157 (!SEQ_GEQ(src->seqhi, seq) || 5158 !SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)))) { 5159#ifdef __FreeBSD__ 5160 if (V_pf_status.debug >= PF_DEBUG_MISC) { 5161#else 5162 if (pf_status.debug >= PF_DEBUG_MISC) { 5163#endif 5164 printf("pf: BAD ICMP %d:%d ", 5165 icmptype, pd->hdr.icmp->icmp_code); 5166 pf_print_host(pd->src, 0, pd->af); 5167 printf(" -> "); 5168 pf_print_host(pd->dst, 0, pd->af); 5169 printf(" state: "); 5170 pf_print_state(*state); 5171 printf(" seq=%u\n", seq); 5172 } 5173 REASON_SET(reason, PFRES_BADSTATE); 5174 return (PF_DROP); 5175 } else { 5176#ifdef __FreeBSD__ 5177 if (V_pf_status.debug >= PF_DEBUG_MISC) { 5178#else 5179 if (pf_status.debug >= PF_DEBUG_MISC) { 5180#endif 5181 printf("pf: OK ICMP %d:%d ", 5182 icmptype, pd->hdr.icmp->icmp_code); 5183 pf_print_host(pd->src, 0, pd->af); 5184 printf(" -> "); 5185 pf_print_host(pd->dst, 0, pd->af); 5186 printf(" state: "); 5187 pf_print_state(*state); 5188 printf(" seq=%u\n", seq); 5189 } 5190 } 5191 5192 /* translate source/destination address, if necessary */ 5193 if ((*state)->key[PF_SK_WIRE] != 5194 (*state)->key[PF_SK_STACK]) { 5195 struct pf_state_key *nk = 5196 (*state)->key[pd->didx]; 5197 5198 if (PF_ANEQ(pd2.src, 5199 &nk->addr[pd2.sidx], pd2.af) || 5200 nk->port[pd2.sidx] != th.th_sport) 5201 pf_change_icmp(pd2.src, &th.th_sport, 5202 daddr, &nk->addr[pd2.sidx], 5203 nk->port[pd2.sidx], NULL, 5204 pd2.ip_sum, icmpsum, 5205 pd->ip_sum, 0, pd2.af); 5206 5207 if (PF_ANEQ(pd2.dst, 5208 &nk->addr[pd2.didx], pd2.af) || 5209 nk->port[pd2.didx] != th.th_dport) 5210 pf_change_icmp(pd2.dst, &th.th_dport, 5211 NULL, /* XXX Inbound NAT? */ 5212 &nk->addr[pd2.didx], 5213 nk->port[pd2.didx], NULL, 5214 pd2.ip_sum, icmpsum, 5215 pd->ip_sum, 0, pd2.af); 5216 copyback = 1; 5217 } 5218 5219 if (copyback) { 5220 switch (pd2.af) { 5221#ifdef INET 5222 case AF_INET: 5223 m_copyback(m, off, ICMP_MINLEN, 5224#ifdef __FreeBSD__ 5225 (caddr_t) 5226#endif 5227 pd->hdr.icmp); 5228 m_copyback(m, ipoff2, sizeof(h2), 5229#ifdef __FreeBSD__ 5230 (caddr_t) 5231#endif 5232 &h2); 5233 break; 5234#endif /* INET */ 5235#ifdef INET6 5236 case AF_INET6: 5237 m_copyback(m, off, 5238 sizeof(struct icmp6_hdr), 5239#ifdef __FreeBSD__ 5240 (caddr_t) 5241#endif 5242 pd->hdr.icmp6); 5243 m_copyback(m, ipoff2, sizeof(h2_6), 5244#ifdef __FreeBSD__ 5245 (caddr_t) 5246#endif 5247 &h2_6); 5248 break; 5249#endif /* INET6 */ 5250 } 5251#ifdef __FreeBSD__ 5252 m_copyback(m, off2, 8, (caddr_t)&th); 5253#else 5254 m_copyback(m, off2, 8, &th); 5255#endif 5256 } 5257 5258 return (PF_PASS); 5259 break; 5260 } 5261 case IPPROTO_UDP: { 5262 struct udphdr uh; 5263 5264 if (!pf_pull_hdr(m, off2, &uh, sizeof(uh), 5265 NULL, reason, pd2.af)) { 5266 DPFPRINTF(PF_DEBUG_MISC, 5267 ("pf: ICMP error message too short " 5268 "(udp)\n")); 5269 return (PF_DROP); 5270 } 5271 5272 key.af = pd2.af; 5273 key.proto = IPPROTO_UDP; 5274 PF_ACPY(&key.addr[pd2.sidx], pd2.src, key.af); 5275 PF_ACPY(&key.addr[pd2.didx], pd2.dst, key.af); 5276 key.port[pd2.sidx] = uh.uh_sport; 5277 key.port[pd2.didx] = uh.uh_dport; 5278 5279#ifdef __FreeBSD__ 5280 STATE_LOOKUP(kif, &key, direction, *state, m, pd->pf_mtag); 5281#else 5282 STATE_LOOKUP(kif, &key, direction, *state, m); 5283#endif 5284 5285 /* translate source/destination address, if necessary */ 5286 if ((*state)->key[PF_SK_WIRE] != 5287 (*state)->key[PF_SK_STACK]) { 5288 struct pf_state_key *nk = 5289 (*state)->key[pd->didx]; 5290 5291 if (PF_ANEQ(pd2.src, 5292 &nk->addr[pd2.sidx], pd2.af) || 5293 nk->port[pd2.sidx] != uh.uh_sport) 5294 pf_change_icmp(pd2.src, &uh.uh_sport, 5295 daddr, &nk->addr[pd2.sidx], 5296 nk->port[pd2.sidx], &uh.uh_sum, 5297 pd2.ip_sum, icmpsum, 5298 pd->ip_sum, 1, pd2.af); 5299 5300 if (PF_ANEQ(pd2.dst, 5301 &nk->addr[pd2.didx], pd2.af) || 5302 nk->port[pd2.didx] != uh.uh_dport) 5303 pf_change_icmp(pd2.dst, &uh.uh_dport, 5304 NULL, /* XXX Inbound NAT? */ 5305 &nk->addr[pd2.didx], 5306 nk->port[pd2.didx], &uh.uh_sum, 5307 pd2.ip_sum, icmpsum, 5308 pd->ip_sum, 1, pd2.af); 5309 5310 switch (pd2.af) { 5311#ifdef INET 5312 case AF_INET: 5313 m_copyback(m, off, ICMP_MINLEN, 5314#ifdef __FreeBSD__ 5315 (caddr_t) 5316#endif 5317 pd->hdr.icmp); 5318#ifdef __FreeBSD__ 5319 m_copyback(m, ipoff2, sizeof(h2), (caddr_t)&h2); 5320#else 5321 m_copyback(m, ipoff2, sizeof(h2), &h2); 5322#endif 5323 break; 5324#endif /* INET */ 5325#ifdef INET6 5326 case AF_INET6: 5327 m_copyback(m, off, 5328 sizeof(struct icmp6_hdr), 5329#ifdef __FreeBSD__ 5330 (caddr_t) 5331#endif 5332 pd->hdr.icmp6); 5333 m_copyback(m, ipoff2, sizeof(h2_6), 5334#ifdef __FreeBSD__ 5335 (caddr_t) 5336#endif 5337 &h2_6); 5338 break; 5339#endif /* INET6 */ 5340 } 5341#ifdef __FreeBSD__ 5342 m_copyback(m, off2, sizeof(uh), (caddr_t)&uh); 5343#else 5344 m_copyback(m, off2, sizeof(uh), &uh); 5345#endif 5346 } 5347 return (PF_PASS); 5348 break; 5349 } 5350#ifdef INET 5351 case IPPROTO_ICMP: { 5352 struct icmp iih; 5353 5354 if (!pf_pull_hdr(m, off2, &iih, ICMP_MINLEN, 5355 NULL, reason, pd2.af)) { 5356 DPFPRINTF(PF_DEBUG_MISC, 5357 ("pf: ICMP error message too short i" 5358 "(icmp)\n")); 5359 return (PF_DROP); 5360 } 5361 5362 key.af = pd2.af; 5363 key.proto = IPPROTO_ICMP; 5364 PF_ACPY(&key.addr[pd2.sidx], pd2.src, key.af); 5365 PF_ACPY(&key.addr[pd2.didx], pd2.dst, key.af); 5366 key.port[0] = key.port[1] = iih.icmp_id; 5367 5368#ifdef __FreeBSD__ 5369 STATE_LOOKUP(kif, &key, direction, *state, m, pd->pf_mtag); 5370#else 5371 STATE_LOOKUP(kif, &key, direction, *state, m); 5372#endif 5373 5374 /* translate source/destination address, if necessary */ 5375 if ((*state)->key[PF_SK_WIRE] != 5376 (*state)->key[PF_SK_STACK]) { 5377 struct pf_state_key *nk = 5378 (*state)->key[pd->didx]; 5379 5380 if (PF_ANEQ(pd2.src, 5381 &nk->addr[pd2.sidx], pd2.af) || 5382 nk->port[pd2.sidx] != iih.icmp_id) 5383 pf_change_icmp(pd2.src, &iih.icmp_id, 5384 daddr, &nk->addr[pd2.sidx], 5385 nk->port[pd2.sidx], NULL, 5386 pd2.ip_sum, icmpsum, 5387 pd->ip_sum, 0, AF_INET); 5388 5389 if (PF_ANEQ(pd2.dst, 5390 &nk->addr[pd2.didx], pd2.af) || 5391 nk->port[pd2.didx] != iih.icmp_id) 5392 pf_change_icmp(pd2.dst, &iih.icmp_id, 5393 NULL, /* XXX Inbound NAT? */ 5394 &nk->addr[pd2.didx], 5395 nk->port[pd2.didx], NULL, 5396 pd2.ip_sum, icmpsum, 5397 pd->ip_sum, 0, AF_INET); 5398 5399#ifdef __FreeBSD__ 5400 m_copyback(m, off, ICMP_MINLEN, (caddr_t)pd->hdr.icmp); 5401 m_copyback(m, ipoff2, sizeof(h2), (caddr_t)&h2); 5402 m_copyback(m, off2, ICMP_MINLEN, (caddr_t)&iih); 5403#else 5404 m_copyback(m, off, ICMP_MINLEN, pd->hdr.icmp); 5405 m_copyback(m, ipoff2, sizeof(h2), &h2); 5406 m_copyback(m, off2, ICMP_MINLEN, &iih); 5407#endif 5408 } 5409 return (PF_PASS); 5410 break; 5411 } 5412#endif /* INET */ 5413#ifdef INET6 5414 case IPPROTO_ICMPV6: { 5415 struct icmp6_hdr iih; 5416 5417 if (!pf_pull_hdr(m, off2, &iih, 5418 sizeof(struct icmp6_hdr), NULL, reason, pd2.af)) { 5419 DPFPRINTF(PF_DEBUG_MISC, 5420 ("pf: ICMP error message too short " 5421 "(icmp6)\n")); 5422 return (PF_DROP); 5423 } 5424 5425 key.af = pd2.af; 5426 key.proto = IPPROTO_ICMPV6; 5427 PF_ACPY(&key.addr[pd2.sidx], pd2.src, key.af); 5428 PF_ACPY(&key.addr[pd2.didx], pd2.dst, key.af); 5429 key.port[0] = key.port[1] = iih.icmp6_id; 5430 5431#ifdef __FreeBSD__ 5432 STATE_LOOKUP(kif, &key, direction, *state, m, pd->pf_mtag); 5433#else 5434 STATE_LOOKUP(kif, &key, direction, *state, m); 5435#endif 5436 5437 /* translate source/destination address, if necessary */ 5438 if ((*state)->key[PF_SK_WIRE] != 5439 (*state)->key[PF_SK_STACK]) { 5440 struct pf_state_key *nk = 5441 (*state)->key[pd->didx]; 5442 5443 if (PF_ANEQ(pd2.src, 5444 &nk->addr[pd2.sidx], pd2.af) || 5445 nk->port[pd2.sidx] != iih.icmp6_id) 5446 pf_change_icmp(pd2.src, &iih.icmp6_id, 5447 daddr, &nk->addr[pd2.sidx], 5448 nk->port[pd2.sidx], NULL, 5449 pd2.ip_sum, icmpsum, 5450 pd->ip_sum, 0, AF_INET6); 5451 5452 if (PF_ANEQ(pd2.dst, 5453 &nk->addr[pd2.didx], pd2.af) || 5454 nk->port[pd2.didx] != iih.icmp6_id) 5455 pf_change_icmp(pd2.dst, &iih.icmp6_id, 5456 NULL, /* XXX Inbound NAT? */ 5457 &nk->addr[pd2.didx], 5458 nk->port[pd2.didx], NULL, 5459 pd2.ip_sum, icmpsum, 5460 pd->ip_sum, 0, AF_INET6); 5461 5462#ifdef __FreeBSD__ 5463 m_copyback(m, off, sizeof(struct icmp6_hdr), 5464 (caddr_t)pd->hdr.icmp6); 5465 m_copyback(m, ipoff2, sizeof(h2_6), (caddr_t)&h2_6); 5466 m_copyback(m, off2, sizeof(struct icmp6_hdr), 5467 (caddr_t)&iih); 5468#else 5469 m_copyback(m, off, sizeof(struct icmp6_hdr), 5470 pd->hdr.icmp6); 5471 m_copyback(m, ipoff2, sizeof(h2_6), &h2_6); 5472 m_copyback(m, off2, sizeof(struct icmp6_hdr), 5473 &iih); 5474#endif 5475 } 5476 return (PF_PASS); 5477 break; 5478 } 5479#endif /* INET6 */ 5480 default: { 5481 key.af = pd2.af; 5482 key.proto = pd2.proto; 5483 PF_ACPY(&key.addr[pd2.sidx], pd2.src, key.af); 5484 PF_ACPY(&key.addr[pd2.didx], pd2.dst, key.af); 5485 key.port[0] = key.port[1] = 0; 5486 5487#ifdef __FreeBSD__ 5488 STATE_LOOKUP(kif, &key, direction, *state, m, pd->pf_mtag); 5489#else 5490 STATE_LOOKUP(kif, &key, direction, *state, m); 5491#endif 5492 5493 /* translate source/destination address, if necessary */ 5494 if ((*state)->key[PF_SK_WIRE] != 5495 (*state)->key[PF_SK_STACK]) { 5496 struct pf_state_key *nk = 5497 (*state)->key[pd->didx]; 5498 5499 if (PF_ANEQ(pd2.src, 5500 &nk->addr[pd2.sidx], pd2.af)) 5501 pf_change_icmp(pd2.src, NULL, daddr, 5502 &nk->addr[pd2.sidx], 0, NULL, 5503 pd2.ip_sum, icmpsum, 5504 pd->ip_sum, 0, pd2.af); 5505 5506 if (PF_ANEQ(pd2.dst, 5507 &nk->addr[pd2.didx], pd2.af)) 5508 pf_change_icmp(pd2.src, NULL, 5509 NULL, /* XXX Inbound NAT? */ 5510 &nk->addr[pd2.didx], 0, NULL, 5511 pd2.ip_sum, icmpsum, 5512 pd->ip_sum, 0, pd2.af); 5513 5514 switch (pd2.af) { 5515#ifdef INET 5516 case AF_INET: 5517#ifdef __FreeBSD__ 5518 m_copyback(m, off, ICMP_MINLEN, 5519 (caddr_t)pd->hdr.icmp); 5520 m_copyback(m, ipoff2, sizeof(h2), (caddr_t)&h2); 5521#else 5522 m_copyback(m, off, ICMP_MINLEN, 5523 pd->hdr.icmp); 5524 m_copyback(m, ipoff2, sizeof(h2), &h2); 5525#endif 5526 break; 5527#endif /* INET */ 5528#ifdef INET6 5529 case AF_INET6: 5530 m_copyback(m, off, 5531 sizeof(struct icmp6_hdr), 5532#ifdef __FreeBSD__ 5533 (caddr_t) 5534#endif 5535 pd->hdr.icmp6); 5536 m_copyback(m, ipoff2, sizeof(h2_6), 5537#ifdef __FreeBSD__ 5538 (caddr_t) 5539#endif 5540 &h2_6); 5541 break; 5542#endif /* INET6 */ 5543 } 5544 } 5545 return (PF_PASS); 5546 break; 5547 } 5548 } 5549 } 5550} 5551 5552int 5553pf_test_state_other(struct pf_state **state, int direction, struct pfi_kif *kif, 5554 struct mbuf *m, struct pf_pdesc *pd) 5555{ 5556 struct pf_state_peer *src, *dst; 5557 struct pf_state_key_cmp key; 5558 5559 key.af = pd->af; 5560 key.proto = pd->proto; 5561 if (direction == PF_IN) { 5562 PF_ACPY(&key.addr[0], pd->src, key.af); 5563 PF_ACPY(&key.addr[1], pd->dst, key.af); 5564 key.port[0] = key.port[1] = 0; 5565 } else { 5566 PF_ACPY(&key.addr[1], pd->src, key.af); 5567 PF_ACPY(&key.addr[0], pd->dst, key.af); 5568 key.port[1] = key.port[0] = 0; 5569 } 5570 5571#ifdef __FreeBSD__ 5572 STATE_LOOKUP(kif, &key, direction, *state, m, pd->pf_mtag); 5573#else 5574 STATE_LOOKUP(kif, &key, direction, *state, m); 5575#endif 5576 5577 if (direction == (*state)->direction) { 5578 src = &(*state)->src; 5579 dst = &(*state)->dst; 5580 } else { 5581 src = &(*state)->dst; 5582 dst = &(*state)->src; 5583 } 5584 5585 /* update states */ 5586 if (src->state < PFOTHERS_SINGLE) 5587 src->state = PFOTHERS_SINGLE; 5588 if (dst->state == PFOTHERS_SINGLE) 5589 dst->state = PFOTHERS_MULTIPLE; 5590 5591 /* update expire time */ 5592 (*state)->expire = time_second; 5593 if (src->state == PFOTHERS_MULTIPLE && dst->state == PFOTHERS_MULTIPLE) 5594 (*state)->timeout = PFTM_OTHER_MULTIPLE; 5595 else 5596 (*state)->timeout = PFTM_OTHER_SINGLE; 5597 5598 /* translate source/destination address, if necessary */ 5599 if ((*state)->key[PF_SK_WIRE] != (*state)->key[PF_SK_STACK]) { 5600 struct pf_state_key *nk = (*state)->key[pd->didx]; 5601 5602#ifdef __FreeBSD__ 5603 KASSERT(nk, ("%s: nk is null", __FUNCTION__)); 5604 KASSERT(pd, ("%s: pd is null", __FUNCTION__)); 5605 KASSERT(pd->src, ("%s: pd->src is null", __FUNCTION__)); 5606 KASSERT(pd->dst, ("%s: pd->dst is null", __FUNCTION__)); 5607#else 5608 KASSERT(nk); 5609 KASSERT(pd); 5610 KASSERT(pd->src); 5611 KASSERT(pd->dst); 5612#endif 5613 switch (pd->af) { 5614#ifdef INET 5615 case AF_INET: 5616 if (PF_ANEQ(pd->src, &nk->addr[pd->sidx], AF_INET)) 5617 pf_change_a(&pd->src->v4.s_addr, 5618 pd->ip_sum, 5619 nk->addr[pd->sidx].v4.s_addr, 5620 0); 5621 5622 5623 if (PF_ANEQ(pd->dst, &nk->addr[pd->didx], AF_INET)) 5624 pf_change_a(&pd->dst->v4.s_addr, 5625 pd->ip_sum, 5626 nk->addr[pd->didx].v4.s_addr, 5627 0); 5628 5629 break; 5630#endif /* INET */ 5631#ifdef INET6 5632 case AF_INET6: 5633 if (PF_ANEQ(pd->src, &nk->addr[pd->sidx], AF_INET)) 5634 PF_ACPY(pd->src, &nk->addr[pd->sidx], pd->af); 5635 5636 if (PF_ANEQ(pd->dst, &nk->addr[pd->didx], AF_INET)) 5637 PF_ACPY(pd->dst, &nk->addr[pd->didx], pd->af); 5638#endif /* INET6 */ 5639 } 5640 } 5641 return (PF_PASS); 5642} 5643 5644/* 5645 * ipoff and off are measured from the start of the mbuf chain. 5646 * h must be at "ipoff" on the mbuf chain. 5647 */ 5648void * 5649pf_pull_hdr(struct mbuf *m, int off, void *p, int len, 5650 u_short *actionp, u_short *reasonp, sa_family_t af) 5651{ 5652 switch (af) { 5653#ifdef INET 5654 case AF_INET: { 5655 struct ip *h = mtod(m, struct ip *); 5656 u_int16_t fragoff = (ntohs(h->ip_off) & IP_OFFMASK) << 3; 5657 5658 if (fragoff) { 5659 if (fragoff >= len) 5660 ACTION_SET(actionp, PF_PASS); 5661 else { 5662 ACTION_SET(actionp, PF_DROP); 5663 REASON_SET(reasonp, PFRES_FRAG); 5664 } 5665 return (NULL); 5666 } 5667 if (m->m_pkthdr.len < off + len || 5668 ntohs(h->ip_len) < off + len) { 5669 ACTION_SET(actionp, PF_DROP); 5670 REASON_SET(reasonp, PFRES_SHORT); 5671 return (NULL); 5672 } 5673 break; 5674 } 5675#endif /* INET */ 5676#ifdef INET6 5677 case AF_INET6: { 5678 struct ip6_hdr *h = mtod(m, struct ip6_hdr *); 5679 5680 if (m->m_pkthdr.len < off + len || 5681 (ntohs(h->ip6_plen) + sizeof(struct ip6_hdr)) < 5682 (unsigned)(off + len)) { 5683 ACTION_SET(actionp, PF_DROP); 5684 REASON_SET(reasonp, PFRES_SHORT); 5685 return (NULL); 5686 } 5687 break; 5688 } 5689#endif /* INET6 */ 5690 } 5691 m_copydata(m, off, len, p); 5692 return (p); 5693} 5694 5695int 5696pf_routable(struct pf_addr *addr, sa_family_t af, struct pfi_kif *kif) 5697{ 5698#ifdef __FreeBSD__ 5699#ifdef RADIX_MPATH 5700 struct radix_node_head *rnh; 5701#endif 5702#endif 5703 struct sockaddr_in *dst; 5704 int ret = 1; 5705 int check_mpath; 5706#ifndef __FreeBSD__ 5707 extern int ipmultipath; 5708#endif 5709#ifdef INET6 5710#ifndef __FreeBSD__ 5711 extern int ip6_multipath; 5712#endif 5713 struct sockaddr_in6 *dst6; 5714 struct route_in6 ro; 5715#else 5716 struct route ro; 5717#endif 5718 struct radix_node *rn; 5719 struct rtentry *rt; 5720 struct ifnet *ifp; 5721 5722 check_mpath = 0; 5723#ifdef __FreeBSD__ 5724#ifdef RADIX_MPATH 5725 /* XXX: stick to table 0 for now */ 5726 rnh = rt_tables_get_rnh(0, af); 5727 if (rnh != NULL && rn_mpath_capable(rnh)) 5728 check_mpath = 1; 5729#endif 5730#endif 5731 bzero(&ro, sizeof(ro)); 5732 switch (af) { 5733 case AF_INET: 5734 dst = satosin(&ro.ro_dst); 5735 dst->sin_family = AF_INET; 5736 dst->sin_len = sizeof(*dst); 5737 dst->sin_addr = addr->v4; 5738#ifndef __FreeBSD__ 5739 if (ipmultipath) 5740 check_mpath = 1; 5741#endif 5742 break; 5743#ifdef INET6 5744 case AF_INET6: 5745 /* 5746 * Skip check for addresses with embedded interface scope, 5747 * as they would always match anyway. 5748 */ 5749 if (IN6_IS_SCOPE_EMBED(&addr->v6)) 5750 goto out; 5751 dst6 = (struct sockaddr_in6 *)&ro.ro_dst; 5752 dst6->sin6_family = AF_INET6; 5753 dst6->sin6_len = sizeof(*dst6); 5754 dst6->sin6_addr = addr->v6; 5755#ifndef __FreeBSD__ 5756 if (ip6_multipath) 5757 check_mpath = 1; 5758#endif 5759 break; 5760#endif /* INET6 */ 5761 default: 5762 return (0); 5763 } 5764 5765 /* Skip checks for ipsec interfaces */ 5766 if (kif != NULL && kif->pfik_ifp->if_type == IFT_ENC) 5767 goto out; 5768 5769#ifdef __FreeBSD__ 5770/* XXX MRT not always INET */ /* stick with table 0 though */ 5771#ifdef INET 5772 if (af == AF_INET) 5773 in_rtalloc_ign((struct route *)&ro, 0, 0); 5774 else 5775#endif 5776 rtalloc_ign((struct route *)&ro, 0); 5777#else /* ! __FreeBSD__ */ 5778 rtalloc_noclone((struct route *)&ro, NO_CLONING); 5779#endif 5780 5781 if (ro.ro_rt != NULL) { 5782 /* No interface given, this is a no-route check */ 5783 if (kif == NULL) 5784 goto out; 5785 5786 if (kif->pfik_ifp == NULL) { 5787 ret = 0; 5788 goto out; 5789 } 5790 5791 /* Perform uRPF check if passed input interface */ 5792 ret = 0; 5793 rn = (struct radix_node *)ro.ro_rt; 5794 do { 5795 rt = (struct rtentry *)rn; 5796#ifndef __FreeBSD__ /* CARPDEV */ 5797 if (rt->rt_ifp->if_type == IFT_CARP) 5798 ifp = rt->rt_ifp->if_carpdev; 5799 else 5800#endif 5801 ifp = rt->rt_ifp; 5802 5803 if (kif->pfik_ifp == ifp) 5804 ret = 1; 5805#ifdef __FreeBSD__ 5806#ifdef RADIX_MPATH 5807 rn = rn_mpath_next(rn); 5808#endif 5809#else 5810 rn = rn_mpath_next(rn, 0); 5811#endif 5812 } while (check_mpath == 1 && rn != NULL && ret == 0); 5813 } else 5814 ret = 0; 5815out: 5816 if (ro.ro_rt != NULL) 5817 RTFREE(ro.ro_rt); 5818 return (ret); 5819} 5820 5821int 5822pf_rtlabel_match(struct pf_addr *addr, sa_family_t af, struct pf_addr_wrap *aw) 5823{ 5824 struct sockaddr_in *dst; 5825#ifdef INET6 5826 struct sockaddr_in6 *dst6; 5827 struct route_in6 ro; 5828#else 5829 struct route ro; 5830#endif 5831 int ret = 0; 5832 5833 bzero(&ro, sizeof(ro)); 5834 switch (af) { 5835 case AF_INET: 5836 dst = satosin(&ro.ro_dst); 5837 dst->sin_family = AF_INET; 5838 dst->sin_len = sizeof(*dst); 5839 dst->sin_addr = addr->v4; 5840 break; 5841#ifdef INET6 5842 case AF_INET6: 5843 dst6 = (struct sockaddr_in6 *)&ro.ro_dst; 5844 dst6->sin6_family = AF_INET6; 5845 dst6->sin6_len = sizeof(*dst6); 5846 dst6->sin6_addr = addr->v6; 5847 break; 5848#endif /* INET6 */ 5849 default: 5850 return (0); 5851 } 5852 5853#ifdef __FreeBSD__ 5854# ifdef RTF_PRCLONING 5855 rtalloc_ign((struct route *)&ro, (RTF_CLONING|RTF_PRCLONING)); 5856# else /* !RTF_PRCLONING */ 5857#ifdef INET 5858 if (af == AF_INET) 5859 in_rtalloc_ign((struct route *)&ro, 0, 0); 5860 else 5861#endif 5862 rtalloc_ign((struct route *)&ro, 0); 5863# endif 5864#else /* ! __FreeBSD__ */ 5865 rtalloc_noclone((struct route *)&ro, NO_CLONING); 5866#endif 5867 5868 if (ro.ro_rt != NULL) { 5869#ifdef __FreeBSD__ 5870 /* XXX_IMPORT: later */ 5871#else 5872 if (ro.ro_rt->rt_labelid == aw->v.rtlabel) 5873 ret = 1; 5874#endif 5875 RTFREE(ro.ro_rt); 5876 } 5877 5878 return (ret); 5879} 5880 5881#ifdef INET 5882void 5883pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, 5884 struct pf_state *s, struct pf_pdesc *pd) 5885{ 5886 struct mbuf *m0, *m1; 5887 struct route iproute; 5888 struct route *ro = NULL; 5889 struct sockaddr_in *dst; 5890 struct ip *ip; 5891 struct ifnet *ifp = NULL; 5892 struct pf_addr naddr; 5893 struct pf_src_node *sn = NULL; 5894 int error = 0; 5895#ifdef __FreeBSD__ 5896 int sw_csum; 5897#endif 5898#ifdef IPSEC 5899 struct m_tag *mtag; 5900#endif /* IPSEC */ 5901 5902 if (m == NULL || *m == NULL || r == NULL || 5903 (dir != PF_IN && dir != PF_OUT) || oifp == NULL) 5904 panic("pf_route: invalid parameters"); 5905 5906#ifdef __FreeBSD__ 5907 if (pd->pf_mtag->routed++ > 3) { 5908#else 5909 if ((*m)->m_pkthdr.pf.routed++ > 3) { 5910#endif 5911 m0 = *m; 5912 *m = NULL; 5913 goto bad; 5914 } 5915 5916 if (r->rt == PF_DUPTO) { 5917#ifdef __FreeBSD__ 5918 if ((m0 = m_dup(*m, M_DONTWAIT)) == NULL) 5919#else 5920 if ((m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT)) == NULL) 5921#endif 5922 return; 5923 } else { 5924 if ((r->rt == PF_REPLYTO) == (r->direction == dir)) 5925 return; 5926 m0 = *m; 5927 } 5928 5929 if (m0->m_len < sizeof(struct ip)) { 5930 DPFPRINTF(PF_DEBUG_URGENT, 5931 ("pf_route: m0->m_len < sizeof(struct ip)\n")); 5932 goto bad; 5933 } 5934 5935 ip = mtod(m0, struct ip *); 5936 5937 ro = &iproute; 5938 bzero((caddr_t)ro, sizeof(*ro)); 5939 dst = satosin(&ro->ro_dst); 5940 dst->sin_family = AF_INET; 5941 dst->sin_len = sizeof(*dst); 5942 dst->sin_addr = ip->ip_dst; 5943 5944 if (r->rt == PF_FASTROUTE) { 5945#ifdef __FreeBSD__ 5946 in_rtalloc(ro, 0); 5947#else 5948 rtalloc(ro); 5949#endif 5950 if (ro->ro_rt == 0) { 5951#ifdef __FreeBSD__ 5952 KMOD_IPSTAT_INC(ips_noroute); 5953#else 5954 ipstat.ips_noroute++; 5955#endif 5956 goto bad; 5957 } 5958 5959 ifp = ro->ro_rt->rt_ifp; 5960 ro->ro_rt->rt_use++; 5961 5962 if (ro->ro_rt->rt_flags & RTF_GATEWAY) 5963 dst = satosin(ro->ro_rt->rt_gateway); 5964 } else { 5965 if (TAILQ_EMPTY(&r->rpool.list)) { 5966 DPFPRINTF(PF_DEBUG_URGENT, 5967 ("pf_route: TAILQ_EMPTY(&r->rpool.list)\n")); 5968 goto bad; 5969 } 5970 if (s == NULL) { 5971 pf_map_addr(AF_INET, r, (struct pf_addr *)&ip->ip_src, 5972 &naddr, NULL, &sn); 5973 if (!PF_AZERO(&naddr, AF_INET)) 5974 dst->sin_addr.s_addr = naddr.v4.s_addr; 5975 ifp = r->rpool.cur->kif ? 5976 r->rpool.cur->kif->pfik_ifp : NULL; 5977 } else { 5978 if (!PF_AZERO(&s->rt_addr, AF_INET)) 5979 dst->sin_addr.s_addr = 5980 s->rt_addr.v4.s_addr; 5981 ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL; 5982 } 5983 } 5984 if (ifp == NULL) 5985 goto bad; 5986 5987 if (oifp != ifp) { 5988#ifdef __FreeBSD__ 5989 PF_UNLOCK(); 5990 if (pf_test(PF_OUT, ifp, &m0, NULL, NULL) != PF_PASS) { 5991 PF_LOCK(); 5992 goto bad; 5993 } else if (m0 == NULL) { 5994 PF_LOCK(); 5995 goto done; 5996 } 5997 PF_LOCK(); 5998#else 5999 if (pf_test(PF_OUT, ifp, &m0, NULL) != PF_PASS) 6000 goto bad; 6001 else if (m0 == NULL) 6002 goto done; 6003#endif 6004 if (m0->m_len < sizeof(struct ip)) { 6005 DPFPRINTF(PF_DEBUG_URGENT, 6006 ("pf_route: m0->m_len < sizeof(struct ip)\n")); 6007 goto bad; 6008 } 6009 ip = mtod(m0, struct ip *); 6010 } 6011 6012#ifdef __FreeBSD__ 6013 /* Copied from FreeBSD 5.1-CURRENT ip_output. */ 6014 m0->m_pkthdr.csum_flags |= CSUM_IP; 6015 sw_csum = m0->m_pkthdr.csum_flags & ~ifp->if_hwassist; 6016 if (sw_csum & CSUM_DELAY_DATA) { 6017 /* 6018 * XXX: in_delayed_cksum assumes HBO for ip->ip_len (at least) 6019 */ 6020 NTOHS(ip->ip_len); 6021 NTOHS(ip->ip_off); /* XXX: needed? */ 6022 in_delayed_cksum(m0); 6023 HTONS(ip->ip_len); 6024 HTONS(ip->ip_off); 6025 sw_csum &= ~CSUM_DELAY_DATA; 6026 } 6027 m0->m_pkthdr.csum_flags &= ifp->if_hwassist; 6028 6029 if (ntohs(ip->ip_len) <= ifp->if_mtu || 6030 (ifp->if_hwassist & CSUM_FRAGMENT && 6031 ((ip->ip_off & htons(IP_DF)) == 0))) { 6032 /* 6033 * ip->ip_len = htons(ip->ip_len); 6034 * ip->ip_off = htons(ip->ip_off); 6035 */ 6036 ip->ip_sum = 0; 6037 if (sw_csum & CSUM_DELAY_IP) { 6038 /* From KAME */ 6039 if (ip->ip_v == IPVERSION && 6040 (ip->ip_hl << 2) == sizeof(*ip)) { 6041 ip->ip_sum = in_cksum_hdr(ip); 6042 } else { 6043 ip->ip_sum = in_cksum(m0, ip->ip_hl << 2); 6044 } 6045 } 6046 PF_UNLOCK(); 6047 error = (*ifp->if_output)(ifp, m0, sintosa(dst), ro); 6048 PF_LOCK(); 6049 goto done; 6050 } 6051#else 6052 /* Copied from ip_output. */ 6053#ifdef IPSEC 6054 /* 6055 * If deferred crypto processing is needed, check that the 6056 * interface supports it. 6057 */ 6058 if ((mtag = m_tag_find(m0, PACKET_TAG_IPSEC_OUT_CRYPTO_NEEDED, NULL)) 6059 != NULL && (ifp->if_capabilities & IFCAP_IPSEC) == 0) { 6060 /* Notify IPsec to do its own crypto. */ 6061 ipsp_skipcrypto_unmark((struct tdb_ident *)(mtag + 1)); 6062 goto bad; 6063 } 6064#endif /* IPSEC */ 6065 6066 /* Catch routing changes wrt. hardware checksumming for TCP or UDP. */ 6067 if (m0->m_pkthdr.csum_flags & M_TCPV4_CSUM_OUT) { 6068 if (!(ifp->if_capabilities & IFCAP_CSUM_TCPv4) || 6069 ifp->if_bridge != NULL) { 6070 in_delayed_cksum(m0); 6071 m0->m_pkthdr.csum_flags &= ~M_TCPV4_CSUM_OUT; /* Clr */ 6072 } 6073 } else if (m0->m_pkthdr.csum_flags & M_UDPV4_CSUM_OUT) { 6074 if (!(ifp->if_capabilities & IFCAP_CSUM_UDPv4) || 6075 ifp->if_bridge != NULL) { 6076 in_delayed_cksum(m0); 6077 m0->m_pkthdr.csum_flags &= ~M_UDPV4_CSUM_OUT; /* Clr */ 6078 } 6079 } 6080 6081 if (ntohs(ip->ip_len) <= ifp->if_mtu) { 6082 ip->ip_sum = 0; 6083 if ((ifp->if_capabilities & IFCAP_CSUM_IPv4) && 6084 ifp->if_bridge == NULL) { 6085 m0->m_pkthdr.csum_flags |= M_IPV4_CSUM_OUT; 6086#ifdef __FreeBSD__ 6087 KMOD_IPSTAT_INC(ips_outhwcsum); 6088#else 6089 ipstat.ips_outhwcsum++; 6090#endif 6091 } else 6092 ip->ip_sum = in_cksum(m0, ip->ip_hl << 2); 6093 /* Update relevant hardware checksum stats for TCP/UDP */ 6094 if (m0->m_pkthdr.csum_flags & M_TCPV4_CSUM_OUT) 6095 KMOD_TCPSTAT_INC(tcps_outhwcsum); 6096 else if (m0->m_pkthdr.csum_flags & M_UDPV4_CSUM_OUT) 6097 KMOD_UDPSTAT_INC(udps_outhwcsum); 6098 error = (*ifp->if_output)(ifp, m0, sintosa(dst), NULL); 6099 goto done; 6100 } 6101#endif 6102 6103 /* 6104 * Too large for interface; fragment if possible. 6105 * Must be able to put at least 8 bytes per fragment. 6106 */ 6107 if (ip->ip_off & htons(IP_DF)) { 6108#ifdef __FreeBSD__ 6109 KMOD_IPSTAT_INC(ips_cantfrag); 6110#else 6111 ipstat.ips_cantfrag++; 6112#endif 6113 if (r->rt != PF_DUPTO) { 6114#ifdef __FreeBSD__ 6115 /* icmp_error() expects host byte ordering */ 6116 NTOHS(ip->ip_len); 6117 NTOHS(ip->ip_off); 6118 PF_UNLOCK(); 6119 icmp_error(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 0, 6120 ifp->if_mtu); 6121 PF_LOCK(); 6122#else 6123 icmp_error(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 0, 6124 ifp->if_mtu); 6125#endif 6126 goto done; 6127 } else 6128 goto bad; 6129 } 6130 6131 m1 = m0; 6132#ifdef __FreeBSD__ 6133 /* 6134 * XXX: is cheaper + less error prone than own function 6135 */ 6136 NTOHS(ip->ip_len); 6137 NTOHS(ip->ip_off); 6138 error = ip_fragment(ip, &m0, ifp->if_mtu, ifp->if_hwassist, sw_csum); 6139#else 6140 error = ip_fragment(m0, ifp, ifp->if_mtu); 6141#endif 6142 if (error) { 6143#ifndef __FreeBSD__ /* ip_fragment does not do m_freem() on FreeBSD */ 6144 m0 = NULL; 6145#endif 6146 goto bad; 6147 } 6148 6149 for (m0 = m1; m0; m0 = m1) { 6150 m1 = m0->m_nextpkt; 6151 m0->m_nextpkt = 0; 6152#ifdef __FreeBSD__ 6153 if (error == 0) { 6154 PF_UNLOCK(); 6155 error = (*ifp->if_output)(ifp, m0, sintosa(dst), 6156 NULL); 6157 PF_LOCK(); 6158 } else 6159#else 6160 if (error == 0) 6161 error = (*ifp->if_output)(ifp, m0, sintosa(dst), 6162 NULL); 6163 else 6164#endif 6165 m_freem(m0); 6166 } 6167 6168 if (error == 0) 6169#ifdef __FreeBSD__ 6170 KMOD_IPSTAT_INC(ips_fragmented); 6171#else 6172 ipstat.ips_fragmented++; 6173#endif 6174 6175done: 6176 if (r->rt != PF_DUPTO) 6177 *m = NULL; 6178 if (ro == &iproute && ro->ro_rt) 6179 RTFREE(ro->ro_rt); 6180 return; 6181 6182bad: 6183 m_freem(m0); 6184 goto done; 6185} 6186#endif /* INET */ 6187 6188#ifdef INET6 6189void 6190pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, 6191 struct pf_state *s, struct pf_pdesc *pd) 6192{ 6193 struct mbuf *m0; 6194 struct route_in6 ip6route; 6195 struct route_in6 *ro; 6196 struct sockaddr_in6 *dst; 6197 struct ip6_hdr *ip6; 6198 struct ifnet *ifp = NULL; 6199 struct pf_addr naddr; 6200 struct pf_src_node *sn = NULL; 6201 6202 if (m == NULL || *m == NULL || r == NULL || 6203 (dir != PF_IN && dir != PF_OUT) || oifp == NULL) 6204 panic("pf_route6: invalid parameters"); 6205 6206#ifdef __FreeBSD__ 6207 if (pd->pf_mtag->routed++ > 3) { 6208#else 6209 if ((*m)->m_pkthdr.pf.routed++ > 3) { 6210#endif 6211 m0 = *m; 6212 *m = NULL; 6213 goto bad; 6214 } 6215 6216 if (r->rt == PF_DUPTO) { 6217#ifdef __FreeBSD__ 6218 if ((m0 = m_dup(*m, M_DONTWAIT)) == NULL) 6219#else 6220 if ((m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT)) == NULL) 6221#endif 6222 return; 6223 } else { 6224 if ((r->rt == PF_REPLYTO) == (r->direction == dir)) 6225 return; 6226 m0 = *m; 6227 } 6228 6229 if (m0->m_len < sizeof(struct ip6_hdr)) { 6230 DPFPRINTF(PF_DEBUG_URGENT, 6231 ("pf_route6: m0->m_len < sizeof(struct ip6_hdr)\n")); 6232 goto bad; 6233 } 6234 ip6 = mtod(m0, struct ip6_hdr *); 6235 6236 ro = &ip6route; 6237 bzero((caddr_t)ro, sizeof(*ro)); 6238 dst = (struct sockaddr_in6 *)&ro->ro_dst; 6239 dst->sin6_family = AF_INET6; 6240 dst->sin6_len = sizeof(*dst); 6241 dst->sin6_addr = ip6->ip6_dst; 6242 6243 /* Cheat. XXX why only in the v6 case??? */ 6244 if (r->rt == PF_FASTROUTE) { 6245#ifdef __FreeBSD__ 6246 m0->m_flags |= M_SKIP_FIREWALL; 6247 PF_UNLOCK(); 6248 ip6_output(m0, NULL, NULL, 0, NULL, NULL, NULL); 6249#else 6250 m0->m_pkthdr.pf.flags |= PF_TAG_GENERATED; 6251 ip6_output(m0, NULL, NULL, 0, NULL, NULL, NULL); 6252#endif 6253 return; 6254 } 6255 6256 if (TAILQ_EMPTY(&r->rpool.list)) { 6257 DPFPRINTF(PF_DEBUG_URGENT, 6258 ("pf_route6: TAILQ_EMPTY(&r->rpool.list)\n")); 6259 goto bad; 6260 } 6261 if (s == NULL) { 6262 pf_map_addr(AF_INET6, r, (struct pf_addr *)&ip6->ip6_src, 6263 &naddr, NULL, &sn); 6264 if (!PF_AZERO(&naddr, AF_INET6)) 6265 PF_ACPY((struct pf_addr *)&dst->sin6_addr, 6266 &naddr, AF_INET6); 6267 ifp = r->rpool.cur->kif ? r->rpool.cur->kif->pfik_ifp : NULL; 6268 } else { 6269 if (!PF_AZERO(&s->rt_addr, AF_INET6)) 6270 PF_ACPY((struct pf_addr *)&dst->sin6_addr, 6271 &s->rt_addr, AF_INET6); 6272 ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL; 6273 } 6274 if (ifp == NULL) 6275 goto bad; 6276 6277 if (oifp != ifp) { 6278#ifdef __FreeBSD__ 6279 PF_UNLOCK(); 6280 if (pf_test6(PF_OUT, ifp, &m0, NULL, NULL) != PF_PASS) { 6281 PF_LOCK(); 6282 goto bad; 6283 } else if (m0 == NULL) { 6284 PF_LOCK(); 6285 goto done; 6286 } 6287 PF_LOCK(); 6288#else 6289 if (pf_test6(PF_OUT, ifp, &m0, NULL) != PF_PASS) 6290 goto bad; 6291 else if (m0 == NULL) 6292 goto done; 6293#endif 6294 if (m0->m_len < sizeof(struct ip6_hdr)) { 6295 DPFPRINTF(PF_DEBUG_URGENT, 6296 ("pf_route6: m0->m_len < sizeof(struct ip6_hdr)\n")); 6297 goto bad; 6298 } 6299 ip6 = mtod(m0, struct ip6_hdr *); 6300 } 6301 6302 /* 6303 * If the packet is too large for the outgoing interface, 6304 * send back an icmp6 error. 6305 */ 6306 if (IN6_IS_SCOPE_EMBED(&dst->sin6_addr)) 6307 dst->sin6_addr.s6_addr16[1] = htons(ifp->if_index); 6308 if ((u_long)m0->m_pkthdr.len <= ifp->if_mtu) { 6309#ifdef __FreeBSD__ 6310 PF_UNLOCK(); 6311#endif 6312 nd6_output(ifp, ifp, m0, dst, NULL); 6313#ifdef __FreeBSD__ 6314 PF_LOCK(); 6315#endif 6316 } else { 6317 in6_ifstat_inc(ifp, ifs6_in_toobig); 6318#ifdef __FreeBSD__ 6319 if (r->rt != PF_DUPTO) { 6320 PF_UNLOCK(); 6321 icmp6_error(m0, ICMP6_PACKET_TOO_BIG, 0, ifp->if_mtu); 6322 PF_LOCK(); 6323 } else 6324#else 6325 if (r->rt != PF_DUPTO) 6326 icmp6_error(m0, ICMP6_PACKET_TOO_BIG, 0, ifp->if_mtu); 6327 else 6328#endif 6329 goto bad; 6330 } 6331 6332done: 6333 if (r->rt != PF_DUPTO) 6334 *m = NULL; 6335 return; 6336 6337bad: 6338 m_freem(m0); 6339 goto done; 6340} 6341#endif /* INET6 */ 6342 6343#ifdef __FreeBSD__ 6344/* 6345 * FreeBSD supports cksum offloads for the following drivers. 6346 * em(4), fxp(4), ixgb(4), lge(4), ndis(4), nge(4), re(4), 6347 * ti(4), txp(4), xl(4) 6348 * 6349 * CSUM_DATA_VALID | CSUM_PSEUDO_HDR : 6350 * network driver performed cksum including pseudo header, need to verify 6351 * csum_data 6352 * CSUM_DATA_VALID : 6353 * network driver performed cksum, needs to additional pseudo header 6354 * cksum computation with partial csum_data(i.e. lack of H/W support for 6355 * pseudo header, for instance hme(4), sk(4) and possibly gem(4)) 6356 * 6357 * After validating the cksum of packet, set both flag CSUM_DATA_VALID and 6358 * CSUM_PSEUDO_HDR in order to avoid recomputation of the cksum in upper 6359 * TCP/UDP layer. 6360 * Also, set csum_data to 0xffff to force cksum validation. 6361 */ 6362int 6363pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p, sa_family_t af) 6364{ 6365 u_int16_t sum = 0; 6366 int hw_assist = 0; 6367 struct ip *ip; 6368 6369 if (off < sizeof(struct ip) || len < sizeof(struct udphdr)) 6370 return (1); 6371 if (m->m_pkthdr.len < off + len) 6372 return (1); 6373 6374 switch (p) { 6375 case IPPROTO_TCP: 6376 if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) { 6377 if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) { 6378 sum = m->m_pkthdr.csum_data; 6379 } else { 6380 ip = mtod(m, struct ip *); 6381 sum = in_pseudo(ip->ip_src.s_addr, 6382 ip->ip_dst.s_addr, htonl((u_short)len + 6383 m->m_pkthdr.csum_data + IPPROTO_TCP)); 6384 } 6385 sum ^= 0xffff; 6386 ++hw_assist; 6387 } 6388 break; 6389 case IPPROTO_UDP: 6390 if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) { 6391 if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) { 6392 sum = m->m_pkthdr.csum_data; 6393 } else { 6394 ip = mtod(m, struct ip *); 6395 sum = in_pseudo(ip->ip_src.s_addr, 6396 ip->ip_dst.s_addr, htonl((u_short)len + 6397 m->m_pkthdr.csum_data + IPPROTO_UDP)); 6398 } 6399 sum ^= 0xffff; 6400 ++hw_assist; 6401 } 6402 break; 6403 case IPPROTO_ICMP: 6404#ifdef INET6 6405 case IPPROTO_ICMPV6: 6406#endif /* INET6 */ 6407 break; 6408 default: 6409 return (1); 6410 } 6411 6412 if (!hw_assist) { 6413 switch (af) { 6414 case AF_INET: 6415 if (p == IPPROTO_ICMP) { 6416 if (m->m_len < off) 6417 return (1); 6418 m->m_data += off; 6419 m->m_len -= off; 6420 sum = in_cksum(m, len); 6421 m->m_data -= off; 6422 m->m_len += off; 6423 } else { 6424 if (m->m_len < sizeof(struct ip)) 6425 return (1); 6426 sum = in4_cksum(m, p, off, len); 6427 } 6428 break; 6429#ifdef INET6 6430 case AF_INET6: 6431 if (m->m_len < sizeof(struct ip6_hdr)) 6432 return (1); 6433 sum = in6_cksum(m, p, off, len); 6434 break; 6435#endif /* INET6 */ 6436 default: 6437 return (1); 6438 } 6439 } 6440 if (sum) { 6441 switch (p) { 6442 case IPPROTO_TCP: 6443 { 6444 KMOD_TCPSTAT_INC(tcps_rcvbadsum); 6445 break; 6446 } 6447 case IPPROTO_UDP: 6448 { 6449 KMOD_UDPSTAT_INC(udps_badsum); 6450 break; 6451 } 6452#ifdef INET 6453 case IPPROTO_ICMP: 6454 { 6455 KMOD_ICMPSTAT_INC(icps_checksum); 6456 break; 6457 } 6458#endif 6459#ifdef INET6 6460 case IPPROTO_ICMPV6: 6461 { 6462 KMOD_ICMP6STAT_INC(icp6s_checksum); 6463 break; 6464 } 6465#endif /* INET6 */ 6466 } 6467 return (1); 6468 } else { 6469 if (p == IPPROTO_TCP || p == IPPROTO_UDP) { 6470 m->m_pkthdr.csum_flags |= 6471 (CSUM_DATA_VALID | CSUM_PSEUDO_HDR); 6472 m->m_pkthdr.csum_data = 0xffff; 6473 } 6474 } 6475 return (0); 6476} 6477#else /* !__FreeBSD__ */ 6478 6479/* 6480 * check protocol (tcp/udp/icmp/icmp6) checksum and set mbuf flag 6481 * off is the offset where the protocol header starts 6482 * len is the total length of protocol header plus payload 6483 * returns 0 when the checksum is valid, otherwise returns 1. 6484 */ 6485int 6486pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p, 6487 sa_family_t af) 6488{ 6489 u_int16_t flag_ok, flag_bad; 6490 u_int16_t sum; 6491 6492 switch (p) { 6493 case IPPROTO_TCP: 6494 flag_ok = M_TCP_CSUM_IN_OK; 6495 flag_bad = M_TCP_CSUM_IN_BAD; 6496 break; 6497 case IPPROTO_UDP: 6498 flag_ok = M_UDP_CSUM_IN_OK; 6499 flag_bad = M_UDP_CSUM_IN_BAD; 6500 break; 6501 case IPPROTO_ICMP: 6502#ifdef INET6 6503 case IPPROTO_ICMPV6: 6504#endif /* INET6 */ 6505 flag_ok = flag_bad = 0; 6506 break; 6507 default: 6508 return (1); 6509 } 6510 if (m->m_pkthdr.csum_flags & flag_ok) 6511 return (0); 6512 if (m->m_pkthdr.csum_flags & flag_bad) 6513 return (1); 6514 if (off < sizeof(struct ip) || len < sizeof(struct udphdr)) 6515 return (1); 6516 if (m->m_pkthdr.len < off + len) 6517 return (1); 6518 switch (af) { 6519#ifdef INET 6520 case AF_INET: 6521 if (p == IPPROTO_ICMP) { 6522 if (m->m_len < off) 6523 return (1); 6524 m->m_data += off; 6525 m->m_len -= off; 6526 sum = in_cksum(m, len); 6527 m->m_data -= off; 6528 m->m_len += off; 6529 } else { 6530 if (m->m_len < sizeof(struct ip)) 6531 return (1); 6532 sum = in4_cksum(m, p, off, len); 6533 } 6534 break; 6535#endif /* INET */ 6536#ifdef INET6 6537 case AF_INET6: 6538 if (m->m_len < sizeof(struct ip6_hdr)) 6539 return (1); 6540 sum = in6_cksum(m, p, off, len); 6541 break; 6542#endif /* INET6 */ 6543 default: 6544 return (1); 6545 } 6546 if (sum) { 6547 m->m_pkthdr.csum_flags |= flag_bad; 6548 switch (p) { 6549 case IPPROTO_TCP: 6550 KMOD_TCPSTAT_INC(tcps_rcvbadsum); 6551 break; 6552 case IPPROTO_UDP: 6553 KMOD_UDPSTAT_INC(udps_badsum); 6554 break; 6555#ifdef INET 6556 case IPPROTO_ICMP: 6557 KMOD_ICMPSTAT_INC(icps_checksum); 6558 break; 6559#endif 6560#ifdef INET6 6561 case IPPROTO_ICMPV6: 6562 KMOD_ICMP6STAT_INC(icp6s_checksum); 6563 break; 6564#endif /* INET6 */ 6565 } 6566 return (1); 6567 } 6568 m->m_pkthdr.csum_flags |= flag_ok; 6569 return (0); 6570} 6571#endif 6572 6573#ifndef __FreeBSD__ 6574struct pf_divert * 6575pf_find_divert(struct mbuf *m) 6576{ 6577 struct m_tag *mtag; 6578 6579 if ((mtag = m_tag_find(m, PACKET_TAG_PF_DIVERT, NULL)) == NULL) 6580 return (NULL); 6581 6582 return ((struct pf_divert *)(mtag + 1)); 6583} 6584 6585struct pf_divert * 6586pf_get_divert(struct mbuf *m) 6587{ 6588 struct m_tag *mtag; 6589 6590 if ((mtag = m_tag_find(m, PACKET_TAG_PF_DIVERT, NULL)) == NULL) { 6591 mtag = m_tag_get(PACKET_TAG_PF_DIVERT, sizeof(struct pf_divert), 6592 M_NOWAIT); 6593 if (mtag == NULL) 6594 return (NULL); 6595 bzero(mtag + 1, sizeof(struct pf_divert)); 6596 m_tag_prepend(m, mtag); 6597 } 6598 6599 return ((struct pf_divert *)(mtag + 1)); 6600} 6601#endif 6602 6603#ifdef INET 6604int 6605#ifdef __FreeBSD__ 6606pf_test(int dir, struct ifnet *ifp, struct mbuf **m0, 6607 struct ether_header *eh, struct inpcb *inp) 6608#else 6609pf_test(int dir, struct ifnet *ifp, struct mbuf **m0, 6610 struct ether_header *eh) 6611#endif 6612{ 6613 struct pfi_kif *kif; 6614 u_short action, reason = 0, log = 0; 6615 struct mbuf *m = *m0; 6616#ifdef __FreeBSD__ 6617 struct ip *h = NULL; 6618 struct m_tag *ipfwtag; 6619 struct pf_rule *a = NULL, *r = &V_pf_default_rule, *tr, *nr; 6620#else 6621 struct ip *h; 6622 struct pf_rule *a = NULL, *r = &pf_default_rule, *tr, *nr; 6623#endif 6624 struct pf_state *s = NULL; 6625 struct pf_ruleset *ruleset = NULL; 6626 struct pf_pdesc pd; 6627 int off, dirndx, pqid = 0; 6628 6629#ifdef __FreeBSD__ 6630 PF_LOCK(); 6631 if (!V_pf_status.running) 6632 { 6633 PF_UNLOCK(); 6634 return (PF_PASS); 6635 } 6636#else 6637 if (!pf_status.running) 6638 return (PF_PASS); 6639#endif 6640 6641 memset(&pd, 0, sizeof(pd)); 6642#ifdef __FreeBSD__ 6643 if ((pd.pf_mtag = pf_get_mtag(m)) == NULL) { 6644 PF_UNLOCK(); 6645 DPFPRINTF(PF_DEBUG_URGENT, 6646 ("pf_test: pf_get_mtag returned NULL\n")); 6647 return (PF_DROP); 6648 } 6649#endif 6650#ifndef __FreeBSD__ 6651 if (ifp->if_type == IFT_CARP && ifp->if_carpdev) 6652 kif = (struct pfi_kif *)ifp->if_carpdev->if_pf_kif; 6653 else 6654#endif 6655 kif = (struct pfi_kif *)ifp->if_pf_kif; 6656 6657 if (kif == NULL) { 6658#ifdef __FreeBSD__ 6659 PF_UNLOCK(); 6660#endif 6661 DPFPRINTF(PF_DEBUG_URGENT, 6662 ("pf_test: kif == NULL, if_xname %s\n", ifp->if_xname)); 6663 return (PF_DROP); 6664 } 6665 if (kif->pfik_flags & PFI_IFLAG_SKIP) 6666#ifdef __FreeBSD__ 6667 { 6668 PF_UNLOCK(); 6669#endif 6670 return (PF_PASS); 6671#ifdef __FreeBSD__ 6672 } 6673#endif 6674 6675#ifdef __FreeBSD__ 6676 M_ASSERTPKTHDR(m); 6677#else 6678#ifdef DIAGNOSTIC 6679 if ((m->m_flags & M_PKTHDR) == 0) 6680 panic("non-M_PKTHDR is passed to pf_test"); 6681#endif /* DIAGNOSTIC */ 6682#endif 6683 6684 if (m->m_pkthdr.len < (int)sizeof(*h)) { 6685 action = PF_DROP; 6686 REASON_SET(&reason, PFRES_SHORT); 6687 log = 1; 6688 goto done; 6689 } 6690 6691#ifdef __FreeBSD__ 6692 if (m->m_flags & M_SKIP_FIREWALL) { 6693 PF_UNLOCK(); 6694 return (PF_PASS); 6695 } 6696#else 6697 if (m->m_pkthdr.pf.flags & PF_TAG_GENERATED) 6698 return (PF_PASS); 6699#endif 6700 6701#ifdef __FreeBSD__ 6702 if (ip_divert_ptr != NULL && 6703 ((ipfwtag = m_tag_locate(m, MTAG_IPFW_RULE, 0, NULL)) != NULL)) { 6704 struct ipfw_rule_ref *rr = (struct ipfw_rule_ref *)(ipfwtag+1); 6705 if (rr->info & IPFW_IS_DIVERT && rr->rulenum == 0) { 6706 pd.pf_mtag->flags |= PF_PACKET_LOOPED; 6707 m_tag_delete(m, ipfwtag); 6708 } 6709 if (pd.pf_mtag->flags & PF_FASTFWD_OURS_PRESENT) { 6710 m->m_flags |= M_FASTFWD_OURS; 6711 pd.pf_mtag->flags &= ~PF_FASTFWD_OURS_PRESENT; 6712 } 6713 } else 6714#endif 6715 /* We do IP header normalization and packet reassembly here */ 6716 if (pf_normalize_ip(m0, dir, kif, &reason, &pd) != PF_PASS) { 6717 action = PF_DROP; 6718 goto done; 6719 } 6720 m = *m0; /* pf_normalize messes with m0 */ 6721 h = mtod(m, struct ip *); 6722 6723 off = h->ip_hl << 2; 6724 if (off < (int)sizeof(*h)) { 6725 action = PF_DROP; 6726 REASON_SET(&reason, PFRES_SHORT); 6727 log = 1; 6728 goto done; 6729 } 6730 6731 pd.src = (struct pf_addr *)&h->ip_src; 6732 pd.dst = (struct pf_addr *)&h->ip_dst; 6733 pd.sport = pd.dport = NULL; 6734 pd.ip_sum = &h->ip_sum; 6735 pd.proto_sum = NULL; 6736 pd.proto = h->ip_p; 6737 pd.dir = dir; 6738 pd.sidx = (dir == PF_IN) ? 0 : 1; 6739 pd.didx = (dir == PF_IN) ? 1 : 0; 6740 pd.af = AF_INET; 6741 pd.tos = h->ip_tos; 6742 pd.tot_len = ntohs(h->ip_len); 6743 pd.eh = eh; 6744 6745 /* handle fragments that didn't get reassembled by normalization */ 6746 if (h->ip_off & htons(IP_MF | IP_OFFMASK)) { 6747 action = pf_test_fragment(&r, dir, kif, m, h, 6748 &pd, &a, &ruleset); 6749 goto done; 6750 } 6751 6752 switch (h->ip_p) { 6753 6754 case IPPROTO_TCP: { 6755 struct tcphdr th; 6756 6757 pd.hdr.tcp = &th; 6758 if (!pf_pull_hdr(m, off, &th, sizeof(th), 6759 &action, &reason, AF_INET)) { 6760 log = action != PF_PASS; 6761 goto done; 6762 } 6763 pd.p_len = pd.tot_len - off - (th.th_off << 2); 6764 if ((th.th_flags & TH_ACK) && pd.p_len == 0) 6765 pqid = 1; 6766 action = pf_normalize_tcp(dir, kif, m, 0, off, h, &pd); 6767 if (action == PF_DROP) 6768 goto done; 6769 action = pf_test_state_tcp(&s, dir, kif, m, off, h, &pd, 6770 &reason); 6771 if (action == PF_PASS) { 6772#if NPFSYNC > 0 6773#ifdef __FreeBSD__ 6774 if (pfsync_update_state_ptr != NULL) 6775 pfsync_update_state_ptr(s); 6776#else 6777 pfsync_update_state(s); 6778#endif 6779#endif /* NPFSYNC */ 6780 r = s->rule.ptr; 6781 a = s->anchor.ptr; 6782 log = s->log; 6783 } else if (s == NULL) 6784#ifdef __FreeBSD__ 6785 action = pf_test_rule(&r, &s, dir, kif, 6786 m, off, h, &pd, &a, &ruleset, NULL, inp); 6787#else 6788 action = pf_test_rule(&r, &s, dir, kif, 6789 m, off, h, &pd, &a, &ruleset, &ipintrq); 6790#endif 6791 break; 6792 } 6793 6794 case IPPROTO_UDP: { 6795 struct udphdr uh; 6796 6797 pd.hdr.udp = &uh; 6798 if (!pf_pull_hdr(m, off, &uh, sizeof(uh), 6799 &action, &reason, AF_INET)) { 6800 log = action != PF_PASS; 6801 goto done; 6802 } 6803 if (uh.uh_dport == 0 || 6804 ntohs(uh.uh_ulen) > m->m_pkthdr.len - off || 6805 ntohs(uh.uh_ulen) < sizeof(struct udphdr)) { 6806 action = PF_DROP; 6807 REASON_SET(&reason, PFRES_SHORT); 6808 goto done; 6809 } 6810 action = pf_test_state_udp(&s, dir, kif, m, off, h, &pd); 6811 if (action == PF_PASS) { 6812#if NPFSYNC > 0 6813#ifdef __FreeBSD__ 6814 if (pfsync_update_state_ptr != NULL) 6815 pfsync_update_state_ptr(s); 6816#else 6817 pfsync_update_state(s); 6818#endif 6819#endif /* NPFSYNC */ 6820 r = s->rule.ptr; 6821 a = s->anchor.ptr; 6822 log = s->log; 6823 } else if (s == NULL) 6824#ifdef __FreeBSD__ 6825 action = pf_test_rule(&r, &s, dir, kif, 6826 m, off, h, &pd, &a, &ruleset, NULL, inp); 6827#else 6828 action = pf_test_rule(&r, &s, dir, kif, 6829 m, off, h, &pd, &a, &ruleset, &ipintrq); 6830#endif 6831 break; 6832 } 6833 6834 case IPPROTO_ICMP: { 6835 struct icmp ih; 6836 6837 pd.hdr.icmp = &ih; 6838 if (!pf_pull_hdr(m, off, &ih, ICMP_MINLEN, 6839 &action, &reason, AF_INET)) { 6840 log = action != PF_PASS; 6841 goto done; 6842 } 6843 action = pf_test_state_icmp(&s, dir, kif, m, off, h, &pd, 6844 &reason); 6845 if (action == PF_PASS) { 6846#if NPFSYNC > 0 6847#ifdef __FreeBSD__ 6848 if (pfsync_update_state_ptr != NULL) 6849 pfsync_update_state_ptr(s); 6850#else 6851 pfsync_update_state(s); 6852#endif 6853#endif /* NPFSYNC */ 6854 r = s->rule.ptr; 6855 a = s->anchor.ptr; 6856 log = s->log; 6857 } else if (s == NULL) 6858#ifdef __FreeBSD__ 6859 action = pf_test_rule(&r, &s, dir, kif, 6860 m, off, h, &pd, &a, &ruleset, NULL, inp); 6861#else 6862 action = pf_test_rule(&r, &s, dir, kif, 6863 m, off, h, &pd, &a, &ruleset, &ipintrq); 6864#endif 6865 break; 6866 } 6867 6868#ifdef INET6 6869 case IPPROTO_ICMPV6: { 6870 action = PF_DROP; 6871 DPFPRINTF(PF_DEBUG_MISC, 6872 ("pf: dropping IPv4 packet with ICMPv6 payload\n")); 6873 goto done; 6874 } 6875#endif 6876 6877 default: 6878 action = pf_test_state_other(&s, dir, kif, m, &pd); 6879 if (action == PF_PASS) { 6880#if NPFSYNC > 0 6881#ifdef __FreeBSD__ 6882 if (pfsync_update_state_ptr != NULL) 6883 pfsync_update_state_ptr(s); 6884#else 6885 pfsync_update_state(s); 6886#endif 6887#endif /* NPFSYNC */ 6888 r = s->rule.ptr; 6889 a = s->anchor.ptr; 6890 log = s->log; 6891 } else if (s == NULL) 6892#ifdef __FreeBSD__ 6893 action = pf_test_rule(&r, &s, dir, kif, m, off, h, 6894 &pd, &a, &ruleset, NULL, inp); 6895#else 6896 action = pf_test_rule(&r, &s, dir, kif, m, off, h, 6897 &pd, &a, &ruleset, &ipintrq); 6898#endif 6899 break; 6900 } 6901 6902done: 6903 if (action == PF_PASS && h->ip_hl > 5 && 6904 !((s && s->state_flags & PFSTATE_ALLOWOPTS) || r->allow_opts)) { 6905 action = PF_DROP; 6906 REASON_SET(&reason, PFRES_IPOPTIONS); 6907 log = 1; 6908 DPFPRINTF(PF_DEBUG_MISC, 6909 ("pf: dropping packet with ip options\n")); 6910 } 6911 6912 if ((s && s->tag) || r->rtableid) 6913#ifdef __FreeBSD__ 6914 pf_tag_packet(m, s ? s->tag : 0, r->rtableid, pd.pf_mtag); 6915#else 6916 pf_tag_packet(m, s ? s->tag : 0, r->rtableid); 6917#endif 6918 6919 if (dir == PF_IN && s && s->key[PF_SK_STACK]) 6920#ifdef __FreeBSD__ 6921 pd.pf_mtag->statekey = s->key[PF_SK_STACK]; 6922#else 6923 m->m_pkthdr.pf.statekey = s->key[PF_SK_STACK]; 6924#endif 6925 6926#ifdef ALTQ 6927 if (action == PF_PASS && r->qid) { 6928#ifdef __FreeBSD__ 6929 if (pqid || (pd.tos & IPTOS_LOWDELAY)) 6930 pd.pf_mtag->qid = r->pqid; 6931 else 6932 pd.pf_mtag->qid = r->qid; 6933 /* add hints for ecn */ 6934 pd.pf_mtag->hdr = h; 6935 6936#else 6937 if (pqid || (pd.tos & IPTOS_LOWDELAY)) 6938 m->m_pkthdr.pf.qid = r->pqid; 6939 else 6940 m->m_pkthdr.pf.qid = r->qid; 6941 /* add hints for ecn */ 6942 m->m_pkthdr.pf.hdr = h; 6943#endif 6944 } 6945#endif /* ALTQ */ 6946 6947 /* 6948 * connections redirected to loopback should not match sockets 6949 * bound specifically to loopback due to security implications, 6950 * see tcp_input() and in_pcblookup_listen(). 6951 */ 6952 if (dir == PF_IN && action == PF_PASS && (pd.proto == IPPROTO_TCP || 6953 pd.proto == IPPROTO_UDP) && s != NULL && s->nat_rule.ptr != NULL && 6954 (s->nat_rule.ptr->action == PF_RDR || 6955 s->nat_rule.ptr->action == PF_BINAT) && 6956 (ntohl(pd.dst->v4.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) 6957#ifdef __FreeBSD__ 6958 m->m_flags |= M_SKIP_FIREWALL; 6959#else 6960 m->m_pkthdr.pf.flags |= PF_TAG_TRANSLATE_LOCALHOST; 6961#endif 6962 6963#ifdef __FreeBSD__ 6964 if (action == PF_PASS && r->divert.port && 6965 ip_divert_ptr != NULL && !PACKET_LOOPED()) { 6966 6967 ipfwtag = m_tag_alloc(MTAG_IPFW_RULE, 0, 6968 sizeof(struct ipfw_rule_ref), M_NOWAIT | M_ZERO); 6969 if (ipfwtag != NULL) { 6970 ((struct ipfw_rule_ref *)(ipfwtag+1))->info = 6971 ntohs(r->divert.port); 6972 ((struct ipfw_rule_ref *)(ipfwtag+1))->rulenum = dir; 6973 6974 m_tag_prepend(m, ipfwtag); 6975 6976 PF_UNLOCK(); 6977 6978 if (m->m_flags & M_FASTFWD_OURS) { 6979 pd.pf_mtag->flags |= PF_FASTFWD_OURS_PRESENT; 6980 m->m_flags &= ~M_FASTFWD_OURS; 6981 } 6982 6983 ip_divert_ptr(*m0, 6984 dir == PF_IN ? DIR_IN : DIR_OUT); 6985 *m0 = NULL; 6986 return (action); 6987 } else { 6988 /* XXX: ipfw has the same behaviour! */ 6989 action = PF_DROP; 6990 REASON_SET(&reason, PFRES_MEMORY); 6991 log = 1; 6992 DPFPRINTF(PF_DEBUG_MISC, 6993 ("pf: failed to allocate divert tag\n")); 6994 } 6995 } 6996#else 6997 if (dir == PF_IN && action == PF_PASS && r->divert.port) { 6998 struct pf_divert *divert; 6999 7000 if ((divert = pf_get_divert(m))) { 7001 m->m_pkthdr.pf.flags |= PF_TAG_DIVERTED; 7002 divert->port = r->divert.port; 7003 divert->addr.ipv4 = r->divert.addr.v4; 7004 } 7005 } 7006#endif 7007 7008 if (log) { 7009 struct pf_rule *lr; 7010 7011 if (s != NULL && s->nat_rule.ptr != NULL && 7012 s->nat_rule.ptr->log & PF_LOG_ALL) 7013 lr = s->nat_rule.ptr; 7014 else 7015 lr = r; 7016 PFLOG_PACKET(kif, h, m, AF_INET, dir, reason, lr, a, ruleset, 7017 &pd); 7018 } 7019 7020 kif->pfik_bytes[0][dir == PF_OUT][action != PF_PASS] += pd.tot_len; 7021 kif->pfik_packets[0][dir == PF_OUT][action != PF_PASS]++; 7022 7023 if (action == PF_PASS || r->action == PF_DROP) { 7024 dirndx = (dir == PF_OUT); 7025 r->packets[dirndx]++; 7026 r->bytes[dirndx] += pd.tot_len; 7027 if (a != NULL) { 7028 a->packets[dirndx]++; 7029 a->bytes[dirndx] += pd.tot_len; 7030 } 7031 if (s != NULL) { 7032 if (s->nat_rule.ptr != NULL) { 7033 s->nat_rule.ptr->packets[dirndx]++; 7034 s->nat_rule.ptr->bytes[dirndx] += pd.tot_len; 7035 } 7036 if (s->src_node != NULL) { 7037 s->src_node->packets[dirndx]++; 7038 s->src_node->bytes[dirndx] += pd.tot_len; 7039 } 7040 if (s->nat_src_node != NULL) { 7041 s->nat_src_node->packets[dirndx]++; 7042 s->nat_src_node->bytes[dirndx] += pd.tot_len; 7043 } 7044 dirndx = (dir == s->direction) ? 0 : 1; 7045 s->packets[dirndx]++; 7046 s->bytes[dirndx] += pd.tot_len; 7047 } 7048 tr = r; 7049 nr = (s != NULL) ? s->nat_rule.ptr : pd.nat_rule; 7050#ifdef __FreeBSD__ 7051 if (nr != NULL && r == &V_pf_default_rule) 7052#else 7053 if (nr != NULL && r == &pf_default_rule) 7054#endif 7055 tr = nr; 7056 if (tr->src.addr.type == PF_ADDR_TABLE) 7057 pfr_update_stats(tr->src.addr.p.tbl, 7058 (s == NULL) ? pd.src : 7059 &s->key[(s->direction == PF_IN)]-> 7060 addr[(s->direction == PF_OUT)], 7061 pd.af, pd.tot_len, dir == PF_OUT, 7062 r->action == PF_PASS, tr->src.neg); 7063 if (tr->dst.addr.type == PF_ADDR_TABLE) 7064 pfr_update_stats(tr->dst.addr.p.tbl, 7065 (s == NULL) ? pd.dst : 7066 &s->key[(s->direction == PF_IN)]-> 7067 addr[(s->direction == PF_IN)], 7068 pd.af, pd.tot_len, dir == PF_OUT, 7069 r->action == PF_PASS, tr->dst.neg); 7070 } 7071 7072 switch (action) { 7073 case PF_SYNPROXY_DROP: 7074 m_freem(*m0); 7075 case PF_DEFER: 7076 *m0 = NULL; 7077 action = PF_PASS; 7078 break; 7079 default: 7080 /* pf_route can free the mbuf causing *m0 to become NULL */ 7081 if (r->rt) 7082 pf_route(m0, r, dir, kif->pfik_ifp, s, &pd); 7083 break; 7084 } 7085#ifdef __FreeBSD__ 7086 PF_UNLOCK(); 7087#endif 7088 return (action); 7089} 7090#endif /* INET */ 7091 7092#ifdef INET6 7093int 7094#ifdef __FreeBSD__ 7095pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0, 7096 struct ether_header *eh, struct inpcb *inp) 7097#else 7098pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0, 7099 struct ether_header *eh) 7100#endif 7101{ 7102 struct pfi_kif *kif; 7103 u_short action, reason = 0, log = 0; 7104 struct mbuf *m = *m0, *n = NULL; 7105#ifdef __FreeBSD__ 7106 struct ip6_hdr *h = NULL; 7107 struct pf_rule *a = NULL, *r = &V_pf_default_rule, *tr, *nr; 7108#else 7109 struct ip6_hdr *h; 7110 struct pf_rule *a = NULL, *r = &pf_default_rule, *tr, *nr; 7111#endif 7112 struct pf_state *s = NULL; 7113 struct pf_ruleset *ruleset = NULL; 7114 struct pf_pdesc pd; 7115 int off, terminal = 0, dirndx, rh_cnt = 0; 7116 7117#ifdef __FreeBSD__ 7118 PF_LOCK(); 7119 if (!V_pf_status.running) { 7120 PF_UNLOCK(); 7121 return (PF_PASS); 7122 } 7123#else 7124 if (!pf_status.running) 7125 return (PF_PASS); 7126#endif 7127 7128 memset(&pd, 0, sizeof(pd)); 7129#ifdef __FreeBSD__ 7130 if ((pd.pf_mtag = pf_get_mtag(m)) == NULL) { 7131 PF_UNLOCK(); 7132 DPFPRINTF(PF_DEBUG_URGENT, 7133 ("pf_test: pf_get_mtag returned NULL\n")); 7134 return (PF_DROP); 7135 } 7136#endif 7137#ifndef __FreeBSD__ 7138 if (ifp->if_type == IFT_CARP && ifp->if_carpdev) 7139 kif = (struct pfi_kif *)ifp->if_carpdev->if_pf_kif; 7140 else 7141#endif 7142 kif = (struct pfi_kif *)ifp->if_pf_kif; 7143 7144 if (kif == NULL) { 7145#ifdef __FreeBSD__ 7146 PF_UNLOCK(); 7147#endif 7148 DPFPRINTF(PF_DEBUG_URGENT, 7149 ("pf_test6: kif == NULL, if_xname %s\n", ifp->if_xname)); 7150 return (PF_DROP); 7151 } 7152 if (kif->pfik_flags & PFI_IFLAG_SKIP) 7153#ifdef __FreeBSD__ 7154 { 7155 PF_UNLOCK(); 7156#endif 7157 return (PF_PASS); 7158#ifdef __FreeBSD__ 7159 } 7160#endif 7161 7162#ifdef __FreeBSD__ 7163 M_ASSERTPKTHDR(m); 7164#else 7165#ifdef DIAGNOSTIC 7166 if ((m->m_flags & M_PKTHDR) == 0) 7167 panic("non-M_PKTHDR is passed to pf_test6"); 7168#endif /* DIAGNOSTIC */ 7169#endif 7170 7171 if (m->m_pkthdr.len < (int)sizeof(*h)) { 7172 action = PF_DROP; 7173 REASON_SET(&reason, PFRES_SHORT); 7174 log = 1; 7175 goto done; 7176 } 7177 7178#ifdef __FreeBSD__ 7179 if (pd.pf_mtag->flags & PF_TAG_GENERATED) 7180#else 7181 if (m->m_pkthdr.pf.flags & PF_TAG_GENERATED) 7182#endif 7183 return (PF_PASS); 7184 7185 /* We do IP header normalization and packet reassembly here */ 7186 if (pf_normalize_ip6(m0, dir, kif, &reason, &pd) != PF_PASS) { 7187 action = PF_DROP; 7188 goto done; 7189 } 7190 m = *m0; /* pf_normalize messes with m0 */ 7191 h = mtod(m, struct ip6_hdr *); 7192 7193#if 1 7194 /* 7195 * we do not support jumbogram yet. if we keep going, zero ip6_plen 7196 * will do something bad, so drop the packet for now. 7197 */ 7198 if (htons(h->ip6_plen) == 0) { 7199 action = PF_DROP; 7200 REASON_SET(&reason, PFRES_NORM); /*XXX*/ 7201 goto done; 7202 } 7203#endif 7204 7205 pd.src = (struct pf_addr *)&h->ip6_src; 7206 pd.dst = (struct pf_addr *)&h->ip6_dst; 7207 pd.sport = pd.dport = NULL; 7208 pd.ip_sum = NULL; 7209 pd.proto_sum = NULL; 7210 pd.dir = dir; 7211 pd.sidx = (dir == PF_IN) ? 0 : 1; 7212 pd.didx = (dir == PF_IN) ? 1 : 0; 7213 pd.af = AF_INET6; 7214 pd.tos = 0; 7215 pd.tot_len = ntohs(h->ip6_plen) + sizeof(struct ip6_hdr); 7216 pd.eh = eh; 7217 7218 off = ((caddr_t)h - m->m_data) + sizeof(struct ip6_hdr); 7219 pd.proto = h->ip6_nxt; 7220 do { 7221 switch (pd.proto) { 7222 case IPPROTO_FRAGMENT: 7223 action = pf_test_fragment(&r, dir, kif, m, h, 7224 &pd, &a, &ruleset); 7225 if (action == PF_DROP) 7226 REASON_SET(&reason, PFRES_FRAG); 7227 goto done; 7228 case IPPROTO_ROUTING: { 7229 struct ip6_rthdr rthdr; 7230 7231 if (rh_cnt++) { 7232 DPFPRINTF(PF_DEBUG_MISC, 7233 ("pf: IPv6 more than one rthdr\n")); 7234 action = PF_DROP; 7235 REASON_SET(&reason, PFRES_IPOPTIONS); 7236 log = 1; 7237 goto done; 7238 } 7239 if (!pf_pull_hdr(m, off, &rthdr, sizeof(rthdr), NULL, 7240 &reason, pd.af)) { 7241 DPFPRINTF(PF_DEBUG_MISC, 7242 ("pf: IPv6 short rthdr\n")); 7243 action = PF_DROP; 7244 REASON_SET(&reason, PFRES_SHORT); 7245 log = 1; 7246 goto done; 7247 } 7248 if (rthdr.ip6r_type == IPV6_RTHDR_TYPE_0) { 7249 DPFPRINTF(PF_DEBUG_MISC, 7250 ("pf: IPv6 rthdr0\n")); 7251 action = PF_DROP; 7252 REASON_SET(&reason, PFRES_IPOPTIONS); 7253 log = 1; 7254 goto done; 7255 } 7256 /* FALLTHROUGH */ 7257 } 7258 case IPPROTO_AH: 7259 case IPPROTO_HOPOPTS: 7260 case IPPROTO_DSTOPTS: { 7261 /* get next header and header length */ 7262 struct ip6_ext opt6; 7263 7264 if (!pf_pull_hdr(m, off, &opt6, sizeof(opt6), 7265 NULL, &reason, pd.af)) { 7266 DPFPRINTF(PF_DEBUG_MISC, 7267 ("pf: IPv6 short opt\n")); 7268 action = PF_DROP; 7269 log = 1; 7270 goto done; 7271 } 7272 if (pd.proto == IPPROTO_AH) 7273 off += (opt6.ip6e_len + 2) * 4; 7274 else 7275 off += (opt6.ip6e_len + 1) * 8; 7276 pd.proto = opt6.ip6e_nxt; 7277 /* goto the next header */ 7278 break; 7279 } 7280 default: 7281 terminal++; 7282 break; 7283 } 7284 } while (!terminal); 7285 7286 /* if there's no routing header, use unmodified mbuf for checksumming */ 7287 if (!n) 7288 n = m; 7289 7290 switch (pd.proto) { 7291 7292 case IPPROTO_TCP: { 7293 struct tcphdr th; 7294 7295 pd.hdr.tcp = &th; 7296 if (!pf_pull_hdr(m, off, &th, sizeof(th), 7297 &action, &reason, AF_INET6)) { 7298 log = action != PF_PASS; 7299 goto done; 7300 } 7301 pd.p_len = pd.tot_len - off - (th.th_off << 2); 7302 action = pf_normalize_tcp(dir, kif, m, 0, off, h, &pd); 7303 if (action == PF_DROP) 7304 goto done; 7305 action = pf_test_state_tcp(&s, dir, kif, m, off, h, &pd, 7306 &reason); 7307 if (action == PF_PASS) { 7308#if NPFSYNC > 0 7309#ifdef __FreeBSD__ 7310 if (pfsync_update_state_ptr != NULL) 7311 pfsync_update_state_ptr(s); 7312#else 7313 pfsync_update_state(s); 7314#endif 7315#endif /* NPFSYNC */ 7316 r = s->rule.ptr; 7317 a = s->anchor.ptr; 7318 log = s->log; 7319 } else if (s == NULL) 7320#ifdef __FreeBSD__ 7321 action = pf_test_rule(&r, &s, dir, kif, 7322 m, off, h, &pd, &a, &ruleset, NULL, inp); 7323#else 7324 action = pf_test_rule(&r, &s, dir, kif, 7325 m, off, h, &pd, &a, &ruleset, &ip6intrq); 7326#endif 7327 break; 7328 } 7329 7330 case IPPROTO_UDP: { 7331 struct udphdr uh; 7332 7333 pd.hdr.udp = &uh; 7334 if (!pf_pull_hdr(m, off, &uh, sizeof(uh), 7335 &action, &reason, AF_INET6)) { 7336 log = action != PF_PASS; 7337 goto done; 7338 } 7339 if (uh.uh_dport == 0 || 7340 ntohs(uh.uh_ulen) > m->m_pkthdr.len - off || 7341 ntohs(uh.uh_ulen) < sizeof(struct udphdr)) { 7342 action = PF_DROP; 7343 REASON_SET(&reason, PFRES_SHORT); 7344 goto done; 7345 } 7346 action = pf_test_state_udp(&s, dir, kif, m, off, h, &pd); 7347 if (action == PF_PASS) { 7348#if NPFSYNC > 0 7349#ifdef __FreeBSD__ 7350 if (pfsync_update_state_ptr != NULL) 7351 pfsync_update_state_ptr(s); 7352#else 7353 pfsync_update_state(s); 7354#endif 7355#endif /* NPFSYNC */ 7356 r = s->rule.ptr; 7357 a = s->anchor.ptr; 7358 log = s->log; 7359 } else if (s == NULL) 7360#ifdef __FreeBSD__ 7361 action = pf_test_rule(&r, &s, dir, kif, 7362 m, off, h, &pd, &a, &ruleset, NULL, inp); 7363#else 7364 action = pf_test_rule(&r, &s, dir, kif, 7365 m, off, h, &pd, &a, &ruleset, &ip6intrq); 7366#endif 7367 break; 7368 } 7369 7370 case IPPROTO_ICMP: { 7371 action = PF_DROP; 7372 DPFPRINTF(PF_DEBUG_MISC, 7373 ("pf: dropping IPv6 packet with ICMPv4 payload\n")); 7374 goto done; 7375 } 7376 7377 case IPPROTO_ICMPV6: { 7378 struct icmp6_hdr ih; 7379 7380 pd.hdr.icmp6 = &ih; 7381 if (!pf_pull_hdr(m, off, &ih, sizeof(ih), 7382 &action, &reason, AF_INET6)) { 7383 log = action != PF_PASS; 7384 goto done; 7385 } 7386 action = pf_test_state_icmp(&s, dir, kif, 7387 m, off, h, &pd, &reason); 7388 if (action == PF_PASS) { 7389#if NPFSYNC > 0 7390#ifdef __FreeBSD__ 7391 if (pfsync_update_state_ptr != NULL) 7392 pfsync_update_state_ptr(s); 7393#else 7394 pfsync_update_state(s); 7395#endif 7396#endif /* NPFSYNC */ 7397 r = s->rule.ptr; 7398 a = s->anchor.ptr; 7399 log = s->log; 7400 } else if (s == NULL) 7401#ifdef __FreeBSD__ 7402 action = pf_test_rule(&r, &s, dir, kif, 7403 m, off, h, &pd, &a, &ruleset, NULL, inp); 7404#else 7405 action = pf_test_rule(&r, &s, dir, kif, 7406 m, off, h, &pd, &a, &ruleset, &ip6intrq); 7407#endif 7408 break; 7409 } 7410 7411 default: 7412 action = pf_test_state_other(&s, dir, kif, m, &pd); 7413 if (action == PF_PASS) { 7414#if NPFSYNC > 0 7415#ifdef __FreeBSD__ 7416 if (pfsync_update_state_ptr != NULL) 7417 pfsync_update_state_ptr(s); 7418#else 7419 pfsync_update_state(s); 7420#endif 7421#endif /* NPFSYNC */ 7422 r = s->rule.ptr; 7423 a = s->anchor.ptr; 7424 log = s->log; 7425 } else if (s == NULL) 7426#ifdef __FreeBSD__ 7427 action = pf_test_rule(&r, &s, dir, kif, m, off, h, 7428 &pd, &a, &ruleset, NULL, inp); 7429#else 7430 action = pf_test_rule(&r, &s, dir, kif, m, off, h, 7431 &pd, &a, &ruleset, &ip6intrq); 7432#endif 7433 break; 7434 } 7435 7436done: 7437 if (n != m) { 7438 m_freem(n); 7439 n = NULL; 7440 } 7441 7442 /* handle dangerous IPv6 extension headers. */ 7443 if (action == PF_PASS && rh_cnt && 7444 !((s && s->state_flags & PFSTATE_ALLOWOPTS) || r->allow_opts)) { 7445 action = PF_DROP; 7446 REASON_SET(&reason, PFRES_IPOPTIONS); 7447 log = 1; 7448 DPFPRINTF(PF_DEBUG_MISC, 7449 ("pf: dropping packet with dangerous v6 headers\n")); 7450 } 7451 7452 if ((s && s->tag) || r->rtableid) 7453#ifdef __FreeBSD__ 7454 pf_tag_packet(m, s ? s->tag : 0, r->rtableid, pd.pf_mtag); 7455#else 7456 pf_tag_packet(m, s ? s->tag : 0, r->rtableid); 7457#endif 7458 7459 if (dir == PF_IN && s && s->key[PF_SK_STACK]) 7460#ifdef __FreeBSD__ 7461 pd.pf_mtag->statekey = s->key[PF_SK_STACK]; 7462#else 7463 m->m_pkthdr.pf.statekey = s->key[PF_SK_STACK]; 7464#endif 7465 7466#ifdef ALTQ 7467 if (action == PF_PASS && r->qid) { 7468#ifdef __FreeBSD__ 7469 if (pd.tos & IPTOS_LOWDELAY) 7470 pd.pf_mtag->qid = r->pqid; 7471 else 7472 pd.pf_mtag->qid = r->qid; 7473 /* add hints for ecn */ 7474 pd.pf_mtag->hdr = h; 7475#else 7476 if (pd.tos & IPTOS_LOWDELAY) 7477 m->m_pkthdr.pf.qid = r->pqid; 7478 else 7479 m->m_pkthdr.pf.qid = r->qid; 7480 /* add hints for ecn */ 7481 m->m_pkthdr.pf.hdr = h; 7482#endif 7483 } 7484#endif /* ALTQ */ 7485 7486 if (dir == PF_IN && action == PF_PASS && (pd.proto == IPPROTO_TCP || 7487 pd.proto == IPPROTO_UDP) && s != NULL && s->nat_rule.ptr != NULL && 7488 (s->nat_rule.ptr->action == PF_RDR || 7489 s->nat_rule.ptr->action == PF_BINAT) && 7490 IN6_IS_ADDR_LOOPBACK(&pd.dst->v6)) 7491#ifdef __FreeBSD__ 7492 m->m_flags |= M_SKIP_FIREWALL; 7493#else 7494 m->m_pkthdr.pf.flags |= PF_TAG_TRANSLATE_LOCALHOST; 7495#endif 7496 7497#ifdef __FreeBSD__ 7498 /* XXX: Anybody working on it?! */ 7499 if (r->divert.port) 7500 printf("pf: divert(9) is not supported for IPv6\n"); 7501#else 7502 if (dir == PF_IN && action == PF_PASS && r->divert.port) { 7503 struct pf_divert *divert; 7504 7505 if ((divert = pf_get_divert(m))) { 7506 m->m_pkthdr.pf.flags |= PF_TAG_DIVERTED; 7507 divert->port = r->divert.port; 7508 divert->addr.ipv6 = r->divert.addr.v6; 7509 } 7510 } 7511#endif 7512 7513 if (log) { 7514 struct pf_rule *lr; 7515 7516 if (s != NULL && s->nat_rule.ptr != NULL && 7517 s->nat_rule.ptr->log & PF_LOG_ALL) 7518 lr = s->nat_rule.ptr; 7519 else 7520 lr = r; 7521 PFLOG_PACKET(kif, h, m, AF_INET6, dir, reason, lr, a, ruleset, 7522 &pd); 7523 } 7524 7525 kif->pfik_bytes[1][dir == PF_OUT][action != PF_PASS] += pd.tot_len; 7526 kif->pfik_packets[1][dir == PF_OUT][action != PF_PASS]++; 7527 7528 if (action == PF_PASS || r->action == PF_DROP) { 7529 dirndx = (dir == PF_OUT); 7530 r->packets[dirndx]++; 7531 r->bytes[dirndx] += pd.tot_len; 7532 if (a != NULL) { 7533 a->packets[dirndx]++; 7534 a->bytes[dirndx] += pd.tot_len; 7535 } 7536 if (s != NULL) { 7537 if (s->nat_rule.ptr != NULL) { 7538 s->nat_rule.ptr->packets[dirndx]++; 7539 s->nat_rule.ptr->bytes[dirndx] += pd.tot_len; 7540 } 7541 if (s->src_node != NULL) { 7542 s->src_node->packets[dirndx]++; 7543 s->src_node->bytes[dirndx] += pd.tot_len; 7544 } 7545 if (s->nat_src_node != NULL) { 7546 s->nat_src_node->packets[dirndx]++; 7547 s->nat_src_node->bytes[dirndx] += pd.tot_len; 7548 } 7549 dirndx = (dir == s->direction) ? 0 : 1; 7550 s->packets[dirndx]++; 7551 s->bytes[dirndx] += pd.tot_len; 7552 } 7553 tr = r; 7554 nr = (s != NULL) ? s->nat_rule.ptr : pd.nat_rule; 7555#ifdef __FreeBSD__ 7556 if (nr != NULL && r == &V_pf_default_rule) 7557#else 7558 if (nr != NULL && r == &pf_default_rule) 7559#endif 7560 tr = nr; 7561 if (tr->src.addr.type == PF_ADDR_TABLE) 7562 pfr_update_stats(tr->src.addr.p.tbl, 7563 (s == NULL) ? pd.src : 7564 &s->key[(s->direction == PF_IN)]->addr[0], 7565 pd.af, pd.tot_len, dir == PF_OUT, 7566 r->action == PF_PASS, tr->src.neg); 7567 if (tr->dst.addr.type == PF_ADDR_TABLE) 7568 pfr_update_stats(tr->dst.addr.p.tbl, 7569 (s == NULL) ? pd.dst : 7570 &s->key[(s->direction == PF_IN)]->addr[1], 7571 pd.af, pd.tot_len, dir == PF_OUT, 7572 r->action == PF_PASS, tr->dst.neg); 7573 } 7574 7575 switch (action) { 7576 case PF_SYNPROXY_DROP: 7577 m_freem(*m0); 7578 case PF_DEFER: 7579 *m0 = NULL; 7580 action = PF_PASS; 7581 break; 7582 default: 7583 /* pf_route6 can free the mbuf causing *m0 to become NULL */ 7584 if (r->rt) 7585 pf_route6(m0, r, dir, kif->pfik_ifp, s, &pd); 7586 break; 7587 } 7588 7589#ifdef __FreeBSD__ 7590 PF_UNLOCK(); 7591#endif 7592 return (action); 7593} 7594#endif /* INET6 */ 7595 7596int 7597pf_check_congestion(struct ifqueue *ifq) 7598{ 7599#ifdef __FreeBSD__ 7600 /* XXX_IMPORT: later */ 7601 return (0); 7602#else 7603 if (ifq->ifq_congestion) 7604 return (1); 7605 else 7606 return (0); 7607#endif 7608} 7609 7610/* 7611 * must be called whenever any addressing information such as 7612 * address, port, protocol has changed 7613 */ 7614void 7615pf_pkt_addr_changed(struct mbuf *m) 7616{ 7617#ifdef __FreeBSD__ 7618 struct pf_mtag *pf_tag; 7619 7620 if ((pf_tag = pf_find_mtag(m)) != NULL) 7621 pf_tag->statekey = NULL; 7622#else 7623 m->m_pkthdr.pf.statekey = NULL; 7624#endif 7625}
| 1631#else 1632 if (pfsync_state_in_use(cur)) 1633#endif 1634 return; 1635#endif 1636#ifdef __FreeBSD__ 1637 KASSERT(cur->timeout == PFTM_UNLINKED, 1638 ("pf_free_state: cur->timeout != PFTM_UNLINKED")); 1639#else 1640 KASSERT(cur->timeout == PFTM_UNLINKED); 1641#endif 1642 if (--cur->rule.ptr->states_cur <= 0 && 1643 cur->rule.ptr->src_nodes <= 0) 1644 pf_rm_rule(NULL, cur->rule.ptr); 1645 if (cur->nat_rule.ptr != NULL) 1646 if (--cur->nat_rule.ptr->states_cur <= 0 && 1647 cur->nat_rule.ptr->src_nodes <= 0) 1648 pf_rm_rule(NULL, cur->nat_rule.ptr); 1649 if (cur->anchor.ptr != NULL) 1650 if (--cur->anchor.ptr->states_cur <= 0) 1651 pf_rm_rule(NULL, cur->anchor.ptr); 1652 pf_normalize_tcp_cleanup(cur); 1653 pfi_kif_unref(cur->kif, PFI_KIF_REF_STATE); 1654#ifdef __FreeBSD__ 1655 TAILQ_REMOVE(&V_state_list, cur, entry_list); 1656#else 1657 TAILQ_REMOVE(&state_list, cur, entry_list); 1658#endif 1659 if (cur->tag) 1660 pf_tag_unref(cur->tag); 1661#ifdef __FreeBSD__ 1662 pool_put(&V_pf_state_pl, cur); 1663 V_pf_status.fcounters[FCNT_STATE_REMOVALS]++; 1664 V_pf_status.states--; 1665#else 1666 pool_put(&pf_state_pl, cur); 1667 pf_status.fcounters[FCNT_STATE_REMOVALS]++; 1668 pf_status.states--; 1669#endif 1670} 1671 1672#ifdef __FreeBSD__ 1673int 1674pf_purge_expired_states(u_int32_t maxcheck, int waslocked) 1675#else 1676void 1677pf_purge_expired_states(u_int32_t maxcheck) 1678#endif 1679{ 1680 static struct pf_state *cur = NULL; 1681 struct pf_state *next; 1682#ifdef __FreeBSD__ 1683 int locked = waslocked; 1684#else 1685 int locked = 0; 1686#endif 1687 1688 while (maxcheck--) { 1689 /* wrap to start of list when we hit the end */ 1690 if (cur == NULL) { 1691#ifdef __FreeBSD__ 1692 cur = TAILQ_FIRST(&V_state_list); 1693#else 1694 cur = TAILQ_FIRST(&state_list); 1695#endif 1696 if (cur == NULL) 1697 break; /* list empty */ 1698 } 1699 1700 /* get next state, as cur may get deleted */ 1701 next = TAILQ_NEXT(cur, entry_list); 1702 1703 if (cur->timeout == PFTM_UNLINKED) { 1704 /* free unlinked state */ 1705 if (! locked) { 1706#ifdef __FreeBSD__ 1707 if (!sx_try_upgrade(&V_pf_consistency_lock)) 1708 return (0); 1709#else 1710 rw_enter_write(&pf_consistency_lock); 1711#endif 1712 locked = 1; 1713 } 1714 pf_free_state(cur); 1715 } else if (pf_state_expires(cur) <= time_second) { 1716 /* unlink and free expired state */ 1717 pf_unlink_state(cur); 1718 if (! locked) { 1719#ifdef __FreeBSD__ 1720 if (!sx_try_upgrade(&V_pf_consistency_lock)) 1721 return (0); 1722#else 1723 rw_enter_write(&pf_consistency_lock); 1724#endif 1725 locked = 1; 1726 } 1727 pf_free_state(cur); 1728 } 1729 cur = next; 1730 } 1731 1732#ifdef __FreeBSD__ 1733 if (!waslocked && locked) 1734 sx_downgrade(&V_pf_consistency_lock); 1735 1736 return (1); 1737#else 1738 if (locked) 1739 rw_exit_write(&pf_consistency_lock); 1740#endif 1741} 1742 1743int 1744pf_tbladdr_setup(struct pf_ruleset *rs, struct pf_addr_wrap *aw) 1745{ 1746 if (aw->type != PF_ADDR_TABLE) 1747 return (0); 1748 if ((aw->p.tbl = pfr_attach_table(rs, aw->v.tblname, 1)) == NULL) 1749 return (1); 1750 return (0); 1751} 1752 1753void 1754pf_tbladdr_remove(struct pf_addr_wrap *aw) 1755{ 1756 if (aw->type != PF_ADDR_TABLE || aw->p.tbl == NULL) 1757 return; 1758 pfr_detach_table(aw->p.tbl); 1759 aw->p.tbl = NULL; 1760} 1761 1762void 1763pf_tbladdr_copyout(struct pf_addr_wrap *aw) 1764{ 1765 struct pfr_ktable *kt = aw->p.tbl; 1766 1767 if (aw->type != PF_ADDR_TABLE || kt == NULL) 1768 return; 1769 if (!(kt->pfrkt_flags & PFR_TFLAG_ACTIVE) && kt->pfrkt_root != NULL) 1770 kt = kt->pfrkt_root; 1771 aw->p.tbl = NULL; 1772 aw->p.tblcnt = (kt->pfrkt_flags & PFR_TFLAG_ACTIVE) ? 1773 kt->pfrkt_cnt : -1; 1774} 1775 1776void 1777pf_print_host(struct pf_addr *addr, u_int16_t p, sa_family_t af) 1778{ 1779 switch (af) { 1780#ifdef INET 1781 case AF_INET: { 1782 u_int32_t a = ntohl(addr->addr32[0]); 1783 printf("%u.%u.%u.%u", (a>>24)&255, (a>>16)&255, 1784 (a>>8)&255, a&255); 1785 if (p) { 1786 p = ntohs(p); 1787 printf(":%u", p); 1788 } 1789 break; 1790 } 1791#endif /* INET */ 1792#ifdef INET6 1793 case AF_INET6: { 1794 u_int16_t b; 1795 u_int8_t i, curstart, curend, maxstart, maxend; 1796 curstart = curend = maxstart = maxend = 255; 1797 for (i = 0; i < 8; i++) { 1798 if (!addr->addr16[i]) { 1799 if (curstart == 255) 1800 curstart = i; 1801 curend = i; 1802 } else { 1803 if ((curend - curstart) > 1804 (maxend - maxstart)) { 1805 maxstart = curstart; 1806 maxend = curend; 1807 } 1808 curstart = curend = 255; 1809 } 1810 } 1811 if ((curend - curstart) > 1812 (maxend - maxstart)) { 1813 maxstart = curstart; 1814 maxend = curend; 1815 } 1816 for (i = 0; i < 8; i++) { 1817 if (i >= maxstart && i <= maxend) { 1818 if (i == 0) 1819 printf(":"); 1820 if (i == maxend) 1821 printf(":"); 1822 } else { 1823 b = ntohs(addr->addr16[i]); 1824 printf("%x", b); 1825 if (i < 7) 1826 printf(":"); 1827 } 1828 } 1829 if (p) { 1830 p = ntohs(p); 1831 printf("[%u]", p); 1832 } 1833 break; 1834 } 1835#endif /* INET6 */ 1836 } 1837} 1838 1839void 1840pf_print_state(struct pf_state *s) 1841{ 1842 pf_print_state_parts(s, NULL, NULL); 1843} 1844 1845void 1846pf_print_state_parts(struct pf_state *s, 1847 struct pf_state_key *skwp, struct pf_state_key *sksp) 1848{ 1849 struct pf_state_key *skw, *sks; 1850 u_int8_t proto, dir; 1851 1852 /* Do our best to fill these, but they're skipped if NULL */ 1853 skw = skwp ? skwp : (s ? s->key[PF_SK_WIRE] : NULL); 1854 sks = sksp ? sksp : (s ? s->key[PF_SK_STACK] : NULL); 1855 proto = skw ? skw->proto : (sks ? sks->proto : 0); 1856 dir = s ? s->direction : 0; 1857 1858 switch (proto) { 1859 case IPPROTO_IPV4: 1860 printf("IPv4"); 1861 break; 1862 case IPPROTO_IPV6: 1863 printf("IPv6"); 1864 break; 1865 case IPPROTO_TCP: 1866 printf("TCP"); 1867 break; 1868 case IPPROTO_UDP: 1869 printf("UDP"); 1870 break; 1871 case IPPROTO_ICMP: 1872 printf("ICMP"); 1873 break; 1874 case IPPROTO_ICMPV6: 1875 printf("ICMPv6"); 1876 break; 1877 default: 1878 printf("%u", skw->proto); 1879 break; 1880 } 1881 switch (dir) { 1882 case PF_IN: 1883 printf(" in"); 1884 break; 1885 case PF_OUT: 1886 printf(" out"); 1887 break; 1888 } 1889 if (skw) { 1890 printf(" wire: "); 1891 pf_print_host(&skw->addr[0], skw->port[0], skw->af); 1892 printf(" "); 1893 pf_print_host(&skw->addr[1], skw->port[1], skw->af); 1894 } 1895 if (sks) { 1896 printf(" stack: "); 1897 if (sks != skw) { 1898 pf_print_host(&sks->addr[0], sks->port[0], sks->af); 1899 printf(" "); 1900 pf_print_host(&sks->addr[1], sks->port[1], sks->af); 1901 } else 1902 printf("-"); 1903 } 1904 if (s) { 1905 if (proto == IPPROTO_TCP) { 1906 printf(" [lo=%u high=%u win=%u modulator=%u", 1907 s->src.seqlo, s->src.seqhi, 1908 s->src.max_win, s->src.seqdiff); 1909 if (s->src.wscale && s->dst.wscale) 1910 printf(" wscale=%u", 1911 s->src.wscale & PF_WSCALE_MASK); 1912 printf("]"); 1913 printf(" [lo=%u high=%u win=%u modulator=%u", 1914 s->dst.seqlo, s->dst.seqhi, 1915 s->dst.max_win, s->dst.seqdiff); 1916 if (s->src.wscale && s->dst.wscale) 1917 printf(" wscale=%u", 1918 s->dst.wscale & PF_WSCALE_MASK); 1919 printf("]"); 1920 } 1921 printf(" %u:%u", s->src.state, s->dst.state); 1922 } 1923} 1924 1925void 1926pf_print_flags(u_int8_t f) 1927{ 1928 if (f) 1929 printf(" "); 1930 if (f & TH_FIN) 1931 printf("F"); 1932 if (f & TH_SYN) 1933 printf("S"); 1934 if (f & TH_RST) 1935 printf("R"); 1936 if (f & TH_PUSH) 1937 printf("P"); 1938 if (f & TH_ACK) 1939 printf("A"); 1940 if (f & TH_URG) 1941 printf("U"); 1942 if (f & TH_ECE) 1943 printf("E"); 1944 if (f & TH_CWR) 1945 printf("W"); 1946} 1947 1948#define PF_SET_SKIP_STEPS(i) \ 1949 do { \ 1950 while (head[i] != cur) { \ 1951 head[i]->skip[i].ptr = cur; \ 1952 head[i] = TAILQ_NEXT(head[i], entries); \ 1953 } \ 1954 } while (0) 1955 1956void 1957pf_calc_skip_steps(struct pf_rulequeue *rules) 1958{ 1959 struct pf_rule *cur, *prev, *head[PF_SKIP_COUNT]; 1960 int i; 1961 1962 cur = TAILQ_FIRST(rules); 1963 prev = cur; 1964 for (i = 0; i < PF_SKIP_COUNT; ++i) 1965 head[i] = cur; 1966 while (cur != NULL) { 1967 1968 if (cur->kif != prev->kif || cur->ifnot != prev->ifnot) 1969 PF_SET_SKIP_STEPS(PF_SKIP_IFP); 1970 if (cur->direction != prev->direction) 1971 PF_SET_SKIP_STEPS(PF_SKIP_DIR); 1972 if (cur->af != prev->af) 1973 PF_SET_SKIP_STEPS(PF_SKIP_AF); 1974 if (cur->proto != prev->proto) 1975 PF_SET_SKIP_STEPS(PF_SKIP_PROTO); 1976 if (cur->src.neg != prev->src.neg || 1977 pf_addr_wrap_neq(&cur->src.addr, &prev->src.addr)) 1978 PF_SET_SKIP_STEPS(PF_SKIP_SRC_ADDR); 1979 if (cur->src.port[0] != prev->src.port[0] || 1980 cur->src.port[1] != prev->src.port[1] || 1981 cur->src.port_op != prev->src.port_op) 1982 PF_SET_SKIP_STEPS(PF_SKIP_SRC_PORT); 1983 if (cur->dst.neg != prev->dst.neg || 1984 pf_addr_wrap_neq(&cur->dst.addr, &prev->dst.addr)) 1985 PF_SET_SKIP_STEPS(PF_SKIP_DST_ADDR); 1986 if (cur->dst.port[0] != prev->dst.port[0] || 1987 cur->dst.port[1] != prev->dst.port[1] || 1988 cur->dst.port_op != prev->dst.port_op) 1989 PF_SET_SKIP_STEPS(PF_SKIP_DST_PORT); 1990 1991 prev = cur; 1992 cur = TAILQ_NEXT(cur, entries); 1993 } 1994 for (i = 0; i < PF_SKIP_COUNT; ++i) 1995 PF_SET_SKIP_STEPS(i); 1996} 1997 1998int 1999pf_addr_wrap_neq(struct pf_addr_wrap *aw1, struct pf_addr_wrap *aw2) 2000{ 2001 if (aw1->type != aw2->type) 2002 return (1); 2003 switch (aw1->type) { 2004 case PF_ADDR_ADDRMASK: 2005 case PF_ADDR_RANGE: 2006 if (PF_ANEQ(&aw1->v.a.addr, &aw2->v.a.addr, 0)) 2007 return (1); 2008 if (PF_ANEQ(&aw1->v.a.mask, &aw2->v.a.mask, 0)) 2009 return (1); 2010 return (0); 2011 case PF_ADDR_DYNIFTL: 2012 return (aw1->p.dyn->pfid_kt != aw2->p.dyn->pfid_kt); 2013 case PF_ADDR_NOROUTE: 2014 case PF_ADDR_URPFFAILED: 2015 return (0); 2016 case PF_ADDR_TABLE: 2017 return (aw1->p.tbl != aw2->p.tbl); 2018 case PF_ADDR_RTLABEL: 2019 return (aw1->v.rtlabel != aw2->v.rtlabel); 2020 default: 2021 printf("invalid address type: %d\n", aw1->type); 2022 return (1); 2023 } 2024} 2025 2026u_int16_t 2027pf_cksum_fixup(u_int16_t cksum, u_int16_t old, u_int16_t new, u_int8_t udp) 2028{ 2029 u_int32_t l; 2030 2031 if (udp && !cksum) 2032 return (0x0000); 2033 l = cksum + old - new; 2034 l = (l >> 16) + (l & 65535); 2035 l = l & 65535; 2036 if (udp && !l) 2037 return (0xFFFF); 2038 return (l); 2039} 2040 2041void 2042pf_change_ap(struct pf_addr *a, u_int16_t *p, u_int16_t *ic, u_int16_t *pc, 2043 struct pf_addr *an, u_int16_t pn, u_int8_t u, sa_family_t af) 2044{ 2045 struct pf_addr ao; 2046 u_int16_t po = *p; 2047 2048 PF_ACPY(&ao, a, af); 2049 PF_ACPY(a, an, af); 2050 2051 *p = pn; 2052 2053 switch (af) { 2054#ifdef INET 2055 case AF_INET: 2056 *ic = pf_cksum_fixup(pf_cksum_fixup(*ic, 2057 ao.addr16[0], an->addr16[0], 0), 2058 ao.addr16[1], an->addr16[1], 0); 2059 *p = pn; 2060 *pc = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(*pc, 2061 ao.addr16[0], an->addr16[0], u), 2062 ao.addr16[1], an->addr16[1], u), 2063 po, pn, u); 2064 break; 2065#endif /* INET */ 2066#ifdef INET6 2067 case AF_INET6: 2068 *pc = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup( 2069 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup( 2070 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup(*pc, 2071 ao.addr16[0], an->addr16[0], u), 2072 ao.addr16[1], an->addr16[1], u), 2073 ao.addr16[2], an->addr16[2], u), 2074 ao.addr16[3], an->addr16[3], u), 2075 ao.addr16[4], an->addr16[4], u), 2076 ao.addr16[5], an->addr16[5], u), 2077 ao.addr16[6], an->addr16[6], u), 2078 ao.addr16[7], an->addr16[7], u), 2079 po, pn, u); 2080 break; 2081#endif /* INET6 */ 2082 } 2083} 2084 2085 2086/* Changes a u_int32_t. Uses a void * so there are no align restrictions */ 2087void 2088pf_change_a(void *a, u_int16_t *c, u_int32_t an, u_int8_t u) 2089{ 2090 u_int32_t ao; 2091 2092 memcpy(&ao, a, sizeof(ao)); 2093 memcpy(a, &an, sizeof(u_int32_t)); 2094 *c = pf_cksum_fixup(pf_cksum_fixup(*c, ao / 65536, an / 65536, u), 2095 ao % 65536, an % 65536, u); 2096} 2097 2098#ifdef INET6 2099void 2100pf_change_a6(struct pf_addr *a, u_int16_t *c, struct pf_addr *an, u_int8_t u) 2101{ 2102 struct pf_addr ao; 2103 2104 PF_ACPY(&ao, a, AF_INET6); 2105 PF_ACPY(a, an, AF_INET6); 2106 2107 *c = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup( 2108 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup( 2109 pf_cksum_fixup(pf_cksum_fixup(*c, 2110 ao.addr16[0], an->addr16[0], u), 2111 ao.addr16[1], an->addr16[1], u), 2112 ao.addr16[2], an->addr16[2], u), 2113 ao.addr16[3], an->addr16[3], u), 2114 ao.addr16[4], an->addr16[4], u), 2115 ao.addr16[5], an->addr16[5], u), 2116 ao.addr16[6], an->addr16[6], u), 2117 ao.addr16[7], an->addr16[7], u); 2118} 2119#endif /* INET6 */ 2120 2121void 2122pf_change_icmp(struct pf_addr *ia, u_int16_t *ip, struct pf_addr *oa, 2123 struct pf_addr *na, u_int16_t np, u_int16_t *pc, u_int16_t *h2c, 2124 u_int16_t *ic, u_int16_t *hc, u_int8_t u, sa_family_t af) 2125{ 2126 struct pf_addr oia, ooa; 2127 2128 PF_ACPY(&oia, ia, af); 2129 if (oa) 2130 PF_ACPY(&ooa, oa, af); 2131 2132 /* Change inner protocol port, fix inner protocol checksum. */ 2133 if (ip != NULL) { 2134 u_int16_t oip = *ip; 2135 u_int32_t opc; 2136 2137 if (pc != NULL) 2138 opc = *pc; 2139 *ip = np; 2140 if (pc != NULL) 2141 *pc = pf_cksum_fixup(*pc, oip, *ip, u); 2142 *ic = pf_cksum_fixup(*ic, oip, *ip, 0); 2143 if (pc != NULL) 2144 *ic = pf_cksum_fixup(*ic, opc, *pc, 0); 2145 } 2146 /* Change inner ip address, fix inner ip and icmp checksums. */ 2147 PF_ACPY(ia, na, af); 2148 switch (af) { 2149#ifdef INET 2150 case AF_INET: { 2151 u_int32_t oh2c = *h2c; 2152 2153 *h2c = pf_cksum_fixup(pf_cksum_fixup(*h2c, 2154 oia.addr16[0], ia->addr16[0], 0), 2155 oia.addr16[1], ia->addr16[1], 0); 2156 *ic = pf_cksum_fixup(pf_cksum_fixup(*ic, 2157 oia.addr16[0], ia->addr16[0], 0), 2158 oia.addr16[1], ia->addr16[1], 0); 2159 *ic = pf_cksum_fixup(*ic, oh2c, *h2c, 0); 2160 break; 2161 } 2162#endif /* INET */ 2163#ifdef INET6 2164 case AF_INET6: 2165 *ic = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup( 2166 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup( 2167 pf_cksum_fixup(pf_cksum_fixup(*ic, 2168 oia.addr16[0], ia->addr16[0], u), 2169 oia.addr16[1], ia->addr16[1], u), 2170 oia.addr16[2], ia->addr16[2], u), 2171 oia.addr16[3], ia->addr16[3], u), 2172 oia.addr16[4], ia->addr16[4], u), 2173 oia.addr16[5], ia->addr16[5], u), 2174 oia.addr16[6], ia->addr16[6], u), 2175 oia.addr16[7], ia->addr16[7], u); 2176 break; 2177#endif /* INET6 */ 2178 } 2179 /* Outer ip address, fix outer ip or icmpv6 checksum, if necessary. */ 2180 if (oa) { 2181 PF_ACPY(oa, na, af); 2182 switch (af) { 2183#ifdef INET 2184 case AF_INET: 2185 *hc = pf_cksum_fixup(pf_cksum_fixup(*hc, 2186 ooa.addr16[0], oa->addr16[0], 0), 2187 ooa.addr16[1], oa->addr16[1], 0); 2188 break; 2189#endif /* INET */ 2190#ifdef INET6 2191 case AF_INET6: 2192 *ic = pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup( 2193 pf_cksum_fixup(pf_cksum_fixup(pf_cksum_fixup( 2194 pf_cksum_fixup(pf_cksum_fixup(*ic, 2195 ooa.addr16[0], oa->addr16[0], u), 2196 ooa.addr16[1], oa->addr16[1], u), 2197 ooa.addr16[2], oa->addr16[2], u), 2198 ooa.addr16[3], oa->addr16[3], u), 2199 ooa.addr16[4], oa->addr16[4], u), 2200 ooa.addr16[5], oa->addr16[5], u), 2201 ooa.addr16[6], oa->addr16[6], u), 2202 ooa.addr16[7], oa->addr16[7], u); 2203 break; 2204#endif /* INET6 */ 2205 } 2206 } 2207} 2208 2209 2210/* 2211 * Need to modulate the sequence numbers in the TCP SACK option 2212 * (credits to Krzysztof Pfaff for report and patch) 2213 */ 2214int 2215pf_modulate_sack(struct mbuf *m, int off, struct pf_pdesc *pd, 2216 struct tcphdr *th, struct pf_state_peer *dst) 2217{ 2218 int hlen = (th->th_off << 2) - sizeof(*th), thoptlen = hlen; 2219#ifdef __FreeBSD__ 2220 u_int8_t opts[TCP_MAXOLEN], *opt = opts; 2221#else 2222 u_int8_t opts[MAX_TCPOPTLEN], *opt = opts; 2223#endif 2224 int copyback = 0, i, olen; 2225 struct sackblk sack; 2226 2227#define TCPOLEN_SACKLEN (TCPOLEN_SACK + 2) 2228 if (hlen < TCPOLEN_SACKLEN || 2229 !pf_pull_hdr(m, off + sizeof(*th), opts, hlen, NULL, NULL, pd->af)) 2230 return 0; 2231 2232 while (hlen >= TCPOLEN_SACKLEN) { 2233 olen = opt[1]; 2234 switch (*opt) { 2235 case TCPOPT_EOL: /* FALLTHROUGH */ 2236 case TCPOPT_NOP: 2237 opt++; 2238 hlen--; 2239 break; 2240 case TCPOPT_SACK: 2241 if (olen > hlen) 2242 olen = hlen; 2243 if (olen >= TCPOLEN_SACKLEN) { 2244 for (i = 2; i + TCPOLEN_SACK <= olen; 2245 i += TCPOLEN_SACK) { 2246 memcpy(&sack, &opt[i], sizeof(sack)); 2247 pf_change_a(&sack.start, &th->th_sum, 2248 htonl(ntohl(sack.start) - 2249 dst->seqdiff), 0); 2250 pf_change_a(&sack.end, &th->th_sum, 2251 htonl(ntohl(sack.end) - 2252 dst->seqdiff), 0); 2253 memcpy(&opt[i], &sack, sizeof(sack)); 2254 } 2255 copyback = 1; 2256 } 2257 /* FALLTHROUGH */ 2258 default: 2259 if (olen < 2) 2260 olen = 2; 2261 hlen -= olen; 2262 opt += olen; 2263 } 2264 } 2265 2266 if (copyback) 2267#ifdef __FreeBSD__ 2268 m_copyback(m, off + sizeof(*th), thoptlen, (caddr_t)opts); 2269#else 2270 m_copyback(m, off + sizeof(*th), thoptlen, opts); 2271#endif 2272 return (copyback); 2273} 2274 2275void 2276#ifdef __FreeBSD__ 2277pf_send_tcp(struct mbuf *replyto, const struct pf_rule *r, sa_family_t af, 2278#else 2279pf_send_tcp(const struct pf_rule *r, sa_family_t af, 2280#endif 2281 const struct pf_addr *saddr, const struct pf_addr *daddr, 2282 u_int16_t sport, u_int16_t dport, u_int32_t seq, u_int32_t ack, 2283 u_int8_t flags, u_int16_t win, u_int16_t mss, u_int8_t ttl, int tag, 2284 u_int16_t rtag, struct ether_header *eh, struct ifnet *ifp) 2285{ 2286 struct mbuf *m; 2287 int len, tlen; 2288#ifdef INET 2289 struct ip *h; 2290#endif /* INET */ 2291#ifdef INET6 2292 struct ip6_hdr *h6; 2293#endif /* INET6 */ 2294 struct tcphdr *th; 2295 char *opt; 2296#ifdef __FreeBSD__ 2297 struct pf_mtag *pf_mtag; 2298 2299 KASSERT( 2300#ifdef INET 2301 af == AF_INET 2302#else 2303 0 2304#endif 2305 || 2306#ifdef INET6 2307 af == AF_INET6 2308#else 2309 0 2310#endif 2311 , ("Unsupported AF %d", af)); 2312 len = 0; 2313 th = NULL; 2314#ifdef INET 2315 h = NULL; 2316#endif 2317#ifdef INET6 2318 h6 = NULL; 2319#endif 2320#endif /* __FreeBSD__ */ 2321 2322 /* maximum segment size tcp option */ 2323 tlen = sizeof(struct tcphdr); 2324 if (mss) 2325 tlen += 4; 2326 2327 switch (af) { 2328#ifdef INET 2329 case AF_INET: 2330 len = sizeof(struct ip) + tlen; 2331 break; 2332#endif /* INET */ 2333#ifdef INET6 2334 case AF_INET6: 2335 len = sizeof(struct ip6_hdr) + tlen; 2336 break; 2337#endif /* INET6 */ 2338 } 2339 2340 /* create outgoing mbuf */ 2341 m = m_gethdr(M_DONTWAIT, MT_HEADER); 2342 if (m == NULL) 2343 return; 2344#ifdef __FreeBSD__ 2345#ifdef MAC 2346 mac_netinet_firewall_send(m); 2347#endif 2348 if ((pf_mtag = pf_get_mtag(m)) == NULL) { 2349 m_freem(m); 2350 return; 2351 } 2352#endif 2353 if (tag) 2354#ifdef __FreeBSD__ 2355 m->m_flags |= M_SKIP_FIREWALL; 2356 pf_mtag->tag = rtag; 2357#else 2358 m->m_pkthdr.pf.flags |= PF_TAG_GENERATED; 2359 m->m_pkthdr.pf.tag = rtag; 2360#endif 2361 2362 if (r != NULL && r->rtableid >= 0) 2363#ifdef __FreeBSD__ 2364 { 2365 M_SETFIB(m, r->rtableid); 2366 pf_mtag->rtableid = r->rtableid; 2367#else 2368 m->m_pkthdr.pf.rtableid = r->rtableid; 2369#endif 2370#ifdef __FreeBSD__ 2371 } 2372#endif 2373 2374#ifdef ALTQ 2375 if (r != NULL && r->qid) { 2376#ifdef __FreeBSD__ 2377 pf_mtag->qid = r->qid; 2378 2379 /* add hints for ecn */ 2380 pf_mtag->hdr = mtod(m, struct ip *); 2381#else 2382 m->m_pkthdr.pf.qid = r->qid; 2383 /* add hints for ecn */ 2384 m->m_pkthdr.pf.hdr = mtod(m, struct ip *); 2385#endif 2386 } 2387#endif /* ALTQ */ 2388 m->m_data += max_linkhdr; 2389 m->m_pkthdr.len = m->m_len = len; 2390 m->m_pkthdr.rcvif = NULL; 2391 bzero(m->m_data, len); 2392 switch (af) { 2393#ifdef INET 2394 case AF_INET: 2395 h = mtod(m, struct ip *); 2396 2397 /* IP header fields included in the TCP checksum */ 2398 h->ip_p = IPPROTO_TCP; 2399 h->ip_len = htons(tlen); 2400 h->ip_src.s_addr = saddr->v4.s_addr; 2401 h->ip_dst.s_addr = daddr->v4.s_addr; 2402 2403 th = (struct tcphdr *)((caddr_t)h + sizeof(struct ip)); 2404 break; 2405#endif /* INET */ 2406#ifdef INET6 2407 case AF_INET6: 2408 h6 = mtod(m, struct ip6_hdr *); 2409 2410 /* IP header fields included in the TCP checksum */ 2411 h6->ip6_nxt = IPPROTO_TCP; 2412 h6->ip6_plen = htons(tlen); 2413 memcpy(&h6->ip6_src, &saddr->v6, sizeof(struct in6_addr)); 2414 memcpy(&h6->ip6_dst, &daddr->v6, sizeof(struct in6_addr)); 2415 2416 th = (struct tcphdr *)((caddr_t)h6 + sizeof(struct ip6_hdr)); 2417 break; 2418#endif /* INET6 */ 2419 } 2420 2421 /* TCP header */ 2422 th->th_sport = sport; 2423 th->th_dport = dport; 2424 th->th_seq = htonl(seq); 2425 th->th_ack = htonl(ack); 2426 th->th_off = tlen >> 2; 2427 th->th_flags = flags; 2428 th->th_win = htons(win); 2429 2430 if (mss) { 2431 opt = (char *)(th + 1); 2432 opt[0] = TCPOPT_MAXSEG; 2433 opt[1] = 4; 2434 HTONS(mss); 2435 bcopy((caddr_t)&mss, (caddr_t)(opt + 2), 2); 2436 } 2437 2438 switch (af) { 2439#ifdef INET 2440 case AF_INET: 2441 /* TCP checksum */ 2442 th->th_sum = in_cksum(m, len); 2443 2444 /* Finish the IP header */ 2445 h->ip_v = 4; 2446 h->ip_hl = sizeof(*h) >> 2; 2447 h->ip_tos = IPTOS_LOWDELAY; 2448#ifdef __FreeBSD__ 2449 h->ip_off = V_path_mtu_discovery ? IP_DF : 0; 2450 h->ip_len = len; 2451 h->ip_ttl = ttl ? ttl : V_ip_defttl; 2452#else 2453 h->ip_len = htons(len); 2454 h->ip_off = htons(ip_mtudisc ? IP_DF : 0); 2455 h->ip_ttl = ttl ? ttl : ip_defttl; 2456#endif 2457 h->ip_sum = 0; 2458 if (eh == NULL) { 2459#ifdef __FreeBSD__ 2460 PF_UNLOCK(); 2461 ip_output(m, (void *)NULL, (void *)NULL, 0, 2462 (void *)NULL, (void *)NULL); 2463 PF_LOCK(); 2464#else /* ! __FreeBSD__ */ 2465 ip_output(m, (void *)NULL, (void *)NULL, 0, 2466 (void *)NULL, (void *)NULL); 2467#endif 2468 } else { 2469 struct route ro; 2470 struct rtentry rt; 2471 struct ether_header *e = (void *)ro.ro_dst.sa_data; 2472 2473 if (ifp == NULL) { 2474 m_freem(m); 2475 return; 2476 } 2477 rt.rt_ifp = ifp; 2478 ro.ro_rt = &rt; 2479 ro.ro_dst.sa_len = sizeof(ro.ro_dst); 2480 ro.ro_dst.sa_family = pseudo_AF_HDRCMPLT; 2481 bcopy(eh->ether_dhost, e->ether_shost, ETHER_ADDR_LEN); 2482 bcopy(eh->ether_shost, e->ether_dhost, ETHER_ADDR_LEN); 2483 e->ether_type = eh->ether_type; 2484#ifdef __FreeBSD__ 2485 PF_UNLOCK(); 2486 /* XXX_IMPORT: later */ 2487 ip_output(m, (void *)NULL, &ro, 0, 2488 (void *)NULL, (void *)NULL); 2489 PF_LOCK(); 2490#else /* ! __FreeBSD__ */ 2491 ip_output(m, (void *)NULL, &ro, IP_ROUTETOETHER, 2492 (void *)NULL, (void *)NULL); 2493#endif 2494 } 2495 break; 2496#endif /* INET */ 2497#ifdef INET6 2498 case AF_INET6: 2499 /* TCP checksum */ 2500 th->th_sum = in6_cksum(m, IPPROTO_TCP, 2501 sizeof(struct ip6_hdr), tlen); 2502 2503 h6->ip6_vfc |= IPV6_VERSION; 2504 h6->ip6_hlim = IPV6_DEFHLIM; 2505 2506#ifdef __FreeBSD__ 2507 PF_UNLOCK(); 2508 ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL); 2509 PF_LOCK(); 2510#else 2511 ip6_output(m, NULL, NULL, 0, NULL, NULL, NULL); 2512#endif 2513 break; 2514#endif /* INET6 */ 2515 } 2516} 2517 2518static void 2519pf_send_icmp(struct mbuf *m, u_int8_t type, u_int8_t code, sa_family_t af, 2520 struct pf_rule *r) 2521{ 2522 struct mbuf *m0; 2523#ifdef __FreeBSD__ 2524#ifdef INET 2525 struct ip *ip; 2526#endif 2527 struct pf_mtag *pf_mtag; 2528#endif 2529 2530#ifdef __FreeBSD__ 2531 m0 = m_copypacket(m, M_DONTWAIT); 2532 if (m0 == NULL) 2533 return; 2534#else 2535 if ((m0 = m_copy(m, 0, M_COPYALL)) == NULL) 2536 return; 2537#endif 2538 2539#ifdef __FreeBSD__ 2540 if ((pf_mtag = pf_get_mtag(m0)) == NULL) 2541 return; 2542 /* XXX: revisit */ 2543 m0->m_flags |= M_SKIP_FIREWALL; 2544#else 2545 m0->m_pkthdr.pf.flags |= PF_TAG_GENERATED; 2546#endif 2547 2548 if (r->rtableid >= 0) 2549#ifdef __FreeBSD__ 2550 { 2551 M_SETFIB(m0, r->rtableid); 2552 pf_mtag->rtableid = r->rtableid; 2553#else 2554 m0->m_pkthdr.pf.rtableid = r->rtableid; 2555#endif 2556#ifdef __FreeBSD__ 2557 } 2558#endif 2559 2560#ifdef ALTQ 2561 if (r->qid) { 2562#ifdef __FreeBSD__ 2563 pf_mtag->qid = r->qid; 2564 /* add hints for ecn */ 2565 pf_mtag->hdr = mtod(m0, struct ip *); 2566#else 2567 m0->m_pkthdr.pf.qid = r->qid; 2568 /* add hints for ecn */ 2569 m0->m_pkthdr.pf.hdr = mtod(m0, struct ip *); 2570#endif 2571 } 2572#endif /* ALTQ */ 2573 2574 switch (af) { 2575#ifdef INET 2576 case AF_INET: 2577#ifdef __FreeBSD__ 2578 /* icmp_error() expects host byte ordering */ 2579 ip = mtod(m0, struct ip *); 2580 NTOHS(ip->ip_len); 2581 NTOHS(ip->ip_off); 2582 PF_UNLOCK(); 2583 icmp_error(m0, type, code, 0, 0); 2584 PF_LOCK(); 2585#else 2586 icmp_error(m0, type, code, 0, 0); 2587#endif 2588 break; 2589#endif /* INET */ 2590#ifdef INET6 2591 case AF_INET6: 2592#ifdef __FreeBSD__ 2593 PF_UNLOCK(); 2594#endif 2595 icmp6_error(m0, type, code, 0); 2596#ifdef __FreeBSD__ 2597 PF_LOCK(); 2598#endif 2599 break; 2600#endif /* INET6 */ 2601 } 2602} 2603 2604/* 2605 * Return 1 if the addresses a and b match (with mask m), otherwise return 0. 2606 * If n is 0, they match if they are equal. If n is != 0, they match if they 2607 * are different. 2608 */ 2609int 2610pf_match_addr(u_int8_t n, struct pf_addr *a, struct pf_addr *m, 2611 struct pf_addr *b, sa_family_t af) 2612{ 2613 int match = 0; 2614 2615 switch (af) { 2616#ifdef INET 2617 case AF_INET: 2618 if ((a->addr32[0] & m->addr32[0]) == 2619 (b->addr32[0] & m->addr32[0])) 2620 match++; 2621 break; 2622#endif /* INET */ 2623#ifdef INET6 2624 case AF_INET6: 2625 if (((a->addr32[0] & m->addr32[0]) == 2626 (b->addr32[0] & m->addr32[0])) && 2627 ((a->addr32[1] & m->addr32[1]) == 2628 (b->addr32[1] & m->addr32[1])) && 2629 ((a->addr32[2] & m->addr32[2]) == 2630 (b->addr32[2] & m->addr32[2])) && 2631 ((a->addr32[3] & m->addr32[3]) == 2632 (b->addr32[3] & m->addr32[3]))) 2633 match++; 2634 break; 2635#endif /* INET6 */ 2636 } 2637 if (match) { 2638 if (n) 2639 return (0); 2640 else 2641 return (1); 2642 } else { 2643 if (n) 2644 return (1); 2645 else 2646 return (0); 2647 } 2648} 2649 2650/* 2651 * Return 1 if b <= a <= e, otherwise return 0. 2652 */ 2653int 2654pf_match_addr_range(struct pf_addr *b, struct pf_addr *e, 2655 struct pf_addr *a, sa_family_t af) 2656{ 2657 switch (af) { 2658#ifdef INET 2659 case AF_INET: 2660 if ((a->addr32[0] < b->addr32[0]) || 2661 (a->addr32[0] > e->addr32[0])) 2662 return (0); 2663 break; 2664#endif /* INET */ 2665#ifdef INET6 2666 case AF_INET6: { 2667 int i; 2668 2669 /* check a >= b */ 2670 for (i = 0; i < 4; ++i) 2671 if (a->addr32[i] > b->addr32[i]) 2672 break; 2673 else if (a->addr32[i] < b->addr32[i]) 2674 return (0); 2675 /* check a <= e */ 2676 for (i = 0; i < 4; ++i) 2677 if (a->addr32[i] < e->addr32[i]) 2678 break; 2679 else if (a->addr32[i] > e->addr32[i]) 2680 return (0); 2681 break; 2682 } 2683#endif /* INET6 */ 2684 } 2685 return (1); 2686} 2687 2688int 2689pf_match(u_int8_t op, u_int32_t a1, u_int32_t a2, u_int32_t p) 2690{ 2691 switch (op) { 2692 case PF_OP_IRG: 2693 return ((p > a1) && (p < a2)); 2694 case PF_OP_XRG: 2695 return ((p < a1) || (p > a2)); 2696 case PF_OP_RRG: 2697 return ((p >= a1) && (p <= a2)); 2698 case PF_OP_EQ: 2699 return (p == a1); 2700 case PF_OP_NE: 2701 return (p != a1); 2702 case PF_OP_LT: 2703 return (p < a1); 2704 case PF_OP_LE: 2705 return (p <= a1); 2706 case PF_OP_GT: 2707 return (p > a1); 2708 case PF_OP_GE: 2709 return (p >= a1); 2710 } 2711 return (0); /* never reached */ 2712} 2713 2714int 2715pf_match_port(u_int8_t op, u_int16_t a1, u_int16_t a2, u_int16_t p) 2716{ 2717 NTOHS(a1); 2718 NTOHS(a2); 2719 NTOHS(p); 2720 return (pf_match(op, a1, a2, p)); 2721} 2722 2723int 2724pf_match_uid(u_int8_t op, uid_t a1, uid_t a2, uid_t u) 2725{ 2726 if (u == UID_MAX && op != PF_OP_EQ && op != PF_OP_NE) 2727 return (0); 2728 return (pf_match(op, a1, a2, u)); 2729} 2730 2731int 2732pf_match_gid(u_int8_t op, gid_t a1, gid_t a2, gid_t g) 2733{ 2734 if (g == GID_MAX && op != PF_OP_EQ && op != PF_OP_NE) 2735 return (0); 2736 return (pf_match(op, a1, a2, g)); 2737} 2738 2739int 2740#ifdef __FreeBSD__ 2741pf_match_tag(struct mbuf *m, struct pf_rule *r, int *tag, 2742 struct pf_mtag *pf_mtag) 2743#else 2744pf_match_tag(struct mbuf *m, struct pf_rule *r, int *tag) 2745#endif 2746{ 2747 if (*tag == -1) 2748#ifdef __FreeBSD__ 2749 *tag = pf_mtag->tag; 2750#else 2751 *tag = m->m_pkthdr.pf.tag; 2752#endif 2753 2754 return ((!r->match_tag_not && r->match_tag == *tag) || 2755 (r->match_tag_not && r->match_tag != *tag)); 2756} 2757 2758int 2759#ifdef __FreeBSD__ 2760pf_tag_packet(struct mbuf *m, int tag, int rtableid, 2761 struct pf_mtag *pf_mtag) 2762#else 2763pf_tag_packet(struct mbuf *m, int tag, int rtableid) 2764#endif 2765{ 2766 if (tag <= 0 && rtableid < 0) 2767 return (0); 2768 2769 if (tag > 0) 2770#ifdef __FreeBSD__ 2771 pf_mtag->tag = tag; 2772#else 2773 m->m_pkthdr.pf.tag = tag; 2774#endif 2775 if (rtableid >= 0) 2776#ifdef __FreeBSD__ 2777 { 2778 M_SETFIB(m, rtableid); 2779 } 2780#else 2781 m->m_pkthdr.pf.rtableid = rtableid; 2782#endif 2783 2784 return (0); 2785} 2786 2787void 2788pf_step_into_anchor(int *depth, struct pf_ruleset **rs, int n, 2789 struct pf_rule **r, struct pf_rule **a, int *match) 2790{ 2791 struct pf_anchor_stackframe *f; 2792 2793 (*r)->anchor->match = 0; 2794 if (match) 2795 *match = 0; 2796#ifdef __FreeBSD__ 2797 if (*depth >= sizeof(V_pf_anchor_stack) / 2798 sizeof(V_pf_anchor_stack[0])) { 2799#else 2800 if (*depth >= sizeof(pf_anchor_stack) / 2801 sizeof(pf_anchor_stack[0])) { 2802#endif 2803 printf("pf_step_into_anchor: stack overflow\n"); 2804 *r = TAILQ_NEXT(*r, entries); 2805 return; 2806 } else if (*depth == 0 && a != NULL) 2807 *a = *r; 2808#ifdef __FreeBSD__ 2809 f = V_pf_anchor_stack + (*depth)++; 2810#else 2811 f = pf_anchor_stack + (*depth)++; 2812#endif 2813 f->rs = *rs; 2814 f->r = *r; 2815 if ((*r)->anchor_wildcard) { 2816 f->parent = &(*r)->anchor->children; 2817 if ((f->child = RB_MIN(pf_anchor_node, f->parent)) == 2818 NULL) { 2819 *r = NULL; 2820 return; 2821 } 2822 *rs = &f->child->ruleset; 2823 } else { 2824 f->parent = NULL; 2825 f->child = NULL; 2826 *rs = &(*r)->anchor->ruleset; 2827 } 2828 *r = TAILQ_FIRST((*rs)->rules[n].active.ptr); 2829} 2830 2831int 2832pf_step_out_of_anchor(int *depth, struct pf_ruleset **rs, int n, 2833 struct pf_rule **r, struct pf_rule **a, int *match) 2834{ 2835 struct pf_anchor_stackframe *f; 2836 int quick = 0; 2837 2838 do { 2839 if (*depth <= 0) 2840 break; 2841#ifdef __FreeBSD__ 2842 f = V_pf_anchor_stack + *depth - 1; 2843#else 2844 f = pf_anchor_stack + *depth - 1; 2845#endif 2846 if (f->parent != NULL && f->child != NULL) { 2847 if (f->child->match || 2848 (match != NULL && *match)) { 2849 f->r->anchor->match = 1; 2850 *match = 0; 2851 } 2852 f->child = RB_NEXT(pf_anchor_node, f->parent, f->child); 2853 if (f->child != NULL) { 2854 *rs = &f->child->ruleset; 2855 *r = TAILQ_FIRST((*rs)->rules[n].active.ptr); 2856 if (*r == NULL) 2857 continue; 2858 else 2859 break; 2860 } 2861 } 2862 (*depth)--; 2863 if (*depth == 0 && a != NULL) 2864 *a = NULL; 2865 *rs = f->rs; 2866 if (f->r->anchor->match || (match != NULL && *match)) 2867 quick = f->r->quick; 2868 *r = TAILQ_NEXT(f->r, entries); 2869 } while (*r == NULL); 2870 2871 return (quick); 2872} 2873 2874#ifdef INET6 2875void 2876pf_poolmask(struct pf_addr *naddr, struct pf_addr *raddr, 2877 struct pf_addr *rmask, struct pf_addr *saddr, sa_family_t af) 2878{ 2879 switch (af) { 2880#ifdef INET 2881 case AF_INET: 2882 naddr->addr32[0] = (raddr->addr32[0] & rmask->addr32[0]) | 2883 ((rmask->addr32[0] ^ 0xffffffff ) & saddr->addr32[0]); 2884 break; 2885#endif /* INET */ 2886 case AF_INET6: 2887 naddr->addr32[0] = (raddr->addr32[0] & rmask->addr32[0]) | 2888 ((rmask->addr32[0] ^ 0xffffffff ) & saddr->addr32[0]); 2889 naddr->addr32[1] = (raddr->addr32[1] & rmask->addr32[1]) | 2890 ((rmask->addr32[1] ^ 0xffffffff ) & saddr->addr32[1]); 2891 naddr->addr32[2] = (raddr->addr32[2] & rmask->addr32[2]) | 2892 ((rmask->addr32[2] ^ 0xffffffff ) & saddr->addr32[2]); 2893 naddr->addr32[3] = (raddr->addr32[3] & rmask->addr32[3]) | 2894 ((rmask->addr32[3] ^ 0xffffffff ) & saddr->addr32[3]); 2895 break; 2896 } 2897} 2898 2899void 2900pf_addr_inc(struct pf_addr *addr, sa_family_t af) 2901{ 2902 switch (af) { 2903#ifdef INET 2904 case AF_INET: 2905 addr->addr32[0] = htonl(ntohl(addr->addr32[0]) + 1); 2906 break; 2907#endif /* INET */ 2908 case AF_INET6: 2909 if (addr->addr32[3] == 0xffffffff) { 2910 addr->addr32[3] = 0; 2911 if (addr->addr32[2] == 0xffffffff) { 2912 addr->addr32[2] = 0; 2913 if (addr->addr32[1] == 0xffffffff) { 2914 addr->addr32[1] = 0; 2915 addr->addr32[0] = 2916 htonl(ntohl(addr->addr32[0]) + 1); 2917 } else 2918 addr->addr32[1] = 2919 htonl(ntohl(addr->addr32[1]) + 1); 2920 } else 2921 addr->addr32[2] = 2922 htonl(ntohl(addr->addr32[2]) + 1); 2923 } else 2924 addr->addr32[3] = 2925 htonl(ntohl(addr->addr32[3]) + 1); 2926 break; 2927 } 2928} 2929#endif /* INET6 */ 2930 2931int 2932#ifdef __FreeBSD__ 2933pf_socket_lookup(int direction, struct pf_pdesc *pd, struct inpcb *inp_arg) 2934#else 2935pf_socket_lookup(int direction, struct pf_pdesc *pd) 2936#endif 2937{ 2938 struct pf_addr *saddr, *daddr; 2939 u_int16_t sport, dport; 2940#ifdef __FreeBSD__ 2941 struct inpcbinfo *pi; 2942#else 2943 struct inpcbtable *tb; 2944#endif 2945 struct inpcb *inp; 2946 2947 if (pd == NULL) 2948 return (-1); 2949 pd->lookup.uid = UID_MAX; 2950 pd->lookup.gid = GID_MAX; 2951 pd->lookup.pid = NO_PID; 2952 2953#ifdef __FreeBSD__ 2954 if (inp_arg != NULL) { 2955 INP_LOCK_ASSERT(inp_arg); 2956 pd->lookup.uid = inp_arg->inp_cred->cr_uid; 2957 pd->lookup.gid = inp_arg->inp_cred->cr_groups[0]; 2958 return (1); 2959 } 2960#endif 2961 2962 switch (pd->proto) { 2963 case IPPROTO_TCP: 2964 if (pd->hdr.tcp == NULL) 2965 return (-1); 2966 sport = pd->hdr.tcp->th_sport; 2967 dport = pd->hdr.tcp->th_dport; 2968#ifdef __FreeBSD__ 2969 pi = &V_tcbinfo; 2970#else 2971 tb = &tcbtable; 2972#endif 2973 break; 2974 case IPPROTO_UDP: 2975 if (pd->hdr.udp == NULL) 2976 return (-1); 2977 sport = pd->hdr.udp->uh_sport; 2978 dport = pd->hdr.udp->uh_dport; 2979#ifdef __FreeBSD__ 2980 pi = &V_udbinfo; 2981#else 2982 tb = &udbtable; 2983#endif 2984 break; 2985 default: 2986 return (-1); 2987 } 2988 if (direction == PF_IN) { 2989 saddr = pd->src; 2990 daddr = pd->dst; 2991 } else { 2992 u_int16_t p; 2993 2994 p = sport; 2995 sport = dport; 2996 dport = p; 2997 saddr = pd->dst; 2998 daddr = pd->src; 2999 } 3000 switch (pd->af) { 3001#ifdef INET 3002 case AF_INET: 3003#ifdef __FreeBSD__ 3004 /* 3005 * XXXRW: would be nice if we had an mbuf here so that we 3006 * could use in_pcblookup_mbuf(). 3007 */ 3008 inp = in_pcblookup(pi, saddr->v4, sport, daddr->v4, 3009 dport, INPLOOKUP_RLOCKPCB, NULL); 3010 if (inp == NULL) { 3011 inp = in_pcblookup(pi, saddr->v4, sport, 3012 daddr->v4, dport, INPLOOKUP_WILDCARD | 3013 INPLOOKUP_RLOCKPCB, NULL); 3014 if (inp == NULL) 3015 return (-1); 3016 } 3017#else 3018 inp = in_pcbhashlookup(tb, saddr->v4, sport, daddr->v4, dport); 3019 if (inp == NULL) { 3020 inp = in_pcblookup_listen(tb, daddr->v4, dport, 0, 3021 NULL); 3022 if (inp == NULL) 3023 return (-1); 3024 } 3025#endif 3026 break; 3027#endif /* INET */ 3028#ifdef INET6 3029 case AF_INET6: 3030#ifdef __FreeBSD__ 3031 /* 3032 * XXXRW: would be nice if we had an mbuf here so that we 3033 * could use in6_pcblookup_mbuf(). 3034 */ 3035 inp = in6_pcblookup(pi, &saddr->v6, sport, 3036 &daddr->v6, dport, INPLOOKUP_RLOCKPCB, NULL); 3037 if (inp == NULL) { 3038 inp = in6_pcblookup(pi, &saddr->v6, sport, 3039 &daddr->v6, dport, INPLOOKUP_WILDCARD | 3040 INPLOOKUP_RLOCKPCB, NULL); 3041 if (inp == NULL) 3042 return (-1); 3043 } 3044#else 3045 inp = in6_pcbhashlookup(tb, &saddr->v6, sport, &daddr->v6, 3046 dport); 3047 if (inp == NULL) { 3048 inp = in6_pcblookup_listen(tb, &daddr->v6, dport, 0, 3049 NULL); 3050 if (inp == NULL) 3051 return (-1); 3052 } 3053#endif 3054 break; 3055#endif /* INET6 */ 3056 3057 default: 3058 return (-1); 3059 } 3060#ifdef __FreeBSD__ 3061 INP_RLOCK_ASSERT(inp); 3062 pd->lookup.uid = inp->inp_cred->cr_uid; 3063 pd->lookup.gid = inp->inp_cred->cr_groups[0]; 3064 INP_RUNLOCK(inp); 3065#else 3066 pd->lookup.uid = inp->inp_socket->so_euid; 3067 pd->lookup.gid = inp->inp_socket->so_egid; 3068 pd->lookup.pid = inp->inp_socket->so_cpid; 3069#endif 3070 return (1); 3071} 3072 3073u_int8_t 3074pf_get_wscale(struct mbuf *m, int off, u_int16_t th_off, sa_family_t af) 3075{ 3076 int hlen; 3077 u_int8_t hdr[60]; 3078 u_int8_t *opt, optlen; 3079 u_int8_t wscale = 0; 3080 3081 hlen = th_off << 2; /* hlen <= sizeof(hdr) */ 3082 if (hlen <= sizeof(struct tcphdr)) 3083 return (0); 3084 if (!pf_pull_hdr(m, off, hdr, hlen, NULL, NULL, af)) 3085 return (0); 3086 opt = hdr + sizeof(struct tcphdr); 3087 hlen -= sizeof(struct tcphdr); 3088 while (hlen >= 3) { 3089 switch (*opt) { 3090 case TCPOPT_EOL: 3091 case TCPOPT_NOP: 3092 ++opt; 3093 --hlen; 3094 break; 3095 case TCPOPT_WINDOW: 3096 wscale = opt[2]; 3097 if (wscale > TCP_MAX_WINSHIFT) 3098 wscale = TCP_MAX_WINSHIFT; 3099 wscale |= PF_WSCALE_FLAG; 3100 /* FALLTHROUGH */ 3101 default: 3102 optlen = opt[1]; 3103 if (optlen < 2) 3104 optlen = 2; 3105 hlen -= optlen; 3106 opt += optlen; 3107 break; 3108 } 3109 } 3110 return (wscale); 3111} 3112 3113u_int16_t 3114pf_get_mss(struct mbuf *m, int off, u_int16_t th_off, sa_family_t af) 3115{ 3116 int hlen; 3117 u_int8_t hdr[60]; 3118 u_int8_t *opt, optlen; 3119#ifdef __FreeBSD__ 3120 u_int16_t mss = V_tcp_mssdflt; 3121#else 3122 u_int16_t mss = tcp_mssdflt; 3123#endif 3124 3125 hlen = th_off << 2; /* hlen <= sizeof(hdr) */ 3126 if (hlen <= sizeof(struct tcphdr)) 3127 return (0); 3128 if (!pf_pull_hdr(m, off, hdr, hlen, NULL, NULL, af)) 3129 return (0); 3130 opt = hdr + sizeof(struct tcphdr); 3131 hlen -= sizeof(struct tcphdr); 3132 while (hlen >= TCPOLEN_MAXSEG) { 3133 switch (*opt) { 3134 case TCPOPT_EOL: 3135 case TCPOPT_NOP: 3136 ++opt; 3137 --hlen; 3138 break; 3139 case TCPOPT_MAXSEG: 3140 bcopy((caddr_t)(opt + 2), (caddr_t)&mss, 2); 3141 NTOHS(mss); 3142 /* FALLTHROUGH */ 3143 default: 3144 optlen = opt[1]; 3145 if (optlen < 2) 3146 optlen = 2; 3147 hlen -= optlen; 3148 opt += optlen; 3149 break; 3150 } 3151 } 3152 return (mss); 3153} 3154 3155u_int16_t 3156pf_calc_mss(struct pf_addr *addr, sa_family_t af, u_int16_t offer) 3157{ 3158#ifdef INET 3159 struct sockaddr_in *dst; 3160 struct route ro; 3161#endif /* INET */ 3162#ifdef INET6 3163 struct sockaddr_in6 *dst6; 3164 struct route_in6 ro6; 3165#endif /* INET6 */ 3166 struct rtentry *rt = NULL; 3167#ifdef __FreeBSD__ 3168 int hlen = 0; 3169 u_int16_t mss = V_tcp_mssdflt; 3170#else 3171 int hlen; 3172 u_int16_t mss = tcp_mssdflt; 3173#endif 3174 3175 switch (af) { 3176#ifdef INET 3177 case AF_INET: 3178 hlen = sizeof(struct ip); 3179 bzero(&ro, sizeof(ro)); 3180 dst = (struct sockaddr_in *)&ro.ro_dst; 3181 dst->sin_family = AF_INET; 3182 dst->sin_len = sizeof(*dst); 3183 dst->sin_addr = addr->v4; 3184#ifdef __FreeBSD__ 3185#ifdef RTF_PRCLONING 3186 rtalloc_ign(&ro, (RTF_CLONING | RTF_PRCLONING)); 3187#else /* !RTF_PRCLONING */ 3188 in_rtalloc_ign(&ro, 0, 0); 3189#endif 3190#else /* ! __FreeBSD__ */ 3191 rtalloc_noclone(&ro, NO_CLONING); 3192#endif 3193 rt = ro.ro_rt; 3194 break; 3195#endif /* INET */ 3196#ifdef INET6 3197 case AF_INET6: 3198 hlen = sizeof(struct ip6_hdr); 3199 bzero(&ro6, sizeof(ro6)); 3200 dst6 = (struct sockaddr_in6 *)&ro6.ro_dst; 3201 dst6->sin6_family = AF_INET6; 3202 dst6->sin6_len = sizeof(*dst6); 3203 dst6->sin6_addr = addr->v6; 3204#ifdef __FreeBSD__ 3205#ifdef RTF_PRCLONING 3206 rtalloc_ign((struct route *)&ro6, 3207 (RTF_CLONING | RTF_PRCLONING)); 3208#else /* !RTF_PRCLONING */ 3209 rtalloc_ign((struct route *)&ro6, 0); 3210#endif 3211#else /* ! __FreeBSD__ */ 3212 rtalloc_noclone((struct route *)&ro6, NO_CLONING); 3213#endif 3214 rt = ro6.ro_rt; 3215 break; 3216#endif /* INET6 */ 3217 } 3218 3219 if (rt && rt->rt_ifp) { 3220 mss = rt->rt_ifp->if_mtu - hlen - sizeof(struct tcphdr); 3221#ifdef __FreeBSD__ 3222 mss = max(V_tcp_mssdflt, mss); 3223#else 3224 mss = max(tcp_mssdflt, mss); 3225#endif 3226 RTFREE(rt); 3227 } 3228 mss = min(mss, offer); 3229 mss = max(mss, 64); /* sanity - at least max opt space */ 3230 return (mss); 3231} 3232 3233void 3234pf_set_rt_ifp(struct pf_state *s, struct pf_addr *saddr) 3235{ 3236 struct pf_rule *r = s->rule.ptr; 3237 struct pf_src_node *sn = NULL; 3238 3239 s->rt_kif = NULL; 3240 if (!r->rt || r->rt == PF_FASTROUTE) 3241 return; 3242 switch (s->key[PF_SK_WIRE]->af) { 3243#ifdef INET 3244 case AF_INET: 3245 pf_map_addr(AF_INET, r, saddr, &s->rt_addr, NULL, &sn); 3246 s->rt_kif = r->rpool.cur->kif; 3247 break; 3248#endif /* INET */ 3249#ifdef INET6 3250 case AF_INET6: 3251 pf_map_addr(AF_INET6, r, saddr, &s->rt_addr, NULL, &sn); 3252 s->rt_kif = r->rpool.cur->kif; 3253 break; 3254#endif /* INET6 */ 3255 } 3256} 3257 3258u_int32_t 3259pf_tcp_iss(struct pf_pdesc *pd) 3260{ 3261 MD5_CTX ctx; 3262 u_int32_t digest[4]; 3263 3264#ifdef __FreeBSD__ 3265 if (V_pf_tcp_secret_init == 0) { 3266 read_random(&V_pf_tcp_secret, sizeof(V_pf_tcp_secret)); 3267 MD5Init(&V_pf_tcp_secret_ctx); 3268 MD5Update(&V_pf_tcp_secret_ctx, V_pf_tcp_secret, 3269 sizeof(V_pf_tcp_secret)); 3270 V_pf_tcp_secret_init = 1; 3271 } 3272 3273 ctx = V_pf_tcp_secret_ctx; 3274#else 3275 if (pf_tcp_secret_init == 0) { 3276 arc4random_buf(pf_tcp_secret, sizeof(pf_tcp_secret)); 3277 MD5Init(&pf_tcp_secret_ctx); 3278 MD5Update(&pf_tcp_secret_ctx, pf_tcp_secret, 3279 sizeof(pf_tcp_secret)); 3280 pf_tcp_secret_init = 1; 3281 } 3282 3283 ctx = pf_tcp_secret_ctx; 3284#endif 3285 3286 MD5Update(&ctx, (char *)&pd->hdr.tcp->th_sport, sizeof(u_short)); 3287 MD5Update(&ctx, (char *)&pd->hdr.tcp->th_dport, sizeof(u_short)); 3288 if (pd->af == AF_INET6) { 3289 MD5Update(&ctx, (char *)&pd->src->v6, sizeof(struct in6_addr)); 3290 MD5Update(&ctx, (char *)&pd->dst->v6, sizeof(struct in6_addr)); 3291 } else { 3292 MD5Update(&ctx, (char *)&pd->src->v4, sizeof(struct in_addr)); 3293 MD5Update(&ctx, (char *)&pd->dst->v4, sizeof(struct in_addr)); 3294 } 3295 MD5Final((u_char *)digest, &ctx); 3296#ifdef __FreeBSD__ 3297 V_pf_tcp_iss_off += 4096; 3298#define ISN_RANDOM_INCREMENT (4096 - 1) 3299 return (digest[0] + (arc4random() & ISN_RANDOM_INCREMENT) + 3300 V_pf_tcp_iss_off); 3301#undef ISN_RANDOM_INCREMENT 3302#else 3303 pf_tcp_iss_off += 4096; 3304 return (digest[0] + tcp_iss + pf_tcp_iss_off); 3305#endif 3306} 3307 3308int 3309pf_test_rule(struct pf_rule **rm, struct pf_state **sm, int direction, 3310 struct pfi_kif *kif, struct mbuf *m, int off, void *h, 3311 struct pf_pdesc *pd, struct pf_rule **am, struct pf_ruleset **rsm, 3312#ifdef __FreeBSD__ 3313 struct ifqueue *ifq, struct inpcb *inp) 3314#else 3315 struct ifqueue *ifq) 3316#endif 3317{ 3318 struct pf_rule *nr = NULL; 3319 struct pf_addr *saddr = pd->src, *daddr = pd->dst; 3320 sa_family_t af = pd->af; 3321 struct pf_rule *r, *a = NULL; 3322 struct pf_ruleset *ruleset = NULL; 3323 struct pf_src_node *nsn = NULL; 3324 struct tcphdr *th = pd->hdr.tcp; 3325 struct pf_state_key *skw = NULL, *sks = NULL; 3326 struct pf_state_key *sk = NULL, *nk = NULL; 3327 u_short reason; 3328 int rewrite = 0, hdrlen = 0; 3329 int tag = -1, rtableid = -1; 3330 int asd = 0; 3331 int match = 0; 3332 int state_icmp = 0; 3333#ifdef __FreeBSD__ 3334 u_int16_t sport = 0, dport = 0; 3335 u_int16_t bproto_sum = 0, bip_sum = 0; 3336#else 3337 u_int16_t sport, dport; 3338 u_int16_t bproto_sum = 0, bip_sum; 3339#endif 3340 u_int8_t icmptype = 0, icmpcode = 0; 3341 3342 3343 if (direction == PF_IN && pf_check_congestion(ifq)) { 3344 REASON_SET(&reason, PFRES_CONGEST); 3345 return (PF_DROP); 3346 } 3347 3348#ifdef __FreeBSD__ 3349 if (inp != NULL) 3350 pd->lookup.done = pf_socket_lookup(direction, pd, inp); 3351 else if (V_debug_pfugidhack) { 3352 PF_UNLOCK(); 3353 DPFPRINTF(PF_DEBUG_MISC, ("pf: unlocked lookup\n")); 3354 pd->lookup.done = pf_socket_lookup(direction, pd, inp); 3355 PF_LOCK(); 3356 } 3357#endif 3358 3359 switch (pd->proto) { 3360 case IPPROTO_TCP: 3361 sport = th->th_sport; 3362 dport = th->th_dport; 3363 hdrlen = sizeof(*th); 3364 break; 3365 case IPPROTO_UDP: 3366 sport = pd->hdr.udp->uh_sport; 3367 dport = pd->hdr.udp->uh_dport; 3368 hdrlen = sizeof(*pd->hdr.udp); 3369 break; 3370#ifdef INET 3371 case IPPROTO_ICMP: 3372 if (pd->af != AF_INET) 3373 break; 3374 sport = dport = pd->hdr.icmp->icmp_id; 3375 hdrlen = sizeof(*pd->hdr.icmp); 3376 icmptype = pd->hdr.icmp->icmp_type; 3377 icmpcode = pd->hdr.icmp->icmp_code; 3378 3379 if (icmptype == ICMP_UNREACH || 3380 icmptype == ICMP_SOURCEQUENCH || 3381 icmptype == ICMP_REDIRECT || 3382 icmptype == ICMP_TIMXCEED || 3383 icmptype == ICMP_PARAMPROB) 3384 state_icmp++; 3385 break; 3386#endif /* INET */ 3387#ifdef INET6 3388 case IPPROTO_ICMPV6: 3389 if (af != AF_INET6) 3390 break; 3391 sport = dport = pd->hdr.icmp6->icmp6_id; 3392 hdrlen = sizeof(*pd->hdr.icmp6); 3393 icmptype = pd->hdr.icmp6->icmp6_type; 3394 icmpcode = pd->hdr.icmp6->icmp6_code; 3395 3396 if (icmptype == ICMP6_DST_UNREACH || 3397 icmptype == ICMP6_PACKET_TOO_BIG || 3398 icmptype == ICMP6_TIME_EXCEEDED || 3399 icmptype == ICMP6_PARAM_PROB) 3400 state_icmp++; 3401 break; 3402#endif /* INET6 */ 3403 default: 3404 sport = dport = hdrlen = 0; 3405 break; 3406 } 3407 3408 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); 3409 3410 /* check packet for BINAT/NAT/RDR */ 3411 if ((nr = pf_get_translation(pd, m, off, direction, kif, &nsn, 3412 &skw, &sks, &sk, &nk, saddr, daddr, sport, dport)) != NULL) { 3413 if (nk == NULL || sk == NULL) { 3414 REASON_SET(&reason, PFRES_MEMORY); 3415 goto cleanup; 3416 } 3417 3418 if (pd->ip_sum) 3419 bip_sum = *pd->ip_sum; 3420 3421 switch (pd->proto) { 3422 case IPPROTO_TCP: 3423 bproto_sum = th->th_sum; 3424 pd->proto_sum = &th->th_sum; 3425 3426 if (PF_ANEQ(saddr, &nk->addr[pd->sidx], af) || 3427 nk->port[pd->sidx] != sport) { 3428 pf_change_ap(saddr, &th->th_sport, pd->ip_sum, 3429 &th->th_sum, &nk->addr[pd->sidx], 3430 nk->port[pd->sidx], 0, af); 3431 pd->sport = &th->th_sport; 3432 sport = th->th_sport; 3433 } 3434 3435 if (PF_ANEQ(daddr, &nk->addr[pd->didx], af) || 3436 nk->port[pd->didx] != dport) { 3437 pf_change_ap(daddr, &th->th_dport, pd->ip_sum, 3438 &th->th_sum, &nk->addr[pd->didx], 3439 nk->port[pd->didx], 0, af); 3440 dport = th->th_dport; 3441 pd->dport = &th->th_dport; 3442 } 3443 rewrite++; 3444 break; 3445 case IPPROTO_UDP: 3446 bproto_sum = pd->hdr.udp->uh_sum; 3447 pd->proto_sum = &pd->hdr.udp->uh_sum; 3448 3449 if (PF_ANEQ(saddr, &nk->addr[pd->sidx], af) || 3450 nk->port[pd->sidx] != sport) { 3451 pf_change_ap(saddr, &pd->hdr.udp->uh_sport, 3452 pd->ip_sum, &pd->hdr.udp->uh_sum, 3453 &nk->addr[pd->sidx], 3454 nk->port[pd->sidx], 1, af); 3455 sport = pd->hdr.udp->uh_sport; 3456 pd->sport = &pd->hdr.udp->uh_sport; 3457 } 3458 3459 if (PF_ANEQ(daddr, &nk->addr[pd->didx], af) || 3460 nk->port[pd->didx] != dport) { 3461 pf_change_ap(daddr, &pd->hdr.udp->uh_dport, 3462 pd->ip_sum, &pd->hdr.udp->uh_sum, 3463 &nk->addr[pd->didx], 3464 nk->port[pd->didx], 1, af); 3465 dport = pd->hdr.udp->uh_dport; 3466 pd->dport = &pd->hdr.udp->uh_dport; 3467 } 3468 rewrite++; 3469 break; 3470#ifdef INET 3471 case IPPROTO_ICMP: 3472 nk->port[0] = nk->port[1]; 3473 if (PF_ANEQ(saddr, &nk->addr[pd->sidx], AF_INET)) 3474 pf_change_a(&saddr->v4.s_addr, pd->ip_sum, 3475 nk->addr[pd->sidx].v4.s_addr, 0); 3476 3477 if (PF_ANEQ(daddr, &nk->addr[pd->didx], AF_INET)) 3478 pf_change_a(&daddr->v4.s_addr, pd->ip_sum, 3479 nk->addr[pd->didx].v4.s_addr, 0); 3480 3481 if (nk->port[1] != pd->hdr.icmp->icmp_id) { 3482 pd->hdr.icmp->icmp_cksum = pf_cksum_fixup( 3483 pd->hdr.icmp->icmp_cksum, sport, 3484 nk->port[1], 0); 3485 pd->hdr.icmp->icmp_id = nk->port[1]; 3486 pd->sport = &pd->hdr.icmp->icmp_id; 3487 } 3488 m_copyback(m, off, ICMP_MINLEN, (caddr_t)pd->hdr.icmp); 3489 break; 3490#endif /* INET */ 3491#ifdef INET6 3492 case IPPROTO_ICMPV6: 3493 nk->port[0] = nk->port[1]; 3494 if (PF_ANEQ(saddr, &nk->addr[pd->sidx], AF_INET6)) 3495 pf_change_a6(saddr, &pd->hdr.icmp6->icmp6_cksum, 3496 &nk->addr[pd->sidx], 0); 3497 3498 if (PF_ANEQ(daddr, &nk->addr[pd->didx], AF_INET6)) 3499 pf_change_a6(daddr, &pd->hdr.icmp6->icmp6_cksum, 3500 &nk->addr[pd->didx], 0); 3501 rewrite++; 3502 break; 3503#endif /* INET */ 3504 default: 3505 switch (af) { 3506#ifdef INET 3507 case AF_INET: 3508 if (PF_ANEQ(saddr, 3509 &nk->addr[pd->sidx], AF_INET)) 3510 pf_change_a(&saddr->v4.s_addr, 3511 pd->ip_sum, 3512 nk->addr[pd->sidx].v4.s_addr, 0); 3513 3514 if (PF_ANEQ(daddr, 3515 &nk->addr[pd->didx], AF_INET)) 3516 pf_change_a(&daddr->v4.s_addr, 3517 pd->ip_sum, 3518 nk->addr[pd->didx].v4.s_addr, 0); 3519 break; 3520#endif /* INET */ 3521#ifdef INET6 3522 case AF_INET6: 3523 if (PF_ANEQ(saddr, 3524 &nk->addr[pd->sidx], AF_INET6)) 3525 PF_ACPY(saddr, &nk->addr[pd->sidx], af); 3526 3527 if (PF_ANEQ(daddr, 3528 &nk->addr[pd->didx], AF_INET6)) 3529 PF_ACPY(saddr, &nk->addr[pd->didx], af); 3530 break; 3531#endif /* INET */ 3532 } 3533 break; 3534 } 3535 if (nr->natpass) 3536 r = NULL; 3537 pd->nat_rule = nr; 3538 } 3539 3540 while (r != NULL) { 3541 r->evaluations++; 3542 if (pfi_kif_match(r->kif, kif) == r->ifnot) 3543 r = r->skip[PF_SKIP_IFP].ptr; 3544 else if (r->direction && r->direction != direction) 3545 r = r->skip[PF_SKIP_DIR].ptr; 3546 else if (r->af && r->af != af) 3547 r = r->skip[PF_SKIP_AF].ptr; 3548 else if (r->proto && r->proto != pd->proto) 3549 r = r->skip[PF_SKIP_PROTO].ptr; 3550 else if (PF_MISMATCHAW(&r->src.addr, saddr, af, 3551 r->src.neg, kif)) 3552 r = r->skip[PF_SKIP_SRC_ADDR].ptr; 3553 /* tcp/udp only. port_op always 0 in other cases */ 3554 else if (r->src.port_op && !pf_match_port(r->src.port_op, 3555 r->src.port[0], r->src.port[1], sport)) 3556 r = r->skip[PF_SKIP_SRC_PORT].ptr; 3557 else if (PF_MISMATCHAW(&r->dst.addr, daddr, af, 3558 r->dst.neg, NULL)) 3559 r = r->skip[PF_SKIP_DST_ADDR].ptr; 3560 /* tcp/udp only. port_op always 0 in other cases */ 3561 else if (r->dst.port_op && !pf_match_port(r->dst.port_op, 3562 r->dst.port[0], r->dst.port[1], dport)) 3563 r = r->skip[PF_SKIP_DST_PORT].ptr; 3564 /* icmp only. type always 0 in other cases */ 3565 else if (r->type && r->type != icmptype + 1) 3566 r = TAILQ_NEXT(r, entries); 3567 /* icmp only. type always 0 in other cases */ 3568 else if (r->code && r->code != icmpcode + 1) 3569 r = TAILQ_NEXT(r, entries); 3570 else if (r->tos && !(r->tos == pd->tos)) 3571 r = TAILQ_NEXT(r, entries); 3572 else if (r->rule_flag & PFRULE_FRAGMENT) 3573 r = TAILQ_NEXT(r, entries); 3574 else if (pd->proto == IPPROTO_TCP && 3575 (r->flagset & th->th_flags) != r->flags) 3576 r = TAILQ_NEXT(r, entries); 3577 /* tcp/udp only. uid.op always 0 in other cases */ 3578 else if (r->uid.op && (pd->lookup.done || (pd->lookup.done = 3579#ifdef __FreeBSD__ 3580 pf_socket_lookup(direction, pd, inp), 1)) && 3581#else 3582 pf_socket_lookup(direction, pd), 1)) && 3583#endif 3584 !pf_match_uid(r->uid.op, r->uid.uid[0], r->uid.uid[1], 3585 pd->lookup.uid)) 3586 r = TAILQ_NEXT(r, entries); 3587 /* tcp/udp only. gid.op always 0 in other cases */ 3588 else if (r->gid.op && (pd->lookup.done || (pd->lookup.done = 3589#ifdef __FreeBSD__ 3590 pf_socket_lookup(direction, pd, inp), 1)) && 3591#else 3592 pf_socket_lookup(direction, pd), 1)) && 3593#endif 3594 !pf_match_gid(r->gid.op, r->gid.gid[0], r->gid.gid[1], 3595 pd->lookup.gid)) 3596 r = TAILQ_NEXT(r, entries); 3597 else if (r->prob && 3598#ifdef __FreeBSD__ 3599 r->prob <= arc4random()) 3600#else 3601 r->prob <= arc4random_uniform(UINT_MAX - 1) + 1) 3602#endif 3603 r = TAILQ_NEXT(r, entries); 3604#ifdef __FreeBSD__ 3605 else if (r->match_tag && !pf_match_tag(m, r, &tag, pd->pf_mtag)) 3606#else 3607 else if (r->match_tag && !pf_match_tag(m, r, &tag)) 3608#endif 3609 r = TAILQ_NEXT(r, entries); 3610 else if (r->os_fingerprint != PF_OSFP_ANY && 3611 (pd->proto != IPPROTO_TCP || !pf_osfp_match( 3612 pf_osfp_fingerprint(pd, m, off, th), 3613 r->os_fingerprint))) 3614 r = TAILQ_NEXT(r, entries); 3615 else { 3616 if (r->tag) 3617 tag = r->tag; 3618 if (r->rtableid >= 0) 3619 rtableid = r->rtableid; 3620 if (r->anchor == NULL) { 3621 match = 1; 3622 *rm = r; 3623 *am = a; 3624 *rsm = ruleset; 3625 if ((*rm)->quick) 3626 break; 3627 r = TAILQ_NEXT(r, entries); 3628 } else 3629 pf_step_into_anchor(&asd, &ruleset, 3630 PF_RULESET_FILTER, &r, &a, &match); 3631 } 3632 if (r == NULL && pf_step_out_of_anchor(&asd, &ruleset, 3633 PF_RULESET_FILTER, &r, &a, &match)) 3634 break; 3635 } 3636 r = *rm; 3637 a = *am; 3638 ruleset = *rsm; 3639 3640 REASON_SET(&reason, PFRES_MATCH); 3641 3642 if (r->log || (nr != NULL && nr->log)) { 3643 if (rewrite) 3644 m_copyback(m, off, hdrlen, pd->hdr.any); 3645 PFLOG_PACKET(kif, h, m, af, direction, reason, r->log ? r : nr, 3646 a, ruleset, pd); 3647 } 3648 3649 if ((r->action == PF_DROP) && 3650 ((r->rule_flag & PFRULE_RETURNRST) || 3651 (r->rule_flag & PFRULE_RETURNICMP) || 3652 (r->rule_flag & PFRULE_RETURN))) { 3653 /* undo NAT changes, if they have taken place */ 3654 if (nr != NULL) { 3655 PF_ACPY(saddr, &sk->addr[pd->sidx], af); 3656 PF_ACPY(daddr, &sk->addr[pd->didx], af); 3657 if (pd->sport) 3658 *pd->sport = sk->port[pd->sidx]; 3659 if (pd->dport) 3660 *pd->dport = sk->port[pd->didx]; 3661 if (pd->proto_sum) 3662 *pd->proto_sum = bproto_sum; 3663 if (pd->ip_sum) 3664 *pd->ip_sum = bip_sum; 3665 m_copyback(m, off, hdrlen, pd->hdr.any); 3666 } 3667 if (pd->proto == IPPROTO_TCP && 3668 ((r->rule_flag & PFRULE_RETURNRST) || 3669 (r->rule_flag & PFRULE_RETURN)) && 3670 !(th->th_flags & TH_RST)) { 3671 u_int32_t ack = ntohl(th->th_seq) + pd->p_len; 3672 int len = 0; 3673#ifdef INET 3674 struct ip *h4; 3675#endif 3676#ifdef INET6 3677 struct ip6_hdr *h6; 3678#endif 3679 3680 switch (af) { 3681#ifdef INET 3682 case AF_INET: 3683 h4 = mtod(m, struct ip *); 3684 len = ntohs(h4->ip_len) - off; 3685 break; 3686#endif 3687#ifdef INET6 3688 case AF_INET6: 3689 h6 = mtod(m, struct ip6_hdr *); 3690 len = ntohs(h6->ip6_plen) - (off - sizeof(*h6)); 3691 break; 3692#endif 3693 } 3694 3695 if (pf_check_proto_cksum(m, off, len, IPPROTO_TCP, af)) 3696 REASON_SET(&reason, PFRES_PROTCKSUM); 3697 else { 3698 if (th->th_flags & TH_SYN) 3699 ack++; 3700 if (th->th_flags & TH_FIN) 3701 ack++; 3702#ifdef __FreeBSD__ 3703 pf_send_tcp(m, r, af, pd->dst, 3704#else 3705 pf_send_tcp(r, af, pd->dst, 3706#endif 3707 pd->src, th->th_dport, th->th_sport, 3708 ntohl(th->th_ack), ack, TH_RST|TH_ACK, 0, 0, 3709 r->return_ttl, 1, 0, pd->eh, kif->pfik_ifp); 3710 } 3711 } else if (pd->proto != IPPROTO_ICMP && af == AF_INET && 3712 r->return_icmp) 3713 pf_send_icmp(m, r->return_icmp >> 8, 3714 r->return_icmp & 255, af, r); 3715 else if (pd->proto != IPPROTO_ICMPV6 && af == AF_INET6 && 3716 r->return_icmp6) 3717 pf_send_icmp(m, r->return_icmp6 >> 8, 3718 r->return_icmp6 & 255, af, r); 3719 } 3720 3721 if (r->action == PF_DROP) 3722 goto cleanup; 3723 3724#ifdef __FreeBSD__ 3725 if (pf_tag_packet(m, tag, rtableid, pd->pf_mtag)) { 3726#else 3727 if (pf_tag_packet(m, tag, rtableid)) { 3728#endif 3729 REASON_SET(&reason, PFRES_MEMORY); 3730 goto cleanup; 3731 } 3732 3733 if (!state_icmp && (r->keep_state || nr != NULL || 3734 (pd->flags & PFDESC_TCP_NORM))) { 3735 int action; 3736 action = pf_create_state(r, nr, a, pd, nsn, skw, sks, nk, sk, m, 3737 off, sport, dport, &rewrite, kif, sm, tag, bproto_sum, 3738 bip_sum, hdrlen); 3739 if (action != PF_PASS) 3740 return (action); 3741 } else { 3742#ifdef __FreeBSD__ 3743 if (sk != NULL) 3744 pool_put(&V_pf_state_key_pl, sk); 3745 if (nk != NULL) 3746 pool_put(&V_pf_state_key_pl, nk); 3747#else 3748 if (sk != NULL) 3749 pool_put(&pf_state_key_pl, sk); 3750 if (nk != NULL) 3751 pool_put(&pf_state_key_pl, nk); 3752#endif 3753 } 3754 3755 /* copy back packet headers if we performed NAT operations */ 3756 if (rewrite) 3757 m_copyback(m, off, hdrlen, pd->hdr.any); 3758 3759#if NPFSYNC > 0 3760 if (*sm != NULL && !ISSET((*sm)->state_flags, PFSTATE_NOSYNC) && 3761#ifdef __FreeBSD__ 3762 direction == PF_OUT && pfsync_up_ptr != NULL && pfsync_up_ptr()) { 3763#else 3764 direction == PF_OUT && pfsync_up()) { 3765#endif 3766 /* 3767 * We want the state created, but we dont 3768 * want to send this in case a partner 3769 * firewall has to know about it to allow 3770 * replies through it. 3771 */ 3772#ifdef __FreeBSD__ 3773 if (pfsync_defer_ptr != NULL) 3774 pfsync_defer_ptr(*sm, m); 3775#else 3776 if (pfsync_defer(*sm, m)) 3777#endif 3778 return (PF_DEFER); 3779 } 3780#endif 3781 3782 return (PF_PASS); 3783 3784cleanup: 3785#ifdef __FreeBSD__ 3786 if (sk != NULL) 3787 pool_put(&V_pf_state_key_pl, sk); 3788 if (nk != NULL) 3789 pool_put(&V_pf_state_key_pl, nk); 3790#else 3791 if (sk != NULL) 3792 pool_put(&pf_state_key_pl, sk); 3793 if (nk != NULL) 3794 pool_put(&pf_state_key_pl, nk); 3795#endif 3796 return (PF_DROP); 3797} 3798 3799static __inline int 3800pf_create_state(struct pf_rule *r, struct pf_rule *nr, struct pf_rule *a, 3801 struct pf_pdesc *pd, struct pf_src_node *nsn, struct pf_state_key *skw, 3802 struct pf_state_key *sks, struct pf_state_key *nk, struct pf_state_key *sk, 3803 struct mbuf *m, int off, u_int16_t sport, u_int16_t dport, int *rewrite, 3804 struct pfi_kif *kif, struct pf_state **sm, int tag, u_int16_t bproto_sum, 3805 u_int16_t bip_sum, int hdrlen) 3806{ 3807 struct pf_state *s = NULL; 3808 struct pf_src_node *sn = NULL; 3809 struct tcphdr *th = pd->hdr.tcp; 3810#ifdef __FreeBSD__ 3811 u_int16_t mss = V_tcp_mssdflt; 3812#else 3813 u_int16_t mss = tcp_mssdflt; 3814#endif 3815 u_short reason; 3816 3817 /* check maximums */ 3818 if (r->max_states && (r->states_cur >= r->max_states)) { 3819#ifdef __FreeBSD__ 3820 V_pf_status.lcounters[LCNT_STATES]++; 3821#else 3822 pf_status.lcounters[LCNT_STATES]++; 3823#endif 3824 REASON_SET(&reason, PFRES_MAXSTATES); 3825 return (PF_DROP); 3826 } 3827 /* src node for filter rule */ 3828 if ((r->rule_flag & PFRULE_SRCTRACK || 3829 r->rpool.opts & PF_POOL_STICKYADDR) && 3830 pf_insert_src_node(&sn, r, pd->src, pd->af) != 0) { 3831 REASON_SET(&reason, PFRES_SRCLIMIT); 3832 goto csfailed; 3833 } 3834 /* src node for translation rule */ 3835 if (nr != NULL && (nr->rpool.opts & PF_POOL_STICKYADDR) && 3836 pf_insert_src_node(&nsn, nr, &sk->addr[pd->sidx], pd->af)) { 3837 REASON_SET(&reason, PFRES_SRCLIMIT); 3838 goto csfailed; 3839 } 3840#ifdef __FreeBSD__ 3841 s = pool_get(&V_pf_state_pl, PR_NOWAIT | PR_ZERO); 3842#else 3843 s = pool_get(&pf_state_pl, PR_NOWAIT | PR_ZERO); 3844#endif 3845 if (s == NULL) { 3846 REASON_SET(&reason, PFRES_MEMORY); 3847 goto csfailed; 3848 } 3849 s->rule.ptr = r; 3850 s->nat_rule.ptr = nr; 3851 s->anchor.ptr = a; 3852 STATE_INC_COUNTERS(s); 3853 if (r->allow_opts) 3854 s->state_flags |= PFSTATE_ALLOWOPTS; 3855 if (r->rule_flag & PFRULE_STATESLOPPY) 3856 s->state_flags |= PFSTATE_SLOPPY; 3857 if (r->rule_flag & PFRULE_PFLOW) 3858 s->state_flags |= PFSTATE_PFLOW; 3859 s->log = r->log & PF_LOG_ALL; 3860 s->sync_state = PFSYNC_S_NONE; 3861 if (nr != NULL) 3862 s->log |= nr->log & PF_LOG_ALL; 3863 switch (pd->proto) { 3864 case IPPROTO_TCP: 3865 s->src.seqlo = ntohl(th->th_seq); 3866 s->src.seqhi = s->src.seqlo + pd->p_len + 1; 3867 if ((th->th_flags & (TH_SYN|TH_ACK)) == TH_SYN && 3868 r->keep_state == PF_STATE_MODULATE) { 3869 /* Generate sequence number modulator */ 3870 if ((s->src.seqdiff = pf_tcp_iss(pd) - s->src.seqlo) == 3871 0) 3872 s->src.seqdiff = 1; 3873 pf_change_a(&th->th_seq, &th->th_sum, 3874 htonl(s->src.seqlo + s->src.seqdiff), 0); 3875 *rewrite = 1; 3876 } else 3877 s->src.seqdiff = 0; 3878 if (th->th_flags & TH_SYN) { 3879 s->src.seqhi++; 3880 s->src.wscale = pf_get_wscale(m, off, 3881 th->th_off, pd->af); 3882 } 3883 s->src.max_win = MAX(ntohs(th->th_win), 1); 3884 if (s->src.wscale & PF_WSCALE_MASK) { 3885 /* Remove scale factor from initial window */ 3886 int win = s->src.max_win; 3887 win += 1 << (s->src.wscale & PF_WSCALE_MASK); 3888 s->src.max_win = (win - 1) >> 3889 (s->src.wscale & PF_WSCALE_MASK); 3890 } 3891 if (th->th_flags & TH_FIN) 3892 s->src.seqhi++; 3893 s->dst.seqhi = 1; 3894 s->dst.max_win = 1; 3895 s->src.state = TCPS_SYN_SENT; 3896 s->dst.state = TCPS_CLOSED; 3897 s->timeout = PFTM_TCP_FIRST_PACKET; 3898 break; 3899 case IPPROTO_UDP: 3900 s->src.state = PFUDPS_SINGLE; 3901 s->dst.state = PFUDPS_NO_TRAFFIC; 3902 s->timeout = PFTM_UDP_FIRST_PACKET; 3903 break; 3904 case IPPROTO_ICMP: 3905#ifdef INET6 3906 case IPPROTO_ICMPV6: 3907#endif 3908 s->timeout = PFTM_ICMP_FIRST_PACKET; 3909 break; 3910 default: 3911 s->src.state = PFOTHERS_SINGLE; 3912 s->dst.state = PFOTHERS_NO_TRAFFIC; 3913 s->timeout = PFTM_OTHER_FIRST_PACKET; 3914 } 3915 3916 s->creation = time_second; 3917 s->expire = time_second; 3918 3919 if (sn != NULL) { 3920 s->src_node = sn; 3921 s->src_node->states++; 3922 } 3923 if (nsn != NULL) { 3924 /* XXX We only modify one side for now. */ 3925 PF_ACPY(&nsn->raddr, &nk->addr[1], pd->af); 3926 s->nat_src_node = nsn; 3927 s->nat_src_node->states++; 3928 } 3929 if (pd->proto == IPPROTO_TCP) { 3930 if ((pd->flags & PFDESC_TCP_NORM) && pf_normalize_tcp_init(m, 3931 off, pd, th, &s->src, &s->dst)) { 3932 REASON_SET(&reason, PFRES_MEMORY); 3933 pf_src_tree_remove_state(s); 3934 STATE_DEC_COUNTERS(s); 3935#ifdef __FreeBSD__ 3936 pool_put(&V_pf_state_pl, s); 3937#else 3938 pool_put(&pf_state_pl, s); 3939#endif 3940 return (PF_DROP); 3941 } 3942 if ((pd->flags & PFDESC_TCP_NORM) && s->src.scrub && 3943 pf_normalize_tcp_stateful(m, off, pd, &reason, th, s, 3944 &s->src, &s->dst, rewrite)) { 3945 /* This really shouldn't happen!!! */ 3946 DPFPRINTF(PF_DEBUG_URGENT, 3947 ("pf_normalize_tcp_stateful failed on first pkt")); 3948 pf_normalize_tcp_cleanup(s); 3949 pf_src_tree_remove_state(s); 3950 STATE_DEC_COUNTERS(s); 3951#ifdef __FreeBSD__ 3952 pool_put(&V_pf_state_pl, s); 3953#else 3954 pool_put(&pf_state_pl, s); 3955#endif 3956 return (PF_DROP); 3957 } 3958 } 3959 s->direction = pd->dir; 3960 3961 if (sk == NULL && pf_state_key_setup(pd, nr, &skw, &sks, &sk, &nk, 3962 pd->src, pd->dst, sport, dport)) 3963 goto csfailed; 3964 3965 if (pf_state_insert(BOUND_IFACE(r, kif), skw, sks, s)) { 3966 if (pd->proto == IPPROTO_TCP) 3967 pf_normalize_tcp_cleanup(s); 3968 REASON_SET(&reason, PFRES_STATEINS); 3969 pf_src_tree_remove_state(s); 3970 STATE_DEC_COUNTERS(s); 3971#ifdef __FreeBSD__ 3972 pool_put(&V_pf_state_pl, s); 3973#else 3974 pool_put(&pf_state_pl, s); 3975#endif 3976 return (PF_DROP); 3977 } else 3978 *sm = s; 3979 3980 pf_set_rt_ifp(s, pd->src); /* needs s->state_key set */ 3981 if (tag > 0) { 3982 pf_tag_ref(tag); 3983 s->tag = tag; 3984 } 3985 if (pd->proto == IPPROTO_TCP && (th->th_flags & (TH_SYN|TH_ACK)) == 3986 TH_SYN && r->keep_state == PF_STATE_SYNPROXY) { 3987 s->src.state = PF_TCPS_PROXY_SRC; 3988 /* undo NAT changes, if they have taken place */ 3989 if (nr != NULL) { 3990 struct pf_state_key *skt = s->key[PF_SK_WIRE]; 3991 if (pd->dir == PF_OUT) 3992 skt = s->key[PF_SK_STACK]; 3993 PF_ACPY(pd->src, &skt->addr[pd->sidx], pd->af); 3994 PF_ACPY(pd->dst, &skt->addr[pd->didx], pd->af); 3995 if (pd->sport) 3996 *pd->sport = skt->port[pd->sidx]; 3997 if (pd->dport) 3998 *pd->dport = skt->port[pd->didx]; 3999 if (pd->proto_sum) 4000 *pd->proto_sum = bproto_sum; 4001 if (pd->ip_sum) 4002 *pd->ip_sum = bip_sum; 4003 m_copyback(m, off, hdrlen, pd->hdr.any); 4004 } 4005 s->src.seqhi = htonl(arc4random()); 4006 /* Find mss option */ 4007 mss = pf_get_mss(m, off, th->th_off, pd->af); 4008 mss = pf_calc_mss(pd->src, pd->af, mss); 4009 mss = pf_calc_mss(pd->dst, pd->af, mss); 4010 s->src.mss = mss; 4011#ifdef __FreeBSD__ 4012 pf_send_tcp(NULL, r, pd->af, pd->dst, pd->src, th->th_dport, 4013#else 4014 pf_send_tcp(r, pd->af, pd->dst, pd->src, th->th_dport, 4015#endif 4016 th->th_sport, s->src.seqhi, ntohl(th->th_seq) + 1, 4017 TH_SYN|TH_ACK, 0, s->src.mss, 0, 1, 0, NULL, NULL); 4018 REASON_SET(&reason, PFRES_SYNPROXY); 4019 return (PF_SYNPROXY_DROP); 4020 } 4021 4022 return (PF_PASS); 4023 4024csfailed: 4025#ifdef __FreeBSD__ 4026 if (sk != NULL) 4027 pool_put(&V_pf_state_key_pl, sk); 4028 if (nk != NULL) 4029 pool_put(&V_pf_state_key_pl, nk); 4030#else 4031 if (sk != NULL) 4032 pool_put(&pf_state_key_pl, sk); 4033 if (nk != NULL) 4034 pool_put(&pf_state_key_pl, nk); 4035#endif 4036 4037 if (sn != NULL && sn->states == 0 && sn->expire == 0) { 4038#ifdef __FreeBSD__ 4039 RB_REMOVE(pf_src_tree, &V_tree_src_tracking, sn); 4040 V_pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 4041 V_pf_status.src_nodes--; 4042 pool_put(&V_pf_src_tree_pl, sn); 4043#else 4044 RB_REMOVE(pf_src_tree, &tree_src_tracking, sn); 4045 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 4046 pf_status.src_nodes--; 4047 pool_put(&pf_src_tree_pl, sn); 4048#endif 4049 } 4050 if (nsn != sn && nsn != NULL && nsn->states == 0 && nsn->expire == 0) { 4051#ifdef __FreeBSD__ 4052 RB_REMOVE(pf_src_tree, &V_tree_src_tracking, nsn); 4053 V_pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 4054 V_pf_status.src_nodes--; 4055 pool_put(&V_pf_src_tree_pl, nsn); 4056#else 4057 RB_REMOVE(pf_src_tree, &tree_src_tracking, nsn); 4058 pf_status.scounters[SCNT_SRC_NODE_REMOVALS]++; 4059 pf_status.src_nodes--; 4060 pool_put(&pf_src_tree_pl, nsn); 4061#endif 4062 } 4063 return (PF_DROP); 4064} 4065 4066int 4067pf_test_fragment(struct pf_rule **rm, int direction, struct pfi_kif *kif, 4068 struct mbuf *m, void *h, struct pf_pdesc *pd, struct pf_rule **am, 4069 struct pf_ruleset **rsm) 4070{ 4071 struct pf_rule *r, *a = NULL; 4072 struct pf_ruleset *ruleset = NULL; 4073 sa_family_t af = pd->af; 4074 u_short reason; 4075 int tag = -1; 4076 int asd = 0; 4077 int match = 0; 4078 4079 r = TAILQ_FIRST(pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); 4080 while (r != NULL) { 4081 r->evaluations++; 4082 if (pfi_kif_match(r->kif, kif) == r->ifnot) 4083 r = r->skip[PF_SKIP_IFP].ptr; 4084 else if (r->direction && r->direction != direction) 4085 r = r->skip[PF_SKIP_DIR].ptr; 4086 else if (r->af && r->af != af) 4087 r = r->skip[PF_SKIP_AF].ptr; 4088 else if (r->proto && r->proto != pd->proto) 4089 r = r->skip[PF_SKIP_PROTO].ptr; 4090 else if (PF_MISMATCHAW(&r->src.addr, pd->src, af, 4091 r->src.neg, kif)) 4092 r = r->skip[PF_SKIP_SRC_ADDR].ptr; 4093 else if (PF_MISMATCHAW(&r->dst.addr, pd->dst, af, 4094 r->dst.neg, NULL)) 4095 r = r->skip[PF_SKIP_DST_ADDR].ptr; 4096 else if (r->tos && !(r->tos == pd->tos)) 4097 r = TAILQ_NEXT(r, entries); 4098 else if (r->os_fingerprint != PF_OSFP_ANY) 4099 r = TAILQ_NEXT(r, entries); 4100 else if (pd->proto == IPPROTO_UDP && 4101 (r->src.port_op || r->dst.port_op)) 4102 r = TAILQ_NEXT(r, entries); 4103 else if (pd->proto == IPPROTO_TCP && 4104 (r->src.port_op || r->dst.port_op || r->flagset)) 4105 r = TAILQ_NEXT(r, entries); 4106 else if ((pd->proto == IPPROTO_ICMP || 4107 pd->proto == IPPROTO_ICMPV6) && 4108 (r->type || r->code)) 4109 r = TAILQ_NEXT(r, entries); 4110 else if (r->prob && r->prob <= 4111 (arc4random() % (UINT_MAX - 1) + 1)) 4112 r = TAILQ_NEXT(r, entries); 4113#ifdef __FreeBSD__ 4114 else if (r->match_tag && !pf_match_tag(m, r, &tag, pd->pf_mtag)) 4115#else 4116 else if (r->match_tag && !pf_match_tag(m, r, &tag)) 4117#endif 4118 r = TAILQ_NEXT(r, entries); 4119 else { 4120 if (r->anchor == NULL) { 4121 match = 1; 4122 *rm = r; 4123 *am = a; 4124 *rsm = ruleset; 4125 if ((*rm)->quick) 4126 break; 4127 r = TAILQ_NEXT(r, entries); 4128 } else 4129 pf_step_into_anchor(&asd, &ruleset, 4130 PF_RULESET_FILTER, &r, &a, &match); 4131 } 4132 if (r == NULL && pf_step_out_of_anchor(&asd, &ruleset, 4133 PF_RULESET_FILTER, &r, &a, &match)) 4134 break; 4135 } 4136 r = *rm; 4137 a = *am; 4138 ruleset = *rsm; 4139 4140 REASON_SET(&reason, PFRES_MATCH); 4141 4142 if (r->log) 4143 PFLOG_PACKET(kif, h, m, af, direction, reason, r, a, ruleset, 4144 pd); 4145 4146 if (r->action != PF_PASS) 4147 return (PF_DROP); 4148 4149#ifdef __FreeBSD__ 4150 if (pf_tag_packet(m, tag, -1, pd->pf_mtag)) { 4151#else 4152 if (pf_tag_packet(m, tag, -1)) { 4153#endif 4154 REASON_SET(&reason, PFRES_MEMORY); 4155 return (PF_DROP); 4156 } 4157 4158 return (PF_PASS); 4159} 4160 4161int 4162pf_tcp_track_full(struct pf_state_peer *src, struct pf_state_peer *dst, 4163 struct pf_state **state, struct pfi_kif *kif, struct mbuf *m, int off, 4164 struct pf_pdesc *pd, u_short *reason, int *copyback) 4165{ 4166 struct tcphdr *th = pd->hdr.tcp; 4167 u_int16_t win = ntohs(th->th_win); 4168 u_int32_t ack, end, seq, orig_seq; 4169 u_int8_t sws, dws; 4170 int ackskew; 4171 4172 if (src->wscale && dst->wscale && !(th->th_flags & TH_SYN)) { 4173 sws = src->wscale & PF_WSCALE_MASK; 4174 dws = dst->wscale & PF_WSCALE_MASK; 4175 } else 4176 sws = dws = 0; 4177 4178 /* 4179 * Sequence tracking algorithm from Guido van Rooij's paper: 4180 * http://www.madison-gurkha.com/publications/tcp_filtering/ 4181 * tcp_filtering.ps 4182 */ 4183 4184 orig_seq = seq = ntohl(th->th_seq); 4185 if (src->seqlo == 0) { 4186 /* First packet from this end. Set its state */ 4187 4188 if ((pd->flags & PFDESC_TCP_NORM || dst->scrub) && 4189 src->scrub == NULL) { 4190 if (pf_normalize_tcp_init(m, off, pd, th, src, dst)) { 4191 REASON_SET(reason, PFRES_MEMORY); 4192 return (PF_DROP); 4193 } 4194 } 4195 4196 /* Deferred generation of sequence number modulator */ 4197 if (dst->seqdiff && !src->seqdiff) { 4198 /* use random iss for the TCP server */ 4199 while ((src->seqdiff = arc4random() - seq) == 0) 4200 ; 4201 ack = ntohl(th->th_ack) - dst->seqdiff; 4202 pf_change_a(&th->th_seq, &th->th_sum, htonl(seq + 4203 src->seqdiff), 0); 4204 pf_change_a(&th->th_ack, &th->th_sum, htonl(ack), 0); 4205 *copyback = 1; 4206 } else { 4207 ack = ntohl(th->th_ack); 4208 } 4209 4210 end = seq + pd->p_len; 4211 if (th->th_flags & TH_SYN) { 4212 end++; 4213 if (dst->wscale & PF_WSCALE_FLAG) { 4214 src->wscale = pf_get_wscale(m, off, th->th_off, 4215 pd->af); 4216 if (src->wscale & PF_WSCALE_FLAG) { 4217 /* Remove scale factor from initial 4218 * window */ 4219 sws = src->wscale & PF_WSCALE_MASK; 4220 win = ((u_int32_t)win + (1 << sws) - 1) 4221 >> sws; 4222 dws = dst->wscale & PF_WSCALE_MASK; 4223 } else { 4224 /* fixup other window */ 4225 dst->max_win <<= dst->wscale & 4226 PF_WSCALE_MASK; 4227 /* in case of a retrans SYN|ACK */ 4228 dst->wscale = 0; 4229 } 4230 } 4231 } 4232 if (th->th_flags & TH_FIN) 4233 end++; 4234 4235 src->seqlo = seq; 4236 if (src->state < TCPS_SYN_SENT) 4237 src->state = TCPS_SYN_SENT; 4238 4239 /* 4240 * May need to slide the window (seqhi may have been set by 4241 * the crappy stack check or if we picked up the connection 4242 * after establishment) 4243 */ 4244 if (src->seqhi == 1 || 4245 SEQ_GEQ(end + MAX(1, dst->max_win << dws), src->seqhi)) 4246 src->seqhi = end + MAX(1, dst->max_win << dws); 4247 if (win > src->max_win) 4248 src->max_win = win; 4249 4250 } else { 4251 ack = ntohl(th->th_ack) - dst->seqdiff; 4252 if (src->seqdiff) { 4253 /* Modulate sequence numbers */ 4254 pf_change_a(&th->th_seq, &th->th_sum, htonl(seq + 4255 src->seqdiff), 0); 4256 pf_change_a(&th->th_ack, &th->th_sum, htonl(ack), 0); 4257 *copyback = 1; 4258 } 4259 end = seq + pd->p_len; 4260 if (th->th_flags & TH_SYN) 4261 end++; 4262 if (th->th_flags & TH_FIN) 4263 end++; 4264 } 4265 4266 if ((th->th_flags & TH_ACK) == 0) { 4267 /* Let it pass through the ack skew check */ 4268 ack = dst->seqlo; 4269 } else if ((ack == 0 && 4270 (th->th_flags & (TH_ACK|TH_RST)) == (TH_ACK|TH_RST)) || 4271 /* broken tcp stacks do not set ack */ 4272 (dst->state < TCPS_SYN_SENT)) { 4273 /* 4274 * Many stacks (ours included) will set the ACK number in an 4275 * FIN|ACK if the SYN times out -- no sequence to ACK. 4276 */ 4277 ack = dst->seqlo; 4278 } 4279 4280 if (seq == end) { 4281 /* Ease sequencing restrictions on no data packets */ 4282 seq = src->seqlo; 4283 end = seq; 4284 } 4285 4286 ackskew = dst->seqlo - ack; 4287 4288 4289 /* 4290 * Need to demodulate the sequence numbers in any TCP SACK options 4291 * (Selective ACK). We could optionally validate the SACK values 4292 * against the current ACK window, either forwards or backwards, but 4293 * I'm not confident that SACK has been implemented properly 4294 * everywhere. It wouldn't surprise me if several stacks accidently 4295 * SACK too far backwards of previously ACKed data. There really aren't 4296 * any security implications of bad SACKing unless the target stack 4297 * doesn't validate the option length correctly. Someone trying to 4298 * spoof into a TCP connection won't bother blindly sending SACK 4299 * options anyway. 4300 */ 4301 if (dst->seqdiff && (th->th_off << 2) > sizeof(struct tcphdr)) { 4302 if (pf_modulate_sack(m, off, pd, th, dst)) 4303 *copyback = 1; 4304 } 4305 4306 4307#define MAXACKWINDOW (0xffff + 1500) /* 1500 is an arbitrary fudge factor */ 4308 if (SEQ_GEQ(src->seqhi, end) && 4309 /* Last octet inside other's window space */ 4310 SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) && 4311 /* Retrans: not more than one window back */ 4312 (ackskew >= -MAXACKWINDOW) && 4313 /* Acking not more than one reassembled fragment backwards */ 4314 (ackskew <= (MAXACKWINDOW << sws)) && 4315 /* Acking not more than one window forward */ 4316 ((th->th_flags & TH_RST) == 0 || orig_seq == src->seqlo || 4317 (orig_seq == src->seqlo + 1) || (orig_seq + 1 == src->seqlo) || 4318 (pd->flags & PFDESC_IP_REAS) == 0)) { 4319 /* Require an exact/+1 sequence match on resets when possible */ 4320 4321 if (dst->scrub || src->scrub) { 4322 if (pf_normalize_tcp_stateful(m, off, pd, reason, th, 4323 *state, src, dst, copyback)) 4324 return (PF_DROP); 4325 } 4326 4327 /* update max window */ 4328 if (src->max_win < win) 4329 src->max_win = win; 4330 /* synchronize sequencing */ 4331 if (SEQ_GT(end, src->seqlo)) 4332 src->seqlo = end; 4333 /* slide the window of what the other end can send */ 4334 if (SEQ_GEQ(ack + (win << sws), dst->seqhi)) 4335 dst->seqhi = ack + MAX((win << sws), 1); 4336 4337 4338 /* update states */ 4339 if (th->th_flags & TH_SYN) 4340 if (src->state < TCPS_SYN_SENT) 4341 src->state = TCPS_SYN_SENT; 4342 if (th->th_flags & TH_FIN) 4343 if (src->state < TCPS_CLOSING) 4344 src->state = TCPS_CLOSING; 4345 if (th->th_flags & TH_ACK) { 4346 if (dst->state == TCPS_SYN_SENT) { 4347 dst->state = TCPS_ESTABLISHED; 4348 if (src->state == TCPS_ESTABLISHED && 4349 (*state)->src_node != NULL && 4350 pf_src_connlimit(state)) { 4351 REASON_SET(reason, PFRES_SRCLIMIT); 4352 return (PF_DROP); 4353 } 4354 } else if (dst->state == TCPS_CLOSING) 4355 dst->state = TCPS_FIN_WAIT_2; 4356 } 4357 if (th->th_flags & TH_RST) 4358 src->state = dst->state = TCPS_TIME_WAIT; 4359 4360 /* update expire time */ 4361 (*state)->expire = time_second; 4362 if (src->state >= TCPS_FIN_WAIT_2 && 4363 dst->state >= TCPS_FIN_WAIT_2) 4364 (*state)->timeout = PFTM_TCP_CLOSED; 4365 else if (src->state >= TCPS_CLOSING && 4366 dst->state >= TCPS_CLOSING) 4367 (*state)->timeout = PFTM_TCP_FIN_WAIT; 4368 else if (src->state < TCPS_ESTABLISHED || 4369 dst->state < TCPS_ESTABLISHED) 4370 (*state)->timeout = PFTM_TCP_OPENING; 4371 else if (src->state >= TCPS_CLOSING || 4372 dst->state >= TCPS_CLOSING) 4373 (*state)->timeout = PFTM_TCP_CLOSING; 4374 else 4375 (*state)->timeout = PFTM_TCP_ESTABLISHED; 4376 4377 /* Fall through to PASS packet */ 4378 4379 } else if ((dst->state < TCPS_SYN_SENT || 4380 dst->state >= TCPS_FIN_WAIT_2 || 4381 src->state >= TCPS_FIN_WAIT_2) && 4382 SEQ_GEQ(src->seqhi + MAXACKWINDOW, end) && 4383 /* Within a window forward of the originating packet */ 4384 SEQ_GEQ(seq, src->seqlo - MAXACKWINDOW)) { 4385 /* Within a window backward of the originating packet */ 4386 4387 /* 4388 * This currently handles three situations: 4389 * 1) Stupid stacks will shotgun SYNs before their peer 4390 * replies. 4391 * 2) When PF catches an already established stream (the 4392 * firewall rebooted, the state table was flushed, routes 4393 * changed...) 4394 * 3) Packets get funky immediately after the connection 4395 * closes (this should catch Solaris spurious ACK|FINs 4396 * that web servers like to spew after a close) 4397 * 4398 * This must be a little more careful than the above code 4399 * since packet floods will also be caught here. We don't 4400 * update the TTL here to mitigate the damage of a packet 4401 * flood and so the same code can handle awkward establishment 4402 * and a loosened connection close. 4403 * In the establishment case, a correct peer response will 4404 * validate the connection, go through the normal state code 4405 * and keep updating the state TTL. 4406 */ 4407 4408#ifdef __FreeBSD__ 4409 if (V_pf_status.debug >= PF_DEBUG_MISC) { 4410#else 4411 if (pf_status.debug >= PF_DEBUG_MISC) { 4412#endif 4413 printf("pf: loose state match: "); 4414 pf_print_state(*state); 4415 pf_print_flags(th->th_flags); 4416 printf(" seq=%u (%u) ack=%u len=%u ackskew=%d " 4417 "pkts=%llu:%llu dir=%s,%s\n", seq, orig_seq, ack, 4418#ifdef __FreeBSD__ 4419 pd->p_len, ackskew, (unsigned long long)(*state)->packets[0], 4420 (unsigned long long)(*state)->packets[1], 4421#else 4422 pd->p_len, ackskew, (*state)->packets[0], 4423 (*state)->packets[1], 4424#endif 4425 pd->dir == PF_IN ? "in" : "out", 4426 pd->dir == (*state)->direction ? "fwd" : "rev"); 4427 } 4428 4429 if (dst->scrub || src->scrub) { 4430 if (pf_normalize_tcp_stateful(m, off, pd, reason, th, 4431 *state, src, dst, copyback)) 4432 return (PF_DROP); 4433 } 4434 4435 /* update max window */ 4436 if (src->max_win < win) 4437 src->max_win = win; 4438 /* synchronize sequencing */ 4439 if (SEQ_GT(end, src->seqlo)) 4440 src->seqlo = end; 4441 /* slide the window of what the other end can send */ 4442 if (SEQ_GEQ(ack + (win << sws), dst->seqhi)) 4443 dst->seqhi = ack + MAX((win << sws), 1); 4444 4445 /* 4446 * Cannot set dst->seqhi here since this could be a shotgunned 4447 * SYN and not an already established connection. 4448 */ 4449 4450 if (th->th_flags & TH_FIN) 4451 if (src->state < TCPS_CLOSING) 4452 src->state = TCPS_CLOSING; 4453 if (th->th_flags & TH_RST) 4454 src->state = dst->state = TCPS_TIME_WAIT; 4455 4456 /* Fall through to PASS packet */ 4457 4458 } else { 4459 if ((*state)->dst.state == TCPS_SYN_SENT && 4460 (*state)->src.state == TCPS_SYN_SENT) { 4461 /* Send RST for state mismatches during handshake */ 4462 if (!(th->th_flags & TH_RST)) 4463#ifdef __FreeBSD__ 4464 pf_send_tcp(NULL, (*state)->rule.ptr, pd->af, 4465#else 4466 pf_send_tcp((*state)->rule.ptr, pd->af, 4467#endif 4468 pd->dst, pd->src, th->th_dport, 4469 th->th_sport, ntohl(th->th_ack), 0, 4470 TH_RST, 0, 0, 4471 (*state)->rule.ptr->return_ttl, 1, 0, 4472 pd->eh, kif->pfik_ifp); 4473 src->seqlo = 0; 4474 src->seqhi = 1; 4475 src->max_win = 1; 4476#ifdef __FreeBSD__ 4477 } else if (V_pf_status.debug >= PF_DEBUG_MISC) { 4478#else 4479 } else if (pf_status.debug >= PF_DEBUG_MISC) { 4480#endif 4481 printf("pf: BAD state: "); 4482 pf_print_state(*state); 4483 pf_print_flags(th->th_flags); 4484 printf(" seq=%u (%u) ack=%u len=%u ackskew=%d " 4485 "pkts=%llu:%llu dir=%s,%s\n", 4486 seq, orig_seq, ack, pd->p_len, ackskew, 4487#ifdef __FreeBSD__ 4488 (unsigned long long)(*state)->packets[0], 4489 (unsigned long long)(*state)->packets[1], 4490#else 4491 (*state)->packets[0], (*state)->packets[1], 4492#endif 4493 pd->dir == PF_IN ? "in" : "out", 4494 pd->dir == (*state)->direction ? "fwd" : "rev"); 4495 printf("pf: State failure on: %c %c %c %c | %c %c\n", 4496 SEQ_GEQ(src->seqhi, end) ? ' ' : '1', 4497 SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)) ? 4498 ' ': '2', 4499 (ackskew >= -MAXACKWINDOW) ? ' ' : '3', 4500 (ackskew <= (MAXACKWINDOW << sws)) ? ' ' : '4', 4501 SEQ_GEQ(src->seqhi + MAXACKWINDOW, end) ?' ' :'5', 4502 SEQ_GEQ(seq, src->seqlo - MAXACKWINDOW) ?' ' :'6'); 4503 } 4504 REASON_SET(reason, PFRES_BADSTATE); 4505 return (PF_DROP); 4506 } 4507 4508 return (PF_PASS); 4509} 4510 4511int 4512pf_tcp_track_sloppy(struct pf_state_peer *src, struct pf_state_peer *dst, 4513 struct pf_state **state, struct pf_pdesc *pd, u_short *reason) 4514{ 4515 struct tcphdr *th = pd->hdr.tcp; 4516 4517 if (th->th_flags & TH_SYN) 4518 if (src->state < TCPS_SYN_SENT) 4519 src->state = TCPS_SYN_SENT; 4520 if (th->th_flags & TH_FIN) 4521 if (src->state < TCPS_CLOSING) 4522 src->state = TCPS_CLOSING; 4523 if (th->th_flags & TH_ACK) { 4524 if (dst->state == TCPS_SYN_SENT) { 4525 dst->state = TCPS_ESTABLISHED; 4526 if (src->state == TCPS_ESTABLISHED && 4527 (*state)->src_node != NULL && 4528 pf_src_connlimit(state)) { 4529 REASON_SET(reason, PFRES_SRCLIMIT); 4530 return (PF_DROP); 4531 } 4532 } else if (dst->state == TCPS_CLOSING) { 4533 dst->state = TCPS_FIN_WAIT_2; 4534 } else if (src->state == TCPS_SYN_SENT && 4535 dst->state < TCPS_SYN_SENT) { 4536 /* 4537 * Handle a special sloppy case where we only see one 4538 * half of the connection. If there is a ACK after 4539 * the initial SYN without ever seeing a packet from 4540 * the destination, set the connection to established. 4541 */ 4542 dst->state = src->state = TCPS_ESTABLISHED; 4543 if ((*state)->src_node != NULL && 4544 pf_src_connlimit(state)) { 4545 REASON_SET(reason, PFRES_SRCLIMIT); 4546 return (PF_DROP); 4547 } 4548 } else if (src->state == TCPS_CLOSING && 4549 dst->state == TCPS_ESTABLISHED && 4550 dst->seqlo == 0) { 4551 /* 4552 * Handle the closing of half connections where we 4553 * don't see the full bidirectional FIN/ACK+ACK 4554 * handshake. 4555 */ 4556 dst->state = TCPS_CLOSING; 4557 } 4558 } 4559 if (th->th_flags & TH_RST) 4560 src->state = dst->state = TCPS_TIME_WAIT; 4561 4562 /* update expire time */ 4563 (*state)->expire = time_second; 4564 if (src->state >= TCPS_FIN_WAIT_2 && 4565 dst->state >= TCPS_FIN_WAIT_2) 4566 (*state)->timeout = PFTM_TCP_CLOSED; 4567 else if (src->state >= TCPS_CLOSING && 4568 dst->state >= TCPS_CLOSING) 4569 (*state)->timeout = PFTM_TCP_FIN_WAIT; 4570 else if (src->state < TCPS_ESTABLISHED || 4571 dst->state < TCPS_ESTABLISHED) 4572 (*state)->timeout = PFTM_TCP_OPENING; 4573 else if (src->state >= TCPS_CLOSING || 4574 dst->state >= TCPS_CLOSING) 4575 (*state)->timeout = PFTM_TCP_CLOSING; 4576 else 4577 (*state)->timeout = PFTM_TCP_ESTABLISHED; 4578 4579 return (PF_PASS); 4580} 4581 4582int 4583pf_test_state_tcp(struct pf_state **state, int direction, struct pfi_kif *kif, 4584 struct mbuf *m, int off, void *h, struct pf_pdesc *pd, 4585 u_short *reason) 4586{ 4587 struct pf_state_key_cmp key; 4588 struct tcphdr *th = pd->hdr.tcp; 4589 int copyback = 0; 4590 struct pf_state_peer *src, *dst; 4591 struct pf_state_key *sk; 4592 4593 key.af = pd->af; 4594 key.proto = IPPROTO_TCP; 4595 if (direction == PF_IN) { /* wire side, straight */ 4596 PF_ACPY(&key.addr[0], pd->src, key.af); 4597 PF_ACPY(&key.addr[1], pd->dst, key.af); 4598 key.port[0] = th->th_sport; 4599 key.port[1] = th->th_dport; 4600 } else { /* stack side, reverse */ 4601 PF_ACPY(&key.addr[1], pd->src, key.af); 4602 PF_ACPY(&key.addr[0], pd->dst, key.af); 4603 key.port[1] = th->th_sport; 4604 key.port[0] = th->th_dport; 4605 } 4606 4607#ifdef __FreeBSD__ 4608 STATE_LOOKUP(kif, &key, direction, *state, m, pd->pf_mtag); 4609#else 4610 STATE_LOOKUP(kif, &key, direction, *state, m); 4611#endif 4612 4613 if (direction == (*state)->direction) { 4614 src = &(*state)->src; 4615 dst = &(*state)->dst; 4616 } else { 4617 src = &(*state)->dst; 4618 dst = &(*state)->src; 4619 } 4620 4621 sk = (*state)->key[pd->didx]; 4622 4623 if ((*state)->src.state == PF_TCPS_PROXY_SRC) { 4624 if (direction != (*state)->direction) { 4625 REASON_SET(reason, PFRES_SYNPROXY); 4626 return (PF_SYNPROXY_DROP); 4627 } 4628 if (th->th_flags & TH_SYN) { 4629 if (ntohl(th->th_seq) != (*state)->src.seqlo) { 4630 REASON_SET(reason, PFRES_SYNPROXY); 4631 return (PF_DROP); 4632 } 4633#ifdef __FreeBSD__ 4634 pf_send_tcp(NULL, (*state)->rule.ptr, pd->af, pd->dst, 4635#else 4636 pf_send_tcp((*state)->rule.ptr, pd->af, pd->dst, 4637#endif 4638 pd->src, th->th_dport, th->th_sport, 4639 (*state)->src.seqhi, ntohl(th->th_seq) + 1, 4640 TH_SYN|TH_ACK, 0, (*state)->src.mss, 0, 1, 4641 0, NULL, NULL); 4642 REASON_SET(reason, PFRES_SYNPROXY); 4643 return (PF_SYNPROXY_DROP); 4644 } else if (!(th->th_flags & TH_ACK) || 4645 (ntohl(th->th_ack) != (*state)->src.seqhi + 1) || 4646 (ntohl(th->th_seq) != (*state)->src.seqlo + 1)) { 4647 REASON_SET(reason, PFRES_SYNPROXY); 4648 return (PF_DROP); 4649 } else if ((*state)->src_node != NULL && 4650 pf_src_connlimit(state)) { 4651 REASON_SET(reason, PFRES_SRCLIMIT); 4652 return (PF_DROP); 4653 } else 4654 (*state)->src.state = PF_TCPS_PROXY_DST; 4655 } 4656 if ((*state)->src.state == PF_TCPS_PROXY_DST) { 4657 if (direction == (*state)->direction) { 4658 if (((th->th_flags & (TH_SYN|TH_ACK)) != TH_ACK) || 4659 (ntohl(th->th_ack) != (*state)->src.seqhi + 1) || 4660 (ntohl(th->th_seq) != (*state)->src.seqlo + 1)) { 4661 REASON_SET(reason, PFRES_SYNPROXY); 4662 return (PF_DROP); 4663 } 4664 (*state)->src.max_win = MAX(ntohs(th->th_win), 1); 4665 if ((*state)->dst.seqhi == 1) 4666 (*state)->dst.seqhi = htonl(arc4random()); 4667#ifdef __FreeBSD__ 4668 pf_send_tcp(NULL, (*state)->rule.ptr, pd->af, 4669#else 4670 pf_send_tcp((*state)->rule.ptr, pd->af, 4671#endif 4672 &sk->addr[pd->sidx], &sk->addr[pd->didx], 4673 sk->port[pd->sidx], sk->port[pd->didx], 4674 (*state)->dst.seqhi, 0, TH_SYN, 0, 4675 (*state)->src.mss, 0, 0, (*state)->tag, NULL, NULL); 4676 REASON_SET(reason, PFRES_SYNPROXY); 4677 return (PF_SYNPROXY_DROP); 4678 } else if (((th->th_flags & (TH_SYN|TH_ACK)) != 4679 (TH_SYN|TH_ACK)) || 4680 (ntohl(th->th_ack) != (*state)->dst.seqhi + 1)) { 4681 REASON_SET(reason, PFRES_SYNPROXY); 4682 return (PF_DROP); 4683 } else { 4684 (*state)->dst.max_win = MAX(ntohs(th->th_win), 1); 4685 (*state)->dst.seqlo = ntohl(th->th_seq); 4686#ifdef __FreeBSD__ 4687 pf_send_tcp(NULL, (*state)->rule.ptr, pd->af, pd->dst, 4688#else 4689 pf_send_tcp((*state)->rule.ptr, pd->af, pd->dst, 4690#endif 4691 pd->src, th->th_dport, th->th_sport, 4692 ntohl(th->th_ack), ntohl(th->th_seq) + 1, 4693 TH_ACK, (*state)->src.max_win, 0, 0, 0, 4694 (*state)->tag, NULL, NULL); 4695#ifdef __FreeBSD__ 4696 pf_send_tcp(NULL, (*state)->rule.ptr, pd->af, 4697#else 4698 pf_send_tcp((*state)->rule.ptr, pd->af, 4699#endif 4700 &sk->addr[pd->sidx], &sk->addr[pd->didx], 4701 sk->port[pd->sidx], sk->port[pd->didx], 4702 (*state)->src.seqhi + 1, (*state)->src.seqlo + 1, 4703 TH_ACK, (*state)->dst.max_win, 0, 0, 1, 4704 0, NULL, NULL); 4705 (*state)->src.seqdiff = (*state)->dst.seqhi - 4706 (*state)->src.seqlo; 4707 (*state)->dst.seqdiff = (*state)->src.seqhi - 4708 (*state)->dst.seqlo; 4709 (*state)->src.seqhi = (*state)->src.seqlo + 4710 (*state)->dst.max_win; 4711 (*state)->dst.seqhi = (*state)->dst.seqlo + 4712 (*state)->src.max_win; 4713 (*state)->src.wscale = (*state)->dst.wscale = 0; 4714 (*state)->src.state = (*state)->dst.state = 4715 TCPS_ESTABLISHED; 4716 REASON_SET(reason, PFRES_SYNPROXY); 4717 return (PF_SYNPROXY_DROP); 4718 } 4719 } 4720 4721 if (((th->th_flags & (TH_SYN|TH_ACK)) == TH_SYN) && 4722 dst->state >= TCPS_FIN_WAIT_2 && 4723 src->state >= TCPS_FIN_WAIT_2) { 4724#ifdef __FreeBSD__ 4725 if (V_pf_status.debug >= PF_DEBUG_MISC) { 4726#else 4727 if (pf_status.debug >= PF_DEBUG_MISC) { 4728#endif 4729 printf("pf: state reuse "); 4730 pf_print_state(*state); 4731 pf_print_flags(th->th_flags); 4732 printf("\n"); 4733 } 4734 /* XXX make sure it's the same direction ?? */ 4735 (*state)->src.state = (*state)->dst.state = TCPS_CLOSED; 4736 pf_unlink_state(*state); 4737 *state = NULL; 4738 return (PF_DROP); 4739 } 4740 4741 if ((*state)->state_flags & PFSTATE_SLOPPY) { 4742 if (pf_tcp_track_sloppy(src, dst, state, pd, reason) == PF_DROP) 4743 return (PF_DROP); 4744 } else { 4745 if (pf_tcp_track_full(src, dst, state, kif, m, off, pd, reason, 4746 ©back) == PF_DROP) 4747 return (PF_DROP); 4748 } 4749 4750 /* translate source/destination address, if necessary */ 4751 if ((*state)->key[PF_SK_WIRE] != (*state)->key[PF_SK_STACK]) { 4752 struct pf_state_key *nk = (*state)->key[pd->didx]; 4753 4754 if (PF_ANEQ(pd->src, &nk->addr[pd->sidx], pd->af) || 4755 nk->port[pd->sidx] != th->th_sport) 4756 pf_change_ap(pd->src, &th->th_sport, pd->ip_sum, 4757 &th->th_sum, &nk->addr[pd->sidx], 4758 nk->port[pd->sidx], 0, pd->af); 4759 4760 if (PF_ANEQ(pd->dst, &nk->addr[pd->didx], pd->af) || 4761 nk->port[pd->didx] != th->th_dport) 4762 pf_change_ap(pd->dst, &th->th_dport, pd->ip_sum, 4763 &th->th_sum, &nk->addr[pd->didx], 4764 nk->port[pd->didx], 0, pd->af); 4765 copyback = 1; 4766 } 4767 4768 /* Copyback sequence modulation or stateful scrub changes if needed */ 4769 if (copyback) 4770#ifdef __FreeBSD__ 4771 m_copyback(m, off, sizeof(*th), (caddr_t)th); 4772#else 4773 m_copyback(m, off, sizeof(*th), th); 4774#endif 4775 4776 return (PF_PASS); 4777} 4778 4779int 4780pf_test_state_udp(struct pf_state **state, int direction, struct pfi_kif *kif, 4781 struct mbuf *m, int off, void *h, struct pf_pdesc *pd) 4782{ 4783 struct pf_state_peer *src, *dst; 4784 struct pf_state_key_cmp key; 4785 struct udphdr *uh = pd->hdr.udp; 4786 4787 key.af = pd->af; 4788 key.proto = IPPROTO_UDP; 4789 if (direction == PF_IN) { /* wire side, straight */ 4790 PF_ACPY(&key.addr[0], pd->src, key.af); 4791 PF_ACPY(&key.addr[1], pd->dst, key.af); 4792 key.port[0] = uh->uh_sport; 4793 key.port[1] = uh->uh_dport; 4794 } else { /* stack side, reverse */ 4795 PF_ACPY(&key.addr[1], pd->src, key.af); 4796 PF_ACPY(&key.addr[0], pd->dst, key.af); 4797 key.port[1] = uh->uh_sport; 4798 key.port[0] = uh->uh_dport; 4799 } 4800 4801#ifdef __FreeBSD__ 4802 STATE_LOOKUP(kif, &key, direction, *state, m, pd->pf_mtag); 4803#else 4804 STATE_LOOKUP(kif, &key, direction, *state, m); 4805#endif 4806 4807 if (direction == (*state)->direction) { 4808 src = &(*state)->src; 4809 dst = &(*state)->dst; 4810 } else { 4811 src = &(*state)->dst; 4812 dst = &(*state)->src; 4813 } 4814 4815 /* update states */ 4816 if (src->state < PFUDPS_SINGLE) 4817 src->state = PFUDPS_SINGLE; 4818 if (dst->state == PFUDPS_SINGLE) 4819 dst->state = PFUDPS_MULTIPLE; 4820 4821 /* update expire time */ 4822 (*state)->expire = time_second; 4823 if (src->state == PFUDPS_MULTIPLE && dst->state == PFUDPS_MULTIPLE) 4824 (*state)->timeout = PFTM_UDP_MULTIPLE; 4825 else 4826 (*state)->timeout = PFTM_UDP_SINGLE; 4827 4828 /* translate source/destination address, if necessary */ 4829 if ((*state)->key[PF_SK_WIRE] != (*state)->key[PF_SK_STACK]) { 4830 struct pf_state_key *nk = (*state)->key[pd->didx]; 4831 4832 if (PF_ANEQ(pd->src, &nk->addr[pd->sidx], pd->af) || 4833 nk->port[pd->sidx] != uh->uh_sport) 4834 pf_change_ap(pd->src, &uh->uh_sport, pd->ip_sum, 4835 &uh->uh_sum, &nk->addr[pd->sidx], 4836 nk->port[pd->sidx], 1, pd->af); 4837 4838 if (PF_ANEQ(pd->dst, &nk->addr[pd->didx], pd->af) || 4839 nk->port[pd->didx] != uh->uh_dport) 4840 pf_change_ap(pd->dst, &uh->uh_dport, pd->ip_sum, 4841 &uh->uh_sum, &nk->addr[pd->didx], 4842 nk->port[pd->didx], 1, pd->af); 4843#ifdef __FreeBSD__ 4844 m_copyback(m, off, sizeof(*uh), (caddr_t)uh); 4845#else 4846 m_copyback(m, off, sizeof(*uh), uh); 4847#endif 4848 } 4849 4850 return (PF_PASS); 4851} 4852 4853int 4854pf_test_state_icmp(struct pf_state **state, int direction, struct pfi_kif *kif, 4855 struct mbuf *m, int off, void *h, struct pf_pdesc *pd, u_short *reason) 4856{ 4857 struct pf_addr *saddr = pd->src, *daddr = pd->dst; 4858#ifdef __FreeBSD__ 4859 u_int16_t icmpid = 0, *icmpsum; 4860#else 4861 u_int16_t icmpid, *icmpsum; 4862#endif 4863 u_int8_t icmptype; 4864 int state_icmp = 0; 4865 struct pf_state_key_cmp key; 4866 4867 switch (pd->proto) { 4868#ifdef INET 4869 case IPPROTO_ICMP: 4870 icmptype = pd->hdr.icmp->icmp_type; 4871 icmpid = pd->hdr.icmp->icmp_id; 4872 icmpsum = &pd->hdr.icmp->icmp_cksum; 4873 4874 if (icmptype == ICMP_UNREACH || 4875 icmptype == ICMP_SOURCEQUENCH || 4876 icmptype == ICMP_REDIRECT || 4877 icmptype == ICMP_TIMXCEED || 4878 icmptype == ICMP_PARAMPROB) 4879 state_icmp++; 4880 break; 4881#endif /* INET */ 4882#ifdef INET6 4883 case IPPROTO_ICMPV6: 4884 icmptype = pd->hdr.icmp6->icmp6_type; 4885 icmpid = pd->hdr.icmp6->icmp6_id; 4886 icmpsum = &pd->hdr.icmp6->icmp6_cksum; 4887 4888 if (icmptype == ICMP6_DST_UNREACH || 4889 icmptype == ICMP6_PACKET_TOO_BIG || 4890 icmptype == ICMP6_TIME_EXCEEDED || 4891 icmptype == ICMP6_PARAM_PROB) 4892 state_icmp++; 4893 break; 4894#endif /* INET6 */ 4895 } 4896 4897 if (!state_icmp) { 4898 4899 /* 4900 * ICMP query/reply message not related to a TCP/UDP packet. 4901 * Search for an ICMP state. 4902 */ 4903 key.af = pd->af; 4904 key.proto = pd->proto; 4905 key.port[0] = key.port[1] = icmpid; 4906 if (direction == PF_IN) { /* wire side, straight */ 4907 PF_ACPY(&key.addr[0], pd->src, key.af); 4908 PF_ACPY(&key.addr[1], pd->dst, key.af); 4909 } else { /* stack side, reverse */ 4910 PF_ACPY(&key.addr[1], pd->src, key.af); 4911 PF_ACPY(&key.addr[0], pd->dst, key.af); 4912 } 4913 4914#ifdef __FreeBSD__ 4915 STATE_LOOKUP(kif, &key, direction, *state, m, pd->pf_mtag); 4916#else 4917 STATE_LOOKUP(kif, &key, direction, *state, m); 4918#endif 4919 4920 (*state)->expire = time_second; 4921 (*state)->timeout = PFTM_ICMP_ERROR_REPLY; 4922 4923 /* translate source/destination address, if necessary */ 4924 if ((*state)->key[PF_SK_WIRE] != (*state)->key[PF_SK_STACK]) { 4925 struct pf_state_key *nk = (*state)->key[pd->didx]; 4926 4927 switch (pd->af) { 4928#ifdef INET 4929 case AF_INET: 4930 if (PF_ANEQ(pd->src, 4931 &nk->addr[pd->sidx], AF_INET)) 4932 pf_change_a(&saddr->v4.s_addr, 4933 pd->ip_sum, 4934 nk->addr[pd->sidx].v4.s_addr, 0); 4935 4936 if (PF_ANEQ(pd->dst, &nk->addr[pd->didx], 4937 AF_INET)) 4938 pf_change_a(&daddr->v4.s_addr, 4939 pd->ip_sum, 4940 nk->addr[pd->didx].v4.s_addr, 0); 4941 4942 if (nk->port[0] != 4943 pd->hdr.icmp->icmp_id) { 4944 pd->hdr.icmp->icmp_cksum = 4945 pf_cksum_fixup( 4946 pd->hdr.icmp->icmp_cksum, icmpid, 4947 nk->port[pd->sidx], 0); 4948 pd->hdr.icmp->icmp_id = 4949 nk->port[pd->sidx]; 4950 } 4951 4952 m_copyback(m, off, ICMP_MINLEN, 4953#ifdef __FreeBSD__ 4954 (caddr_t) 4955#endif 4956 pd->hdr.icmp); 4957 break; 4958#endif /* INET */ 4959#ifdef INET6 4960 case AF_INET6: 4961 if (PF_ANEQ(pd->src, 4962 &nk->addr[pd->sidx], AF_INET6)) 4963 pf_change_a6(saddr, 4964 &pd->hdr.icmp6->icmp6_cksum, 4965 &nk->addr[pd->sidx], 0); 4966 4967 if (PF_ANEQ(pd->dst, 4968 &nk->addr[pd->didx], AF_INET6)) 4969 pf_change_a6(daddr, 4970 &pd->hdr.icmp6->icmp6_cksum, 4971 &nk->addr[pd->didx], 0); 4972 4973 m_copyback(m, off, 4974 sizeof(struct icmp6_hdr), 4975#ifdef __FreeBSD__ 4976 (caddr_t) 4977#endif 4978 pd->hdr.icmp6); 4979 break; 4980#endif /* INET6 */ 4981 } 4982 } 4983 return (PF_PASS); 4984 4985 } else { 4986 /* 4987 * ICMP error message in response to a TCP/UDP packet. 4988 * Extract the inner TCP/UDP header and search for that state. 4989 */ 4990 4991 struct pf_pdesc pd2; 4992#ifdef __FreeBSD__ 4993 bzero(&pd2, sizeof pd2); 4994#endif 4995#ifdef INET 4996 struct ip h2; 4997#endif /* INET */ 4998#ifdef INET6 4999 struct ip6_hdr h2_6; 5000 int terminal = 0; 5001#endif /* INET6 */ 5002#ifdef __FreeBSD__ 5003 int ipoff2 = 0; 5004 int off2 = 0; 5005#else 5006 int ipoff2; 5007 int off2; 5008#endif 5009 5010 pd2.af = pd->af; 5011 /* Payload packet is from the opposite direction. */ 5012 pd2.sidx = (direction == PF_IN) ? 1 : 0; 5013 pd2.didx = (direction == PF_IN) ? 0 : 1; 5014 switch (pd->af) { 5015#ifdef INET 5016 case AF_INET: 5017 /* offset of h2 in mbuf chain */ 5018 ipoff2 = off + ICMP_MINLEN; 5019 5020 if (!pf_pull_hdr(m, ipoff2, &h2, sizeof(h2), 5021 NULL, reason, pd2.af)) { 5022 DPFPRINTF(PF_DEBUG_MISC, 5023 ("pf: ICMP error message too short " 5024 "(ip)\n")); 5025 return (PF_DROP); 5026 } 5027 /* 5028 * ICMP error messages don't refer to non-first 5029 * fragments 5030 */ 5031 if (h2.ip_off & htons(IP_OFFMASK)) { 5032 REASON_SET(reason, PFRES_FRAG); 5033 return (PF_DROP); 5034 } 5035 5036 /* offset of protocol header that follows h2 */ 5037 off2 = ipoff2 + (h2.ip_hl << 2); 5038 5039 pd2.proto = h2.ip_p; 5040 pd2.src = (struct pf_addr *)&h2.ip_src; 5041 pd2.dst = (struct pf_addr *)&h2.ip_dst; 5042 pd2.ip_sum = &h2.ip_sum; 5043 break; 5044#endif /* INET */ 5045#ifdef INET6 5046 case AF_INET6: 5047 ipoff2 = off + sizeof(struct icmp6_hdr); 5048 5049 if (!pf_pull_hdr(m, ipoff2, &h2_6, sizeof(h2_6), 5050 NULL, reason, pd2.af)) { 5051 DPFPRINTF(PF_DEBUG_MISC, 5052 ("pf: ICMP error message too short " 5053 "(ip6)\n")); 5054 return (PF_DROP); 5055 } 5056 pd2.proto = h2_6.ip6_nxt; 5057 pd2.src = (struct pf_addr *)&h2_6.ip6_src; 5058 pd2.dst = (struct pf_addr *)&h2_6.ip6_dst; 5059 pd2.ip_sum = NULL; 5060 off2 = ipoff2 + sizeof(h2_6); 5061 do { 5062 switch (pd2.proto) { 5063 case IPPROTO_FRAGMENT: 5064 /* 5065 * ICMPv6 error messages for 5066 * non-first fragments 5067 */ 5068 REASON_SET(reason, PFRES_FRAG); 5069 return (PF_DROP); 5070 case IPPROTO_AH: 5071 case IPPROTO_HOPOPTS: 5072 case IPPROTO_ROUTING: 5073 case IPPROTO_DSTOPTS: { 5074 /* get next header and header length */ 5075 struct ip6_ext opt6; 5076 5077 if (!pf_pull_hdr(m, off2, &opt6, 5078 sizeof(opt6), NULL, reason, 5079 pd2.af)) { 5080 DPFPRINTF(PF_DEBUG_MISC, 5081 ("pf: ICMPv6 short opt\n")); 5082 return (PF_DROP); 5083 } 5084 if (pd2.proto == IPPROTO_AH) 5085 off2 += (opt6.ip6e_len + 2) * 4; 5086 else 5087 off2 += (opt6.ip6e_len + 1) * 8; 5088 pd2.proto = opt6.ip6e_nxt; 5089 /* goto the next header */ 5090 break; 5091 } 5092 default: 5093 terminal++; 5094 break; 5095 } 5096 } while (!terminal); 5097 break; 5098#endif /* INET6 */ 5099 } 5100 5101 switch (pd2.proto) { 5102 case IPPROTO_TCP: { 5103 struct tcphdr th; 5104 u_int32_t seq; 5105 struct pf_state_peer *src, *dst; 5106 u_int8_t dws; 5107 int copyback = 0; 5108 5109 /* 5110 * Only the first 8 bytes of the TCP header can be 5111 * expected. Don't access any TCP header fields after 5112 * th_seq, an ackskew test is not possible. 5113 */ 5114 if (!pf_pull_hdr(m, off2, &th, 8, NULL, reason, 5115 pd2.af)) { 5116 DPFPRINTF(PF_DEBUG_MISC, 5117 ("pf: ICMP error message too short " 5118 "(tcp)\n")); 5119 return (PF_DROP); 5120 } 5121 5122 key.af = pd2.af; 5123 key.proto = IPPROTO_TCP; 5124 PF_ACPY(&key.addr[pd2.sidx], pd2.src, key.af); 5125 PF_ACPY(&key.addr[pd2.didx], pd2.dst, key.af); 5126 key.port[pd2.sidx] = th.th_sport; 5127 key.port[pd2.didx] = th.th_dport; 5128 5129#ifdef __FreeBSD__ 5130 STATE_LOOKUP(kif, &key, direction, *state, m, pd->pf_mtag); 5131#else 5132 STATE_LOOKUP(kif, &key, direction, *state, m); 5133#endif 5134 5135 if (direction == (*state)->direction) { 5136 src = &(*state)->dst; 5137 dst = &(*state)->src; 5138 } else { 5139 src = &(*state)->src; 5140 dst = &(*state)->dst; 5141 } 5142 5143 if (src->wscale && dst->wscale) 5144 dws = dst->wscale & PF_WSCALE_MASK; 5145 else 5146 dws = 0; 5147 5148 /* Demodulate sequence number */ 5149 seq = ntohl(th.th_seq) - src->seqdiff; 5150 if (src->seqdiff) { 5151 pf_change_a(&th.th_seq, icmpsum, 5152 htonl(seq), 0); 5153 copyback = 1; 5154 } 5155 5156 if (!((*state)->state_flags & PFSTATE_SLOPPY) && 5157 (!SEQ_GEQ(src->seqhi, seq) || 5158 !SEQ_GEQ(seq, src->seqlo - (dst->max_win << dws)))) { 5159#ifdef __FreeBSD__ 5160 if (V_pf_status.debug >= PF_DEBUG_MISC) { 5161#else 5162 if (pf_status.debug >= PF_DEBUG_MISC) { 5163#endif 5164 printf("pf: BAD ICMP %d:%d ", 5165 icmptype, pd->hdr.icmp->icmp_code); 5166 pf_print_host(pd->src, 0, pd->af); 5167 printf(" -> "); 5168 pf_print_host(pd->dst, 0, pd->af); 5169 printf(" state: "); 5170 pf_print_state(*state); 5171 printf(" seq=%u\n", seq); 5172 } 5173 REASON_SET(reason, PFRES_BADSTATE); 5174 return (PF_DROP); 5175 } else { 5176#ifdef __FreeBSD__ 5177 if (V_pf_status.debug >= PF_DEBUG_MISC) { 5178#else 5179 if (pf_status.debug >= PF_DEBUG_MISC) { 5180#endif 5181 printf("pf: OK ICMP %d:%d ", 5182 icmptype, pd->hdr.icmp->icmp_code); 5183 pf_print_host(pd->src, 0, pd->af); 5184 printf(" -> "); 5185 pf_print_host(pd->dst, 0, pd->af); 5186 printf(" state: "); 5187 pf_print_state(*state); 5188 printf(" seq=%u\n", seq); 5189 } 5190 } 5191 5192 /* translate source/destination address, if necessary */ 5193 if ((*state)->key[PF_SK_WIRE] != 5194 (*state)->key[PF_SK_STACK]) { 5195 struct pf_state_key *nk = 5196 (*state)->key[pd->didx]; 5197 5198 if (PF_ANEQ(pd2.src, 5199 &nk->addr[pd2.sidx], pd2.af) || 5200 nk->port[pd2.sidx] != th.th_sport) 5201 pf_change_icmp(pd2.src, &th.th_sport, 5202 daddr, &nk->addr[pd2.sidx], 5203 nk->port[pd2.sidx], NULL, 5204 pd2.ip_sum, icmpsum, 5205 pd->ip_sum, 0, pd2.af); 5206 5207 if (PF_ANEQ(pd2.dst, 5208 &nk->addr[pd2.didx], pd2.af) || 5209 nk->port[pd2.didx] != th.th_dport) 5210 pf_change_icmp(pd2.dst, &th.th_dport, 5211 NULL, /* XXX Inbound NAT? */ 5212 &nk->addr[pd2.didx], 5213 nk->port[pd2.didx], NULL, 5214 pd2.ip_sum, icmpsum, 5215 pd->ip_sum, 0, pd2.af); 5216 copyback = 1; 5217 } 5218 5219 if (copyback) { 5220 switch (pd2.af) { 5221#ifdef INET 5222 case AF_INET: 5223 m_copyback(m, off, ICMP_MINLEN, 5224#ifdef __FreeBSD__ 5225 (caddr_t) 5226#endif 5227 pd->hdr.icmp); 5228 m_copyback(m, ipoff2, sizeof(h2), 5229#ifdef __FreeBSD__ 5230 (caddr_t) 5231#endif 5232 &h2); 5233 break; 5234#endif /* INET */ 5235#ifdef INET6 5236 case AF_INET6: 5237 m_copyback(m, off, 5238 sizeof(struct icmp6_hdr), 5239#ifdef __FreeBSD__ 5240 (caddr_t) 5241#endif 5242 pd->hdr.icmp6); 5243 m_copyback(m, ipoff2, sizeof(h2_6), 5244#ifdef __FreeBSD__ 5245 (caddr_t) 5246#endif 5247 &h2_6); 5248 break; 5249#endif /* INET6 */ 5250 } 5251#ifdef __FreeBSD__ 5252 m_copyback(m, off2, 8, (caddr_t)&th); 5253#else 5254 m_copyback(m, off2, 8, &th); 5255#endif 5256 } 5257 5258 return (PF_PASS); 5259 break; 5260 } 5261 case IPPROTO_UDP: { 5262 struct udphdr uh; 5263 5264 if (!pf_pull_hdr(m, off2, &uh, sizeof(uh), 5265 NULL, reason, pd2.af)) { 5266 DPFPRINTF(PF_DEBUG_MISC, 5267 ("pf: ICMP error message too short " 5268 "(udp)\n")); 5269 return (PF_DROP); 5270 } 5271 5272 key.af = pd2.af; 5273 key.proto = IPPROTO_UDP; 5274 PF_ACPY(&key.addr[pd2.sidx], pd2.src, key.af); 5275 PF_ACPY(&key.addr[pd2.didx], pd2.dst, key.af); 5276 key.port[pd2.sidx] = uh.uh_sport; 5277 key.port[pd2.didx] = uh.uh_dport; 5278 5279#ifdef __FreeBSD__ 5280 STATE_LOOKUP(kif, &key, direction, *state, m, pd->pf_mtag); 5281#else 5282 STATE_LOOKUP(kif, &key, direction, *state, m); 5283#endif 5284 5285 /* translate source/destination address, if necessary */ 5286 if ((*state)->key[PF_SK_WIRE] != 5287 (*state)->key[PF_SK_STACK]) { 5288 struct pf_state_key *nk = 5289 (*state)->key[pd->didx]; 5290 5291 if (PF_ANEQ(pd2.src, 5292 &nk->addr[pd2.sidx], pd2.af) || 5293 nk->port[pd2.sidx] != uh.uh_sport) 5294 pf_change_icmp(pd2.src, &uh.uh_sport, 5295 daddr, &nk->addr[pd2.sidx], 5296 nk->port[pd2.sidx], &uh.uh_sum, 5297 pd2.ip_sum, icmpsum, 5298 pd->ip_sum, 1, pd2.af); 5299 5300 if (PF_ANEQ(pd2.dst, 5301 &nk->addr[pd2.didx], pd2.af) || 5302 nk->port[pd2.didx] != uh.uh_dport) 5303 pf_change_icmp(pd2.dst, &uh.uh_dport, 5304 NULL, /* XXX Inbound NAT? */ 5305 &nk->addr[pd2.didx], 5306 nk->port[pd2.didx], &uh.uh_sum, 5307 pd2.ip_sum, icmpsum, 5308 pd->ip_sum, 1, pd2.af); 5309 5310 switch (pd2.af) { 5311#ifdef INET 5312 case AF_INET: 5313 m_copyback(m, off, ICMP_MINLEN, 5314#ifdef __FreeBSD__ 5315 (caddr_t) 5316#endif 5317 pd->hdr.icmp); 5318#ifdef __FreeBSD__ 5319 m_copyback(m, ipoff2, sizeof(h2), (caddr_t)&h2); 5320#else 5321 m_copyback(m, ipoff2, sizeof(h2), &h2); 5322#endif 5323 break; 5324#endif /* INET */ 5325#ifdef INET6 5326 case AF_INET6: 5327 m_copyback(m, off, 5328 sizeof(struct icmp6_hdr), 5329#ifdef __FreeBSD__ 5330 (caddr_t) 5331#endif 5332 pd->hdr.icmp6); 5333 m_copyback(m, ipoff2, sizeof(h2_6), 5334#ifdef __FreeBSD__ 5335 (caddr_t) 5336#endif 5337 &h2_6); 5338 break; 5339#endif /* INET6 */ 5340 } 5341#ifdef __FreeBSD__ 5342 m_copyback(m, off2, sizeof(uh), (caddr_t)&uh); 5343#else 5344 m_copyback(m, off2, sizeof(uh), &uh); 5345#endif 5346 } 5347 return (PF_PASS); 5348 break; 5349 } 5350#ifdef INET 5351 case IPPROTO_ICMP: { 5352 struct icmp iih; 5353 5354 if (!pf_pull_hdr(m, off2, &iih, ICMP_MINLEN, 5355 NULL, reason, pd2.af)) { 5356 DPFPRINTF(PF_DEBUG_MISC, 5357 ("pf: ICMP error message too short i" 5358 "(icmp)\n")); 5359 return (PF_DROP); 5360 } 5361 5362 key.af = pd2.af; 5363 key.proto = IPPROTO_ICMP; 5364 PF_ACPY(&key.addr[pd2.sidx], pd2.src, key.af); 5365 PF_ACPY(&key.addr[pd2.didx], pd2.dst, key.af); 5366 key.port[0] = key.port[1] = iih.icmp_id; 5367 5368#ifdef __FreeBSD__ 5369 STATE_LOOKUP(kif, &key, direction, *state, m, pd->pf_mtag); 5370#else 5371 STATE_LOOKUP(kif, &key, direction, *state, m); 5372#endif 5373 5374 /* translate source/destination address, if necessary */ 5375 if ((*state)->key[PF_SK_WIRE] != 5376 (*state)->key[PF_SK_STACK]) { 5377 struct pf_state_key *nk = 5378 (*state)->key[pd->didx]; 5379 5380 if (PF_ANEQ(pd2.src, 5381 &nk->addr[pd2.sidx], pd2.af) || 5382 nk->port[pd2.sidx] != iih.icmp_id) 5383 pf_change_icmp(pd2.src, &iih.icmp_id, 5384 daddr, &nk->addr[pd2.sidx], 5385 nk->port[pd2.sidx], NULL, 5386 pd2.ip_sum, icmpsum, 5387 pd->ip_sum, 0, AF_INET); 5388 5389 if (PF_ANEQ(pd2.dst, 5390 &nk->addr[pd2.didx], pd2.af) || 5391 nk->port[pd2.didx] != iih.icmp_id) 5392 pf_change_icmp(pd2.dst, &iih.icmp_id, 5393 NULL, /* XXX Inbound NAT? */ 5394 &nk->addr[pd2.didx], 5395 nk->port[pd2.didx], NULL, 5396 pd2.ip_sum, icmpsum, 5397 pd->ip_sum, 0, AF_INET); 5398 5399#ifdef __FreeBSD__ 5400 m_copyback(m, off, ICMP_MINLEN, (caddr_t)pd->hdr.icmp); 5401 m_copyback(m, ipoff2, sizeof(h2), (caddr_t)&h2); 5402 m_copyback(m, off2, ICMP_MINLEN, (caddr_t)&iih); 5403#else 5404 m_copyback(m, off, ICMP_MINLEN, pd->hdr.icmp); 5405 m_copyback(m, ipoff2, sizeof(h2), &h2); 5406 m_copyback(m, off2, ICMP_MINLEN, &iih); 5407#endif 5408 } 5409 return (PF_PASS); 5410 break; 5411 } 5412#endif /* INET */ 5413#ifdef INET6 5414 case IPPROTO_ICMPV6: { 5415 struct icmp6_hdr iih; 5416 5417 if (!pf_pull_hdr(m, off2, &iih, 5418 sizeof(struct icmp6_hdr), NULL, reason, pd2.af)) { 5419 DPFPRINTF(PF_DEBUG_MISC, 5420 ("pf: ICMP error message too short " 5421 "(icmp6)\n")); 5422 return (PF_DROP); 5423 } 5424 5425 key.af = pd2.af; 5426 key.proto = IPPROTO_ICMPV6; 5427 PF_ACPY(&key.addr[pd2.sidx], pd2.src, key.af); 5428 PF_ACPY(&key.addr[pd2.didx], pd2.dst, key.af); 5429 key.port[0] = key.port[1] = iih.icmp6_id; 5430 5431#ifdef __FreeBSD__ 5432 STATE_LOOKUP(kif, &key, direction, *state, m, pd->pf_mtag); 5433#else 5434 STATE_LOOKUP(kif, &key, direction, *state, m); 5435#endif 5436 5437 /* translate source/destination address, if necessary */ 5438 if ((*state)->key[PF_SK_WIRE] != 5439 (*state)->key[PF_SK_STACK]) { 5440 struct pf_state_key *nk = 5441 (*state)->key[pd->didx]; 5442 5443 if (PF_ANEQ(pd2.src, 5444 &nk->addr[pd2.sidx], pd2.af) || 5445 nk->port[pd2.sidx] != iih.icmp6_id) 5446 pf_change_icmp(pd2.src, &iih.icmp6_id, 5447 daddr, &nk->addr[pd2.sidx], 5448 nk->port[pd2.sidx], NULL, 5449 pd2.ip_sum, icmpsum, 5450 pd->ip_sum, 0, AF_INET6); 5451 5452 if (PF_ANEQ(pd2.dst, 5453 &nk->addr[pd2.didx], pd2.af) || 5454 nk->port[pd2.didx] != iih.icmp6_id) 5455 pf_change_icmp(pd2.dst, &iih.icmp6_id, 5456 NULL, /* XXX Inbound NAT? */ 5457 &nk->addr[pd2.didx], 5458 nk->port[pd2.didx], NULL, 5459 pd2.ip_sum, icmpsum, 5460 pd->ip_sum, 0, AF_INET6); 5461 5462#ifdef __FreeBSD__ 5463 m_copyback(m, off, sizeof(struct icmp6_hdr), 5464 (caddr_t)pd->hdr.icmp6); 5465 m_copyback(m, ipoff2, sizeof(h2_6), (caddr_t)&h2_6); 5466 m_copyback(m, off2, sizeof(struct icmp6_hdr), 5467 (caddr_t)&iih); 5468#else 5469 m_copyback(m, off, sizeof(struct icmp6_hdr), 5470 pd->hdr.icmp6); 5471 m_copyback(m, ipoff2, sizeof(h2_6), &h2_6); 5472 m_copyback(m, off2, sizeof(struct icmp6_hdr), 5473 &iih); 5474#endif 5475 } 5476 return (PF_PASS); 5477 break; 5478 } 5479#endif /* INET6 */ 5480 default: { 5481 key.af = pd2.af; 5482 key.proto = pd2.proto; 5483 PF_ACPY(&key.addr[pd2.sidx], pd2.src, key.af); 5484 PF_ACPY(&key.addr[pd2.didx], pd2.dst, key.af); 5485 key.port[0] = key.port[1] = 0; 5486 5487#ifdef __FreeBSD__ 5488 STATE_LOOKUP(kif, &key, direction, *state, m, pd->pf_mtag); 5489#else 5490 STATE_LOOKUP(kif, &key, direction, *state, m); 5491#endif 5492 5493 /* translate source/destination address, if necessary */ 5494 if ((*state)->key[PF_SK_WIRE] != 5495 (*state)->key[PF_SK_STACK]) { 5496 struct pf_state_key *nk = 5497 (*state)->key[pd->didx]; 5498 5499 if (PF_ANEQ(pd2.src, 5500 &nk->addr[pd2.sidx], pd2.af)) 5501 pf_change_icmp(pd2.src, NULL, daddr, 5502 &nk->addr[pd2.sidx], 0, NULL, 5503 pd2.ip_sum, icmpsum, 5504 pd->ip_sum, 0, pd2.af); 5505 5506 if (PF_ANEQ(pd2.dst, 5507 &nk->addr[pd2.didx], pd2.af)) 5508 pf_change_icmp(pd2.src, NULL, 5509 NULL, /* XXX Inbound NAT? */ 5510 &nk->addr[pd2.didx], 0, NULL, 5511 pd2.ip_sum, icmpsum, 5512 pd->ip_sum, 0, pd2.af); 5513 5514 switch (pd2.af) { 5515#ifdef INET 5516 case AF_INET: 5517#ifdef __FreeBSD__ 5518 m_copyback(m, off, ICMP_MINLEN, 5519 (caddr_t)pd->hdr.icmp); 5520 m_copyback(m, ipoff2, sizeof(h2), (caddr_t)&h2); 5521#else 5522 m_copyback(m, off, ICMP_MINLEN, 5523 pd->hdr.icmp); 5524 m_copyback(m, ipoff2, sizeof(h2), &h2); 5525#endif 5526 break; 5527#endif /* INET */ 5528#ifdef INET6 5529 case AF_INET6: 5530 m_copyback(m, off, 5531 sizeof(struct icmp6_hdr), 5532#ifdef __FreeBSD__ 5533 (caddr_t) 5534#endif 5535 pd->hdr.icmp6); 5536 m_copyback(m, ipoff2, sizeof(h2_6), 5537#ifdef __FreeBSD__ 5538 (caddr_t) 5539#endif 5540 &h2_6); 5541 break; 5542#endif /* INET6 */ 5543 } 5544 } 5545 return (PF_PASS); 5546 break; 5547 } 5548 } 5549 } 5550} 5551 5552int 5553pf_test_state_other(struct pf_state **state, int direction, struct pfi_kif *kif, 5554 struct mbuf *m, struct pf_pdesc *pd) 5555{ 5556 struct pf_state_peer *src, *dst; 5557 struct pf_state_key_cmp key; 5558 5559 key.af = pd->af; 5560 key.proto = pd->proto; 5561 if (direction == PF_IN) { 5562 PF_ACPY(&key.addr[0], pd->src, key.af); 5563 PF_ACPY(&key.addr[1], pd->dst, key.af); 5564 key.port[0] = key.port[1] = 0; 5565 } else { 5566 PF_ACPY(&key.addr[1], pd->src, key.af); 5567 PF_ACPY(&key.addr[0], pd->dst, key.af); 5568 key.port[1] = key.port[0] = 0; 5569 } 5570 5571#ifdef __FreeBSD__ 5572 STATE_LOOKUP(kif, &key, direction, *state, m, pd->pf_mtag); 5573#else 5574 STATE_LOOKUP(kif, &key, direction, *state, m); 5575#endif 5576 5577 if (direction == (*state)->direction) { 5578 src = &(*state)->src; 5579 dst = &(*state)->dst; 5580 } else { 5581 src = &(*state)->dst; 5582 dst = &(*state)->src; 5583 } 5584 5585 /* update states */ 5586 if (src->state < PFOTHERS_SINGLE) 5587 src->state = PFOTHERS_SINGLE; 5588 if (dst->state == PFOTHERS_SINGLE) 5589 dst->state = PFOTHERS_MULTIPLE; 5590 5591 /* update expire time */ 5592 (*state)->expire = time_second; 5593 if (src->state == PFOTHERS_MULTIPLE && dst->state == PFOTHERS_MULTIPLE) 5594 (*state)->timeout = PFTM_OTHER_MULTIPLE; 5595 else 5596 (*state)->timeout = PFTM_OTHER_SINGLE; 5597 5598 /* translate source/destination address, if necessary */ 5599 if ((*state)->key[PF_SK_WIRE] != (*state)->key[PF_SK_STACK]) { 5600 struct pf_state_key *nk = (*state)->key[pd->didx]; 5601 5602#ifdef __FreeBSD__ 5603 KASSERT(nk, ("%s: nk is null", __FUNCTION__)); 5604 KASSERT(pd, ("%s: pd is null", __FUNCTION__)); 5605 KASSERT(pd->src, ("%s: pd->src is null", __FUNCTION__)); 5606 KASSERT(pd->dst, ("%s: pd->dst is null", __FUNCTION__)); 5607#else 5608 KASSERT(nk); 5609 KASSERT(pd); 5610 KASSERT(pd->src); 5611 KASSERT(pd->dst); 5612#endif 5613 switch (pd->af) { 5614#ifdef INET 5615 case AF_INET: 5616 if (PF_ANEQ(pd->src, &nk->addr[pd->sidx], AF_INET)) 5617 pf_change_a(&pd->src->v4.s_addr, 5618 pd->ip_sum, 5619 nk->addr[pd->sidx].v4.s_addr, 5620 0); 5621 5622 5623 if (PF_ANEQ(pd->dst, &nk->addr[pd->didx], AF_INET)) 5624 pf_change_a(&pd->dst->v4.s_addr, 5625 pd->ip_sum, 5626 nk->addr[pd->didx].v4.s_addr, 5627 0); 5628 5629 break; 5630#endif /* INET */ 5631#ifdef INET6 5632 case AF_INET6: 5633 if (PF_ANEQ(pd->src, &nk->addr[pd->sidx], AF_INET)) 5634 PF_ACPY(pd->src, &nk->addr[pd->sidx], pd->af); 5635 5636 if (PF_ANEQ(pd->dst, &nk->addr[pd->didx], AF_INET)) 5637 PF_ACPY(pd->dst, &nk->addr[pd->didx], pd->af); 5638#endif /* INET6 */ 5639 } 5640 } 5641 return (PF_PASS); 5642} 5643 5644/* 5645 * ipoff and off are measured from the start of the mbuf chain. 5646 * h must be at "ipoff" on the mbuf chain. 5647 */ 5648void * 5649pf_pull_hdr(struct mbuf *m, int off, void *p, int len, 5650 u_short *actionp, u_short *reasonp, sa_family_t af) 5651{ 5652 switch (af) { 5653#ifdef INET 5654 case AF_INET: { 5655 struct ip *h = mtod(m, struct ip *); 5656 u_int16_t fragoff = (ntohs(h->ip_off) & IP_OFFMASK) << 3; 5657 5658 if (fragoff) { 5659 if (fragoff >= len) 5660 ACTION_SET(actionp, PF_PASS); 5661 else { 5662 ACTION_SET(actionp, PF_DROP); 5663 REASON_SET(reasonp, PFRES_FRAG); 5664 } 5665 return (NULL); 5666 } 5667 if (m->m_pkthdr.len < off + len || 5668 ntohs(h->ip_len) < off + len) { 5669 ACTION_SET(actionp, PF_DROP); 5670 REASON_SET(reasonp, PFRES_SHORT); 5671 return (NULL); 5672 } 5673 break; 5674 } 5675#endif /* INET */ 5676#ifdef INET6 5677 case AF_INET6: { 5678 struct ip6_hdr *h = mtod(m, struct ip6_hdr *); 5679 5680 if (m->m_pkthdr.len < off + len || 5681 (ntohs(h->ip6_plen) + sizeof(struct ip6_hdr)) < 5682 (unsigned)(off + len)) { 5683 ACTION_SET(actionp, PF_DROP); 5684 REASON_SET(reasonp, PFRES_SHORT); 5685 return (NULL); 5686 } 5687 break; 5688 } 5689#endif /* INET6 */ 5690 } 5691 m_copydata(m, off, len, p); 5692 return (p); 5693} 5694 5695int 5696pf_routable(struct pf_addr *addr, sa_family_t af, struct pfi_kif *kif) 5697{ 5698#ifdef __FreeBSD__ 5699#ifdef RADIX_MPATH 5700 struct radix_node_head *rnh; 5701#endif 5702#endif 5703 struct sockaddr_in *dst; 5704 int ret = 1; 5705 int check_mpath; 5706#ifndef __FreeBSD__ 5707 extern int ipmultipath; 5708#endif 5709#ifdef INET6 5710#ifndef __FreeBSD__ 5711 extern int ip6_multipath; 5712#endif 5713 struct sockaddr_in6 *dst6; 5714 struct route_in6 ro; 5715#else 5716 struct route ro; 5717#endif 5718 struct radix_node *rn; 5719 struct rtentry *rt; 5720 struct ifnet *ifp; 5721 5722 check_mpath = 0; 5723#ifdef __FreeBSD__ 5724#ifdef RADIX_MPATH 5725 /* XXX: stick to table 0 for now */ 5726 rnh = rt_tables_get_rnh(0, af); 5727 if (rnh != NULL && rn_mpath_capable(rnh)) 5728 check_mpath = 1; 5729#endif 5730#endif 5731 bzero(&ro, sizeof(ro)); 5732 switch (af) { 5733 case AF_INET: 5734 dst = satosin(&ro.ro_dst); 5735 dst->sin_family = AF_INET; 5736 dst->sin_len = sizeof(*dst); 5737 dst->sin_addr = addr->v4; 5738#ifndef __FreeBSD__ 5739 if (ipmultipath) 5740 check_mpath = 1; 5741#endif 5742 break; 5743#ifdef INET6 5744 case AF_INET6: 5745 /* 5746 * Skip check for addresses with embedded interface scope, 5747 * as they would always match anyway. 5748 */ 5749 if (IN6_IS_SCOPE_EMBED(&addr->v6)) 5750 goto out; 5751 dst6 = (struct sockaddr_in6 *)&ro.ro_dst; 5752 dst6->sin6_family = AF_INET6; 5753 dst6->sin6_len = sizeof(*dst6); 5754 dst6->sin6_addr = addr->v6; 5755#ifndef __FreeBSD__ 5756 if (ip6_multipath) 5757 check_mpath = 1; 5758#endif 5759 break; 5760#endif /* INET6 */ 5761 default: 5762 return (0); 5763 } 5764 5765 /* Skip checks for ipsec interfaces */ 5766 if (kif != NULL && kif->pfik_ifp->if_type == IFT_ENC) 5767 goto out; 5768 5769#ifdef __FreeBSD__ 5770/* XXX MRT not always INET */ /* stick with table 0 though */ 5771#ifdef INET 5772 if (af == AF_INET) 5773 in_rtalloc_ign((struct route *)&ro, 0, 0); 5774 else 5775#endif 5776 rtalloc_ign((struct route *)&ro, 0); 5777#else /* ! __FreeBSD__ */ 5778 rtalloc_noclone((struct route *)&ro, NO_CLONING); 5779#endif 5780 5781 if (ro.ro_rt != NULL) { 5782 /* No interface given, this is a no-route check */ 5783 if (kif == NULL) 5784 goto out; 5785 5786 if (kif->pfik_ifp == NULL) { 5787 ret = 0; 5788 goto out; 5789 } 5790 5791 /* Perform uRPF check if passed input interface */ 5792 ret = 0; 5793 rn = (struct radix_node *)ro.ro_rt; 5794 do { 5795 rt = (struct rtentry *)rn; 5796#ifndef __FreeBSD__ /* CARPDEV */ 5797 if (rt->rt_ifp->if_type == IFT_CARP) 5798 ifp = rt->rt_ifp->if_carpdev; 5799 else 5800#endif 5801 ifp = rt->rt_ifp; 5802 5803 if (kif->pfik_ifp == ifp) 5804 ret = 1; 5805#ifdef __FreeBSD__ 5806#ifdef RADIX_MPATH 5807 rn = rn_mpath_next(rn); 5808#endif 5809#else 5810 rn = rn_mpath_next(rn, 0); 5811#endif 5812 } while (check_mpath == 1 && rn != NULL && ret == 0); 5813 } else 5814 ret = 0; 5815out: 5816 if (ro.ro_rt != NULL) 5817 RTFREE(ro.ro_rt); 5818 return (ret); 5819} 5820 5821int 5822pf_rtlabel_match(struct pf_addr *addr, sa_family_t af, struct pf_addr_wrap *aw) 5823{ 5824 struct sockaddr_in *dst; 5825#ifdef INET6 5826 struct sockaddr_in6 *dst6; 5827 struct route_in6 ro; 5828#else 5829 struct route ro; 5830#endif 5831 int ret = 0; 5832 5833 bzero(&ro, sizeof(ro)); 5834 switch (af) { 5835 case AF_INET: 5836 dst = satosin(&ro.ro_dst); 5837 dst->sin_family = AF_INET; 5838 dst->sin_len = sizeof(*dst); 5839 dst->sin_addr = addr->v4; 5840 break; 5841#ifdef INET6 5842 case AF_INET6: 5843 dst6 = (struct sockaddr_in6 *)&ro.ro_dst; 5844 dst6->sin6_family = AF_INET6; 5845 dst6->sin6_len = sizeof(*dst6); 5846 dst6->sin6_addr = addr->v6; 5847 break; 5848#endif /* INET6 */ 5849 default: 5850 return (0); 5851 } 5852 5853#ifdef __FreeBSD__ 5854# ifdef RTF_PRCLONING 5855 rtalloc_ign((struct route *)&ro, (RTF_CLONING|RTF_PRCLONING)); 5856# else /* !RTF_PRCLONING */ 5857#ifdef INET 5858 if (af == AF_INET) 5859 in_rtalloc_ign((struct route *)&ro, 0, 0); 5860 else 5861#endif 5862 rtalloc_ign((struct route *)&ro, 0); 5863# endif 5864#else /* ! __FreeBSD__ */ 5865 rtalloc_noclone((struct route *)&ro, NO_CLONING); 5866#endif 5867 5868 if (ro.ro_rt != NULL) { 5869#ifdef __FreeBSD__ 5870 /* XXX_IMPORT: later */ 5871#else 5872 if (ro.ro_rt->rt_labelid == aw->v.rtlabel) 5873 ret = 1; 5874#endif 5875 RTFREE(ro.ro_rt); 5876 } 5877 5878 return (ret); 5879} 5880 5881#ifdef INET 5882void 5883pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, 5884 struct pf_state *s, struct pf_pdesc *pd) 5885{ 5886 struct mbuf *m0, *m1; 5887 struct route iproute; 5888 struct route *ro = NULL; 5889 struct sockaddr_in *dst; 5890 struct ip *ip; 5891 struct ifnet *ifp = NULL; 5892 struct pf_addr naddr; 5893 struct pf_src_node *sn = NULL; 5894 int error = 0; 5895#ifdef __FreeBSD__ 5896 int sw_csum; 5897#endif 5898#ifdef IPSEC 5899 struct m_tag *mtag; 5900#endif /* IPSEC */ 5901 5902 if (m == NULL || *m == NULL || r == NULL || 5903 (dir != PF_IN && dir != PF_OUT) || oifp == NULL) 5904 panic("pf_route: invalid parameters"); 5905 5906#ifdef __FreeBSD__ 5907 if (pd->pf_mtag->routed++ > 3) { 5908#else 5909 if ((*m)->m_pkthdr.pf.routed++ > 3) { 5910#endif 5911 m0 = *m; 5912 *m = NULL; 5913 goto bad; 5914 } 5915 5916 if (r->rt == PF_DUPTO) { 5917#ifdef __FreeBSD__ 5918 if ((m0 = m_dup(*m, M_DONTWAIT)) == NULL) 5919#else 5920 if ((m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT)) == NULL) 5921#endif 5922 return; 5923 } else { 5924 if ((r->rt == PF_REPLYTO) == (r->direction == dir)) 5925 return; 5926 m0 = *m; 5927 } 5928 5929 if (m0->m_len < sizeof(struct ip)) { 5930 DPFPRINTF(PF_DEBUG_URGENT, 5931 ("pf_route: m0->m_len < sizeof(struct ip)\n")); 5932 goto bad; 5933 } 5934 5935 ip = mtod(m0, struct ip *); 5936 5937 ro = &iproute; 5938 bzero((caddr_t)ro, sizeof(*ro)); 5939 dst = satosin(&ro->ro_dst); 5940 dst->sin_family = AF_INET; 5941 dst->sin_len = sizeof(*dst); 5942 dst->sin_addr = ip->ip_dst; 5943 5944 if (r->rt == PF_FASTROUTE) { 5945#ifdef __FreeBSD__ 5946 in_rtalloc(ro, 0); 5947#else 5948 rtalloc(ro); 5949#endif 5950 if (ro->ro_rt == 0) { 5951#ifdef __FreeBSD__ 5952 KMOD_IPSTAT_INC(ips_noroute); 5953#else 5954 ipstat.ips_noroute++; 5955#endif 5956 goto bad; 5957 } 5958 5959 ifp = ro->ro_rt->rt_ifp; 5960 ro->ro_rt->rt_use++; 5961 5962 if (ro->ro_rt->rt_flags & RTF_GATEWAY) 5963 dst = satosin(ro->ro_rt->rt_gateway); 5964 } else { 5965 if (TAILQ_EMPTY(&r->rpool.list)) { 5966 DPFPRINTF(PF_DEBUG_URGENT, 5967 ("pf_route: TAILQ_EMPTY(&r->rpool.list)\n")); 5968 goto bad; 5969 } 5970 if (s == NULL) { 5971 pf_map_addr(AF_INET, r, (struct pf_addr *)&ip->ip_src, 5972 &naddr, NULL, &sn); 5973 if (!PF_AZERO(&naddr, AF_INET)) 5974 dst->sin_addr.s_addr = naddr.v4.s_addr; 5975 ifp = r->rpool.cur->kif ? 5976 r->rpool.cur->kif->pfik_ifp : NULL; 5977 } else { 5978 if (!PF_AZERO(&s->rt_addr, AF_INET)) 5979 dst->sin_addr.s_addr = 5980 s->rt_addr.v4.s_addr; 5981 ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL; 5982 } 5983 } 5984 if (ifp == NULL) 5985 goto bad; 5986 5987 if (oifp != ifp) { 5988#ifdef __FreeBSD__ 5989 PF_UNLOCK(); 5990 if (pf_test(PF_OUT, ifp, &m0, NULL, NULL) != PF_PASS) { 5991 PF_LOCK(); 5992 goto bad; 5993 } else if (m0 == NULL) { 5994 PF_LOCK(); 5995 goto done; 5996 } 5997 PF_LOCK(); 5998#else 5999 if (pf_test(PF_OUT, ifp, &m0, NULL) != PF_PASS) 6000 goto bad; 6001 else if (m0 == NULL) 6002 goto done; 6003#endif 6004 if (m0->m_len < sizeof(struct ip)) { 6005 DPFPRINTF(PF_DEBUG_URGENT, 6006 ("pf_route: m0->m_len < sizeof(struct ip)\n")); 6007 goto bad; 6008 } 6009 ip = mtod(m0, struct ip *); 6010 } 6011 6012#ifdef __FreeBSD__ 6013 /* Copied from FreeBSD 5.1-CURRENT ip_output. */ 6014 m0->m_pkthdr.csum_flags |= CSUM_IP; 6015 sw_csum = m0->m_pkthdr.csum_flags & ~ifp->if_hwassist; 6016 if (sw_csum & CSUM_DELAY_DATA) { 6017 /* 6018 * XXX: in_delayed_cksum assumes HBO for ip->ip_len (at least) 6019 */ 6020 NTOHS(ip->ip_len); 6021 NTOHS(ip->ip_off); /* XXX: needed? */ 6022 in_delayed_cksum(m0); 6023 HTONS(ip->ip_len); 6024 HTONS(ip->ip_off); 6025 sw_csum &= ~CSUM_DELAY_DATA; 6026 } 6027 m0->m_pkthdr.csum_flags &= ifp->if_hwassist; 6028 6029 if (ntohs(ip->ip_len) <= ifp->if_mtu || 6030 (ifp->if_hwassist & CSUM_FRAGMENT && 6031 ((ip->ip_off & htons(IP_DF)) == 0))) { 6032 /* 6033 * ip->ip_len = htons(ip->ip_len); 6034 * ip->ip_off = htons(ip->ip_off); 6035 */ 6036 ip->ip_sum = 0; 6037 if (sw_csum & CSUM_DELAY_IP) { 6038 /* From KAME */ 6039 if (ip->ip_v == IPVERSION && 6040 (ip->ip_hl << 2) == sizeof(*ip)) { 6041 ip->ip_sum = in_cksum_hdr(ip); 6042 } else { 6043 ip->ip_sum = in_cksum(m0, ip->ip_hl << 2); 6044 } 6045 } 6046 PF_UNLOCK(); 6047 error = (*ifp->if_output)(ifp, m0, sintosa(dst), ro); 6048 PF_LOCK(); 6049 goto done; 6050 } 6051#else 6052 /* Copied from ip_output. */ 6053#ifdef IPSEC 6054 /* 6055 * If deferred crypto processing is needed, check that the 6056 * interface supports it. 6057 */ 6058 if ((mtag = m_tag_find(m0, PACKET_TAG_IPSEC_OUT_CRYPTO_NEEDED, NULL)) 6059 != NULL && (ifp->if_capabilities & IFCAP_IPSEC) == 0) { 6060 /* Notify IPsec to do its own crypto. */ 6061 ipsp_skipcrypto_unmark((struct tdb_ident *)(mtag + 1)); 6062 goto bad; 6063 } 6064#endif /* IPSEC */ 6065 6066 /* Catch routing changes wrt. hardware checksumming for TCP or UDP. */ 6067 if (m0->m_pkthdr.csum_flags & M_TCPV4_CSUM_OUT) { 6068 if (!(ifp->if_capabilities & IFCAP_CSUM_TCPv4) || 6069 ifp->if_bridge != NULL) { 6070 in_delayed_cksum(m0); 6071 m0->m_pkthdr.csum_flags &= ~M_TCPV4_CSUM_OUT; /* Clr */ 6072 } 6073 } else if (m0->m_pkthdr.csum_flags & M_UDPV4_CSUM_OUT) { 6074 if (!(ifp->if_capabilities & IFCAP_CSUM_UDPv4) || 6075 ifp->if_bridge != NULL) { 6076 in_delayed_cksum(m0); 6077 m0->m_pkthdr.csum_flags &= ~M_UDPV4_CSUM_OUT; /* Clr */ 6078 } 6079 } 6080 6081 if (ntohs(ip->ip_len) <= ifp->if_mtu) { 6082 ip->ip_sum = 0; 6083 if ((ifp->if_capabilities & IFCAP_CSUM_IPv4) && 6084 ifp->if_bridge == NULL) { 6085 m0->m_pkthdr.csum_flags |= M_IPV4_CSUM_OUT; 6086#ifdef __FreeBSD__ 6087 KMOD_IPSTAT_INC(ips_outhwcsum); 6088#else 6089 ipstat.ips_outhwcsum++; 6090#endif 6091 } else 6092 ip->ip_sum = in_cksum(m0, ip->ip_hl << 2); 6093 /* Update relevant hardware checksum stats for TCP/UDP */ 6094 if (m0->m_pkthdr.csum_flags & M_TCPV4_CSUM_OUT) 6095 KMOD_TCPSTAT_INC(tcps_outhwcsum); 6096 else if (m0->m_pkthdr.csum_flags & M_UDPV4_CSUM_OUT) 6097 KMOD_UDPSTAT_INC(udps_outhwcsum); 6098 error = (*ifp->if_output)(ifp, m0, sintosa(dst), NULL); 6099 goto done; 6100 } 6101#endif 6102 6103 /* 6104 * Too large for interface; fragment if possible. 6105 * Must be able to put at least 8 bytes per fragment. 6106 */ 6107 if (ip->ip_off & htons(IP_DF)) { 6108#ifdef __FreeBSD__ 6109 KMOD_IPSTAT_INC(ips_cantfrag); 6110#else 6111 ipstat.ips_cantfrag++; 6112#endif 6113 if (r->rt != PF_DUPTO) { 6114#ifdef __FreeBSD__ 6115 /* icmp_error() expects host byte ordering */ 6116 NTOHS(ip->ip_len); 6117 NTOHS(ip->ip_off); 6118 PF_UNLOCK(); 6119 icmp_error(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 0, 6120 ifp->if_mtu); 6121 PF_LOCK(); 6122#else 6123 icmp_error(m0, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG, 0, 6124 ifp->if_mtu); 6125#endif 6126 goto done; 6127 } else 6128 goto bad; 6129 } 6130 6131 m1 = m0; 6132#ifdef __FreeBSD__ 6133 /* 6134 * XXX: is cheaper + less error prone than own function 6135 */ 6136 NTOHS(ip->ip_len); 6137 NTOHS(ip->ip_off); 6138 error = ip_fragment(ip, &m0, ifp->if_mtu, ifp->if_hwassist, sw_csum); 6139#else 6140 error = ip_fragment(m0, ifp, ifp->if_mtu); 6141#endif 6142 if (error) { 6143#ifndef __FreeBSD__ /* ip_fragment does not do m_freem() on FreeBSD */ 6144 m0 = NULL; 6145#endif 6146 goto bad; 6147 } 6148 6149 for (m0 = m1; m0; m0 = m1) { 6150 m1 = m0->m_nextpkt; 6151 m0->m_nextpkt = 0; 6152#ifdef __FreeBSD__ 6153 if (error == 0) { 6154 PF_UNLOCK(); 6155 error = (*ifp->if_output)(ifp, m0, sintosa(dst), 6156 NULL); 6157 PF_LOCK(); 6158 } else 6159#else 6160 if (error == 0) 6161 error = (*ifp->if_output)(ifp, m0, sintosa(dst), 6162 NULL); 6163 else 6164#endif 6165 m_freem(m0); 6166 } 6167 6168 if (error == 0) 6169#ifdef __FreeBSD__ 6170 KMOD_IPSTAT_INC(ips_fragmented); 6171#else 6172 ipstat.ips_fragmented++; 6173#endif 6174 6175done: 6176 if (r->rt != PF_DUPTO) 6177 *m = NULL; 6178 if (ro == &iproute && ro->ro_rt) 6179 RTFREE(ro->ro_rt); 6180 return; 6181 6182bad: 6183 m_freem(m0); 6184 goto done; 6185} 6186#endif /* INET */ 6187 6188#ifdef INET6 6189void 6190pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp, 6191 struct pf_state *s, struct pf_pdesc *pd) 6192{ 6193 struct mbuf *m0; 6194 struct route_in6 ip6route; 6195 struct route_in6 *ro; 6196 struct sockaddr_in6 *dst; 6197 struct ip6_hdr *ip6; 6198 struct ifnet *ifp = NULL; 6199 struct pf_addr naddr; 6200 struct pf_src_node *sn = NULL; 6201 6202 if (m == NULL || *m == NULL || r == NULL || 6203 (dir != PF_IN && dir != PF_OUT) || oifp == NULL) 6204 panic("pf_route6: invalid parameters"); 6205 6206#ifdef __FreeBSD__ 6207 if (pd->pf_mtag->routed++ > 3) { 6208#else 6209 if ((*m)->m_pkthdr.pf.routed++ > 3) { 6210#endif 6211 m0 = *m; 6212 *m = NULL; 6213 goto bad; 6214 } 6215 6216 if (r->rt == PF_DUPTO) { 6217#ifdef __FreeBSD__ 6218 if ((m0 = m_dup(*m, M_DONTWAIT)) == NULL) 6219#else 6220 if ((m0 = m_copym2(*m, 0, M_COPYALL, M_NOWAIT)) == NULL) 6221#endif 6222 return; 6223 } else { 6224 if ((r->rt == PF_REPLYTO) == (r->direction == dir)) 6225 return; 6226 m0 = *m; 6227 } 6228 6229 if (m0->m_len < sizeof(struct ip6_hdr)) { 6230 DPFPRINTF(PF_DEBUG_URGENT, 6231 ("pf_route6: m0->m_len < sizeof(struct ip6_hdr)\n")); 6232 goto bad; 6233 } 6234 ip6 = mtod(m0, struct ip6_hdr *); 6235 6236 ro = &ip6route; 6237 bzero((caddr_t)ro, sizeof(*ro)); 6238 dst = (struct sockaddr_in6 *)&ro->ro_dst; 6239 dst->sin6_family = AF_INET6; 6240 dst->sin6_len = sizeof(*dst); 6241 dst->sin6_addr = ip6->ip6_dst; 6242 6243 /* Cheat. XXX why only in the v6 case??? */ 6244 if (r->rt == PF_FASTROUTE) { 6245#ifdef __FreeBSD__ 6246 m0->m_flags |= M_SKIP_FIREWALL; 6247 PF_UNLOCK(); 6248 ip6_output(m0, NULL, NULL, 0, NULL, NULL, NULL); 6249#else 6250 m0->m_pkthdr.pf.flags |= PF_TAG_GENERATED; 6251 ip6_output(m0, NULL, NULL, 0, NULL, NULL, NULL); 6252#endif 6253 return; 6254 } 6255 6256 if (TAILQ_EMPTY(&r->rpool.list)) { 6257 DPFPRINTF(PF_DEBUG_URGENT, 6258 ("pf_route6: TAILQ_EMPTY(&r->rpool.list)\n")); 6259 goto bad; 6260 } 6261 if (s == NULL) { 6262 pf_map_addr(AF_INET6, r, (struct pf_addr *)&ip6->ip6_src, 6263 &naddr, NULL, &sn); 6264 if (!PF_AZERO(&naddr, AF_INET6)) 6265 PF_ACPY((struct pf_addr *)&dst->sin6_addr, 6266 &naddr, AF_INET6); 6267 ifp = r->rpool.cur->kif ? r->rpool.cur->kif->pfik_ifp : NULL; 6268 } else { 6269 if (!PF_AZERO(&s->rt_addr, AF_INET6)) 6270 PF_ACPY((struct pf_addr *)&dst->sin6_addr, 6271 &s->rt_addr, AF_INET6); 6272 ifp = s->rt_kif ? s->rt_kif->pfik_ifp : NULL; 6273 } 6274 if (ifp == NULL) 6275 goto bad; 6276 6277 if (oifp != ifp) { 6278#ifdef __FreeBSD__ 6279 PF_UNLOCK(); 6280 if (pf_test6(PF_OUT, ifp, &m0, NULL, NULL) != PF_PASS) { 6281 PF_LOCK(); 6282 goto bad; 6283 } else if (m0 == NULL) { 6284 PF_LOCK(); 6285 goto done; 6286 } 6287 PF_LOCK(); 6288#else 6289 if (pf_test6(PF_OUT, ifp, &m0, NULL) != PF_PASS) 6290 goto bad; 6291 else if (m0 == NULL) 6292 goto done; 6293#endif 6294 if (m0->m_len < sizeof(struct ip6_hdr)) { 6295 DPFPRINTF(PF_DEBUG_URGENT, 6296 ("pf_route6: m0->m_len < sizeof(struct ip6_hdr)\n")); 6297 goto bad; 6298 } 6299 ip6 = mtod(m0, struct ip6_hdr *); 6300 } 6301 6302 /* 6303 * If the packet is too large for the outgoing interface, 6304 * send back an icmp6 error. 6305 */ 6306 if (IN6_IS_SCOPE_EMBED(&dst->sin6_addr)) 6307 dst->sin6_addr.s6_addr16[1] = htons(ifp->if_index); 6308 if ((u_long)m0->m_pkthdr.len <= ifp->if_mtu) { 6309#ifdef __FreeBSD__ 6310 PF_UNLOCK(); 6311#endif 6312 nd6_output(ifp, ifp, m0, dst, NULL); 6313#ifdef __FreeBSD__ 6314 PF_LOCK(); 6315#endif 6316 } else { 6317 in6_ifstat_inc(ifp, ifs6_in_toobig); 6318#ifdef __FreeBSD__ 6319 if (r->rt != PF_DUPTO) { 6320 PF_UNLOCK(); 6321 icmp6_error(m0, ICMP6_PACKET_TOO_BIG, 0, ifp->if_mtu); 6322 PF_LOCK(); 6323 } else 6324#else 6325 if (r->rt != PF_DUPTO) 6326 icmp6_error(m0, ICMP6_PACKET_TOO_BIG, 0, ifp->if_mtu); 6327 else 6328#endif 6329 goto bad; 6330 } 6331 6332done: 6333 if (r->rt != PF_DUPTO) 6334 *m = NULL; 6335 return; 6336 6337bad: 6338 m_freem(m0); 6339 goto done; 6340} 6341#endif /* INET6 */ 6342 6343#ifdef __FreeBSD__ 6344/* 6345 * FreeBSD supports cksum offloads for the following drivers. 6346 * em(4), fxp(4), ixgb(4), lge(4), ndis(4), nge(4), re(4), 6347 * ti(4), txp(4), xl(4) 6348 * 6349 * CSUM_DATA_VALID | CSUM_PSEUDO_HDR : 6350 * network driver performed cksum including pseudo header, need to verify 6351 * csum_data 6352 * CSUM_DATA_VALID : 6353 * network driver performed cksum, needs to additional pseudo header 6354 * cksum computation with partial csum_data(i.e. lack of H/W support for 6355 * pseudo header, for instance hme(4), sk(4) and possibly gem(4)) 6356 * 6357 * After validating the cksum of packet, set both flag CSUM_DATA_VALID and 6358 * CSUM_PSEUDO_HDR in order to avoid recomputation of the cksum in upper 6359 * TCP/UDP layer. 6360 * Also, set csum_data to 0xffff to force cksum validation. 6361 */ 6362int 6363pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p, sa_family_t af) 6364{ 6365 u_int16_t sum = 0; 6366 int hw_assist = 0; 6367 struct ip *ip; 6368 6369 if (off < sizeof(struct ip) || len < sizeof(struct udphdr)) 6370 return (1); 6371 if (m->m_pkthdr.len < off + len) 6372 return (1); 6373 6374 switch (p) { 6375 case IPPROTO_TCP: 6376 if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) { 6377 if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) { 6378 sum = m->m_pkthdr.csum_data; 6379 } else { 6380 ip = mtod(m, struct ip *); 6381 sum = in_pseudo(ip->ip_src.s_addr, 6382 ip->ip_dst.s_addr, htonl((u_short)len + 6383 m->m_pkthdr.csum_data + IPPROTO_TCP)); 6384 } 6385 sum ^= 0xffff; 6386 ++hw_assist; 6387 } 6388 break; 6389 case IPPROTO_UDP: 6390 if (m->m_pkthdr.csum_flags & CSUM_DATA_VALID) { 6391 if (m->m_pkthdr.csum_flags & CSUM_PSEUDO_HDR) { 6392 sum = m->m_pkthdr.csum_data; 6393 } else { 6394 ip = mtod(m, struct ip *); 6395 sum = in_pseudo(ip->ip_src.s_addr, 6396 ip->ip_dst.s_addr, htonl((u_short)len + 6397 m->m_pkthdr.csum_data + IPPROTO_UDP)); 6398 } 6399 sum ^= 0xffff; 6400 ++hw_assist; 6401 } 6402 break; 6403 case IPPROTO_ICMP: 6404#ifdef INET6 6405 case IPPROTO_ICMPV6: 6406#endif /* INET6 */ 6407 break; 6408 default: 6409 return (1); 6410 } 6411 6412 if (!hw_assist) { 6413 switch (af) { 6414 case AF_INET: 6415 if (p == IPPROTO_ICMP) { 6416 if (m->m_len < off) 6417 return (1); 6418 m->m_data += off; 6419 m->m_len -= off; 6420 sum = in_cksum(m, len); 6421 m->m_data -= off; 6422 m->m_len += off; 6423 } else { 6424 if (m->m_len < sizeof(struct ip)) 6425 return (1); 6426 sum = in4_cksum(m, p, off, len); 6427 } 6428 break; 6429#ifdef INET6 6430 case AF_INET6: 6431 if (m->m_len < sizeof(struct ip6_hdr)) 6432 return (1); 6433 sum = in6_cksum(m, p, off, len); 6434 break; 6435#endif /* INET6 */ 6436 default: 6437 return (1); 6438 } 6439 } 6440 if (sum) { 6441 switch (p) { 6442 case IPPROTO_TCP: 6443 { 6444 KMOD_TCPSTAT_INC(tcps_rcvbadsum); 6445 break; 6446 } 6447 case IPPROTO_UDP: 6448 { 6449 KMOD_UDPSTAT_INC(udps_badsum); 6450 break; 6451 } 6452#ifdef INET 6453 case IPPROTO_ICMP: 6454 { 6455 KMOD_ICMPSTAT_INC(icps_checksum); 6456 break; 6457 } 6458#endif 6459#ifdef INET6 6460 case IPPROTO_ICMPV6: 6461 { 6462 KMOD_ICMP6STAT_INC(icp6s_checksum); 6463 break; 6464 } 6465#endif /* INET6 */ 6466 } 6467 return (1); 6468 } else { 6469 if (p == IPPROTO_TCP || p == IPPROTO_UDP) { 6470 m->m_pkthdr.csum_flags |= 6471 (CSUM_DATA_VALID | CSUM_PSEUDO_HDR); 6472 m->m_pkthdr.csum_data = 0xffff; 6473 } 6474 } 6475 return (0); 6476} 6477#else /* !__FreeBSD__ */ 6478 6479/* 6480 * check protocol (tcp/udp/icmp/icmp6) checksum and set mbuf flag 6481 * off is the offset where the protocol header starts 6482 * len is the total length of protocol header plus payload 6483 * returns 0 when the checksum is valid, otherwise returns 1. 6484 */ 6485int 6486pf_check_proto_cksum(struct mbuf *m, int off, int len, u_int8_t p, 6487 sa_family_t af) 6488{ 6489 u_int16_t flag_ok, flag_bad; 6490 u_int16_t sum; 6491 6492 switch (p) { 6493 case IPPROTO_TCP: 6494 flag_ok = M_TCP_CSUM_IN_OK; 6495 flag_bad = M_TCP_CSUM_IN_BAD; 6496 break; 6497 case IPPROTO_UDP: 6498 flag_ok = M_UDP_CSUM_IN_OK; 6499 flag_bad = M_UDP_CSUM_IN_BAD; 6500 break; 6501 case IPPROTO_ICMP: 6502#ifdef INET6 6503 case IPPROTO_ICMPV6: 6504#endif /* INET6 */ 6505 flag_ok = flag_bad = 0; 6506 break; 6507 default: 6508 return (1); 6509 } 6510 if (m->m_pkthdr.csum_flags & flag_ok) 6511 return (0); 6512 if (m->m_pkthdr.csum_flags & flag_bad) 6513 return (1); 6514 if (off < sizeof(struct ip) || len < sizeof(struct udphdr)) 6515 return (1); 6516 if (m->m_pkthdr.len < off + len) 6517 return (1); 6518 switch (af) { 6519#ifdef INET 6520 case AF_INET: 6521 if (p == IPPROTO_ICMP) { 6522 if (m->m_len < off) 6523 return (1); 6524 m->m_data += off; 6525 m->m_len -= off; 6526 sum = in_cksum(m, len); 6527 m->m_data -= off; 6528 m->m_len += off; 6529 } else { 6530 if (m->m_len < sizeof(struct ip)) 6531 return (1); 6532 sum = in4_cksum(m, p, off, len); 6533 } 6534 break; 6535#endif /* INET */ 6536#ifdef INET6 6537 case AF_INET6: 6538 if (m->m_len < sizeof(struct ip6_hdr)) 6539 return (1); 6540 sum = in6_cksum(m, p, off, len); 6541 break; 6542#endif /* INET6 */ 6543 default: 6544 return (1); 6545 } 6546 if (sum) { 6547 m->m_pkthdr.csum_flags |= flag_bad; 6548 switch (p) { 6549 case IPPROTO_TCP: 6550 KMOD_TCPSTAT_INC(tcps_rcvbadsum); 6551 break; 6552 case IPPROTO_UDP: 6553 KMOD_UDPSTAT_INC(udps_badsum); 6554 break; 6555#ifdef INET 6556 case IPPROTO_ICMP: 6557 KMOD_ICMPSTAT_INC(icps_checksum); 6558 break; 6559#endif 6560#ifdef INET6 6561 case IPPROTO_ICMPV6: 6562 KMOD_ICMP6STAT_INC(icp6s_checksum); 6563 break; 6564#endif /* INET6 */ 6565 } 6566 return (1); 6567 } 6568 m->m_pkthdr.csum_flags |= flag_ok; 6569 return (0); 6570} 6571#endif 6572 6573#ifndef __FreeBSD__ 6574struct pf_divert * 6575pf_find_divert(struct mbuf *m) 6576{ 6577 struct m_tag *mtag; 6578 6579 if ((mtag = m_tag_find(m, PACKET_TAG_PF_DIVERT, NULL)) == NULL) 6580 return (NULL); 6581 6582 return ((struct pf_divert *)(mtag + 1)); 6583} 6584 6585struct pf_divert * 6586pf_get_divert(struct mbuf *m) 6587{ 6588 struct m_tag *mtag; 6589 6590 if ((mtag = m_tag_find(m, PACKET_TAG_PF_DIVERT, NULL)) == NULL) { 6591 mtag = m_tag_get(PACKET_TAG_PF_DIVERT, sizeof(struct pf_divert), 6592 M_NOWAIT); 6593 if (mtag == NULL) 6594 return (NULL); 6595 bzero(mtag + 1, sizeof(struct pf_divert)); 6596 m_tag_prepend(m, mtag); 6597 } 6598 6599 return ((struct pf_divert *)(mtag + 1)); 6600} 6601#endif 6602 6603#ifdef INET 6604int 6605#ifdef __FreeBSD__ 6606pf_test(int dir, struct ifnet *ifp, struct mbuf **m0, 6607 struct ether_header *eh, struct inpcb *inp) 6608#else 6609pf_test(int dir, struct ifnet *ifp, struct mbuf **m0, 6610 struct ether_header *eh) 6611#endif 6612{ 6613 struct pfi_kif *kif; 6614 u_short action, reason = 0, log = 0; 6615 struct mbuf *m = *m0; 6616#ifdef __FreeBSD__ 6617 struct ip *h = NULL; 6618 struct m_tag *ipfwtag; 6619 struct pf_rule *a = NULL, *r = &V_pf_default_rule, *tr, *nr; 6620#else 6621 struct ip *h; 6622 struct pf_rule *a = NULL, *r = &pf_default_rule, *tr, *nr; 6623#endif 6624 struct pf_state *s = NULL; 6625 struct pf_ruleset *ruleset = NULL; 6626 struct pf_pdesc pd; 6627 int off, dirndx, pqid = 0; 6628 6629#ifdef __FreeBSD__ 6630 PF_LOCK(); 6631 if (!V_pf_status.running) 6632 { 6633 PF_UNLOCK(); 6634 return (PF_PASS); 6635 } 6636#else 6637 if (!pf_status.running) 6638 return (PF_PASS); 6639#endif 6640 6641 memset(&pd, 0, sizeof(pd)); 6642#ifdef __FreeBSD__ 6643 if ((pd.pf_mtag = pf_get_mtag(m)) == NULL) { 6644 PF_UNLOCK(); 6645 DPFPRINTF(PF_DEBUG_URGENT, 6646 ("pf_test: pf_get_mtag returned NULL\n")); 6647 return (PF_DROP); 6648 } 6649#endif 6650#ifndef __FreeBSD__ 6651 if (ifp->if_type == IFT_CARP && ifp->if_carpdev) 6652 kif = (struct pfi_kif *)ifp->if_carpdev->if_pf_kif; 6653 else 6654#endif 6655 kif = (struct pfi_kif *)ifp->if_pf_kif; 6656 6657 if (kif == NULL) { 6658#ifdef __FreeBSD__ 6659 PF_UNLOCK(); 6660#endif 6661 DPFPRINTF(PF_DEBUG_URGENT, 6662 ("pf_test: kif == NULL, if_xname %s\n", ifp->if_xname)); 6663 return (PF_DROP); 6664 } 6665 if (kif->pfik_flags & PFI_IFLAG_SKIP) 6666#ifdef __FreeBSD__ 6667 { 6668 PF_UNLOCK(); 6669#endif 6670 return (PF_PASS); 6671#ifdef __FreeBSD__ 6672 } 6673#endif 6674 6675#ifdef __FreeBSD__ 6676 M_ASSERTPKTHDR(m); 6677#else 6678#ifdef DIAGNOSTIC 6679 if ((m->m_flags & M_PKTHDR) == 0) 6680 panic("non-M_PKTHDR is passed to pf_test"); 6681#endif /* DIAGNOSTIC */ 6682#endif 6683 6684 if (m->m_pkthdr.len < (int)sizeof(*h)) { 6685 action = PF_DROP; 6686 REASON_SET(&reason, PFRES_SHORT); 6687 log = 1; 6688 goto done; 6689 } 6690 6691#ifdef __FreeBSD__ 6692 if (m->m_flags & M_SKIP_FIREWALL) { 6693 PF_UNLOCK(); 6694 return (PF_PASS); 6695 } 6696#else 6697 if (m->m_pkthdr.pf.flags & PF_TAG_GENERATED) 6698 return (PF_PASS); 6699#endif 6700 6701#ifdef __FreeBSD__ 6702 if (ip_divert_ptr != NULL && 6703 ((ipfwtag = m_tag_locate(m, MTAG_IPFW_RULE, 0, NULL)) != NULL)) { 6704 struct ipfw_rule_ref *rr = (struct ipfw_rule_ref *)(ipfwtag+1); 6705 if (rr->info & IPFW_IS_DIVERT && rr->rulenum == 0) { 6706 pd.pf_mtag->flags |= PF_PACKET_LOOPED; 6707 m_tag_delete(m, ipfwtag); 6708 } 6709 if (pd.pf_mtag->flags & PF_FASTFWD_OURS_PRESENT) { 6710 m->m_flags |= M_FASTFWD_OURS; 6711 pd.pf_mtag->flags &= ~PF_FASTFWD_OURS_PRESENT; 6712 } 6713 } else 6714#endif 6715 /* We do IP header normalization and packet reassembly here */ 6716 if (pf_normalize_ip(m0, dir, kif, &reason, &pd) != PF_PASS) { 6717 action = PF_DROP; 6718 goto done; 6719 } 6720 m = *m0; /* pf_normalize messes with m0 */ 6721 h = mtod(m, struct ip *); 6722 6723 off = h->ip_hl << 2; 6724 if (off < (int)sizeof(*h)) { 6725 action = PF_DROP; 6726 REASON_SET(&reason, PFRES_SHORT); 6727 log = 1; 6728 goto done; 6729 } 6730 6731 pd.src = (struct pf_addr *)&h->ip_src; 6732 pd.dst = (struct pf_addr *)&h->ip_dst; 6733 pd.sport = pd.dport = NULL; 6734 pd.ip_sum = &h->ip_sum; 6735 pd.proto_sum = NULL; 6736 pd.proto = h->ip_p; 6737 pd.dir = dir; 6738 pd.sidx = (dir == PF_IN) ? 0 : 1; 6739 pd.didx = (dir == PF_IN) ? 1 : 0; 6740 pd.af = AF_INET; 6741 pd.tos = h->ip_tos; 6742 pd.tot_len = ntohs(h->ip_len); 6743 pd.eh = eh; 6744 6745 /* handle fragments that didn't get reassembled by normalization */ 6746 if (h->ip_off & htons(IP_MF | IP_OFFMASK)) { 6747 action = pf_test_fragment(&r, dir, kif, m, h, 6748 &pd, &a, &ruleset); 6749 goto done; 6750 } 6751 6752 switch (h->ip_p) { 6753 6754 case IPPROTO_TCP: { 6755 struct tcphdr th; 6756 6757 pd.hdr.tcp = &th; 6758 if (!pf_pull_hdr(m, off, &th, sizeof(th), 6759 &action, &reason, AF_INET)) { 6760 log = action != PF_PASS; 6761 goto done; 6762 } 6763 pd.p_len = pd.tot_len - off - (th.th_off << 2); 6764 if ((th.th_flags & TH_ACK) && pd.p_len == 0) 6765 pqid = 1; 6766 action = pf_normalize_tcp(dir, kif, m, 0, off, h, &pd); 6767 if (action == PF_DROP) 6768 goto done; 6769 action = pf_test_state_tcp(&s, dir, kif, m, off, h, &pd, 6770 &reason); 6771 if (action == PF_PASS) { 6772#if NPFSYNC > 0 6773#ifdef __FreeBSD__ 6774 if (pfsync_update_state_ptr != NULL) 6775 pfsync_update_state_ptr(s); 6776#else 6777 pfsync_update_state(s); 6778#endif 6779#endif /* NPFSYNC */ 6780 r = s->rule.ptr; 6781 a = s->anchor.ptr; 6782 log = s->log; 6783 } else if (s == NULL) 6784#ifdef __FreeBSD__ 6785 action = pf_test_rule(&r, &s, dir, kif, 6786 m, off, h, &pd, &a, &ruleset, NULL, inp); 6787#else 6788 action = pf_test_rule(&r, &s, dir, kif, 6789 m, off, h, &pd, &a, &ruleset, &ipintrq); 6790#endif 6791 break; 6792 } 6793 6794 case IPPROTO_UDP: { 6795 struct udphdr uh; 6796 6797 pd.hdr.udp = &uh; 6798 if (!pf_pull_hdr(m, off, &uh, sizeof(uh), 6799 &action, &reason, AF_INET)) { 6800 log = action != PF_PASS; 6801 goto done; 6802 } 6803 if (uh.uh_dport == 0 || 6804 ntohs(uh.uh_ulen) > m->m_pkthdr.len - off || 6805 ntohs(uh.uh_ulen) < sizeof(struct udphdr)) { 6806 action = PF_DROP; 6807 REASON_SET(&reason, PFRES_SHORT); 6808 goto done; 6809 } 6810 action = pf_test_state_udp(&s, dir, kif, m, off, h, &pd); 6811 if (action == PF_PASS) { 6812#if NPFSYNC > 0 6813#ifdef __FreeBSD__ 6814 if (pfsync_update_state_ptr != NULL) 6815 pfsync_update_state_ptr(s); 6816#else 6817 pfsync_update_state(s); 6818#endif 6819#endif /* NPFSYNC */ 6820 r = s->rule.ptr; 6821 a = s->anchor.ptr; 6822 log = s->log; 6823 } else if (s == NULL) 6824#ifdef __FreeBSD__ 6825 action = pf_test_rule(&r, &s, dir, kif, 6826 m, off, h, &pd, &a, &ruleset, NULL, inp); 6827#else 6828 action = pf_test_rule(&r, &s, dir, kif, 6829 m, off, h, &pd, &a, &ruleset, &ipintrq); 6830#endif 6831 break; 6832 } 6833 6834 case IPPROTO_ICMP: { 6835 struct icmp ih; 6836 6837 pd.hdr.icmp = &ih; 6838 if (!pf_pull_hdr(m, off, &ih, ICMP_MINLEN, 6839 &action, &reason, AF_INET)) { 6840 log = action != PF_PASS; 6841 goto done; 6842 } 6843 action = pf_test_state_icmp(&s, dir, kif, m, off, h, &pd, 6844 &reason); 6845 if (action == PF_PASS) { 6846#if NPFSYNC > 0 6847#ifdef __FreeBSD__ 6848 if (pfsync_update_state_ptr != NULL) 6849 pfsync_update_state_ptr(s); 6850#else 6851 pfsync_update_state(s); 6852#endif 6853#endif /* NPFSYNC */ 6854 r = s->rule.ptr; 6855 a = s->anchor.ptr; 6856 log = s->log; 6857 } else if (s == NULL) 6858#ifdef __FreeBSD__ 6859 action = pf_test_rule(&r, &s, dir, kif, 6860 m, off, h, &pd, &a, &ruleset, NULL, inp); 6861#else 6862 action = pf_test_rule(&r, &s, dir, kif, 6863 m, off, h, &pd, &a, &ruleset, &ipintrq); 6864#endif 6865 break; 6866 } 6867 6868#ifdef INET6 6869 case IPPROTO_ICMPV6: { 6870 action = PF_DROP; 6871 DPFPRINTF(PF_DEBUG_MISC, 6872 ("pf: dropping IPv4 packet with ICMPv6 payload\n")); 6873 goto done; 6874 } 6875#endif 6876 6877 default: 6878 action = pf_test_state_other(&s, dir, kif, m, &pd); 6879 if (action == PF_PASS) { 6880#if NPFSYNC > 0 6881#ifdef __FreeBSD__ 6882 if (pfsync_update_state_ptr != NULL) 6883 pfsync_update_state_ptr(s); 6884#else 6885 pfsync_update_state(s); 6886#endif 6887#endif /* NPFSYNC */ 6888 r = s->rule.ptr; 6889 a = s->anchor.ptr; 6890 log = s->log; 6891 } else if (s == NULL) 6892#ifdef __FreeBSD__ 6893 action = pf_test_rule(&r, &s, dir, kif, m, off, h, 6894 &pd, &a, &ruleset, NULL, inp); 6895#else 6896 action = pf_test_rule(&r, &s, dir, kif, m, off, h, 6897 &pd, &a, &ruleset, &ipintrq); 6898#endif 6899 break; 6900 } 6901 6902done: 6903 if (action == PF_PASS && h->ip_hl > 5 && 6904 !((s && s->state_flags & PFSTATE_ALLOWOPTS) || r->allow_opts)) { 6905 action = PF_DROP; 6906 REASON_SET(&reason, PFRES_IPOPTIONS); 6907 log = 1; 6908 DPFPRINTF(PF_DEBUG_MISC, 6909 ("pf: dropping packet with ip options\n")); 6910 } 6911 6912 if ((s && s->tag) || r->rtableid) 6913#ifdef __FreeBSD__ 6914 pf_tag_packet(m, s ? s->tag : 0, r->rtableid, pd.pf_mtag); 6915#else 6916 pf_tag_packet(m, s ? s->tag : 0, r->rtableid); 6917#endif 6918 6919 if (dir == PF_IN && s && s->key[PF_SK_STACK]) 6920#ifdef __FreeBSD__ 6921 pd.pf_mtag->statekey = s->key[PF_SK_STACK]; 6922#else 6923 m->m_pkthdr.pf.statekey = s->key[PF_SK_STACK]; 6924#endif 6925 6926#ifdef ALTQ 6927 if (action == PF_PASS && r->qid) { 6928#ifdef __FreeBSD__ 6929 if (pqid || (pd.tos & IPTOS_LOWDELAY)) 6930 pd.pf_mtag->qid = r->pqid; 6931 else 6932 pd.pf_mtag->qid = r->qid; 6933 /* add hints for ecn */ 6934 pd.pf_mtag->hdr = h; 6935 6936#else 6937 if (pqid || (pd.tos & IPTOS_LOWDELAY)) 6938 m->m_pkthdr.pf.qid = r->pqid; 6939 else 6940 m->m_pkthdr.pf.qid = r->qid; 6941 /* add hints for ecn */ 6942 m->m_pkthdr.pf.hdr = h; 6943#endif 6944 } 6945#endif /* ALTQ */ 6946 6947 /* 6948 * connections redirected to loopback should not match sockets 6949 * bound specifically to loopback due to security implications, 6950 * see tcp_input() and in_pcblookup_listen(). 6951 */ 6952 if (dir == PF_IN && action == PF_PASS && (pd.proto == IPPROTO_TCP || 6953 pd.proto == IPPROTO_UDP) && s != NULL && s->nat_rule.ptr != NULL && 6954 (s->nat_rule.ptr->action == PF_RDR || 6955 s->nat_rule.ptr->action == PF_BINAT) && 6956 (ntohl(pd.dst->v4.s_addr) >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET) 6957#ifdef __FreeBSD__ 6958 m->m_flags |= M_SKIP_FIREWALL; 6959#else 6960 m->m_pkthdr.pf.flags |= PF_TAG_TRANSLATE_LOCALHOST; 6961#endif 6962 6963#ifdef __FreeBSD__ 6964 if (action == PF_PASS && r->divert.port && 6965 ip_divert_ptr != NULL && !PACKET_LOOPED()) { 6966 6967 ipfwtag = m_tag_alloc(MTAG_IPFW_RULE, 0, 6968 sizeof(struct ipfw_rule_ref), M_NOWAIT | M_ZERO); 6969 if (ipfwtag != NULL) { 6970 ((struct ipfw_rule_ref *)(ipfwtag+1))->info = 6971 ntohs(r->divert.port); 6972 ((struct ipfw_rule_ref *)(ipfwtag+1))->rulenum = dir; 6973 6974 m_tag_prepend(m, ipfwtag); 6975 6976 PF_UNLOCK(); 6977 6978 if (m->m_flags & M_FASTFWD_OURS) { 6979 pd.pf_mtag->flags |= PF_FASTFWD_OURS_PRESENT; 6980 m->m_flags &= ~M_FASTFWD_OURS; 6981 } 6982 6983 ip_divert_ptr(*m0, 6984 dir == PF_IN ? DIR_IN : DIR_OUT); 6985 *m0 = NULL; 6986 return (action); 6987 } else { 6988 /* XXX: ipfw has the same behaviour! */ 6989 action = PF_DROP; 6990 REASON_SET(&reason, PFRES_MEMORY); 6991 log = 1; 6992 DPFPRINTF(PF_DEBUG_MISC, 6993 ("pf: failed to allocate divert tag\n")); 6994 } 6995 } 6996#else 6997 if (dir == PF_IN && action == PF_PASS && r->divert.port) { 6998 struct pf_divert *divert; 6999 7000 if ((divert = pf_get_divert(m))) { 7001 m->m_pkthdr.pf.flags |= PF_TAG_DIVERTED; 7002 divert->port = r->divert.port; 7003 divert->addr.ipv4 = r->divert.addr.v4; 7004 } 7005 } 7006#endif 7007 7008 if (log) { 7009 struct pf_rule *lr; 7010 7011 if (s != NULL && s->nat_rule.ptr != NULL && 7012 s->nat_rule.ptr->log & PF_LOG_ALL) 7013 lr = s->nat_rule.ptr; 7014 else 7015 lr = r; 7016 PFLOG_PACKET(kif, h, m, AF_INET, dir, reason, lr, a, ruleset, 7017 &pd); 7018 } 7019 7020 kif->pfik_bytes[0][dir == PF_OUT][action != PF_PASS] += pd.tot_len; 7021 kif->pfik_packets[0][dir == PF_OUT][action != PF_PASS]++; 7022 7023 if (action == PF_PASS || r->action == PF_DROP) { 7024 dirndx = (dir == PF_OUT); 7025 r->packets[dirndx]++; 7026 r->bytes[dirndx] += pd.tot_len; 7027 if (a != NULL) { 7028 a->packets[dirndx]++; 7029 a->bytes[dirndx] += pd.tot_len; 7030 } 7031 if (s != NULL) { 7032 if (s->nat_rule.ptr != NULL) { 7033 s->nat_rule.ptr->packets[dirndx]++; 7034 s->nat_rule.ptr->bytes[dirndx] += pd.tot_len; 7035 } 7036 if (s->src_node != NULL) { 7037 s->src_node->packets[dirndx]++; 7038 s->src_node->bytes[dirndx] += pd.tot_len; 7039 } 7040 if (s->nat_src_node != NULL) { 7041 s->nat_src_node->packets[dirndx]++; 7042 s->nat_src_node->bytes[dirndx] += pd.tot_len; 7043 } 7044 dirndx = (dir == s->direction) ? 0 : 1; 7045 s->packets[dirndx]++; 7046 s->bytes[dirndx] += pd.tot_len; 7047 } 7048 tr = r; 7049 nr = (s != NULL) ? s->nat_rule.ptr : pd.nat_rule; 7050#ifdef __FreeBSD__ 7051 if (nr != NULL && r == &V_pf_default_rule) 7052#else 7053 if (nr != NULL && r == &pf_default_rule) 7054#endif 7055 tr = nr; 7056 if (tr->src.addr.type == PF_ADDR_TABLE) 7057 pfr_update_stats(tr->src.addr.p.tbl, 7058 (s == NULL) ? pd.src : 7059 &s->key[(s->direction == PF_IN)]-> 7060 addr[(s->direction == PF_OUT)], 7061 pd.af, pd.tot_len, dir == PF_OUT, 7062 r->action == PF_PASS, tr->src.neg); 7063 if (tr->dst.addr.type == PF_ADDR_TABLE) 7064 pfr_update_stats(tr->dst.addr.p.tbl, 7065 (s == NULL) ? pd.dst : 7066 &s->key[(s->direction == PF_IN)]-> 7067 addr[(s->direction == PF_IN)], 7068 pd.af, pd.tot_len, dir == PF_OUT, 7069 r->action == PF_PASS, tr->dst.neg); 7070 } 7071 7072 switch (action) { 7073 case PF_SYNPROXY_DROP: 7074 m_freem(*m0); 7075 case PF_DEFER: 7076 *m0 = NULL; 7077 action = PF_PASS; 7078 break; 7079 default: 7080 /* pf_route can free the mbuf causing *m0 to become NULL */ 7081 if (r->rt) 7082 pf_route(m0, r, dir, kif->pfik_ifp, s, &pd); 7083 break; 7084 } 7085#ifdef __FreeBSD__ 7086 PF_UNLOCK(); 7087#endif 7088 return (action); 7089} 7090#endif /* INET */ 7091 7092#ifdef INET6 7093int 7094#ifdef __FreeBSD__ 7095pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0, 7096 struct ether_header *eh, struct inpcb *inp) 7097#else 7098pf_test6(int dir, struct ifnet *ifp, struct mbuf **m0, 7099 struct ether_header *eh) 7100#endif 7101{ 7102 struct pfi_kif *kif; 7103 u_short action, reason = 0, log = 0; 7104 struct mbuf *m = *m0, *n = NULL; 7105#ifdef __FreeBSD__ 7106 struct ip6_hdr *h = NULL; 7107 struct pf_rule *a = NULL, *r = &V_pf_default_rule, *tr, *nr; 7108#else 7109 struct ip6_hdr *h; 7110 struct pf_rule *a = NULL, *r = &pf_default_rule, *tr, *nr; 7111#endif 7112 struct pf_state *s = NULL; 7113 struct pf_ruleset *ruleset = NULL; 7114 struct pf_pdesc pd; 7115 int off, terminal = 0, dirndx, rh_cnt = 0; 7116 7117#ifdef __FreeBSD__ 7118 PF_LOCK(); 7119 if (!V_pf_status.running) { 7120 PF_UNLOCK(); 7121 return (PF_PASS); 7122 } 7123#else 7124 if (!pf_status.running) 7125 return (PF_PASS); 7126#endif 7127 7128 memset(&pd, 0, sizeof(pd)); 7129#ifdef __FreeBSD__ 7130 if ((pd.pf_mtag = pf_get_mtag(m)) == NULL) { 7131 PF_UNLOCK(); 7132 DPFPRINTF(PF_DEBUG_URGENT, 7133 ("pf_test: pf_get_mtag returned NULL\n")); 7134 return (PF_DROP); 7135 } 7136#endif 7137#ifndef __FreeBSD__ 7138 if (ifp->if_type == IFT_CARP && ifp->if_carpdev) 7139 kif = (struct pfi_kif *)ifp->if_carpdev->if_pf_kif; 7140 else 7141#endif 7142 kif = (struct pfi_kif *)ifp->if_pf_kif; 7143 7144 if (kif == NULL) { 7145#ifdef __FreeBSD__ 7146 PF_UNLOCK(); 7147#endif 7148 DPFPRINTF(PF_DEBUG_URGENT, 7149 ("pf_test6: kif == NULL, if_xname %s\n", ifp->if_xname)); 7150 return (PF_DROP); 7151 } 7152 if (kif->pfik_flags & PFI_IFLAG_SKIP) 7153#ifdef __FreeBSD__ 7154 { 7155 PF_UNLOCK(); 7156#endif 7157 return (PF_PASS); 7158#ifdef __FreeBSD__ 7159 } 7160#endif 7161 7162#ifdef __FreeBSD__ 7163 M_ASSERTPKTHDR(m); 7164#else 7165#ifdef DIAGNOSTIC 7166 if ((m->m_flags & M_PKTHDR) == 0) 7167 panic("non-M_PKTHDR is passed to pf_test6"); 7168#endif /* DIAGNOSTIC */ 7169#endif 7170 7171 if (m->m_pkthdr.len < (int)sizeof(*h)) { 7172 action = PF_DROP; 7173 REASON_SET(&reason, PFRES_SHORT); 7174 log = 1; 7175 goto done; 7176 } 7177 7178#ifdef __FreeBSD__ 7179 if (pd.pf_mtag->flags & PF_TAG_GENERATED) 7180#else 7181 if (m->m_pkthdr.pf.flags & PF_TAG_GENERATED) 7182#endif 7183 return (PF_PASS); 7184 7185 /* We do IP header normalization and packet reassembly here */ 7186 if (pf_normalize_ip6(m0, dir, kif, &reason, &pd) != PF_PASS) { 7187 action = PF_DROP; 7188 goto done; 7189 } 7190 m = *m0; /* pf_normalize messes with m0 */ 7191 h = mtod(m, struct ip6_hdr *); 7192 7193#if 1 7194 /* 7195 * we do not support jumbogram yet. if we keep going, zero ip6_plen 7196 * will do something bad, so drop the packet for now. 7197 */ 7198 if (htons(h->ip6_plen) == 0) { 7199 action = PF_DROP; 7200 REASON_SET(&reason, PFRES_NORM); /*XXX*/ 7201 goto done; 7202 } 7203#endif 7204 7205 pd.src = (struct pf_addr *)&h->ip6_src; 7206 pd.dst = (struct pf_addr *)&h->ip6_dst; 7207 pd.sport = pd.dport = NULL; 7208 pd.ip_sum = NULL; 7209 pd.proto_sum = NULL; 7210 pd.dir = dir; 7211 pd.sidx = (dir == PF_IN) ? 0 : 1; 7212 pd.didx = (dir == PF_IN) ? 1 : 0; 7213 pd.af = AF_INET6; 7214 pd.tos = 0; 7215 pd.tot_len = ntohs(h->ip6_plen) + sizeof(struct ip6_hdr); 7216 pd.eh = eh; 7217 7218 off = ((caddr_t)h - m->m_data) + sizeof(struct ip6_hdr); 7219 pd.proto = h->ip6_nxt; 7220 do { 7221 switch (pd.proto) { 7222 case IPPROTO_FRAGMENT: 7223 action = pf_test_fragment(&r, dir, kif, m, h, 7224 &pd, &a, &ruleset); 7225 if (action == PF_DROP) 7226 REASON_SET(&reason, PFRES_FRAG); 7227 goto done; 7228 case IPPROTO_ROUTING: { 7229 struct ip6_rthdr rthdr; 7230 7231 if (rh_cnt++) { 7232 DPFPRINTF(PF_DEBUG_MISC, 7233 ("pf: IPv6 more than one rthdr\n")); 7234 action = PF_DROP; 7235 REASON_SET(&reason, PFRES_IPOPTIONS); 7236 log = 1; 7237 goto done; 7238 } 7239 if (!pf_pull_hdr(m, off, &rthdr, sizeof(rthdr), NULL, 7240 &reason, pd.af)) { 7241 DPFPRINTF(PF_DEBUG_MISC, 7242 ("pf: IPv6 short rthdr\n")); 7243 action = PF_DROP; 7244 REASON_SET(&reason, PFRES_SHORT); 7245 log = 1; 7246 goto done; 7247 } 7248 if (rthdr.ip6r_type == IPV6_RTHDR_TYPE_0) { 7249 DPFPRINTF(PF_DEBUG_MISC, 7250 ("pf: IPv6 rthdr0\n")); 7251 action = PF_DROP; 7252 REASON_SET(&reason, PFRES_IPOPTIONS); 7253 log = 1; 7254 goto done; 7255 } 7256 /* FALLTHROUGH */ 7257 } 7258 case IPPROTO_AH: 7259 case IPPROTO_HOPOPTS: 7260 case IPPROTO_DSTOPTS: { 7261 /* get next header and header length */ 7262 struct ip6_ext opt6; 7263 7264 if (!pf_pull_hdr(m, off, &opt6, sizeof(opt6), 7265 NULL, &reason, pd.af)) { 7266 DPFPRINTF(PF_DEBUG_MISC, 7267 ("pf: IPv6 short opt\n")); 7268 action = PF_DROP; 7269 log = 1; 7270 goto done; 7271 } 7272 if (pd.proto == IPPROTO_AH) 7273 off += (opt6.ip6e_len + 2) * 4; 7274 else 7275 off += (opt6.ip6e_len + 1) * 8; 7276 pd.proto = opt6.ip6e_nxt; 7277 /* goto the next header */ 7278 break; 7279 } 7280 default: 7281 terminal++; 7282 break; 7283 } 7284 } while (!terminal); 7285 7286 /* if there's no routing header, use unmodified mbuf for checksumming */ 7287 if (!n) 7288 n = m; 7289 7290 switch (pd.proto) { 7291 7292 case IPPROTO_TCP: { 7293 struct tcphdr th; 7294 7295 pd.hdr.tcp = &th; 7296 if (!pf_pull_hdr(m, off, &th, sizeof(th), 7297 &action, &reason, AF_INET6)) { 7298 log = action != PF_PASS; 7299 goto done; 7300 } 7301 pd.p_len = pd.tot_len - off - (th.th_off << 2); 7302 action = pf_normalize_tcp(dir, kif, m, 0, off, h, &pd); 7303 if (action == PF_DROP) 7304 goto done; 7305 action = pf_test_state_tcp(&s, dir, kif, m, off, h, &pd, 7306 &reason); 7307 if (action == PF_PASS) { 7308#if NPFSYNC > 0 7309#ifdef __FreeBSD__ 7310 if (pfsync_update_state_ptr != NULL) 7311 pfsync_update_state_ptr(s); 7312#else 7313 pfsync_update_state(s); 7314#endif 7315#endif /* NPFSYNC */ 7316 r = s->rule.ptr; 7317 a = s->anchor.ptr; 7318 log = s->log; 7319 } else if (s == NULL) 7320#ifdef __FreeBSD__ 7321 action = pf_test_rule(&r, &s, dir, kif, 7322 m, off, h, &pd, &a, &ruleset, NULL, inp); 7323#else 7324 action = pf_test_rule(&r, &s, dir, kif, 7325 m, off, h, &pd, &a, &ruleset, &ip6intrq); 7326#endif 7327 break; 7328 } 7329 7330 case IPPROTO_UDP: { 7331 struct udphdr uh; 7332 7333 pd.hdr.udp = &uh; 7334 if (!pf_pull_hdr(m, off, &uh, sizeof(uh), 7335 &action, &reason, AF_INET6)) { 7336 log = action != PF_PASS; 7337 goto done; 7338 } 7339 if (uh.uh_dport == 0 || 7340 ntohs(uh.uh_ulen) > m->m_pkthdr.len - off || 7341 ntohs(uh.uh_ulen) < sizeof(struct udphdr)) { 7342 action = PF_DROP; 7343 REASON_SET(&reason, PFRES_SHORT); 7344 goto done; 7345 } 7346 action = pf_test_state_udp(&s, dir, kif, m, off, h, &pd); 7347 if (action == PF_PASS) { 7348#if NPFSYNC > 0 7349#ifdef __FreeBSD__ 7350 if (pfsync_update_state_ptr != NULL) 7351 pfsync_update_state_ptr(s); 7352#else 7353 pfsync_update_state(s); 7354#endif 7355#endif /* NPFSYNC */ 7356 r = s->rule.ptr; 7357 a = s->anchor.ptr; 7358 log = s->log; 7359 } else if (s == NULL) 7360#ifdef __FreeBSD__ 7361 action = pf_test_rule(&r, &s, dir, kif, 7362 m, off, h, &pd, &a, &ruleset, NULL, inp); 7363#else 7364 action = pf_test_rule(&r, &s, dir, kif, 7365 m, off, h, &pd, &a, &ruleset, &ip6intrq); 7366#endif 7367 break; 7368 } 7369 7370 case IPPROTO_ICMP: { 7371 action = PF_DROP; 7372 DPFPRINTF(PF_DEBUG_MISC, 7373 ("pf: dropping IPv6 packet with ICMPv4 payload\n")); 7374 goto done; 7375 } 7376 7377 case IPPROTO_ICMPV6: { 7378 struct icmp6_hdr ih; 7379 7380 pd.hdr.icmp6 = &ih; 7381 if (!pf_pull_hdr(m, off, &ih, sizeof(ih), 7382 &action, &reason, AF_INET6)) { 7383 log = action != PF_PASS; 7384 goto done; 7385 } 7386 action = pf_test_state_icmp(&s, dir, kif, 7387 m, off, h, &pd, &reason); 7388 if (action == PF_PASS) { 7389#if NPFSYNC > 0 7390#ifdef __FreeBSD__ 7391 if (pfsync_update_state_ptr != NULL) 7392 pfsync_update_state_ptr(s); 7393#else 7394 pfsync_update_state(s); 7395#endif 7396#endif /* NPFSYNC */ 7397 r = s->rule.ptr; 7398 a = s->anchor.ptr; 7399 log = s->log; 7400 } else if (s == NULL) 7401#ifdef __FreeBSD__ 7402 action = pf_test_rule(&r, &s, dir, kif, 7403 m, off, h, &pd, &a, &ruleset, NULL, inp); 7404#else 7405 action = pf_test_rule(&r, &s, dir, kif, 7406 m, off, h, &pd, &a, &ruleset, &ip6intrq); 7407#endif 7408 break; 7409 } 7410 7411 default: 7412 action = pf_test_state_other(&s, dir, kif, m, &pd); 7413 if (action == PF_PASS) { 7414#if NPFSYNC > 0 7415#ifdef __FreeBSD__ 7416 if (pfsync_update_state_ptr != NULL) 7417 pfsync_update_state_ptr(s); 7418#else 7419 pfsync_update_state(s); 7420#endif 7421#endif /* NPFSYNC */ 7422 r = s->rule.ptr; 7423 a = s->anchor.ptr; 7424 log = s->log; 7425 } else if (s == NULL) 7426#ifdef __FreeBSD__ 7427 action = pf_test_rule(&r, &s, dir, kif, m, off, h, 7428 &pd, &a, &ruleset, NULL, inp); 7429#else 7430 action = pf_test_rule(&r, &s, dir, kif, m, off, h, 7431 &pd, &a, &ruleset, &ip6intrq); 7432#endif 7433 break; 7434 } 7435 7436done: 7437 if (n != m) { 7438 m_freem(n); 7439 n = NULL; 7440 } 7441 7442 /* handle dangerous IPv6 extension headers. */ 7443 if (action == PF_PASS && rh_cnt && 7444 !((s && s->state_flags & PFSTATE_ALLOWOPTS) || r->allow_opts)) { 7445 action = PF_DROP; 7446 REASON_SET(&reason, PFRES_IPOPTIONS); 7447 log = 1; 7448 DPFPRINTF(PF_DEBUG_MISC, 7449 ("pf: dropping packet with dangerous v6 headers\n")); 7450 } 7451 7452 if ((s && s->tag) || r->rtableid) 7453#ifdef __FreeBSD__ 7454 pf_tag_packet(m, s ? s->tag : 0, r->rtableid, pd.pf_mtag); 7455#else 7456 pf_tag_packet(m, s ? s->tag : 0, r->rtableid); 7457#endif 7458 7459 if (dir == PF_IN && s && s->key[PF_SK_STACK]) 7460#ifdef __FreeBSD__ 7461 pd.pf_mtag->statekey = s->key[PF_SK_STACK]; 7462#else 7463 m->m_pkthdr.pf.statekey = s->key[PF_SK_STACK]; 7464#endif 7465 7466#ifdef ALTQ 7467 if (action == PF_PASS && r->qid) { 7468#ifdef __FreeBSD__ 7469 if (pd.tos & IPTOS_LOWDELAY) 7470 pd.pf_mtag->qid = r->pqid; 7471 else 7472 pd.pf_mtag->qid = r->qid; 7473 /* add hints for ecn */ 7474 pd.pf_mtag->hdr = h; 7475#else 7476 if (pd.tos & IPTOS_LOWDELAY) 7477 m->m_pkthdr.pf.qid = r->pqid; 7478 else 7479 m->m_pkthdr.pf.qid = r->qid; 7480 /* add hints for ecn */ 7481 m->m_pkthdr.pf.hdr = h; 7482#endif 7483 } 7484#endif /* ALTQ */ 7485 7486 if (dir == PF_IN && action == PF_PASS && (pd.proto == IPPROTO_TCP || 7487 pd.proto == IPPROTO_UDP) && s != NULL && s->nat_rule.ptr != NULL && 7488 (s->nat_rule.ptr->action == PF_RDR || 7489 s->nat_rule.ptr->action == PF_BINAT) && 7490 IN6_IS_ADDR_LOOPBACK(&pd.dst->v6)) 7491#ifdef __FreeBSD__ 7492 m->m_flags |= M_SKIP_FIREWALL; 7493#else 7494 m->m_pkthdr.pf.flags |= PF_TAG_TRANSLATE_LOCALHOST; 7495#endif 7496 7497#ifdef __FreeBSD__ 7498 /* XXX: Anybody working on it?! */ 7499 if (r->divert.port) 7500 printf("pf: divert(9) is not supported for IPv6\n"); 7501#else 7502 if (dir == PF_IN && action == PF_PASS && r->divert.port) { 7503 struct pf_divert *divert; 7504 7505 if ((divert = pf_get_divert(m))) { 7506 m->m_pkthdr.pf.flags |= PF_TAG_DIVERTED; 7507 divert->port = r->divert.port; 7508 divert->addr.ipv6 = r->divert.addr.v6; 7509 } 7510 } 7511#endif 7512 7513 if (log) { 7514 struct pf_rule *lr; 7515 7516 if (s != NULL && s->nat_rule.ptr != NULL && 7517 s->nat_rule.ptr->log & PF_LOG_ALL) 7518 lr = s->nat_rule.ptr; 7519 else 7520 lr = r; 7521 PFLOG_PACKET(kif, h, m, AF_INET6, dir, reason, lr, a, ruleset, 7522 &pd); 7523 } 7524 7525 kif->pfik_bytes[1][dir == PF_OUT][action != PF_PASS] += pd.tot_len; 7526 kif->pfik_packets[1][dir == PF_OUT][action != PF_PASS]++; 7527 7528 if (action == PF_PASS || r->action == PF_DROP) { 7529 dirndx = (dir == PF_OUT); 7530 r->packets[dirndx]++; 7531 r->bytes[dirndx] += pd.tot_len; 7532 if (a != NULL) { 7533 a->packets[dirndx]++; 7534 a->bytes[dirndx] += pd.tot_len; 7535 } 7536 if (s != NULL) { 7537 if (s->nat_rule.ptr != NULL) { 7538 s->nat_rule.ptr->packets[dirndx]++; 7539 s->nat_rule.ptr->bytes[dirndx] += pd.tot_len; 7540 } 7541 if (s->src_node != NULL) { 7542 s->src_node->packets[dirndx]++; 7543 s->src_node->bytes[dirndx] += pd.tot_len; 7544 } 7545 if (s->nat_src_node != NULL) { 7546 s->nat_src_node->packets[dirndx]++; 7547 s->nat_src_node->bytes[dirndx] += pd.tot_len; 7548 } 7549 dirndx = (dir == s->direction) ? 0 : 1; 7550 s->packets[dirndx]++; 7551 s->bytes[dirndx] += pd.tot_len; 7552 } 7553 tr = r; 7554 nr = (s != NULL) ? s->nat_rule.ptr : pd.nat_rule; 7555#ifdef __FreeBSD__ 7556 if (nr != NULL && r == &V_pf_default_rule) 7557#else 7558 if (nr != NULL && r == &pf_default_rule) 7559#endif 7560 tr = nr; 7561 if (tr->src.addr.type == PF_ADDR_TABLE) 7562 pfr_update_stats(tr->src.addr.p.tbl, 7563 (s == NULL) ? pd.src : 7564 &s->key[(s->direction == PF_IN)]->addr[0], 7565 pd.af, pd.tot_len, dir == PF_OUT, 7566 r->action == PF_PASS, tr->src.neg); 7567 if (tr->dst.addr.type == PF_ADDR_TABLE) 7568 pfr_update_stats(tr->dst.addr.p.tbl, 7569 (s == NULL) ? pd.dst : 7570 &s->key[(s->direction == PF_IN)]->addr[1], 7571 pd.af, pd.tot_len, dir == PF_OUT, 7572 r->action == PF_PASS, tr->dst.neg); 7573 } 7574 7575 switch (action) { 7576 case PF_SYNPROXY_DROP: 7577 m_freem(*m0); 7578 case PF_DEFER: 7579 *m0 = NULL; 7580 action = PF_PASS; 7581 break; 7582 default: 7583 /* pf_route6 can free the mbuf causing *m0 to become NULL */ 7584 if (r->rt) 7585 pf_route6(m0, r, dir, kif->pfik_ifp, s, &pd); 7586 break; 7587 } 7588 7589#ifdef __FreeBSD__ 7590 PF_UNLOCK(); 7591#endif 7592 return (action); 7593} 7594#endif /* INET6 */ 7595 7596int 7597pf_check_congestion(struct ifqueue *ifq) 7598{ 7599#ifdef __FreeBSD__ 7600 /* XXX_IMPORT: later */ 7601 return (0); 7602#else 7603 if (ifq->ifq_congestion) 7604 return (1); 7605 else 7606 return (0); 7607#endif 7608} 7609 7610/* 7611 * must be called whenever any addressing information such as 7612 * address, port, protocol has changed 7613 */ 7614void 7615pf_pkt_addr_changed(struct mbuf *m) 7616{ 7617#ifdef __FreeBSD__ 7618 struct pf_mtag *pf_tag; 7619 7620 if ((pf_tag = pf_find_mtag(m)) != NULL) 7621 pf_tag->statekey = NULL; 7622#else 7623 m->m_pkthdr.pf.statekey = NULL; 7624#endif 7625}
|