1712 /*
1713 * set s0's as appropriate. Use syn-ack packet as it
1714 * contains both pieces of required information.
1715 */
1716 /*
1717 * Window scale option is only present in SYN/SYN-ACK packet.
1718 * Compare with ~TH_FIN to mask out T/TCP setups.
1719 */
1720 flags = tcp->th_flags & ~(TH_FIN|TH_ECNALL);
1721 if (flags == (TH_SYN|TH_ACK)) {
1722 is->is_s0[source] = ntohl(tcp->th_ack);
1723 is->is_s0[!source] = ntohl(tcp->th_seq) + 1;
1724 if (TCP_OFF(tcp) > (sizeof (tcphdr_t) >> 2)) {
1725 (void) fr_tcpoptions(fin, tcp, fdata);
1726 }
1727 if ((fin->fin_out != 0) && (is->is_pass & FR_NEWISN))
1728 fr_checknewisn(fin, is);
1729 } else if (flags == TH_SYN) {
1730 is->is_s0[source] = ntohl(tcp->th_seq) + 1;
1731 if ((TCP_OFF(tcp) > (sizeof(tcphdr_t) >> 2)))
1732 (void) fr_tcpoptions(fin, tcp, tdata);
1733
1734 if ((fin->fin_out != 0) && (is->is_pass & FR_NEWISN))
1735 fr_checknewisn(fin, is);
1736
1737 }
1738 ret = 1;
1739 } else
1740 fin->fin_flx |= FI_OOW;
1741 MUTEX_EXIT(&is->is_lock);
1742 return ret;
1743 }
1744
1745
1746 /* ------------------------------------------------------------------------ */
1747 /* Function: fr_checknewisn */
1748 /* Returns: Nil */
1749 /* Parameters: fin(I) - pointer to packet information */
1750 /* is(I) - pointer to master state structure */
1751 /* */
1752 /* Check to see if this TCP connection is expecting and needs a new */
1823 * the window is closed (win == 0).
1824 */
1825 if (win == 0)
1826 win = 1;
1827
1828 dsize = fin->fin_dlen - (TCP_OFF(tcp) << 2) +
1829 ((tcpflags & TH_SYN) ? 1 : 0) + ((tcpflags & TH_FIN) ? 1 : 0);
1830
1831 /*
1832 * if window scaling is present, the scaling is only allowed
1833 * for windows not in the first SYN packet. In that packet the
1834 * window is 65535 to specify the largest window possible
1835 * for receivers not implementing the window scale option.
1836 * Currently, we do not assume TTCP here. That means that
1837 * if we see a second packet from a host (after the initial
1838 * SYN), we can assume that the receiver of the SYN did
1839 * already send back the SYN/ACK (and thus that we know if
1840 * the receiver also does window scaling)
1841 */
1842 if (!(tcpflags & TH_SYN) && (fdata->td_winflags & TCP_WSCALE_FIRST)) {
1843 fdata->td_maxwin = win;
1844 }
1845
1846 end = seq + dsize;
1847
1848 if ((fdata->td_end == 0) &&
1849 (!(flags & IS_TCPFSM) ||
1850 ((tcpflags & TH_OPENING) == TH_OPENING))) {
1851 /*
1852 * Must be a (outgoing) SYN-ACK in reply to a SYN.
1853 */
1854 fdata->td_end = end - 1;
1855 fdata->td_maxwin = 1;
1856 fdata->td_maxend = end + win;
1857 }
1858
1859 if (!(tcpflags & TH_ACK)) { /* Pretend an ack was sent */
1860 ack = tdata->td_end;
1861 } else if (((tcpflags & (TH_ACK|TH_RST)) == (TH_ACK|TH_RST)) &&
1862 (ack == 0)) {
1885 int, dsize,
1886 int, ackskew,
1887 int, maxwin,
1888 int, win
1889 );
1890 if (
1891 #if defined(_KERNEL)
1892 /*
1893 * end <-> s + n
1894 * maxend <-> ack + win
1895 * this is upperbound check
1896 */
1897 (SEQ_GE(fdata->td_maxend, end)) &&
1898 /*
1899 * this is lowerbound check
1900 */
1901 (SEQ_GE(seq, fdata->td_end - maxwin)) &&
1902 #endif
1903 /* XXX what about big packets */
1904 #define MAXACKWINDOW 66000
1905 (-ackskew <= (MAXACKWINDOW << fdata->td_winscale)) &&
1906 ( ackskew <= (MAXACKWINDOW << fdata->td_winscale))) {
1907 inseq = 1;
1908 /*
1909 * Microsoft Windows will send the next packet to the right of the
1910 * window if SACK is in use.
1911 */
1912 } else if ((seq == fdata->td_maxend) && (ackskew == 0) &&
1913 (fdata->td_winflags & TCP_SACK_PERMIT) &&
1914 (tdata->td_winflags & TCP_SACK_PERMIT)) {
1915 inseq = 1;
1916 /*
1917 * RST ACK with SEQ equal to 0 is sent by some OSes (i.e. Solaris) as a
1918 * response to initial SYN packet, when there is no application
1919 * listeing to on a port, where the SYN packet has came to.
1920 */
1921 } else if ((seq == 0) && (tcpflags == (TH_RST|TH_ACK)) &&
1922 (ackskew >= -1) && (ackskew <= 1)) {
1923 inseq = 1;
1924 } else if (!(flags & IS_TCPFSM)) {
1925
|
1712 /*
1713 * set s0's as appropriate. Use syn-ack packet as it
1714 * contains both pieces of required information.
1715 */
1716 /*
1717 * Window scale option is only present in SYN/SYN-ACK packet.
1718 * Compare with ~TH_FIN to mask out T/TCP setups.
1719 */
1720 flags = tcp->th_flags & ~(TH_FIN|TH_ECNALL);
1721 if (flags == (TH_SYN|TH_ACK)) {
1722 is->is_s0[source] = ntohl(tcp->th_ack);
1723 is->is_s0[!source] = ntohl(tcp->th_seq) + 1;
1724 if (TCP_OFF(tcp) > (sizeof (tcphdr_t) >> 2)) {
1725 (void) fr_tcpoptions(fin, tcp, fdata);
1726 }
1727 if ((fin->fin_out != 0) && (is->is_pass & FR_NEWISN))
1728 fr_checknewisn(fin, is);
1729 } else if (flags == TH_SYN) {
1730 is->is_s0[source] = ntohl(tcp->th_seq) + 1;
1731 if ((TCP_OFF(tcp) > (sizeof(tcphdr_t) >> 2)))
1732 (void) fr_tcpoptions(fin, tcp, fdata);
1733
1734 if ((fin->fin_out != 0) && (is->is_pass & FR_NEWISN))
1735 fr_checknewisn(fin, is);
1736
1737 }
1738 ret = 1;
1739 } else
1740 fin->fin_flx |= FI_OOW;
1741 MUTEX_EXIT(&is->is_lock);
1742 return ret;
1743 }
1744
1745
1746 /* ------------------------------------------------------------------------ */
1747 /* Function: fr_checknewisn */
1748 /* Returns: Nil */
1749 /* Parameters: fin(I) - pointer to packet information */
1750 /* is(I) - pointer to master state structure */
1751 /* */
1752 /* Check to see if this TCP connection is expecting and needs a new */
1823 * the window is closed (win == 0).
1824 */
1825 if (win == 0)
1826 win = 1;
1827
1828 dsize = fin->fin_dlen - (TCP_OFF(tcp) << 2) +
1829 ((tcpflags & TH_SYN) ? 1 : 0) + ((tcpflags & TH_FIN) ? 1 : 0);
1830
1831 /*
1832 * if window scaling is present, the scaling is only allowed
1833 * for windows not in the first SYN packet. In that packet the
1834 * window is 65535 to specify the largest window possible
1835 * for receivers not implementing the window scale option.
1836 * Currently, we do not assume TTCP here. That means that
1837 * if we see a second packet from a host (after the initial
1838 * SYN), we can assume that the receiver of the SYN did
1839 * already send back the SYN/ACK (and thus that we know if
1840 * the receiver also does window scaling)
1841 */
1842 if (!(tcpflags & TH_SYN) && (fdata->td_winflags & TCP_WSCALE_FIRST)) {
1843 fdata->td_winflags &= ~TCP_WSCALE_FIRST;
1844 fdata->td_maxwin = win;
1845 }
1846
1847 end = seq + dsize;
1848
1849 if ((fdata->td_end == 0) &&
1850 (!(flags & IS_TCPFSM) ||
1851 ((tcpflags & TH_OPENING) == TH_OPENING))) {
1852 /*
1853 * Must be a (outgoing) SYN-ACK in reply to a SYN.
1854 */
1855 fdata->td_end = end - 1;
1856 fdata->td_maxwin = 1;
1857 fdata->td_maxend = end + win;
1858 }
1859
1860 if (!(tcpflags & TH_ACK)) { /* Pretend an ack was sent */
1861 ack = tdata->td_end;
1862 } else if (((tcpflags & (TH_ACK|TH_RST)) == (TH_ACK|TH_RST)) &&
1863 (ack == 0)) {
1886 int, dsize,
1887 int, ackskew,
1888 int, maxwin,
1889 int, win
1890 );
1891 if (
1892 #if defined(_KERNEL)
1893 /*
1894 * end <-> s + n
1895 * maxend <-> ack + win
1896 * this is upperbound check
1897 */
1898 (SEQ_GE(fdata->td_maxend, end)) &&
1899 /*
1900 * this is lowerbound check
1901 */
1902 (SEQ_GE(seq, fdata->td_end - maxwin)) &&
1903 #endif
1904 /* XXX what about big packets */
1905 #define MAXACKWINDOW 66000
1906 (-ackskew <= (MAXACKWINDOW)) &&
1907 ( ackskew <= (MAXACKWINDOW << fdata->td_winscale))) {
1908 inseq = 1;
1909 /*
1910 * Microsoft Windows will send the next packet to the right of the
1911 * window if SACK is in use.
1912 */
1913 } else if ((seq == fdata->td_maxend) && (ackskew == 0) &&
1914 (fdata->td_winflags & TCP_SACK_PERMIT) &&
1915 (tdata->td_winflags & TCP_SACK_PERMIT)) {
1916 inseq = 1;
1917 /*
1918 * RST ACK with SEQ equal to 0 is sent by some OSes (i.e. Solaris) as a
1919 * response to initial SYN packet, when there is no application
1920 * listeing to on a port, where the SYN packet has came to.
1921 */
1922 } else if ((seq == 0) && (tcpflags == (TH_RST|TH_ACK)) &&
1923 (ackskew >= -1) && (ackskew <= 1)) {
1924 inseq = 1;
1925 } else if (!(flags & IS_TCPFSM)) {
1926
|