* Send SYN|ACK or ACK to the peer. Either in response to a peer's segment, * i.e. m0 != NULL, or upon 3WHS ACK timeout, i.e. m0 == NULL. */
| 1860 | * i.e. m0 != NULL, or upon 3WHS ACK timeout, i.e. m0 == NULL. |
| 1861 | */ |
| 1862 | static int |
| 1863 | syncache_respond(struct syncache *sc, const struct mbuf *m0, int flags) |
| 1864 | { |
| 1865 | struct ip *ip = NULL; |
| 1866 | struct mbuf *m; |
| 1867 | struct tcphdr *th = NULL; |
| 1868 | int optlen, error = 0; /* Make compiler happy */ |
| 1869 | u_int16_t hlen, tlen, mssopt; |
| 1870 | struct tcpopt to; |
| 1871 | #ifdef INET6 |
| 1872 | struct ip6_hdr *ip6 = NULL; |
| 1873 | #endif |
| 1874 | |
| 1875 | NET_EPOCH_ASSERT(); |
| 1876 | |
| 1877 | hlen = |
| 1878 | #ifdef INET6 |
| 1879 | (sc->sc_inc.inc_flags & INC_ISIPV6) ? sizeof(struct ip6_hdr) : |
| 1880 | #endif |
| 1881 | sizeof(struct ip); |
| 1882 | tlen = hlen + sizeof(struct tcphdr); |
| 1883 | |
| 1884 | /* Determine MSS we advertize to other end of connection. */ |
| 1885 | mssopt = max(tcp_mssopt(&sc->sc_inc), V_tcp_minmss); |
| 1886 | |
| 1887 | /* XXX: Assume that the entire packet will fit in a header mbuf. */ |
| 1888 | KASSERT(max_linkhdr + tlen + TCP_MAXOLEN <= MHLEN, |
| 1889 | ("syncache: mbuf too small")); |
| 1890 | |
| 1891 | /* Create the IP+TCP header from scratch. */ |
| 1892 | m = m_gethdr(M_NOWAIT, MT_DATA); |
| 1893 | if (m == NULL) |
| 1894 | return (ENOBUFS); |
| 1895 | #ifdef MAC |
| 1896 | mac_syncache_create_mbuf(sc->sc_label, m); |
| 1897 | #endif |
| 1898 | m->m_data += max_linkhdr; |
| 1899 | m->m_len = tlen; |
| 1900 | m->m_pkthdr.len = tlen; |
| 1901 | m->m_pkthdr.rcvif = NULL; |
| 1902 | |
| 1903 | #ifdef INET6 |
| 1904 | if (sc->sc_inc.inc_flags & INC_ISIPV6) { |
| 1905 | ip6 = mtod(m, struct ip6_hdr *); |
| 1906 | ip6->ip6_vfc = IPV6_VERSION; |
| 1907 | ip6->ip6_nxt = IPPROTO_TCP; |
| 1908 | ip6->ip6_src = sc->sc_inc.inc6_laddr; |
| 1909 | ip6->ip6_dst = sc->sc_inc.inc6_faddr; |
| 1910 | ip6->ip6_plen = htons(tlen - hlen); |
| 1911 | /* ip6_hlim is set after checksum */ |
| 1912 | /* Zero out traffic class and flow label. */ |
| 1913 | ip6->ip6_flow &= ~IPV6_FLOWINFO_MASK; |
| 1914 | ip6->ip6_flow |= sc->sc_flowlabel; |
| 1915 | ip6->ip6_flow |= htonl(sc->sc_ip_tos << 20); |
| 1916 | |
| 1917 | th = (struct tcphdr *)(ip6 + 1); |
| 1918 | } |
| 1919 | #endif |
no test coverage detected