th = (void *)(ti + sizeof(struct ip6_hdr));
th = (void *)((caddr_t)ti + sizeof(struct ip6_hdr));
tcp_respond(tp, template, m, ack, seq, flags)	struct tcpcb *tp;	caddr_t template;	register struct mbuf *m;	tcp_seq ack, seq;	int flags;{	register int tlen;	int win = 0;	struct route *ro = 0;	register struct tcphdr *th;	register struct tcpiphdr *ti = (struct tcpiphdr *)template;#ifdef INET6	int is_ipv6 = 0;   /* true iff IPv6 */#endif /* INET6 */	if (tp) {		win = sbspace(&tp->t_inpcb->inp_socket->so_rcv);#ifdef INET6		/*		 * If this is called with an unconnected		 * socket/tp/pcb (tp->pf is 0), we lose.		 */		is_ipv6 = (tp->pf == PF_INET6);		/*		 * The route/route6 distinction is meaningless		 * unless you're allocating space or passing parameters.		 */#endif /* INET6 */		ro = &tp->t_inpcb->inp_route;	}#ifdef INET6	else		is_ipv6 = (((struct ip *)ti)->ip_v == 6);#endif /* INET6 */	if (m == 0) {		m = m_gethdr(M_DONTWAIT, MT_HEADER);		if (m == NULL)			return;#ifdef TCP_COMPAT_42		tlen = 1;#else		tlen = 0;#endif		m->m_data += max_linkhdr;#ifdef INET6		if (is_ipv6)			bcopy(ti, mtod(m, caddr_t), sizeof(struct tcphdr) +			    sizeof(struct ip6_hdr));		else#endif /* INET6 */			bcopy(ti, mtod(m, caddr_t), sizeof(struct tcphdr) +			    sizeof(struct ip));		ti = mtod(m, struct tcpiphdr *);		flags = TH_ACK;	} else {		m_freem(m->m_next);		m->m_next = 0;		m->m_data = (caddr_t)ti;		tlen = 0;#define xchg(a,b,type) { type t; t=a; a=b; b=t; }#ifdef INET6		if (is_ipv6) {			m->m_len = sizeof(struct tcphdr) + sizeof(struct ip6_hdr);			xchg(((struct ip6_hdr *)ti)->ip6_dst,\			    ((struct ip6_hdr *)ti)->ip6_src,\			    struct in6_addr);			th = (void *)(ti + sizeof(struct ip6_hdr));		} else#endif /* INET6 */		{			m->m_len = sizeof (struct tcpiphdr);			xchg(ti->ti_dst.s_addr, ti->ti_src.s_addr, u_int32_t);			th = (void *)(ti + sizeof(struct ip));		}		xchg(th->th_dport, th->th_sport, u_int16_t);#undef xchg	}#ifdef INET6	if (is_ipv6) {		tlen += sizeof(struct tcphdr) + sizeof(struct ip6_hdr); 		th = (struct tcphdr *)((caddr_t)ti + sizeof(struct ip6_hdr));	} else#endif /* INET6 */	{		ti->ti_len = htons((u_int16_t)(sizeof (struct tcphdr) + tlen));		tlen += sizeof (struct tcpiphdr);		th = (struct tcphdr *)((caddr_t)ti + sizeof(struct ip));	}	m->m_len = tlen;	m->m_pkthdr.len = tlen;	m->m_pkthdr.rcvif = (struct ifnet *) 0;	th->th_seq = htonl(seq);	th->th_ack = htonl(ack);	th->th_x2 = 0;	th->th_off = sizeof (struct tcphdr) >> 2;	th->th_flags = flags;	if (tp)		win >>= tp->rcv_scale;	if (win > TCP_MAXWIN)		win = TCP_MAXWIN;	th->th_win = htons((u_int16_t)win);	th->th_urp = 0;#ifdef INET6	if (is_ipv6) {		((struct ip6_hdr *)ti)->ip6_flow   = htonl(0x60000000);		((struct ip6_hdr *)ti)->ip6_nxt  = IPPROTO_TCP;		((struct ip6_hdr *)ti)->ip6_hlim =			in6_selecthlim(tp ? tp->t_inpcb : NULL, NULL);	/*XXX*/		((struct ip6_hdr *)ti)->ip6_plen = tlen - sizeof(struct ip6_hdr);		th->th_sum = 0;		th->th_sum = in6_cksum(m, IPPROTO_TCP,		   sizeof(struct ip6_hdr), ((struct ip6_hdr *)ti)->ip6_plen);		HTONS(((struct ip6_hdr *)ti)->ip6_plen);		ip6_output(m, tp ? tp->t_inpcb->inp_outputopts6 : NULL,			(struct route_in6 *)ro, 0, NULL, NULL);	} else#endif /* INET6 */	{		bzero(ti->ti_x1, sizeof ti->ti_x1);		ti->ti_len = htons((u_short)tlen - sizeof(struct ip));		/*		 * There's no point deferring to hardware checksum processing		 * here, as we only send a minimal TCP packet whose checksum		 * we need to compute in any case.		 */		th->th_sum = in_cksum(m, tlen);		((struct ip *)ti)->ip_len = tlen;		((struct ip *)ti)->ip_ttl = ip_defttl;		ip_output(m, NULL, ro, ip_mtudisc ? IP_MTUDISC : 0, NULL,			  tp ? tp->t_inpcb : NULL);	}}