+ struct tcpiphdr tcpiph_save = *(mtod(m, struct tcpiphdr *));
+ struct ip *ip;
+ struct ip6 *ip6;
+
+ switch (af) {
+ case AF_INET:
+ m->m_data += sizeof(struct tcpiphdr) - sizeof(struct tcphdr)
+ - sizeof(struct ip);
+ m->m_len -= sizeof(struct tcpiphdr) - sizeof(struct tcphdr)
+ - sizeof(struct ip);
+ ip = mtod(m, struct ip *);
+ ip->ip_len = tlen;
+ ip->ip_dst = tcpiph_save.ti_dst;
+ ip->ip_src = tcpiph_save.ti_src;
+ ip->ip_p = tcpiph_save.ti_pr;
+
+ if (flags & TH_RST) {
+ ip->ip_ttl = MAXTTL;
+ } else {
+ ip->ip_ttl = IPDEFTTL;
+ }
+
+ ip_output(NULL, m);
+ break;
+
+ case AF_INET6:
+ m->m_data += sizeof(struct tcpiphdr) - sizeof(struct tcphdr)
+ - sizeof(struct ip6);
+ m->m_len -= sizeof(struct tcpiphdr) - sizeof(struct tcphdr)
+ - sizeof(struct ip6);
+ ip6 = mtod(m, struct ip6 *);
+ ip6->ip_pl = tlen;
+ ip6->ip_dst = tcpiph_save.ti_dst6;
+ ip6->ip_src = tcpiph_save.ti_src6;
+ ip6->ip_nh = tcpiph_save.ti_nh6;
+
+ ip6_output(NULL, m, 0);
+ break;
+
+ default:
+ g_assert_not_reached();
+ }