Deleted Added
full compact
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 ---