+
+/*
+ * Determine a reasonable value for maxseg size.
+ * If the route is known, use one that can be handled
+ * on the given interface without forcing IP to fragment.
+ * If bigger than a page (CLSIZE), round down to nearest pagesize
+ * to utilize pagesize mbufs.
+ * If interface pointer is unavailable, or the destination isn't local,
+ * use a conservative size (512 or the default IP max size),
+ * as we can't discover anything about intervening gateways or networks.
+ *
+ * This is ugly, and doesn't belong at this level, but has to happen somehow.
+ */
+tcp_mss(tp)
+register struct tcpcb *tp;
+{
+ struct route *ro;
+ struct ifnet *ifp;
+ int mss;
+ struct inpcb *inp;
+
+ inp = tp->t_inpcb;
+ ro = &inp->inp_route;
+ if ((ro->ro_rt == (struct rtentry *)0) ||
+ (ifp = ro->ro_rt->rt_ifp) == (struct ifnet *)0) {
+ /* No route yet, so try to acquire one */
+ if (inp->inp_faddr.s_addr != INADDR_ANY) {
+ ro->ro_dst.sa_family = AF_INET;
+ ((struct sockaddr_in *) &ro->ro_dst)->sin_addr =
+ inp->inp_faddr;
+ rtalloc(ro);
+ }
+ if ((ro->ro_rt == 0) || (ifp = ro->ro_rt->rt_ifp) == 0)
+ return (TCP_MSS);
+ }
+
+ mss = ifp->if_mtu - sizeof(struct tcpiphdr);
+#if (CLBYTES & (CLBYTES - 1)) == 0
+ if (mss > CLBYTES)
+ mss &= ~(CLBYTES-1);
+#else
+ if (mss > CLBYTES)
+ mss = mss / CLBYTES * CLBYTES;
+#endif
+ if (in_localaddr(tp->t_inpcb->inp_faddr))
+ return(mss);
+ return (MIN(mss, TCP_MSS));
+}