aboutsummaryrefslogtreecommitdiff
path: root/sys/netinet
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet')
-rw-r--r--sys/netinet/icmp_var.h14
-rw-r--r--sys/netinet/if_ether.c14
-rw-r--r--sys/netinet/if_ether.h14
-rw-r--r--sys/netinet/in.c30
-rw-r--r--sys/netinet/in.h48
-rw-r--r--sys/netinet/in_mtudisc.c377
-rw-r--r--sys/netinet/in_pcb.c54
-rw-r--r--sys/netinet/in_pcb.h40
-rw-r--r--sys/netinet/in_proto.c80
-rw-r--r--sys/netinet/in_systm.h6
-rw-r--r--sys/netinet/in_var.c354
-rw-r--r--sys/netinet/in_var.h81
-rw-r--r--sys/netinet/ip.h6
-rw-r--r--sys/netinet/ip_icmp.c168
-rw-r--r--sys/netinet/ip_icmp.h41
-rw-r--r--sys/netinet/ip_input.c83
-rw-r--r--sys/netinet/ip_output.c9
-rw-r--r--sys/netinet/ip_var.h12
-rw-r--r--sys/netinet/raw_ip.c14
-rw-r--r--sys/netinet/tcp.h6
-rw-r--r--sys/netinet/tcp_debug.c16
-rw-r--r--sys/netinet/tcp_debug.h10
-rw-r--r--sys/netinet/tcp_fsm.h8
-rw-r--r--sys/netinet/tcp_input.c68
-rw-r--r--sys/netinet/tcp_output.c14
-rw-r--r--sys/netinet/tcp_seq.h8
-rw-r--r--sys/netinet/tcp_subr.c76
-rw-r--r--sys/netinet/tcp_timer.c11
-rw-r--r--sys/netinet/tcp_timer.h12
-rw-r--r--sys/netinet/tcp_usrreq.c23
-rw-r--r--sys/netinet/tcp_var.h66
-rw-r--r--sys/netinet/tcpip.h6
-rw-r--r--sys/netinet/udp.h6
-rw-r--r--sys/netinet/udp_usrreq.c37
-rw-r--r--sys/netinet/udp_var.h19
35 files changed, 1563 insertions, 268 deletions
diff --git a/sys/netinet/icmp_var.h b/sys/netinet/icmp_var.h
index 34ab22bf56f2..47454f89b51d 100644
--- a/sys/netinet/icmp_var.h
+++ b/sys/netinet/icmp_var.h
@@ -31,9 +31,12 @@
* SUCH DAMAGE.
*
* from: @(#)icmp_var.h 7.5 (Berkeley) 6/28/90
- * $Id: icmp_var.h,v 1.2 1993/10/16 18:25:52 rgrimes Exp $
+ * $Id: icmp_var.h,v 1.5 1993/12/19 00:52:29 wollman Exp $
*/
+#ifndef _NETINET_ICMP_VAR_H_
+#define _NETINET_ICMP_VAR_H_ 1
+
/*
* Variables related to this implementation
* of the internet control message protocol.
@@ -43,6 +46,8 @@ struct icmpstat {
int icps_error; /* # of calls to icmp_error */
int icps_oldshort; /* no error 'cuz old ip too short */
int icps_oldicmp; /* no error 'cuz old was icmp */
+ int icps_oldmcast; /* no error 'cuz old was multicast */
+ int icps_oldbadaddr; /* no error 'cuz old had bad address */
int icps_outhist[ICMP_MAXTYPE + 1];
/* statistics related to input messages processed */
int icps_badcode; /* icmp_code out of range */
@@ -54,5 +59,10 @@ struct icmpstat {
};
#ifdef KERNEL
-struct icmpstat icmpstat;
+extern struct icmpstat icmpstat;
+extern int icmpprintfs;
+extern int ipbroadcastecho;
+extern int ipmaskagent;
+extern struct sockaddr_in icmpmask;
#endif
+#endif /* _NETINET_ICMP_VAR_H_ */
diff --git a/sys/netinet/if_ether.c b/sys/netinet/if_ether.c
index ad39b441e26f..ebad56b12dcf 100644
--- a/sys/netinet/if_ether.c
+++ b/sys/netinet/if_ether.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)if_ether.c 7.13 (Berkeley) 10/31/90
- * $Id: if_ether.c,v 1.3 1993/10/16 18:25:54 rgrimes Exp $
+ * $Id: if_ether.c,v 1.4 1993/11/25 01:34:57 wollman Exp $
*/
/*
@@ -60,6 +60,9 @@
#include "ip.h"
#include "if_ether.h"
+static void in_arpinput(struct arpcom *, struct mbuf *);
+static void arptfree(struct arptab *);
+
#ifdef GATEWAY
#define ARPTAB_BSIZ 16 /* bucket size */
#define ARPTAB_NB 37 /* number of buckets */
@@ -100,6 +103,7 @@ extern struct ifnet loif;
/*
* Timeout routine. Age arp_tab entries once a minute.
*/
+void
arptimer()
{
register struct arptab *at;
@@ -121,6 +125,7 @@ arptimer()
/*
* Broadcast an ARP packet, asking who has addr on interface ac.
*/
+void
arpwhohas(ac, addr)
register struct arpcom *ac;
struct in_addr *addr;
@@ -172,6 +177,7 @@ int useloopback = 1; /* use loopback interface for local traffic */
* arptab is also altered from input interrupt service (ecintr/ilintr
* calls arpinput when ETHERTYPE_ARP packets come in).
*/
+int
arpresolve(ac, m, destip, desten, usetrailers)
register struct arpcom *ac;
struct mbuf *m;
@@ -270,6 +276,7 @@ arpresolve(ac, m, destip, desten, usetrailers)
* is received. Common length and type checks are done here,
* then the protocol-specific routine is called.
*/
+void
arpinput(ac, m)
struct arpcom *ac;
struct mbuf *m;
@@ -314,13 +321,14 @@ out:
* We reply to requests for ETHERTYPE_TRAIL protocol as well,
* but don't normally send requests.
*/
+void
in_arpinput(ac, m)
register struct arpcom *ac;
struct mbuf *m;
{
register struct ether_arp *ea;
struct ether_header *eh;
- register struct arptab *at; /* same as "merge" flag */
+ register struct arptab *at = 0; /* same as "merge" flag */
register struct in_ifaddr *ia;
struct in_ifaddr *maybe_ia = 0;
struct mbuf *mcopy = 0;
@@ -469,6 +477,7 @@ out:
/*
* Free an arptab entry.
*/
+void
arptfree(at)
register struct arptab *at;
{
@@ -524,6 +533,7 @@ out:
return (at);
}
+int
arpioctl(cmd, data)
int cmd;
caddr_t data;
diff --git a/sys/netinet/if_ether.h b/sys/netinet/if_ether.h
index 8dc3d26a8c95..787b561e6fdf 100644
--- a/sys/netinet/if_ether.h
+++ b/sys/netinet/if_ether.h
@@ -31,9 +31,12 @@
* SUCH DAMAGE.
*
* from: @(#)if_ether.h 7.5 (Berkeley) 6/28/90
- * $Id: if_ether.h,v 1.2 1993/10/16 18:25:55 rgrimes Exp $
+ * $Id: if_ether.h,v 1.4 1993/11/25 01:35:01 wollman Exp $
*/
+#ifndef _NETINET_IF_ETHER_H_
+#define _NETINET_IF_ETHER_H_ 1
+
/*
* Structure of a 10Mb/s Ethernet header.
*/
@@ -102,8 +105,11 @@ struct arptab {
};
#ifdef KERNEL
-u_char etherbroadcastaddr[6];
+extern u_char etherbroadcastaddr[6]; /* defined in net/if_ethersubr.c */
struct arptab *arptnew();
-int ether_output(), ether_input();
-char *ether_sprintf();
+
+extern void ether_input(struct ifnet *, struct ether_header *, struct mbuf *);
+extern char *ether_sprintf(u_char *);
+
#endif
+#endif /* _NETINET_IF_ETHER_H_ */
diff --git a/sys/netinet/in.c b/sys/netinet/in.c
index 7f989a233e27..2c662e2d6336 100644
--- a/sys/netinet/in.c
+++ b/sys/netinet/in.c
@@ -31,10 +31,11 @@
* SUCH DAMAGE.
*
* from: @(#)in.c 7.17 (Berkeley) 4/20/91
- * $Id: in.c,v 1.2 1993/10/16 18:25:57 rgrimes Exp $
+ * $Id: in.c,v 1.8 1994/01/15 14:29:21 davidg Exp $
*/
#include "param.h"
+#include "systm.h"
#include "ioctl.h"
#include "mbuf.h"
#include "socket.h"
@@ -42,11 +43,13 @@
#include "in_systm.h"
#include "net/if.h"
#include "net/route.h"
-#include "net/af.h"
#include "in.h"
#include "in_var.h"
#ifdef INET
+
+static void in_ifscrub(struct ifnet *, struct in_ifaddr *);
+
/*
* Formulate an Internet address from network + host.
*/
@@ -106,6 +109,7 @@ in_netof(in)
/*
* Compute and save network mask as sockaddr from an internet address.
*/
+void
in_sockmaskof(in, sockmask)
struct in_addr in;
register struct sockaddr_in *sockmask;
@@ -183,16 +187,13 @@ in_lnaof(in)
return (host);
}
-#ifndef SUBNETSARELOCAL
-#define SUBNETSARELOCAL 1
-#endif
-int subnetsarelocal = SUBNETSARELOCAL;
/*
* Return 1 if an internet address is for a ``local'' host
* (one to which we have a connection). If subnetsarelocal
* is true, this includes other subnets of the local net.
* Otherwise, it includes only the directly-connected (sub)nets.
*/
+int
in_localaddr(in)
struct in_addr in;
{
@@ -216,6 +217,7 @@ in_localaddr(in)
* that may not be forwarded, or whether datagrams to that destination
* may be forwarded.
*/
+int
in_canforward(in)
struct in_addr in;
{
@@ -226,20 +228,20 @@ in_canforward(in)
return (0);
if (IN_CLASSA(i)) {
net = i & IN_CLASSA_NET;
- if (net == 0 || net == IN_LOOPBACKNET)
+ if (net == 0 || net == (IN_LOOPBACKNET << IN_CLASSA_NSHIFT))
return (0);
}
return (1);
}
-int in_interfaces; /* number of external internet interfaces */
-extern struct ifnet loif;
+static int in_interfaces; /* number of external internet interfaces */
/*
* Generic internet control operations (ioctl's).
* Ifp is 0 if not an interface-specific ioctl.
*/
/* ARGSUSED */
+int
in_control(so, cmd, data, ifp)
struct socket *so;
int cmd;
@@ -364,7 +366,8 @@ in_control(so, cmd, data, ifp)
oldaddr = ia->ia_dstaddr;
ia->ia_dstaddr = *(struct sockaddr_in *)&ifr->ifr_dstaddr;
if (ifp->if_ioctl &&
- (error = (*ifp->if_ioctl)(ifp, SIOCSIFDSTADDR, ia))) {
+ (error = (*ifp->if_ioctl)(ifp, SIOCSIFDSTADDR,
+ (caddr_t)ia))) {
ia->ia_dstaddr = oldaddr;
return (error);
}
@@ -463,6 +466,7 @@ in_control(so, cmd, data, ifp)
/*
* Delete any existing route for an interface.
*/
+static void
in_ifscrub(ifp, ia)
register struct ifnet *ifp;
register struct in_ifaddr *ia;
@@ -481,10 +485,12 @@ in_ifscrub(ifp, ia)
* Initialize an interface's internet address
* and routing table entry.
*/
+int
in_ifinit(ifp, ia, sin, scrub)
register struct ifnet *ifp;
register struct in_ifaddr *ia;
struct sockaddr_in *sin;
+ int scrub;
{
register u_long i = ntohl(sin->sin_addr.s_addr);
struct sockaddr_in oldaddr;
@@ -497,7 +503,8 @@ in_ifinit(ifp, ia, sin, scrub)
* if this is its first address,
* and to validate the address if necessary.
*/
- if (ifp->if_ioctl && (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, ia))) {
+ if (ifp->if_ioctl && (error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR,
+ (caddr_t)ia))) {
splx(s);
ia->ia_addr = oldaddr;
return (error);
@@ -571,6 +578,7 @@ in_iaonnetof(net)
/*
* Return 1 if the address might be a local broadcast address.
*/
+int
in_broadcast(in)
struct in_addr in;
{
diff --git a/sys/netinet/in.h b/sys/netinet/in.h
index 89a9da45a500..48f24b39ede4 100644
--- a/sys/netinet/in.h
+++ b/sys/netinet/in.h
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)in.h 7.11 (Berkeley) 4/20/91
- * $Id: in.h,v 1.3 1993/10/16 18:25:58 rgrimes Exp $
+ * $Id: in.h,v 1.4 1993/12/19 00:52:35 wollman Exp $
*/
#ifndef _NETINET_IN_H_
@@ -82,33 +82,33 @@ struct in_addr {
* On subnets, the decomposition of addresses to host and net parts
* is done according to subnet mask, not the masks here.
*/
-#define IN_CLASSA(i) (((long)(i) & 0x80000000) == 0)
-#define IN_CLASSA_NET 0xff000000
+#define IN_CLASSA(i) (((u_long)(i) & 0x80000000UL) == 0)
+#define IN_CLASSA_NET 0xff000000UL
#define IN_CLASSA_NSHIFT 24
-#define IN_CLASSA_HOST 0x00ffffff
+#define IN_CLASSA_HOST 0x00ffffffUL
#define IN_CLASSA_MAX 128
-#define IN_CLASSB(i) (((long)(i) & 0xc0000000) == 0x80000000)
-#define IN_CLASSB_NET 0xffff0000
+#define IN_CLASSB(i) (((u_long)(i) & 0xc0000000UL) == 0x80000000UL)
+#define IN_CLASSB_NET 0xffff0000UL
#define IN_CLASSB_NSHIFT 16
-#define IN_CLASSB_HOST 0x0000ffff
+#define IN_CLASSB_HOST 0x0000ffffUL
#define IN_CLASSB_MAX 65536
-#define IN_CLASSC(i) (((long)(i) & 0xe0000000) == 0xc0000000)
-#define IN_CLASSC_NET 0xffffff00
+#define IN_CLASSC(i) (((u_long)(i) & 0xe0000000UL) == 0xc0000000UL)
+#define IN_CLASSC_NET 0xffffff00UL
#define IN_CLASSC_NSHIFT 8
-#define IN_CLASSC_HOST 0x000000ff
+#define IN_CLASSC_HOST 0x000000ffUL
-#define IN_CLASSD(i) (((long)(i) & 0xf0000000) == 0xe0000000)
+#define IN_CLASSD(i) (((u_long)(i) & 0xf0000000UL) == 0xe0000000UL)
#define IN_MULTICAST(i) IN_CLASSD(i)
-#define IN_EXPERIMENTAL(i) (((long)(i) & 0xe0000000) == 0xe0000000)
-#define IN_BADCLASS(i) (((long)(i) & 0xf0000000) == 0xf0000000)
+#define IN_EXPERIMENTAL(i) (((u_long)(i) & 0xe0000000UL) == 0xe0000000UL)
+#define IN_BADCLASS(i) (((u_long)(i) & 0xf0000000UL) == 0xf0000000UL)
-#define INADDR_ANY (u_long)0x00000000
-#define INADDR_BROADCAST (u_long)0xffffffff /* must be masked */
+#define INADDR_ANY 0x00000000UL
+#define INADDR_BROADCAST 0xffffffffUL /* must be masked */
#ifndef KERNEL
-#define INADDR_NONE 0xffffffff /* -1 return */
+#define INADDR_NONE 0xffffffffUL /* -1 return */
#endif
#define IN_LOOPBACKNET 127 /* official! */
@@ -150,8 +150,18 @@ struct ip_opts {
#define IP_RETOPTS 8 /* ip_opts; set/get IP per-packet options */
#ifdef KERNEL
-struct in_addr in_makeaddr();
-u_long in_netof(), in_lnaof();
-#endif
+/* From in.c: */
+extern struct in_addr in_makeaddr(u_long, u_long);
+extern u_long in_netof(struct in_addr);
+extern void in_sockmaskof(struct in_addr, struct sockaddr_in *);
+extern u_long in_lnaof(struct in_addr);
+extern int in_localaddr(struct in_addr);
+extern int in_canforward(struct in_addr);
+struct socket; struct ifnet;
+extern int in_control(struct socket *, int, caddr_t, struct ifnet *);
+struct in_ifaddr;
+extern int in_broadcast(struct in_addr);
+
+#endif /* KERNEL */
#endif /* _NETINET_IN_H_ */
diff --git a/sys/netinet/in_mtudisc.c b/sys/netinet/in_mtudisc.c
new file mode 100644
index 000000000000..db74443bf8c6
--- /dev/null
+++ b/sys/netinet/in_mtudisc.c
@@ -0,0 +1,377 @@
+/*-
+ * Copyright (c) 1993, University of Vermont and State
+ * Agricultural College.
+ * Copyright (c) 1993, Garrett A. Wollman.
+ *
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND AUTHOR ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE UNIVERSITY OR AUTHORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: in_mtudisc.c,v 1.2 1993/12/19 00:52:36 wollman Exp $
+ */
+
+#ifdef MTUDISC
+
+#include "param.h"
+#include "systm.h"
+#include "kernel.h"
+#include "mbuf.h"
+#include "socket.h"
+#include "socketvar.h"
+#include "in_systm.h"
+#include "net/if.h"
+#include "net/route.h"
+#include "in.h"
+#include "in_var.h"
+#include "ip.h"
+#include "protosw.h"
+#include "in_pcb.h"
+
+#ifdef INET
+
+/*
+ * checkpcbs[] lists all the PCB heads that might call on the services
+ * of MTU discovery.
+ * This is really bogus 'cuz a ULP needs to both get its entry added here
+ * /and/ set INP_DISCOVERMTU in each PCB.
+ */
+extern struct inpcb tcb; /* XXX move to header file */
+
+struct inpcb *checkpcbs[] = {
+ &tcb,
+ 0
+};
+
+
+/*
+ * Table of likely MTU values, courtesy of RFC 1191.
+ * This MUST remain in sorted order.
+ */
+static const u_short in_mtus[] = {
+ 65535, /* maximum */
+ 32767, /* convenient power of 2 - 1 */
+ 17914, /* 16Mb Token Ring */
+ 16383, /* convenient power of 2 - 1 */
+ 8166, /* IEEE 802.4 */
+ 6288, /* convenient stopping point */
+ 4352, /* FDDI */
+ 3144, /* convenient stopping point */
+ 2002, /* IEEE 802.5 */
+ 1492, /* IEEE 802.3 */
+ 1006, /* BBN 1822 */
+ 508, /* ARCNET */
+ 296, /* SLIP, PPP */
+ 128 /* minimum we'll accept */
+};
+
+#define NMTUS ((sizeof in_mtus)/(sizeof in_mtus[0]))
+
+/*
+ * Find the next MTU in the sequence from CURRENT.
+ * If HIGHER, increase size; else decrease.
+ * Return of zero means we're stuck.
+ * NB: We might be called with a CURRENT MTU that's not in the
+ * table (as, for example, when an ICMP tells us there's a problem
+ * and reports a max path MTU value).
+ */
+unsigned
+in_nextmtu(unsigned current, int higher) {
+ int i;
+
+ for(i = 0; i < NMTUS; i++) {
+ if(in_mtus[i] <= (u_short)current)
+ break;
+ }
+
+ if(i == NMTUS) {
+ if(higher) return in_mtus[NMTUS - 1];
+ else return 0; /* error return */
+ }
+
+ /*
+ * Now we know that CURRENT lies somewhere in the interval
+ * (in_mtus[i - 1], in_mtus[i]]. If we want to go higher,
+ * take in_mtus[i - 1] always. If we want to go lower, we
+ * must check the lower bound to see if it's equal, and if so,
+ * take in_mtus[i + 1], unless i == NMTUS - 1, in which case
+ * we return failure.
+ * Got that?
+ */
+ if(higher)
+ return in_mtus[(i >= 1) ? (i - 1) : 0];
+
+ /* now we know it's lower */
+ if(current == in_mtus[i]) {
+ if(i == NMTUS - 1)
+ return 0;
+ else
+ return in_mtus[i + 1];
+ }
+
+ return in_mtus[i];
+}
+
+/*
+ * Set up the route to do MTU discovery. This only works for host routes,
+ * not net routes; in any case, ALL systems should have all IP routes
+ * marked with RTF_CLONING (and a genmask of zero), which will do the right
+ * thing, and also arrange for the pre-ARPing code to get called on
+ * on appropriate interfaces.
+ *
+ * We also go to some pains to keep listeners on the routing socket aware
+ * of what's going on when we fiddle the flags or metrics. I don't know
+ * if this is really necessary or not (or even if we're doing it in the
+ * right way).
+ */
+int in_routemtu(struct route *ro) {
+ if(!ro->ro_rt)
+ return 0;
+
+ if((ro->ro_rt->rt_flags & (RTF_HOST | RTF_UP)) != (RTF_HOST | RTF_UP))
+ return 0;
+
+ if(ro->ro_rt->rt_rmx.rmx_mtu) {
+ /*
+ * Let the user know that we've turned on MTU discovery for this
+ * route entry. This doesn't do anything at present, but may
+ * be useful later on.
+ */
+ if(!(ro->ro_rt->rt_flags & RTF_PROTO1)) {
+ ro->ro_rt->rt_flags |= RTF_PROTO1;
+ }
+ return 1;
+ }
+
+ if(ro->ro_rt->rt_ifp && !(ro->ro_rt->rt_rmx.rmx_locks & RTV_MTU)) {
+ ro->ro_rt->rt_flags |= RTF_PROTO1;
+ /*
+ * Subtraction is necessary because the interface's MTU includes
+ * the interface's own headers. We subtract the header length
+ * provided and hope for the best.
+ */
+ ro->ro_rt->rt_rmx.rmx_mtu =
+ ro->ro_rt->rt_ifp->if_mtu - ro->ro_rt->rt_ifp->if_hdrlen;
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * Perform the PCB fiddling necessary when the route changes.
+ * Protect against recursion, since we might get called as a
+ * result of notifying someone else that the MTU is changing.
+ */
+void
+in_pcbmtu(struct inpcb *inp) {
+ static int notifying = 0;
+ static int timerstarted = 0;
+ unsigned oldmtu = inp->inp_pmtu;
+ int oldflags = inp->inp_flags;
+
+ if (!timerstarted) {
+ timeout(in_mtutimer, 0, 60 * hz);
+ timerstarted = 1;
+ }
+
+ if (inp->inp_flags & INP_DISCOVERMTU) {
+ /*
+ * If no route present, get one.
+ * If there is one present, but it's marked as being `down',
+ * try to get another one.
+ */
+ if(!inp->inp_route.ro_rt)
+ rtalloc(&inp->inp_route);
+ else if((inp->inp_route.ro_rt->rt_flags & RTF_UP) == 0) {
+ RTFREE(inp->inp_route.ro_rt);
+ inp->inp_route.ro_rt = 0;
+ rtalloc(&inp->inp_route);
+ }
+
+ if(in_routemtu(&inp->inp_route)) {
+ inp->inp_flags |= INP_MTUDISCOVERED;
+ inp->inp_pmtu = inp->inp_route.ro_rt->rt_rmx.rmx_mtu;
+ inp->inp_ip.ip_off |= IP_DF;
+ } else {
+ inp->inp_flags &= ~INP_MTUDISCOVERED;
+ inp->inp_ip.ip_off &= ~IP_DF;
+ }
+ /*
+ * If nothing has changed since the last value we had,
+ * don't waste any time notifying everybody that nothing
+ * has changed.
+ */
+ if(inp->inp_pmtu != oldmtu
+ || (inp->inp_flags ^ oldflags)) {
+ notifying = 1;
+ /*
+ * If the MTU has decreased, use timer 2.
+ */
+ inp->inp_mtutimer =
+ (inp->inp_pmtu < oldmtu) ? in_mtutimer2 : in_mtutimer1;
+ in_mtunotify(inp);
+ notifying = 0;
+ }
+ }
+}
+
+/*
+ * Tell the clients that have the same destination as INP that they
+ * need to take a new look at the MTU value and flags.
+ */
+void
+in_mtunotify(struct inpcb *inp) {
+ in_pcbnotify(inp->inp_head, &inp->inp_route.ro_dst, 0, zeroin_addr,
+ 0, PRC_MTUCHANGED, inp->inp_mtunotify);
+}
+
+/*
+ * Adjust the MTU listed in the route on the basis of an ICMP
+ * Unreachable: Need Fragmentation message.
+ * Note that the PRC_MSGSIZE error is still delivered; this just
+ * makes the adjustment in the route, and depends on the ULPs which
+ * are required to translate PRC_MSGSIZE into an in_pcbmtu() which will
+ * pick up the new size.
+ */
+void
+in_mtureduce(struct in_addr dst, unsigned newsize) {
+ struct route ro;
+
+ ro.ro_dst.sa_family = AF_INET;
+ ro.ro_dst.sa_len = sizeof ro.ro_dst;
+ ((struct sockaddr_in *)&ro.ro_dst)->sin_addr = dst;
+ ro.ro_rt = 0;
+ rtalloc(&ro);
+
+ /*
+ * If there was no route, just forget about it, can't do anything.
+ */
+ if(!ro.ro_rt)
+ return;
+
+ /*
+ * If there was a route, but it's the wrong kind, forget it.
+ */
+ if((ro.ro_rt->rt_flags & (RTF_UP | RTF_HOST)) != (RTF_UP | RTF_HOST)) {
+ RTFREE(ro.ro_rt);
+ return;
+ }
+
+ /*
+ * If the MTU is locked by some outside agency, forget it.
+ */
+ if(ro.ro_rt->rt_rmx.rmx_locks & RTV_MTU) {
+ RTFREE(ro.ro_rt);
+ return;
+ }
+
+ /*
+ * If newsize == 0, then we got an ICMP from a router
+ * which doesn't support the MTU extension, so just go down one.
+ */
+ newsize = in_nextmtu(ro.ro_rt->rt_rmx.rmx_mtu, 0);
+
+ if(!newsize) {
+ ro.ro_rt->rt_rmx.rmx_mtu = 0; /* we can't go any lower */
+ RTFREE(ro.ro_rt);
+ return;
+ }
+ /*
+ * If the new MTU is greater than the old MTU, forget it. (Prevent
+ * denial-of-service attack.) Don't bother if the new MTU is the
+ * same as the old one.
+ */
+ if(ro.ro_rt->rt_rmx.rmx_mtu <= newsize) {
+ RTFREE(ro.ro_rt);
+ return;
+ }
+
+ /*
+ * OK, do it.
+ */
+ ro.ro_rt->rt_rmx.rmx_mtu = newsize;
+ RTFREE(ro.ro_rt);
+}
+
+/*
+ * Walk through all the PCB lists in checkpcbs[] and decrement the
+ * timers on the ones still participating in MTU discovery.
+ * If the timers reach zero, bump the MTU (clamped to the interface
+ * MTU), assuming the route is still good.
+ */
+void
+in_mtutimer(caddr_t dummy1, int dummy2) {
+ int i;
+ struct inpcb *inp;
+ struct rtentry *rt;
+ int s = splnet();
+
+ for(i = 0; checkpcbs[i]; i++) {
+ inp = checkpcbs[i];
+
+ while(inp = inp->inp_next) {
+ if(inp->inp_flags & INP_MTUDISCOVERED) {
+ if(!inp->inp_route.ro_rt
+ || !(inp->inp_route.ro_rt->rt_flags & RTF_UP)) {
+ inp->inp_flags &= ~INP_MTUDISCOVERED;
+ continue; /* we'll notice it later */
+ }
+
+ if(--inp->inp_mtutimer == 0) {
+ in_bumpmtu(inp);
+ inp->inp_mtutimer = in_mtutimer1;
+ if(inp->inp_route.ro_rt->rt_rmx.rmx_rtt
+ && ((in_mtutimer1 * 60)
+ > (inp->inp_route.ro_rt->rt_rmx.rmx_rtt / RTM_RTTUNIT))) {
+ inp->inp_mtutimer =
+ inp->inp_route.ro_rt->rt_rmx.rmx_rtt / RTM_RTTUNIT;
+ }
+ }
+ }
+ }
+ }
+ splx(s);
+ timeout(in_mtutimer, (caddr_t)0, 60 * hz);
+}
+
+/*
+ * Try to increase the MTU and let everyone know that it has changed.
+ * Must be called with a valid route in inp->inp_route. Probably
+ * must be at splnet(), too.
+ */
+void
+in_bumpmtu(struct inpcb *inp) {
+ struct route *ro;
+ unsigned newmtu;
+
+ ro = &inp->inp_route;
+ newmtu = in_nextmtu(inp->inp_pmtu, 1);
+ if(!newmtu) return; /* doing the best we can */
+ if(newmtu <= ro->ro_rt->rt_ifp->if_mtu) {
+ if(!(ro->ro_rt->rt_rmx.rmx_locks & RTV_MTU)) {
+ ro->ro_rt->rt_rmx.rmx_mtu = newmtu;
+ in_pcbmtu(inp);
+ }
+ }
+}
+
+#endif /* INET */
+#endif /* MTUDISC */
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index 3d333bcfc6fd..cc404e6f1510 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)in_pcb.c 7.14 (Berkeley) 4/20/91
- * $Id: in_pcb.c,v 1.2 1993/10/16 18:26:01 rgrimes Exp $
+ * $Id: in_pcb.c,v 1.5 1993/12/19 00:52:37 wollman Exp $
*/
#include "param.h"
@@ -52,8 +52,7 @@
#include "in_pcb.h"
#include "in_var.h"
-struct in_addr zeroin_addr;
-
+int
in_pcballoc(so, head)
struct socket *so;
struct inpcb *head;
@@ -72,6 +71,7 @@ in_pcballoc(so, head)
return (0);
}
+int
in_pcbbind(inp, nam)
register struct inpcb *inp;
struct mbuf *nam;
@@ -135,12 +135,13 @@ noname:
* If don't have a local address for this socket yet,
* then pick one.
*/
+int
in_pcbconnect(inp, nam)
register struct inpcb *inp;
struct mbuf *nam;
{
struct in_ifaddr *ia;
- struct sockaddr_in *ifaddr;
+ struct sockaddr_in *ifaddr = 0;
register struct sockaddr_in *sin = mtod(nam, struct sockaddr_in *);
if (nam->m_len != sizeof (*sin))
@@ -232,19 +233,31 @@ in_pcbconnect(inp, nam)
}
inp->inp_faddr = sin->sin_addr;
inp->inp_fport = sin->sin_port;
+#ifdef MTUDISC
+ /*
+ * If the upper layer asked for PMTU discovery services, see
+ * if we can get an idea of what the MTU should be...
+ */
+ in_pcbmtu(inp);
+#endif /* MTUDISC */
return (0);
}
+void
in_pcbdisconnect(inp)
struct inpcb *inp;
{
inp->inp_faddr.s_addr = INADDR_ANY;
inp->inp_fport = 0;
+#ifdef MTUDISC
+ inp->inp_flags &= ~INP_MTUDISCOVERED;
+#endif
if (inp->inp_socket->so_state & SS_NOFDREF)
in_pcbdetach(inp);
}
+void
in_pcbdetach(inp)
struct inpcb *inp;
{
@@ -260,6 +273,7 @@ in_pcbdetach(inp)
(void) m_free(dtom(inp));
}
+void
in_setsockaddr(inp, nam)
register struct inpcb *inp;
struct mbuf *nam;
@@ -275,6 +289,7 @@ in_setsockaddr(inp, nam)
sin->sin_addr = inp->inp_laddr;
}
+void
in_setpeeraddr(inp, nam)
struct inpcb *inp;
struct mbuf *nam;
@@ -301,18 +316,18 @@ in_setpeeraddr(inp, nam)
*
* Must be called at splnet.
*/
+void
in_pcbnotify(head, dst, fport, laddr, lport, cmd, notify)
struct inpcb *head;
struct sockaddr *dst;
u_short fport, lport;
struct in_addr laddr;
- int cmd, (*notify)();
+ int cmd;
+ void (*notify)(struct inpcb *, int);
{
register struct inpcb *inp, *oinp;
struct in_addr faddr;
int errno;
- int in_rtchange();
- extern u_char inetctlerrmap[];
if ((unsigned)cmd > PRC_NCMDS || dst->sa_family != AF_INET)
return;
@@ -324,14 +339,16 @@ in_pcbnotify(head, dst, fport, laddr, lport, cmd, notify)
* Redirects go to all references to the destination,
* and use in_rtchange to invalidate the route cache.
* Dead host indications: notify all references to the destination.
+ * MTU change indications: same thing.
* Otherwise, if we have knowledge of the local port and address,
* deliver only to that socket.
*/
- if (PRC_IS_REDIRECT(cmd) || cmd == PRC_HOSTDEAD) {
+ if (PRC_IS_REDIRECT(cmd) || cmd == PRC_HOSTDEAD
+ || cmd == PRC_MTUCHANGED) {
fport = 0;
lport = 0;
laddr.s_addr = 0;
- if (cmd != PRC_HOSTDEAD)
+ if (cmd != PRC_HOSTDEAD && cmd != PRC_MTUCHANGED)
notify = in_rtchange;
}
errno = inetctlerrmap[cmd];
@@ -357,6 +374,7 @@ in_pcbnotify(head, dst, fport, laddr, lport, cmd, notify)
* routing information. If the route was created dynamically
* (by a redirect), time to try a default gateway again.
*/
+void
in_losing(inp)
struct inpcb *inp;
{
@@ -372,10 +390,14 @@ in_losing(inp)
(struct rtentry **)0);
inp->inp_route.ro_rt = 0;
rtfree(rt);
+
+#ifdef MTUDISC
/*
- * A new route can be allocated
- * the next time output is attempted.
+ * When doing MTU discovery, we want to find out as
+ * quickly as possible what the MTU of the new route is.
*/
+ in_pcbmtu(inp);
+#endif /* MTUDISC */
}
}
@@ -383,16 +405,22 @@ in_losing(inp)
* After a routing change, flush old routing
* and allocate a (hopefully) better one.
*/
-in_rtchange(inp)
+void
+in_rtchange(inp, errno)
register struct inpcb *inp;
+ int errno;
{
if (inp->inp_route.ro_rt) {
rtfree(inp->inp_route.ro_rt);
inp->inp_route.ro_rt = 0;
+#ifdef MTUDISC
/*
* A new route can be allocated the next time
- * output is attempted.
+ * output is attempted, but make sure to let
+ * MTU discovery know about it.
*/
+ in_pcbmtu(inp);
+#endif /* MTUDISC */
}
}
diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h
index 92e3ddf0a315..e4adb614e6d4 100644
--- a/sys/netinet/in_pcb.h
+++ b/sys/netinet/in_pcb.h
@@ -31,9 +31,12 @@
* SUCH DAMAGE.
*
* from: @(#)in_pcb.h 7.6 (Berkeley) 6/28/90
- * $Id: in_pcb.h,v 1.2 1993/10/16 18:26:03 rgrimes Exp $
+ * $Id: in_pcb.h,v 1.5 1993/11/25 01:35:06 wollman Exp $
*/
+#ifndef _NETINET_IN_PCB_H_
+#define _NETINET_IN_PCB_H_ 1
+
/*
* Common structure pcb for internet protocol implementation.
* Here are stored pointers to local and foreign host table
@@ -56,12 +59,24 @@ struct inpcb {
int inp_flags; /* generic IP/datagram flags */
struct ip inp_ip; /* header prototype; should have more */
struct mbuf *inp_options; /* IP options */
+#ifdef MTUDISC
+ int inp_pmtu; /* path mtu if INP_MTUDISCOVERED */
+ int inp_mtutimer; /* decremented once a minute to
+ try to increase mtu */
+ int (*inp_mtunotify)(struct inpcb *, int);
+ /* function to call when MTU may have
+ * changed */
+#endif /* MTUDISC */
};
/* flags in inp_flags: */
#define INP_RECVOPTS 0x01 /* receive incoming IP options */
#define INP_RECVRETOPTS 0x02 /* receive IP options for reply */
#define INP_RECVDSTADDR 0x04 /* receive IP dst address */
+#ifdef MTUDISC
+#define INP_DISCOVERMTU 0x08 /* practice Path MTU discovery */
+#define INP_MTUDISCOVERED 0x10 /* we were able to get such a route */
+#endif /* MTUDISC */
#define INP_CONTROLOPTS (INP_RECVOPTS|INP_RECVRETOPTS|INP_RECVDSTADDR)
#ifdef sotorawcb
@@ -88,5 +103,24 @@ struct raw_inpcb {
#define sotorawinpcb(so) ((struct raw_inpcb *)(so)->so_pcb)
#ifdef KERNEL
-struct inpcb *in_pcblookup();
-#endif
+/* From in_pcb.h: */
+extern int in_pcballoc(struct socket *, struct inpcb *);
+extern int in_pcbbind(struct inpcb *, struct mbuf *);
+extern int in_pcbconnect(struct inpcb *, struct mbuf *);
+extern void in_pcbdisconnect(struct inpcb *);
+extern void in_pcbdetach(struct inpcb *);
+extern void in_setsockaddr(struct inpcb *, struct mbuf *);
+extern void in_setpeeraddr(struct inpcb *, struct mbuf *);
+extern void in_pcbnotify(struct inpcb *, struct sockaddr *, int, struct in_addr, int, int, void (*)(struct inpcb *, int));
+extern void in_losing(struct inpcb *);
+extern void in_rtchange(struct inpcb *, int);
+extern struct inpcb *in_pcblookup(struct inpcb *, struct in_addr, int, struct in_addr, int, int);
+
+
+#ifdef MTUDISC
+extern void in_pcbmtu(struct inpcb *);
+extern void in_mtunotify(struct inpcb *);
+extern void in_bumpmtu(struct inpcb *);
+#endif /* MTUDISC */
+#endif /* KERNEL */
+#endif /* _NETINET_IN_PCB_H_ */
diff --git a/sys/netinet/in_proto.c b/sys/netinet/in_proto.c
index 2aa8279328df..dc147f090b51 100644
--- a/sys/netinet/in_proto.c
+++ b/sys/netinet/in_proto.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)in_proto.c 7.5 (Berkeley) 6/28/90
- * $Id: in_proto.c,v 1.2 1993/10/16 18:26:04 rgrimes Exp $
+ * $Id: in_proto.c,v 1.3 1993/12/19 00:52:38 wollman Exp $
*/
#include "param.h"
@@ -39,23 +39,52 @@
#include "protosw.h"
#include "domain.h"
#include "mbuf.h"
+#include "net/if.h"
+#include "net/route.h"
#include "in.h"
#include "in_systm.h"
+#include "in_var.h" /* IP prototypes */
+
+#include "ip.h"
+#include "ip_var.h" /* more IP prototypes */
+
+#include "ip_icmp.h"
+#include "icmp_var.h" /* ICMP prototypes */
+
+#include "udp.h"
+#include "udp_var.h" /* UDP prototypes */
+
+#include "tcp.h"
+#include "tcp_fsm.h"
+#include "tcp_seq.h"
+#include "tcp_timer.h"
+#include "tcp_var.h" /* TCP prototypes */
/*
* TCP/IP protocol family: IP, ICMP, UDP, TCP.
*/
-int ip_output(),ip_ctloutput();
-int ip_init(),ip_slowtimo(),ip_drain();
-int icmp_input();
-int udp_input(),udp_ctlinput();
-int udp_usrreq();
-int udp_init();
-int tcp_input(),tcp_ctlinput();
-int tcp_usrreq(),tcp_ctloutput();
-int tcp_init(),tcp_fasttimo(),tcp_slowtimo(),tcp_drain();
-int rip_input(),rip_output(),rip_ctloutput(), rip_usrreq();
+in_output_t ip_output;
+in_ctloutput_t ip_ctloutput;
+void ip_init();
+void ip_slowtimo();
+void ip_drain();
+in_input_t udp_input;
+in_ctlinput_t udp_ctlinput;
+int udp_usrreq();
+void udp_init();
+in_input_t tcp_input;
+in_ctlinput_t tcp_ctlinput;
+int tcp_usrreq();
+in_ctloutput_t tcp_ctloutput;
+void tcp_init();
+void tcp_fasttimo();
+void tcp_slowtimo();
+void tcp_drain();
+in_input_t rip_input;
+in_output_t rip_output;
+in_ctloutput_t rip_ctloutput;
+int rip_usrreq();
/*
* IMP protocol family: raw interface.
* Using the raw interface entry to get the timer routine
@@ -63,25 +92,34 @@ int rip_input(),rip_output(),rip_ctloutput(), rip_usrreq();
*/
#include "imp.h"
#if NIMP > 0
-int rimp_output(), hostslowtimo();
+int rimp_output();
+void hostslowtimo();
#endif
#ifdef NSIP
-int idpip_input(), nsip_ctlinput();
+in_input_t idpip_input;
+in_ctlinput_t nsip_ctlinput;
#endif
#ifdef TPIP
-int tpip_input(), tpip_ctlinput(), tp_ctloutput(), tp_usrreq();
-int tp_init(), tp_slowtimo(), tp_drain();
+in_input_t tpip_input;
+in_ctlinput_t tpip_ctlinput;
+in_ctloutput_t tp_ctloutput;
+int tp_usrreq();
+void tp_init();
+void tp_slowtimo();
+void tp_drain();
#endif
#ifdef EON
-int eoninput(), eonctlinput(), eonprotoinit();
-#endif EON
+in_input_t eoninput;
+in_ctlinput_t eonctlinput;
+void eonprotoinit();
+#endif /* EON */
extern struct domain inetdomain;
-struct protosw inetsw[] = {
+struct in_protosw inetsw[] = {
{ 0, &inetdomain, 0, 0,
0, ip_output, 0, 0,
0,
@@ -138,8 +176,10 @@ struct protosw inetsw[] = {
};
struct domain inetdomain =
- { AF_INET, "internet", 0, 0, 0,
- inetsw, &inetsw[sizeof(inetsw)/sizeof(inetsw[0])] };
+{ AF_INET, "internet", 0, 0, 0,
+ (struct protosw *)inetsw,
+ (struct protosw *)&inetsw[sizeof(inetsw)/sizeof(inetsw[0])]
+};
#if NIMP > 0
extern struct domain impdomain;
diff --git a/sys/netinet/in_systm.h b/sys/netinet/in_systm.h
index ad2c205f7269..6faca52cd61e 100644
--- a/sys/netinet/in_systm.h
+++ b/sys/netinet/in_systm.h
@@ -31,9 +31,12 @@
* SUCH DAMAGE.
*
* from: @(#)in_systm.h 7.4 (Berkeley) 6/28/90
- * $Id: in_systm.h,v 1.2 1993/10/16 18:26:06 rgrimes Exp $
+ * $Id: in_systm.h,v 1.3 1993/11/07 17:47:52 wollman Exp $
*/
+#ifndef _NETINET_IN_SYSTM_H_
+#define _NETINET_IN_SYSTM_H_ 1
+
/*
* Miscellaneous internetwork
* definitions for kernel.
@@ -55,3 +58,4 @@ typedef u_long n_time; /* ms since 00:00 GMT, byte rev */
#ifdef KERNEL
n_time iptime();
#endif
+#endif /* _NETINET_IN_SYSTM_H_ */
diff --git a/sys/netinet/in_var.c b/sys/netinet/in_var.c
new file mode 100644
index 000000000000..4a292b000d6a
--- /dev/null
+++ b/sys/netinet/in_var.c
@@ -0,0 +1,354 @@
+/*
+ * Copyright (c) 1982, 1986, 1988 Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id: in_var.c,v 1.1 1993/12/09 03:43:29 wollman Exp $
+ */
+
+/*
+ * This file attempts to centralize all the various variables that have
+ * a hand in controlling the operation of IP and its ULPs.
+ */
+
+#include "param.h"
+#include "systm.h"
+#include "mbuf.h"
+#include "domain.h"
+#include "protosw.h"
+#include "socket.h"
+#include "time.h"
+#include "net/if.h"
+#include "net/route.h"
+
+#include "in.h"
+#include "in_systm.h"
+#include "ip.h"
+#include "in_pcb.h"
+#include "in_var.h"
+#include "ip_var.h"
+#include "ip_icmp.h"
+#include "icmp_var.h"
+
+
+/*
+ * IPFORWARDING controls whether the IP layer will forward packets received
+ * by us but not addressed to one of our addresses.
+ *
+ * IPSENDREDIRECTS controls whether the IP layer will send ICMP Redirect
+ * messages.
+ *
+ * GATEWAY turns both of these on, and also allocates more memory for some
+ * networking functions.
+ */
+
+#ifndef IPFORWARDING
+#ifdef GATEWAY
+#define IPFORWARDING 1 /* forward IP packets not for us */
+#else /* not GATEWAY */
+#define IPFORWARDING 0 /* don't forward IP packets not for us */
+#endif /* not GATEWAY */
+#endif /* not IPFORWARDING */
+
+/*
+ * NB: RFC 1122, ``Requirements for Internet Hosts: Communication Layers'',
+ * absolutely forbids hosts (which are not acting as gateways) from sending
+ * ICMP redirects.
+ */
+#ifndef IPSENDREDIRECTS
+#ifdef GATEWAY
+#define IPSENDREDIRECTS 1
+#else /* not GATEWAY */
+#define IPSENDREDIRECTS 0
+#endif /* not GATEWAY */
+#endif /* not IPSENDREDIRECTS */
+
+int ipforwarding = IPFORWARDING;
+int ipsendredirects = IPSENDREDIRECTS;
+#ifdef DIAGNOSTIC
+int ipprintfs = 0;
+#endif
+
+/*
+ * ip_protox[] maps from IP protocol number to an index in inetsw[].
+ */
+u_char ip_protox[IPPROTO_MAX];
+
+/*
+ * ipqmaxlen is the maximum length of the IP input queue.
+ * ipintrq is the queue itself.
+ */
+struct ifqueue ipintrq;
+int ipqmaxlen = IFQ_MAXLEN;
+
+/*
+ * the IP reassembly queue
+ */
+struct ipq ipq;
+
+/*
+ * in_ifaddr points to a linked list of IP interface addresses, managed
+ * by the code in in.c.
+ */
+struct in_ifaddr *in_ifaddr; /* first inet address */
+
+/*
+ * statistics for netstat and management
+ */
+struct ipstat ipstat;
+
+/*
+ * ip_id is the next IP packet id number to be assigned (used in fragmentation
+ * and reassembly).
+ */
+u_short ip_id;
+
+/*
+ * When acting as a gateway, the IP layer keeps track of how many packets
+ * are forwarded for each (in-ifp, out-ifp) pair. This code needs to get
+ * updated or junked now that interfaces can come and go like the wind.
+ * (in ip_input.c)
+ */
+#ifdef GATEWAY
+u_long *ip_ifmatrix;
+#endif
+
+/*
+ * ipaddr is a sockaddr_in used by various bits of code when they
+ * need to convert a `struct in_addr' to a `struct sockaddr_in'.
+ *
+ * ipforward_rt is a route used when forwarding packets. It functions
+ * as a route cache of order one, if you want to think of it that way.
+ */
+struct sockaddr_in ipaddr = { sizeof(ipaddr), AF_INET };
+struct route ipforward_rt;
+
+/*
+ * inetctlerrmap[] maps control input commands to errno values. 0 means
+ * don't signal error.
+ */
+u_char inetctlerrmap[PRC_NCMDS] = {
+ 0, /* ifdown */
+ 0, /* routedead */
+ 0, /* #2 */
+ 0, /* quench2 */
+ 0, /* quench */
+ EMSGSIZE, /* msgsize */
+ EHOSTDOWN, /* hostdead */
+ EHOSTUNREACH, /* hostunreach */
+ EHOSTUNREACH, /* unreachnet */
+ EHOSTUNREACH, /* unreachhost */
+ ECONNREFUSED, /* unreachproto */
+ ECONNREFUSED, /* unreachport */
+ EMSGSIZE, /* old needfrag */
+ EHOSTUNREACH, /* srcfail */
+ EHOSTUNREACH, /* netunknown */
+ EHOSTUNREACH, /* hostunknown */
+ EHOSTUNREACH, /* isolated */
+ ECONNREFUSED, /* net admin. prohibited */
+ ECONNREFUSED, /* host admin. prohibited */
+ EHOSTUNREACH, /* tos net unreachable */
+ EHOSTUNREACH, /* tos host unreachable */
+ 0, /* redirect net */
+ 0, /* redirect host */
+ 0, /* redirect tosnet */
+ 0, /* redirect toshost */
+ 0, /* time exceeded */
+ 0, /* reassembly timeout */
+ ENOPROTOOPT, /* parameter problem */
+ ENOPROTOOPT, /* required option missing */
+ 0, /* MTU changed */
+ /* NB: this means that this error will only
+ get propagated by in_mtunotify(), which
+ doesn't bother to check. */
+};
+
+/*
+ * SUBNETSARELOCAL determines where IP subnets are considered to be ``local''
+ * or not. This option is obsolete.
+ */
+#ifndef SUBNETSARELOCAL
+#define SUBNETSARELOCAL 1
+#endif
+int subnetsarelocal = SUBNETSARELOCAL;
+
+#ifdef MTUDISC
+/*
+ * MTUTIMER1 is the number of minutes to wait after having incremented
+ * the MTU estimate before trying again. MTUTIMER2 is the number
+ * of minutes to wait after having decremented the MTU estimate
+ * before trying to increment it.
+ */
+#ifndef MTUTIMER1
+#define MTUTIMER1 2
+#endif
+int in_mtutimer1 = MTUTIMER1;
+
+#ifndef MTUTIMER2
+#define MTUTIMER2 10
+#endif
+int in_mtutimer2 = MTUTIMER2;
+#endif /* MTUDISC */
+
+/*
+ * and a zero in_addr to make some code happy...
+ */
+struct in_addr zeroin_addr;
+
+/*
+ * ICMPPRINTFS enables some debugging printfs in ip_icmp.c.
+ *
+ * IPBROADCASTECHO controls whether ICMP Echo Reply packets are sent
+ * in response to ICMP Echo packets which were addressed to a multicast
+ * or broadcast address.
+ *
+ * IPMASKAGENT controls whether ICMP Mask Reply packets are sent.
+ * It should only be enabled on the machine which is the authoritative
+ * mask agent for a subnet.
+ */
+#ifdef ICMPPRINTFS
+int icmpprintfs = 0;
+#endif
+
+#ifndef IPBROADCASTECHO
+#define IPBROADCASTECHO 0
+#endif
+int ipbroadcastecho = IPBROADCASTECHO;
+
+#ifndef IPMASKAGENT
+#define IPMASKAGENT 0
+#endif
+int ipmaskagent = IPMASKAGENT;
+
+/*
+ * ICMP statistics
+ */
+struct icmpstat icmpstat;
+
+/*
+ * Yet Another sockaddr_in filled in by various routines when convenient.
+ */
+struct sockaddr_in icmpmask = { 8, 0 };
+
+/*
+ * Print out TCP debugging messages on the console.
+ */
+#ifdef TCPDEBUG
+int tcpconsdebug = 0;
+#endif
+
+#include "tcp.h"
+#include "tcp_fsm.h"
+#include "tcp_seq.h"
+#include "tcp_timer.h"
+#include "tcp_var.h"
+#include "tcpip.h"
+
+/*
+ * tcp_ttl is the default IP TTL for TCP segments.
+ * tcp_mssdflt is the default max segment size.
+ * tcp_rttdflt is the initial round trip time estimate when there is no RTT
+ * in the route.
+ */
+int tcp_ttl = TCP_TTL;
+int tcp_mssdflt = TCP_MSS;
+int tcp_rttdflt = TCPTV_SRTTDFLT / PR_SLOWHZ;
+
+/*
+ * When KPROF is defined (god only knows why), TCP keeps track of
+ * protocol requests in this matrix.
+ */
+#ifdef KPROF
+int tcp_acounts[TCP_NSTATES][PRU_NREQ];
+#endif
+
+/*
+ * tcp_keepidle is the a fraction of the length of non-response time in a
+ * in a keepalive situation after which TCP abandons the connection.
+ *
+ * tcp_keepintvl is the interval between keepalives.
+ *
+ * tcp_maxidle is the time after which a connection will be dropped in
+ * certain states. It is computed as `TCPTV_KEEPCNT * tcp_keepintvl'.
+ */
+int tcp_keepidle = TCPTV_KEEP_IDLE;
+int tcp_keepintvl = TCPTV_KEEPINTVL;
+int tcp_maxidle;
+
+/*
+ * tcp_sendspace and tcp_recvspace are the default send and receive window
+ * sizes, respectively. These are obsolescent (this information should
+ * be set by the route).
+ */
+#ifdef TCP_SMALLSPACE
+u_long tcp_sendspace = 1024*4;
+u_long tcp_recvspace = 1024*4;
+#else
+u_long tcp_sendspace = 1024*16;
+u_long tcp_recvspace = 1024*16;
+#endif /* TCP_SMALLSPACE */
+
+#include "udp.h"
+#include "udp_var.h"
+
+/*
+ * udpcksum tells whether to do UDP checksums. It should always be
+ * turned on, except as required for compatibility with ancient
+ * 4.2-based systems like SunOS 3.5 and Ultrix 2.0.
+ */
+#ifndef COMPAT_42
+int udpcksum = 1;
+#else
+int udpcksum = 0; /* XXX */
+#endif
+
+
+/*
+ * udp_ttl is the default IP TTL for UDP packets.
+ */
+int udp_ttl = UDP_TTL;
+
+/*
+ * UDP statistics for netstat.
+ */
+struct udpstat udpstat;
+
+/*
+ * udp_sendspace is the maximum datagram size the UDP layer is willing to
+ * attempt to transmit.
+ *
+ * udp_recvspace is the amount of buffer space the UDP layer will
+ * reserve for holding received packets.
+ */
+u_long udp_sendspace = 9216; /* really max datagram size */
+u_long udp_recvspace = 40 * (1024 + sizeof(struct sockaddr_in));
+ /* 40 1K datagrams */
+
+
diff --git a/sys/netinet/in_var.h b/sys/netinet/in_var.h
index 42c93fbac3e4..9e03a296adb4 100644
--- a/sys/netinet/in_var.h
+++ b/sys/netinet/in_var.h
@@ -31,9 +31,12 @@
* SUCH DAMAGE.
*
* from: @(#)in_var.h 7.6 (Berkeley) 6/28/90
- * $Id: in_var.h,v 1.2 1993/10/16 18:26:07 rgrimes Exp $
+ * $Id: in_var.h,v 1.6 1993/12/19 21:43:26 wollman Exp $
*/
+#ifndef _NETINET_IN_VAR_H_
+#define _NETINET_IN_VAR_H_ 1
+
/*
* Interface address, Internet version. One of these structures
* is allocated for each interface with an Internet address.
@@ -70,8 +73,76 @@ struct in_aliasreq {
*/
#define IA_SIN(ia) (&(((struct in_ifaddr *)(ia))->ia_addr))
+struct ip; /* forward declaration */
+typedef void in_input_t(struct mbuf *, int);
+/*
+ * Grrr... `netstat' expects to be able to include this file
+ * with KERNEL defined, to get all sorts of interesting structures,
+ * but without having to get all these prototypes. (Well, it's not
+ * really netstat's fault, but this should get fixed when KERNEL gets
+ * changed to _KERNEL.)
+ */
+struct socket;
+typedef int in_output_t(struct mbuf *, struct socket *);
+typedef void in_ctlinput_t(int, struct sockaddr *, struct ip *);
+typedef int in_ctloutput_t(int, struct socket *, int, int, struct mbuf **);
+
+/*
+ * This structure is a pun for `struct protosw'. The difference is that it
+ * has appropriate interprotocol hook prototypes for the Internet family.
+ */
+struct in_protosw {
+ short pr_type; /* socket type used for */
+ struct domain *pr_domain; /* domain protocol a member of */
+ short pr_protocol; /* protocol number */
+ short pr_flags; /* see below */
+/* protocol-protocol hooks */
+ in_input_t *pr_input;
+ in_output_t *pr_output;
+ in_ctlinput_t *pr_ctlinput;
+ in_ctloutput_t *pr_ctloutput;
+/* user-protocol hook */
+ int (*pr_usrreq)(struct socket *, int, struct mbuf *,
+ struct mbuf *, struct mbuf *, struct mbuf *);
+/* utility hooks */
+ void (*pr_init)(void); /* initialization hook */
+ void (*pr_fasttimo)(void); /* fast timeout (200ms) */
+ void (*pr_slowtimo)(void); /* slow timeout (500ms) */
+ void (*pr_drain)(void); /* flush any excess space possible */
+};
+
+
#ifdef KERNEL
-struct in_ifaddr *in_ifaddr;
-struct in_ifaddr *in_iaonnetof();
-struct ifqueue ipintrq; /* ip packet input queue */
-#endif
+extern struct in_ifaddr *in_ifaddr;
+extern struct in_ifaddr *in_iaonnetof(u_long);
+extern struct in_ifaddr *ifptoia(struct ifnet *);
+extern int in_ifinit(struct ifnet *, struct in_ifaddr *, struct sockaddr_in *, int);
+
+extern int in_cksum(struct mbuf *, int);
+
+extern struct ifqueue ipintrq; /* ip packet input queue */
+extern struct in_protosw inetsw[];
+extern struct domain inetdomain;
+extern u_char ip_protox[];
+extern u_char inetctlerrmap[];
+extern struct in_addr zeroin_addr;
+
+/* From in_var.c: */
+struct route;
+extern int subnetsarelocal; /* obsolescent */
+extern int ipqmaxlen;
+extern u_long *ip_ifmatrix;
+extern int ipforwarding;
+extern struct sockaddr_in ipaddr;
+extern struct route ipforward_rt;
+extern int ipsendredirects;
+
+
+#ifdef MTUDISC
+extern unsigned in_nextmtu(unsigned, int);
+extern int in_routemtu(struct route *);
+extern void in_mtureduce(struct in_addr, unsigned);
+extern void in_mtutimer(caddr_t, int);
+#endif /* MTUDISC */
+#endif /* KERNEL */
+#endif /* _NETINET_IN_VAR_H_ */
diff --git a/sys/netinet/ip.h b/sys/netinet/ip.h
index 2f5687e9f7fb..69b5bf0e428d 100644
--- a/sys/netinet/ip.h
+++ b/sys/netinet/ip.h
@@ -31,9 +31,12 @@
* SUCH DAMAGE.
*
* from: @(#)ip.h 7.10 (Berkeley) 6/28/90
- * $Id: ip.h,v 1.2 1993/10/16 18:26:08 rgrimes Exp $
+ * $Id: ip.h,v 1.3 1993/11/07 17:47:54 wollman Exp $
*/
+#ifndef _NETINET_IP_H_
+#define _NETINET_IP_H_ 1
+
/*
* Definitions for internet protocol version 4.
* Per RFC 791, September 1981.
@@ -165,3 +168,4 @@ struct ip_timestamp {
#define IPTTLDEC 1 /* subtracted when forwarding */
#define IP_MSS 576 /* default maximum segment size */
+#endif /* _NETINET_IP_H_ */
diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c
index b9a444c685b1..ed9b199e1db4 100644
--- a/sys/netinet/ip_icmp.c
+++ b/sys/netinet/ip_icmp.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)ip_icmp.c 7.15 (Berkeley) 4/20/91
- * $Id: ip_icmp.c,v 1.2 1993/10/16 18:26:11 rgrimes Exp $
+ * $Id: ip_icmp.c,v 1.6 1993/12/19 00:52:42 wollman Exp $
*/
#include "param.h"
@@ -58,27 +58,29 @@
* routines to turnaround packets back to the originator, and
* host table maintenance routines.
*/
-#ifdef ICMPPRINTFS
-int icmpprintfs = 0;
-#endif
-extern struct protosw inetsw[];
+#define satosin(sa) ((struct sockaddr_in *)(sa))
+static void icmp_reflect(struct mbuf *);
+static void icmp_send(struct mbuf *, struct mbuf *);
+
/*
* Generate an error packet of type error
* in response to bad packet ip.
*/
-/*VARARGS3*/
-icmp_error(n, type, code, dest)
+void
+icmp_error(n, type, code, dest, mtu)
struct mbuf *n;
int type, code;
struct in_addr dest;
+ int mtu; /* mtu for ICMP_UNREACH_SRCFRAG */
{
register struct ip *oip = mtod(n, struct ip *), *nip;
register unsigned oiplen = oip->ip_hl << 2;
register struct icmp *icp;
- register struct mbuf *m;
+ register struct mbuf *m = 0;
unsigned icmplen;
+ u_long oaddr;
#ifdef ICMPPRINTFS
if (icmpprintfs)
@@ -86,6 +88,61 @@ icmp_error(n, type, code, dest)
#endif
if (type != ICMP_REDIRECT)
icmpstat.icps_error++;
+
+ /*
+ * Quoth RFC 1122 (Requirements for Internet Hosts):
+ *
+ * An ICMP error message MUST NOT be sent as the result of
+ * receiving:
+ * - an ICMP error message, or
+ * - a datagram destined to an IP broadcast or IP multicast
+ * address, or
+ * - a datagram sent as a link-layer broadcast, or
+ * - a non-initial fragment, or
+ * - a datagram whose source address does not define a single
+ * host -- e.g., a zero address, a loopback address, a
+ * broadcast address, a multicast address, or a Class E
+ * address.
+ *
+ * NOTE: THESE RESTRICTIONS TAKE PRECEDENCE OVER ANY REQUIREMENT
+ * ELSEWHERE IN THIS DOCUMENT FOR SENDING ICMP ERROR MESSAGES.
+ */
+
+ oaddr = ntohl(oip->ip_src.s_addr);
+
+ /*
+ * Don't send error messages to multicast or broadcast addresses.
+ */
+ if (IN_MULTICAST(oaddr)
+ || oaddr == INADDR_BROADCAST
+ || n->m_flags & (M_BCAST | M_MCAST)) {
+ icmpstat.icps_oldmcast++;
+ goto freeit;
+ }
+
+ /*
+ * Don't send error messages to zero addresses or class E's.
+ */
+ if (IN_EXPERIMENTAL(oaddr)
+ || ! in_lnaof(oip->ip_src)
+ || ! in_netof(oip->ip_src)) {
+ icmpstat.icps_oldbadaddr++;
+ goto freeit;
+ }
+
+ /*
+ * Don't send error messages to loopback addresses.
+ * As a special (unauthorized) exception, we check to see
+ * if the packet came from the loopback interface. If it
+ * did, then we should allow the errors through, because
+ * the upper layers rely on them.
+ */
+ if(in_netof(oip->ip_src) == IN_LOOPBACKNET
+ && !(m->m_pkthdr.rcvif->if_flags & IFF_LOOPBACK)) {
+ icmpstat.icps_oldbadaddr++;
+ goto freeit;
+ }
+
/*
* Don't send error if not the first fragment of message.
* Don't error if the old packet protocol was ICMP
@@ -116,8 +173,12 @@ icmp_error(n, type, code, dest)
icp->icmp_type = type;
if (type == ICMP_REDIRECT)
icp->icmp_gwaddr = dest;
- else
+ else if (type == ICMP_UNREACH && code == ICMP_UNREACH_NEEDFRAG) {
+ icp->icmp_mtu = htons(mtu);
+ icp->icmp_mtuvoid = 0;
+ } else {
icp->icmp_void = 0;
+ }
if (type == ICMP_PARAMPROB) {
icp->icmp_pptr = code;
code = 0;
@@ -152,12 +213,11 @@ static struct sockproto icmproto = { AF_INET, IPPROTO_ICMP };
static struct sockaddr_in icmpsrc = { sizeof (struct sockaddr_in), AF_INET };
static struct sockaddr_in icmpdst = { sizeof (struct sockaddr_in), AF_INET };
static struct sockaddr_in icmpgw = { sizeof (struct sockaddr_in), AF_INET };
-struct sockaddr_in icmpmask = { 8, 0 };
-struct in_ifaddr *ifptoia();
/*
* Process a received ICMP message.
*/
+void
icmp_input(m, hlen)
register struct mbuf *m;
int hlen;
@@ -167,9 +227,8 @@ icmp_input(m, hlen)
int icmplen = ip->ip_len;
register int i;
struct in_ifaddr *ia;
- int (*ctlfunc)(), code;
- extern u_char ip_protox[];
- extern struct in_addr in_makeaddr();
+ in_ctlinput_t *ctlfunc;
+ int code;
/*
* Locate icmp structure in mbuf, and check
@@ -214,21 +273,35 @@ icmp_input(m, hlen)
switch (icp->icmp_type) {
case ICMP_UNREACH:
- if (code > 5)
+ if (code > ICMP_UNREACH_MAXCODE)
goto badcode;
- code += PRC_UNREACH_NET;
+ if (code == ICMP_UNREACH_NEEDFRAG) {
+#ifdef MTUDISC
+ /*
+ * Need to adjust the routing tables immediately;
+ * when ULP's get the PRC_MSGSIZE, it is their
+ * responsibility to notice it and update their
+ * internal ideas of MTU-derived protocol parameters.
+ */
+ in_mtureduce(icp->icmp_ip.ip_dst,
+ ntohs(icp->icmp_mtu));
+ code = PRC_MSGSIZE;
+#endif /* MTUDISC */
+ } else {
+ code += PRC_UNREACH_NET;
+ }
goto deliver;
case ICMP_TIMXCEED:
- if (code > 1)
+ if (code > ICMP_TIMXCEED_MAXCODE)
goto badcode;
code += PRC_TIMXCEED_INTRANS;
goto deliver;
case ICMP_PARAMPROB:
- if (code)
+ if (code > ICMP_PARAMPROB_MAXCODE)
goto badcode;
- code = PRC_PARAMPROB;
+ code += PRC_PARAMPROB;
goto deliver;
case ICMP_SOURCEQUENCH:
@@ -252,14 +325,36 @@ icmp_input(m, hlen)
icmpsrc.sin_addr = icp->icmp_ip.ip_dst;
if (ctlfunc = inetsw[ip_protox[icp->icmp_ip.ip_p]].pr_ctlinput)
(*ctlfunc)(code, (struct sockaddr *)&icmpsrc,
- (caddr_t) &icp->icmp_ip);
+ &icp->icmp_ip);
break;
badcode:
icmpstat.icps_badcode++;
break;
+ /*
+ * Always respond to pings from valid addresses.
+ * Don't respond to broadcast pings unless ipbroadcastecho
+ * is set. Don't respond to multicast pings unless
+ * ipbraodcastecho is set AND we support multicasting
+ * to begin with. (Per RFC 1122, we may choose either.)
+ */
case ICMP_ECHO:
+ {
+ u_long srcaddr = ntohl(icp->icmp_ip.ip_src.s_addr);
+#ifdef MULTICAST
+ if(IN_MULTICAST(srcaddr) && !ipbroadcastecho)
+ break;
+#else /* not MULTICAST */
+ if(IN_MULTICAST(srcaddr))
+ break;
+#endif /* not MULTICAST */
+ if((srcaddr == INADDR_BROADCAST
+ || m->m_flags & M_BCAST)
+ && !ipbroadcastecho)
+ break;
+ }
+
icp->icmp_type = ICMP_ECHOREPLY;
goto reflect;
@@ -273,16 +368,14 @@ icmp_input(m, hlen)
icp->icmp_ttime = icp->icmp_rtime; /* bogus, do later! */
goto reflect;
- case ICMP_IREQ:
-#define satosin(sa) ((struct sockaddr_in *)(sa))
- if (in_netof(ip->ip_src) == 0 &&
- (ia = ifptoia(m->m_pkthdr.rcvif)))
- ip->ip_src = in_makeaddr(in_netof(IA_SIN(ia)->sin_addr),
- in_lnaof(ip->ip_src));
- icp->icmp_type = ICMP_IREQREPLY;
- goto reflect;
-
+ /*
+ * Per RFC 1122, only respond to ICMP mask requests
+ * if the administrator has SPECIFICALLY CONFIGURED
+ * this host as an address mask agent.
+ */
case ICMP_MASKREQ:
+ if (!ipmaskagent)
+ break;
if (icmplen < ICMP_MASKLEN ||
(ia = ifptoia(m->m_pkthdr.rcvif)) == 0)
break;
@@ -320,8 +413,21 @@ reflect:
printf("redirect dst %x to %x\n", icp->icmp_ip.ip_dst,
icp->icmp_gwaddr);
#endif
+ /*
+ * Per RFC 1122, throw away redirects that
+ * suggested places we can't get to, or
+ * an interface other than the one the packet
+ * arrived on.
+ *
+ * It also says that we SHOULD throw away
+ * redirects that come from someone other
+ * than the current first-hop gateway for the
+ * specified destination.
+ *
+ * These are both implemented as general policy
+ * by rtredirect().
+ */
if (code == ICMP_REDIRECT_NET || code == ICMP_REDIRECT_TOSNET) {
- u_long in_netof();
icmpsrc.sin_addr =
in_makeaddr(in_netof(icp->icmp_ip.ip_dst), INADDR_ANY);
in_sockmaskof(icp->icmp_ip.ip_dst, &icmpmask);
@@ -369,6 +475,7 @@ freeit:
/*
* Reflect the ip packet back to the source
*/
+static void
icmp_reflect(m)
struct mbuf *m;
{
@@ -485,6 +592,7 @@ ifptoia(ifp)
* Send an icmp packet back to the ip level,
* after supplying a checksum.
*/
+static void
icmp_send(m, opts)
register struct mbuf *m;
struct mbuf *opts;
diff --git a/sys/netinet/ip_icmp.h b/sys/netinet/ip_icmp.h
index effd9e48812d..7f27f2df94c6 100644
--- a/sys/netinet/ip_icmp.h
+++ b/sys/netinet/ip_icmp.h
@@ -31,9 +31,12 @@
* SUCH DAMAGE.
*
* from: @(#)ip_icmp.h 7.5 (Berkeley) 6/28/90
- * $Id: ip_icmp.h,v 1.2 1993/10/16 18:26:12 rgrimes Exp $
+ * $Id: ip_icmp.h,v 1.4 1993/11/18 00:08:19 wollman Exp $
*/
+#ifndef _NETINET_IP_ICMP_H_
+#define _NETINET_IP_ICMP_H_ 1
+
/*
* Interface Control Message Protocol Definitions.
* Per RFC 792, September 1981.
@@ -53,6 +56,10 @@ struct icmp {
n_short icd_id;
n_short icd_seq;
} ih_idseq;
+ struct ih_mtu {
+ n_short imt_unused;
+ n_short imt_nhmtu;
+ } ih_mtu;
int ih_void;
} icmp_hun;
#define icmp_pptr icmp_hun.ih_pptr
@@ -60,6 +67,8 @@ struct icmp {
#define icmp_id icmp_hun.ih_idseq.icd_id
#define icmp_seq icmp_hun.ih_idseq.icd_seq
#define icmp_void icmp_hun.ih_void
+#define icmp_mtu icmp_hun.ih_mtu.imt_nhmtu
+#define icmp_mtuvoid icmp_hun.ih_mtu.imt_unused
union {
struct id_ts {
n_time its_otime;
@@ -107,17 +116,38 @@ struct icmp {
#define ICMP_UNREACH_PORT 3 /* bad port */
#define ICMP_UNREACH_NEEDFRAG 4 /* IP_DF caused drop */
#define ICMP_UNREACH_SRCFAIL 5 /* src route failed */
+#define ICMP_UNREACH_NETUNKNOWN 6 /* dest net unknown */
+#define ICMP_UNREACH_HSTUNKNOWN 7 /* dst host unknown */
+#define ICMP_UNREACH_ISOLATED 8 /* src host isolated*/
+/* next two are for administratively prohibited */
+#define ICMP_UNREACH_NETADMIN 9 /* dest net */
+#define ICMP_UNREACH_HOSTADMIN 10 /* dest host */
+/* next two are for TOS unreachables */
+#define ICMP_UNREACH_TOSNET 11 /* dest net+tos */
+#define ICMP_UNREACH_TOSHOST 12 /* dest host+tos */
+#define ICMP_UNREACH_MAXCODE 12
+
#define ICMP_SOURCEQUENCH 4 /* packet lost, slow down */
+
#define ICMP_REDIRECT 5 /* shorter route, codes: */
#define ICMP_REDIRECT_NET 0 /* for network */
#define ICMP_REDIRECT_HOST 1 /* for host */
#define ICMP_REDIRECT_TOSNET 2 /* for tos and net */
#define ICMP_REDIRECT_TOSHOST 3 /* for tos and host */
+#define ICMP_REDIRECT_MAXCODE 3
+
#define ICMP_ECHO 8 /* echo service */
+
#define ICMP_TIMXCEED 11 /* time exceeded, code: */
#define ICMP_TIMXCEED_INTRANS 0 /* ttl==0 in transit */
#define ICMP_TIMXCEED_REASS 1 /* ttl==0 in reass */
+#define ICMP_TIMXCEED_MAXCODE 1
+
#define ICMP_PARAMPROB 12 /* ip header bad */
+#define ICMP_PARAMPROB_GENERAL 0 /* generic problems */
+#define ICMP_PARAMPROB_REQDOPT 1 /* option misssing */
+#define ICMP_PARAMPROB_MAXCODE 1
+
#define ICMP_TSTAMP 13 /* timestamp request */
#define ICMP_TSTAMPREPLY 14 /* timestamp reply */
#define ICMP_IREQ 15 /* information request */
@@ -132,3 +162,12 @@ struct icmp {
(type) == ICMP_TSTAMP || (type) == ICMP_TSTAMPREPLY || \
(type) == ICMP_IREQ || (type) == ICMP_IREQREPLY || \
(type) == ICMP_MASKREQ || (type) == ICMP_MASKREPLY)
+
+#ifdef KERNEL
+struct mbuf;
+extern void icmp_error(struct mbuf *, int, int, struct in_addr, int);
+extern void icmp_input(struct mbuf *, int);
+n_time iptime(void);
+#endif
+
+#endif /* _NETINET_IP_ICMP_H_ */
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index c4e0ba1c6823..6c45aed63234 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)ip_input.c 7.19 (Berkeley) 5/25/91
- * $Id: ip_input.c,v 1.2 1993/10/16 18:26:14 rgrimes Exp $
+ * $Id: ip_input.c,v 1.8 1994/01/04 17:47:13 ache Exp $
*/
#include "param.h"
@@ -56,27 +56,12 @@
#include "ip_var.h"
#include "ip_icmp.h"
-#ifndef IPFORWARDING
-#ifdef GATEWAY
-#define IPFORWARDING 1 /* forward IP packets not for us */
-#else /* GATEWAY */
-#define IPFORWARDING 0 /* don't forward IP packets not for us */
-#endif /* GATEWAY */
-#endif /* IPFORWARDING */
-#ifndef IPSENDREDIRECTS
-#define IPSENDREDIRECTS 1
-#endif
-int ipforwarding = IPFORWARDING;
-int ipsendredirects = IPSENDREDIRECTS;
-#ifdef DIAGNOSTIC
-int ipprintfs = 0;
-#endif
-
-extern struct domain inetdomain;
-extern struct protosw inetsw[];
-u_char ip_protox[IPPROTO_MAX];
-int ipqmaxlen = IFQ_MAXLEN;
-struct in_ifaddr *in_ifaddr; /* first inet address */
+static void ip_freef(struct ipq *);
+static void ip_enq(struct ipasfrag *, struct ipasfrag *);
+static void ip_deq(struct ipasfrag *);
+static void save_rte(u_char *, struct in_addr);
+static void ip_forward(struct mbuf *, int);
+static struct ip *ip_reass(struct ipasfrag *, struct ipq *);
/*
* We need to save the IP options in case a protocol wants to respond
@@ -93,27 +78,28 @@ static struct ip_srcrt {
struct in_addr route[MAX_IPOPTLEN/sizeof(struct in_addr)];
} ip_srcrt;
-#ifdef GATEWAY
extern int if_index;
-u_long *ip_ifmatrix;
+#ifdef DIAGNOSTIC
+extern int ipprintfs;
#endif
/*
* IP initialization: fill in IP protocol switch table.
* All protocols not implemented in kernel go to raw IP protocol handler.
*/
+void
ip_init()
{
- register struct protosw *pr;
+ register struct in_protosw *pr;
register int i;
- pr = pffindproto(PF_INET, IPPROTO_RAW, SOCK_RAW);
+ pr = (struct in_protosw *)pffindproto(PF_INET, IPPROTO_RAW, SOCK_RAW);
if (pr == 0)
panic("ip_init");
for (i = 0; i < IPPROTO_MAX; i++)
ip_protox[i] = pr - inetsw;
- for (pr = inetdomain.dom_protosw;
- pr < inetdomain.dom_protoswNPROTOSW; pr++)
+ for (pr = (struct in_protosw *)inetdomain.dom_protosw;
+ pr < (struct in_protosw *)inetdomain.dom_protoswNPROTOSW; pr++)
if (pr->pr_domain->dom_family == PF_INET &&
pr->pr_protocol && pr->pr_protocol != IPPROTO_RAW)
ip_protox[pr->pr_protocol] = pr - inetsw;
@@ -127,14 +113,11 @@ ip_init()
#endif
}
-struct ip *ip_reass();
-struct sockaddr_in ipaddr = { sizeof(ipaddr), AF_INET };
-struct route ipforward_rt;
-
/*
* Ip input routine. Checksum and byte swap header. If fragmented
* try to reassemble. Process options. Pass to next level.
*/
+void
ipintr()
{
register struct ip *ip;
@@ -348,7 +331,7 @@ bad:
* reassembly of this datagram already exists, then it
* is given as fp; otherwise have to make a chain.
*/
-struct ip *
+static struct ip *
ip_reass(ip, fp)
register struct ipasfrag *ip;
register struct ipq *fp;
@@ -488,6 +471,7 @@ dropfrag:
* Free a fragment reassembly header and all
* associated datagrams.
*/
+static void
ip_freef(fp)
struct ipq *fp;
{
@@ -506,6 +490,7 @@ ip_freef(fp)
* Put an ip fragment on a reassembly chain.
* Like insque, but pointers in middle of structure.
*/
+static void
ip_enq(p, prev)
register struct ipasfrag *p, *prev;
{
@@ -519,6 +504,7 @@ ip_enq(p, prev)
/*
* To ip_enq as remque is to insque.
*/
+static void
ip_deq(p)
register struct ipasfrag *p;
{
@@ -532,6 +518,7 @@ ip_deq(p)
* if a timer expires on a reassembly
* queue, discard it.
*/
+void
ip_slowtimo()
{
register struct ipq *fp;
@@ -556,6 +543,7 @@ ip_slowtimo()
/*
* Drain off all datagram fragments.
*/
+void
ip_drain()
{
@@ -575,6 +563,7 @@ struct in_ifaddr *ip_rtaddr();
* Returns 1 if packet has been forwarded/freed,
* 0 if the packet should be processed further.
*/
+int
ip_dooptions(m)
struct mbuf *m;
{
@@ -748,7 +737,10 @@ ip_dooptions(m)
} else
return (0);
bad:
- icmp_error(m, type, code);
+ {
+ static struct in_addr fake;
+ icmp_error(m, type, code, fake, 0);
+ }
return (1);
}
@@ -784,6 +776,7 @@ ip_rtaddr(dst)
* Save incoming source route for use in replies,
* to be picked up later by ip_srcroute if the receiver is interested.
*/
+static void
save_rte(option, dst)
u_char *option;
struct in_addr dst;
@@ -878,6 +871,7 @@ ip_srcroute()
* will be moved, and return value is their length.
* XXX should be deleted; last arg currently ignored.
*/
+void
ip_stripoptions(m, mopt)
register struct mbuf *m;
struct mbuf *mopt;
@@ -897,15 +891,6 @@ ip_stripoptions(m, mopt)
ip->ip_hl = sizeof(struct ip) >> 2;
}
-u_char inetctlerrmap[PRC_NCMDS] = {
- 0, 0, 0, 0,
- 0, EMSGSIZE, EHOSTDOWN, EHOSTUNREACH,
- EHOSTUNREACH, EHOSTUNREACH, ECONNREFUSED, ECONNREFUSED,
- EMSGSIZE, EHOSTUNREACH, 0, 0,
- 0, 0, 0, 0,
- ENOPROTOOPT
-};
-
/*
* Forward a packet. If some error occurs return the sender
* an icmp packet. Note we can't always generate a meaningful
@@ -920,6 +905,7 @@ u_char inetctlerrmap[PRC_NCMDS] = {
* The srcrt parameter indicates whether the packet is being forwarded
* via a source route.
*/
+static void
ip_forward(m, srcrt)
struct mbuf *m;
int srcrt;
@@ -927,9 +913,10 @@ ip_forward(m, srcrt)
register struct ip *ip = mtod(m, struct ip *);
register struct sockaddr_in *sin;
register struct rtentry *rt;
- int error, type = 0, code;
+ int error, type = 0, code = 0;
struct mbuf *mcopy;
struct in_addr dest;
+ int mtu = 0;
dest.s_addr = 0;
#ifdef DIAGNOSTIC
@@ -944,7 +931,7 @@ ip_forward(m, srcrt)
}
HTONS(ip->ip_id);
if (ip->ip_ttl <= IPTTLDEC) {
- icmp_error(m, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS, dest);
+ icmp_error(m, ICMP_TIMXCEED, ICMP_TIMXCEED_INTRANS, dest, 0);
return;
}
ip->ip_ttl -= IPTTLDEC;
@@ -962,10 +949,12 @@ ip_forward(m, srcrt)
rtalloc(&ipforward_rt);
if (ipforward_rt.ro_rt == 0) {
- icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, dest);
+ icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, dest, 0);
return;
}
rt = ipforward_rt.ro_rt;
+ mtu = rt->rt_ifp->if_mtu;
+ /* salt away if's mtu */
}
/*
@@ -1065,5 +1054,5 @@ ip_forward(m, srcrt)
code = 0;
break;
}
- icmp_error(mcopy, type, code, dest);
+ icmp_error(mcopy, type, code, dest, mtu);
}
diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c
index ec5a5dd4527d..e9b459e870b8 100644
--- a/sys/netinet/ip_output.c
+++ b/sys/netinet/ip_output.c
@@ -31,10 +31,11 @@
* SUCH DAMAGE.
*
* from: @(#)ip_output.c 7.23 (Berkeley) 11/12/90
- * $Id: ip_output.c,v 1.3 1993/10/19 09:14:15 davidg Exp $
+ * $Id: ip_output.c,v 1.5 1993/12/19 00:52:45 wollman Exp $
*/
#include "param.h"
+#include "systm.h"
#include "malloc.h"
#include "mbuf.h"
#include "errno.h"
@@ -64,6 +65,7 @@ struct mbuf *ip_insertoptions();
* The mbuf chain containing the packet will be freed.
* The mbuf opt, if present, will not be freed.
*/
+int
ip_output(m0, opt, ro, flags)
struct mbuf *m0;
struct mbuf *opt;
@@ -345,6 +347,7 @@ ip_insertoptions(m, opt, phlen)
* Copy options from ip to jp,
* omitting those not copied during fragmentation.
*/
+int
ip_optcopy(ip, jp)
struct ip *ip, *jp;
{
@@ -378,6 +381,7 @@ ip_optcopy(ip, jp)
/*
* IP socket option processing.
*/
+int
ip_ctloutput(op, so, level, optname, mp)
int op;
struct socket *so;
@@ -386,7 +390,7 @@ ip_ctloutput(op, so, level, optname, mp)
{
register struct inpcb *inp = sotoinpcb(so);
register struct mbuf *m = *mp;
- register int optval;
+ register int optval = 0;
int error = 0;
if (level != IPPROTO_IP)
@@ -512,6 +516,7 @@ ip_ctloutput(op, so, level, optname, mp)
* Store in mbuf with pointer in pcbopt, adding pseudo-option
* with destination address if source routed.
*/
+int
#ifdef notyet
ip_pcbopts(optname, pcbopt, m)
int optname;
diff --git a/sys/netinet/ip_var.h b/sys/netinet/ip_var.h
index 9cdfbe1a5aee..47d76fe01b5a 100644
--- a/sys/netinet/ip_var.h
+++ b/sys/netinet/ip_var.h
@@ -31,9 +31,12 @@
* SUCH DAMAGE.
*
* from: @(#)ip_var.h 7.7 (Berkeley) 6/28/90
- * $Id: ip_var.h,v 1.2 1993/10/16 18:26:17 rgrimes Exp $
+ * $Id: ip_var.h,v 1.3 1993/11/07 17:48:00 wollman Exp $
*/
+#ifndef _NETINET_IP_VAR_H_
+#define _NETINET_IP_VAR_H_ 1
+
/*
* Overlay for ip header used by other protocols (tcp, udp).
*/
@@ -129,9 +132,10 @@ struct ipstat {
#define IP_ROUTETOIF SO_DONTROUTE /* bypass routing tables */
#define IP_ALLOWBROADCAST SO_BROADCAST /* can send broadcast packets */
-struct ipstat ipstat;
-struct ipq ipq; /* ip reass. queue */
-u_short ip_id; /* ip packet ctr, for ids */
+extern struct ipstat ipstat;
+extern struct ipq ipq; /* ip reass. queue */
+extern u_short ip_id; /* ip packet ctr, for ids */
struct mbuf *ip_srcroute();
#endif
+#endif /* _NETINET_IP_VAR_H_ */
diff --git a/sys/netinet/raw_ip.c b/sys/netinet/raw_ip.c
index 6734534962df..1618339176ae 100644
--- a/sys/netinet/raw_ip.c
+++ b/sys/netinet/raw_ip.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)raw_ip.c 7.8 (Berkeley) 7/25/90
- * $Id: raw_ip.c,v 1.2 1993/10/16 18:26:19 rgrimes Exp $
+ * $Id: raw_ip.c,v 1.4 1993/12/19 00:52:46 wollman Exp $
*/
#include "param.h"
@@ -55,15 +55,16 @@
/*
* Raw interface to IP protocol.
*/
+static struct sockaddr_in ripdst = { sizeof(ripdst), AF_INET };
+static struct sockaddr_in ripsrc = { sizeof(ripsrc), AF_INET };
+static struct sockproto ripproto = { PF_INET };
-struct sockaddr_in ripdst = { sizeof(ripdst), AF_INET };
-struct sockaddr_in ripsrc = { sizeof(ripsrc), AF_INET };
-struct sockproto ripproto = { PF_INET };
/*
* Setup generic address and protocol structures
* for raw_input routine, then pass them along with
* mbuf chain.
*/
+void
rip_input(m)
struct mbuf *m;
{
@@ -84,6 +85,7 @@ rip_input(m)
* Tack on options user may have setup with control call.
*/
#define satosin(sa) ((struct sockaddr_in *)(sa))
+int
rip_output(m, so)
register struct mbuf *m;
struct socket *so;
@@ -122,6 +124,7 @@ rip_output(m, so)
/*
* Raw IP socket option processing.
*/
+int
rip_ctloutput(op, so, level, optname, m)
int op;
struct socket *so;
@@ -190,6 +193,7 @@ rip_ctloutput(op, so, level, optname, m)
}
/*ARGSUSED*/
+int
rip_usrreq(so, req, m, nam, control)
register struct socket *so;
int req;
@@ -254,7 +258,7 @@ rip_usrreq(so, req, m, nam, control)
return (0);
}
}
- error = raw_usrreq(so, req, m, nam, control);
+ error = raw_usrreq(so, req, m, nam, control, 0);
if (error && (req == PRU_ATTACH) && so->so_pcb)
free(so->so_pcb, M_PCB);
diff --git a/sys/netinet/tcp.h b/sys/netinet/tcp.h
index 4ea9d576e0bf..c52883cbdfdf 100644
--- a/sys/netinet/tcp.h
+++ b/sys/netinet/tcp.h
@@ -31,9 +31,12 @@
* SUCH DAMAGE.
*
* from: @(#)tcp.h 7.7 (Berkeley) 6/28/90
- * $Id: tcp.h,v 1.2 1993/10/16 18:26:20 rgrimes Exp $
+ * $Id: tcp.h,v 1.3 1993/11/07 17:48:02 wollman Exp $
*/
+#ifndef _NETINET_TCP_H_
+#define _NETINET_TCP_H_ 1
+
typedef u_long tcp_seq;
/*
* TCP header.
@@ -83,3 +86,4 @@ struct tcphdr {
*/
#define TCP_NODELAY 0x01 /* don't delay send to coalesce packets */
#define TCP_MAXSEG 0x02 /* set maximum segment size */
+#endif /* _NETINET_TCP_H_ */
diff --git a/sys/netinet/tcp_debug.c b/sys/netinet/tcp_debug.c
index 7e141dbdee88..b361f0a125fb 100644
--- a/sys/netinet/tcp_debug.c
+++ b/sys/netinet/tcp_debug.c
@@ -31,16 +31,14 @@
* SUCH DAMAGE.
*
* from: @(#)tcp_debug.c 7.6 (Berkeley) 6/28/90
- * $Id: tcp_debug.c,v 1.2 1993/10/16 18:26:22 rgrimes Exp $
+ * $Id: tcp_debug.c,v 1.7 1994/01/24 05:12:31 davidg Exp $
*/
-#ifdef TCPDEBUG
/* load symbolic names */
#define PRUREQUESTS
#define TCPSTATES
#define TCPTIMERS
#define TANAMES
-#endif
#include "param.h"
#include "systm.h"
@@ -66,12 +64,13 @@
#include "tcpip.h"
#include "tcp_debug.h"
-#ifdef TCPDEBUG
-int tcpconsdebug = 0;
-#endif
+struct tcp_debug tcp_debug[TCP_NDEBUG];
+int tcp_debx;
+
/*
* Tcp debug routines
*/
+void
tcp_trace(act, ostate, tp, ti, req)
short act, ostate;
struct tcpcb *tp;
@@ -97,7 +96,6 @@ tcp_trace(act, ostate, tp, ti, req)
else
bzero((caddr_t)&td->td_ti, sizeof (*ti));
td->td_req = req;
-#ifdef TCPDEBUG
if (tcpconsdebug == 0)
return;
if (tp)
@@ -131,8 +129,9 @@ tcp_trace(act, ostate, tp, ti, req)
if (flags) {
#ifndef lint
char *cp = "<";
-#define pf(f) { if (ti->ti_flags&TH_/**/f) { printf("%s%s", cp, "f"); cp = ","; } }
+#define pf(f) { if (ti->ti_flags& TH_ ## f) { printf("%s" #f, cp); cp = ","; } }
pf(SYN); pf(ACK); pf(FIN); pf(RST); pf(PUSH); pf(URG);
+#undef pf
#endif
printf(">");
}
@@ -155,5 +154,4 @@ tcp_trace(act, ostate, tp, ti, req)
tp->snd_max);
printf("\tsnd_(wl1,wl2,wnd) (%x,%x,%x)\n",
tp->snd_wl1, tp->snd_wl2, tp->snd_wnd);
-#endif /* TCPDEBUG */
}
diff --git a/sys/netinet/tcp_debug.h b/sys/netinet/tcp_debug.h
index b6b134a77ad4..6316ed992dbe 100644
--- a/sys/netinet/tcp_debug.h
+++ b/sys/netinet/tcp_debug.h
@@ -31,9 +31,12 @@
* SUCH DAMAGE.
*
* from: @(#)tcp_debug.h 7.4 (Berkeley) 6/28/90
- * $Id: tcp_debug.h,v 1.2 1993/10/16 18:26:23 rgrimes Exp $
+ * $Id: tcp_debug.h,v 1.3 1993/11/07 17:48:04 wollman Exp $
*/
+#ifndef _NETINET_TCP_DEBUG_H_
+#define _NETINET_TCP_DEBUG_H_ 1
+
struct tcp_debug {
n_time td_time;
short td_act;
@@ -56,5 +59,6 @@ char *tanames[] =
#endif
#define TCP_NDEBUG 100
-struct tcp_debug tcp_debug[TCP_NDEBUG];
-int tcp_debx;
+extern struct tcp_debug tcp_debug[TCP_NDEBUG];
+extern int tcp_debx;
+#endif /* _NETINET_TCP_DEBUG_H_ */
diff --git a/sys/netinet/tcp_fsm.h b/sys/netinet/tcp_fsm.h
index f1c354e8cc62..e9bbe11a34d4 100644
--- a/sys/netinet/tcp_fsm.h
+++ b/sys/netinet/tcp_fsm.h
@@ -31,9 +31,12 @@
* SUCH DAMAGE.
*
* from: @(#)tcp_fsm.h 7.4 (Berkeley) 6/28/90
- * $Id: tcp_fsm.h,v 1.2 1993/10/16 18:26:24 rgrimes Exp $
+ * $Id: tcp_fsm.h,v 1.3 1993/11/07 17:48:05 wollman Exp $
*/
+#ifndef _NETINET_TCP_FSM_H_
+#define _NETINET_TCP_FSM_H_ 1
+
/*
* TCP FSM state definitions.
* Per RFC793, September, 1981.
@@ -74,7 +77,7 @@ u_char tcp_outflags[TCP_NSTATES] = {
#endif
#ifdef KPROF
-int tcp_acounts[TCP_NSTATES][PRU_NREQ];
+extern int tcp_acounts[TCP_NSTATES][PRU_NREQ];
#endif
#ifdef TCPSTATES
@@ -84,3 +87,4 @@ char *tcpstates[] = {
"LAST_ACK", "FIN_WAIT_2", "TIME_WAIT",
};
#endif
+#endif /* _NETINET_TCP_FSM_H_ */
diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c
index 4258b00d860a..e841fac4077c 100644
--- a/sys/netinet/tcp_input.c
+++ b/sys/netinet/tcp_input.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)tcp_input.c 7.25 (Berkeley) 6/30/90
- * $Id: tcp_input.c,v 1.2 1993/10/16 18:26:26 rgrimes Exp $
+ * $Id: tcp_input.c,v 1.9 1994/01/31 09:47:02 davidg Exp $
*/
#include "param.h"
@@ -57,16 +57,23 @@
#include "tcp_timer.h"
#include "tcp_var.h"
#include "tcpip.h"
+#ifdef TCPDEBUG
#include "tcp_debug.h"
+#endif
+
+static void tcp_dooptions(struct tcpcb *, struct mbuf *, struct tcpiphdr *);
+static void tcp_pulloutofband(struct socket *, struct tcpiphdr *, struct mbuf *);
+static void tcp_xmit_timer(struct tcpcb *);
int tcprexmtthresh = 3;
int tcppredack; /* XXX debugging: times hdr predict ok for acks */
int tcppreddat; /* XXX # times header prediction ok for data packets */
int tcppcbcachemiss;
+#ifdef TCPDEBUG
struct tcpiphdr tcp_saveti;
+#endif
struct inpcb *tcp_last_inpcb = &tcb;
-struct tcpcb *tcp_newtcpcb();
/*
* Insert segment ti into reassembly queue of tcp with
@@ -95,6 +102,7 @@ struct tcpcb *tcp_newtcpcb();
} \
}
+int
tcp_reass(tp, ti, m)
register struct tcpcb *tp;
register struct tcpiphdr *ti;
@@ -202,6 +210,7 @@ present:
* TCP input routine, follows pages 65-76 of the
* protocol specification dated September, 1981 very closely.
*/
+void
tcp_input(m, iphlen)
register struct mbuf *m;
int iphlen;
@@ -212,12 +221,14 @@ tcp_input(m, iphlen)
int len, tlen, off;
register struct tcpcb *tp = 0;
register int tiflags;
- struct socket *so;
+ struct socket *so = 0;
int todrop, acked, ourfinisacked, needoutput = 0;
- short ostate;
struct in_addr laddr;
int dropsocket = 0;
int iss = 0;
+#ifdef TCPDEBUG
+ short ostate = 0;
+#endif
tcpstat.tcps_rcvtotal++;
/*
@@ -321,10 +332,12 @@ findpcb:
goto drop;
so = inp->inp_socket;
if (so->so_options & (SO_DEBUG|SO_ACCEPTCONN)) {
+#ifdef TCPDEBUG
if (so->so_options & SO_DEBUG) {
ostate = tp->t_state;
tcp_saveti = *ti;
}
+#endif
if (so->so_options & SO_ACCEPTCONN) {
so = sonewconn(so, 0);
if (so == 0)
@@ -443,7 +456,17 @@ findpcb:
m->m_len -= sizeof(struct tcpiphdr);
sbappend(&so->so_rcv, m);
sorwakeup(so);
- tp->t_flags |= TF_DELACK;
+ /*
+ * If this is a small packet, then ACK now - with Nagel
+ * congestion avoidance sender won't send more until
+ * he gets an ACK.
+ */
+ if ((unsigned)ti->ti_len < tp->t_maxseg) {
+ tp->t_flags |= TF_ACKNOW;
+ tcp_output(tp);
+ } else {
+ tp->t_flags |= TF_DELACK;
+ }
return;
}
}
@@ -594,7 +617,7 @@ trimthenstep6:
* dropping FIN if necessary.
*/
ti->ti_seq++;
- if (ti->ti_len > tp->rcv_wnd) {
+ if ((u_long)ti->ti_len > (u_long)tp->rcv_wnd) {
todrop = ti->ti_len - tp->rcv_wnd;
m_adj(m, -todrop);
ti->ti_len = tp->rcv_wnd;
@@ -1057,7 +1080,7 @@ step6:
* but if two URG's are pending at once, some out-of-band
* data may creep in... ick.
*/
- if (ti->ti_urp <= ti->ti_len
+ if ((u_long)ti->ti_urp <= (u_long)ti->ti_len
#ifdef SO_OOBINLINE
&& (so->so_options & SO_OOBINLINE) == 0
#endif
@@ -1144,8 +1167,18 @@ dodata: /* XXX */
break;
}
}
+#ifdef TCPDEBUG
if (so->so_options & SO_DEBUG)
tcp_trace(TA_INPUT, ostate, tp, &tcp_saveti, 0);
+#endif
+
+ /*
+ * If this is a small packet, then ACK now - with Nagel
+ * congestion avoidance sender won't send more until
+ * he gets an ACK.
+ */
+ if (ti->ti_len && ((unsigned)ti->ti_len < tp->t_maxseg))
+ tp->t_flags |= TF_ACKNOW;
/*
* Return any desired output.
@@ -1197,8 +1230,10 @@ drop:
/*
* Drop space held by incoming segment and return.
*/
+#ifdef TCPDEBUG
if (tp && (tp->t_inpcb->inp_socket->so_options & SO_DEBUG))
tcp_trace(TA_DROP, ostate, tp, &tcp_saveti, 0);
+#endif
m_freem(m);
/* destroy temporarily created socket */
if (dropsocket)
@@ -1206,6 +1241,7 @@ drop:
return;
}
+static void
tcp_dooptions(tp, om, ti)
struct tcpcb *tp;
struct mbuf *om;
@@ -1253,6 +1289,7 @@ tcp_dooptions(tp, om, ti)
* It is still reflected in the segment length for
* sequencing purposes.
*/
+static void
tcp_pulloutofband(so, ti, m)
struct socket *so;
struct tcpiphdr *ti;
@@ -1283,6 +1320,7 @@ tcp_pulloutofband(so, ti, m)
* Collect new round-trip time estimate
* and update averages and current timeout.
*/
+static void
tcp_xmit_timer(tp)
register struct tcpcb *tp;
{
@@ -1366,7 +1404,7 @@ tcp_xmit_timer(tp)
* While looking at the routing entry, we also initialize other path-dependent
* parameters from pre-set or cached values in the routing entry.
*/
-
+int
tcp_mss(tp, offer)
register struct tcpcb *tp;
u_short offer;
@@ -1462,20 +1500,22 @@ tcp_mss(tp, offer)
bufsize = so->so_snd.sb_hiwat;
if (bufsize < mss)
mss = bufsize;
- else {
+ else
bufsize = min(bufsize, SB_MAX) / mss * mss;
- (void) sbreserve(&so->so_snd, bufsize);
- }
+
+ (void) sbreserve(&so->so_snd, bufsize);
tp->t_maxseg = mss;
#ifdef RTV_RPIPE
if ((bufsize = rt->rt_rmx.rmx_recvpipe) == 0)
#endif
bufsize = so->so_rcv.sb_hiwat;
- if (bufsize > mss) {
+ if (bufsize < mss)
+ bufsize = mss;
+ else
bufsize = min(bufsize, SB_MAX) / mss * mss;
- (void) sbreserve(&so->so_rcv, bufsize);
- }
+
+ (void) sbreserve(&so->so_rcv, bufsize);
}
tp->snd_cwnd = mss;
diff --git a/sys/netinet/tcp_output.c b/sys/netinet/tcp_output.c
index 5eb58fb5c9a3..d3e1b8d89cb6 100644
--- a/sys/netinet/tcp_output.c
+++ b/sys/netinet/tcp_output.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)tcp_output.c 7.22 (Berkeley) 8/31/90
- * $Id: tcp_output.c,v 1.2 1993/10/16 18:26:29 rgrimes Exp $
+ * $Id: tcp_output.c,v 1.4 1994/01/24 05:12:34 davidg Exp $
*/
#include "param.h"
@@ -57,10 +57,8 @@
#include "tcp_timer.h"
#include "tcp_var.h"
#include "tcpip.h"
+#ifdef TCPDEBUG
#include "tcp_debug.h"
-
-#ifdef notyet
-extern struct mbuf *m_copypack();
#endif
/*
@@ -71,6 +69,7 @@ u_char tcp_initopt[4] = { TCPOPT_MAXSEG, 4, 0x0, 0x0, };
/*
* Tcp output routine: figure out what should be sent and send it.
*/
+int
tcp_output(tp)
register struct tcpcb *tp;
{
@@ -79,7 +78,7 @@ tcp_output(tp)
int off, flags, error;
register struct mbuf *m;
register struct tcpiphdr *ti;
- u_char *opt;
+ u_char *opt = 0;
unsigned optlen, hdrlen;
int idle, sendalot;
@@ -434,11 +433,13 @@ send:
if (SEQ_GT(tp->snd_nxt + len, tp->snd_max))
tp->snd_max = tp->snd_nxt + len;
+#ifdef TCPDEBUG
/*
* Trace.
*/
if (so->so_options & SO_DEBUG)
tcp_trace(TA_OUTPUT, tp->t_state, tp, ti, 0);
+#endif
/*
* Fill in IP length and desired time to live and
@@ -460,7 +461,7 @@ send:
if (error) {
out:
if (error == ENOBUFS) {
- tcp_quench(tp->t_inpcb);
+ tcp_quench(tp->t_inpcb, 0);
return (0);
}
if ((error == EHOSTUNREACH || error == ENETDOWN)
@@ -486,6 +487,7 @@ out:
return (0);
}
+void
tcp_setpersist(tp)
register struct tcpcb *tp;
{
diff --git a/sys/netinet/tcp_seq.h b/sys/netinet/tcp_seq.h
index 437ea7076b19..266362515a04 100644
--- a/sys/netinet/tcp_seq.h
+++ b/sys/netinet/tcp_seq.h
@@ -31,9 +31,12 @@
* SUCH DAMAGE.
*
* from: @(#)tcp_seq.h 7.4 (Berkeley) 6/28/90
- * $Id: tcp_seq.h,v 1.2 1993/10/16 18:26:30 rgrimes Exp $
+ * $Id: tcp_seq.h,v 1.3 1993/11/07 17:48:07 wollman Exp $
*/
+#ifndef _NETINET_TCP_SEQ_H_
+#define _NETINET_TCP_SEQ_H_ 1
+
/*
* TCP sequence numbers are 32 bit integers operated
* on with modular arithmetic. These macros can be
@@ -59,5 +62,6 @@
#define TCP_ISSINCR (125*1024) /* increment for tcp_iss each second */
#ifdef KERNEL
-tcp_seq tcp_iss; /* tcp initial send seq # */
+extern tcp_seq tcp_iss; /* tcp initial send seq # */
#endif
+#endif /* _NETINET_TCP_SEQ_H_ */
diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c
index 8558464fb70a..eea64bb08ab1 100644
--- a/sys/netinet/tcp_subr.c
+++ b/sys/netinet/tcp_subr.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)tcp_subr.c 7.20 (Berkeley) 12/1/90
- * $Id: tcp_subr.c,v 1.2 1993/10/16 18:26:31 rgrimes Exp $
+ * $Id: tcp_subr.c,v 1.6 1993/12/19 00:52:50 wollman Exp $
*/
#include "param.h"
@@ -50,6 +50,7 @@
#include "in_systm.h"
#include "ip.h"
#include "in_pcb.h"
+#include "in_var.h"
#include "ip_var.h"
#include "ip_icmp.h"
#include "tcp.h"
@@ -59,16 +60,18 @@
#include "tcp_var.h"
#include "tcpip.h"
-/* patchable/settable parameters for tcp */
-int tcp_ttl = TCP_TTL;
-int tcp_mssdflt = TCP_MSS;
-int tcp_rttdflt = TCPTV_SRTTDFLT / PR_SLOWHZ;
+tcp_seq tcp_iss;
+struct inpcb tcb;
+struct tcpstat tcpstat;
-extern struct inpcb *tcp_last_inpcb;
+#ifdef MTUDISC
+int tcp_mtuchanged(struct inpcb *, int);
+#endif
/*
* Tcp initialization
*/
+void
tcp_init()
{
@@ -133,6 +136,7 @@ tcp_template(tp)
* In any case the ack and sequence number of the transmitted
* segment are as specified by the parameters.
*/
+void
tcp_respond(tp, ti, m, ack, seq, flags)
struct tcpcb *tp;
register struct tcpiphdr *ti;
@@ -227,6 +231,13 @@ tcp_newtcpcb(inp)
tp->snd_ssthresh = TCP_MAXWIN;
inp->inp_ip.ip_ttl = tcp_ttl;
inp->inp_ppcb = (caddr_t)tp;
+#ifdef MTUDISC
+ /*
+ * Enable Path MTU Discovery on this PCB.
+ */
+ inp->inp_mtunotify = tcp_mtuchanged;
+ inp->inp_flags |= INP_DISCOVERMTU;
+#endif /* MTUDISC */
return (tp);
}
@@ -286,7 +297,7 @@ tcp_close(tp)
if (SEQ_LT(tp->iss + so->so_snd.sb_hiwat * 16, tp->snd_max) &&
(rt = inp->inp_route.ro_rt) &&
((struct sockaddr_in *)rt_key(rt))->sin_addr.s_addr != INADDR_ANY) {
- register u_long i;
+ register u_long i = 0;
if ((rt->rt_rmx.rmx_locks & RTV_RTT) == 0) {
i = tp->t_srtt *
@@ -337,7 +348,7 @@ tcp_close(tp)
rt->rt_rmx.rmx_ssthresh = i;
}
}
-#endif RTV_RTT
+#endif /* RTV_RTT */
/* free the reassembly queue, if any */
t = tp->seg_next;
while (t != (struct tcpiphdr *)tp) {
@@ -359,6 +370,7 @@ tcp_close(tp)
return ((struct tcpcb *)0);
}
+void
tcp_drain()
{
@@ -369,6 +381,7 @@ tcp_drain()
* store error as soft error, but wake up user
* (for now, won't do anything until can select for soft error).
*/
+void
tcp_notify(inp, error)
register struct inpcb *inp;
int error;
@@ -380,18 +393,55 @@ tcp_notify(inp, error)
sowwakeup(inp->inp_socket);
}
+/*
+ * When we get a PRC_MSGSIZE error (generated by the ICMP layer upon
+ * receipt of an ICMP_UNREACH_NEEDFRAG message), we need to get the
+ * IP layer to check the cached MTU data that it has in its PCBs.
+ * If things have changed, this will cause us to receive a
+ * PRC_MTUCHANGED message for /every/ connection to the same
+ * destination; that is handled by he tcp_mtuchanged() function,
+ * below.
+ *
+ * In the immortal words of Ken and Dennis, ``You are not expected to
+ * understand this.''
+ */
+void
+tcp_checkmtu(struct inpcb *inp, int error) {
+#ifdef MTUDISC
+ /*
+ * XXX - this should also cause an immediate retransmission and
+ * slow start, since we know for a fact that the message we just sent
+ * got dropped on the floor. For now, just do what tcp_quench does.
+ */
+ tcp_quench(inp);
+ in_pcbmtu(inp);
+#endif /* MTUDISC */
+}
+
+#ifdef MTUDISC
+int /* grrr... should be void... */
+tcp_mtuchanged(struct inpcb *inp, int error) {
+ /* don't do anything just yet... */;
+}
+#endif /* MTUDISC */
+
+void
tcp_ctlinput(cmd, sa, ip)
int cmd;
struct sockaddr *sa;
register struct ip *ip;
{
register struct tcphdr *th;
- extern struct in_addr zeroin_addr;
- extern u_char inetctlerrmap[];
- int (*notify)() = tcp_notify, tcp_quench();
+ void (*notify)(struct inpcb *, int) = tcp_notify;
if (cmd == PRC_QUENCH)
notify = tcp_quench;
+#ifdef MTUDISC
+ else if (cmd == PRC_MSGSIZE)
+ notify = tcp_checkmtu;
+ else if (cmd == PRC_MTUCHANGED) /* just in case */
+ notify = tcp_mtuchanged;
+#endif /* MTUDISC */
else if ((unsigned)cmd > PRC_NCMDS || inetctlerrmap[cmd] == 0)
return;
if (ip) {
@@ -406,8 +456,10 @@ tcp_ctlinput(cmd, sa, ip)
* When a source quench is received, close congestion window
* to one segment. We will gradually open it again as we proceed.
*/
-tcp_quench(inp)
+void
+tcp_quench(inp, errno)
struct inpcb *inp;
+ int errno;
{
struct tcpcb *tp = intotcpcb(inp);
diff --git a/sys/netinet/tcp_timer.c b/sys/netinet/tcp_timer.c
index f43a507b861a..e22a337deeb3 100644
--- a/sys/netinet/tcp_timer.c
+++ b/sys/netinet/tcp_timer.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)tcp_timer.c 7.18 (Berkeley) 6/28/90
- * $Id: tcp_timer.c,v 1.2 1993/10/16 18:26:33 rgrimes Exp $
+ * $Id: tcp_timer.c,v 1.4 1993/12/19 00:52:52 wollman Exp $
*/
#include "param.h"
@@ -58,12 +58,10 @@
#include "tcp_var.h"
#include "tcpip.h"
-int tcp_keepidle = TCPTV_KEEP_IDLE;
-int tcp_keepintvl = TCPTV_KEEPINTVL;
-int tcp_maxidle;
/*
* Fast timeout routine for processing delayed acks
*/
+void
tcp_fasttimo()
{
register struct inpcb *inp;
@@ -88,6 +86,7 @@ tcp_fasttimo()
* Updates the timers in all active tcb's and
* causes finite state machine actions if timers expire.
*/
+void
tcp_slowtimo()
{
register struct inpcb *ip, *ipnxt;
@@ -113,7 +112,8 @@ tcp_slowtimo()
if (tp->t_timer[i] && --tp->t_timer[i] == 0) {
(void) tcp_usrreq(tp->t_inpcb->inp_socket,
PRU_SLOWTIMO, (struct mbuf *)0,
- (struct mbuf *)i, (struct mbuf *)0);
+ (struct mbuf *)i, (struct mbuf *)0,
+ (struct mbuf *)0);
if (ipnxt->inp_prev != ip)
goto tpgone;
}
@@ -135,6 +135,7 @@ tpgone:
/*
* Cancel all timers for TCP tp.
*/
+void
tcp_canceltimers(tp)
struct tcpcb *tp;
{
diff --git a/sys/netinet/tcp_timer.h b/sys/netinet/tcp_timer.h
index 05106e438448..21cd4c06959b 100644
--- a/sys/netinet/tcp_timer.h
+++ b/sys/netinet/tcp_timer.h
@@ -31,9 +31,12 @@
* SUCH DAMAGE.
*
* from: @(#)tcp_timer.h 7.8 (Berkeley) 6/28/90
- * $Id: tcp_timer.h,v 1.2 1993/10/16 18:26:35 rgrimes Exp $
+ * $Id: tcp_timer.h,v 1.4 1993/11/25 01:35:19 wollman Exp $
*/
+#ifndef _NETINET_TCP_TIMER_H_
+#define _NETINET_TCP_TIMER_H_ 1
+
/*
* Definitions of the TCP timers. These timers are counted
* down PR_SLOWHZ times a second.
@@ -106,7 +109,7 @@
#define TCP_MAXRXTSHIFT 12 /* maximum retransmits */
#ifdef TCPTIMERS
-char *tcptimers[] =
+const char *tcptimers[] =
{ "REXMT", "PERSIST", "KEEP", "2MSL" };
#endif
@@ -115,9 +118,9 @@ char *tcptimers[] =
*/
#define TCPT_RANGESET(tv, value, tvmin, tvmax) { \
(tv) = (value); \
- if ((tv) < (tvmin)) \
+ if ((u_long)(tv) < (u_long)(tvmin)) \
(tv) = (tvmin); \
- else if ((tv) > (tvmax)) \
+ else if ((u_long)(tv) > (u_long)(tvmax)) \
(tv) = (tvmax); \
}
@@ -128,3 +131,4 @@ extern int tcp_maxidle; /* time to drop after starting probes */
extern int tcp_ttl; /* time to live for TCP segs */
extern int tcp_backoff[];
#endif
+#endif /* _NETINET_TCP_TIMER_H_ */
diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c
index f0f51fcb40b8..b6f377690856 100644
--- a/sys/netinet/tcp_usrreq.c
+++ b/sys/netinet/tcp_usrreq.c
@@ -31,7 +31,7 @@
* SUCH DAMAGE.
*
* from: @(#)tcp_usrreq.c 7.15 (Berkeley) 6/28/90
- * $Id: tcp_usrreq.c,v 1.2 1993/10/16 18:26:36 rgrimes Exp $
+ * $Id: tcp_usrreq.c,v 1.5 1994/01/24 05:12:36 davidg Exp $
*/
#include "param.h"
@@ -58,13 +58,14 @@
#include "tcp_timer.h"
#include "tcp_var.h"
#include "tcpip.h"
+#ifdef TCPDEBUG
#include "tcp_debug.h"
+#endif
/*
* TCP protocol interface to socket abstraction.
*/
extern char *tcpstates[];
-struct tcpcb *tcp_newtcpcb();
/*
* Process a TCP user request for TCP tb. If this is a send request
@@ -72,13 +73,15 @@ struct tcpcb *tcp_newtcpcb();
* (called from the software clock routine), then timertype tells which timer.
*/
/*ARGSUSED*/
-tcp_usrreq(so, req, m, nam, control)
+int
+tcp_usrreq(so, req, m, nam, control, dummy)
struct socket *so;
int req;
struct mbuf *m, *nam, *control;
+ struct mbuf *dummy;
{
register struct inpcb *inp;
- register struct tcpcb *tp;
+ register struct tcpcb *tp = 0;
int s;
int error = 0;
int ostate;
@@ -331,12 +334,15 @@ tcp_usrreq(so, req, m, nam, control)
default:
panic("tcp_usrreq");
}
+#ifdef TCPDEBUG
if (tp && (so->so_options & SO_DEBUG))
tcp_trace(TA_USER, ostate, tp, (struct tcpiphdr *)0, req);
+#endif
splx(s);
return (error);
}
+int
tcp_ctloutput(op, so, level, optname, mp)
int op;
struct socket *so;
@@ -395,19 +401,12 @@ tcp_ctloutput(op, so, level, optname, mp)
return (error);
}
-#ifdef TCP_SMALLSPACE
-u_long tcp_sendspace = 1024*4;
-u_long tcp_recvspace = 1024*4;
-#else
-u_long tcp_sendspace = 1024*16;
-u_long tcp_recvspace = 1024*16;
-#endif /* TCP_SMALLSPACE */
-
/*
* Attach TCP protocol to socket, allocating
* internet protocol control block, tcp control block,
* bufer space, and entering LISTEN state if to accept connections.
*/
+int
tcp_attach(so)
struct socket *so;
{
diff --git a/sys/netinet/tcp_var.h b/sys/netinet/tcp_var.h
index ed51ec057191..8d70a9b26906 100644
--- a/sys/netinet/tcp_var.h
+++ b/sys/netinet/tcp_var.h
@@ -31,9 +31,12 @@
* SUCH DAMAGE.
*
* from: @(#)tcp_var.h 7.10 (Berkeley) 6/28/90
- * $Id: tcp_var.h,v 1.2 1993/10/16 18:26:38 rgrimes Exp $
+ * $Id: tcp_var.h,v 1.5 1993/12/19 00:52:54 wollman Exp $
*/
+#ifndef _NETINET_TCP_VAR_H_
+#define _NETINET_TCP_VAR_H_ 1
+
/*
* Kernel variables for tcp.
*/
@@ -211,9 +214,60 @@ struct tcpstat {
};
#ifdef KERNEL
-struct inpcb tcb; /* head of queue of active tcpcb's */
-struct tcpstat tcpstat; /* tcp statistics */
-struct tcpiphdr *tcp_template();
-struct tcpcb *tcp_close(), *tcp_drop();
-struct tcpcb *tcp_timers(), *tcp_disconnect(), *tcp_usrclosed();
+extern struct inpcb tcb; /* head of queue of active tcpcb's */
+extern struct tcpstat tcpstat; /* tcp statistics */
+
+/* From tcp_input.c: */
+extern int tcp_reass(struct tcpcb *, struct tcpiphdr *, struct mbuf *);
+extern void tcp_input(struct mbuf *, int);
+extern int tcp_mss(struct tcpcb *, int /*u_short*/);
+
+/* From tcp_output.c: */
+extern int tcp_output(struct tcpcb *);
+extern void tcp_setpersist(struct tcpcb *);
+
+/* From tcp_subr.c: */
+extern void tcp_init(void);
+extern struct tcpiphdr *tcp_template(struct tcpcb *);
+extern void tcp_respond(struct tcpcb *, struct tcpiphdr *, struct mbuf *,
+ tcp_seq, tcp_seq, int);
+extern struct tcpcb *tcp_newtcpcb(struct inpcb *);
+extern struct tcpcb *tcp_drop(struct tcpcb *, int);
+extern struct tcpcb *tcp_close(struct tcpcb *);
+extern void tcp_drain(void);
+extern void tcp_notify(struct inpcb *, int);
+#ifdef MTUDISC
+extern void tcp_checkmtu(struct inpcb *, int);
+extern void tcp_mtuchanged(struct inpcb *, int);
#endif
+extern void tcp_ctlinput(int, struct sockaddr *, struct ip *);
+extern void tcp_quench(struct inpcb *, int);
+
+/* From tcp_timer.c: */
+extern void tcp_fasttimo(void);
+extern void tcp_slowtimo(void);
+extern void tcp_canceltimers(struct tcpcb *);
+extern struct tcpcb *tcp_timers(struct tcpcb *, int);
+
+/* From tcp_usrreq.c: */
+extern int tcp_usrreq(struct socket *, int, struct mbuf *, struct mbuf *,
+ struct mbuf *, struct mbuf *);
+extern int tcp_ctloutput(int, struct socket *, int, int, struct mbuf **);
+extern int tcp_attach(struct socket *);
+extern struct tcpcb *tcp_disconnect(struct tcpcb *);
+extern struct tcpcb *tcp_usrclosed(struct tcpcb *);
+
+extern struct inpcb *tcp_last_inpcb;
+
+/* From in_var.c: */
+extern int tcp_ttl;
+extern int tcp_mssdflt;
+extern int tcp_rttdflt;
+extern int tcp_keepidle;
+extern int tcp_keepintvl;
+extern int tcp_maxidle;
+extern u_long tcp_sendspace;
+extern u_long tcp_recvspace;
+
+#endif /* KERNEL */
+#endif /* _NETINET_TCP_VAR_H_ */
diff --git a/sys/netinet/tcpip.h b/sys/netinet/tcpip.h
index 69e54216080b..cd17fa5cfbc7 100644
--- a/sys/netinet/tcpip.h
+++ b/sys/netinet/tcpip.h
@@ -31,9 +31,12 @@
* SUCH DAMAGE.
*
* from: @(#)tcpip.h 7.4 (Berkeley) 6/28/90
- * $Id: tcpip.h,v 1.2 1993/10/16 18:26:40 rgrimes Exp $
+ * $Id: tcpip.h,v 1.3 1993/11/07 17:48:12 wollman Exp $
*/
+#ifndef _NETINET_TCPIP_H_
+#define _NETINET_TCPIP_H_ 1
+
/*
* Tcp+ip header, after ip options removed.
*/
@@ -58,3 +61,4 @@ struct tcpiphdr {
#define ti_win ti_t.th_win
#define ti_sum ti_t.th_sum
#define ti_urp ti_t.th_urp
+#endif /* _NETINET_TCPIP_H_ */
diff --git a/sys/netinet/udp.h b/sys/netinet/udp.h
index d6ecd5c8f7c2..b4e00136bcc6 100644
--- a/sys/netinet/udp.h
+++ b/sys/netinet/udp.h
@@ -31,9 +31,12 @@
* SUCH DAMAGE.
*
* from: @(#)udp.h 7.4 (Berkeley) 6/28/90
- * $Id: udp.h,v 1.2 1993/10/16 18:26:41 rgrimes Exp $
+ * $Id: udp.h,v 1.3 1993/11/07 17:48:13 wollman Exp $
*/
+#ifndef _NETINET_UDP_H_
+#define _NETINET_UDP_H_ 1
+
/*
* Udp protocol header.
* Per RFC 768, September, 1981.
@@ -44,3 +47,4 @@ struct udphdr {
short uh_ulen; /* udp length */
u_short uh_sum; /* udp checksum */
};
+#endif /* _NETINET_UDP_H_ */
diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
index 726988226d78..44e244c31c95 100644
--- a/sys/netinet/udp_usrreq.c
+++ b/sys/netinet/udp_usrreq.c
@@ -31,10 +31,11 @@
* SUCH DAMAGE.
*
* from: @(#)udp_usrreq.c 7.20 (Berkeley) 4/20/91
- * $Id: udp_usrreq.c,v 1.2 1993/10/16 18:26:43 rgrimes Exp $
+ * $Id: udp_usrreq.c,v 1.7 1994/02/07 19:53:25 ache Exp $
*/
#include "param.h"
+#include "systm.h"
#include "malloc.h"
#include "mbuf.h"
#include "protosw.h"
@@ -47,6 +48,7 @@
#include "in.h"
#include "in_systm.h"
+#include "in_var.h"
#include "ip.h"
#include "in_pcb.h"
#include "ip_var.h"
@@ -54,27 +56,25 @@
#include "udp.h"
#include "udp_var.h"
-struct inpcb *udp_last_inpcb = &udb;
+struct inpcb udb; /* Can't be static, because of netstat want it */
+static struct inpcb *udp_last_inpcb = &udb;
+
+static void udp_detach(struct inpcb *);
/*
* UDP protocol implementation.
* Per RFC 768, August, 1980.
*/
+void
udp_init()
{
udb.inp_next = udb.inp_prev = &udb;
}
-#ifndef COMPAT_42
-int udpcksum = 1;
-#else
-int udpcksum = 0; /* XXX */
-#endif
-int udp_ttl = UDP_TTL;
-
-struct sockaddr_in udp_in = { sizeof(udp_in), AF_INET };
+static struct sockaddr_in udp_in = { sizeof(udp_in), AF_INET };
+void
udp_input(m, iphlen)
register struct mbuf *m;
int iphlen;
@@ -169,7 +169,10 @@ udp_input(m, iphlen)
}
*ip = save_ip;
ip->ip_len += iphlen;
- icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_PORT);
+ {
+ static struct in_addr fake;
+ icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_PORT, fake, 0);
+ }
return;
}
@@ -252,8 +255,10 @@ udp_saveopt(p, size, type)
* Notify a udp user of an asynchronous error;
* just wake up so that he can collect error status.
*/
+void
udp_notify(inp, errno)
register struct inpcb *inp;
+ int errno;
{
inp->inp_socket->so_error = errno;
@@ -261,6 +266,7 @@ udp_notify(inp, errno)
sowwakeup(inp->inp_socket);
}
+void
udp_ctlinput(cmd, sa, ip)
int cmd;
struct sockaddr *sa;
@@ -280,6 +286,7 @@ udp_ctlinput(cmd, sa, ip)
in_pcbnotify(&udb, sa, 0, zeroin_addr, 0, cmd, udp_notify);
}
+int
udp_output(inp, m, addr, control)
register struct inpcb *inp;
register struct mbuf *m;
@@ -288,7 +295,7 @@ udp_output(inp, m, addr, control)
register struct udpiphdr *ui;
register int len = m->m_pkthdr.len;
struct in_addr laddr;
- int s, error = 0;
+ int s = 0, error = 0;
if (control)
m_freem(control); /* XXX */
@@ -362,11 +369,8 @@ release:
return (error);
}
-u_long udp_sendspace = 9216; /* really max datagram size */
-u_long udp_recvspace = 40 * (1024 + sizeof(struct sockaddr_in));
- /* 40 1K datagrams */
-
/*ARGSUSED*/
+int
udp_usrreq(so, req, m, addr, control)
struct socket *so;
int req;
@@ -503,6 +507,7 @@ release:
return (error);
}
+static void
udp_detach(inp)
struct inpcb *inp;
{
diff --git a/sys/netinet/udp_var.h b/sys/netinet/udp_var.h
index bb97b4b5a64e..8bd35b466078 100644
--- a/sys/netinet/udp_var.h
+++ b/sys/netinet/udp_var.h
@@ -31,9 +31,12 @@
* SUCH DAMAGE.
*
* from: @(#)udp_var.h 7.7 (Berkeley) 6/28/90
- * $Id: udp_var.h,v 1.2 1993/10/16 18:26:44 rgrimes Exp $
+ * $Id: udp_var.h,v 1.4 1993/12/19 00:52:57 wollman Exp $
*/
+#ifndef _NETINET_UDP_VAR_H_
+#define _NETINET_UDP_VAR_H_ 1
+
/*
* UDP kernel structures and variables.
*/
@@ -70,6 +73,14 @@ struct udpstat {
#define UDP_TTL 30 /* default time to live for UDP packets */
#ifdef KERNEL
-struct inpcb udb;
-struct udpstat udpstat;
-#endif
+extern struct inpcb udb;
+extern struct udpstat udpstat;
+
+/* From in_var.h: */
+extern int udpcksum;
+extern int udp_ttl;
+extern u_long udp_sendspace;
+extern u_long udp_recvspace;
+
+#endif /* KERNEL */
+#endif /* _NETINET_UDP_VAR_H_ */