ip_nat.c (60857) | ip_nat.c (63523) |
---|---|
1/* 2 * Copyright (C) 1995-2000 by Darren Reed. 3 * 4 * Redistribution and use in source and binary forms are permitted 5 * provided that this notice is preserved and due credit is given 6 * to the original author and the contributors. 7 * 8 * Added redirect stuff and a LOT of bug fixes. (mcn@EnGarde.com) 9 */ 10#if !defined(lint) 11static const char sccsid[] = "@(#)ip_nat.c 1.11 6/5/96 (C) 1995 Darren Reed"; | 1/* 2 * Copyright (C) 1995-2000 by Darren Reed. 3 * 4 * Redistribution and use in source and binary forms are permitted 5 * provided that this notice is preserved and due credit is given 6 * to the original author and the contributors. 7 * 8 * Added redirect stuff and a LOT of bug fixes. (mcn@EnGarde.com) 9 */ 10#if !defined(lint) 11static const char sccsid[] = "@(#)ip_nat.c 1.11 6/5/96 (C) 1995 Darren Reed"; |
12/*static const char rcsid[] = "@(#)$Id: ip_nat.c,v 2.2.2.12 2000/01/24 12:43:40 darrenr Exp $";*/ 13static const char rcsid[] = "@(#)$FreeBSD: head/sys/contrib/ipfilter/netinet/ip_nat.c 60857 2000-05-24 04:40:17Z darrenr $"; | 12/*static const char rcsid[] = "@(#)$Id: ip_nat.c,v 2.37.2.16 2000/07/18 13:57:40 darrenr Exp $";*/ 13static const char rcsid[] = "@(#)$FreeBSD: head/sys/contrib/ipfilter/netinet/ip_nat.c 63523 2000-07-19 14:02:09Z darrenr $"; |
14#endif 15 16#if defined(__FreeBSD__) && defined(KERNEL) && !defined(_KERNEL) 17#define _KERNEL 18#endif 19 20#include <sys/errno.h> 21#include <sys/types.h> --- 447 unchanged lines hidden (view full) --- 469 if (!n->in_apr) { 470 error = ENOENT; 471 break; 472 } 473 } 474 n->in_next = NULL; 475 *np = n; 476 | 14#endif 15 16#if defined(__FreeBSD__) && defined(KERNEL) && !defined(_KERNEL) 17#define _KERNEL 18#endif 19 20#include <sys/errno.h> 21#include <sys/types.h> --- 447 unchanged lines hidden (view full) --- 469 if (!n->in_apr) { 470 error = ENOENT; 471 break; 472 } 473 } 474 n->in_next = NULL; 475 *np = n; 476 |
477 if (n->in_redir & NAT_REDIRECT) | 477 if (n->in_redir & NAT_REDIRECT) { 478 n->in_flags &= ~IPN_NOTDST; |
478 nat_addrdr(n); | 479 nat_addrdr(n); |
479 if (n->in_redir & (NAT_MAP|NAT_MAPBLK)) | 480 } 481 if (n->in_redir & (NAT_MAP|NAT_MAPBLK)) { 482 n->in_flags &= ~IPN_NOTSRC; |
480 nat_addnat(n); | 483 nat_addnat(n); |
484 } |
|
481 482 n->in_use = 0; 483 if (n->in_redir & NAT_MAPBLK) 484 n->in_space = USABLE_PORTS * ~ntohl(n->in_outmsk); 485 else if (n->in_flags & IPN_AUTOPORTMAP) 486 n->in_space = USABLE_PORTS * ~ntohl(n->in_inmsk); 487 else if (n->in_flags & IPN_IPRANGE) 488 n->in_space = ntohl(n->in_outmsk) - ntohl(n->in_outip); --- 1024 unchanged lines hidden (view full) --- 1513{ 1514 u_32_t sum1, sum2, sumd; 1515 struct in_addr in; 1516 icmphdr_t *icmp; 1517 nat_t *nat; 1518 ip_t *oip; 1519 int flags = 0; 1520 | 485 486 n->in_use = 0; 487 if (n->in_redir & NAT_MAPBLK) 488 n->in_space = USABLE_PORTS * ~ntohl(n->in_outmsk); 489 else if (n->in_flags & IPN_AUTOPORTMAP) 490 n->in_space = USABLE_PORTS * ~ntohl(n->in_inmsk); 491 else if (n->in_flags & IPN_IPRANGE) 492 n->in_space = ntohl(n->in_outmsk) - ntohl(n->in_outip); --- 1024 unchanged lines hidden (view full) --- 1517{ 1518 u_32_t sum1, sum2, sumd; 1519 struct in_addr in; 1520 icmphdr_t *icmp; 1521 nat_t *nat; 1522 ip_t *oip; 1523 int flags = 0; 1524 |
1525 if ((fin->fin_fi.fi_fl & FI_SHORT) || (ip->ip_off & IP_OFFMASK)) 1526 return NULL; |
|
1521 if ((ip->ip_v != 4) || !(nat = nat_icmplookup(ip, fin, dir))) 1522 return NULL; 1523 *nflags = IPN_ICMPERR; 1524 icmp = (icmphdr_t *)fin->fin_dp; 1525 oip = (ip_t *)&icmp->icmp_ip; 1526 if (oip->ip_p == IPPROTO_TCP) 1527 flags = IPN_TCP; 1528 else if (oip->ip_p == IPPROTO_UDP) --- 26 unchanged lines hidden (view full) --- 1555 fix_incksum(&oip->ip_sum, sumd, 0); 1556 1557 sumd += (sumd & 0xffff); 1558 while (sumd > 0xffff) 1559 sumd = (sumd & 0xffff) + (sumd >> 16); 1560 fix_outcksum(&icmp->icmp_cksum, sumd, 0); 1561 } else { 1562 fix_outcksum(&oip->ip_sum, sumd, 0); | 1527 if ((ip->ip_v != 4) || !(nat = nat_icmplookup(ip, fin, dir))) 1528 return NULL; 1529 *nflags = IPN_ICMPERR; 1530 icmp = (icmphdr_t *)fin->fin_dp; 1531 oip = (ip_t *)&icmp->icmp_ip; 1532 if (oip->ip_p == IPPROTO_TCP) 1533 flags = IPN_TCP; 1534 else if (oip->ip_p == IPPROTO_UDP) --- 26 unchanged lines hidden (view full) --- 1561 fix_incksum(&oip->ip_sum, sumd, 0); 1562 1563 sumd += (sumd & 0xffff); 1564 while (sumd > 0xffff) 1565 sumd = (sumd & 0xffff) + (sumd >> 16); 1566 fix_outcksum(&icmp->icmp_cksum, sumd, 0); 1567 } else { 1568 fix_outcksum(&oip->ip_sum, sumd, 0); |
1563 | 1569#if !SOLARIS && !defined(__sgi) |
1564 sumd += (sumd & 0xffff); 1565 while (sumd > 0xffff) 1566 sumd = (sumd & 0xffff) + (sumd >> 16); | 1570 sumd += (sumd & 0xffff); 1571 while (sumd > 0xffff) 1572 sumd = (sumd & 0xffff) + (sumd >> 16); |
1567/* fix_incksum(&icmp->icmp_cksum, sumd, 0); */ | 1573 fix_incksum(&icmp->icmp_cksum, sumd, 0); 1574#endif |
1568 } 1569 | 1575 } 1576 |
1570 | |
1571 if ((flags & IPN_TCPUDP) != 0) { 1572 tcphdr_t *tcp; 1573 1574 /* XXX - what if this is bogus hl and we go off the end ? */ 1575 tcp = (tcphdr_t *)((((char *)oip) + (oip->ip_hl << 2))); 1576 1577 if (nat->nat_dir == NAT_OUTBOUND) { 1578 if (tcp->th_sport != nat->nat_inport) { --- 131 unchanged lines hidden (view full) --- 1710 frtuc_t *ft; 1711 1712 if (ip->ip_v != 4) 1713 return 0; 1714 1715 if (np->in_p && ip->ip_p != np->in_p) 1716 return 0; 1717 if (fin->fin_out) { | 1577 if ((flags & IPN_TCPUDP) != 0) { 1578 tcphdr_t *tcp; 1579 1580 /* XXX - what if this is bogus hl and we go off the end ? */ 1581 tcp = (tcphdr_t *)((((char *)oip) + (oip->ip_hl << 2))); 1582 1583 if (nat->nat_dir == NAT_OUTBOUND) { 1584 if (tcp->th_sport != nat->nat_inport) { --- 131 unchanged lines hidden (view full) --- 1716 frtuc_t *ft; 1717 1718 if (ip->ip_v != 4) 1719 return 0; 1720 1721 if (np->in_p && ip->ip_p != np->in_p) 1722 return 0; 1723 if (fin->fin_out) { |
1718 if (!(np->in_redir && (NAT_MAP|NAT_MAPBLK))) | 1724 if (!(np->in_redir & (NAT_MAP|NAT_MAPBLK))) |
1719 return 0; | 1725 return 0; |
1720 if ((fin->fin_fi.fi_saddr & np->in_inmsk) != np->in_inip) | 1726 if (((fin->fin_fi.fi_saddr & np->in_inmsk) != np->in_inip) 1727 ^ ((np->in_flags & IPN_NOTSRC) != 0)) |
1721 return 0; | 1728 return 0; |
1722 if ((fin->fin_fi.fi_daddr & np->in_srcmsk) != np->in_srcip) | 1729 if (((fin->fin_fi.fi_daddr & np->in_srcmsk) != np->in_srcip) 1730 ^ ((np->in_flags & IPN_NOTDST) != 0)) |
1723 return 0; 1724 } else { | 1731 return 0; 1732 } else { |
1725 if (!(np->in_redir && NAT_REDIRECT)) | 1733 if (!(np->in_redir & NAT_REDIRECT)) |
1726 return 0; | 1734 return 0; |
1735 if (((fin->fin_fi.fi_saddr & np->in_srcmsk) != np->in_srcip) 1736 ^ ((np->in_flags & IPN_NOTSRC) != 0)) 1737 return 0; 1738 if (((fin->fin_fi.fi_daddr & np->in_outmsk) != np->in_outip) 1739 ^ ((np->in_flags & IPN_NOTDST) != 0)) 1740 return 0; |
|
1727 } 1728 1729 ft = &np->in_tuc; | 1741 } 1742 1743 ft = &np->in_tuc; |
1730 if (!(fin->fin_fi.fi_fl & FI_TCPUDP)) { | 1744 if (!(fin->fin_fi.fi_fl & FI_TCPUDP) || 1745 (fin->fin_fi.fi_fl & FI_SHORT) || (ip->ip_off & IP_OFFMASK)) { |
1731 if (ft->ftu_scmp || ft->ftu_dcmp) 1732 return 0; 1733 return 1; 1734 } 1735 1736 return fr_tcpudpchk(ft, fin); 1737} 1738 --- 120 unchanged lines hidden (view full) --- 1859 } 1860 MUTEX_DOWNGRADE(&ipf_nat); 1861 } 1862 1863 if (nat) { 1864 np = nat->nat_ptr; 1865 if (natadd && fin->fin_fi.fi_fl & FI_FRAG) 1866 ipfr_nat_newfrag(ip, fin, 0, nat); | 1746 if (ft->ftu_scmp || ft->ftu_dcmp) 1747 return 0; 1748 return 1; 1749 } 1750 1751 return fr_tcpudpchk(ft, fin); 1752} 1753 --- 120 unchanged lines hidden (view full) --- 1874 } 1875 MUTEX_DOWNGRADE(&ipf_nat); 1876 } 1877 1878 if (nat) { 1879 np = nat->nat_ptr; 1880 if (natadd && fin->fin_fi.fi_fl & FI_FRAG) 1881 ipfr_nat_newfrag(ip, fin, 0, nat); |
1867 ip->ip_src = nat->nat_outip; | |
1868 MUTEX_ENTER(&nat->nat_lock); 1869 nat->nat_age = fr_defnatage; 1870 nat->nat_bytes += ip->ip_len; 1871 nat->nat_pkts++; 1872 MUTEX_EXIT(&nat->nat_lock); 1873 1874 /* 1875 * Fix up checksums, not by recalculating them, but 1876 * simply computing adjustments. 1877 */ | 1882 MUTEX_ENTER(&nat->nat_lock); 1883 nat->nat_age = fr_defnatage; 1884 nat->nat_bytes += ip->ip_len; 1885 nat->nat_pkts++; 1886 MUTEX_EXIT(&nat->nat_lock); 1887 1888 /* 1889 * Fix up checksums, not by recalculating them, but 1890 * simply computing adjustments. 1891 */ |
1892 if (nflags == IPN_ICMPERR) { 1893 u_32_t s1, s2, sumd; 1894 1895 s1 = LONG_SUM(ntohl(ip->ip_src.s_addr)); 1896 s2 = LONG_SUM(ntohl(nat->nat_outip.s_addr)); 1897 CALC_SUMD(s1, s2, sumd); 1898 1899 if (nat->nat_dir == NAT_OUTBOUND) 1900 fix_incksum(&ip->ip_sum, sumd, 0); 1901 else 1902 fix_outcksum(&ip->ip_sum, sumd, 0); 1903 } |
|
1878#if SOLARIS || defined(__sgi) | 1904#if SOLARIS || defined(__sgi) |
1879 if (nat->nat_dir == NAT_OUTBOUND) 1880 fix_outcksum(&ip->ip_sum, nat->nat_ipsumd, 0); 1881 else 1882 fix_incksum(&ip->ip_sum, nat->nat_ipsumd, 0); | 1905 else { 1906 if (nat->nat_dir == NAT_OUTBOUND) 1907 fix_outcksum(&ip->ip_sum, nat->nat_ipsumd, 0); 1908 else 1909 fix_incksum(&ip->ip_sum, nat->nat_ipsumd, 0); 1910 } |
1883#endif | 1911#endif |
1912 ip->ip_src = nat->nat_outip; |
|
1884 1885 if (!(ip->ip_off & IP_OFFMASK) && 1886 !(fin->fin_fi.fi_fl & FI_SHORT)) { 1887 1888 if ((nat->nat_outport != 0) && (nflags & IPN_TCPUDP)) { 1889 tcp->th_sport = nat->nat_outport; 1890 fin->fin_data[0] = ntohs(tcp->th_sport); 1891 } --- 21 unchanged lines hidden (view full) --- 1913 } else if (ip->ip_p == IPPROTO_UDP) { 1914 udphdr_t *udp = (udphdr_t *)tcp; 1915 1916 if (udp->uh_sum) 1917 csump = &udp->uh_sum; 1918 } else if (ip->ip_p == IPPROTO_ICMP) { 1919 nat->nat_age = fr_defnaticmpage; 1920 } | 1913 1914 if (!(ip->ip_off & IP_OFFMASK) && 1915 !(fin->fin_fi.fi_fl & FI_SHORT)) { 1916 1917 if ((nat->nat_outport != 0) && (nflags & IPN_TCPUDP)) { 1918 tcp->th_sport = nat->nat_outport; 1919 fin->fin_data[0] = ntohs(tcp->th_sport); 1920 } --- 21 unchanged lines hidden (view full) --- 1942 } else if (ip->ip_p == IPPROTO_UDP) { 1943 udphdr_t *udp = (udphdr_t *)tcp; 1944 1945 if (udp->uh_sum) 1946 csump = &udp->uh_sum; 1947 } else if (ip->ip_p == IPPROTO_ICMP) { 1948 nat->nat_age = fr_defnaticmpage; 1949 } |
1950 |
|
1921 if (csump) { 1922 if (nat->nat_dir == NAT_OUTBOUND) 1923 fix_outcksum(csump, nat->nat_sumd[1], 1924 ip->ip_len); 1925 else 1926 fix_incksum(csump, nat->nat_sumd[1], 1927 ip->ip_len); 1928 } --- 53 unchanged lines hidden (view full) --- 1982 /* make sure the source address is to be redirected */ 1983 src = ip->ip_src; 1984 1985 READ_ENTER(&ipf_nat); 1986 1987 if ((ip->ip_p == IPPROTO_ICMP) && 1988 (nat = nat_icmp(ip, fin, &nflags, NAT_INBOUND))) 1989 ; | 1951 if (csump) { 1952 if (nat->nat_dir == NAT_OUTBOUND) 1953 fix_outcksum(csump, nat->nat_sumd[1], 1954 ip->ip_len); 1955 else 1956 fix_incksum(csump, nat->nat_sumd[1], 1957 ip->ip_len); 1958 } --- 53 unchanged lines hidden (view full) --- 2012 /* make sure the source address is to be redirected */ 2013 src = ip->ip_src; 2014 2015 READ_ENTER(&ipf_nat); 2016 2017 if ((ip->ip_p == IPPROTO_ICMP) && 2018 (nat = nat_icmp(ip, fin, &nflags, NAT_INBOUND))) 2019 ; |
1990 else if ((ip->ip_off & IP_OFFMASK) && | 2020 else if ((ip->ip_off & (IP_OFFMASK|IP_MF)) && |
1991 (nat = ipfr_nat_knownfrag(ip, fin))) 1992 natadd = 0; 1993 else if ((nat = nat_inlookup(fin->fin_ifp, nflags, (u_int)ip->ip_p, 1994 ip->ip_src, in, (dport << 16) | sport))) { 1995 nflags = nat->nat_flags; 1996 if ((nflags & (FI_W_SPORT|FI_W_DPORT)) != 0) { 1997 if ((nat->nat_oport != sport) && (nflags & FI_W_DPORT)) 1998 nat->nat_oport = sport; --- 21 unchanged lines hidden (view full) --- 2020 (np->in_flags && !(nflags & np->in_flags))) 2021 continue; 2022 if (np->in_flags & IPN_FILTER) { 2023 if (!nat_match(fin, np, ip)) 2024 continue; 2025 } else if ((in.s_addr & np->in_outmsk) != np->in_outip) 2026 continue; 2027 if ((np->in_redir & NAT_REDIRECT) && | 2021 (nat = ipfr_nat_knownfrag(ip, fin))) 2022 natadd = 0; 2023 else if ((nat = nat_inlookup(fin->fin_ifp, nflags, (u_int)ip->ip_p, 2024 ip->ip_src, in, (dport << 16) | sport))) { 2025 nflags = nat->nat_flags; 2026 if ((nflags & (FI_W_SPORT|FI_W_DPORT)) != 0) { 2027 if ((nat->nat_oport != sport) && (nflags & FI_W_DPORT)) 2028 nat->nat_oport = sport; --- 21 unchanged lines hidden (view full) --- 2050 (np->in_flags && !(nflags & np->in_flags))) 2051 continue; 2052 if (np->in_flags & IPN_FILTER) { 2053 if (!nat_match(fin, np, ip)) 2054 continue; 2055 } else if ((in.s_addr & np->in_outmsk) != np->in_outip) 2056 continue; 2057 if ((np->in_redir & NAT_REDIRECT) && |
2028 (!np->in_pmin || | 2058 (!np->in_pmin || (np->in_flags & IPN_FILTER) || |
2029 ((ntohs(np->in_pmax) >= ntohs(dport)) && 2030 (ntohs(dport) >= ntohs(np->in_pmin))))) 2031 if ((nat = nat_new(np, ip, fin, nflags, 2032 NAT_INBOUND))) { 2033 np->in_hits++; 2034#ifdef IPFILTER_LOG 2035 nat_log(nat, (u_int)np->in_redir); 2036#endif --- 266 unchanged lines hidden --- | 2059 ((ntohs(np->in_pmax) >= ntohs(dport)) && 2060 (ntohs(dport) >= ntohs(np->in_pmin))))) 2061 if ((nat = nat_new(np, ip, fin, nflags, 2062 NAT_INBOUND))) { 2063 np->in_hits++; 2064#ifdef IPFILTER_LOG 2065 nat_log(nat, (u_int)np->in_redir); 2066#endif --- 266 unchanged lines hidden --- |