Update to 4.4-Lite networking code, with a few local changes.

This commit is contained in:
mycroft 1994-05-13 06:08:03 +00:00
parent 13e5e05cdb
commit c427e65091
67 changed files with 4101 additions and 3131 deletions

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,13 +30,10 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)argo_debug.h 7.4 (Berkeley) 5/6/91
* $Id: argo_debug.h,v 1.3 1993/05/20 05:26:42 cgd Exp $
* from: @(#)argo_debug.h 8.1 (Berkeley) 6/10/93
* $Id: argo_debug.h,v 1.4 1994/05/13 06:08:03 mycroft Exp $
*/
#ifndef _NETISO_ARGO_DEBUG_H_
#define _NETISO_ARGO_DEBUG_H_
/*****************************************************************
Copyright IBM Corporation 1987
@ -64,6 +61,9 @@ SOFTWARE.
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
*/
#ifndef _NETISO_ARGO_DEBUG_H_
#define _NETISO_ARGO_DEBUG_H_
#define dump_buf(a, b) Dump_buf((caddr_t)(a), (int)(b))
/***********************************************
@ -74,14 +74,14 @@ SOFTWARE.
* lint can't handle the flaky vacuous definitions
* of IFDEBUG, ENDDEBUG, etc.
*/
#endif defined(lint)
#endif /* defined(lint) */
/***********************************************
* DEBUG ON:
**********************************************/
#ifndef ARGO_DEBUG
#define ARGO_DEBUG
#endif ARGO_DEBUG
#endif /* ARGO_DEBUG */
#ifdef ARGO_DEBUG
@ -101,7 +101,7 @@ unsigned char argo_debug[128];
if(argo_debug[ascii]) {
#define ENDDEBUG ; }
#else ARGO_DEBUG
#else /* ARGO_DEBUG */
/***********************************************
* DEBUG OFF:
@ -109,11 +109,11 @@ unsigned char argo_debug[128];
#ifndef STAR
#define STAR *
#endif STAR
#endif /* STAR */
#define IFDEBUG(ascii) //*beginning of comment*/STAR
#define ENDDEBUG STAR/*end of comment*//
#endif ARGO_DEBUG
#endif /* ARGO_DEBUG */
/***********************************************
* ASSERT
@ -123,15 +123,15 @@ unsigned char argo_debug[128];
#ifndef lint
#define ASSERT(phrase) \
if( !(phrase) ) printf("ASSERTION NOT VALID at line %d file %s\n",__LINE__,__FILE__)
#else lint
#else /* lint */
#define ASSERT(phrase) /* phrase */
#endif lint
#endif /* lint */
#else ARGO_DEBUG
#else /* ARGO_DEBUG */
#define ASSERT(phrase) /* phrase */
#endif ARGO_DEBUG
#endif /* ARGO_DEBUG */
/***********************************************
@ -275,7 +275,7 @@ void dump_mbuf();
#define TPMT_PCB 0x23
#define TPMT_PERF 0x45
#else ARGO_DEBUG
#else /* ARGO_DEBUG */
#define TPMT_DATA MT_DATA
#define TPMT_RCVRTC MT_DATA
@ -288,6 +288,6 @@ void dump_mbuf();
#define TPMT_PCB MT_PCB
#define TPMT_PERF MT_PCB
#endif ARGO_DEBUG
#endif /* ARGO_DEBUG */
#endif /* !_NETISO_ARGO_DEBUG_H_ */
#endif /* _NETISO_ARGO_DEBUG_H_ */

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,13 +30,10 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)clnl.h 7.3 (Berkeley) 5/6/91
* $Id: clnl.h,v 1.3 1993/05/20 05:26:44 cgd Exp $
* from: @(#)clnl.h 8.1 (Berkeley) 6/10/93
* $Id: clnl.h,v 1.4 1994/05/13 06:08:05 mycroft Exp $
*/
#ifndef _NETISO_CLNL_H_
#define _NETISO_CLNL_H_
/***********************************************************
Copyright IBM Corporation 1987
@ -64,7 +61,5 @@ SOFTWARE.
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
*/
struct clnl_protosw {
int (*clnl_input)(); /* input routine */
void (*clnl_input)(); /* input routine */
};
#endif /* !_NETISO_CLNL_H_ */

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993, 1994
* The 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
@ -30,13 +30,10 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)clnp.h 7.8 (Berkeley) 5/6/91
* $Id: clnp.h,v 1.4 1994/04/12 08:15:38 cgd Exp $
* from: @(#)clnp.h 8.2 (Berkeley) 4/16/94
* $Id: clnp.h,v 1.5 1994/05/13 06:08:07 mycroft Exp $
*/
#ifndef _NETISO_CLNP_H_
#define _NETISO_CLNP_H_
/***********************************************************
Copyright IBM Corporation 1987
@ -279,12 +276,13 @@ struct clnp_optidx {
#define CLNP_NO_ER 0x020 /* do not generate ERs */
#define CLNP_SEND_RAW 0x080 /* send pkt as RAW DT rather than TP DT */
#define CLNP_NO_CKSUM 0x100 /* don't use clnp checksum */
#define CLNP_ECHO 0x200 /* fake echo function */
#define CLNP_ECHO 0x200 /* send echo request */
#define CLNP_NOCACHE 0x400 /* don't store cache information */
#define CLNP_ECHOR 0x800 /* send echo reply */
/* valid clnp flags */
#define CLNP_VFLAGS (CLNP_SEND_RAW|CLNP_NO_SEG|CLNP_NO_ER|CLNP_NO_CKSUM\
|CLNP_ECHO|CLNP_NOCACHE)
|CLNP_ECHO|CLNP_NOCACHE|CLNP_ECHOR)
/*
* Constants used by clnp
@ -401,7 +399,7 @@ extern float troll_random;
#define SN_MTU(ifp, rt) (((rt && rt->rt_rmx.rmx_mtu) ?\
rt->rt_rmx.rmx_mtu : clnp_badmtu(ifp, rt, __LINE__, __FILE__)))
#endif TROLL
#endif /* TROLL */
/*
* Macro to remove an address from a clnp header
@ -460,7 +458,5 @@ struct iso_addr *clnp_srcaddr();
struct mbuf *clnp_reass();
#ifdef TROLL
struct troll trollctl;
#endif TROLL
#endif KERNEL
#endif /* !_NETISO_CLNP_H_ */
#endif /* TROLL */
#endif /* KERNEL */

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,8 +30,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)clnp_debug.c 7.8 (Berkeley) 5/27/91
* $Id: clnp_debug.c,v 1.3 1993/12/18 00:42:25 mycroft Exp $
* from: @(#)clnp_debug.c 8.1 (Berkeley) 6/10/93
* $Id: clnp_debug.c,v 1.4 1994/05/13 06:08:10 mycroft Exp $
*/
/***********************************************************
@ -61,7 +61,6 @@ SOFTWARE.
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
*/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/mbuf.h>
#include <sys/domain.h>
@ -90,7 +89,7 @@ struct addr_osinet u_osinet = {
{0x00, 0x04},
{0x00, 0x02, 0x00, 0x01, 0x23, 0x42, 0x78, 0x20, 0x01, 0x05, 0x00}
};
#endif notdef
#endif /* notdef */
struct addr_rfc986 u_rfc986 = {
{0x00, 0x06},
{0x01, 0xc0, 0x0c, 0x0c, 0xab, 0x11}
@ -129,7 +128,7 @@ main()
a.isoa_len = 9;
printf("type bad idi: %s\n", clnp_iso_addrp(&a));
}
#endif TESTDEBUG
#endif /* TESTDEBUG */
unsigned int clnp_debug;
static char letters[] = "0123456789abcdef";
@ -141,14 +140,15 @@ static char letters[] = "0123456789abcdef";
char *
clnp_hexp(src, len, where)
char *src; /* src of data to print */
int len; /* lengthof src */
int len; /* lengthof src */
char *where; /* where to put data */
{
int i;
for (i=0; i<len; i++) {
*where++ = letters[src[i] >> 4];
*where++ = letters[src[i] & 0x0f];
register int j = ((u_char *)src)[i];
*where++ = letters[j >> 4];
*where++ = letters[j & 0x0f];
}
return where;
}
@ -227,7 +227,7 @@ struct iso_addr *isoa;
cp = clnp_hexp(&o986->o986_inetaddr[3], 1, cp);
*cp++ = DELIM;
cp = clnp_hexp(&o986->o986_upid, 1, cp);
#endif vax
#endif /* vax */
}
} break;
@ -236,7 +236,7 @@ struct iso_addr *isoa;
*cp++ = '?';
break;
}
#endif notdef
#endif /* notdef */
*cp = (char)0;
return(iso_addr_b);
@ -256,4 +256,4 @@ register struct sockaddr_iso *s;
return (iso_addr_b);
}
#endif ARGO_DEBUG
#endif /* ARGO_DEBUG */

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,8 +30,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)clnp_er.c 7.7 (Berkeley) 5/6/91
* $Id: clnp_er.c,v 1.3 1993/12/18 00:42:29 mycroft Exp $
* from: @(#)clnp_er.c 8.1 (Berkeley) 6/10/93
* $Id: clnp_er.c,v 1.4 1994/05/13 06:08:12 mycroft Exp $
*/
/***********************************************************

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,8 +30,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)clnp_frag.c 7.12 (Berkeley) 5/6/91
* $Id: clnp_frag.c,v 1.3 1993/12/18 00:42:32 mycroft Exp $
* from: @(#)clnp_frag.c 8.1 (Berkeley) 6/10/93
* $Id: clnp_frag.c,v 1.4 1994/05/13 06:08:13 mycroft Exp $
*/
/***********************************************************
@ -62,6 +62,7 @@ SOFTWARE.
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/domain.h>
#include <sys/protosw.h>
@ -242,7 +243,7 @@ struct rtentry *rt; /* route if direct ether */
error = troll_output(ifp, frag_hdr, first_hop, rt);
#else
error = (*ifp->if_output)(ifp, frag_hdr, first_hop, rt);
#endif TROLL
#endif /* TROLL */
/*
* Tough situation: if the error occured on the last
@ -281,7 +282,7 @@ struct rtentry *rt; /* route if direct ether */
num_bytes *= troll_random();
frag_size -= num_bytes;
}
#endif TROLL
#endif /* TROLL */
total_len -= frag_size;
if (!last_frag) {
frag_base += frag_size;
@ -854,4 +855,4 @@ struct rtentry *rt;
}
}
#endif TROLL
#endif /* TROLL */

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,8 +30,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)clnp_input.c 7.13 (Berkeley) 5/6/91
* $Id: clnp_input.c,v 1.5 1994/01/04 08:13:28 cgd Exp $
* from: @(#)clnp_input.c 8.1 (Berkeley) 6/10/93
* $Id: clnp_input.c,v 1.6 1994/05/13 06:08:15 mycroft Exp $
*/
/***********************************************************
@ -61,7 +61,6 @@ SOFTWARE.
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
*/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/mbuf.h>
#include <sys/domain.h>
@ -94,13 +93,10 @@ struct clnl_protosw clnl_protox[256];
int clnpqmaxlen = IFQ_MAXLEN; /* RAH? why is this a variable */
struct mbuf *clnp_data_ck();
int clnp_input();
int esis_input();
void clnp_input(), esis_input();
#ifdef ISO_X25ESIS
int x25esis_input();
#endif ISO_X25ESIS
void x25esis_input();
#endif /* ISO_X25ESIS */
/*
* FUNCTION: clnp_init
@ -114,6 +110,7 @@ int x25esis_input();
*
* NOTES:
*/
void
clnp_init()
{
register struct protosw *pr;
@ -279,6 +276,7 @@ next:
* TODO: I would like to make seg_part a pointer into the mbuf, but
* will it be correctly aligned?
*/
void
clnp_input(m, shp)
struct mbuf *m; /* ptr to first mbuf of pkt */
struct snpa_hdr *shp; /* subnetwork header */
@ -436,7 +434,7 @@ struct snpa_hdr *shp; /* subnetwork header */
if (need_afrin)
INCSTAT(cns_congest_rcvd);
}
#endif DECBIT
#endif /* DECBIT */
if (errcode != 0) {
clnp_discard(m, (char)errcode);
@ -534,60 +532,9 @@ struct snpa_hdr *shp; /* subnetwork header */
IFDEBUG(D_INPUT)
printf("clnp_input: echoing packet\n");
ENDDEBUG
{
/*
* Echo whole datagram in a new datagram, as per RFC 1139
* and ISO/IEC 8473-1, 2nd edition.
*/
static struct clnp_fixed ecr_template = {
ISO8473_CLNP, /* network identifier */
0, /* length */
ISO8473_V1, /* version */
CLNP_TTL, /* ttl */
CLNP_ECR|CNF_SEG_OK,/* type & flags */
0, /* segment length */
0 /* checksum */
};
struct clnp_segment *seg;
register struct mbuf *mnew;
/* Get header */
MGETHDR(mnew, M_DONTWAIT, MT_HEADER);
if (mnew == 0) {
m_freem(m);
INCSTAT(cns_odropped);
return;
}
mnew->m_next = m; /* chain in old datagram */
/* construct new CLNP PDU header */
clnp = mtod(mnew, struct clnp_fixed *);
*clnp = ecr_template;
hoff = (caddr_t)clnp + sizeof(struct clnp_fixed);
/* Insert addresses in reverse order from original PDU */
CLNP_INSERT_ADDR(hoff, src);
CLNP_INSERT_ADDR(hoff, dst);
/* Insert empty segmentation part */
seg = (struct clnp_segment*) hoff;
bzero((caddr_t)seg, sizeof(struct clnp_segment));
/* increment offset accordingly */
hoff += sizeof(struct clnp_segment);
/* Calculate length */
clnp->cnf_hdr_len = mnew->m_len = (u_char)(hoff - (caddr_t)clnp);
seg_len += clnp->cnf_hdr_len;
/* Stuff in packet at various places... */
seg->cng_tot_len = seg_len;
clnp->cnf_seglen_msb = (seg_len & 0xff00) >> 8;
clnp->cnf_seglen_lsb = (seg_len & 0x00ff);
/*
* Forward (umm... really send new PDU) back to sender
*/
clnp_forward(mnew, (int)seg_len, &src, (struct clnp_optidx *)0,
/*seg_off*/0, (struct snpa_hdr *)0);
}
(void)clnp_echoreply(m,
(clnp->cnf_type & CNF_SEG_OK ? (int)seg_part.cng_tot_len : seg_len),
&source, &target, oidxp);
break;
default:
@ -599,4 +546,4 @@ struct snpa_hdr *shp; /* subnetwork header */
break;
}
}
#endif ISO
#endif /* ISO */

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,8 +30,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)clnp_options.c 7.8 (Berkeley) 5/6/91
* $Id: clnp_options.c,v 1.3 1993/12/18 00:42:36 mycroft Exp $
* from: @(#)clnp_options.c 8.1 (Berkeley) 6/10/93
* $Id: clnp_options.c,v 1.4 1994/05/13 06:08:17 mycroft Exp $
*/
/***********************************************************
@ -63,7 +63,6 @@ SOFTWARE.
#ifdef ISO
#include <sys/types.h>
#include <sys/param.h>
#include <sys/mbuf.h>
#include <sys/domain.h>
@ -529,4 +528,4 @@ struct clnp_optidx *oidx; /* RETURN: filled in with option idx info */
ENDDEBUG
return(0);
}
#endif ISO
#endif /* ISO */

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,8 +30,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)clnp_output.c 7.10 (Berkeley) 5/6/91
* $Id: clnp_output.c,v 1.3 1993/12/18 00:42:38 mycroft Exp $
* from: @(#)clnp_output.c 8.1 (Berkeley) 6/10/93
* $Id: clnp_output.c,v 1.4 1994/05/13 06:08:20 mycroft Exp $
*/
/***********************************************************
@ -110,10 +110,20 @@ static struct clnp_fixed echo_template = {
0 /* checksum */
};
static struct clnp_fixed echor_template = {
ISO8473_CLNP, /* network identifier */
0, /* length */
ISO8473_V1, /* version */
CLNP_TTL, /* ttl */
CLNP_ECR|CNF_SEG_OK|CNF_ERR_OK, /* type */
0, /* segment length */
0 /* checksum */
};
#ifdef DECBIT
u_char qos_option[] = {CLNPOVAL_QOS, 1,
CLNPOVAL_GLOBAL|CLNPOVAL_SEQUENCING|CLNPOVAL_LOWDELAY};
#endif DECBIT
#endif /* DECBIT */
int clnp_id = 0; /* id for segmented dgrams */
@ -370,6 +380,8 @@ int flags; /* flags */
*clnp = raw_template;
} else if (flags & CLNP_ECHO) {
*clnp = echo_template;
} else if (flags & CLNP_ECHOR) {
*clnp = echor_template;
} else {
*clnp = dt_template;
}
@ -453,7 +465,7 @@ int flags; /* flags */
hdrlen += sizeof(qos_option);
m->m_len += sizeof(qos_option);
}
#endif DECBIT
#endif /* DECBIT */
/*
* If an options mbuf is present, concatenate a copy to the hdr mbuf.

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,8 +30,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)clnp_raw.c 7.8 (Berkeley) 5/6/91
* $Id: clnp_raw.c,v 1.3 1993/12/18 00:42:46 mycroft Exp $
* from: @(#)clnp_raw.c 8.1 (Berkeley) 6/10/93
* $Id: clnp_raw.c,v 1.4 1994/05/13 06:08:22 mycroft Exp $
*/
/***********************************************************
@ -80,7 +80,7 @@ SOFTWARE.
#include <netiso/clnp_stat.h>
#include <netiso/argo_debug.h>
#include <netiso/tp_user.h>/* XXX -- defines SOL_NETWORK */
#include <netiso/tp_user.h> /* XXX -- defines SOL_NETWORK */
struct sockproto rclnp_proto = { PF_ISO, 0 };
/*
@ -97,6 +97,7 @@ struct sockproto rclnp_proto = { PF_ISO, 0 };
* NOTES: The protocol field of rclnp_proto is set to zero indicating
* no protocol.
*/
void
rclnp_input(m, src, dst, hdrlen)
struct mbuf *m; /* ptr to packet */
struct sockaddr_iso *src; /* ptr to src address */
@ -108,13 +109,9 @@ int hdrlen; /* length (in bytes) of clnp header */
m_freem(m);
return;
}
#endif TROLL
#endif /* TROLL */
if (raw_input(m, &rclnp_proto, (struct sockaddr *)src,
(struct sockaddr *)dst) == 0) {
clnp_stat.cns_delivered--;
clnp_stat.cns_noproto++;
}
raw_input(m, &rclnp_proto, (struct sockaddr *)src, (struct sockaddr *)dst);
}
/*
@ -141,7 +138,7 @@ struct socket *so; /* socket to send from */
int error; /* return value of function */
int flags; /* flags for clnp_output */
if (0 == m0->m_flags & M_PKTHDR)
if (0 == (m0->m_flags & M_PKTHDR))
return (EINVAL);
/*
* Set up src address. If user has bound socket to an address, use it.
@ -209,7 +206,7 @@ struct mbuf **m; /* ptr to ptr to option data */
else switch (op) {
#else
switch (op) {
#endif SOL_NETWORK
#endif /* SOL_NETWORK */
case PRCO_SETOPT:
switch (optname) {
case CLNPOPT_FLAGS: {
@ -255,7 +252,7 @@ struct mbuf **m; /* ptr to ptr to option data */
error = EINVAL;
break;
}
#endif notdef
#endif /* notdef */
break;
default:
error = EINVAL;

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,13 +30,10 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)clnp_stat.h 7.4 (Berkeley) 5/6/91
* $Id: clnp_stat.h,v 1.3 1993/05/20 05:26:56 cgd Exp $
* from: @(#)clnp_stat.h 8.1 (Berkeley) 6/10/93
* $Id: clnp_stat.h,v 1.4 1994/05/13 06:08:24 mycroft Exp $
*/
#ifndef _NETISO_CLNP_STAT_H_
#define _NETISO_CLNP_STAT_H_
/***********************************************************
Copyright IBM Corporation 1987
@ -64,6 +61,9 @@ SOFTWARE.
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
*/
#ifndef _NETISO_CLNP_STAT_H_
#define _NETISO_CLNP_STAT_H_
struct clnp_stat {
int cns_total; /* total pkts received */
int cns_toosmall; /* fixed part of header too small */
@ -95,7 +95,7 @@ struct clnp_stat {
#ifdef INCSTAT
#undef INCSTAT
#endif INCSTAT
#endif /* INCSTAT */
#define INCSTAT(x) clnp_stat./**/x/**/++
#endif /* !_NETISO_CLNP_STAT_H_ */
#endif /* _NETISO_CLNP_STAT_H_ */

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,8 +30,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)clnp_subr.c 7.13 (Berkeley) 5/6/91
* $Id: clnp_subr.c,v 1.3 1993/12/18 00:42:51 mycroft Exp $
* from: @(#)clnp_subr.c 8.1 (Berkeley) 6/10/93
* $Id: clnp_subr.c,v 1.4 1994/05/13 06:08:26 mycroft Exp $
*/
/***********************************************************
@ -63,7 +63,6 @@ SOFTWARE.
#ifdef ISO
#include <sys/types.h>
#include <sys/param.h>
#include <sys/mbuf.h>
#include <sys/domain.h>
@ -184,7 +183,7 @@ register struct iso_addr *destp; /* ptr to destination address buffer */
else
return (caddr_t) 0;
}
#endif notdef
#endif /* notdef */
/*
* FUNCTION: clnp_ours
@ -363,7 +362,7 @@ struct snpa_hdr *inbound_shp; /* subnetwork header of inbound packet */
}
}
}
#endif DECBIT
#endif /* DECBIT */
/*
* Dispatch the datagram if it is small enough, otherwise fragment
@ -413,7 +412,7 @@ register struct iso_addr *dstp; /* ptr to dst addr */
return bufp;
}
#endif notdef
#endif /* notdef */
/*
* FUNCTION: clnp_route
@ -576,6 +575,42 @@ struct iso_addr *final_dst; /* final destination */
return error;
}
/*
* FUNCTION: clnp_echoreply
*
* PURPOSE: generate an echo reply packet and transmit
*
* RETURNS: result of clnp_output
*
* SIDE EFFECTS:
*/
clnp_echoreply(ec_m, ec_len, ec_src, ec_dst, ec_oidxp)
struct mbuf *ec_m; /* echo request */
int ec_len; /* length of ec */
struct sockaddr_iso *ec_src; /* src of ec */
struct sockaddr_iso *ec_dst; /* destination of ec (i.e., us) */
struct clnp_optidx *ec_oidxp; /* options index to ec packet */
{
struct isopcb isopcb;
int flags = CLNP_NOCACHE|CLNP_ECHOR;
int ret;
/* fill in fake isopcb to pass to output function */
bzero(&isopcb, sizeof(isopcb));
isopcb.isop_laddr = ec_dst;
isopcb.isop_faddr = ec_src;
/* forget copying the options for now. If implemented, need only
* copy record route option, but it must be reset to zero length */
ret = clnp_output(ec_m, &isopcb, ec_len, flags);
IFDEBUG(D_OUTPUT)
printf("clnp_echoreply: output returns %d\n", ret);
ENDDEBUG
return ret;
}
/*
* FUNCTION: clnp_badmtu
*
@ -591,10 +626,10 @@ struct rtentry *rt; /* dst route */
int line; /* where the dirty deed occured */
char *file; /* where the dirty deed occured */
{
printf("sending on route %x with no mtu, line %s of file %s\n",
printf("sending on route 0x%x with no mtu, line %d of file %s\n",
rt, line, file);
#ifdef ARGO_DEBUG
printf("route dst is");
printf("route dst is ");
dump_isoaddr(rt_key(rt));
#endif
return ifp->if_mtu;
@ -619,4 +654,4 @@ u_int len; /* number of bytes */
while (len--)
*(to + len) = *(from + len);
}
#endif ISO
#endif /* ISO */

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,8 +30,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)clnp_timer.c 7.5 (Berkeley) 5/6/91
* $Id: clnp_timer.c,v 1.3 1993/12/18 00:42:54 mycroft Exp $
* from: @(#)clnp_timer.c 8.1 (Berkeley) 6/10/93
* $Id: clnp_timer.c,v 1.4 1994/05/13 06:08:28 mycroft Exp $
*/
/***********************************************************
@ -142,6 +142,7 @@ register struct clnp_fragl *cfh; /* fragment header to delete */
*
* NOTES:
*/
void
clnp_slowtimo()
{
register struct clnp_fragl *cfh = clnp_frags;
@ -170,6 +171,7 @@ clnp_slowtimo()
* NOTES:
* TODO: should send back ER
*/
void
clnp_drain()
{
register struct clnp_fragl *cfh = clnp_frags;

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 1989 Regents of the University of California.
* All rights reserved.
* Copyright (c) 1989, 1993
* The 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
@ -30,8 +30,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)cltp_usrreq.c 7.6 (Berkeley) 6/27/91
* $Id: cltp_usrreq.c,v 1.3 1993/12/18 00:42:56 mycroft Exp $
* from: @(#)cltp_usrreq.c 8.1 (Berkeley) 6/10/93
* $Id: cltp_usrreq.c,v 1.4 1994/05/13 06:08:30 mycroft Exp $
*/
#ifndef CLTPOVAL_SRC /* XXX -- till files gets changed */
@ -59,6 +59,7 @@
* CLTP protocol implementation.
* Per ISO 8602, December, 1987.
*/
void
cltp_init()
{
@ -69,6 +70,7 @@ int cltp_cksum = 1;
/* ARGUSED */
void
cltp_input(m0, srcsa, dstsa, cons_channel, output)
struct mbuf *m0;
struct sockaddr *srcsa, *dstsa;
@ -148,7 +150,6 @@ bad:
m_freem(dtom(src));
if (m0)
m_freem(m0);
return 0;
}
/*
@ -163,6 +164,7 @@ cltp_notify(isop)
sowwakeup(isop->isop_socket);
}
void
cltp_ctlinput(cmd, sa)
int cmd;
struct sockaddr *sa;
@ -250,12 +252,6 @@ bad:
return (error);
}
#ifndef TP_LOCAL
/* XXXX should go in iso.h maybe? from tp_param.h, in any case */
#define TP_LOCAL 22
#define TP_FOREIGN 33
#endif
u_long cltp_sendspace = 9216; /* really max datagram size */
u_long cltp_recvspace = 40 * (1024 + sizeof(struct sockaddr_iso));
/* 40 1K datagrams */
@ -267,7 +263,7 @@ cltp_usrreq(so, req, m, nam, control)
int req;
struct mbuf *m, *nam, *control;
{
struct isopcb *isop = sotoisopcb(so);
register struct isopcb *isop = sotoisopcb(so);
int s, error = 0;
if (req == PRU_CONTROL)
@ -371,11 +367,15 @@ cltp_usrreq(so, req, m, nam, control)
break;
case PRU_SOCKADDR:
iso_getnetaddr(isop, nam, TP_LOCAL);
if (isop->isop_laddr)
bcopy((caddr_t)isop->isop_laddr, mtod(m, caddr_t),
nam->m_len = isop->isop_laddr->siso_len);
break;
case PRU_PEERADDR:
iso_getnetaddr(isop, nam, TP_FOREIGN);
if (isop->isop_faddr)
bcopy((caddr_t)isop->isop_faddr, mtod(m, caddr_t),
nam->m_len = isop->isop_faddr->siso_len);
break;
case PRU_SENSE:

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 1989 Regents of the University of California.
* All rights reserved.
* Copyright (c) 1989, 1993
* The 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
@ -30,13 +30,10 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)cltp_var.h 7.3 (Berkeley) 6/28/90
* $Id: cltp_var.h,v 1.3 1993/05/20 05:27:01 cgd Exp $
* from: @(#)cltp_var.h 8.1 (Berkeley) 6/10/93
* $Id: cltp_var.h,v 1.4 1994/05/13 06:08:31 mycroft Exp $
*/
#ifndef _NETISO_CLTP_VAR_H_
#define _NETISO_CLTP_VAR_H_
#define UD_TPDU_type 0x40 /* packet type */
#define CLTPOVAL_SRC 0xc1 /* Source TSAP -- required */
@ -56,5 +53,3 @@ struct cltpstat {
struct isopcb cltb;
struct cltpstat cltpstat;
#endif
#endif /* !_NETISO_CLTP_VAR_H_ */

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,13 +30,10 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)cons.h 7.3 (Berkeley) 5/6/91
* $Id: cons.h,v 1.3 1993/05/20 05:27:02 cgd Exp $
* from: @(#)cons.h 8.1 (Berkeley) 6/10/93
* $Id: cons.h,v 1.4 1994/05/13 06:08:33 mycroft Exp $
*/
#ifndef _NETISO_CONS_H_
#define _NETISO_CONS_H_
/***********************************************************
Copyright IBM Corporation 1987
@ -85,11 +82,9 @@ struct dte_addr {
#define CONS_NOT_DGM 0x0
#ifndef PRC_NCMDS
#include "protosw.h"
#endif PRC_NCMDS
#include <sys/protosw.h>
#endif /* PRC_NCMDS */
#define PRC_CONS_SEND_DONE 2 /* something unused in protosw.h */
#endif KERNEL
#endif /* !_NETISO_CONS_H_ */
#endif /* KERNEL */

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,13 +30,10 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)cons_pcb.h 7.4 (Berkeley) 5/6/91
* $Id: cons_pcb.h,v 1.3 1993/05/20 05:27:04 cgd Exp $
* from: @(#)cons_pcb.h 8.1 (Berkeley) 6/10/93
* $Id: cons_pcb.h,v 1.4 1994/05/13 06:08:34 mycroft Exp $
*/
#ifndef _NETISO_CONS_PCB_H_
#define _NETISO_CONS_PCB_H_
/***********************************************************
Copyright IBM Corporation 1987
@ -80,9 +77,9 @@ SOFTWARE.
#ifndef ARGO_DEBUG
#define X25_TTL 600 /* 5 min */
#else ARGO_DEBUG
#else /* ARGO_DEBUG */
#define X25_TTL 120 /* 1 min */
#endif ARGO_DEBUG
#endif /* ARGO_DEBUG */
struct cons_pcb {
struct isopcb _co_isopcb;
@ -192,6 +189,4 @@ struct e_clear_data {
#ifdef KERNEL
#define IncStat(XYZ) cons_stat.XYZ++
#endif KERNEL
#endif /* !_NETISO_CONS_PCB_H_ */
#endif /* KERNEL */

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,13 +30,10 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)eonvar.h 7.5 (Berkeley) 5/6/91
* $Id: eonvar.h,v 1.3 1993/05/20 05:27:05 cgd Exp $
* from: @(#)eonvar.h 8.1 (Berkeley) 6/10/93
* $Id: eonvar.h,v 1.4 1994/05/13 06:08:36 mycroft Exp $
*/
#ifndef _NETISO_EONVAR_H_
#define _NETISO_EONVAR_H_
/***********************************************************
Copyright IBM Corporation 1987
@ -172,5 +169,3 @@ struct eon_llinfo {
};
#define el_iphdr el_ei.ei_ip
#define el_eonhdr el_ei.ei_eh
#endif /* !_NETISO_EONVAR_H_ */

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,8 +30,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)esis.c 7.19 (Berkeley) 6/27/91
* $Id: esis.c,v 1.4 1993/12/18 00:42:59 mycroft Exp $
* from: @(#)esis.c 8.1 (Berkeley) 6/10/93
* $Id: esis.c,v 1.5 1994/05/13 06:08:39 mycroft Exp $
*/
/***********************************************************
@ -63,7 +63,6 @@ SOFTWARE.
#ifdef ISO
#include <sys/types.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
@ -118,6 +117,12 @@ extern char all_es_snpa[], all_is_snpa[];
(m) = (m)->m_next;\
(cp) = mtod((m), caddr_t);\
}
void esis_input(), isis_input();
#ifdef ISO_X25ESIS
void x25esis_input();
#endif /* ISO_X25ESIS */
/*
* FUNCTION: esis_init
*
@ -129,13 +134,10 @@ extern char all_es_snpa[], all_is_snpa[];
*
* NOTES:
*/
void
esis_init()
{
extern struct clnl_protosw clnl_protox[256];
int esis_input(), isis_input();
#ifdef ISO_X25ESIS
int x25esis_input();
#endif ISO_X25ESIS
esis_pcb.rcb_next = esis_pcb.rcb_prev = &esis_pcb;
llinfo_llc.lc_next = llinfo_llc.lc_prev = &llinfo_llc;
@ -147,7 +149,7 @@ esis_init()
clnl_protox[ISO10589_ISIS].clnl_input = isis_input;
#ifdef ISO_X25ESIS
clnl_protox[ISO9542X25_ESIS].clnl_input = x25esis_input;
#endif ISO_X25ESIS
#endif /* ISO_X25ESIS */
}
/*
@ -243,6 +245,7 @@ release:
*
* NOTES:
*/
void
esis_input(m0, shp)
struct mbuf *m0; /* ptr to first mbuf of pkt */
struct snpa_hdr *shp; /* subnetwork header */
@ -444,7 +447,7 @@ struct rtentry *rt; /* snpa cache info regarding next hop of
siso.siso_nlen = 6 + 1; /* should be taken from snpa_hdr */
/* +1 is for AFI */
bcopy(inbound_shp->snh_shost, siso.siso_data + 1, 6);
(ifp->if_output)(ifp, m0, &siso, 0);
(ifp->if_output)(ifp, m0, (struct sockaddr *)&siso, 0);
}
/*
@ -922,7 +925,7 @@ struct iso_addr *isoa;
siso.siso_data[0] = AFI_SNA;
siso.siso_nlen = sn_len + 1;
bcopy(sn_addr, siso.siso_data + 1, (unsigned)sn_len);
(ifp->if_output)(ifp, m0, &siso, 0);
(ifp->if_output)(ifp, m0, (struct sockaddr *)&siso, 0);
}
/*
@ -936,6 +939,7 @@ struct iso_addr *isoa;
*
* NOTES:
*/
void
isis_input(m0, shp)
struct mbuf *m0; /* ptr to first mbuf of pkt */
struct snpa_hdr *shp; /* subnetwork header */
@ -968,9 +972,10 @@ struct snpa_hdr *shp; /* subnetwork header */
}
if (mm = m_copy(m0, 0, M_COPYALL)) { /*can't block at interrupt level */
if (sbappendaddr(&rp->rcb_socket->so_rcv,
&esis_dl, mm, (struct mbuf *)0) != 0)
(struct sockaddr *)&esis_dl, mm,
(struct mbuf *)0) != 0) {
sorwakeup(rp->rcb_socket);
else {
} else {
IFDEBUG(D_ISISINPUT)
printf("Error in sbappenaddr, mm = 0x%x\n", mm);
ENDDEBUG
@ -979,7 +984,7 @@ struct snpa_hdr *shp; /* subnetwork header */
}
}
if (first_rp && sbappendaddr(&first_rp->rcb_socket->so_rcv,
&esis_dl, m0, (struct mbuf *)0) != 0) {
(struct sockaddr *)&esis_dl, m0, (struct mbuf *)0) != 0) {
sorwakeup(first_rp->rcb_socket);
return;
}
@ -996,7 +1001,7 @@ struct mbuf *m;
int error = 0;
unsigned sn_len;
ifa = ifa_ifwithnet(sdl); /* extract ifp from sockaddr_dl */
ifa = ifa_ifwithnet((struct sockaddr *)sdl); /* get ifp from sdl */
if (ifa == 0) {
IFDEBUG(D_ISISOUTPUT)
printf("isis_output: interface not found\n");
@ -1049,6 +1054,7 @@ release:
* The loop through iso_ifaddr is stupid because
* back in if_down, we knew the ifp...
*/
void
esis_ctlinput(req, siso)
int req; /* request: we handle only PRC_IFDOWN */
struct sockaddr_iso *siso; /* address of ifp */
@ -1062,4 +1068,4 @@ struct sockaddr_iso *siso; /* address of ifp */
}
}
#endif ISO
#endif /* ISO */

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,13 +30,10 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)esis.h 7.4 (Berkeley) 5/6/91
* $Id: esis.h,v 1.4 1994/05/05 07:56:35 cgd Exp $
* from: @(#)esis.h 8.1 (Berkeley) 6/10/93
* $Id: esis.h,v 1.5 1994/05/13 06:08:41 mycroft Exp $
*/
#ifndef _NETISO_ESIS_H_
#define _NETISO_ESIS_H_
/***********************************************************
Copyright IBM Corporation 1987
@ -64,6 +61,8 @@ SOFTWARE.
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
*/
#include <machine/endian.h>
#define SNPAC_AGE 60 /* seconds */
#define ESIS_CONFIG 60 /* seconds */
#define ESIS_HT (ESIS_CONFIG * 2)
@ -116,6 +115,4 @@ struct esis_stat {
#ifdef KERNEL
struct esis_stat esis_stat;
#endif KERNEL
#endif /* !_NETISO_ESIS_H_ */
#endif /* KERNEL */

180
sys/netiso/idrp_usrreq.c Normal file
View File

@ -0,0 +1,180 @@
/*
* Copyright (c) 1992, 1993
* The 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.
*
* from: @(#)idrp_usrreq.c 8.1 (Berkeley) 6/10/93
* $Id: idrp_usrreq.c,v 1.1 1994/05/13 06:08:42 mycroft Exp $
*/
#include <sys/param.h>
#include <sys/proc.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/protosw.h>
#include <sys/errno.h>
#include <net/route.h>
#include <net/if.h>
#include <netiso/argo_debug.h>
#include <netiso/iso.h>
#include <netiso/clnp.h>
#include <netiso/clnl.h>
#include <netiso/iso_pcb.h>
#include <netiso/iso_var.h>
void idrp_input();
struct isopcb idrp_isop;
static struct sockaddr_iso idrp_addrs[2] =
{ { sizeof(idrp_addrs), AF_ISO, }, { sizeof(idrp_addrs[1]), AF_ISO, } };
/*
* IDRP initialization
*/
void
idrp_init()
{
extern struct clnl_protosw clnl_protox[256];
idrp_isop.isop_next = idrp_isop.isop_prev = &idrp_isop;
idrp_isop.isop_faddr = &idrp_isop.isop_sfaddr;
idrp_isop.isop_laddr = &idrp_isop.isop_sladdr;
idrp_isop.isop_sladdr = idrp_addrs[1];
idrp_isop.isop_sfaddr = idrp_addrs[1];
clnl_protox[ISO10747_IDRP].clnl_input = idrp_input;
}
/*
* CALLED FROM:
* tpclnp_input().
* FUNCTION and ARGUMENTS:
* Take a packet (m) from clnp, strip off the clnp header
* and mke suitable for the idrp socket.
* No return value.
*/
void
idrp_input(m, src, dst)
register struct mbuf *m;
struct sockaddr_iso *src, *dst;
{
if (idrp_isop.isop_socket == 0) {
bad: m_freem(m);
return;
}
bzero(idrp_addrs[0].siso_data, sizeof(idrp_addrs[0].siso_data));
bcopy((caddr_t)&(src->siso_addr), (caddr_t)&idrp_addrs[0].siso_addr,
1 + src->siso_nlen);
bzero(idrp_addrs[1].siso_data, sizeof(idrp_addrs[1].siso_data));
bcopy((caddr_t)&(dst->siso_addr), (caddr_t)&idrp_addrs[1].siso_addr,
1 + dst->siso_nlen);
if (sbappendaddr(&idrp_isop.isop_socket->so_rcv,
(struct sockaddr *)idrp_addrs, m, (struct mbuf *)0) == 0)
goto bad;
sorwakeup(idrp_isop.isop_socket);
}
idrp_output(m, addr)
struct mbuf *m, *addr;
{
register struct sockaddr_iso *siso = mtod(addr, struct sockaddr_iso *);
int s = splnet(), i;
bcopy((caddr_t)&(siso->siso_addr),
(caddr_t)&idrp_isop.isop_sfaddr.siso_addr, 1 + siso->siso_nlen);
siso++;
bcopy((caddr_t)&(siso->siso_addr),
(caddr_t)&idrp_isop.isop_sladdr.siso_addr, 1 + siso->siso_nlen);
i = clnp_output(m, idrp_isop, m->m_pkthdr.len, 0);
splx(s);
return (i);
}
u_long idrp_sendspace = 3072; /* really max datagram size */
u_long idrp_recvspace = 40 * 1024; /* 40 1K datagrams */
/*ARGSUSED*/
idrp_usrreq(so, req, m, addr, control)
struct socket *so;
int req;
struct mbuf *m, *addr, *control;
{
int error = 0;
/* Note: need to block idrp_input while changing
* the udp pcb queue and/or pcb addresses.
*/
switch (req) {
case PRU_ATTACH:
if (idrp_isop.isop_socket != NULL) {
error = ENXIO;
break;
}
idrp_isop.isop_socket = so;
error = soreserve(so, idrp_sendspace, idrp_recvspace);
break;
case PRU_SHUTDOWN:
socantsendmore(so);
break;
case PRU_SEND:
return (idrp_output(m, addr));
case PRU_ABORT:
soisdisconnected(so);
case PRU_DETACH:
idrp_isop.isop_socket = 0;
break;
case PRU_SENSE:
/*
* stat: don't bother with a blocksize.
*/
return (0);
default:
return (EOPNOTSUPP); /* do not free mbuf's */
}
release:
if (control) {
printf("idrp control data unexpectedly retained\n");
m_freem(control);
}
if (m)
m_freem(m);
return (error);
}

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,8 +30,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)if_cons.c 7.10 (Berkeley) 5/29/91
* $Id: if_cons.c,v 1.3 1993/12/18 00:43:02 mycroft Exp $
* from: @(#)if_cons.c 8.1 (Berkeley) 6/10/93
* $Id: if_cons.c,v 1.4 1994/05/13 06:08:44 mycroft Exp $
*/
/***********************************************************
@ -71,11 +71,9 @@ SOFTWARE.
#ifdef ARGO_DEBUG
#define Static
unsigned LAST_CALL_PCB;
#else ARGO_DEBUG
#else /* ARGO_DEBUG */
#define Static static
#endif ARGO_DEBUG
#endif /* ARGO_DEBUG */
#ifndef SOCK_STREAM
#include <sys/param.h>
@ -86,7 +84,7 @@ unsigned LAST_CALL_PCB;
#include <sys/socketvar.h>
#include <sys/errno.h>
#include <sys/ioctl.h>
#include "tsleep.h"
#include <sys/tsleep.h>
#include <net/if.h>
#include <net/netisr.h>
@ -116,7 +114,7 @@ unsigned LAST_CALL_PCB;
#define MT_XCONFIRM MT_DATA
#define MT_XDATA MT_DATA
#define MT_XHEADER MT_HEADER
#endif ARGO_DEBUG
#endif /* ARGO_DEBUG */
#define DONTCLEAR -1
@ -167,21 +165,12 @@ Static int issue_clear_req();
#ifndef PHASEONE
extern struct ifaddr *ifa_ifwithnet();
#endif PHASEONE
#endif /* PHASEONE */
extern struct ifaddr *ifa_ifwithaddr();
Static struct socket dummysocket; /* for use by cosns */
extern struct isopcb tp_isopcb; /* chain of all TP pcbs */
struct isopcb tp_incoming_pending; /* incoming connections
for TP, pending */
struct isopcb *Xpcblist[] = {
&tp_incoming_pending,
&tp_isopcb,
(struct isopcb *)0
};
Static int parse_facil(), NSAPtoDTE(), make_partial_x25_packet();
Static int FACILtoNSAP(), DTEtoNSAP();
@ -297,6 +286,7 @@ nibble_match( src_octet, src_nibble, dst_octet, dst_nibble, len)
* FUNCTION:
* initialize the protocol
*/
void
cons_init()
{
int tp_incoming(), clnp_incoming();
@ -322,14 +312,13 @@ struct pklcd *lcp;
register struct mbuf *m;
{
register struct isopcb *isop;
extern struct isopcb tp_isopcb;
int cons_tpinput();
if (iso_pcballoc((struct socket *)0, &tp_incoming_pending)) {
if (iso_pcballoc((struct socket *)0, &tp_isopcb)) {
pk_close(lcp);
return;
}
isop = tp_incoming_pending.isop_next;
isop = tp_isopcb.isop_next;
lcp->lcd_upper = cons_tpinput;
lcp->lcd_upnext = (caddr_t)isop;
lcp->lcd_send(lcp); /* Confirms call */
@ -338,7 +327,7 @@ register struct mbuf *m;
isop->isop_faddr = &isop->isop_sfaddr;
DTEtoNSAP(isop->isop_laddr, &lcp->lcd_laddr);
DTEtoNSAP(isop->isop_faddr, &lcp->lcd_faddr);
parse_facil(isop, lcp, &(mtod(m, struct x25_packet *)->packet_data),
parse_facil(lcp, isop, &(mtod(m, struct x25_packet *)->packet_data),
m->m_pkthdr.len - PKHEADERLN);
}
@ -348,26 +337,20 @@ struct pklcd *lcp;
{
register struct isopcb *isop = (struct isopcb *)lcp->lcd_upnext;
register struct x25_packet *xp;
int cmd;
int cmd, ptype = CLEAR;
if (isop == 0)
return;
if (m0 == 0) {
isop->isop_chan = 0;
isop->isop_refcnt = 0;
lcp->lcd_upnext = 0;
lcp->lcd_upper = 0;
if (m0 == 0)
goto dead;
}
switch(m0->m_type) {
case MT_DATA:
case MT_OOBDATA:
tpcons_input(m0, isop->isop_faddr, isop->isop_laddr,
(struct socket *)0, (caddr_t)lcp);
tpcons_input(m0, isop->isop_faddr, isop->isop_laddr, (caddr_t)lcp);
return;
case MT_CONTROL:
switch (pk_decode(mtod(m0, struct x25_packet *))) {
switch (ptype = pk_decode(mtod(m0, struct x25_packet *))) {
case RR:
cmd = PRC_CONS_SEND_DONE;
@ -381,12 +364,17 @@ struct pklcd *lcp;
return;
dead:
case RESET:
case CLEAR:
case CLEAR_CONF:
lcp->lcd_upper = 0;
lcp->lcd_upnext = 0;
isop->isop_chan = 0;
case RESET:
cmd = PRC_ROUTEDEAD;
}
tpcons_ctlinput(cmd, isop->isop_faddr, isop);
if (cmd = PRC_ROUTEDEAD && isop->isop_refcnt == 0)
iso_pcbdetach(isop);
}
}
@ -447,6 +435,7 @@ cons_connect(isop)
* NOTE: this takes 3rd arg. because cons uses it to inform itself
* of things (timeouts, etc) but has a pcb instead of an address.
*/
void
cons_ctlinput(cmd, sa, copcb)
int cmd;
struct sockaddr *sa;
@ -524,7 +513,7 @@ done:
#endif KERNEL
#endif /* KERNEL */
/*
* NAME: make_partial_x25_packet()
@ -553,9 +542,9 @@ done:
#ifdef X25_1984
int cons_use_facils = 1;
#else X25_1984
#else /* X25_1984 */
int cons_use_facils = 0;
#endif X25_1984
#endif /* X25_1984 */
int cons_use_udata = 1; /* KLUDGE FOR DEBUGGING */
@ -594,7 +583,7 @@ make_partial_x25_packet(isop, lcp)
lcp->lcd_facilities = 0;
return 0;
}
MGETHDR(m, MT_DATA, M_WAITOK);
MGETHDR(m, M_WAITOK, MT_DATA);
if (m == 0)
return ENOBUFS;
buf = mtod(m, caddr_t);
@ -727,10 +716,15 @@ NSAPtoDTE(siso, sx25)
dtelen = out - sx25->x25_addr;
*out++ = 0;
} else {
register struct rtentry *rt = rtalloc1(siso, 1);
/* error = iso_8208snparesolve(addr, x121string, &x121strlen);*/
register struct rtentry *rt;
extern struct sockaddr_iso blank_siso;
struct sockaddr_iso nsiso;
if (rt) {
nsiso = blank_siso;
bcopy(nsiso.siso_data, siso->siso_data,
nsiso.siso_nlen = siso->siso_nlen);
if (rt = rtalloc1(&nsiso, 1)) {
register struct sockaddr_x25 *sxx =
(struct sockaddr_x25 *)rt->rt_gateway;
register char *in = sxx->x25_addr;
@ -754,16 +748,16 @@ NSAPtoDTE(siso, sx25)
* Creates and NSAP in the sockaddr_iso (addr) from the
* x.25 facility found at buf - 1.
* RETURNS:
* length of parameter if ok, -1 if error.
* 0 if ok, -1 if error.
*/
Static int
FACILtoNSAP(addr, buf)
u_char *buf;
register u_char *buf;
register struct sockaddr_iso *addr;
{
int len_in_nibbles, param_len = *buf++;
u_char buf_len; /* in bytes */
int len_in_nibbles = *++buf & 0x3f;
u_char buf_len = (len_in_nibbles + 1) >> 1;; /* in bytes */
IFDEBUG(D_CADDR)
printf("FACILtoNSAP( 0x%x, 0x%x, 0x%x )\n",
@ -771,7 +765,6 @@ FACILtoNSAP(addr, buf)
ENDDEBUG
len_in_nibbles = *buf & 0x3f;
buf_len = (len_in_nibbles + 1) >> 1;
/* despite the fact that X.25 makes us put a length in nibbles
* here, the NSAP-addrs are always in full octets
*/
@ -793,10 +786,10 @@ FACILtoNSAP(addr, buf)
/* Rather than blow away the connection, just ignore and use
NSAP from DTE */;
}
return param_len;
return 0;
}
static
Static
init_siso(siso)
register struct sockaddr_iso *siso;
{
@ -830,15 +823,17 @@ DTEtoNSAP(addr, sx)
init_siso(addr);
src_len = strlen(sx->x25_addr);
in = sx->x25_addr;
out = addr->siso_data + 1;
if (*in == '0' && (src_len & 1 == 0)) {
src_len = strlen(in);
addr->siso_nlen = (src_len + 3) / 2;
out = addr->siso_data;
*out++ = 0x37;
if (src_len & 1) {
pad_tail = 0xf;
src_len++;
}
for (first = 0; src_len > 0; src_len --) {
first |= *in++;
for (first = 0; src_len > 0; src_len--) {
first |= 0xf & *in++;
if (src_len & 1) {
*out++ = first;
first = 0;
@ -858,15 +853,13 @@ DTEtoNSAP(addr, sx)
* 0 if ok, E* otherwise.
*/
static int
Static int
parse_facil(lcp, isop, buf, buf_len)
caddr_t buf;
u_char buf_len; /* in bytes */
struct isopcb *isop;
struct pklcd *lcp;
{
register struct sockaddr_iso *called = isop->isop_laddr;
register struct sockaddr_iso *calling = isop->isop_faddr;
register int i;
register u_char *ptr = (u_char *)buf;
u_char *ptr_lim, *facil_lim;
@ -874,7 +867,7 @@ parse_facil(lcp, isop, buf, buf_len)
IFDEBUG(D_CADDR)
printf("parse_facil(0x%x, 0x%x, 0x%x, 0x%x)\n",
buf, buf_len, called, calling);
lcp, isop, buf, buf_len);
dump_buf(buf, buf_len);
ENDDEBUG
@ -896,7 +889,7 @@ parse_facil(lcp, isop, buf, buf_len)
printf("parse_facils: facil length is 0x%x\n", (int) facil_len);
ENDDEBUG
while (ptr <= facil_lim) {
while (ptr < facil_lim) {
/* get NSAP addresses from facilities */
switch (*ptr++) {
case 0xcb:
@ -929,6 +922,7 @@ parse_facil(lcp, isop, buf, buf_len)
(example of intelligent protocol design) */
case 0x04: /* charging info : requesting service */
case 0x08: /* called line addr modified notification */
case 0x00: /* marker to indicate beginning of CCITT facils */
facil_param_len = 1;
break;
@ -941,24 +935,26 @@ parse_facil(lcp, isop, buf, buf_len)
facil_param_len = 2;
break;
/* don't have any 3 octets */
/*
facil_param_len = 3;
*/
default:
printf(
"BOGUS FACILITY CODE facil_len 0x%x *facil_len 0x%x, ptr 0x%x *ptr 0x%x\n",
ptr, facil_len, ptr - 1, ptr[-1]);
/* facil that we don't handle */
return E_CO_HLI_REJI;
"BOGUS FACILITY CODE facil_lim 0x%x facil_len %d, ptr 0x%x *ptr 0x%x\n",
facil_lim, facil_len, ptr - 1, ptr[-1]);
/* facil that we don't handle
return E_CO_HLI_REJI; */
switch (ptr[-1] & 0xc0) {
case 0x00: facil_param_len = 1; break;
case 0x40: facil_param_len = 2; break;
case 0x80: facil_param_len = 3; break;
case 0xc0: facil_param_len = 0; break;
}
}
if (facil_param_len == -1)
return E_CO_REG_ICDA;
if (facil_param_len == 0) /* variable length */
facil_param_len = (int)*ptr; /* 1 + the real facil param */
facil_param_len = (int)*ptr++; /* 1 + the real facil param */
ptr += facil_param_len;
}
return 0;
}
#endif TPCONS
#endif /* TPCONS */

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,8 +30,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)if_eon.c 7.16 (Berkeley) 6/27/91
* $Id: if_eon.c,v 1.6 1994/02/11 06:41:51 mycroft Exp $
* from: @(#)if_eon.c 8.1 (Berkeley) 6/10/93
* $Id: if_eon.c,v 1.7 1994/05/13 06:08:46 mycroft Exp $
*/
/***********************************************************
@ -75,7 +75,6 @@ SOFTWARE.
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/types.h>
#include <sys/mbuf.h>
#include <sys/buf.h>
#include <sys/protosw.h>
@ -104,8 +103,6 @@ SOFTWARE.
#include <netiso/iso_errno.h>
#include <netiso/eonvar.h>
#include <machine/cpu.h>
extern struct timeval time;
extern struct ifnet loif;
@ -115,8 +112,7 @@ int eoninput();
int eonoutput();
int eonioctl();
int eonattach();
int eoninit();
int eonrtrequest();
void eonrtrequest();
struct ifnet eonif[1];
eonprotoinit() {
@ -195,7 +191,6 @@ eonioctl(ifp, cmd, data)
ifp->if_flags |= IFF_UP;
if (ifa->ifa_addr->sa_family != AF_LINK)
ifa->ifa_rtrequest = eonrtrequest;
ifa->ifa_llinfolen = sizeof(struct eon_llinfo);
}
break;
}
@ -260,6 +255,7 @@ caddr_t loc;
*
* RETURNS: nothing
*/
void
eonrtrequest(cmd, rt, gate)
register struct rtentry *rt;
register struct sockaddr *gate;
@ -297,7 +293,7 @@ register struct sockaddr *gate;
if (gate || (gate = rt->rt_gateway)) switch (gate->sa_family) {
case AF_LINK:
#define SDL(x) ((struct sockaddr_dl *)x)
if (SDL(gate)->sdl_alen = 1)
if (SDL(gate)->sdl_alen == 1)
el->el_snpaoffset = *(u_char *)LLADDR(SDL(gate));
else
ipaddrloc = LLADDR(SDL(gate));
@ -316,21 +312,6 @@ register struct sockaddr *gate;
- sizeof(el->el_ei);
}
/*
* FUNCTION: eoninit
*
* PURPOSE: initialization
*
* RETURNS: nothing
*/
eoninit(unit)
int unit;
{
printf("eon driver-init eon%d\n", unit);
}
/*
* FUNCTION: eonoutput
*
@ -430,7 +411,7 @@ send:
dump_buf(ei, sizeof(struct eon_iphdr));
ENDDEBUG
error = ip_output(m, NULL, ro, 0, NULL); /* XXX */
error = ip_output(m, (struct mbuf *)0, ro, 0, NULL);
m = 0;
if (error) {
ifp->if_oerrors++;

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,8 +30,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)iso.c 7.14 (Berkeley) 6/27/91
* $Id: iso.c,v 1.5 1994/02/14 06:42:43 cgd Exp $
* from: @(#)iso.c 8.2 (Berkeley) 11/15/93
* $Id: iso.c,v 1.6 1994/05/13 06:08:50 mycroft Exp $
*/
/***********************************************************
@ -64,8 +64,8 @@ SOFTWARE.
* iso.c: miscellaneous routines to support the iso address family
*/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/ioctl.h>
#include <sys/mbuf.h>
#include <sys/domain.h>
@ -83,36 +83,16 @@ SOFTWARE.
#include <netiso/iso_pcb.h>
#include <netiso/clnp.h>
#include <netiso/argo_debug.h>
#ifdef TUBA
#include <netiso/tuba_table.h>
#endif
#ifdef ISO
int iso_interfaces = 0; /* number of external interfaces */
extern struct ifnet loif; /* loopback interface */
int ether_output(), llc_rtrequest();
/*
* FUNCTION: iso_init
*
* PURPOSE: initialize the iso address family
*
* RETURNS: nothing
*
* SIDE EFFECTS: 1) initializes the routing table.
*
*
* NOTES:
*/
struct radix_node_head *iso_rnhead;
iso_init()
{
static iso_init_done;
if (iso_init_done == 0) {
iso_init_done++;
rn_inithead(&iso_rnhead, 48, AF_ISO);
}
}
int ether_output();
void llc_rtrequest();
/*
* FUNCTION: iso_addrmatch1
@ -226,7 +206,7 @@ struct sockaddr_iso *sisoa, *sisob;
return ((lena == lenb) && (!bcmp(bufa, bufb, lena)));
}
#endif notdef
#endif /* notdef */
/*
* FUNCTION: iso_hashchar
@ -280,6 +260,150 @@ register int len; /* length of buffer */
return(h);
}
#ifdef notdef
/*
* FUNCTION: iso_hash
*
* PURPOSE: Fill in fields of afhash structure based upon addr passed.
*
* RETURNS: none
*
* SIDE EFFECTS:
*
* NOTES:
*/
iso_hash(siso, hp)
struct sockaddr_iso *siso; /* address to perform hash on */
struct afhash *hp; /* RETURN: hash info here */
{
u_long buf[sizeof(struct sockaddr_iso)+1/4];
register int bufsize;
bzero(buf, sizeof(buf));
bufsize = iso_netof(&siso->siso_addr, buf);
hp->afh_nethash = iso_hashchar((caddr_t)buf, bufsize);
IFDEBUG(D_ROUTE)
printf("iso_hash: iso_netof: bufsize = %d\n", bufsize);
ENDDEBUG
hp->afh_hosthash = iso_hashchar((caddr_t)&siso->siso_addr,
siso->siso_addr.isoa_len);
IFDEBUG(D_ROUTE)
printf("iso_hash: %s: nethash = x%x, hosthash = x%x\n",
clnp_iso_addrp(&siso->siso_addr), hp->afh_nethash,
hp->afh_hosthash);
ENDDEBUG
}
/*
* FUNCTION: iso_netof
*
* PURPOSE: Extract the network portion of the iso address.
* The network portion of the iso address varies depending
* on the type of address. The network portion of the
* address will include the IDP. The network portion is:
*
* TYPE DESC
* t37 The AFI and x.121 (IDI)
* osinet The AFI, orgid, snetid
* rfc986 The AFI, vers and network part of
* internet address.
*
* RETURNS: number of bytes placed into buf.
*
* SIDE EFFECTS:
*
* NOTES: Buf is assumed to be big enough
*/
iso_netof(isoa, buf)
struct iso_addr *isoa; /* address */
caddr_t buf; /* RESULT: network portion of address here */
{
u_int len = 1; /* length of afi */
switch (isoa->isoa_afi) {
case AFI_37:
/*
* Due to classic x.25 tunnel vision, there is no
* net portion of an x.121 address. For our purposes
* the AFI will do, so that all x.25 -type addresses
* map to the single x.25 SNPA. (Cannot have more than
* one, obviously).
*/
break;
/* case AFI_OSINET:*/
case AFI_RFC986: {
u_short idi; /* value of idi */
/* osinet and rfc986 have idi in the same place */
CTOH(isoa->rfc986_idi[0], isoa->rfc986_idi[1], idi);
if (idi == IDI_OSINET)
/*
* Network portion of OSINET address can only be the IDI. Clearly,
* with one x25 interface, one could get to several orgids, and
* several snetids.
len += (ADDROSINET_IDI_LEN + OVLOSINET_ORGID_LEN +
OVLOSINET_SNETID_LEN);
*/
len += ADDROSINET_IDI_LEN;
else if (idi == IDI_RFC986) {
u_long inetaddr;
struct ovl_rfc986 *o986 = (struct ovl_rfc986 *)isoa;
/* bump len to include idi and version (1 byte) */
len += ADDRRFC986_IDI_LEN + 1;
/* get inet addr long aligned */
bcopy(o986->o986_inetaddr, &inetaddr, sizeof(inetaddr));
inetaddr = ntohl(inetaddr); /* convert to host byte order */
IFDEBUG(D_ROUTE)
printf("iso_netof: isoa ");
dump_buf(isoa, sizeof(*isoa));
printf("iso_netof: inetaddr 0x%x ", inetaddr);
ENDDEBUG
/* bump len by size of network portion of inet address */
if (IN_CLASSA(inetaddr)) {
len += 4-IN_CLASSA_NSHIFT/8;
IFDEBUG(D_ROUTE)
printf("iso_netof: class A net len is now %d\n", len);
ENDDEBUG
} else if (IN_CLASSB(inetaddr)) {
len += 4-IN_CLASSB_NSHIFT/8;
IFDEBUG(D_ROUTE)
printf("iso_netof: class B net len is now %d\n", len);
ENDDEBUG
} else {
len += 4-IN_CLASSC_NSHIFT/8;
IFDEBUG(D_ROUTE)
printf("iso_netof: class C net len is now %d\n", len);
ENDDEBUG
}
} else
len = 0;
} break;
default:
len = 0;
}
bcopy((caddr_t)isoa, buf, len);
IFDEBUG(D_ROUTE)
printf("iso_netof: isoa ");
dump_buf(isoa, len);
printf("iso_netof: net ");
dump_buf(buf, len);
ENDDEBUG
return len;
}
#endif /* notdef */
/*
* Generic iso control operations (ioctl's).
* Ifp is 0 if not an interface-specific ioctl.
@ -324,6 +448,11 @@ iso_control(so, cmd, data, ifp)
struct iso_ifaddr *nia;
if (cmd == SIOCDIFADDR_ISO)
return (EADDRNOTAVAIL);
#ifdef TUBA
/* XXXXXX can't be done in the proto init routines */
if (tuba_tree == 0)
tuba_table_init();
#endif
MALLOC(nia, struct iso_ifaddr *, sizeof(*nia),
M_IFADDR, M_WAITOK);
if (nia == (struct iso_ifaddr *)0)
@ -430,7 +559,7 @@ iso_control(so, cmd, data, ifp)
else
printf("Didn't unlink isoifadr from list\n");
}
free((caddr_t)oia, M_IFADDR);
IFAFREE((&oia->ia_ifa));
break;
default:
@ -482,7 +611,8 @@ iso_ifinit(ifp, ia, siso, 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);
@ -497,7 +627,6 @@ iso_ifinit(ifp, ia, siso, scrub)
if (ifp->if_output == ether_output) {
ia->ia_ifa.ifa_rtrequest = llc_rtrequest;
ia->ia_ifa.ifa_flags |= RTF_CLONING;
ia->ia_ifa.ifa_llinfolen = sizeof(struct llinfo_llc);
}
/*
* Add route for the network.
@ -576,7 +705,7 @@ iso_ifwithidi(addr)
return ((struct ifaddr *)0);
}
#endif notdef
#endif /* notdef */
/*
* FUNCTION: iso_ck_addr
*
@ -625,7 +754,7 @@ struct iso_addr *isoab; /* other addr to check */
}
return(0);
}
#endif notdef
#endif /* notdef */
/*
* FUNCTION: iso_localifa()
*
@ -681,7 +810,7 @@ iso_localifa(siso)
#ifdef TPCONS
#include <netiso/cons.h>
#endif TPCONS
#endif /* TPCONS */
/*
* FUNCTION: iso_nlctloutput
*
@ -742,15 +871,16 @@ struct mbuf *m; /* data for set, buffer for get */
bcopy(data, (caddr_t)isop->isop_x25crud, (unsigned)data_len);
isop->isop_x25crud_len = data_len;
break;
#endif TPCONS
#endif /* TPCONS */
default:
error = EOPNOTSUPP;
}
if (cmd == PRCO_SETOPT)
m_freem(m);
return error;
}
#endif ISO
#endif /* ISO */
#ifdef ARGO_DEBUG
@ -784,4 +914,4 @@ dump_isoaddr(s)
}
}
#endif ARGO_DEBUG
#endif /* ARGO_DEBUG */

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,13 +30,10 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)iso.h 7.6 (Berkeley) 5/6/91
* $Id: iso.h,v 1.3 1993/05/20 05:27:14 cgd Exp $
* from: @(#)iso.h 8.1 (Berkeley) 6/10/93
* $Id: iso.h,v 1.4 1994/05/13 06:08:51 mycroft Exp $
*/
#ifndef _NETISO_ISO_H_
#define _NETISO_ISO_H_
/***********************************************************
Copyright IBM Corporation 1987
@ -64,6 +61,9 @@ SOFTWARE.
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
*/
#ifndef _NETISO_ISO_H_
#define _NETISO_ISO_H_
/*
* Return true if this is a multicast address
* This assumes that the bit transmission is lsb first. This
@ -77,6 +77,8 @@ SOFTWARE.
/*
* Protocols
*/
#define ISOPROTO_TCP 6 /* IETF experiment */
#define ISOPROTO_UDP 17 /* IETF experiment */
#define ISOPROTO_TP0 25 /* connection oriented transport protocol */
#define ISOPROTO_TP1 26 /* not implemented */
#define ISOPROTO_TP2 27 /* not implemented */
@ -89,6 +91,7 @@ SOFTWARE.
#define ISOPROTO_INACT_NL 33 /* inactive network layer! */
#define ISOPROTO_ESIS 34 /* ES-IS protocol */
#define ISOPROTO_INTRAISIS 35 /* IS-IS protocol */
#define ISOPROTO_IDRP 36 /* Interdomain Routing Protocol */
#define ISOPROTO_RAW 255 /* raw clnp */
#define ISOPROTO_MAX 256
@ -120,11 +123,13 @@ SOFTWARE.
#define ISO9542_ESIS 0x82
#define ISO9542X25_ESIS 0x8a
#define ISO10589_ISIS 0x83
#define ISO8878A_CONS 0x84
#define ISO10747_IDRP 0x85
#ifndef IN_CLASSA_NET
#include "../netinet/in.h"
#endif IN_CLASSA_NET
#include <netinet/in.h>
#endif /* IN_CLASSA_NET */
@ -186,5 +191,4 @@ __END_DECLS
#endif /* KERNEL */
#define _offsetof(t, m) ((int)((caddr_t)&((t *)0)->m))
#endif /* !_NETISO_ISO_H_ */
#endif /* _NETISO_ISO_H_ */

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,8 +30,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)iso_chksum.c 7.5 (Berkeley) 5/6/91
* $Id: iso_chksum.c,v 1.3 1993/12/18 00:43:17 mycroft Exp $
* from: @(#)iso_chksum.c 8.1 (Berkeley) 6/10/93
* $Id: iso_chksum.c,v 1.4 1994/05/13 06:08:53 mycroft Exp $
*/
/***********************************************************
@ -81,15 +81,15 @@ SOFTWARE.
*/
#ifdef ISO
#include <sys/param.h>
#include <sys/mbuf.h>
#include <netiso/argo_debug.h>
#endif ISO
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#endif /* ISO */
#ifndef MNULL
#define MNULL (struct mbuf *)0
#endif MNULL
#endif /* MNULL */
/*
* FUNCTION: iso_check_csum
@ -120,7 +120,7 @@ iso_check_csum(m, len)
int l;
l = len;
len = MIN(m->m_len, len);
len = min(m->m_len, len);
i = 0;
IFDEBUG(D_CHKSUM)
@ -144,7 +144,7 @@ iso_check_csum(m, len)
l,i,m->m_data);
ENDDEBUG
ASSERT( m != MNULL);
len = MIN( m->m_len, l-i);
len = min( m->m_len, l-i);
p = mtod(m, u_char *);
}
}
@ -196,9 +196,9 @@ iso_gen_csum(m,n,l)
ENDDEBUG
while(i < l) {
len = MIN(m->m_len, CLBYTES);
len = min(m->m_len, CLBYTES);
/* RAH: don't cksum more than l bytes */
len = MIN(len, l - i);
len = min(len, l - i);
cum +=len;
p = mtod(m, u_char *);
@ -252,22 +252,6 @@ iso_gen_csum(m,n,l)
ENDDEBUG
}
struct mbuf *
m_append(head, m)
struct mbuf *head, *m;
{
register struct mbuf *n;
if (m == 0)
return head;
if (head == 0)
return m;
n = head;
while (n->m_next)
n = n->m_next;
n->m_next = m;
return head;
}
/*
* FUNCTION: m_datalen
*
@ -282,23 +266,13 @@ m_append(head, m)
*/
int
m_datalen (morig)
struct mbuf *morig;
m_datalen (m)
register struct mbuf *m;
{
int s = splimp();
register struct mbuf *n=morig;
register int datalen = 0;
register int datalen;
if( morig == (struct mbuf *)0)
return 0;
for(;;) {
datalen += n->m_len;
if (n->m_next == (struct mbuf *)0 ) {
break;
}
n = n->m_next;
}
splx(s);
for (datalen = 0; m; m = m->m_next)
datalen += m->m_len;
return datalen;
}
@ -347,7 +321,7 @@ m_compress(in, out)
int len;
len = M_TRAILINGSPACE(*out);
len = MIN(len, in->m_len);
len = min(len, in->m_len);
datalen += len;
IFDEBUG(D_REQUEST)

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,13 +30,10 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)iso_errno.h 7.5 (Berkeley) 5/6/91
* $Id: iso_errno.h,v 1.3 1993/05/20 05:27:17 cgd Exp $
* from: @(#)iso_errno.h 8.1 (Berkeley) 6/10/93
* $Id: iso_errno.h,v 1.4 1994/05/13 06:08:54 mycroft Exp $
*/
#ifndef _NETISO_ISO_ERRNO_H_
#define _NETISO_ISO_ERRNO_H_
/***********************************************************
Copyright IBM Corporation 1987
@ -64,6 +61,9 @@ SOFTWARE.
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
*/
#ifndef _NETISO_ISO_ERRNO_H_
#define _NETISO_ISO_ERRNO_H_
#define ISO_ERROR_MASK 0x8000
#define BSD_ERROR_MASK 0x0000
#define TP_ERROR_MASK 0x8800 /* transport layer */
@ -272,4 +272,4 @@ SOFTWARE.
#define CONL_ERROR_MAX 0x1c3
#endif /* !_NETISO_ISO_ERRNO_H_ */
#endif /* _NETISO_ISO_ERRNO_H_ */

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,8 +30,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)iso_pcb.c 7.10 (Berkeley) 6/27/91
* $Id: iso_pcb.c,v 1.4 1994/01/06 23:57:36 mycroft Exp $
* from: @(#)iso_pcb.c 8.1 (Berkeley) 6/10/93
* $Id: iso_pcb.c,v 1.5 1994/05/13 06:08:56 mycroft Exp $
*/
/***********************************************************
@ -72,18 +72,16 @@ SOFTWARE.
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/errno.h>
#include <sys/protosw.h>
#include <net/if.h>
#include <net/route.h>
#include <netinet/in_systm.h>
#include <netiso/argo_debug.h>
#include <netiso/iso.h>
#include <netiso/clnp.h>
#include <netinet/in_systm.h>
#include <net/if.h>
#include <net/route.h>
#include <netiso/iso_pcb.h>
#include <netiso/iso_var.h>
#include <sys/protosw.h>
#ifdef TPCONS
#include <netccitt/x25.h>
@ -194,11 +192,6 @@ iso_pcbbind(isop, nam)
if( (nam->m_len < 2) || (nam->m_len < siso->siso_len)) {
return ENAMETOOLONG;
}
if (siso->siso_tlen) {
register char *cp = TSEL(siso);
suf.data[0] = cp[0];
suf.data[1] = cp[1];
}
if (siso->siso_nlen) {
/* non-zero net addr- better match one of our interfaces */
IFDEBUG(D_ISO)
@ -218,13 +211,17 @@ iso_pcbbind(isop, nam)
isop->isop_laddr = mtod(nam, struct sockaddr_iso *);
}
bcopy((caddr_t)siso, (caddr_t)isop->isop_laddr, siso->siso_len);
if (suf.s || siso->siso_tlen != 2) {
if((suf.s < ISO_PORT_RESERVED) && (siso->siso_tlen <= 2) &&
if (siso->siso_tlen == 0)
goto noname;
if ((isop->isop_socket->so_options & SO_REUSEADDR) == 0 &&
iso_pcblookup(head, 0, (caddr_t)0, isop->isop_laddr))
return EADDRINUSE;
if (siso->siso_tlen <= 2) {
bcopy(TSEL(siso), suf.data, sizeof(suf.data));
suf.s = ntohs(suf.s);
if((suf.s < ISO_PORT_RESERVED) &&
(isop->isop_socket->so_state && SS_PRIV) == 0)
return EACCES;
if ((isop->isop_socket->so_options & SO_REUSEADDR) == 0 &&
iso_pcblookup(head, 0, (caddr_t)0, isop->isop_laddr))
return EADDRINUSE;
} else {
register char *cp;
noname:
@ -236,7 +233,7 @@ noname:
if (head->isop_lport++ < ISO_PORT_RESERVED ||
head->isop_lport > ISO_PORT_USERRESERVED)
head->isop_lport = ISO_PORT_RESERVED;
suf.s = head->isop_lport;
suf.s = htons(head->isop_lport);
cp[0] = suf.data[0];
cp[1] = suf.data[1];
} while (iso_pcblookup(head, 0, (caddr_t)0, isop->isop_laddr));
@ -457,12 +454,15 @@ iso_pcbdetach(isop)
isop, isop->isop_socket, so);
ENDDEBUG
#ifdef TPCONS
if (isop->isop_refcnt) {
if (isop->isop_chan) {
register struct pklcd *lcp = (struct pklcd *)isop->isop_chan;
if (--isop->isop_refcnt > 0)
return;
if (lcp && lcp->lcd_state == DATA_TRANSFER)
if (lcp && lcp->lcd_state == DATA_TRANSFER) {
lcp->lcd_upper = 0;
lcp->lcd_upnext = 0;
pk_disconnect(lcp);
}
isop->isop_chan = 0;
}
#endif
@ -612,4 +612,4 @@ iso_pcblookup(head, fportlen, fport, laddr)
}
return (struct isopcb *)0;
}
#endif ISO
#endif /* ISO */

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,13 +30,10 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)iso_pcb.h 7.5 (Berkeley) 5/6/91
* $Id: iso_pcb.h,v 1.3 1993/05/20 05:27:20 cgd Exp $
* from: @(#)iso_pcb.h 8.1 (Berkeley) 6/10/93
* $Id: iso_pcb.h,v 1.4 1994/05/13 06:08:58 mycroft Exp $
*/
#ifndef _NETISO_ISO_PCB_H_
#define _NETISO_ISO_PCB_H_
/***********************************************************
Copyright IBM Corporation 1987
@ -86,6 +83,7 @@ struct isopcb {
caddr_t isop_chan; /* actually struct pklcb * */
u_short isop_refcnt; /* mult TP4 tpcb's -> here */
u_short isop_lport; /* MISLEADLING work var */
u_short isop_tuba_cached; /* for tuba address ref cnts */
int isop_x25crud_len; /* x25 call request ud */
char isop_x25crud[MAXX25CRUDLEN];
struct ifaddr *isop_ifa; /* ESIS interface assoc w/sock */
@ -112,5 +110,3 @@ struct rawisopcb {
#ifdef KERNEL
struct isopcb *iso_pcblookup();
#endif
#endif /* !_NETISO_ISO_PCB_H_ */

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,8 +30,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)iso_proto.c 7.8 (Berkeley) 5/6/91
* $Id: iso_proto.c,v 1.3 1993/12/18 00:43:24 mycroft Exp $
* from: @(#)iso_proto.c 8.1 (Berkeley) 6/10/93
* $Id: iso_proto.c,v 1.4 1994/05/13 06:08:59 mycroft Exp $
*/
/***********************************************************
@ -60,36 +60,40 @@ SOFTWARE.
/*
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
*/
/* iso_proto.c : protocol switch tables in the ISO domain
/*
* iso_proto.c : protocol switch tables in the ISO domain
*
* ISO protocol family includes TP, CLTP, CLNP, 8208
* TP and CLNP are implemented here.
*/
#ifdef ISO
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/protosw.h>
#include <sys/domain.h>
#include <sys/mbuf.h>
#include <net/radix.h>
#include <netiso/iso.h>
int clnp_output(), clnp_init(),clnp_slowtimo(),clnp_drain();
int rclnp_input(), rclnp_output(), rclnp_ctloutput(), raw_usrreq();
int clnp_usrreq();
int clnp_output(), rclnp_output(), rclnp_ctloutput();
int raw_usrreq(), clnp_usrreq();
void clnp_init(), clnp_slowtimo(), clnp_drain(), rclnp_input();
int tp_ctloutput();
int tpclnp_ctlinput();
int tpclnp_input();
int tp_usrreq();
int tp_init(), tp_slowtimo(), tp_drain();
int cons_init(), tpcons_input();
int tp_ctloutput(), tp_usrreq(), tpcons_input();
void tp_init(), tp_fasttimo(), tp_slowtimo(), tp_drain(), cons_init();
void tpclnp_input(), tpclnp_ctlinput();
int esis_input(), esis_ctlinput(), esis_init(), esis_usrreq();
int cltp_input(), cltp_ctlinput(), cltp_init(), cltp_usrreq(), cltp_output();
int isis_input();
int esis_usrreq(), idrp_usrreq(), cltp_usrreq(), cltp_output();
void esis_init(), idrp_init(), cltp_init(), isis_input(), esis_input();
void idrp_input(), cltp_input(), esis_ctlinput(), cltp_ctlinput();
#ifdef TUBA
int tuba_usrreq(), tuba_ctloutput(), tuba_tcpinput();
void tuba_init(), tuba_slowtimo(), tuba_fasttimo();
#endif
struct protosw isosw[] = {
/*
@ -141,13 +145,28 @@ struct protosw isosw[] = {
0, 0, 0, 0
},
/* ISOPROTO_IDRP */
{ SOCK_DGRAM, &isodomain, ISOPROTO_IDRP, PR_ATOMIC|PR_ADDR,
idrp_input, 0, 0, 0,
idrp_usrreq,
idrp_init, 0, 0, 0
},
/* ISOPROTO_TP */
{ SOCK_SEQPACKET, &isodomain, ISOPROTO_TP, PR_CONNREQUIRED|PR_WANTRCVD,
tpclnp_input, 0, tpclnp_ctlinput, tp_ctloutput,
tpclnp_input, 0, tpclnp_ctlinput, tp_ctloutput,
tp_usrreq,
tp_init, 0, tp_slowtimo, tp_drain,
tp_init, tp_fasttimo, tp_slowtimo, tp_drain,
},
#ifdef TUBA
{ SOCK_STREAM, &isodomain, ISOPROTO_TCP, PR_CONNREQUIRED|PR_WANTRCVD,
tuba_tcpinput, 0, 0, tuba_ctloutput,
tuba_usrreq,
tuba_init, tuba_fasttimo, tuba_fasttimo, 0
},
#endif
#ifdef TPCONS
/* ISOPROTO_TP */
{ SOCK_SEQPACKET, &isodomain, ISOPROTO_TP0, PR_CONNREQUIRED|PR_WANTRCVD,
@ -159,15 +178,18 @@ struct protosw isosw[] = {
};
int iso_init();
struct domain isodomain = {
AF_ISO, /* family */
"iso-domain", /* name */
iso_init, /* initialize routine */
0, /* initialize routine */
0, /* externalize access rights */
0, /* dispose of internalized rights */
isosw, /* protosw */
&isosw[sizeof(isosw)/sizeof(isosw[0])] /* NPROTOSW */
&isosw[sizeof(isosw)/sizeof(isosw[0])], /* NPROTOSW */
0, /* next */
rn_inithead, /* rtattach */
48, /* rtoffset */
sizeof(struct sockaddr_iso) /* maxkeylen */
};
#endif ISO
#endif /* ISO */

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,8 +30,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)iso_snpac.c 7.14 (Berkeley) 6/27/91
* $Id: iso_snpac.c,v 1.4 1993/12/18 00:43:26 mycroft Exp $
* from: @(#)iso_snpac.c 8.1 (Berkeley) 6/10/93
* $Id: iso_snpac.c,v 1.5 1994/05/13 06:09:01 mycroft Exp $
*/
/***********************************************************
@ -63,7 +63,6 @@ SOFTWARE.
#ifdef ISO
#include <sys/types.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
@ -90,9 +89,9 @@ SOFTWARE.
int iso_systype = SNPA_ES; /* default to be an ES */
extern short esis_holding_time, esis_config_time, esis_esconfig_time;
extern struct timeval time;
extern void esis_config();
extern int hz;
static void snpac_fixdstandmask();
extern void esis_config();
extern int hz;
static void snpac_fixdstandmask();
struct sockaddr_iso blank_siso = {sizeof(blank_siso), AF_ISO};
extern u_long iso_hashchar();
@ -101,7 +100,7 @@ static struct sockaddr_iso
gte = {sizeof(dst), AF_ISO},
src = {sizeof(dst), AF_ISO},
msk = {sizeof(dst), AF_ISO},
zmk = {1};
zmk = {0};
#define zsi blank_siso
#define zero_isoa zsi.siso_addr
#define zap_isoaddr(a, b) {Bzero(&a.siso_addr, sizeof(*r)); r = b; \
@ -163,59 +162,27 @@ struct sockaddr *sa;
struct rtentry *rt2;
struct ifnet *ifp = rt->rt_ifp;
int addrlen = ifp->if_addrlen;
static struct rtentry *recursing = 0;
#define LLC_SIZE 3 /* XXXXXX do this right later */
IFDEBUG (D_SNPA)
printf("llc_rtrequest(%d, %x, %x)\n", req, rt, sa);
ENDDEBUG
if (rt->rt_flags & RTF_GATEWAY) {
if (recursing) {
log(LOG_DEBUG, "llc_rtrequest: gateway route points to same type %x %x\n",
recursing, rt);
} else switch (req) {
case RTM_RESOLVE:
case RTM_ADD:
recursing = rt;
rt->rt_llinfo = (caddr_t)rtalloc1(&gate->sa, 1);
recursing = 0;
if (rt->rt_rmx.rmx_mtu == 0) {
rt->rt_rmx.rmx_mtu =
((rt2 = (struct rtentry *)rt->rt_llinfo) &&
(rt2->rt_rmx.rmx_mtu)) ?
rt2->rt_rmx.rmx_mtu :
rt->rt_ifp->if_mtu - LLC_SIZE;
}
return;
case RTM_DELETE:
if (lc)
RTFREE((struct rtentry *)lc);
rt->rt_llinfo = 0;
}
} else switch (req) {
if (rt->rt_flags & RTF_GATEWAY)
return;
else switch (req) {
case RTM_ADD:
/*
* Case 1: This route may come from a route to iface with mask
* or from a default route.
*/
if (rt->rt_flags & RTF_CLONING) {
register struct ifaddr *ifa;
register struct sockaddr *sa;
for (ifa = ifp->if_addrlist; ifa; ifa->ifa_next)
if ((sa = ifa->ifa_addr)->sa_family == AF_LINK) {
if (sa->sa_len > gate->sa.sa_len)
log(LOG_DEBUG, "llc_rtrequest: cloning address too small\n");
else {
Bcopy(sa, gate, gate->sa.sa_len);
gate->sdl.sdl_alen = 0;
}
break;
}
if (ifa == 0)
log(LOG_DEBUG, "llc_rtrequest: can't find LL ifaddr for iface\n");
break;
iso_setmcasts(ifp, req);
rt_setgate(rt, rt_key(rt),
(struct sockaddr *)&blank_dl);
return;
}
if (lc != 0)
return; /* happens on a route change */
/* FALLTHROUGH */
case RTM_RESOLVE:
/*
@ -226,8 +193,6 @@ struct sockaddr *sa;
log(LOG_DEBUG, "llc_rtrequest: got non-link non-gateway route\n");
break;
}
if (lc != 0)
return; /* happens on a route change */
R_Malloc(lc, struct llinfo_llc *, sizeof (*lc));
rt->rt_llinfo = (caddr_t)lc;
if (lc == 0) {
@ -246,7 +211,9 @@ struct sockaddr *sa;
lc->lc_flags = (SNPA_ES | SNPA_VALID | SNPA_PERM);
break;
case RTM_DELETE:
if (lc == 0 || (rt->rt_flags & RTF_CLONING))
if (rt->rt_flags & RTF_CLONING)
iso_setmcasts(ifp, req);
if (lc == 0)
return;
remque(lc);
Free(lc);
@ -258,6 +225,41 @@ struct sockaddr *sa;
rt->rt_rmx.rmx_mtu = rt->rt_ifp->if_mtu - LLC_SIZE;
}
}
/*
* FUNCTION: iso_setmcasts
*
* PURPOSE: Enable/Disable ESIS/ISIS multicast reception on interfaces.
*
* NOTES: This also does a lot of obscure magic;
*/
iso_setmcasts(ifp, req)
struct ifnet *ifp;
int req;
{
static char *addrlist[] =
{ all_es_snpa, all_is_snpa, all_l1is_snpa, all_l2is_snpa, 0};
struct ifreq ifr;
register caddr_t *cpp;
int doreset = 0;
bzero((caddr_t)&ifr, sizeof(ifr));
for (cpp = (caddr_t *)addrlist; *cpp; cpp++) {
bcopy(*cpp, (caddr_t)ifr.ifr_addr.sa_data, 6);
if (req == RTM_ADD)
if (ether_addmulti(&ifr, (struct arpcom *)ifp) == ENETRESET)
doreset++;
else
if (ether_delmulti(&ifr, (struct arpcom *)ifp) == ENETRESET)
doreset++;
}
if (doreset) {
if (ifp->if_reset)
(*ifp->if_reset)(ifp->if_unit);
else
printf("iso_setmcasts: %s%d needs reseting to receive iso mcasts\n",
ifp->if_name, ifp->if_unit);
}
}
/*
* FUNCTION: iso_snparesolve
*
@ -385,7 +387,7 @@ int nsellength; /* nsaps may differ only in trailing bytes */
struct rtentry *mrt = 0;
register struct iso_addr *r; /* for zap_isoaddr macro */
int snpalen = min(ifp->if_addrlen, MAX_SNPALEN);
int new_entry = 0, index = ifp->if_index;
int new_entry = 0, index = ifp->if_index, iftype = ifp->if_type;
IFDEBUG(D_SNPA)
printf("snpac_add(%x, %x, %x, %x, %x, %x)\n",
@ -408,6 +410,7 @@ int nsellength; /* nsaps may differ only in trailing bytes */
}
new_entry = 1;
zap_linkaddr((&gte_dl), snpa, snpalen, index);
gte_dl.sdl_type = iftype;
if (rtrequest(RTM_ADD, S(dst), S(gte_dl), netmask, flags, &mrt) ||
mrt == 0)
return (0);
@ -420,8 +423,9 @@ int nsellength; /* nsaps may differ only in trailing bytes */
goto add;
if (nsellength && (rt->rt_flags & RTF_HOST)) {
if (rt->rt_refcnt == 0) {
rtrequest(RTM_DELETE, S(dst), (struct sockaddr *)0,
(struct sockaddr *)0, 0, (struct rtentry *)0);
rtrequest(RTM_DELETE, S(dst),
(struct sockaddr *)0, (struct sockaddr *)0,
0, (struct rtentry **)0);
rt = 0;
goto add;
} else {
@ -441,6 +445,7 @@ int nsellength; /* nsaps may differ only in trailing bytes */
}
zap_linkaddr(sdl, snpa, snpalen, index);
sdl->sdl_len = old_sdl_len;
sdl->sdl_type = iftype;
new_entry = 1;
}
}
@ -448,7 +453,7 @@ int nsellength; /* nsaps may differ only in trailing bytes */
panic("snpac_rtrequest");
rt->rt_rmx.rmx_expire = ht + time.tv_sec;
lc->lc_flags = SNPA_VALID | type;
if (type & SNPA_IS)
if ((type & SNPA_IS) && !(iso_systype & SNPA_IS))
snpac_logdefis(rt);
return (new_entry);
}
@ -541,23 +546,23 @@ register struct rtentry *sc;
{
register struct iso_addr *r;
register struct sockaddr_dl *sdl = (struct sockaddr_dl *)sc->rt_gateway;
register struct rtentry *rt = rtalloc1((struct sockaddr *)&zsi, 0);
register struct rtentry *rt;
zap_linkaddr((&gte_dl), LLADDR(sdl), sdl->sdl_alen, sdl->sdl_index);
if (known_is == 0)
known_is = sc;
if (known_is != sc) {
rtfree(known_is);
known_is = sc;
}
if (rt == 0) {
rtrequest(RTM_ADD, S(zsi), S(gte_dl), S(zmk),
RTF_DYNAMIC|RTF_GATEWAY|RTF_CLONING, 0);
if (known_is == sc || !(sc->rt_flags & RTF_HOST))
return;
if (known_is) {
RTFREE(known_is);
}
rt->rt_refcnt--;
if (rt->rt_flags & (RTF_DYNAMIC | RTF_MODIFIED)) {
*((struct sockaddr_dl *)rt->rt_gateway) = gte_dl;
known_is = sc;
sc->rt_refcnt++;
rt = rtalloc1((struct sockaddr *)&zsi, 0);
if (rt == 0)
rtrequest(RTM_ADD, S(zsi), rt_key(sc), S(zmk),
RTF_DYNAMIC|RTF_GATEWAY, 0);
else {
if ((rt->rt_flags & RTF_DYNAMIC) &&
(rt->rt_flags & RTF_GATEWAY) && rt_mask(rt)->sa_len == 0)
rt_setgate(rt, rt_key(rt), rt_key(sc));
}
}
@ -592,12 +597,10 @@ snpac_age()
for (lc = llinfo_llc.lc_next; lc != & llinfo_llc; lc = nlc) {
nlc = lc->lc_next;
if (((lc->lc_flags & SNPA_PERM) == 0) && (lc->lc_flags & SNPA_VALID)) {
if (lc->lc_flags & SNPA_VALID) {
rt = lc->lc_rt;
if (rt->rt_rmx.rmx_expire && rt->rt_rmx.rmx_expire < time.tv_sec)
snpac_free(lc);
else
continue;
}
}
}
@ -731,4 +734,4 @@ struct iso_addr *host, *gateway, *netmask;
rtredirect(S(dst), S(gte), (struct sockaddr *)0,
RTF_DONE | RTF_HOST, S(gte), 0);
}
#endif ISO
#endif /* ISO */

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,13 +30,10 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)iso_snpac.h 7.8 (Berkeley) 5/6/91
* $Id: iso_snpac.h,v 1.3 1993/05/20 05:27:24 cgd Exp $
* from: @(#)iso_snpac.h 8.1 (Berkeley) 6/10/93
* $Id: iso_snpac.h,v 1.4 1994/05/13 06:09:03 mycroft Exp $
*/
#ifndef _NETISO_ISO_SNPAC_H_
#define _NETISO_ISO_SNPAC_H_
/***********************************************************
Copyright IBM Corporation 1987
@ -113,6 +110,4 @@ struct llinfo_llc {
#ifdef KERNEL
struct llinfo_llc llinfo_llc; /* head for linked lists */
#endif KERNEL
#endif /* !_NETISO_ISO_SNPAC_H_ */
#endif /* KERNEL */

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1988, 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1988, 1991, 1993
* The 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
@ -30,13 +30,10 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)iso_var.h 7.5 (Berkeley) 5/6/91
* $Id: iso_var.h,v 1.3 1993/05/20 05:27:25 cgd Exp $
* from: @(#)iso_var.h 8.1 (Berkeley) 6/10/93
* $Id: iso_var.h,v 1.4 1994/05/13 06:09:04 mycroft Exp $
*/
#ifndef _NETISO_ISO_VAR_H_
#define _NETISO_ISO_VAR_H_
/***********************************************************
Copyright IBM Corporation 1987
@ -135,6 +132,4 @@ struct snpa_hdr {
struct iso_ifaddr *iso_ifaddr; /* linked list of iso address ifaces */
struct iso_ifaddr *iso_localifa(); /* linked list of iso address ifaces */
struct ifqueue clnlintrq; /* clnl packet input queue */
#endif KERNEL
#endif /* !_NETISO_ISO_VAR_H_ */
#endif /* KERNEL */

View File

@ -1,6 +1,7 @@
/* NEW */
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,8 +31,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)tp.trans 7.9 (Berkeley) 5/7/91
* $Id: tp.trans,v 1.2 1993/05/20 05:27:27 cgd Exp $
* from: @(#)tp.trans 8.1 (Berkeley) 6/10/93
* $Id: tp.trans,v 1.3 1994/05/13 06:09:06 mycroft Exp $
*/
/***********************************************************
@ -84,23 +85,25 @@ SOFTWARE.
*INCLUDE
{
/* @(#)tp.trans 7.9 (Berkeley) 5/7/91 */
#include "param.h"
#include "socket.h"
#include "socketvar.h"
#include "protosw.h"
#include "mbuf.h"
#include "time.h"
#include "errno.h"
#include "../netiso/tp_param.h"
#include "../netiso/tp_stat.h"
#include "../netiso/tp_pcb.h"
#include "../netiso/tp_tpdu.h"
#include "../netiso/argo_debug.h"
#include "../netiso/tp_trace.h"
#include "../netiso/iso_errno.h"
#include "../netiso/tp_seq.h"
#include "../netiso/cons.h"
/* @(#)tp.trans 8.1 (Berkeley) 6/10/93 */
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/protosw.h>
#include <sys/mbuf.h>
#include <sys/time.h>
#include <sys/errno.h>
#include <netiso/tp_param.h>
#include <netiso/tp_stat.h>
#include <netiso/tp_pcb.h>
#include <netiso/tp_tpdu.h>
#include <netiso/argo_debug.h>
#include <netiso/tp_trace.h>
#include <netiso/iso_errno.h>
#include <netiso/tp_seq.h>
#include <netiso/cons.h>
#define DRIVERTRACE TPPTdriver
#define sbwakeup(sb) sowakeup(p->tp_sock, sb);
@ -115,9 +118,11 @@ int tp_emit(),
void tp_indicate(), tp_getoptions(),
tp_soisdisconnecting(), tp_soisdisconnected(),
tp_recycle_tsuffix(),
#ifdef TP_DEBUG_TIMERS
tp_etimeout(), tp_euntimeout(),
tp_euntimeout_lss(), tp_ctimeout(),
tp_cuntimeout(), tp_ctimeout_MIN(),
tp_ctimeout(), tp_cuntimeout(),
tp_ctimeout_MIN(),
#endif
tp_freeref(), tp_detach(),
tp0_stash(), tp0_send(),
tp_netcmd(), tp_send()
@ -157,14 +162,12 @@ TP_CONFIRMING /* Local to this implementation */
*/
TM_sendack
/* TM_sendack does dual duty - keepalive AND sendack.
/* TM_sendack does dual duty - keepalive AND closed-window
* Probes.
* It's set w/ keepalive-ticks every time an ack is sent.
* (this is done in (void) tp_emit() ).
* It's cancelled and reset whenever a DT
* arrives and it doesn't require immediate acking.
* Note that in this case it's set w/ the minimum of
* its prev value and the sendack-ticks value so the
* purpose of the keepalive is preserved.
* Whenever a DT arrives which doesn't require immediate acking,
* a separate fast-timeout flag is set ensuring 200ms response.
*/
TM_notused
@ -329,7 +332,7 @@ TP_CLOSED <== [ TP_LISTENING, TP_CLOSED ] T_DETACH
TP_CONFIRMING <== TP_LISTENING CR_TPDU
( $P.tp_class == TP_CLASS_0)
{
$P.tp_refp->tpr_state = REF_OPEN; /* has timers ??? */
$P.tp_refstate = REF_OPEN; /* has timers ??? */
}
;
@ -342,7 +345,7 @@ TP_CONFIRMING <== TP_LISTENING CR_TPDU
IFDEBUG(D_CONN)
printf("CR datalen 0x%x data 0x%x", $$.e_datalen, $$.e_data);
ENDDEBUG
$P.tp_refp->tpr_state = REF_OPEN; /* has timers */
$P.tp_refstate = REF_OPEN; /* has timers */
$P.tp_fcredit = $$.e_cdt;
if ($$.e_datalen > 0) {
@ -380,11 +383,12 @@ TP_AKWAIT <== TP_CONFIRMING T_ACPT_req
IFDEBUG(D_CONN)
printf("Confirming connection: $P" );
ENDDEBUG
tp_getoptions($P);
soisconnecting($P.tp_sock);
if (($P.tp_rx_strat & TPRX_FASTSTART) && ($P.tp_fcredit > 0))
$P.tp_cong_win = $P.tp_fcredit;
$P.tp_cong_win = $P.tp_fcredit * $P.tp_l_tpdusize;
$P.tp_retrans = $P.tp_Nretrans;
tp_ctimeout($P.tp_refp, TM_retrans, (int)$P.tp_cc_ticks);
tp_ctimeout($P, TM_retrans, (int)$P.tp_cc_ticks);
}
;
@ -392,14 +396,12 @@ TP_AKWAIT <== TP_CONFIRMING T_ACPT_req
TP_CLOSED <== TP_CONFIRMING T_ACPT_req
DEFAULT /* emit failed */
{
register struct tp_ref *r = $P.tp_refp;
IFDEBUG(D_CONN)
printf("event: CR_TPDU emit CC failed done " );
ENDDEBUG
soisdisconnected($P.tp_sock);
tp_recycle_tsuffix( $P );
tp_freeref(r);
tp_recycle_tsuffix($P);
tp_freeref($P.tp_lref);
tp_detach($P);
}
;
@ -427,10 +429,10 @@ TP_CRSENT <== TP_CLOSED T_CONN_req
if (error = tp_emit(CR_TPDU_type, $P, 0, 0, data) )
return error; /* driver WON'T change state; will return error */
$P.tp_refp->tpr_state = REF_OPEN; /* has timers */
$P.tp_refstate = REF_OPEN; /* has timers */
if($P.tp_class != TP_CLASS_0) {
$P.tp_retrans = $P.tp_Nretrans;
tp_ctimeout($P.tp_refp, TM_retrans, (int)$P.tp_cr_ticks);
tp_ctimeout($P, TM_retrans, (int)$P.tp_cr_ticks);
}
}
;
@ -444,16 +446,26 @@ TP_REFWAIT <== [ TP_CRSENT, TP_AKWAIT, TP_OPEN ] DR_TPDU
sbappendrecord(&$P.tp_Xrcv, $$.e_data);
$$.e_data = MNULL;
}
tp_indicate(T_DISCONNECT, $P, 0);
if ($P.tp_state == TP_OPEN)
tp_indicate(T_DISCONNECT, $P, 0);
else {
int so_error = ECONNREFUSED;
if ($$.e_reason != (E_TP_NO_SESSION ^ TP_ERROR_MASK) &&
$$.e_reason != (E_TP_NO_CR_ON_NC ^ TP_ERROR_MASK) &&
$$.e_reason != (E_TP_REF_OVERFLOW ^ TP_ERROR_MASK))
so_error = ECONNABORTED;
tp_indicate(T_DISCONNECT, $P, so_error);
}
tp_soisdisconnected($P);
if ($P.tp_class != TP_CLASS_0) {
if ($P.tp_state == TP_OPEN ) {
tp_euntimeout($P.tp_refp, TM_data_retrans); /* all */
tp_cuntimeout($P.tp_refp, TM_retrans);
tp_cuntimeout($P.tp_refp, TM_inact);
tp_cuntimeout($P.tp_refp, TM_sendack);
tp_euntimeout($P, TM_data_retrans); /* all */
tp_cuntimeout($P, TM_retrans);
tp_cuntimeout($P, TM_inact);
tp_cuntimeout($P, TM_sendack);
$P.tp_flags &= ~TPF_DELACK;
}
tp_cuntimeout($P.tp_refp, TM_retrans);
tp_cuntimeout($P, TM_retrans);
if( $$.e_sref != 0 )
(void) tp_emit(DC_TPDU_type, $P, 0, 0, MNULL);
}
@ -466,8 +478,8 @@ SAME <== TP_CLOSED DR_TPDU
if( $$.e_sref != 0 )
(void) tp_emit(DC_TPDU_type, $P, 0, 0, MNULL);
/* reference timer already set - reset it to be safe (???) */
tp_euntimeout($P.tp_refp, TM_reference); /* all */
tp_etimeout($P.tp_refp, TM_reference, 0, 0, 0, (int)$P.tp_refer_ticks);
tp_euntimeout($P, TM_reference); /* all */
tp_etimeout($P, TM_reference, (int)$P.tp_refer_ticks);
}
;
@ -475,7 +487,7 @@ SAME <== TP_CLOSED DR_TPDU
TP_REFWAIT <== TP_CRSENT ER_TPDU
DEFAULT
{
tp_cuntimeout($P.tp_refp, TM_retrans);
tp_cuntimeout($P, TM_retrans);
tp_indicate(ER_TPDU, $P, $$.e_reason);
tp_soisdisconnected($P);
}
@ -485,7 +497,7 @@ TP_REFWAIT <== TP_CRSENT ER_TPDU
TP_REFWAIT <== TP_CLOSING DR_TPDU
DEFAULT
{
tp_cuntimeout($P.tp_refp, TM_retrans);
tp_cuntimeout($P, TM_retrans);
tp_soisdisconnected($P);
}
;
@ -497,7 +509,7 @@ TP_REFWAIT <== TP_CLOSING ER_TPDU
DEFAULT
{
tp_indicate(ER_TPDU, $P, $$.e_reason);
tp_cuntimeout($P.tp_refp, TM_retrans);
tp_cuntimeout($P, TM_retrans);
tp_soisdisconnected($P);
}
;
@ -505,7 +517,7 @@ TP_REFWAIT <== TP_CLOSING ER_TPDU
TP_REFWAIT <== TP_CLOSING DC_TPDU
DEFAULT
{
tp_cuntimeout($P.tp_refp, TM_retrans);
tp_cuntimeout($P, TM_retrans);
tp_soisdisconnected($P);
}
;
@ -534,14 +546,14 @@ TP_CLOSING <== [ TP_AKWAIT, TP_OPEN ] ER_TPDU
DEFAULT
{
if ($P.tp_state == TP_OPEN) {
tp_euntimeout($P.tp_refp, TM_data_retrans); /* all */
tp_cuntimeout($P.tp_refp, TM_inact);
tp_cuntimeout($P.tp_refp, TM_sendack);
tp_euntimeout($P, TM_data_retrans); /* all */
tp_cuntimeout($P, TM_inact);
tp_cuntimeout($P, TM_sendack);
}
tp_soisdisconnecting($P.tp_sock);
tp_indicate(ER_TPDU, $P, $$.e_reason);
$P.tp_retrans = $P.tp_Nretrans;
tp_ctimeout($P.tp_refp, TM_retrans, (int)$P.tp_dr_ticks);
tp_ctimeout($P, TM_retrans, (int)$P.tp_dr_ticks);
(void) tp_emit(DR_TPDU_type, $P, 0, E_TP_PROTO_ERR, MNULL);
}
;
@ -549,7 +561,7 @@ TP_CLOSING <== [ TP_AKWAIT, TP_OPEN ] ER_TPDU
TP_OPEN <== TP_CRSENT CC_TPDU
($P.tp_class == TP_CLASS_0)
{
tp_cuntimeout($P.tp_refp, TM_retrans);
tp_cuntimeout($P, TM_retrans);
IncStat(ts_tp0_conn);
$P.tp_fcredit = 1;
soisconnected($P.tp_sock);
@ -566,11 +578,10 @@ TP_OPEN <== TP_CRSENT CC_TPDU
IncStat(ts_tp4_conn);
$P.tp_fref = $$.e_sref;
$P.tp_fcredit = $$.e_cdt;
$P.tp_ackrcvd = 0;
if (($P.tp_rx_strat & TPRX_FASTSTART) && ($$.e_cdt > 0))
$P.tp_cong_win = $$.e_cdt;
$P.tp_cong_win = $$.e_cdt * $P.tp_l_tpdusize;
tp_getoptions($P);
tp_cuntimeout($P.tp_refp, TM_retrans);
tp_cuntimeout($P, TM_retrans);
if ($P.tp_ucddata) {
IFDEBUG(D_CONN)
printf("dropping user connect data cc 0x%x\n",
@ -587,7 +598,7 @@ TP_OPEN <== TP_CRSENT CC_TPDU
}
(void) tp_emit(AK_TPDU_type, $P, $P.tp_rcvnxt, 0, MNULL);
tp_ctimeout($P.tp_refp, TM_inact, (int)$P.tp_inact_ticks);
tp_ctimeout($P, TM_inact, (int)$P.tp_inact_ticks);
}
;
@ -599,8 +610,7 @@ SAME <== TP_CRSENT TM_retrans
int error;
IncStat(ts_retrans_cr);
$P.tp_cong_win = 1;
$P.tp_ackrcvd = 0;
$P.tp_cong_win = 1 * $P.tp_l_tpdusize;
data = MCPY($P.tp_ucddata, M_NOWAIT);
if($P.tp_ucddata) {
IFDEBUG(D_CONN)
@ -615,7 +625,7 @@ SAME <== TP_CRSENT TM_retrans
if( error = tp_emit(CR_TPDU_type, $P, 0, 0, data) ) {
$P.tp_sock->so_error = error;
}
tp_ctimeout($P.tp_refp, TM_retrans, (int)$P.tp_cr_ticks);
tp_ctimeout($P, TM_retrans, (int)$P.tp_cr_ticks);
}
;
@ -645,7 +655,7 @@ SAME <== TP_AKWAIT CR_TPDU
$P.tp_sock->so_error = error;
}
$P.tp_retrans = $P.tp_Nretrans;
tp_ctimeout($P.tp_refp, TM_retrans, (int)$P.tp_cc_ticks);
tp_ctimeout($P, TM_retrans, (int)$P.tp_cc_ticks);
}
;
@ -664,11 +674,10 @@ TP_OPEN <== TP_AKWAIT DT_TPDU
m_freem($P.tp_ucddata);
$P.tp_ucddata = 0;
}
tp_ctimeout($P.tp_refp, TM_inact, (int)$P.tp_inact_ticks);
tp_cuntimeout($P.tp_refp, TM_retrans);
tp_ctimeout($P, TM_inact, (int)$P.tp_inact_ticks);
tp_cuntimeout($P, TM_retrans);
soisconnected($P.tp_sock);
tp_getoptions($P);
tp_ctimeout($P.tp_refp, TM_inact, (int)$P.tp_inact_ticks);
tp_ctimeout($P, TM_inact, (int)$P.tp_inact_ticks);
/* see also next 2 transitions, if you make any changes */
@ -677,11 +686,11 @@ TP_OPEN <== TP_AKWAIT DT_TPDU
printf("tp_stash returns %d\n",doack);
ENDDEBUG
if(doack) {
if (doack) {
(void) tp_emit(AK_TPDU_type, $P, $P.tp_rcvnxt, 0, MNULL );
tp_ctimeout($P.tp_refp, TM_sendack, (int)$P.tp_keepalive_ticks);
tp_ctimeout($P, TM_sendack, (int)$P.tp_keepalive_ticks);
} else
tp_ctimeout( $P.tp_refp, TM_sendack, (int)$P.tp_sendack_ticks);
tp_ctimeout( $P, TM_sendack, (int)$P.tp_sendack_ticks);
IFDEBUG(D_DATA)
printf("after stash calling sbwakeup\n");
@ -708,7 +717,7 @@ SAME <== TP_OPEN DT_TPDU
{
int doack; /* tells if we must ack immediately */
tp_ctimeout($P.tp_refp, TM_inact, (int)$P.tp_inact_ticks);
tp_ctimeout($P, TM_inact, (int)$P.tp_inact_ticks);
sbwakeup( &$P.tp_sock->so_rcv );
doack = tp_stash($P, $E);
@ -719,7 +728,7 @@ SAME <== TP_OPEN DT_TPDU
if(doack)
(void) tp_emit(AK_TPDU_type, $P, $P.tp_rcvnxt, 0, MNULL );
else
tp_ctimeout_MIN( $P.tp_refp, TM_sendack, (int)$P.tp_sendack_ticks);
tp_ctimeout_MIN( $P, TM_sendack, (int)$P.tp_sendack_ticks);
IFDEBUG(D_DATA)
printf("after stash calling sbwakeup\n");
@ -746,7 +755,7 @@ SAME <== [ TP_OPEN, TP_AKWAIT ] DT_TPDU
ENDTRACE
IncStat(ts_dt_niw);
m_freem($$.e_data);
tp_ctimeout($P.tp_refp, TM_inact, (int)$P.tp_inact_ticks);
tp_ctimeout($P, TM_inact, (int)$P.tp_inact_ticks);
(void) tp_emit(AK_TPDU_type, $P, $P.tp_rcvnxt, 0, MNULL );
}
;
@ -760,9 +769,8 @@ TP_OPEN <== TP_AKWAIT AK_TPDU
$P.tp_ucddata = 0;
}
(void) tp_goodack($P, $$.e_cdt, $$.e_seq, $$.e_subseq);
tp_cuntimeout($P.tp_refp, TM_retrans);
tp_cuntimeout($P, TM_retrans);
tp_getoptions($P);
soisconnected($P.tp_sock);
IFTRACE(D_CONN)
struct socket *so = $P.tp_sock;
@ -774,8 +782,8 @@ TP_OPEN <== TP_AKWAIT AK_TPDU
so->so_qlen, so->so_error, so->so_rcv.sb_cc, so->so_head);
ENDTRACE
tp_ctimeout($P.tp_refp, TM_sendack, (int)$P.tp_keepalive_ticks);
tp_ctimeout($P.tp_refp, TM_inact, (int)$P.tp_inact_ticks);
tp_ctimeout($P, TM_sendack, (int)$P.tp_keepalive_ticks);
tp_ctimeout($P, TM_inact, (int)$P.tp_inact_ticks);
}
;
@ -788,11 +796,10 @@ TP_OPEN <== [ TP_OPEN, TP_AKWAIT ] XPD_TPDU
m_freem($P.tp_ucddata);
$P.tp_ucddata = 0;
}
tp_cuntimeout($P.tp_refp, TM_retrans);
tp_getoptions($P);
tp_cuntimeout($P, TM_retrans);
soisconnected($P.tp_sock);
tp_ctimeout($P.tp_refp, TM_sendack, (int)$P.tp_keepalive_ticks);
tp_ctimeout($P.tp_refp, TM_inact, (int)$P.tp_inact_ticks);
tp_ctimeout($P, TM_sendack, (int)$P.tp_keepalive_ticks);
tp_ctimeout($P, TM_inact, (int)$P.tp_inact_ticks);
}
IFTRACE(D_XPD)
tptrace(TPPTmisc, "XPD tpdu accepted Xrcvnxt, e_seq datalen m_len\n",
@ -860,7 +867,7 @@ SAME <== [ TP_AKWAIT, TP_OPEN ] XPD_TPDU
IncStat(ts_xpd_dup);
}
m_freem($$.e_data);
tp_ctimeout($P.tp_refp, TM_inact, (int)$P.tp_inact_ticks);
tp_ctimeout($P, TM_inact, (int)$P.tp_inact_ticks);
/* don't send an xack because the xak gives "last one received", not
* "next one i expect" (dumb)
*/
@ -906,7 +913,7 @@ TP_CLOSING <== [ TP_CLOSING, TP_AKWAIT, TP_CRSENT, TP_CONFIRMING ] T_DETACH
data = MCPY($P.tp_ucddata, M_NOWAIT);
(void) tp_emit(DR_TPDU_type, $P, 0, E_TP_NORMAL_DISC, data);
$P.tp_retrans = $P.tp_Nretrans;
tp_ctimeout($P.tp_refp, TM_retrans, (int)$P.tp_dr_ticks);
tp_ctimeout($P, TM_retrans, (int)$P.tp_dr_ticks);
}
}
;
@ -927,9 +934,10 @@ TP_CLOSING <== [ TP_AKWAIT, TP_OPEN, TP_CRSENT, TP_CONFIRMING ] T_DISC_req
struct mbuf *data = MCPY($P.tp_ucddata, M_WAIT);
if($P.tp_state == TP_OPEN) {
tp_euntimeout($P.tp_refp, TM_data_retrans); /* all */
tp_cuntimeout($P.tp_refp, TM_inact);
tp_cuntimeout($P.tp_refp, TM_sendack);
tp_euntimeout($P, TM_data_retrans); /* all */
tp_cuntimeout($P, TM_inact);
tp_cuntimeout($P, TM_sendack);
$P.tp_flags &= ~TPF_DELACK;
}
if (data) {
IFDEBUG(D_CONN)
@ -940,7 +948,7 @@ TP_CLOSING <== [ TP_AKWAIT, TP_OPEN, TP_CRSENT, TP_CONFIRMING ] T_DISC_req
}
tp_soisdisconnecting($P.tp_sock);
$P.tp_retrans = $P.tp_Nretrans;
tp_ctimeout($P.tp_refp, TM_retrans, (int)$P.tp_dr_ticks);
tp_ctimeout($P, TM_retrans, (int)$P.tp_dr_ticks);
if( trick_hc )
return tp_emit(DR_TPDU_type, $P, 0, $$.e_reason, data);
@ -956,12 +964,11 @@ SAME <== TP_AKWAIT TM_retrans
IncStat(ts_retrans_cc);
$P.tp_retrans --;
$P.tp_cong_win = 1;
$P.tp_ackrcvd = 0;
$P.tp_cong_win = 1 * $P.tp_l_tpdusize;
if( error = tp_emit(CC_TPDU_type, $P, 0, 0, data) )
$P.tp_sock->so_error = error;
tp_ctimeout($P.tp_refp, TM_retrans, (int)$P.tp_cc_ticks);
tp_ctimeout($P, TM_retrans, (int)$P.tp_cc_ticks);
}
;
@ -975,7 +982,7 @@ TP_CLOSING <== TP_AKWAIT TM_retrans
tp_indicate(T_DISCONNECT, $P, ETIMEDOUT);
(void) tp_emit(DR_TPDU_type, $P, 0, E_TP_CONGEST, MNULL);
$P.tp_retrans = $P.tp_Nretrans;
tp_ctimeout($P.tp_refp, TM_retrans, (int)$P.tp_dr_ticks);
tp_ctimeout($P, TM_retrans, (int)$P.tp_dr_ticks);
}
;
@ -988,9 +995,9 @@ TP_CLOSING <== TP_AKWAIT TM_retrans
TP_CLOSING <== TP_OPEN [ TM_inact, TM_retrans, TM_data_retrans ]
DEFAULT
{
tp_euntimeout($P.tp_refp, TM_data_retrans); /* all */
tp_cuntimeout($P.tp_refp, TM_inact);
tp_cuntimeout($P.tp_refp, TM_sendack);
tp_euntimeout($P, TM_data_retrans); /* all */
tp_cuntimeout($P, TM_inact);
tp_cuntimeout($P, TM_sendack);
IncStat(ts_conn_gaveup);
tp_soisdisconnecting($P.tp_sock);
@ -998,7 +1005,7 @@ TP_CLOSING <== TP_OPEN [ TM_inact, TM_retrans, TM_data_retrans ]
tp_indicate(T_DISCONNECT, $P, ETIMEDOUT);
(void) tp_emit(DR_TPDU_type, $P, 0, E_TP_CONGEST_2, MNULL);
$P.tp_retrans = $P.tp_Nretrans;
tp_ctimeout($P.tp_refp, TM_retrans, (int)$P.tp_dr_ticks);
tp_ctimeout($P, TM_retrans, (int)$P.tp_dr_ticks);
}
;
@ -1006,18 +1013,15 @@ TP_CLOSING <== TP_OPEN [ TM_inact, TM_retrans, TM_data_retrans ]
SAME <== TP_OPEN TM_retrans
( $P.tp_retrans > 0 )
{
$P.tp_cong_win = 1;
$P.tp_ackrcvd = 0;
$P.tp_cong_win = 1 * $P.tp_l_tpdusize;
/* resume XPD */
if ( $P.tp_Xsnd.sb_mb ) {
struct mbuf *m = m_copy($P.tp_Xsnd.sb_mb, 0, (int)$P.tp_Xsnd.sb_cc);
/* m_copy doesn't preserve the m_xlink field, but at this pt.
* that doesn't matter
*/
int shift;
IFTRACE(D_XPD)
tptrace(TPPTmisc, "XPD retrans: Xuna Xsndnxt sndhiwat snduna",
$P.tp_Xuna, $P.tp_Xsndnxt, $P.tp_sndhiwat,
tptrace(TPPTmisc, "XPD retrans: Xuna Xsndnxt sndnxt snduna",
$P.tp_Xuna, $P.tp_Xsndnxt, $P.tp_sndnxt,
$P.tp_snduna);
ENDTRACE
IFDEBUG(D_XPD)
@ -1025,68 +1029,19 @@ SAME <== TP_OPEN TM_retrans
ENDDEBUG
IncStat(ts_retrans_xpd);
$P.tp_retrans --;
shift = max($P.tp_Nretrans - $P.tp_retrans, 6);
(void) tp_emit(XPD_TPDU_type, $P, $P.tp_Xuna, 1, m);
tp_ctimeout($P.tp_refp, TM_retrans, (int)$P.tp_xpd_ticks);
tp_ctimeout($P, TM_retrans, ((int)$P.tp_dt_ticks) << shift);
}
}
;
/* TP4 only */
SAME <== TP_OPEN TM_data_retrans
( $$.e_retrans > 0 )
($P.tp_rxtshift < TP_NRETRANS)
{
register SeqNum low, lowsave = 0;
register struct tp_rtc *r = $P.tp_snduna_rtc;
register struct mbuf *m;
register SeqNum high = $$.e_high;
low = $P.tp_snduna;
lowsave = high = low;
tp_euntimeout_lss($P.tp_refp, TM_data_retrans,
SEQ_ADD($P, $P.tp_sndhiwat, 1));
$P.tp_retrans_hiwat = $P.tp_sndhiwat;
if (($P.tp_rx_strat & TPRX_EACH) == 0)
high = (high>low)?low:high;
if( $P.tp_rx_strat & TPRX_USE_CW ) {
register int i;
$P.tp_cong_win = 1;
$P.tp_ackrcvd = 0;
i = SEQ_ADD($P, low, $P.tp_cong_win);
high = SEQ_MIN($P, high, $P.tp_sndhiwat);
}
while( SEQ_LEQ($P, low, high) ){
if ( r == (struct tp_rtc *)0 ){
IFDEBUG(D_RTC)
printf( "tp: retrans rtc list is GONE!\n");
ENDDEBUG
break;
}
if ( r->tprt_seq == low ){
if(( m = m_copy(r->tprt_data, 0, r->tprt_octets ))== MNULL)
break;
(void) tp_emit(DT_TPDU_type, $P, low, r->tprt_eot, m);
IncStat(ts_retrans_dt);
SEQ_INC($P, low );
}
r = r->tprt_next;
}
/* CE_BIT
if ( SEQ_LEQ($P, lowsave, high) ){
*/
$$.e_retrans --;
tp_etimeout($P.tp_refp, TM_data_retrans, (caddr_t)lowsave,
(caddr_t)high, $$.e_retrans,
($P.tp_Nretrans - $$.e_retrans) * (int)$P.tp_dt_ticks);
/* CE_BIT
}
*/
$P.tp_rxtshift++;
(void) tp_data_retrans($P);
}
;
@ -1097,7 +1052,7 @@ SAME <== TP_CLOSING TM_retrans
$P.tp_retrans --;
(void) tp_emit(DR_TPDU_type, $P, 0, E_TP_DR_NO_REAS, MNULL);
IncStat(ts_retrans_dr);
tp_ctimeout($P.tp_refp, TM_retrans, (int)$P.tp_dr_ticks);
tp_ctimeout($P, TM_retrans, (int)$P.tp_dr_ticks);
}
;
@ -1106,9 +1061,9 @@ TP_REFWAIT <== TP_CLOSING TM_retrans
DEFAULT /* no more retrans - gave up */
{
$P.tp_sock->so_error = ETIMEDOUT;
$P.tp_refp->tpr_state = REF_FROZEN;
$P.tp_refstate = REF_FROZEN;
tp_recycle_tsuffix( $P );
tp_etimeout($P.tp_refp, TM_reference, 0,0,0, (int)$P.tp_refer_ticks);
tp_etimeout($P, TM_reference, (int)$P.tp_refer_ticks);
}
;
@ -1120,7 +1075,7 @@ TP_REFWAIT <== TP_CLOSING TM_retrans
TP_CLOSED <== TP_REFWAIT TM_reference
DEFAULT
{
tp_freeref($P.tp_refp);
tp_freeref($P.tp_lref);
tp_detach($P);
}
;
@ -1131,7 +1086,7 @@ SAME <== TP_OPEN [ CR_TPDU, CC_TPDU ]
DEFAULT
{
if( $P.tp_class != TP_CLASS_0) {
tp_ctimeout($P.tp_refp, TM_inact, (int)$P.tp_inact_ticks);
tp_ctimeout($P, TM_inact, (int)$P.tp_inact_ticks);
if ( $E.ev_number == CC_TPDU )
(void) tp_emit(AK_TPDU_type, $P, $P.tp_rcvnxt, 0, MNULL);
}
@ -1144,8 +1099,8 @@ SAME <== TP_OPEN T_DATA_req
DEFAULT
{
IFTRACE(D_DATA)
tptrace(TPPTmisc, "T_DATA_req sndhiwat snduna fcredit, tpcb",
$P.tp_sndhiwat, $P.tp_snduna, $P.tp_fcredit, $P);
tptrace(TPPTmisc, "T_DATA_req sndnxt snduna fcredit, tpcb",
$P.tp_sndnxt, $P.tp_snduna, $P.tp_fcredit, $P);
ENDTRACE
tp_send($P);
@ -1170,8 +1125,8 @@ SAME <== TP_OPEN T_XPD_req
*/
IFTRACE(D_XPD)
tptrace(TPPTmisc, "XPD req: Xuna Xsndnxt sndhiwat snduna",
$P.tp_Xuna, $P.tp_Xsndnxt, $P.tp_sndhiwat,
tptrace(TPPTmisc, "XPD req: Xuna Xsndnxt sndnxt snduna",
$P.tp_Xuna, $P.tp_Xsndnxt, $P.tp_sndnxt,
$P.tp_snduna);
ENDTRACE
IFDEBUG(D_XPD)
@ -1181,7 +1136,8 @@ SAME <== TP_OPEN T_XPD_req
error =
tp_emit(XPD_TPDU_type, $P, $P.tp_Xuna, 1, m);
$P.tp_retrans = $P.tp_Nretrans;
tp_ctimeout($P.tp_refp, TM_retrans, (int)$P.tp_xpd_ticks);
tp_ctimeout($P, TM_retrans, (int)$P.tp_rxtcur);
SEQ_INC($P, $P.tp_Xsndnxt);
}
if(trick_hc)
@ -1198,59 +1154,17 @@ SAME <== TP_OPEN AK_TPDU
* OR no news but the credit should be processed.
*/
{
struct sockbuf *sb = &$P.tp_sock->so_snd;
IFDEBUG(D_ACKRECV)
printf("GOOD ACK seq 0x%x cdt 0x%x\n", $$.e_seq, $$.e_cdt);
ENDDEBUG
if( $P.tp_class != TP_CLASS_0) {
tp_ctimeout($P.tp_refp, TM_inact, (int)$P.tp_inact_ticks);
tp_euntimeout_lss($P.tp_refp, TM_data_retrans, $$.e_seq);
}
sbwakeup( &$P.tp_sock->so_snd );
if ($P.tp_sndhiwat <= $P.tp_retrans_hiwat &&
$P.tp_snduna <= $P.tp_retrans_hiwat) {
register struct mbuf *m;
/* extern struct mbuf *m_copy(); */
register struct tp_rtc *r;
SeqNum high, retrans, low_save;
high = SEQ_MIN($P, SEQ_ADD($P, $P.tp_snduna,
MIN($P.tp_cong_win, $P.tp_fcredit)) - 1,
$P.tp_sndhiwat);
low_save = retrans = SEQ_MAX($P, SEQ_ADD($P, $P.tp_last_retrans, 1),
$P.tp_snduna);
for (; SEQ_LEQ($P, retrans, high); SEQ_INC($P, retrans)) {
for (r = $P.tp_snduna_rtc; r; r = r->tprt_next){
if ( r->tprt_seq == retrans ){
if(( m = m_copy(r->tprt_data, 0, r->tprt_octets ))
== MNULL)
break;
(void) tp_emit(DT_TPDU_type, $P, retrans,
r->tprt_eot, m);
$P.tp_last_retrans = retrans;
IncStat(ts_retrans_dt);
break;
}
}
if ( r == (struct tp_rtc *)0 ){
IFDEBUG(D_RTC)
printf( "tp: retrans rtc list is GONE!\n");
ENDDEBUG
break;
}
}
tp_etimeout($P.tp_refp, TM_data_retrans, (caddr_t)low_save,
(caddr_t)high, $P.tp_retrans, (int)$P.tp_dt_ticks);
if (SEQ_DEC($P, retrans) == $P.tp_retrans_hiwat)
tp_send($P);
}
else {
tp_send($P);
tp_ctimeout($P, TM_inact, (int)$P.tp_inact_ticks);
}
sbwakeup(sb);
IFDEBUG(D_ACKRECV)
printf("GOOD ACK new sndhiwat 0x%x\n", $P.tp_sndhiwat);
printf("GOOD ACK new sndnxt 0x%x\n", $P.tp_sndnxt);
ENDDEBUG
}
;
@ -1270,7 +1184,7 @@ SAME <== TP_OPEN AK_TPDU
IncStat( ts_ackreason[_ACK_FCC_] );
(void) tp_emit(AK_TPDU_type, $P, $P.tp_rcvnxt, 1, MNULL);
}
tp_ctimeout($P.tp_refp, TM_inact, (int)$P.tp_inact_ticks);
tp_ctimeout($P, TM_inact, (int)$P.tp_inact_ticks);
}
}
;
@ -1284,7 +1198,7 @@ SAME <== TP_OPEN AK_TPDU
(void) tp_emit(XPD_TPDU_type, $P, $P.tp_Xuna, 1, m);
$P.tp_retrans = $P.tp_Nretrans;
tp_ctimeout($P.tp_refp, TM_retrans, (int)$P.tp_xpd_ticks);
tp_ctimeout($P, TM_retrans, (int)$P.tp_xpd_ticks);
SEQ_INC($P, $P.tp_Xsndnxt);
}
*/
@ -1298,8 +1212,8 @@ SAME <== TP_OPEN XAK_TPDU
* also updates tp_Xuna
*/
{
tp_ctimeout($P.tp_refp, TM_inact, (int)$P.tp_inact_ticks);
tp_cuntimeout($P.tp_refp, TM_retrans);
tp_ctimeout($P, TM_inact, (int)$P.tp_inact_ticks);
tp_cuntimeout($P, TM_retrans);
sbwakeup( &$P.tp_sock->so_snd );
@ -1316,7 +1230,7 @@ SAME <== TP_OPEN XAK_TPDU
tptrace(TPPTmisc, "BOGUS XACK eventtype ", $E.ev_number, 0, 0,0);
ENDTRACE
if( $P.tp_class != TP_CLASS_0 ) {
tp_ctimeout($P.tp_refp, TM_inact, (int)$P.tp_inact_ticks);
tp_ctimeout($P, TM_inact, (int)$P.tp_inact_ticks);
}
}
;
@ -1325,12 +1239,20 @@ SAME <== TP_OPEN XAK_TPDU
SAME <== TP_OPEN TM_sendack
DEFAULT
{
int timo;
IFTRACE(D_TIMER)
tptrace(TPPTsendack, -1, $P.tp_lcredit, $P.tp_sent_uwe,
$P.tp_sent_lcdt, 0);
ENDTRACE
IncPStat($P, tps_n_TMsendack);
(void) tp_emit(AK_TPDU_type, $P, $P.tp_rcvnxt, 0, MNULL);
if ($P.tp_fcredit == 0) {
if ($P.tp_rxtshift < TP_MAXRXTSHIFT)
$P.tp_rxtshift++;
timo = ($P.tp_dt_ticks) << $P.tp_rxtshift;
} else
timo = $P.tp_sendack_ticks;
tp_ctimeout($P, TM_sendack, timo);
}
;
@ -1357,14 +1279,22 @@ SAME <== TP_OPEN T_USR_rcvd
DEFAULT
{
if( trick_hc ) {
IncStat(ts_ackreason[_ACK_USRRCV_]);
/* send an ACK only if there's new information */
LOCAL_CREDIT( $P );
if (($P.tp_rcvnxt != $P.tp_sent_rcvnxt) ||
($P.tp_lcredit != $P.tp_sent_lcdt))
SeqNum ack_thresh;
/*
* If the upper window edge has advanced a reasonable
* amount beyond what was known, send an ACK.
* A reasonable amount is 2 packets, unless the max window
* is only 1 or 2 packets, in which case we
* should send an ack for any advance in the upper window edge.
*/
LOCAL_CREDIT($P);
ack_thresh = SEQ_SUB($P, $P.tp_lcredit + $P.tp_rcvnxt,
($P.tp_maxlcredit > 2 ? 2 : 1));
if (SEQ_GT($P, ack_thresh, $P.tp_sent_uwe)) {
IncStat(ts_ackreason[_ACK_USRRCV_]);
$P.tp_flags &= ~TPF_DELACK;
return tp_emit(AK_TPDU_type, $P, $P.tp_rcvnxt, 0, MNULL);
}
}
}
;

75
sys/netiso/tp_astring.c Normal file
View File

@ -0,0 +1,75 @@
/*-
* Copyright (c) 1991, 1993
* The 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.
*
* from: @(#)tp_astring.c 8.1 (Berkeley) 6/10/93
* $Id: tp_astring.c,v 1.1 1994/05/13 06:09:09 mycroft Exp $
*/
char *tp_sstring[] = {
"ST_ERROR(0x0)",
"TP_CLOSED(0x1)",
"TP_CRSENT(0x2)",
"TP_AKWAIT(0x3)",
"TP_OPEN(0x4)",
"TP_CLOSING(0x5)",
"TP_REFWAIT(0x6)",
"TP_LISTENING(0x7)",
"TP_CONFIRMING(0x8)",
};
char *tp_estring[] = {
"TM_inact(0x0)",
"TM_retrans(0x1)",
"TM_sendack(0x2)",
"TM_notused(0x3)",
"TM_reference(0x4)",
"TM_data_retrans(0x5)",
"ER_TPDU(0x6)",
"CR_TPDU(0x7)",
"DR_TPDU(0x8)",
"DC_TPDU(0x9)",
"CC_TPDU(0xa)",
"AK_TPDU(0xb)",
"DT_TPDU(0xc)",
"XPD_TPDU(0xd)",
"XAK_TPDU(0xe)",
"T_CONN_req(0xf)",
"T_DISC_req(0x10)",
"T_LISTEN_req(0x11)",
"T_DATA_req(0x12)",
"T_XPD_req(0x13)",
"T_USR_rcvd(0x14)",
"T_USR_Xrcvd(0x15)",
"T_DETACH(0x16)",
"T_NETRESET(0x17)",
"T_ACPT_req(0x18)",
};

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,13 +30,10 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)tp_clnp.h 7.3 (Berkeley) 5/6/91
* $Id: tp_clnp.h,v 1.3 1993/05/20 05:27:30 cgd Exp $
* from: @(#)tp_clnp.h 8.1 (Berkeley) 6/10/93
* $Id: tp_clnp.h,v 1.4 1994/05/13 06:09:11 mycroft Exp $
*/
#ifndef _NETISO_TP_CLNP_H_
#define _NETISO_TP_CLNP_H_
/***********************************************************
Copyright IBM Corporation 1987
@ -64,28 +61,28 @@ SOFTWARE.
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
*/
/*
* ARGO TP
*
* AF_ISO net-dependent structures and include files
*
*/
#ifndef _NETISO_TP_CLNP_H_
#define _NETISO_TP_CLNP_H_
#ifndef SOCK_STREAM
#include "socket.h"
#endif SOCK_STREAM
#include <sys/socket.h>
#endif /* SOCK_STREAM */
#ifndef RTFREE
#include "../net/route.h"
#include <net/route.h>
#endif
#include "../netiso/iso.h"
#include "../netiso/clnp.h"
#include "../netiso/iso_pcb.h"
#include <netiso/iso.h>
#include <netiso/clnp.h>
#include <netiso/iso_pcb.h>
#ifndef IF_DEQUEUE
#include "../net/if.h"
#include <net/if.h>
#endif
#include "../netiso/iso_var.h"
#include <netiso/iso_var.h>
struct isopcb tp_isopcb;
/* queue of active inpcbs for tp ; for tp with dod ip */
#endif /* !_NETISO_TP_CLNP_H_ */
#endif /* _NETISO_TP_CLNP_H_ */

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,8 +30,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)tp_cons.c 7.8 (Berkeley) 5/9/91
* $Id: tp_cons.c,v 1.4 1993/12/18 04:58:03 mycroft Exp $
* from: @(#)tp_cons.c 8.1 (Berkeley) 6/10/93
* $Id: tp_cons.c,v 1.5 1994/05/13 06:09:12 mycroft Exp $
*/
/***********************************************************
@ -61,8 +61,6 @@ SOFTWARE.
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
*/
/*
* ARGO TP
*
* Here is where you find the iso- and cons-dependent code. We've tried
* keep all net-level and (primarily) address-family-dependent stuff
* out of the tp source, and everthing here is reached indirectly
@ -107,7 +105,6 @@ SOFTWARE.
#include <netccitt/pk_var.h>
#include <netiso/if_cons.c>
int tpcons_output();
/*
@ -146,22 +143,24 @@ register struct mbuf *nam;
* FUNCTION and ARGUMENTS:
* THIS MAYBE BELONGS IN SOME OTHER PLACE??? but i think not -
*/
ProtoHook
void
tpcons_ctlinput(cmd, siso, isop)
int cmd;
struct sockaddr_iso *siso;
struct isopcb *isop;
{
register struct tp_pcb *tpcb = 0;
if (isop->isop_socket)
tpcb = (struct tp_pcb *)isop->isop_socket->so_pcb;
switch (cmd) {
case PRC_CONS_SEND_DONE:
if( isop->isop_socket ) { /* tp 0 only */
register struct tp_pcb *tpcb =
(struct tp_pcb *)isop->isop_socket->so_tpcb;
if (tpcb) {
struct tp_event E;
int error = 0;
if( tpcb->tp_class == TP_CLASS_0 ) {
if (tpcb->tp_class == TP_CLASS_0) {
/* only if class is exactly class zero, not
* still in class negotiation
*/
@ -184,18 +183,17 @@ tpcons_ctlinput(cmd, siso, isop)
tpcb->tp_sock->so_error = error;
}
} /* else ignore it */
}
}
break;
case PRC_ROUTEDEAD:
if( isop->isop_socket ) { /* tp 0 only */
if (tpcb && tpcb->tp_class == TP_CLASS_0) {
tpiso_reset(isop);
break;
} /* else drop through */
default:
(void) tpclnp_ctlinput(cmd, siso);
tpclnp_ctlinput(cmd, siso);
break;
}
return 0;
}
/*
@ -206,14 +204,14 @@ tpcons_ctlinput(cmd, siso, isop)
* ignore the socket argument, and call tp_input.
* No return value.
*/
ProtoHook
void
tpcons_input(m, faddr, laddr, channel)
struct mbuf *m;
struct sockaddr_iso *faddr, *laddr;
caddr_t channel;
{
if( m == MNULL)
return 0;
return;
m = (struct mbuf *)tp_inputprep(m);
@ -222,7 +220,6 @@ tpcons_input(m, faddr, laddr, channel)
dump_buf( m, 12+ m->m_len);
ENDDEBUG
tp_input(m, faddr, laddr, channel, tpcons_output, 0);
return 0;
}
@ -262,9 +259,25 @@ tpcons_output(isop, m0, datalen, nochksum)
m->m_next = m0;
}
m->m_pkthdr.len = datalen;
error = pk_send(isop->isop_chan, m);
IncStat(ts_tpdu_sent);
if (isop->isop_chan == 0) {
/* got a restart maybe? */
if ((isop->isop_chan = (caddr_t) pk_attach((struct socket *)0)) == 0) {
IFDEBUG(D_CCONS)
printf("tpcons_output: no pklcd\n");
ENDDEBUG
error = ENOBUFS;
}
if (error = cons_connect(isop)) {
pk_disconnect((struct pklcd *)isop->isop_chan);
isop->isop_chan = 0;
IFDEBUG(D_CCONS)
printf("tpcons_output: can't reconnect\n");
ENDDEBUG
}
} else {
error = pk_send(isop->isop_chan, m);
IncStat(ts_tpdu_sent);
}
return error;
}
/*
@ -286,5 +299,5 @@ tpcons_dg_output(chan, m0, datalen)
{
return tpcons_output(((struct pklcd *)chan)->lcd_upnext, m0, datalen, 0);
}
#endif TPCONS
#endif ISO
#endif /* TPCONS */
#endif /* ISO */

View File

@ -1,17 +1,19 @@
/* $Id: tp_driver.c,v 1.4 1993/12/18 04:55:38 mycroft Exp $ */
#define _XEBEC_PG static
#include <netiso/tp_states.h>
#include "tp_states.h"
static struct act_ent {
int a_newstate;
int a_action;
} statetable[] = { {0,0},
#include <netiso/tp_states.init>
#include "tp_states.init"
};
/* from: @(#)tp.trans 8.1 (Berkeley) 6/10/93 */
/* $Id: tp_driver.c,v 1.5 1994/05/13 06:09:15 mycroft Exp $ */
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/protosw.h>
@ -42,9 +44,11 @@ int tp_emit(),
void tp_indicate(), tp_getoptions(),
tp_soisdisconnecting(), tp_soisdisconnected(),
tp_recycle_tsuffix(),
#ifdef TP_DEBUG_TIMERS
tp_etimeout(), tp_euntimeout(),
tp_euntimeout_lss(), tp_ctimeout(),
tp_cuntimeout(), tp_ctimeout_MIN(),
tp_ctimeout(), tp_cuntimeout(),
tp_ctimeout_MIN(),
#endif
tp_freeref(), tp_detach(),
tp0_stash(), tp0_send(),
tp_netcmd(), tp_send()
@ -56,7 +60,7 @@ typedef struct tp_pcb tpcb_struct;
typedef tpcb_struct tp_PCB_;
#include <netiso/tp_events.h>
#include "tp_events.h"
_XEBEC_PG int _Xebec_action(a,e,p)
int a;
@ -95,7 +99,7 @@ case 0x4:
break;
case 0x5:
{
p->tp_refp->tpr_state = REF_OPEN; /* has timers ??? */
p->tp_refstate = REF_OPEN; /* has timers ??? */
}
break;
case 0x6:
@ -106,7 +110,7 @@ case 0x6:
IFDEBUG(D_CONN)
printf("CR datalen 0x%x data 0x%x", e->ev_union.EV_CR_TPDU.e_datalen, e->ev_union.EV_CR_TPDU.e_data);
ENDDEBUG
p->tp_refp->tpr_state = REF_OPEN; /* has timers */
p->tp_refstate = REF_OPEN; /* has timers */
p->tp_fcredit = e->ev_union.EV_CR_TPDU.e_cdt;
if (e->ev_union.EV_CR_TPDU.e_datalen > 0) {
@ -140,23 +144,22 @@ case 0x8:
IFDEBUG(D_CONN)
printf("Confirming connection: p" );
ENDDEBUG
tp_getoptions(p);
soisconnecting(p->tp_sock);
if ((p->tp_rx_strat & TPRX_FASTSTART) && (p->tp_fcredit > 0))
p->tp_cong_win = p->tp_fcredit;
p->tp_cong_win = p->tp_fcredit * p->tp_l_tpdusize;
p->tp_retrans = p->tp_Nretrans;
tp_ctimeout(p->tp_refp, TM_retrans, (int)p->tp_cc_ticks);
tp_ctimeout(p, TM_retrans, (int)p->tp_cc_ticks);
}
break;
case 0x9:
{
register struct tp_ref *r = p->tp_refp;
IFDEBUG(D_CONN)
printf("event: CR_TPDU emit CC failed done " );
ENDDEBUG
soisdisconnected(p->tp_sock);
tp_recycle_tsuffix( p );
tp_freeref(r);
tp_recycle_tsuffix(p);
tp_freeref(p->tp_lref);
tp_detach(p);
}
break;
@ -181,10 +184,10 @@ case 0xa:
if (error = tp_emit(CR_TPDU_type, p, 0, 0, data) )
return error; /* driver WON'T change state; will return error */
p->tp_refp->tpr_state = REF_OPEN; /* has timers */
p->tp_refstate = REF_OPEN; /* has timers */
if(p->tp_class != TP_CLASS_0) {
p->tp_retrans = p->tp_Nretrans;
tp_ctimeout(p->tp_refp, TM_retrans, (int)p->tp_cr_ticks);
tp_ctimeout(p, TM_retrans, (int)p->tp_cr_ticks);
}
}
break;
@ -195,17 +198,26 @@ case 0xb:
sbappendrecord(&p->tp_Xrcv, e->ev_union.EV_DR_TPDU.e_data);
e->ev_union.EV_DR_TPDU.e_data = MNULL;
}
/* must return no error, or disc data and reason can't be read */
tp_indicate(T_DISCONNECT, p, 0);
if (p->tp_state == TP_OPEN)
tp_indicate(T_DISCONNECT, p, 0);
else {
int so_error = ECONNREFUSED;
if (e->ev_union.EV_DR_TPDU.e_reason != (E_TP_NO_SESSION ^ TP_ERROR_MASK) &&
e->ev_union.EV_DR_TPDU.e_reason != (E_TP_NO_CR_ON_NC ^ TP_ERROR_MASK) &&
e->ev_union.EV_DR_TPDU.e_reason != (E_TP_REF_OVERFLOW ^ TP_ERROR_MASK))
so_error = ECONNABORTED;
tp_indicate(T_DISCONNECT, p, so_error);
}
tp_soisdisconnected(p);
if (p->tp_class != TP_CLASS_0) {
if (p->tp_state == TP_OPEN ) {
tp_euntimeout(p->tp_refp, TM_data_retrans); /* all */
tp_cuntimeout(p->tp_refp, TM_retrans);
tp_cuntimeout(p->tp_refp, TM_inact);
tp_cuntimeout(p->tp_refp, TM_sendack);
tp_euntimeout(p, TM_data_retrans); /* all */
tp_cuntimeout(p, TM_retrans);
tp_cuntimeout(p, TM_inact);
tp_cuntimeout(p, TM_sendack);
p->tp_flags &= ~TPF_DELACK;
}
tp_cuntimeout(p->tp_refp, TM_retrans);
tp_cuntimeout(p, TM_retrans);
if( e->ev_union.EV_DR_TPDU.e_sref != 0 )
(void) tp_emit(DC_TPDU_type, p, 0, 0, MNULL);
}
@ -216,33 +228,33 @@ case 0xc:
if( e->ev_union.EV_DR_TPDU.e_sref != 0 )
(void) tp_emit(DC_TPDU_type, p, 0, 0, MNULL);
/* reference timer already set - reset it to be safe (???) */
tp_euntimeout(p->tp_refp, TM_reference); /* all */
tp_etimeout(p->tp_refp, TM_reference, 0, 0, 0, (int)p->tp_refer_ticks);
tp_euntimeout(p, TM_reference); /* all */
tp_etimeout(p, TM_reference, (int)p->tp_refer_ticks);
}
break;
case 0xd:
{
tp_cuntimeout(p->tp_refp, TM_retrans);
tp_cuntimeout(p, TM_retrans);
tp_indicate(ER_TPDU, p, e->ev_union.EV_ER_TPDU.e_reason);
tp_soisdisconnected(p);
}
break;
case 0xe:
{
tp_cuntimeout(p->tp_refp, TM_retrans);
tp_cuntimeout(p, TM_retrans);
tp_soisdisconnected(p);
}
break;
case 0xf:
{
tp_indicate(ER_TPDU, p, e->ev_union.EV_ER_TPDU.e_reason);
tp_cuntimeout(p->tp_refp, TM_retrans);
tp_cuntimeout(p, TM_retrans);
tp_soisdisconnected(p);
}
break;
case 0x10:
{
tp_cuntimeout(p->tp_refp, TM_retrans);
tp_cuntimeout(p, TM_retrans);
tp_soisdisconnected(p);
}
break;
@ -263,20 +275,20 @@ case 0x12:
case 0x13:
{
if (p->tp_state == TP_OPEN) {
tp_euntimeout(p->tp_refp, TM_data_retrans); /* all */
tp_cuntimeout(p->tp_refp, TM_inact);
tp_cuntimeout(p->tp_refp, TM_sendack);
tp_euntimeout(p, TM_data_retrans); /* all */
tp_cuntimeout(p, TM_inact);
tp_cuntimeout(p, TM_sendack);
}
tp_soisdisconnecting(p->tp_sock);
tp_indicate(ER_TPDU, p, e->ev_union.EV_ER_TPDU.e_reason);
p->tp_retrans = p->tp_Nretrans;
tp_ctimeout(p->tp_refp, TM_retrans, (int)p->tp_dr_ticks);
tp_ctimeout(p, TM_retrans, (int)p->tp_dr_ticks);
(void) tp_emit(DR_TPDU_type, p, 0, E_TP_PROTO_ERR, MNULL);
}
break;
case 0x14:
{
tp_cuntimeout(p->tp_refp, TM_retrans);
tp_cuntimeout(p, TM_retrans);
IncStat(ts_tp0_conn);
p->tp_fcredit = 1;
soisconnected(p->tp_sock);
@ -291,11 +303,10 @@ case 0x15:
IncStat(ts_tp4_conn);
p->tp_fref = e->ev_union.EV_CC_TPDU.e_sref;
p->tp_fcredit = e->ev_union.EV_CC_TPDU.e_cdt;
p->tp_ackrcvd = 0;
if ((p->tp_rx_strat & TPRX_FASTSTART) && (e->ev_union.EV_CC_TPDU.e_cdt > 0))
p->tp_cong_win = e->ev_union.EV_CC_TPDU.e_cdt;
p->tp_cong_win = e->ev_union.EV_CC_TPDU.e_cdt * p->tp_l_tpdusize;
tp_getoptions(p);
tp_cuntimeout(p->tp_refp, TM_retrans);
tp_cuntimeout(p, TM_retrans);
if (p->tp_ucddata) {
IFDEBUG(D_CONN)
printf("dropping user connect data cc 0x%x\n",
@ -312,7 +323,7 @@ case 0x15:
}
(void) tp_emit(AK_TPDU_type, p, p->tp_rcvnxt, 0, MNULL);
tp_ctimeout(p->tp_refp, TM_inact, (int)p->tp_inact_ticks);
tp_ctimeout(p, TM_inact, (int)p->tp_inact_ticks);
}
break;
case 0x16:
@ -321,8 +332,7 @@ case 0x16:
int error;
IncStat(ts_retrans_cr);
p->tp_cong_win = 1;
p->tp_ackrcvd = 0;
p->tp_cong_win = 1 * p->tp_l_tpdusize;
data = MCPY(p->tp_ucddata, M_NOWAIT);
if(p->tp_ucddata) {
IFDEBUG(D_CONN)
@ -337,7 +347,7 @@ case 0x16:
if( error = tp_emit(CR_TPDU_type, p, 0, 0, data) ) {
p->tp_sock->so_error = error;
}
tp_ctimeout(p->tp_refp, TM_retrans, (int)p->tp_cr_ticks);
tp_ctimeout(p, TM_retrans, (int)p->tp_cr_ticks);
}
break;
case 0x17:
@ -357,7 +367,7 @@ case 0x18:
p->tp_sock->so_error = error;
}
p->tp_retrans = p->tp_Nretrans;
tp_ctimeout(p->tp_refp, TM_retrans, (int)p->tp_cc_ticks);
tp_ctimeout(p, TM_retrans, (int)p->tp_cc_ticks);
}
break;
case 0x19:
@ -372,11 +382,10 @@ case 0x19:
m_freem(p->tp_ucddata);
p->tp_ucddata = 0;
}
tp_ctimeout(p->tp_refp, TM_inact, (int)p->tp_inact_ticks);
tp_cuntimeout(p->tp_refp, TM_retrans);
tp_ctimeout(p, TM_inact, (int)p->tp_inact_ticks);
tp_cuntimeout(p, TM_retrans);
soisconnected(p->tp_sock);
tp_getoptions(p);
tp_ctimeout(p->tp_refp, TM_inact, (int)p->tp_inact_ticks);
tp_ctimeout(p, TM_inact, (int)p->tp_inact_ticks);
/* see also next 2 transitions, if you make any changes */
@ -385,11 +394,11 @@ case 0x19:
printf("tp_stash returns %d\n",doack);
ENDDEBUG
if(doack) {
if (doack) {
(void) tp_emit(AK_TPDU_type, p, p->tp_rcvnxt, 0, MNULL );
tp_ctimeout(p->tp_refp, TM_sendack, (int)p->tp_keepalive_ticks);
tp_ctimeout(p, TM_sendack, (int)p->tp_keepalive_ticks);
} else
tp_ctimeout( p->tp_refp, TM_sendack, (int)p->tp_sendack_ticks);
tp_ctimeout( p, TM_sendack, (int)p->tp_sendack_ticks);
IFDEBUG(D_DATA)
printf("after stash calling sbwakeup\n");
@ -410,7 +419,7 @@ case 0x1b:
{
int doack; /* tells if we must ack immediately */
tp_ctimeout(p->tp_refp, TM_inact, (int)p->tp_inact_ticks);
tp_ctimeout(p, TM_inact, (int)p->tp_inact_ticks);
sbwakeup( &p->tp_sock->so_rcv );
doack = tp_stash(p, e);
@ -421,7 +430,7 @@ case 0x1b:
if(doack)
(void) tp_emit(AK_TPDU_type, p, p->tp_rcvnxt, 0, MNULL );
else
tp_ctimeout_MIN( p->tp_refp, TM_sendack, (int)p->tp_sendack_ticks);
tp_ctimeout_MIN( p, TM_sendack, (int)p->tp_sendack_ticks);
IFDEBUG(D_DATA)
printf("after stash calling sbwakeup\n");
@ -436,7 +445,7 @@ case 0x1c:
ENDTRACE
IncStat(ts_dt_niw);
m_freem(e->ev_union.EV_DT_TPDU.e_data);
tp_ctimeout(p->tp_refp, TM_inact, (int)p->tp_inact_ticks);
tp_ctimeout(p, TM_inact, (int)p->tp_inact_ticks);
(void) tp_emit(AK_TPDU_type, p, p->tp_rcvnxt, 0, MNULL );
}
break;
@ -447,9 +456,8 @@ case 0x1d:
p->tp_ucddata = 0;
}
(void) tp_goodack(p, e->ev_union.EV_AK_TPDU.e_cdt, e->ev_union.EV_AK_TPDU.e_seq, e->ev_union.EV_AK_TPDU.e_subseq);
tp_cuntimeout(p->tp_refp, TM_retrans);
tp_cuntimeout(p, TM_retrans);
tp_getoptions(p);
soisconnected(p->tp_sock);
IFTRACE(D_CONN)
struct socket *so = p->tp_sock;
@ -461,8 +469,8 @@ case 0x1d:
so->so_qlen, so->so_error, so->so_rcv.sb_cc, so->so_head);
ENDTRACE
tp_ctimeout(p->tp_refp, TM_sendack, (int)p->tp_keepalive_ticks);
tp_ctimeout(p->tp_refp, TM_inact, (int)p->tp_inact_ticks);
tp_ctimeout(p, TM_sendack, (int)p->tp_keepalive_ticks);
tp_ctimeout(p, TM_inact, (int)p->tp_inact_ticks);
}
break;
case 0x1e:
@ -472,11 +480,10 @@ case 0x1e:
m_freem(p->tp_ucddata);
p->tp_ucddata = 0;
}
tp_cuntimeout(p->tp_refp, TM_retrans);
tp_getoptions(p);
tp_cuntimeout(p, TM_retrans);
soisconnected(p->tp_sock);
tp_ctimeout(p->tp_refp, TM_sendack, (int)p->tp_keepalive_ticks);
tp_ctimeout(p->tp_refp, TM_inact, (int)p->tp_inact_ticks);
tp_ctimeout(p, TM_sendack, (int)p->tp_keepalive_ticks);
tp_ctimeout(p, TM_inact, (int)p->tp_inact_ticks);
}
IFTRACE(D_XPD)
tptrace(TPPTmisc, "XPD tpdu accepted Xrcvnxt, e_seq datalen m_len\n",
@ -518,7 +525,7 @@ case 0x20:
IncStat(ts_xpd_dup);
}
m_freem(e->ev_union.EV_XPD_TPDU.e_data);
tp_ctimeout(p->tp_refp, TM_inact, (int)p->tp_inact_ticks);
tp_ctimeout(p, TM_inact, (int)p->tp_inact_ticks);
/* don't send an xack because the xak gives "last one received", not
* "next one i expect" (dumb)
*/
@ -555,7 +562,7 @@ case 0x22:
data = MCPY(p->tp_ucddata, M_NOWAIT);
(void) tp_emit(DR_TPDU_type, p, 0, E_TP_NORMAL_DISC, data);
p->tp_retrans = p->tp_Nretrans;
tp_ctimeout(p->tp_refp, TM_retrans, (int)p->tp_dr_ticks);
tp_ctimeout(p, TM_retrans, (int)p->tp_dr_ticks);
}
}
break;
@ -571,9 +578,10 @@ case 0x24:
struct mbuf *data = MCPY(p->tp_ucddata, M_WAIT);
if(p->tp_state == TP_OPEN) {
tp_euntimeout(p->tp_refp, TM_data_retrans); /* all */
tp_cuntimeout(p->tp_refp, TM_inact);
tp_cuntimeout(p->tp_refp, TM_sendack);
tp_euntimeout(p, TM_data_retrans); /* all */
tp_cuntimeout(p, TM_inact);
tp_cuntimeout(p, TM_sendack);
p->tp_flags &= ~TPF_DELACK;
}
if (data) {
IFDEBUG(D_CONN)
@ -584,7 +592,7 @@ case 0x24:
}
tp_soisdisconnecting(p->tp_sock);
p->tp_retrans = p->tp_Nretrans;
tp_ctimeout(p->tp_refp, TM_retrans, (int)p->tp_dr_ticks);
tp_ctimeout(p, TM_retrans, (int)p->tp_dr_ticks);
if( trick_hc )
return tp_emit(DR_TPDU_type, p, 0, e->ev_union.EV_T_DISC_req.e_reason, data);
@ -597,12 +605,11 @@ case 0x25:
IncStat(ts_retrans_cc);
p->tp_retrans --;
p->tp_cong_win = 1;
p->tp_ackrcvd = 0;
p->tp_cong_win = 1 * p->tp_l_tpdusize;
if( error = tp_emit(CC_TPDU_type, p, 0, 0, data) )
p->tp_sock->so_error = error;
tp_ctimeout(p->tp_refp, TM_retrans, (int)p->tp_cc_ticks);
tp_ctimeout(p, TM_retrans, (int)p->tp_cc_ticks);
}
break;
case 0x26:
@ -613,14 +620,14 @@ case 0x26:
tp_indicate(T_DISCONNECT, p, ETIMEDOUT);
(void) tp_emit(DR_TPDU_type, p, 0, E_TP_CONGEST, MNULL);
p->tp_retrans = p->tp_Nretrans;
tp_ctimeout(p->tp_refp, TM_retrans, (int)p->tp_dr_ticks);
tp_ctimeout(p, TM_retrans, (int)p->tp_dr_ticks);
}
break;
case 0x27:
{
tp_euntimeout(p->tp_refp, TM_data_retrans); /* all */
tp_cuntimeout(p->tp_refp, TM_inact);
tp_cuntimeout(p->tp_refp, TM_sendack);
tp_euntimeout(p, TM_data_retrans); /* all */
tp_cuntimeout(p, TM_inact);
tp_cuntimeout(p, TM_sendack);
IncStat(ts_conn_gaveup);
tp_soisdisconnecting(p->tp_sock);
@ -628,23 +635,20 @@ case 0x27:
tp_indicate(T_DISCONNECT, p, ETIMEDOUT);
(void) tp_emit(DR_TPDU_type, p, 0, E_TP_CONGEST_2, MNULL);
p->tp_retrans = p->tp_Nretrans;
tp_ctimeout(p->tp_refp, TM_retrans, (int)p->tp_dr_ticks);
tp_ctimeout(p, TM_retrans, (int)p->tp_dr_ticks);
}
break;
case 0x28:
{
p->tp_cong_win = 1;
p->tp_ackrcvd = 0;
p->tp_cong_win = 1 * p->tp_l_tpdusize;
/* resume XPD */
if ( p->tp_Xsnd.sb_mb ) {
struct mbuf *m = m_copy(p->tp_Xsnd.sb_mb, 0, (int)p->tp_Xsnd.sb_cc);
/* m_copy doesn't preserve the m_xlink field, but at this pt.
* that doesn't matter
*/
int shift;
IFTRACE(D_XPD)
tptrace(TPPTmisc, "XPD retrans: Xuna Xsndnxt sndhiwat snduna",
p->tp_Xuna, p->tp_Xsndnxt, p->tp_sndhiwat,
tptrace(TPPTmisc, "XPD retrans: Xuna Xsndnxt sndnxt snduna",
p->tp_Xuna, p->tp_Xsndnxt, p->tp_sndnxt,
p->tp_snduna);
ENDTRACE
IFDEBUG(D_XPD)
@ -652,65 +656,16 @@ case 0x28:
ENDDEBUG
IncStat(ts_retrans_xpd);
p->tp_retrans --;
shift = max(p->tp_Nretrans - p->tp_retrans, 6);
(void) tp_emit(XPD_TPDU_type, p, p->tp_Xuna, 1, m);
tp_ctimeout(p->tp_refp, TM_retrans, (int)p->tp_xpd_ticks);
tp_ctimeout(p, TM_retrans, ((int)p->tp_dt_ticks) << shift);
}
}
break;
case 0x29:
{
register SeqNum low, lowsave = 0;
register struct tp_rtc *r = p->tp_snduna_rtc;
register struct mbuf *m;
register SeqNum high = e->ev_union.EV_TM_data_retrans.e_high;
low = p->tp_snduna;
lowsave = high = low;
tp_euntimeout_lss(p->tp_refp, TM_data_retrans,
SEQ_ADD(p, p->tp_sndhiwat, 1));
p->tp_retrans_hiwat = p->tp_sndhiwat;
if ((p->tp_rx_strat & TPRX_EACH) == 0)
high = (high>low)?low:high;
if( p->tp_rx_strat & TPRX_USE_CW ) {
register int i;
p->tp_cong_win = 1;
p->tp_ackrcvd = 0;
i = SEQ_ADD(p, low, p->tp_cong_win);
high = SEQ_MIN(p, high, p->tp_sndhiwat);
}
while( SEQ_LEQ(p, low, high) ){
if ( r == (struct tp_rtc *)0 ){
IFDEBUG(D_RTC)
printf( "tp: retrans rtc list is GONE!\n");
ENDDEBUG
break;
}
if ( r->tprt_seq == low ){
if(( m = m_copy(r->tprt_data, 0, r->tprt_octets ))== MNULL)
break;
(void) tp_emit(DT_TPDU_type, p, low, r->tprt_eot, m);
IncStat(ts_retrans_dt);
SEQ_INC(p, low );
}
r = r->tprt_next;
}
/* CE_BIT
if ( SEQ_LEQ(p, lowsave, high) ){
*/
e->ev_union.EV_TM_data_retrans.e_retrans --;
tp_etimeout(p->tp_refp, TM_data_retrans, (caddr_t)lowsave,
(caddr_t)high, e->ev_union.EV_TM_data_retrans.e_retrans,
(p->tp_Nretrans - e->ev_union.EV_TM_data_retrans.e_retrans) * (int)p->tp_dt_ticks);
/* CE_BIT
}
*/
p->tp_rxtshift++;
(void) tp_data_retrans(p);
}
break;
case 0x2a:
@ -718,27 +673,27 @@ case 0x2a:
p->tp_retrans --;
(void) tp_emit(DR_TPDU_type, p, 0, E_TP_DR_NO_REAS, MNULL);
IncStat(ts_retrans_dr);
tp_ctimeout(p->tp_refp, TM_retrans, (int)p->tp_dr_ticks);
tp_ctimeout(p, TM_retrans, (int)p->tp_dr_ticks);
}
break;
case 0x2b:
{
p->tp_sock->so_error = ETIMEDOUT;
p->tp_refp->tpr_state = REF_FROZEN;
p->tp_refstate = REF_FROZEN;
tp_recycle_tsuffix( p );
tp_etimeout(p->tp_refp, TM_reference, 0,0,0, (int)p->tp_refer_ticks);
tp_etimeout(p, TM_reference, (int)p->tp_refer_ticks);
}
break;
case 0x2c:
{
tp_freeref(p->tp_refp);
tp_freeref(p->tp_lref);
tp_detach(p);
}
break;
case 0x2d:
{
if( p->tp_class != TP_CLASS_0) {
tp_ctimeout(p->tp_refp, TM_inact, (int)p->tp_inact_ticks);
tp_ctimeout(p, TM_inact, (int)p->tp_inact_ticks);
if ( e->ev_number == CC_TPDU )
(void) tp_emit(AK_TPDU_type, p, p->tp_rcvnxt, 0, MNULL);
}
@ -748,8 +703,8 @@ case 0x2d:
case 0x2e:
{
IFTRACE(D_DATA)
tptrace(TPPTmisc, "T_DATA_req sndhiwat snduna fcredit, tpcb",
p->tp_sndhiwat, p->tp_snduna, p->tp_fcredit, p);
tptrace(TPPTmisc, "T_DATA_req sndnxt snduna fcredit, tpcb",
p->tp_sndnxt, p->tp_snduna, p->tp_fcredit, p);
ENDTRACE
tp_send(p);
@ -767,8 +722,8 @@ case 0x2f:
*/
IFTRACE(D_XPD)
tptrace(TPPTmisc, "XPD req: Xuna Xsndnxt sndhiwat snduna",
p->tp_Xuna, p->tp_Xsndnxt, p->tp_sndhiwat,
tptrace(TPPTmisc, "XPD req: Xuna Xsndnxt sndnxt snduna",
p->tp_Xuna, p->tp_Xsndnxt, p->tp_sndnxt,
p->tp_snduna);
ENDTRACE
IFDEBUG(D_XPD)
@ -778,7 +733,8 @@ case 0x2f:
error =
tp_emit(XPD_TPDU_type, p, p->tp_Xuna, 1, m);
p->tp_retrans = p->tp_Nretrans;
tp_ctimeout(p->tp_refp, TM_retrans, (int)p->tp_xpd_ticks);
tp_ctimeout(p, TM_retrans, (int)p->tp_rxtcur);
SEQ_INC(p, p->tp_Xsndnxt);
}
if(trick_hc)
@ -787,59 +743,17 @@ case 0x2f:
break;
case 0x30:
{
struct sockbuf *sb = &p->tp_sock->so_snd;
IFDEBUG(D_ACKRECV)
printf("GOOD ACK seq 0x%x cdt 0x%x\n", e->ev_union.EV_AK_TPDU.e_seq, e->ev_union.EV_AK_TPDU.e_cdt);
ENDDEBUG
if( p->tp_class != TP_CLASS_0) {
tp_ctimeout(p->tp_refp, TM_inact, (int)p->tp_inact_ticks);
tp_euntimeout_lss(p->tp_refp, TM_data_retrans, e->ev_union.EV_AK_TPDU.e_seq);
}
sbwakeup( &p->tp_sock->so_snd );
if (p->tp_sndhiwat <= p->tp_retrans_hiwat &&
p->tp_snduna <= p->tp_retrans_hiwat) {
register struct mbuf *m;
/* extern struct mbuf *m_copy(); */
register struct tp_rtc *r;
SeqNum high, retrans, low_save;
high = SEQ_MIN(p, SEQ_ADD(p, p->tp_snduna,
MIN(p->tp_cong_win, p->tp_fcredit)) - 1,
p->tp_sndhiwat);
low_save = retrans = SEQ_MAX(p, SEQ_ADD(p, p->tp_last_retrans, 1),
p->tp_snduna);
for (; SEQ_LEQ(p, retrans, high); SEQ_INC(p, retrans)) {
for (r = p->tp_snduna_rtc; r; r = r->tprt_next){
if ( r->tprt_seq == retrans ){
if(( m = m_copy(r->tprt_data, 0, r->tprt_octets ))
== MNULL)
break;
(void) tp_emit(DT_TPDU_type, p, retrans,
r->tprt_eot, m);
p->tp_last_retrans = retrans;
IncStat(ts_retrans_dt);
break;
}
}
if ( r == (struct tp_rtc *)0 ){
IFDEBUG(D_RTC)
printf( "tp: retrans rtc list is GONE!\n");
ENDDEBUG
break;
}
}
tp_etimeout(p->tp_refp, TM_data_retrans, (caddr_t)low_save,
(caddr_t)high, p->tp_retrans, (int)p->tp_dt_ticks);
if (SEQ_DEC(p, retrans) == p->tp_retrans_hiwat)
tp_send(p);
}
else {
tp_send(p);
tp_ctimeout(p, TM_inact, (int)p->tp_inact_ticks);
}
sbwakeup(sb);
IFDEBUG(D_ACKRECV)
printf("GOOD ACK new sndhiwat 0x%x\n", p->tp_sndhiwat);
printf("GOOD ACK new sndnxt 0x%x\n", p->tp_sndnxt);
ENDDEBUG
}
break;
@ -856,14 +770,14 @@ case 0x31:
IncStat( ts_ackreason[_ACK_FCC_] );
(void) tp_emit(AK_TPDU_type, p, p->tp_rcvnxt, 1, MNULL);
}
tp_ctimeout(p->tp_refp, TM_inact, (int)p->tp_inact_ticks);
tp_ctimeout(p, TM_inact, (int)p->tp_inact_ticks);
}
}
break;
case 0x32:
{
tp_ctimeout(p->tp_refp, TM_inact, (int)p->tp_inact_ticks);
tp_cuntimeout(p->tp_refp, TM_retrans);
tp_ctimeout(p, TM_inact, (int)p->tp_inact_ticks);
tp_cuntimeout(p, TM_retrans);
sbwakeup( &p->tp_sock->so_snd );
@ -877,18 +791,26 @@ case 0x33:
tptrace(TPPTmisc, "BOGUS XACK eventtype ", e->ev_number, 0, 0,0);
ENDTRACE
if( p->tp_class != TP_CLASS_0 ) {
tp_ctimeout(p->tp_refp, TM_inact, (int)p->tp_inact_ticks);
tp_ctimeout(p, TM_inact, (int)p->tp_inact_ticks);
}
}
break;
case 0x34:
{
int timo;
IFTRACE(D_TIMER)
tptrace(TPPTsendack, -1, p->tp_lcredit, p->tp_sent_uwe,
p->tp_sent_lcdt, 0);
ENDTRACE
IncPStat(p, tps_n_TMsendack);
(void) tp_emit(AK_TPDU_type, p, p->tp_rcvnxt, 0, MNULL);
if (p->tp_fcredit == 0) {
if (p->tp_rxtshift < TP_MAXRXTSHIFT)
p->tp_rxtshift++;
timo = (p->tp_dt_ticks) << p->tp_rxtshift;
} else
timo = p->tp_sendack_ticks;
tp_ctimeout(p, TM_sendack, timo);
}
break;
case 0x35:
@ -900,14 +822,22 @@ case 0x35:
case 0x36:
{
if( trick_hc ) {
IncStat(ts_ackreason[_ACK_USRRCV_]);
/* send an ACK only if there's new information */
LOCAL_CREDIT( p );
if ((p->tp_rcvnxt != p->tp_sent_rcvnxt) ||
(p->tp_lcredit != p->tp_sent_lcdt))
SeqNum ack_thresh;
/*
* If the upper window edge has advanced a reasonable
* amount beyond what was known, send an ACK.
* A reasonable amount is 2 packets, unless the max window
* is only 1 or 2 packets, in which case we
* should send an ack for any advance in the upper window edge.
*/
LOCAL_CREDIT(p);
ack_thresh = SEQ_SUB(p, p->tp_lcredit + p->tp_rcvnxt,
(p->tp_maxlcredit > 2 ? 2 : 1));
if (SEQ_GT(p, ack_thresh, p->tp_sent_uwe)) {
IncStat(ts_ackreason[_ACK_USRRCV_]);
p->tp_flags &= ~TPF_DELACK;
return tp_emit(AK_TPDU_type, p, p->tp_rcvnxt, 0, MNULL);
}
}
}
break;
@ -947,7 +877,7 @@ case 0x15:
if ( p->tp_retrans > 0 ) return 0x34;
else return 0x35;
case 0x54:
if ( e->ev_union.EV_TM_data_retrans.e_retrans > 0 ) return 0x33;
if (p->tp_rxtshift < TP_NRETRANS) return 0x33;
else return 0x31;
case 0x64:
if (p->tp_class == TP_CLASS_0) return 0x1a;
@ -1059,7 +989,6 @@ register struct tp_event *e;
error = _Xebec_action( a->a_action, e, p );
IFTRACE(D_DRIVER)
tptrace(DRIVERTRACE, a->a_newstate, p->tp_state, e->ev_number, a->a_action, 0);
ENDTRACE
if(error==0)
p->tp_state = a->a_newstate;

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,8 +30,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)tp_emit.c 7.9 (Berkeley) 5/9/91
* $Id: tp_emit.c,v 1.3 1993/12/18 00:43:31 mycroft Exp $
* from: @(#)tp_emit.c 8.1 (Berkeley) 6/10/93
* $Id: tp_emit.c,v 1.4 1994/05/13 06:09:16 mycroft Exp $
*/
/***********************************************************
@ -61,8 +61,6 @@ SOFTWARE.
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
*/
/*
* ARGO TP
*
* This file contains tp_emit() and tp_error_emit(), which
* form TPDUs and hand them to ip.
* They take data in the form of mbuf chain, allocate mbufs as
@ -78,16 +76,14 @@ SOFTWARE.
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/protosw.h>
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/time.h>
#include <net/if.h>
#include <netiso/iso.h>
#include <netiso/iso_pcb.h>
#include <netiso/argo_debug.h>
@ -101,6 +97,7 @@ SOFTWARE.
#include <netiso/tp_seq.h>
#include <netiso/iso_errno.h>
#include <net/if.h>
#ifdef TRUE
#undef FALSE
#undef TRUE
@ -174,6 +171,8 @@ tp_emit(dutype, tpcb, seq, eot, data)
int csum_offset=0;
int datalen = 0;
int error = 0;
SeqNum olduwe;
int acking_ooo;
/* NOTE:
* here we treat tpdu_li as if it DID include the li field, up until
@ -240,26 +239,21 @@ tp_emit(dutype, tpcb, seq, eot, data)
case CR_TPDU_type:
hdr->tpdu_CRdref_0 = 0; /* must be zero */
case CC_TPDU_type:
if (!tpcb->tp_cebit_off) {
tpcb->tp_win_recv = tp_start_win << 8;
LOCAL_CREDIT(tpcb);
CONG_INIT_SAMPLE(tpcb);
tpcb->tp_ackrcvd = 0;
}
else
} else
LOCAL_CREDIT(tpcb);
case CC_TPDU_type:
{
/* Case CC_TPDU_type used to be here */
{
u_char x;
hdr->tpdu_CCsref = htons(tpcb->tp_lref); /* same as CRsref */
if( tpcb->tp_class > TP_CLASS_1 ) {
/* ifdef CE_BIT, we did this in tp_input when the CR came in */
if (tpcb->tp_cebit_off)
LOCAL_CREDIT( tpcb );
tpcb->tp_sent_uwe = tpcb->tp_lcredit -1;
tpcb->tp_sent_rcvnxt = 1;
tpcb->tp_sent_lcdt = tpcb->tp_lcredit;
@ -313,6 +307,19 @@ tp_emit(dutype, tpcb, seq, eot, data)
| (tpcb->tp_xpd_service? TPAO_USE_TXPD: 0);
ADDOPTION(TPP_addl_opt, hdr, 1, x);
if ((tpcb->tp_l_tpdusize ^ (1 << tpcb->tp_tpdusize)) != 0) {
u_short size_s = tpcb->tp_l_tpdusize >> 7;
u_char size_c = size_s;
ASSERT(tpcb->tp_l_tpdusize < 65536 * 128);
if (dutype == CR_TPDU_type)
tpcb->tp_ptpdusize = size_s;
if (size_s < 256) {
ADDOPTION(TPP_ptpdu_size, hdr, 1, size_c);
} else {
size_s = htons(size_s);
ADDOPTION(TPP_ptpdu_size, hdr, 2, size_s);
}
}
}
if( (dutype == CR_TPDU_type) && (tpcb->tp_class != TP_CLASS_0)){
@ -377,7 +384,7 @@ tp_emit(dutype, tpcb, seq, eot, data)
hdr->tpdu_seqeotX = htonl(seqeotX.s_seqeot);
#else
hdr->tpdu_XAKseqX = seq;
#endif BYTE_ORDER
#endif /* BYTE_ORDER */
} else {
hdr->tpdu_XAKseq = seq;
}
@ -398,7 +405,7 @@ tp_emit(dutype, tpcb, seq, eot, data)
#else
hdr->tpdu_XPDseqX = seq;
hdr->tpdu_XPDeotX = 1; /* always 1 for XPD tpdu */
#endif BYTE_ORDER
#endif /* BYTE_ORDER */
} else {
hdr->tpdu_XPDseq = seq;
hdr->tpdu_XPDeot = 1; /* always 1 for XPD tpdu */
@ -431,7 +438,7 @@ tp_emit(dutype, tpcb, seq, eot, data)
#else
hdr->tpdu_DTseqX = seq;
hdr->tpdu_DTeotX = eot;
#endif BYTE_ORDER
#endif /* BYTE_ORDER */
} else if (tpcb->tp_class == TP_CLASS_0) {
IFDEBUG(D_EMIT)
printf("DT tpdu: class 0 m 0x%x hdr 0x%x\n", m, hdr);
@ -457,68 +464,71 @@ tp_emit(dutype, tpcb, seq, eot, data)
case AK_TPDU_type:/* ak not used in class 0 */
ASSERT( tpcb->tp_class != TP_CLASS_0);
data = (struct mbuf *)0;
{ SeqNum olduwe = tpcb->tp_sent_uwe;
olduwe = tpcb->tp_sent_uwe;
if (seq != tpcb->tp_sent_rcvnxt || tpcb->tp_rsycnt == 0) {
LOCAL_CREDIT( tpcb );
tpcb->tp_sent_uwe =
SEQ(tpcb,tpcb->tp_rcvnxt + tpcb->tp_lcredit -1);
LOCAL_CREDIT( tpcb );
tpcb->tp_sent_lcdt = tpcb->tp_lcredit;
acking_ooo = 0;
} else
acking_ooo = 1;
IFDEBUG(D_RENEG)
/* occasionally fake a reneging so
you can test subsequencing */
if( olduwe & 0x1 ) {
tpcb->tp_reneged = 1;
IncStat(ts_ldebug);
}
ENDDEBUG
/* Are we about to reneg on credit?
* When might we do so?
* a) when using optimistic credit (which we no longer do).
* b) when drain() gets implemented (not in the plans).
* c) when D_RENEG is on.
* d) when DEC BIT response is implemented.
* (not- when we do this, we'll need to implement flow control
* confirmation)
*/
if( SEQ_LT(tpcb, tpcb->tp_sent_uwe, olduwe) ) {
IFDEBUG(D_RENEG)
/* occasionally fake a reneging so
you can test subsequencing */
if( olduwe & 0x1 ) {
tpcb->tp_reneged = 1;
IncStat(ts_lcdt_reduced);
IFTRACE(D_CREDIT)
tptraceTPCB(TPPTmisc,
"RENEG: olduwe newuwe lcredit rcvnxt",
olduwe,
tpcb->tp_sent_uwe, tpcb->tp_lcredit,
tpcb->tp_rcvnxt);
ENDTRACE
IncStat(ts_ldebug);
}
IFPERF(tpcb)
/* new lwe is less than old uwe means we're
* acking before we received a whole window full
*/
if( SEQ_LT( tpcb, tpcb->tp_rcvnxt, olduwe) ) {
/* tmp1 = number of pkts fewer than the full window */
register int tmp1 =
(int) SEQ_SUB( tpcb, olduwe, tpcb->tp_rcvnxt);
if(tmp1 > TP_PM_MAX)
tmp1 = TP_PM_MAX;
IncPStat( tpcb, tps_ack_early[tmp1] );
/* tmp1 = amt of new cdt we're advertising */
tmp1 = SEQ_SUB( tpcb, seq, tpcb->tp_sent_rcvnxt);
if(tmp1 > TP_PM_MAX )
tmp1 = TP_PM_MAX;
IncPStat( tpcb,
tps_cdt_acked [ tmp1 ]
[ ((tpcb->tp_lcredit > TP_PM_MAX)?
TP_PM_MAX:tpcb->tp_lcredit) ] );
}
ENDPERF
ENDDEBUG
/* Are we about to reneg on credit?
* When might we do so?
* a) when using optimistic credit (which we no longer do).
* b) when drain() gets implemented (not in the plans).
* c) when D_RENEG is on.
* d) when DEC BIT response is implemented.
* (not- when we do this, we'll need to implement flow control
* confirmation)
*/
if( SEQ_LT(tpcb, tpcb->tp_sent_uwe, olduwe) ) {
tpcb->tp_reneged = 1;
IncStat(ts_lcdt_reduced);
IFTRACE(D_CREDIT)
tptraceTPCB(TPPTmisc,
"RENEG: olduwe newuwe lcredit rcvnxt",
olduwe,
tpcb->tp_sent_uwe, tpcb->tp_lcredit,
tpcb->tp_rcvnxt);
ENDTRACE
}
IFPERF(tpcb)
/* new lwe is less than old uwe means we're
* acking before we received a whole window full
*/
if( SEQ_LT( tpcb, tpcb->tp_rcvnxt, olduwe) ) {
/* tmp1 = number of pkts fewer than the full window */
register int tmp1 =
(int) SEQ_SUB( tpcb, olduwe, tpcb->tp_rcvnxt);
if(tmp1 > TP_PM_MAX)
tmp1 = TP_PM_MAX;
IncPStat( tpcb, tps_ack_early[tmp1] );
/* tmp1 = amt of new cdt we're advertising */
tmp1 = SEQ_SUB( tpcb, seq, tpcb->tp_sent_rcvnxt);
if(tmp1 > TP_PM_MAX )
tmp1 = TP_PM_MAX;
IncPStat( tpcb,
tps_cdt_acked [ tmp1 ]
[ ((tpcb->tp_lcredit > TP_PM_MAX)?
TP_PM_MAX:tpcb->tp_lcredit) ] );
}
ENDPERF
IFTRACE(D_ACKSEND)
tptraceTPCB(TPPTack, seq, tpcb->tp_lcredit, tpcb->tp_sent_uwe,
tpcb->tp_r_subseq, 0);
@ -535,12 +545,13 @@ tp_emit(dutype, tpcb, seq, eot, data)
hdr->tpdu_cdt = 0;
hdr->tpdu_AKseqX = seq;
hdr->tpdu_AKcdtX = tpcb->tp_lcredit;
#endif BYTE_ORDER
#endif /* BYTE_ORDER */
} else {
hdr->tpdu_AKseq = seq;
hdr->tpdu_AKcdt = tpcb->tp_lcredit;
}
if ((tpcb->tp_class == TP_CLASS_4) && tpcb->tp_reneged ) {
if ((tpcb->tp_class == TP_CLASS_4) &&
(tpcb->tp_reneged || acking_ooo)) {
/*
* Ack subsequence parameter req'd if WE reneged on
* credit offered. (ISO 8073, 12.2.3.8.2, p. 74)
@ -620,8 +631,14 @@ tp_emit(dutype, tpcb, seq, eot, data)
}
tpcb->tp_reneged = 0;
tpcb->tp_sent_rcvnxt = seq;
tp_ctimeout(tpcb->tp_refp, TM_sendack,
(int)tpcb->tp_keepalive_ticks);
if (tpcb->tp_fcredit == 0) {
int timo = tpcb->tp_keepalive_ticks;
if (tpcb->tp_rxtshift < TP_MAXRXTSHIFT)
tpcb->tp_rxtshift++;
timo = min(timo, ((int)tpcb->tp_dt_ticks) << tpcb->tp_rxtshift);
tp_ctimeout(tpcb, TM_sendack, timo);
} else
tp_ctimeout(tpcb, TM_sendack, tpcb->tp_keepalive_ticks);
IncStat(ts_AK_sent);
IncPStat(tpcb, tps_AK_sent);
IFDEBUG(D_ACKSEND)
@ -717,9 +734,13 @@ tp_emit(dutype, tpcb, seq, eot, data)
tpcb->tp_nlproto->nlp_output, tpcb->tp_netservice, error, datalen);
ENDTRACE
done:
if( error == E_CO_QFULL ) {
tp_quench(tpcb, PRC_QUENCH);
return 0;
if (error) {
if (dutype == AK_TPDU_type)
tp_ctimeout(tpcb, TM_sendack, 1);
if (error == E_CO_QFULL) {
tp_quench(tpcb, PRC_QUENCH);
return 0;
}
}
return error;
}
@ -757,7 +778,7 @@ tp_error_emit(error, sref, faddr, laddr, erdata, erlen, tpcb, cons_channel,
struct mbuf *erdata;
int erlen;
struct tp_pcb *tpcb;
int cons_channel;
caddr_t cons_channel;
int (*dgout_routine)();
{
int dutype;
@ -834,6 +855,7 @@ tp_error_emit(error, sref, faddr, laddr, erdata, erlen, tpcb, cons_channel,
IncStat(ts_ER_sent);
hdr->tpdu_li = 5;
hdr->tpdu_ERreason = (char)error;
hdr->tpdu_ERdref = htons(sref);
break;
default:
@ -899,8 +921,7 @@ tp_error_emit(error, sref, faddr, laddr, erdata, erlen, tpcb, cons_channel,
ENDTRACE
datalen = m_datalen( m);
if(tpcb) {
if (tpcb) {
if( tpcb->tp_use_checksum ) {
IFTRACE(D_ERROR_EMIT)
tptrace(TPPTmisc, "before gen csum datalen", datalen,0,0,0);
@ -917,11 +938,27 @@ tp_error_emit(error, sref, faddr, laddr, erdata, erlen, tpcb, cons_channel,
printf("OUTPUT: tpcb 0x%x, isop 0x%x, so 0x%x\n",
tpcb, tpcb->tp_npcb, tpcb->tp_sock);
ENDDEBUG
/* Problem: if packet comes in on ISO but sock is listening
* in INET, this assertion will fail.
* Have to believe the argument, not the nlp_proto.
ASSERT( tpcb->tp_nlproto->nlp_dgoutput == dgout_routine );
*/
}
if (cons_channel) {
#ifdef TPCONS
struct pklcd *lcp = (struct pklcd *)cons_channel;
struct isopcb *isop = (struct isopcb *)lcp->lcd_upnext;
tpcons_dg_output(cons_channel, m, datalen);
/* was if (tpcb == 0) iso_pcbdetach(isop); */
/* but other side may want to try again over same VC,
so, we'll depend on him closing it, but in case it gets forgotten
we'll mark it for garbage collection */
lcp->lcd_flags |= X25_DG_CIRCUIT;
IFDEBUG(D_ERROR_EMIT)
printf("OUTPUT: dutype 0x%x channel 0x%x\n",
dutype, cons_channel);
ENDDEBUG
#else
printf("TP panic! cons channel 0x%x but not cons configured\n",
cons_channel);
#endif
} else if (tpcb) {
IFDEBUG(D_ERROR_EMIT)
printf("tp_error_emit 1 sending DG: Laddr\n");
@ -934,38 +971,22 @@ tp_error_emit(error, sref, faddr, laddr, erdata, erlen, tpcb, cons_channel,
&faddr->siso_addr,
m, datalen,
/* no route */ (caddr_t)0, !tpcb->tp_use_checksum);
} else {
if( cons_channel ) {
#ifdef TPCONS
tpcons_dg_output(cons_channel, m, datalen);
pk_disconnect((struct pklcd *)cons_channel);
IFDEBUG(D_ERROR_EMIT)
printf("OUTPUT: dutype 0x%x channel 0x%x\n",
dutype, cons_channel);
ENDDEBUG
#else
printf("TP panic! cons channel 0x%x but not cons configured\n",
cons_channel);
#endif
} else {
#ifndef notdef
} else if (dgout_routine) {
IFDEBUG(D_ERROR_EMIT)
printf("tp_error_emit sending DG: Laddr\n");
dump_addr((struct sockaddr *)laddr);
printf("Faddr\n");
dump_addr((struct sockaddr *)faddr);
ENDDEBUG
return (*dgout_routine)( &laddr->siso_addr, &faddr->siso_addr,
m, datalen, /* no route */
(caddr_t)0, /* nochecksum==false */0);
#else notdef
return (*dgout_routine)( &laddr->siso_addr, &faddr->siso_addr,
m, datalen, /* no route */
(caddr_t)0, /* nochecksum==false */0);
} else {
IFDEBUG(D_ERROR_EMIT)
printf("tp_error_emit DROPPING \n", m);
ENDDEBUG
IncStat(ts_send_drop);
m_freem(m);
return 0;
#endif notdef
}
}
}

View File

@ -1,4 +1,4 @@
/* $Id: tp_events.h,v 1.2 1993/05/20 05:27:37 cgd Exp $ */
/* $Id: tp_events.h,v 1.3 1994/05/13 06:09:18 mycroft Exp $ */
struct tp_event {
int ev_number;

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,8 +30,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)tp_inet.c 7.8 (Berkeley) 5/6/91
* $Id: tp_inet.c,v 1.5 1994/01/10 22:01:47 mycroft Exp $
* from: @(#)tp_inet.c 8.1 (Berkeley) 6/10/93
* $Id: tp_inet.c,v 1.6 1994/05/13 06:09:20 mycroft Exp $
*/
/***********************************************************
@ -61,8 +61,6 @@ SOFTWARE.
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
*/
/*
* ARGO TP
*
* Here is where you find the inet-dependent code. We've tried
* keep all net-level and (primarily) address-family-dependent stuff
* out of the tp source, and everthing here is reached indirectly
@ -100,9 +98,7 @@ SOFTWARE.
#include <netiso/tp_trace.h>
#include <netiso/tp_stat.h>
#include <netiso/tp_tpdu.h>
#include <netinet/in_var.h>
#include <netinet/ip_var.h>
#ifndef ISO
#include <netiso/iso_chksum.c>
@ -313,102 +309,32 @@ in_getnetaddr( inp, name, which)
* NAME: tpip_mtu()
*
* CALLED FROM:
* tp_input() on incoming CR, CC, and pr_usrreq() for PRU_CONNECT
* tp_route_to() on incoming CR, CC, and pr_usrreq() for PRU_CONNECT
*
* FUNCTION, ARGUMENTS, and RETURN VALUE:
*
* Determine the proper maximum transmission unit, i.e., MTU, to use, given
* a) the header size for the network protocol and the max transmission
* unit on the subnet interface, determined from the information in (inp),
* b) the max size negotiated so far (negot)
* c) the window size used by the tp connection (found in so),
*
* The result is put in the integer *size in its integer form and in
* *negot in its logarithmic form.
*
* The rules are:
* a) can only negotiate down from the value found in *negot.
* b) the MTU must be < the windowsize,
* c) If src and dest are on the same net,
* we will negotiate the closest size larger than MTU but really USE
* the actual device mtu - ll hdr sizes.
* otherwise we negotiate the closest size smaller than MTU - ll hdr sizes.
* Perform subnetwork dependent part of determining MTU information.
* It appears that setting a double pointer to the rtentry associated with
* the destination, and returning the header size for the network protocol
* suffices.
*
* SIDE EFFECTS:
* changes the values addressed by the arguments (size) and (negot)
* and
* when the peer is not on one of our directly connected subnets, it
* looks up a route, leaving the route in the inpcb addressed by (inp)
* Sets tp_routep pointer in pcb.
*
* NOTES:
*/
void
tpip_mtu(so, inp, size, negot)
struct socket *so;
struct inpcb *inp;
int *size;
u_char *negot;
tpip_mtu(tpcb)
register struct tp_pcb *tpcb;
{
register struct ifnet *ifp;
struct ifnet *tpip_route();
struct in_ifaddr *ia;
register int i;
int windowsize = so->so_rcv.sb_hiwat;
struct inpcb *inp = (struct inpcb *)tpcb->tp_npcb;
IFDEBUG(D_CONN)
printf("tpip_mtu(0x%x,0x%x,0x%x,0x%x)\n",
so, inp, size, negot);
printf("tpip_mtu routing to addr 0x%x\n", inp->inp_faddr);
printf("tpip_mtu(tpcb)\n", tpcb);
printf("tpip_mtu routing to addr 0x%x\n", inp->inp_faddr.s_addr);
ENDDEBUG
IFTRACE(D_CONN)
tptrace(TPPTmisc, "ENTER GET MTU: size negot \n",*size, *negot, 0, 0);
ENDTRACE
*size = 1 << *negot;
if( *size > windowsize ) {
*size = windowsize;
}
ia = in_iaonnetof(in_netof(inp->inp_faddr));
if ( ia == (struct in_ifaddr *)0 ) {
ifp = tpip_route(&inp->inp_faddr);
if( ifp == (struct ifnet *)0 )
return ;
} else
ifp = ia->ia_ifp;
/****************************************************************
* TODO - make this indirect off the socket structure to the
* network layer to get headersize
* After all, who knows what lies below the IP layer?
* Who knows how big the NL header will be?
***************************************************************/
if( *size > ifp->if_mtu - sizeof(struct ip)) {
*size = ifp->if_mtu - sizeof(struct ip);
}
for(i=TP_MIN_TPDUSIZE; (i<TP_MAX_TPDUSIZE && ((1<<i)<*size)) ; i++)
;
i--;
if (in_netof(inp->inp_laddr) != in_netof(inp->inp_faddr)) {
i++;
} else {
*size = 1<<i;
}
*negot = i;
IFDEBUG(D_CONN)
printf("GET MTU RETURNS: ifp %s size 0x%x negot 0x%x\n",
ifp->if_name, *size, *negot);
ENDDEBUG
IFTRACE(D_CONN)
tptrace(TPPTmisc, "EXIT GET MTU: tpcb size negot \n",
*size, *negot, 0, 0);
ENDTRACE
tpcb->tp_routep = &(inp->inp_route.ro_rt);
return (sizeof (struct ip));
}
@ -505,7 +431,7 @@ tpip_output_dg(laddr, faddr, m0, datalen, ro, nochksum)
dump_mbuf(m, "tpip_output_dg before ip_output\n");
ENDDEBUG
error = ip_output(m, NULL, ro, IP_ALLOWBROADCAST, NULL); /* XXX */
error = ip_output(m, (struct mbuf *)0, ro, IP_ALLOWBROADCAST, NULL);
IFDEBUG(D_EMIT)
printf("tpip_output_dg after ip_output\n");
@ -534,7 +460,7 @@ bad:
*
* NOTES:
*/
ProtoHook
void
tpip_input(m, iplen)
struct mbuf *m;
int iplen;
@ -601,9 +527,9 @@ tpip_input(m, iplen)
dst.sin_family = AF_INET;
dst.sin_len = sizeof(dst);
(void) tp_input(m, (struct sockaddr *)&src, (struct sockaddr *)&dst,
0, tpip_output_dg, 0);
return 0;
tp_input(m, (struct sockaddr *)&src, (struct sockaddr *)&dst, 0,
tpip_output_dg, 0);
return;
discard:
IFDEBUG(D_TPINPUT)
@ -615,7 +541,6 @@ discard:
m_freem(m);
IncStat(ts_recv_drop);
splx(s);
return 0;
}
@ -641,7 +566,7 @@ void
tpin_quench(inp)
struct inpcb *inp;
{
tp_quench((struct tp_pcb *)inp->inp_socket->so_tpcb, PRC_QUENCH);
tp_quench((struct tp_pcb *)inp->inp_socket->so_pcb, PRC_QUENCH);
}
/*
@ -664,27 +589,27 @@ tpin_quench(inp)
*
* NOTES:
*/
ProtoHook
void
tpip_ctlinput(cmd, sin)
int cmd;
struct sockaddr_in *sin;
{
extern u_char inetctlerrmap[];
extern ProtoHook tpin_abort();
extern ProtoHook in_rtchange();
extern struct in_addr zeroin_addr;
void tp_quench __P((struct inpcb *, int));
void tpin_abort __P((struct inpcb *, int));
if (sin->sin_family != AF_INET && sin->sin_family != AF_IMPLINK)
return 0;
return;
if (sin->sin_addr.s_addr == INADDR_ANY)
return 0;
return;
if (cmd < 0 || cmd > PRC_NCMDS)
return 0;
return;
switch (cmd) {
case PRC_QUENCH:
in_pcbnotify(&tp_inpcb, sin, 0,
zeroin_addr, 0, cmd, (int (*)())tp_quench);
in_pcbnotify(&tp_inpcb, (struct sockaddr *)sin, 0,
zeroin_addr, 0, cmd, tp_quench);
break;
case PRC_ROUTEDEAD:
@ -692,7 +617,7 @@ tpip_ctlinput(cmd, sin)
case PRC_UNREACH_NET:
case PRC_IFDOWN:
case PRC_HOSTDEAD:
in_pcbnotify(&tp_inpcb, sin, 0,
in_pcbnotify(&tp_inpcb, (struct sockaddr *)sin, 0,
zeroin_addr, 0, cmd, in_rtchange);
break;
@ -712,10 +637,9 @@ tpip_ctlinput(cmd, sin)
case PRC_TIMXCEED_REASS:
case PRC_PARAMPROB:
*/
in_pcbnotify(&tp_inpcb, sin, 0, zeroin_addr, 0,
cmd, tpin_abort);
in_pcbnotify(&tp_inpcb, (struct sockaddr *)sin, 0,
zeroin_addr, 0, cmd, tpin_abort);
}
return 0;
}
/*
@ -737,16 +661,16 @@ tpip_ctlinput(cmd, sin)
* NOTES:
*/
ProtoHook
tpin_abort(inp)
void
tpin_abort(inp, n)
struct inpcb *inp;
int n;
{
struct tp_event e;
e.ev_number = ER_TPDU;
e.ATTR(ER_TPDU).e_reason = ENETRESET;
(void) tp_driver((struct tp_pcb *)inp->inp_ppcb, &e);
return 0;
tp_driver((struct tp_pcb *)inp->inp_ppcb, &e);
}
#ifdef ARGO_DEBUG
@ -755,66 +679,5 @@ dump_inaddr(addr)
{
printf("INET: port 0x%x; addr 0x%x\n", addr->sin_port, addr->sin_addr);
}
#endif ARGO_DEBUG
/*
* NAME: tpip_route()
*
* CALLED FROM: tpip_mtu()
*
* FUNCTION and ARGUMENTS: given a destination addresss,
* find the interface that would be used to send something to this address.
*
* RETURNS: pointer to an ifnet structure
*
* SIDE EFFECTS:
*
* NOTES:
*/
struct ifnet *
tpip_route(dst)
struct in_addr *dst;
{
struct ifnet *ifp = (struct ifnet *)0;
struct sockaddr_in insock;
struct sockaddr_in *sin = &insock;
struct rtentry *rt;
struct ifaddr *ia;
IFDEBUG(D_CONN)
printf("tpip_route: dst is x%x\n", *dst);
ENDDEBUG
bzero((caddr_t)sin, sizeof (*sin));
sin->sin_family = AF_INET;
sin->sin_len = sizeof(*sin);
sin->sin_addr = *dst;
ia = ifa_ifwithdstaddr((struct sockaddr *)sin);
if (ia == 0)
ia = ifa_ifwithnet((struct sockaddr *)sin);
if (ia != 0) {
ifp = ia->ifa_ifp;
IFDEBUG(D_CONN)
printf("tpip_route: ifp from ia:0x%x\n", ia);
ENDDEBUG
} else {
rt = rtalloc1((struct sockaddr *)sin, 0);
if (rt != 0) {
ifp = rt->rt_ifp;
IFDEBUG(D_CONN)
printf("tpip_route: ifp from rentry: 0x%x\n", rt);
ENDDEBUG
rtfree(rt);
}
}
IFDEBUG(D_CONN)
printf("tpip_route: returning 0x%x\n", ifp);
if (ifp)
printf("tpip_route: if name %s unit 0x%x, mtu 0x%x\n",
ifp->if_name, ifp->if_unit, ifp->if_mtu);
ENDDEBUG
return ifp;
}
#endif INET
#endif /* ARGO_DEBUG */
#endif /* INET */

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,8 +30,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)tp_input.c 7.19 (Berkeley) 6/27/91
* $Id: tp_input.c,v 1.3 1993/12/18 00:43:36 mycroft Exp $
* from: @(#)tp_input.c 8.1 (Berkeley) 6/10/93
* $Id: tp_input.c,v 1.4 1994/05/13 06:09:22 mycroft Exp $
*/
/***********************************************************
@ -61,13 +61,11 @@ SOFTWARE.
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
*/
/*
* ARGO TP
*
* tp_input() gets an mbuf chain from ip. Actually, not directly
* from ip, because ip calls a net-level routine that strips off
* the net header and then calls tp_input(), passing the proper type
* of addresses for the address family in use (how it figures out
* which AF is not yet determined.
* which AF is not yet determined.)
*
* Decomposing the tpdu is some of the most laughable code. The variable-length
* parameters and the problem of non-aligned memory references
@ -94,9 +92,6 @@ SOFTWARE.
#include <sys/errno.h>
#include <sys/time.h>
#include <sys/kernel.h>
#include <sys/types.h>
#include <net/if.h>
#include <netiso/iso.h>
#include <netiso/iso_errno.h>
@ -109,6 +104,7 @@ SOFTWARE.
#include <netiso/tp_trace.h>
#include <netiso/tp_tpdu.h>
#include <net/if.h>
#ifdef TRUE
#undef FALSE
#undef TRUE
@ -137,9 +133,21 @@ tp_inputprep(m)
ENDDEBUG
while( m->m_len < 1 ) {
if( (m = m_free(m)) == MNULL ) {
return (struct mbuf *)0;
}
/* The "m_free" logic
* if( (m = m_free(m)) == MNULL )
* return (struct mbuf *)0;
* would cause a system crash if ever executed.
* This logic will be executed if the first mbuf
* in the chain only contains a CLNP header. The m_free routine
* will release the mbuf containing the CLNP header from the
* chain and the new head of the chain will not have the
* M_PKTHDR bit set. This routine, tp_inputprep, will
* eventually call the "sbappendaddr" routine. "sbappendaddr"
* calls "panic" if M_PKTHDR is not set. m_pullup is a cheap
* way of keeping the head of the chain from being freed.
*/
if((m = m_pullup(m, 1)) == MNULL)
return (MNULL);
}
if(((int)m->m_data) & 0x3) {
/* If we are not 4-byte aligned, we have to be
@ -149,7 +157,7 @@ tp_inputprep(m)
caddr_t ocp = m->m_data;
m->m_data = (caddr_t)(((int)m->m_data) & ~0x3);
ovbcopy(ocp, m->m_data, (unsigned)m->m_len);
bcopy(ocp, m->m_data, (unsigned)m->m_len);
}
CHANGE_MTYPE(m, TPMT_DATA);
@ -208,11 +216,9 @@ static u_char tpdu_info[][4] =
};
#define CHECK(Phrase, Erval, Stat, Whattodo, Loc)\
if (Phrase) {error = (Erval); errlen = (int)(Loc); IncStat(Stat); tpibrk();\
if (Phrase) {error = (Erval); errlen = (int)(Loc); IncStat(Stat);\
goto Whattodo; }
tpibrk() {}
/*
* WHENEVER YOU USE THE FOLLOWING MACRO,
* BE SURE THE TPDUTYPE IS A LEGIT VALUE FIRST!
@ -255,7 +261,7 @@ static struct socket *
tp_newsocket(so, fname, cons_channel, class_to_use, netservice)
struct socket *so;
struct sockaddr *fname;
u_int cons_channel;
caddr_t cons_channel;
u_char class_to_use;
u_int netservice;
{
@ -306,7 +312,6 @@ tp_newsocket(so, fname, cons_channel, class_to_use, netservice)
newtpcb->tp_l_tpdusize = tpcb->tp_l_tpdusize;
newtpcb->tp_lsuffixlen = tpcb->tp_lsuffixlen;
bcopy( tpcb->tp_lsuffix, newtpcb->tp_lsuffix, newtpcb->tp_lsuffixlen);
soreserve(so, (u_long)tpcb->tp_winsize, (u_long)tpcb->tp_winsize);
if( /* old */ tpcb->tp_ucddata) {
/*
@ -376,7 +381,7 @@ tpcons_output()
{
return(0);
}
#endif !CONS
#endif /* !CONS */
/*
* NAME: tp_input()
@ -404,41 +409,49 @@ tpcons_output()
* mustn't be zero.
* 2 seems like a reasonable minimum.
*/
ProtoHook
void
tp_input(m, faddr, laddr, cons_channel, dgout_routine, ce_bit)
register struct mbuf *m;
struct sockaddr *faddr, *laddr; /* NSAP addresses */
u_int cons_channel;
caddr_t cons_channel;
int (*dgout_routine)();
int ce_bit;
{
register struct tp_pcb *tpcb = (struct tp_pcb *)0;
register struct tp_pcb *tpcb;
register struct tpdu *hdr;
struct socket *so;
struct tp_event e;
int error = 0;
int error;
unsigned dutype;
u_short dref, sref = 0, acktime = 2, subseq = 0; /*VAX*/
u_char preferred_class = 0, class_to_use = 0;
u_char opt, dusize = TP_DFL_TPDUSIZE, addlopt = 0, version;
u_short dref, sref, acktime, subseq;
u_char preferred_class, class_to_use, pdusize;
u_char opt, dusize, addlopt, version;
#ifdef TP_PERF_MEAS
u_char perf_meas;
#endif TP_PERF_MEAS
u_char fsufxlen = 0, lsufxlen = 0, intercepted = 0;
caddr_t fsufxloc = 0, lsufxloc = 0;
int tpdu_len = 0;
u_int takes_data = FALSE;
u_int fcc_present = FALSE;
int errlen = 0;
#endif /* TP_PERF_MEAS */
u_char fsufxlen, lsufxlen;
caddr_t fsufxloc, lsufxloc;
int tpdu_len;
u_int takes_data;
u_int fcc_present;
int errlen;
struct tp_conn_param tpp;
int tpcons_output();
again:
hdr = mtod(m, struct tpdu *);
tpcb = 0;
error = errlen = tpdu_len = 0;
takes_data = fcc_present = FALSE;
acktime = 2; sref = subseq = 0;
fsufxloc = lsufxloc = NULL;
fsufxlen = lsufxlen =
preferred_class = class_to_use = pdusize = addlopt = 0;
dusize = TP_DFL_TPDUSIZE;
#ifdef TP_PERF_MEAS
GET_CUR_TIME( &e.e_time ); perf_meas = 0;
#endif TP_PERF_MEAS
#endif /* TP_PERF_MEAS */
IFDEBUG(D_TPINPUT)
printf("tp_input(0x%x, ... 0x%x)\n", m, cons_channel);
@ -507,7 +520,7 @@ again:
IncStat(ts_inv_dutype);
goto discard;
}
#endif ARGO_DEBUG
#endif /* ARGO_DEBUG */
CHECK( (dutype < TP_MIN_TPDUTYPE || dutype > TP_MAX_TPDUTYPE),
E_TP_INV_TPDU, ts_inv_dutype, respond,
@ -539,6 +552,16 @@ again:
if (dusize < TP_MIN_TPDUSIZE || dusize > TP_MAX_TPDUSIZE)
dusize = TP_DFL_TPDUSIZE;
break;
case TPP_ptpdu_size:
switch (vbptr(P)->tpv_len) {
case 1: pdusize = vbval(P, u_char); break;
case 2: pdusize = ntohs(vbval(P, u_short)); break;
default: ;
IFDEBUG(D_TPINPUT)
printf("malformed prefered TPDU option\n");
ENDDEBUG
}
break;
case TPP_addl_opt:
vb_getval(P, u_char, addlopt);
break;
@ -579,7 +602,7 @@ again:
case TPP_perf_meas:
vb_getval(P, u_char, perf_meas);
break;
#endif TP_PERF_MEAS
#endif /* TP_PERF_MEAS */
case TPP_vers:
/* not in class 0; 1 octet; in CR_TPDU only */
@ -660,21 +683,27 @@ again:
goto respond;
} else {
register struct tp_pcb *t;
for (t = tp_intercepts; t ; t = t->tp_nextlisten) {
if (laddr->sa_family != t->tp_nlproto->nlp_afamily)
continue;
if ((*t->tp_nlproto->nlp_cmpnetaddr)(
t->tp_npcb, laddr, TP_LOCAL)) {
intercepted = 1;
goto check_duplicate_cr;
}
}
/*
* The intention here is to trap all CR requests
* to a given nsap, for constructing transport
* service bridges at user level; so these
* intercepts should precede the normal listens.
* Phrasing the logic in this way also allows for
* mop-up listeners, which we don't currently implement.
* We also wish to have a single socket be able to
* listen over any network service provider,
* (cons or clns or ip).
*/
for (t = tp_listeners; t ; t = t->tp_nextlisten)
if (lsufxlen == t->tp_lsuffixlen &&
bcmp(lsufxloc, t->tp_lsuffix, lsufxlen) == 0 &&
laddr->sa_family == t->tp_nlproto->nlp_afamily)
break;
if ((t->tp_lsuffixlen == 0 ||
(lsufxlen == t->tp_lsuffixlen &&
bcmp(lsufxloc, t->tp_lsuffix, lsufxlen) == 0)) &&
((t->tp_flags & TPF_GENERAL_ADDR) ||
(laddr->sa_family == t->tp_domain &&
(*t->tp_nlproto->nlp_cmpnetaddr)
(t->tp_npcb, laddr, TP_LOCAL))))
break;
CHECK(t == 0, E_TP_NO_SESSION, ts_inv_sufx, respond,
(1 + 2 + (caddr_t)&hdr->_tpduf - (caddr_t)hdr))
/* _tpduf is the fixed part; add 2 to get the dref bits of
@ -683,7 +712,6 @@ again:
IFDEBUG(D_TPINPUT)
printf("checking if dup CR\n");
ENDDEBUG
check_duplicate_cr:
tpcb = t;
for (t = tpcb->tp_next; t != tpcb; t = t->tp_next) {
if (sref != t->tp_fref)
@ -728,6 +756,7 @@ again:
tpp = tpcb->_tp_param;
tpp.p_class = class_to_use;
tpp.p_tpdusize = dusize;
tpp.p_ptpdusize = pdusize;
tpp.p_xtd_format = (opt & TPO_XTD_FMT) == TPO_XTD_FMT;
tpp.p_xpd_service = (addlopt & TPAO_USE_TXPD) == TPAO_USE_TXPD;
tpp.p_use_checksum = (tpp.p_class == TP_CLASS_0)?0:
@ -737,11 +766,11 @@ again:
tpp.p_use_efc = (opt & TPO_USE_EFC) == TPO_USE_EFC;
tpp.p_use_nxpd = (addlopt & TPAO_USE_NXPD) == TPAO_USE_NXPD;
tpp.p_use_rcc = (addlopt & TPAO_USE_RCC) == TPAO_USE_RCC;
#endif notdef
#endif /* notdef */
CHECK(
tp_consistency(tpcb, 0 /* not force or strict */, &tpp) != 0,
E_TP_NEGOT_FAILED, ts_negotfailed, respond,
E_TP_NEGOT_FAILED, ts_negotfailed, clear_parent_tcb,
(1 + 2 + (caddr_t)&hdr->_tpdufr.CRCC - (caddr_t)hdr)
/* ^ more or less the location of class */
)
@ -755,7 +784,7 @@ again:
ENDTRACE
CHECK(
((class_to_use == TP_CLASS_0)&&(dgout_routine != tpcons_output)),
E_TP_NEGOT_FAILED, ts_negotfailed, respond,
E_TP_NEGOT_FAILED, ts_negotfailed, clear_parent_tcb,
(1 + 2 + (caddr_t)&hdr->_tpdufr.CRCC - (caddr_t)hdr)
/* ^ more or less the location of class */
)
@ -792,6 +821,9 @@ again:
printf("tp_newsocket returns 0\n");
ENDDEBUG
goto discard;
clear_parent_tcb:
tpcb = 0;
goto respond;
}
tpcb = sototpcb(so);
insque(tpcb, parent_tpcb);
@ -801,18 +833,20 @@ again:
* kind of like a pcbconnect() but don't need
* or want all those checks.
*/
(tpcb->tp_nlproto->nlp_putnetaddr)(so->so_pcb, faddr, TP_FOREIGN);
(tpcb->tp_nlproto->nlp_putnetaddr)(so->so_pcb, laddr, TP_LOCAL);
(tpcb->tp_nlproto->nlp_putnetaddr)(tpcb->tp_npcb, faddr, TP_FOREIGN);
(tpcb->tp_nlproto->nlp_putnetaddr)(tpcb->tp_npcb, laddr, TP_LOCAL);
/* stash the f suffix in the new tpcb */
bcopy(fsufxloc, tpcb->tp_fsuffix, fsufxlen);
/* l suffix is already there, unless this is an intercept case */
if (intercepted)
bcopy(lsufxloc, tpcb->tp_lsuffix, lsufxlen);
if (tpcb->tp_fsuffixlen = fsufxlen) {
bcopy(fsufxloc, tpcb->tp_fsuffix, fsufxlen);
(tpcb->tp_nlproto->nlp_putsufx)
(tpcb->tp_npcb, fsufxloc, fsufxlen, TP_FOREIGN);
}
/* stash the l suffix in the new tpcb */
tpcb->tp_lsuffixlen = lsufxlen;
bcopy(lsufxloc, tpcb->tp_lsuffix, lsufxlen);
(tpcb->tp_nlproto->nlp_putsufx)
(so->so_pcb, fsufxloc, fsufxlen, TP_FOREIGN);
(tpcb->tp_nlproto->nlp_putsufx)
(so->so_pcb, lsufxloc, lsufxlen, TP_LOCAL);
(tpcb->tp_npcb, lsufxloc, lsufxlen, TP_LOCAL);
#ifdef TP_PERF_MEAS
if( tpcb->tp_perf_on = perf_meas ) { /* assignment */
/* ok, let's create an mbuf for stashing the
@ -820,7 +854,7 @@ again:
*/
(void) tp_setup_perf(tpcb);
}
#endif TP_PERF_MEAS
#endif /* TP_PERF_MEAS */
tpcb->tp_fref = sref;
/* We've already checked for consistency with the options
@ -837,12 +871,6 @@ again:
if(tpcb->tp_xtd_format)
IncStat(ts_xtd_fmt);
/*
* Get the maximum transmission unit from the lower layer(s)
* so we can negotiate a reasonable max TPDU size.
*/
(tpcb->tp_nlproto->nlp_mtu)(so, so->so_pcb,
&tpcb->tp_l_tpdusize, &tpcb->tp_tpdusize, 0);
tpcb->tp_peer_acktime = acktime;
/*
@ -854,15 +882,14 @@ again:
/*tpcb->tp_fref = 0;*/
ENDDEBUG
}
LOCAL_CREDIT(tpcb);
IncStat(ts_CR_rcvd);
if (!tpcb->tp_cebit_off) {
tpcb->tp_win_recv = tp_start_win << 8;
tpcb->tp_cong_sample.cs_size = 0;
LOCAL_CREDIT(tpcb);
CONG_INIT_SAMPLE(tpcb);
CONG_UPDATE_SAMPLE(tpcb, ce_bit);
}
tpcb->tp_ackrcvd = 0;
} else if ( dutype == ER_TPDU_type ) {
/*
* ER TPDUs have to be recognized separately
@ -877,10 +904,10 @@ again:
IncStat(ts_ER_rcvd);
e.ev_number = ER_TPDU;
e.ATTR(ER_TPDU).e_reason = (u_char)hdr->tpdu_ERreason;
CHECK (((int)dref <= 0 || dref >= N_TPREF ||
CHECK (((int)dref <= 0 || dref >= tp_refinfo.tpr_size ||
(tpcb = tp_ref[dref].tpr_pcb ) == (struct tp_pcb *) 0 ||
tpcb->tp_refp->tpr_state == REF_FREE ||
tpcb->tp_refp->tpr_state == REF_FROZEN),
tpcb->tp_refstate == REF_FREE ||
tpcb->tp_refstate == REF_FROZEN),
E_TP_MISM_REFS, ts_inv_dref, discard, 0)
} else {
@ -890,44 +917,35 @@ again:
* _tpduf is the fixed part; add 2 to get the dref bits of
* the fixed part (can't take the address of a bit field)
*/
#ifdef old_history
if(cons_channel) {
#ifdef NARGOXTWENTYFIVE
extern struct tp_pcb *cons_chan_to_tpcb();
#ifdef TPCONS
if (cons_channel && dutype == DT_TPDU_type) {
struct isopcb *isop = ((struct isopcb *)
((struct pklcd *)cons_channel)->lcd_upnext);
if (isop && isop->isop_refcnt == 1 && isop->isop_socket &&
(tpcb = sototpcb(isop->isop_socket)) &&
(tpcb->tp_class == TP_CLASS_0/* || == CLASS_1 */)) {
IFDEBUG(D_TPINPUT)
printf("tpinput_dt: class 0 short circuit\n");
ENDDEBUG
dref = tpcb->tp_lref;
sref = tpcb->tp_fref;
CHECK( (tpcb->tp_refstate == REF_FREE),
E_TP_MISM_REFS,ts_inv_dref, nonx_dref,
(1 + 2 + (caddr_t)&hdr->_tpduf - (caddr_t)hdr))
goto tp0_data;
}
tpcb = cons_chan_to_tpcb( cons_channel );
/* Problem: We may have a legit
* error situation yet we may or may not have
* a correspondence between the tpcb and the vc,
* e.g., TP4cr--> <no dice, respond w/ DR on vc>
* <--- DR
* Now it's up to TP to look at the tpdu and do one of:
* confirm(dgm)(cr), confirm(circuit)(cr), reject(cr), or
* nothing, if the circuit is already open (any other tpdu).
* Sigh.
*/
/* I don't know about this error value */
CHECK( (tpcb == (struct tp_pcb *)0) ,
E_TP_NO_CR_ON_NC, ts_inv_dref, respond,
(1 + 2 + (caddr_t)&hdr->_tpduf - (caddr_t)hdr))
#else
printf("tp_input(): X25 NOT CONFIGURED!!\n");
}
#endif
} else
/* we've now made the error reporting thing check for
multiple channels and not close out if more than
one in use */
#endif old_history
{
CHECK( ((int)dref <= 0 || dref >= N_TPREF) ,
CHECK( ((int)dref <= 0 || dref >= tp_refinfo.tpr_size) ,
E_TP_MISM_REFS,ts_inv_dref, nonx_dref,
(1 + 2 + (caddr_t)&hdr->_tpduf - (caddr_t)hdr))
CHECK( ((tpcb = tp_ref[dref].tpr_pcb ) == (struct tp_pcb *) 0 ),
E_TP_MISM_REFS,ts_inv_dref, nonx_dref,
(1 + 2 + (caddr_t)&hdr->_tpduf - (caddr_t)hdr))
CHECK( (tpcb->tp_refp->tpr_state == REF_FREE),
CHECK( (tpcb->tp_refstate == REF_FREE),
E_TP_MISM_REFS,ts_inv_dref, nonx_dref,
(1 + 2 + (caddr_t)&hdr->_tpduf - (caddr_t)hdr))
}
@ -937,7 +955,7 @@ again:
ENDDEBUG
/* causes a DR to be sent for CC; ER for all else */
CHECK( (tpcb->tp_refp->tpr_state == REF_FROZEN),
CHECK( (tpcb->tp_refstate == REF_FROZEN),
(dutype == CC_TPDU_type?E_TP_NO_SESSION:E_TP_MISM_REFS),
ts_inv_dref, respond,
(1 + 2 + (caddr_t)&hdr->_tpduf - (caddr_t)hdr))
@ -958,6 +976,7 @@ again:
CONG_UPDATE_SAMPLE(tpcb, ce_bit);
dusize = tpcb->tp_tpdusize;
pdusize = tpcb->tp_ptpdusize;
dutype = hdr->tpdu_type << 8; /* for the switch below */
@ -983,6 +1002,23 @@ again:
ENDDEBUG
}
break;
caseof( CC_TPDU_type, TPP_ptpdu_size ):
{
u_short opdusize = pdusize;
switch (vbptr(P)->tpv_len) {
case 1: pdusize = vbval(P, u_char); break;
case 2: pdusize = ntohs(vbval(P, u_short)); break;
default: ;
IFDEBUG(D_TPINPUT)
printf("malformed prefered TPDU option\n");
ENDDEBUG
}
CHECK( (pdusize == 0 ||
(opdusize && (pdusize > opdusize))),
E_TP_INV_PVAL, ts_inv_pval, respond,
(1 + (caddr_t)&vbptr(P)->tpv_val - (caddr_t)hdr) )
}
break;
caseof( CC_TPDU_type, TPP_calling_sufx):
IFDEBUG(D_TPINPUT)
printf("CC calling (local) sufxlen 0x%x\n", lsufxlen);
@ -1034,14 +1070,14 @@ again:
* to pass this info to the user anyway
*/
break;
#endif notdef
#endif /* notdef */
caseof( AK_TPDU_type, TPP_subseq ):
/* used after reduction of window */
vb_getval(P, u_short, subseq);
subseq = ntohs(subseq);
IFDEBUG(D_ACKRECV)
printf("AK Subsequence # 0x%x\n", subseq);
printf("AK dref 0x%x Subseq 0x%x\n", dref, subseq);
ENDDEBUG
break;
@ -1058,8 +1094,8 @@ again:
ysubseq = ntohs(ysubseq);
ycredit = ntohs(ycredit);
IFDEBUG(D_ACKRECV)
printf("AK FCC lwe 0x%x, subseq 0x%x, cdt 0x%x\n",
ylwe, ysubseq, ycredit);
printf("%s%x, subseq 0x%x, cdt 0x%x dref 0x%x\n",
"AK FCC lwe 0x", ylwe, ysubseq, ycredit, dref);
ENDDEBUG
}
break;
@ -1093,6 +1129,7 @@ again:
tpp = tpcb->_tp_param;
tpp.p_class = (1<<hdr->tpdu_CCclass);
tpp.p_tpdusize = dusize;
tpp.p_ptpdusize = pdusize;
tpp.p_dont_change_params = 0;
tpp.p_xtd_format = (opt & TPO_XTD_FMT) == TPO_XTD_FMT;
tpp.p_xpd_service = (addlopt & TPAO_USE_TXPD) == TPAO_USE_TXPD;
@ -1101,7 +1138,7 @@ again:
tpp.p_use_efc = (opt & TPO_USE_EFC) == TPO_USE_EFC;
tpp.p_use_nxpd = (addlopt & TPAO_USE_NXPD) == TPAO_USE_NXPD;
tpp.p_use_rcc = (addlopt & TPAO_USE_RCC) == TPAO_USE_RCC;
#endif notdef
#endif /* notdef */
CHECK(
tp_consistency(tpcb, TP_FORCE, &tpp) != 0,
@ -1144,16 +1181,6 @@ again:
hdr->tpdu_CCclass);
ENDTRACE
/*
* Get the maximum transmission unit from the lower layer(s)
* so we can decide how large a TPDU size to negotiate.
* It would be nice if the arguments to this
* were more reasonable.
*/
(tpcb->tp_nlproto->nlp_mtu)(tpcb->tp_sock, tpcb->tp_sock->so_pcb,
&tpcb->tp_l_tpdusize, &tpcb->tp_tpdusize, 0);
/* if called or calling suffices appeared on the CC,
* they'd better jive with what's in the pcb
*/
@ -1235,7 +1262,7 @@ again:
#else
e.ATTR(AK_TPDU).e_cdt = hdr->tpdu_AKcdtX;
e.ATTR(AK_TPDU).e_seq = hdr->tpdu_AKseqX;
#endif BYTE_ORDER
#endif /* BYTE_ORDER */
} else {
e.ATTR(AK_TPDU).e_cdt = hdr->tpdu_AKcdt;
e.ATTR(AK_TPDU).e_seq = hdr->tpdu_AKseq;
@ -1260,7 +1287,7 @@ again:
e.ATTR(XAK_TPDU).e_seq = seqeotX.s_seq;
#else
e.ATTR(XAK_TPDU).e_seq = hdr->tpdu_XAKseqX;
#endif BYTE_ORDER
#endif /* BYTE_ORDER */
} else {
e.ATTR(XAK_TPDU).e_seq = hdr->tpdu_XAKseq;
}
@ -1278,7 +1305,7 @@ again:
e.ATTR(XPD_TPDU).e_seq = seqeotX.s_seq;
#else
e.ATTR(XPD_TPDU).e_seq = hdr->tpdu_XPDseqX;
#endif BYTE_ORDER
#endif /* BYTE_ORDER */
} else {
e.ATTR(XPD_TPDU).e_seq = hdr->tpdu_XPDseq;
}
@ -1301,6 +1328,7 @@ again:
ENDDEBUG
}
if (tpcb->tp_class == TP_CLASS_0) {
tp0_data:
e.ATTR(DT_TPDU).e_seq = 0; /* actually don't care */
e.ATTR(DT_TPDU).e_eot = (((struct tp0du *)hdr)->tp0du_eot);
} else if (tpcb->tp_xtd_format) {
@ -1313,7 +1341,7 @@ again:
#else
e.ATTR(DT_TPDU).e_seq = hdr->tpdu_DTseqX;
e.ATTR(DT_TPDU).e_eot = hdr->tpdu_DTeotX;
#endif BYTE_ORDER
#endif /* BYTE_ORDER */
} else {
e.ATTR(DT_TPDU).e_seq = hdr->tpdu_DTseq;
e.ATTR(DT_TPDU).e_eot = hdr->tpdu_DTeot;
@ -1489,7 +1517,7 @@ separate:
printf("tp_input : after m_freem 0x%x\n", m);
ENDDEBUG
}
return (ProtoHook) tpcb;
return;
discard:
/* class 4: drop the tpdu */
@ -1504,7 +1532,7 @@ discard:
ENDTRACE
m_freem(m);
IncStat(ts_recv_drop);
return (ProtoHook)0;
return;
nonx_dref:
switch (dutype) {
@ -1527,16 +1555,15 @@ respond:
goto discard;
(void) tp_error_emit(error, (u_long)sref, (struct sockaddr_iso *)faddr,
(struct sockaddr_iso *)laddr, m, errlen, tpcb,
(int)cons_channel, dgout_routine);
cons_channel, dgout_routine);
IFDEBUG(D_ERROR_EMIT)
printf("tp_input after error_emit\n");
ENDDEBUG
#ifdef lint
printf("",sref,opt);
#endif lint
#endif /* lint */
IncStat(ts_recv_drop);
return (ProtoHook)0;
}

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,13 +30,10 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)tp_ip.h 7.3 (Berkeley) 5/6/91
* $Id: tp_ip.h,v 1.3 1993/05/20 05:27:42 cgd Exp $
* from: @(#)tp_ip.h 8.1 (Berkeley) 6/10/93
* $Id: tp_ip.h,v 1.4 1994/05/13 06:09:24 mycroft Exp $
*/
#ifndef _NETISO_TP_IP_H_
#define _NETISO_TP_IP_H_
/***********************************************************
Copyright IBM Corporation 1987
@ -64,25 +61,25 @@ SOFTWARE.
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
*/
/*
* ARGO TP
*
* internet IP-dependent structures and include files
*
*/
#ifndef SOCK_STREAM
#include "socket.h"
#endif SOCK_STREAM
#ifndef _NETISO_TP_IP_H_
#define _NETISO_TP_IP_H_
#include "../netinet/in.h"
#include "../netinet/in_systm.h"
#include "../netinet/ip.h"
#include "../net/route.h"
#include "../netinet/in_pcb.h"
#include "../netinet/ip_var.h"
#ifndef SOCK_STREAM
#include <sys/socket.h>
#endif
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <net/route.h>
#include <netinet/in_pcb.h>
#include <netinet/ip_var.h>
struct inpcb tp_inpcb;
/* queue of active inpcbs for tp ; for tp with dod ip */
#endif /* !_NETISO_TP_IP_H_ */
#endif /* _NETISO_TP_IP_H_ */

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,8 +30,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)tp_iso.c 7.11 (Berkeley) 5/6/91
* $Id: tp_iso.c,v 1.3 1993/12/18 00:43:38 mycroft Exp $
* from: @(#)tp_iso.c 8.1 (Berkeley) 6/10/93
* $Id: tp_iso.c,v 1.4 1994/05/13 06:09:25 mycroft Exp $
*/
/***********************************************************
@ -61,8 +61,6 @@ SOFTWARE.
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
*/
/*
* ARGO TP
*
* Here is where you find the iso-dependent code. We've tried
* keep all net-level and (primarily) address-family-dependent stuff
* out of the tp source, and everthing here is reached indirectly
@ -108,6 +106,8 @@ SOFTWARE.
#include <netiso/tp_clnp.h>
#include <netiso/cltp_var.h>
void tpclnp_ctlinput();
/*
* CALLED FROM:
* pr_usrreq() on PRU_BIND, PRU_CONNECT, PRU_ACCEPT, and PRU_PEERADDR
@ -312,103 +312,41 @@ iso_getnetaddr( isop, name, which)
else
name->m_len = 0;
}
/*
* CALLED FROM:
* tp_input() on incoming CR, CC, and pr_usrreq() for PRU_CONNECT
* FUNCTION, ARGUMENTS, SIDE EFFECTS and RETURN VALUE:
* Determine the proper maximum transmission unit, i.e., MTU, to use, given
* a) the header size for the network protocol and the max transmission
* unit on the subnet interface, determined from the information in (isop),
* b) the max size negotiated so far (negot)
* c) the window size used by the tp connection (found in so),
* NAME: tpclnp_mtu()
*
* The result is put in the integer *size in its integer form and in
* *negot in its logarithmic form.
* CALLED FROM:
* tp_route_to() on incoming CR, CC, and pr_usrreq() for PRU_CONNECT
*
* FUNCTION, ARGUMENTS, and RETURN VALUE:
*
* Perform subnetwork dependent part of determining MTU information.
* It appears that setting a double pointer to the rtentry associated with
* the destination, and returning the header size for the network protocol
* suffices.
*
* The rules are:
* a) can only negotiate down from the value found in *negot.
* b) the MTU must be < the windowsize,
* c) If src and dest are on the same net,
* we will negotiate the closest size larger than MTU but really USE
* the actual device mtu - ll hdr sizes.
* otherwise we negotiate the closest size smaller than MTU - ll hdr sizes.
* SIDE EFFECTS:
* Sets tp_routep pointer in pcb.
*
* NOTES:
*/
void
tpclnp_mtu(so, isop, size, negot )
struct socket *so;
struct isopcb *isop;
int *size;
u_char *negot;
tpclnp_mtu(tpcb)
register struct tp_pcb *tpcb;
{
struct ifnet *ifp = 0;
struct iso_ifaddr *ia = 0;
register int i;
int windowsize = so->so_rcv.sb_hiwat;
int clnp_size, mtu;
int sizeismtu = 0;
register struct rtentry *rt = isop->isop_route.ro_rt;
struct isopcb *isop = (struct isopcb *)tpcb->tp_npcb;
IFDEBUG(D_CONN)
printf("tpclnp_mtu(0x%x,0x%x,0x%x,0x%x)\n", so, isop, size, negot);
printf("tpclnp_mtu(tpcb)\n", tpcb);
ENDDEBUG
IFTRACE(D_CONN)
tptrace(TPPTmisc, "ENTER GET MTU: size negot \n",*size, *negot, 0, 0);
ENDTRACE
tpcb->tp_routep = &(isop->isop_route.ro_rt);
if (tpcb->tp_netservice == ISO_CONS)
return 0;
else
return (sizeof(struct clnp_fixed) + sizeof(struct clnp_segment) +
2 * sizeof(struct iso_addr));
*size = 1 << *negot;
if( *size > windowsize ) {
*size = windowsize;
}
if (rt == 0 || (rt->rt_flags & RTF_UP == 0) ||
(ia = (struct iso_ifaddr *)rt->rt_ifa) == 0 ||
(ifp = ia->ia_ifp) == 0) {
IFDEBUG(D_CONN)
printf("tpclnp_mtu routing abort rt=0x%x ia=0x%x ifp=0x%x\n",
rt, ia, ifp)
ENDDEBUG
return;
}
/* TODO - make this indirect off the socket structure to the
* network layer to get headersize
*/
clnp_size = sizeof(struct clnp_fixed) + sizeof(struct clnp_segment) +
2 * sizeof(struct iso_addr);
mtu = SN_MTU(ifp, rt) - clnp_size;
if(*size > mtu) {
*size = mtu;
sizeismtu = 1;
}
/* have to transform size to the log2 of size */
for(i=TP_MIN_TPDUSIZE; (i<=TP_MAX_TPDUSIZE && ((1<<i) <= *size)) ; i++)
;
i--;
IFTRACE(D_CONN)
tptrace(TPPTmisc, "GET MTU MID: tpcb size negot i \n",
*size, *negot, i, 0);
ENDTRACE
*size = 1<<i;
*negot = i;
IFDEBUG(D_CONN)
printf("GET MTU RETURNS: ifp %s size 0x%x negot 0x%x\n",
ifp->if_name, *size, *negot);
ENDDEBUG
IFTRACE(D_CONN)
tptrace(TPPTmisc, "EXIT GET MTU: tpcb size negot \n",
*size, *negot, 0, 0);
ENDTRACE
}
/*
* CALLED FROM:
* tp_emit()
@ -416,7 +354,7 @@ tpclnp_mtu(so, isop, size, negot )
* Take a packet(m0) from tp and package it so that clnp will accept it.
* This means prepending space for the clnp header and filling in a few
* of the fields.
* inp is the isopcb structure; datalen is the length of the data in the
* isop is the isopcb structure; datalen is the length of the data in the
* mbuf string m0.
* RETURN VALUE:
* whatever (E*) is returned form the net layer output routine.
@ -520,15 +458,14 @@ tpclnp_output_dg(laddr, faddr, m0, datalen, ro, nochksum)
* Take a packet (m) from clnp, strip off the clnp header and give it to tp
* No return value.
*/
ProtoHook
void
tpclnp_input(m, src, dst, clnp_len, ce_bit)
register struct mbuf *m;
struct sockaddr_iso *src, *dst;
int clnp_len, ce_bit;
{
int s = splnet();
struct mbuf *tp_inputprep();
int tp_input(), cltp_input(), (*input)() = tp_input;
void tp_input(), cltp_input(), (*input)() = tp_input;
IncStat(ts_pkt_rcvd);
@ -542,13 +479,27 @@ tpclnp_input(m, src, dst, clnp_len, ce_bit)
* First, strip off the Clnp header. leave the mbuf there for the
* pullup that follows.
*/
m->m_len -= clnp_len;
m->m_data += clnp_len;
m->m_pkthdr.len -= clnp_len;
/* XXXX: should probably be in clnp_input */
switch (dst->siso_data[dst->siso_nlen - 1]) {
#ifdef TUBA
case ISOPROTO_TCP:
tuba_tcpinput(m, src, dst);
return;
#endif
case 0:
if (m->m_len == 0 && (m = m_pullup(m, 1)) == 0)
return;
if (*(mtod(m, u_char *)) == ISO10747_IDRP) {
idrp_input(m, src, dst);
return;
}
}
m = tp_inputprep(m);
if (m == 0)
return 0;
return;
if (mtod(m, u_char *)[1] == UD_TPDU_type)
input = cltp_input;
@ -564,31 +515,27 @@ tpclnp_input(m, src, dst, clnp_len, ce_bit)
dump_isoaddr(dst);
ENDDEBUG
(void) (*input)(m, (struct sockaddr *)src, (struct sockaddr *)dst,
0, tpclnp_output_dg, ce_bit);
(*input)(m, (struct sockaddr *)src, (struct sockaddr *)dst, 0,
tpclnp_output_dg, ce_bit);
IFDEBUG(D_QUENCH)
{
if(time.tv_usec & 0x4 && time.tv_usec & 0x40) {
printf("tpclnp_input: FAKING %s\n",
tp_stat.ts_pkt_rcvd & 0x1?"QUENCH":"QUENCH2");
if(tp_stat.ts_pkt_rcvd & 0x1) {
if (tp_stat.ts_pkt_rcvd & 0x1)
tpclnp_ctlinput(PRC_QUENCH, &src);
} else {
else
tpclnp_ctlinput(PRC_QUENCH2, &src);
}
}
}
ENDDEBUG
splx(s);
return 0;
}
ProtoHook
void
iso_rtchange()
{
return 0;
}
/*
@ -601,7 +548,7 @@ void
tpiso_decbit(isop)
struct isopcb *isop;
{
tp_quench((struct tp_pcb *)isop->isop_socket->so_tpcb, PRC_QUENCH2);
tp_quench((struct tp_pcb *)isop->isop_socket->so_pcb, PRC_QUENCH2);
}
/*
* CALLED FROM:
@ -613,7 +560,7 @@ void
tpiso_quench(isop)
struct isopcb *isop;
{
tp_quench((struct tp_pcb *)isop->isop_socket->so_tpcb, PRC_QUENCH);
tp_quench((struct tp_pcb *)isop->isop_socket->so_pcb, PRC_QUENCH);
}
/*
@ -627,16 +574,13 @@ tpiso_quench(isop)
* (cmd) is the type of ICMP error.
* (siso) is the address of the guy who sent the ER CLNPDU
*/
ProtoHook
void
tpclnp_ctlinput(cmd, siso)
int cmd;
struct sockaddr_iso *siso;
{
extern u_char inetctlerrmap[];
extern ProtoHook tpiso_abort();
extern ProtoHook iso_rtchange();
extern ProtoHook tpiso_reset();
void iso_pcbnotify();
void tpiso_abort(), iso_rtchange(), tpiso_reset(), iso_pcbnotify();
IFDEBUG(D_TPINPUT)
printf("tpclnp_ctlinput1: cmd 0x%x addr: \n", cmd);
@ -644,9 +588,9 @@ tpclnp_ctlinput(cmd, siso)
ENDDEBUG
if (cmd < 0 || cmd > PRC_NCMDS)
return 0;
return;
if (siso->siso_family != AF_ISO)
return 0;
return;
switch (cmd) {
case PRC_QUENCH2:
@ -688,7 +632,6 @@ tpclnp_ctlinput(cmd, siso)
iso_pcbnotify(&tp_isopcb, siso, (int)inetctlerrmap[cmd], tpiso_abort);
break;
}
return 0;
}
/*
* XXX - Variant which is called by clnp_er.c with an isoaddr rather
@ -717,7 +660,7 @@ tpclnp_ctlinput1(cmd, isoa)
* abort always aborts the TP connection.
* reset may or may not, depending on the TP class that's in use.
*/
ProtoHook
void
tpiso_abort(isop)
struct isopcb *isop;
{
@ -728,18 +671,18 @@ tpiso_abort(isop)
ENDDEBUG
e.ev_number = ER_TPDU;
e.ATTR(ER_TPDU).e_reason = ECONNABORTED;
return tp_driver((struct tp_pcb *)isop->isop_socket->so_tpcb, &e);
tp_driver((struct tp_pcb *)isop->isop_socket->so_pcb, &e);
}
ProtoHook
void
tpiso_reset(isop)
struct isopcb *isop;
{
struct tp_event e;
e.ev_number = T_NETRESET;
return tp_driver((struct tp_pcb *)isop->isop_socket->so_tpcb, &e);
tp_driver((struct tp_pcb *)isop->isop_socket->so_pcb, &e);
}
#endif ISO
#endif /* ISO */

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,8 +30,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)tp_meas.c 7.4 (Berkeley) 5/6/91
* $Id: tp_meas.c,v 1.4 1993/12/18 00:43:40 mycroft Exp $
* from: @(#)tp_meas.c 8.1 (Berkeley) 6/10/93
* $Id: tp_meas.c,v 1.5 1994/05/13 06:09:26 mycroft Exp $
*/
/***********************************************************
@ -66,7 +66,6 @@ SOFTWARE.
*/
#include <sys/types.h>
#include <sys/cdefs.h>
#include <sys/time.h>
#include <netiso/argo_debug.h>
@ -123,4 +122,4 @@ Tpmeas(ref, kind, timev, seq, win, size)
tpm->tpm_size = size;
}
#endif TP_PERF_MEAS
#endif /* TP_PERF_MEAS */

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,13 +30,10 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)tp_meas.h 7.5 (Berkeley) 5/6/91
* $Id: tp_meas.h,v 1.3 1993/05/20 05:27:46 cgd Exp $
* from: @(#)tp_meas.h 8.1 (Berkeley) 6/10/93
* $Id: tp_meas.h,v 1.4 1994/05/13 06:09:28 mycroft Exp $
*/
#ifndef _NETISO_TP_MEAS_H_
#define _NETISO_TP_MEAS_H_
/***********************************************************
Copyright IBM Corporation 1987
@ -95,6 +92,4 @@ extern struct tp_Meas tp_Meas[];
#define TPtime_open_X 0x28 /* xtd format */
#define TPtime_close 0x09
#endif TP_PERF_MEAS
#endif /* !_NETISO_TP_MEAS_H_ */
#endif /* TP_PERF_MEAS */

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,8 +30,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)tp_output.c 7.10 (Berkeley) 6/27/91
* $Id: tp_output.c,v 1.4 1993/12/18 00:43:44 mycroft Exp $
* from: @(#)tp_output.c 8.1 (Berkeley) 6/10/93
* $Id: tp_output.c,v 1.5 1994/05/13 06:09:30 mycroft Exp $
*/
/***********************************************************
@ -61,8 +61,6 @@ SOFTWARE.
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
*/
/*
* ARGO TP
*
* In here is tp_ctloutput(), the guy called by [sg]etsockopt(),
*/
@ -86,8 +84,6 @@ SOFTWARE.
#include <netiso/tp_pcb.h>
#include <netiso/tp_trace.h>
#define USERFLAGSMASK_G 0x0f00643b
#define USERFLAGSMASK_S 0x0f000432
#define TPDUSIZESHIFT 24
#define CLASSHIFT 16
@ -162,7 +158,7 @@ tp_consistency( tpcb, cmd, param )
printf("p_class 0x%x, class_to_use 0x%x\n", param->p_class,
class_to_use);
ENDDEBUG
if( param->p_netservice > TP_MAX_NETSERVICES) {
if((param->p_netservice < 0) || (param->p_netservice > TP_MAX_NETSERVICES)){
error = EINVAL; goto done;
}
if( (param->p_class & TP_CLASSES_IMPLEMENTED) == 0 ) {
@ -176,18 +172,6 @@ tp_consistency( tpcb, cmd, param )
/* bad for any class because negot has to be done a la class 4 */
error = EINVAL; goto done;
}
IFDEBUG(D_SETPARAMS)
printf("winsize 0x%x\n", param->p_winsize );
ENDDEBUG
if( (param->p_winsize < 128 ) ||
(param->p_winsize < param->p_tpdusize ) ||
(param->p_winsize > ((1+SB_MAX)>>2 /* 1/4 of the max */)) ) {
error = EINVAL; goto done;
} else {
if( tpcb->tp_state == TP_CLOSED )
soreserve(tpcb->tp_sock, (u_long)param->p_winsize,
(u_long)param->p_winsize);
}
IFDEBUG(D_SETPARAMS)
printf("use_csum 0x%x\n", param->p_use_checksum );
printf("xtd_format 0x%x\n", param->p_xtd_format );
@ -300,9 +284,8 @@ tp_consistency( tpcb, cmd, param )
}
if ((error==0) && (cmd & TP_FORCE)) {
long dusize = ((long)param->p_ptpdusize) << 7;
/* Enforce Negotation rules below */
if (tpcb->tp_tpdusize > param->p_tpdusize)
tpcb->tp_tpdusize = param->p_tpdusize;
tpcb->tp_class = param->p_class;
if (tpcb->tp_use_checksum || param->p_use_checksum)
tpcb->tp_use_checksum = 1;
@ -310,8 +293,19 @@ tp_consistency( tpcb, cmd, param )
tpcb->tp_xpd_service = 0;
if (!tpcb->tp_xtd_format || !param->p_xtd_format)
tpcb->tp_xtd_format = 0;
if (dusize) {
if (tpcb->tp_l_tpdusize > dusize)
tpcb->tp_l_tpdusize = dusize;
if (tpcb->tp_ptpdusize == 0 ||
tpcb->tp_ptpdusize > param->p_ptpdusize)
tpcb->tp_ptpdusize = param->p_ptpdusize;
} else {
if (param->p_tpdusize != 0 &&
tpcb->tp_tpdusize > param->p_tpdusize)
tpcb->tp_tpdusize = param->p_tpdusize;
tpcb->tp_l_tpdusize = 1 << tpcb->tp_tpdusize;
}
}
done:
IFTRACE(D_CONN)
@ -362,7 +356,7 @@ done:
*
* NOTES:
*/
ProtoHook
int
tp_ctloutput(cmd, so, level, optname, mp)
int cmd, level, optname;
struct socket *so;
@ -408,8 +402,20 @@ tp_ctloutput(cmd, so, level, optname, mp)
else if (tpcb->tp_nlproto->nlp_ctloutput == NULL)
error = EOPNOTSUPP;
else
error = (tpcb->tp_nlproto->nlp_ctloutput)(cmd, optname,
tpcb->tp_npcb, *mp);
return ((tpcb->tp_nlproto->nlp_ctloutput)(cmd, optname,
tpcb->tp_npcb, *mp));
goto done;
} else if ( level == SOL_SOCKET) {
if (optname == SO_RCVBUF && cmd == PRCO_SETOPT) {
u_long old_credit = tpcb->tp_maxlcredit;
tp_rsyset(tpcb);
if (tpcb->tp_rhiwat != so->so_rcv.sb_hiwat &&
tpcb->tp_state == TP_OPEN &&
(old_credit < tpcb->tp_maxlcredit))
tp_emit(AK_TPDU_type, tpcb,
tpcb->tp_rcvnxt, 0, MNULL);
tpcb->tp_rhiwat = so->so_rcv.sb_hiwat;
}
goto done;
} else if ( level != SOL_TRANSPORT ) {
error = EOPNOTSUPP; goto done;
@ -439,7 +445,7 @@ tp_ctloutput(cmd, so, level, optname, mp)
* the tpcb is gone
*/
if ((so->so_state & (SS_ISCONNECTED | SS_ISCONFIRMING)) == 0) {
if ( so->so_tpcb == (caddr_t)0 ) {
if ( so->so_pcb == (caddr_t)0 ) {
error = ENOTCONN; goto done;
}
if ( (tpcb->tp_state == TP_REFWAIT || tpcb->tp_state == TP_CLOSING) &&
@ -456,48 +462,46 @@ tp_ctloutput(cmd, so, level, optname, mp)
switch (optname) {
case TPOPT_INTERCEPT:
#define INA(t) (((struct inpcb *)(t->tp_npcb))->inp_laddr.s_addr)
#define ISOA(t) (((struct isopcb *)(t->tp_npcb))->isop_laddr->siso_addr)
if ((so->so_state & SS_PRIV) == 0) {
error = EPERM;
break;
} else if (cmd != PRCO_SETOPT || tpcb->tp_state != TP_LISTENING)
} else if (cmd != PRCO_SETOPT || tpcb->tp_state != TP_CLOSED ||
(tpcb->tp_flags & TPF_GENERAL_ADDR) ||
tpcb->tp_next == 0)
error = EINVAL;
else {
register struct tp_pcb *t = 0;
struct mbuf *m = m_getclr(M_WAIT, MT_SONAME);
struct sockaddr *sa = mtod(m, struct sockaddr *);
(*tpcb->tp_nlproto->nlp_getnetaddr)(tpcb->tp_npcb, m, TP_LOCAL);
switch (sa->sa_family) {
case AF_ISO:
if (((struct sockaddr_iso *)sa)->siso_nlen == 0)
default: error = EINVAL;
break;
case AF_INET:
if (((struct sockaddr_in *)sa)->sin_addr.s_addr == 0)
error = EINVAL;
break;
}
for (t = tp_intercepts; t; t = t->tp_nextlisten) {
if (t->tp_nlproto->nlp_afamily != tpcb->tp_nlproto->nlp_afamily)
continue;
if ((*t->tp_nlproto->nlp_cmpnetaddr)(t->tp_npcb, sa, TP_LOCAL))
error = EADDRINUSE;
}
m_freem(m);
if (error)
break;
register struct tp_pcb *t;
error = EADDRINUSE;
for (t = tp_listeners; t; t = t->tp_nextlisten)
if ((t->tp_flags & TPF_GENERAL_ADDR) == 0 &&
t->tp_domain == tpcb->tp_domain)
switch (tpcb->tp_domain) {
default:
goto done;
#ifdef INET
case AF_INET:
if (INA(t) == INA(tpcb))
goto done;
continue;
#endif
#ifdef ISO
case AF_ISO:
if (bcmp(ISOA(t).isoa_genaddr, ISOA(tpcb).isoa_genaddr,
ISOA(t).isoa_len) == 0)
goto done;
continue;
#endif
}
tpcb->tp_lsuffixlen = 0;
tpcb->tp_state = TP_LISTENING;
error = 0;
remque(tpcb);
tpcb->tp_next = tpcb->tp_prev = tpcb;
tpcb->tp_nextlisten = tp_listeners;
tp_listeners = tpcb;
}
{
register struct tp_pcb **tt;
for (tt = &tp_listeners; *tt; tt = &((*tt)->tp_nextlisten))
if (*tt == tpcb)
break;
if (*tt)
*tt = tpcb->tp_nextlisten;
else
{error = EHOSTUNREACH; goto done; }
}
tpcb->tp_nextlisten = tp_intercepts;
tp_intercepts = tpcb;
break;
case TPOPT_MY_TSEL:
@ -603,7 +607,7 @@ tp_ctloutput(cmd, so, level, optname, mp)
#else
error = EOPNOTSUPP;
goto done;
#endif TP_PERF_MEAS
#endif /* TP_PERF_MEAS */
case TPOPT_CDDATA_CLEAR:
if (cmd == PRCO_GETOPT) {
@ -649,7 +653,7 @@ tp_ctloutput(cmd, so, level, optname, mp)
tptrace(TPPTmisc,"C/D DATA: flags snd.sbcc val_len",
tpcb->tp_flags, so->so_snd.sb_cc,val_len,0);
ENDTRACE
*mp = MNULL; /* prevent sosetopt from freeing it! */
*mp = MNULL;
if (optname == TPOPT_CFRM_DATA && (so->so_state & SS_ISCONFIRMING))
(void) tp_confirm(tpcb);
}
@ -668,9 +672,9 @@ tp_ctloutput(cmd, so, level, optname, mp)
}
if( tpcb->tp_perf_on )
error = tp_setup_perf(tpcb);
#else TP_PERF_MEAS
#else /* TP_PERF_MEAS */
error = EOPNOTSUPP;
#endif TP_PERF_MEAS
#endif /* TP_PERF_MEAS */
break;
default:
@ -686,15 +690,19 @@ done:
* sigh: getsockopt looks only at m_len : all output data must
* reside in the first mbuf
*/
if ( error && (*mp) != MNULL )
(*mp)->m_len = 0;
if( (*mp) != MNULL ) {
ASSERT ( m_compress(*mp, mp) <= MLEN );
IFDEBUG(D_REQUEST)
dump_mbuf(*mp, "tp_ctloutput *mp after compress");
ENDDEBUG
if (*mp) {
if (cmd == PRCO_SETOPT) {
m_freem(*mp);
*mp = MNULL;
} else {
ASSERT ( m_compress(*mp, mp) <= MLEN );
if (error)
(*mp)->m_len = 0;
IFDEBUG(D_REQUEST)
dump_mbuf(*mp, "tp_ctloutput *mp after compress");
ENDDEBUG
}
}
splx(s);
return error;
}

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,13 +30,10 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)tp_param.h 7.8 (Berkeley) 6/27/91
* $Id: tp_param.h,v 1.3 1993/05/20 05:27:48 cgd Exp $
* from: @(#)tp_param.h 8.1 (Berkeley) 6/10/93
* $Id: tp_param.h,v 1.4 1994/05/13 06:09:32 mycroft Exp $
*/
#ifndef _NETISO_TP_PARAM_H_
#define _NETISO_TP_PARAM_H_
/***********************************************************
Copyright IBM Corporation 1987
@ -64,6 +61,9 @@ SOFTWARE.
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
*/
#ifndef _NETISO_TP_PARAM_H_
#define _NETISO_TP_PARAM_H_
/******************************************************
* compile time parameters that can be changed
*****************************************************/
@ -89,15 +89,19 @@ extern int N_TPREF;
* wraparound in checksumming
* (No mtu is likely to be larger than 4K anyway...)
*/
#define TP_NRETRANS 5 /* was 1; cray uses 6 */
#define TP_NRETRANS 12 /* TCP_MAXRXTSHIFT + 1 */
#define TP_MAXRXTSHIFT 6 /* factor of 64 */
#define TP_MAXPORT 0xefff
#define TP_RTT_NUM 0x7
/* ALPHA: to be used in the context: gain= 1/(2**alpha), or
* put another way, gaintimes(x) (x)>>alpha (forgetting the case alpha==0)
*/
#define TP_RTT_ALPHA 3
#define TP_RTV_ALPHA 2
#define TP_REXMTVAL(tpcb)\
((tp_rttadd + (tpcb)->tp_rtt + ((tpcb)->tp_rtv) << 2) / tp_rttdiv)
#define TP_RANGESET(tv, value, min, max) \
((tv = value) > (max) ? (tv = max) : (tv < min ? tv = min : tv))
/*
* not sure how to treat data on disconnect
@ -194,24 +198,27 @@ extern int N_TPREF;
#define TPP_addl_opt 0xc6
#define TPP_alt_class 0xc7
#define TPP_perf_meas 0xc8 /* local item : perf meas on, svp */
#define TPP_ptpdu_size 0xf0 /* preferred TPDU size */
#define TPP_inact_time 0xf2 /* inactivity time exchanged */
/******************************************************
* Some fundamental data types
*****************************************************/
#ifndef TRUE
#define TRUE 1
#endif TRUE
#endif /* TRUE */
#ifndef FALSE
#define FALSE 0
#endif FALSE
#endif /* FALSE */
#define TP_LOCAL 22
#define TP_FOREIGN 33
#ifndef EOK
#define EOK 0
#endif EOK
#endif /* EOK */
#define TP_CLASS_0 (1<<0)
#define TP_CLASS_1 (1<<1)
@ -224,7 +231,7 @@ extern int N_TPREF;
#ifndef MNULL
#define MNULL (struct mbuf *)0
#endif MNULL
#endif /* MNULL */
/* if ../sys/mbuf.h gets MT_types up to 0x40, these will
* have to be changed:
*/
@ -235,16 +242,6 @@ extern int N_TPREF;
typedef unsigned int SeqNum;
typedef unsigned short RefNum;
typedef int ProtoHook;
/******************************************************
* Some fundamental constants
*****************************************************/
#define TP_MIN_WIN 2048
#define TP_MAX_WIN 16384
#define TP_MAX_WIN_UNPRIV 8192
/******************************************************
* Macro used all over, for driver
@ -327,36 +324,36 @@ bcopy((caddr_t)&(((struct tp_vbp *)(src))->tpv_val),(caddr_t)&(dst),sizeof(type)
#if defined(ARGO_DEBUG)&&!defined(LOCAL_CREDIT_EXPAND)
#define LOCAL_CREDIT(tpcb) tp_local_credit(tpcb)
#else
#define LOCAL_CREDIT( tpcb ) {\
#define LOCAL_CREDIT(tpcb) { if (tpcb->tp_rsycnt == 0) {\
register struct sockbuf *xxsb = &((tpcb)->tp_sock->so_rcv);\
register int xxi = ((xxsb)->sb_hiwat-(xxsb)->sb_cc);\
register int maxcredit = ((tpcb)->tp_xtd_format?0xffff:0xf);\
xxi = (xxi<0) ? 0 : ((xxi)>>(tpcb)->tp_tpdusize);\
xxi = MIN(xxi, maxcredit); \
register int xxi = sbspace(xxsb);\
xxi = (xxi<0) ? 0 : ((xxi) / (tpcb)->tp_l_tpdusize);\
xxi = min(xxi, (tpcb)->tp_maxlcredit); \
if (!(tpcb->tp_cebit_off)) { \
(tpcb)->tp_lcredit = ROUND((tpcb)->tp_win_recv); \
if (xxi < (tpcb)->tp_lcredit) { \
(tpcb)->tp_lcredit = xxi; \
} \
} \
else { \
} else \
(tpcb)->tp_lcredit = xxi; \
} \
}
#endif ARGO_DEBUG
} }
#endif /* ARGO_DEBUG */
#ifdef KERNEL
extern int tp_rttadd, tp_rttdiv;
#include <sys/syslog.h>
#define printf logpri(LOG_DEBUG),addlog
#ifndef tp_NSTATES
#include "tp_states.h"
#include "tp_events.h"
#include <netiso/tp_states.h>
#include <netiso/tp_events.h>
#if defined(__STDC__) || defined(__cplusplus)
#undef ATTR
#define ATTR(X) ev_union.EV_ ## X
#endif /* defined(__STDC__) || defined(__cplusplus) */
#endif tp_NSTATES
#endif KERNEL
#endif /* tp_NSTATES */
#endif /* KERNEL */
#endif /* !_NETISO_TP_PARAM_H_ */
#endif /* _NETISO_TP_PARAM_H_ */

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,8 +30,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)tp_pcb.c 7.11 (Berkeley) 5/6/91
* $Id: tp_pcb.c,v 1.3 1993/12/18 00:43:53 mycroft Exp $
* from: @(#)tp_pcb.c 8.1 (Berkeley) 6/10/93
* $Id: tp_pcb.c,v 1.4 1994/05/13 06:09:34 mycroft Exp $
*/
/***********************************************************
@ -61,8 +61,6 @@ SOFTWARE.
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
*/
/*
* ARGO TP
*
* This is the initialization and cleanup stuff -
* for the tp machine in general as well as for the individual pcbs.
* tp_init() is called at system startup. tp_attach() and tp_getref() are
@ -72,14 +70,14 @@ SOFTWARE.
* tp_soisdisconnecting() and tp_soisdisconnected() are tp-specific
* versions of soisconnect*
* and are called (obviously) during the closing phase.
*
*/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/domain.h>
#include <sys/protosw.h>
#include <sys/errno.h>
#include <sys/time.h>
@ -96,10 +94,6 @@ SOFTWARE.
#include <netiso/tp_seq.h>
#include <netiso/tp_clnp.h>
struct tp_param tp_param = {
1, /* configured */
};
/* ticks are in units of:
* 500 nano-fortnights ;-) or
* 500 ms or
@ -267,7 +261,7 @@ int in_pcballoc();
int tpip_output();
int tpip_output_dg();
struct inpcb tp_inpcb;
#endif INET
#endif /* INET */
#ifdef ISO
int iso_putnetaddr();
int iso_getnetaddr();
@ -285,7 +279,7 @@ int tpclnp_output();
int tpclnp_output_dg();
int iso_nlctloutput();
struct isopcb tp_isopcb;
#endif ISO
#endif /* ISO */
#ifdef TPCONS
int iso_putnetaddr();
int iso_getnetaddr();
@ -301,7 +295,7 @@ int iso_pcbdetach();
int iso_pcballoc();
int tpcons_output();
struct isopcb tp_isopcb;
#endif TPCONS
#endif /* TPCONS */
struct nl_protosw nl_protosw[] = {
@ -318,7 +312,7 @@ struct nl_protosw nl_protosw[] = {
},
#else
{ 0 },
#endif ISO
#endif /* ISO */
/* IN_CLNS */
#ifdef INET
{ AF_INET, in_putnetaddr, in_getnetaddr, in_cmpnetaddr,
@ -332,7 +326,7 @@ struct nl_protosw nl_protosw[] = {
},
#else
{ 0 },
#endif INET
#endif /* INET */
/* ISO_CONS */
#if defined(ISO) && defined(TPCONS)
{ AF_ISO, iso_putnetaddr, iso_getnetaddr, iso_cmpnetaddr,
@ -346,11 +340,14 @@ struct nl_protosw nl_protosw[] = {
},
#else
{ 0 },
#endif ISO_CONS
#endif /* ISO_CONS */
/* End of protosw marker */
{ 0 }
};
u_long tp_sendspace = 1024 * 4;
u_long tp_recvspace = 1024 * 4;
/*
* NAME: tp_init()
*
@ -366,15 +363,14 @@ struct nl_protosw nl_protosw[] = {
*
* NOTES:
*/
int
void
tp_init()
{
static int init_done=0;
void tp_timerinit();
if (init_done++)
return 0;
return;
/* FOR INET */
tp_inpcb.inp_next = tp_inpcb.inp_prev = &tp_inpcb;
@ -385,7 +381,6 @@ tp_init()
tp_timerinit();
bzero((caddr_t)&tp_stat, sizeof(struct tp_stat));
return 0;
}
/*
@ -458,7 +453,7 @@ tp_soisdisconnected(tpcb)
soisdisconnecting(so);
so->so_state &= ~SS_CANTSENDMORE;
IFPERF(sototpcb(so))
IFPERF(tpcb)
register struct tp_pcb *ttpcb = sototpcb(so);
u_int fsufx, lsufx;
@ -471,13 +466,11 @@ tp_soisdisconnected(tpcb)
tpcb->tp_perf_on = 0; /* turn perf off */
ENDPERF
tpcb->tp_refp->tpr_state = REF_FROZEN;
tp_recycle_tsuffix( tpcb );
tp_etimeout(tpcb->tp_refp, TM_reference, 0,0,0, (int)tpcb->tp_refer_ticks);
tpcb->tp_refstate = REF_FROZEN;
tp_recycle_tsuffix(tpcb);
tp_etimeout(tpcb, TM_reference, (int)tpcb->tp_refer_ticks);
}
int tp_maxrefopen; /* highest reference # of the set of open tp connections */
/*
* NAME: tp_freeref()
*
@ -497,33 +490,37 @@ int tp_maxrefopen; /* highest reference # of the set of open tp connections */
* NOTES: better be called at clock priority !!!!!
*/
void
tp_freeref(r)
register struct tp_ref *r;
tp_freeref(n)
RefNum n;
{
register struct tp_ref *r = tp_ref + n;
register struct tp_pcb *tpcb;
tpcb = r->tpr_pcb;
IFDEBUG(D_TIMER)
printf("tp_freeref called for ref %d maxrefopen %d\n",
r - tp_ref, tp_maxrefopen);
printf("tp_freeref called for ref %d pcb %x maxrefopen %d\n",
n, tpcb, tp_refinfo.tpr_maxopen);
ENDDEBUG
IFTRACE(D_TIMER)
tptrace(TPPTmisc, "tp_freeref ref tp_maxrefopen",
r - tp_ref, tp_maxrefopen, 0, 0);
tptrace(TPPTmisc, "tp_freeref ref maxrefopen pcb",
n, tp_refinfo.tpr_maxopen, tpcb, 0);
ENDTRACE
r->tpr_state = REF_FREE;
if (tpcb == 0)
return;
IFDEBUG(D_CONN)
printf("tp_freeref: CLEARING tpr_pcb 0x%x\n", r->tpr_pcb);
printf("tp_freeref: CLEARING tpr_pcb 0x%x\n", tpcb);
ENDDEBUG
r->tpr_pcb = (struct tp_pcb *)0;
tpcb->tp_refstate = REF_FREE;
r = &tp_ref[tp_maxrefopen];
while( tp_maxrefopen > 0 ) {
if(r->tpr_state )
for (r = tp_ref + tp_refinfo.tpr_maxopen; r > tp_ref; r--)
if (r->tpr_pcb)
break;
tp_maxrefopen--;
r--;
}
tp_refinfo.tpr_maxopen = r - tp_ref;
tp_refinfo.tpr_numopen--;
IFDEBUG(D_TIMER)
printf("tp_freeref ends w/ maxrefopen %d\n", tp_maxrefopen);
printf("tp_freeref ends w/ maxrefopen %d\n", tp_refinfo.tpr_maxopen);
ENDDEBUG
}
@ -545,27 +542,72 @@ tp_freeref(r)
*
* NOTES:
*/
static RefNum
u_long
tp_getref(tpcb)
register struct tp_pcb *tpcb;
{
register struct tp_ref *r = tp_ref; /* tp_ref[0] is never used */
register int i=1;
register struct tp_ref *r, *rlim;
register int i;
caddr_t obase;
unsigned size;
if (++tp_refinfo.tpr_numopen < tp_refinfo.tpr_size)
for (r = tp_refinfo.tpr_base, rlim = r + tp_refinfo.tpr_size;
++r < rlim; ) /* tp_ref[0] is never used */
if (r->tpr_pcb == 0)
goto got_one;
/* else have to allocate more space */
while ((++r)->tpr_state != REF_FREE) {
if (++i == N_TPREF)
return TP_ENOREF;
}
r->tpr_state = REF_OPENING;
if (tp_maxrefopen < i)
tp_maxrefopen = i;
obase = (caddr_t)tp_refinfo.tpr_base;
size = tp_refinfo.tpr_size * sizeof(struct tp_ref);
r = (struct tp_ref *) malloc(size + size, M_PCB, M_NOWAIT);
if (r == 0)
return (--tp_refinfo.tpr_numopen, TP_ENOREF);
tp_refinfo.tpr_base = tp_ref = r;
tp_refinfo.tpr_size *= 2;
bcopy(obase, (caddr_t)r, size);
free(obase, M_PCB);
r = (struct tp_ref *)(size + (caddr_t)r);
bzero((caddr_t)r, size);
got_one:
r->tpr_pcb = tpcb;
tpcb->tp_refp = r;
return i;
tpcb->tp_refstate = REF_OPENING;
i = r - tp_refinfo.tpr_base;
if (tp_refinfo.tpr_maxopen < i)
tp_refinfo.tpr_maxopen = i;
return (u_long)i;
}
/*
* NAME: tp_set_npcb()
*
* CALLED FROM:
* tp_attach(), tp_route_to()
*
* FUNCTION and ARGUMENTS:
* given a tpcb, allocate an appropriate lower-lever npcb, freeing
* any old ones that might need re-assigning.
*/
tp_set_npcb(tpcb)
register struct tp_pcb *tpcb;
{
register struct socket *so = tpcb->tp_sock;
int error;
if (tpcb->tp_nlproto && tpcb->tp_npcb) {
short so_state = so->so_state;
so->so_state &= ~SS_NOFDREF;
tpcb->tp_nlproto->nlp_pcbdetach(tpcb->tp_npcb);
so->so_state = so_state;
}
tpcb->tp_nlproto = &nl_protosw[tpcb->tp_netservice];
/* xx_pcballoc sets so_pcb */
error = tpcb->tp_nlproto->nlp_pcballoc(so, tpcb->tp_nlproto->nlp_pcblist);
tpcb->tp_npcb = so->so_pcb;
so->so_pcb = (caddr_t)tpcb;
return (error);
}
/*
* NAME: tp_attach()
*
@ -591,13 +633,14 @@ tp_getref(tpcb)
*
* NOTES:
*/
tp_attach(so, dom)
struct socket *so;
int dom;
tp_attach(so, protocol)
struct socket *so;
int protocol;
{
register struct tp_pcb *tpcb;
int error;
int protocol = so->so_proto->pr_protocol;
int error = 0;
int dom = so->so_proto->pr_domain->dom_family;
u_long lref;
extern struct tp_conn_param tp_conn_param[];
IFDEBUG(D_CONN)
@ -606,16 +649,13 @@ tp_attach(so, dom)
IFTRACE(D_CONN)
tptrace(TPPTmisc, "tp_attach:dom so", dom, so, 0, 0);
ENDTRACE
if ( ! tp_param.tpp_configed ) {
error = ENOPROTOOPT; /* protocol not available */
goto bad2;
}
if (so->so_pcb != NULL) {
return EISCONN; /* socket already part of a connection*/
}
error = soreserve(so, TP_SOCKBUFSIZE, TP_SOCKBUFSIZE);
if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0)
error = soreserve(so, tp_sendspace, tp_recvspace);
/* later an ioctl will allow reallocation IF still in closed state */
if (error)
@ -628,13 +668,16 @@ tp_attach(so, dom)
}
bzero( (caddr_t)tpcb, sizeof (struct tp_pcb) );
if ( ((tpcb->tp_lref = tp_getref(tpcb)) & TP_ENOREF) != 0 ) {
if ( ((lref = tp_getref(tpcb)) & TP_ENOREF) != 0 ) {
error = ETOOMANYREFS;
goto bad3;
}
tpcb->tp_lref = lref;
tpcb->tp_sock = so;
tpcb->tp_domain = dom;
if (protocol<ISOPROTO_TP4) {
tpcb->tp_rhiwat = so->so_rcv.sb_hiwat;
/* tpcb->tp_proto = protocol; someday maybe? */
if (protocol && protocol<ISOPROTO_TP4) {
tpcb->tp_netservice = ISO_CONS;
tpcb->tp_snduna = (SeqNum) -1;/* kludge so the pseudo-ack from the CR/CC
* will generate correct fake-ack values
@ -645,9 +688,9 @@ tp_attach(so, dom)
}
tpcb->_tp_param = tp_conn_param[tpcb->tp_netservice];
tpcb->tp_cong_win = 1;
tpcb->tp_state = TP_CLOSED;
tpcb->tp_vers = TP_VERSION;
tpcb->tp_notdetached = 1;
/* Spec says default is 128 octets,
* that is, if the tpdusize argument never appears, use 128.
@ -658,46 +701,21 @@ tp_attach(so, dom)
* we'll respond w/ this.
* Our maximum is 4096. See tp_chksum.c comments.
*/
tpcb->tp_l_tpdusize = 1 << tpcb->tp_tpdusize;
tpcb->tp_cong_win =
tpcb->tp_l_tpdusize = 1 << tpcb->tp_tpdusize;
tpcb->tp_seqmask = TP_NML_FMT_MASK;
tpcb->tp_seqbit = TP_NML_FMT_BIT;
tpcb->tp_seqhalf = tpcb->tp_seqbit >> 1;
tpcb->tp_sndhiwat = (SeqNum) - 1; /* a kludge but it works */
tpcb->tp_s_subseq = 0;
/* attach to a network-layer protoswitch */
/* new way */
tpcb->tp_nlproto = & nl_protosw[tpcb->tp_netservice];
ASSERT( tpcb->tp_nlproto->nlp_afamily == tpcb->tp_domain);
#ifdef notdef
/* OLD WAY */
/* TODO: properly, this search would be on the basis of
* domain,netservice or just netservice only (if you have
* IN_CLNS, ISO_CLNS, and ISO_CONS)
*/
tpcb->tp_nlproto = nl_protosw;
while(tpcb->tp_nlproto->nlp_afamily != tpcb->tp_domain ) {
if( tpcb->tp_nlproto->nlp_afamily == 0 ) {
error = EAFNOSUPPORT;
goto bad4;
}
tpcb->tp_nlproto ++;
}
#endif notdef
/* xx_pcballoc sets so_pcb */
if ( error = (tpcb->tp_nlproto->nlp_pcballoc) (
so, tpcb->tp_nlproto->nlp_pcblist ) ) {
if ( error = tp_set_npcb(tpcb))
goto bad4;
}
ASSERT( tpcb->tp_nlproto->nlp_afamily == tpcb->tp_domain);
/* nothing to do for iso case */
if( dom == AF_INET )
sotoinpcb(so)->inp_ppcb = (caddr_t) tpcb;
/* nothing to do for iso case */
tpcb->tp_npcb = (caddr_t) so->so_pcb;
so->so_tpcb = (caddr_t) tpcb;
return 0;
@ -705,7 +723,7 @@ bad4:
IFDEBUG(D_CONN)
printf("BAD4 in tp_attach, so 0x%x\n", so);
ENDDEBUG
tp_freeref(tpcb->tp_refp);
tp_freeref(tpcb->tp_lref);
bad3:
IFDEBUG(D_CONN)
@ -719,7 +737,6 @@ bad2:
printf("BAD2 in tp_attach, so 0x%x\n", so);
ENDDEBUG
so->so_pcb = 0;
so->so_tpcb = 0;
/*bad:*/
IFDEBUG(D_CONN)
@ -755,7 +772,7 @@ void
tp_detach(tpcb)
register struct tp_pcb *tpcb;
{
void tp_freeref();
void tp_freeref(), tp_rsyflush();
register struct socket *so = tpcb->tp_sock;
IFDEBUG(D_CONN)
@ -767,33 +784,6 @@ tp_detach(tpcb)
tpcb, so, *(u_short *)(tpcb->tp_lsuffix), 0);
ENDTRACE
if (so->so_head) {
if (!soqremque(so, 0) && !soqremque(so, 1))
panic("sofree dq");
so->so_head = 0;
}
IFDEBUG(D_CONN)
printf("tp_detach(freeing RTC list snduna 0x%x rcvnxt 0x%x)\n",
tpcb->tp_snduna_rtc,
tpcb->tp_rcvnxt_rtc);
ENDDEBUG
#define FREE_RTC_LIST(XXX)\
{ register struct tp_rtc *xxr = XXX, *xxs; while (xxr) {\
xxs = xxr->tprt_next;\
m_freem( xxr->tprt_data );\
m_free( dtom(xxr) ); xxr = xxs; }\
XXX = (struct tp_rtc *)0;\
}
FREE_RTC_LIST( tpcb->tp_snduna_rtc );
tpcb->tp_sndhiwat_rtc = (struct tp_rtc *)0;
FREE_RTC_LIST( tpcb->tp_rcvnxt_rtc );
#undef FREE_RTC_LIST
IFDEBUG(D_CONN)
printf("so_snd at 0x%x so_rcv at 0x%x\n", &so->so_snd, &so->so_rcv);
dump_mbuf(so->so_snd.sb_mb, "so_snd at detach ");
@ -801,45 +791,60 @@ tp_detach(tpcb)
tpcb->tp_nlproto, tpcb->tp_nlproto->nlp_pcbdetach);
ENDDEBUG
if (so->so_snd.sb_cc != 0)
sbflush(&so->so_snd);
if (tpcb->tp_Xrcv.sb_cc != 0)
sbdrop(&tpcb->tp_Xrcv, (int)tpcb->tp_Xrcv.sb_cc);
if (tpcb->tp_Xsnd.sb_mb) {
printf("Unsent Xdata on detach; would panic");
sbflush(&tpcb->tp_Xsnd);
}
if (tpcb->tp_ucddata)
m_freem(tpcb->tp_ucddata);
IFDEBUG(D_CONN)
printf("reassembly info cnt %d rsyq 0x%x\n",
tpcb->tp_rsycnt, tpcb->tp_rsyq);
ENDDEBUG
if (tpcb->tp_rsyq)
tp_rsyflush(tpcb);
if (tpcb->tp_next) {
remque(tpcb);
tpcb->tp_next = tpcb->tp_prev = 0;
}
tpcb->tp_notdetached = 0;
IFDEBUG(D_CONN)
printf("calling (...nlproto->...)(0x%x, so 0x%x)\n",
so->so_pcb, so);
tpcb->tp_npcb, so);
printf("so 0x%x so_head 0x%x, qlen %d q0len %d qlimit %d\n",
so, so->so_head,
so->so_q0len, so->so_qlen, so->so_qlimit);
ENDDEBUG
(tpcb->tp_nlproto->nlp_pcbdetach)(so->so_pcb);
/* does an sofree(so) */
(tpcb->tp_nlproto->nlp_pcbdetach)(tpcb->tp_npcb);
/* does an so->so_pcb = 0; sofree(so) */
IFDEBUG(D_CONN)
printf("after xxx_pcbdetach\n");
ENDDEBUG
if( tpcb->tp_refp->tpr_state == REF_OPENING ) {
if (tpcb->tp_state == TP_LISTENING) {
register struct tp_pcb **tt;
for (tt = &tp_listeners; *tt; tt = &((*tt)->tp_nextlisten))
if (*tt == tpcb)
break;
if (*tt)
*tt = tpcb->tp_nextlisten;
else
printf("tp_detach from listen: should panic\n");
}
if (tpcb->tp_refstate == REF_OPENING ) {
/* no connection existed here so no reference timer will be called */
IFDEBUG(D_CONN)
printf("SETTING ref %d, 0x%x to REF_FREE\n", tpcb->tp_lref,
tpcb->tp_refp - &tp_ref[0]);
printf("SETTING ref %d to REF_FREE\n", tpcb->tp_lref);
ENDDEBUG
tp_freeref(tpcb->tp_refp);
tp_freeref(tpcb->tp_lref);
}
if (tpcb->tp_Xsnd.sb_mb) {
printf("Unsent Xdata on detach; would panic");
sbflush(&tpcb->tp_Xsnd);
}
so->so_tpcb = (caddr_t)0;
#ifdef TP_PERF_MEAS
/*
* Get rid of the cluster mbuf allocated for performance measurements, if
* there is one. Note that tpcb->tp_perf_on says nothing about whether or
@ -847,7 +852,6 @@ tp_detach(tpcb)
* to one (that is, we need the TP_PERF_MEASs around the following section
* of code, not the IFPERFs)
*/
#ifdef TP_PERF_MEAS
if (tpcb->tp_p_mbuf) {
register struct mbuf *m = tpcb->tp_p_mbuf;
struct mbuf *n;
@ -861,10 +865,127 @@ tp_detach(tpcb)
tpcb->tp_p_meas = 0;
tpcb->tp_p_mbuf = 0;
}
#endif TP_PERF_MEAS
#endif /* TP_PERF_MEAS */
IFDEBUG(D_CONN)
printf( "end of detach, NOT single, tpcb 0x%x\n", tpcb);
ENDDEBUG
/* free((caddr_t)tpcb, M_PCB); WHere to put this ? */
}
struct que {
struct tp_pcb *next;
struct tp_pcb *prev;
} tp_bound_pcbs =
{(struct tp_pcb *)&tp_bound_pcbs, (struct tp_pcb *)&tp_bound_pcbs};
u_short tp_unique;
tp_tselinuse(tlen, tsel, siso, reuseaddr)
caddr_t tsel;
register struct sockaddr_iso *siso;
{
struct tp_pcb *b = tp_bound_pcbs.next, *l = tp_listeners;
register struct tp_pcb *t;
for (;;) {
if (b != (struct tp_pcb *)&tp_bound_pcbs) {
t = b; b = t->tp_next;
} else if (l) {
t = l; l = t->tp_nextlisten;
} else
break;
if (tlen == t->tp_lsuffixlen && bcmp(tsel, t->tp_lsuffix, tlen) == 0) {
if (t->tp_flags & TPF_GENERAL_ADDR) {
if (siso == 0 || reuseaddr == 0)
return 1;
} else if (siso) {
if (siso->siso_family == t->tp_domain &&
t->tp_nlproto->nlp_cmpnetaddr(t->tp_npcb, siso, TP_LOCAL))
return 1;
} else if (reuseaddr == 0)
return 1;
}
}
return 0;
}
tp_pcbbind(tpcb, nam)
register struct tp_pcb *tpcb;
register struct mbuf *nam;
{
register struct sockaddr_iso *siso = 0;
int tlen = 0, wrapped = 0;
caddr_t tsel;
u_short tutil;
if (tpcb->tp_state != TP_CLOSED)
return (EINVAL);
if (nam) {
siso = mtod(nam, struct sockaddr_iso *);
switch (siso->siso_family) {
default:
return (EAFNOSUPPORT);
#ifdef ISO
case AF_ISO:
tlen = siso->siso_tlen;
tsel = TSEL(siso);
if (siso->siso_nlen == 0)
siso = 0;
break;
#endif
#ifdef INET
case AF_INET:
tsel = (caddr_t)&tutil;
if (tutil = ((struct sockaddr_in *)siso)->sin_port) {
tlen = 2;
}
if (((struct sockaddr_in *)siso)->sin_addr.s_addr == 0)
siso = 0;
}
#endif
}
if (tpcb->tp_lsuffixlen == 0) {
if (tlen) {
if (tp_tselinuse(tlen, tsel, siso,
tpcb->tp_sock->so_options & SO_REUSEADDR))
return (EINVAL);
} else {
for (tsel = (caddr_t)&tutil, tlen = 2;;){
if (tp_unique++ < ISO_PORT_RESERVED ||
tp_unique > ISO_PORT_USERRESERVED) {
if (wrapped++)
return ESRCH;
tp_unique = ISO_PORT_RESERVED;
}
tutil = htons(tp_unique);
if (tp_tselinuse(tlen, tsel, siso, 0) == 0)
break;
}
if (siso) switch (siso->siso_family) {
#ifdef ISO
case AF_ISO:
bcopy(tsel, TSEL(siso), tlen);
siso->siso_tlen = tlen;
break;
#endif
#ifdef INET
case AF_INET:
((struct sockaddr_in *)siso)->sin_port = tutil;
#endif
}
}
bcopy(tsel, tpcb->tp_lsuffix, (tpcb->tp_lsuffixlen = tlen));
insque(tpcb, &tp_bound_pcbs);
} else {
if (tlen || siso == 0)
return (EINVAL);
}
if (siso == 0) {
tpcb->tp_flags |= TPF_GENERAL_ADDR;
return (0);
}
return tpcb->tp_nlproto->nlp_pcbbind(tpcb->tp_npcb, nam);
}

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,13 +30,10 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)tp_pcb.h 7.9 (Berkeley) 5/6/91
* $Id: tp_pcb.h,v 1.3 1993/05/20 05:27:51 cgd Exp $
* from: @(#)tp_pcb.h 8.1 (Berkeley) 6/10/93
* $Id: tp_pcb.h,v 1.4 1994/05/13 06:09:37 mycroft Exp $
*/
#ifndef _NETISO_TP_PCB_H_
#define _NETISO_TP_PCB_H_
/***********************************************************
Copyright IBM Corporation 1987
@ -64,18 +61,19 @@ SOFTWARE.
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
*/
/*
* ARGO TP
*
* This file defines the transport protocol control block (tpcb).
* and a bunch of #define values that are used in the tpcb.
*/
#include "../netiso/tp_param.h"
#include "../netiso/tp_timer.h"
#include "../netiso/tp_user.h"
#ifndef _NETISO_TP_PCB_H_
#define _NETISO_TP_PCB_H_
#include <netiso/tp_param.h>
#include <netiso/tp_timer.h>
#include <netiso/tp_user.h>
#ifndef sblock
#include "socketvar.h"
#endif sblock
#include <sys/socketvar.h>
#endif /* sblock */
/* NOTE: the code depends on REF_CLOSED > REF_OPEN > the rest, and
* on REF_FREE being zero
@ -106,31 +104,18 @@ SOFTWARE.
#define REF_OPENING 1 /* in use (has a pcb) but no timers */
#define REF_FREE 0 /* free to reallocate */
#define N_CTIMERS 4
#define N_ETIMERS 2
#define TM_NTIMERS 6
struct tp_ref {
u_char tpr_state; /* values REF_FROZEN, etc. above */
struct Ccallout tpr_callout[N_CTIMERS]; /* C timers */
struct Ecallout tpr_calltodo; /* list of active E timers */
struct tp_pcb *tpr_pcb; /* back ptr to PCB */
};
struct tp_param {
/* PER system stuff (one static structure instead of a bunch of names) */
unsigned tpp_configed:1; /* Has TP been initialized? */
};
/*
* retransmission control and performance measurement
*/
struct tp_rtc {
struct tp_rtc *tprt_next; /* ptr to next rtc structure in the list */
SeqNum tprt_seq; /* seq # of this TPDU */
int tprt_eot; /* Will this TPDU have the eot bit set? */
int tprt_octets;/* # octets in this TPDU */
struct mbuf *tprt_data; /* ptr to the octets of data */
/* PER system stuff (one static structure instead of a bunch of names) */
struct tp_refinfo {
struct tp_ref *tpr_base;
int tpr_size;
int tpr_maxopen;
int tpr_numopen;
};
struct nl_protosw {
@ -158,12 +143,12 @@ struct tp_pcb {
struct tp_pcb *tp_next;
struct tp_pcb *tp_prev;
struct tp_pcb *tp_nextlisten; /* chain all listeners */
struct socket *tp_sock; /* back ptr */
u_short tp_state; /* state of fsm */
short tp_retrans; /* # times can still retrans */
struct tp_ref *tp_refp; /* rest of pcb */
caddr_t tp_npcb; /* to lower layer pcb */
struct nl_protosw *tp_nlproto; /* lower-layer dependent routines */
struct socket *tp_sock; /* back ptr */
struct rtentry **tp_routep; /* obtain mtu; inside npcb */
RefNum tp_lref; /* local reference */
@ -173,38 +158,37 @@ struct tp_pcb {
u_int tp_seqbit; /* bit for seq number wraparound */
u_int tp_seqhalf; /* half the seq space */
/* credit & sequencing info for SENDING */
u_short tp_fcredit; /* current remote credit in # packets */
u_short tp_cong_win; /* congestion window : set to 1 on
* source quench
* Minimizes the amount of retrans-
* missions (independently of the
* retrans strategy). Increased
* by one for each good ack received.
* Minimizes the amount sent in a
* regular tp_send() also.
*/
u_int tp_ackrcvd; /* ACKs received since the send window was updated */
SeqNum tp_last_retrans;
SeqNum tp_retrans_hiwat;
SeqNum tp_snduna; /* seq # of lowest unacked DT */
struct tp_rtc *tp_snduna_rtc; /* lowest unacked stuff sent so far */
SeqNum tp_sndhiwat; /* highest seq # sent so far */
struct tp_rtc *tp_sndhiwat_rtc; /* last stuff sent so far */
int tp_Nwindow; /* for perf. measurement */
struct mbuf *tp_ucddata; /* user connect/disconnect data */
/* credit & sequencing info for SENDING */
u_short tp_fcredit; /* current remote credit in # packets */
u_short tp_maxfcredit; /* max remote credit in # packets */
u_short tp_dupacks; /* intuit packet loss before rxt timo */
u_long tp_cong_win; /* congestion window in bytes.
* see profuse comments in TCP code
*/
u_long tp_ssthresh; /* cong_win threshold for slow start
* exponential to linear switch
*/
SeqNum tp_snduna; /* seq # of lowest unacked DT */
SeqNum tp_sndnew; /* seq # of lowest unsent DT */
SeqNum tp_sndnum; /* next seq # to be assigned */
SeqNum tp_sndnxt; /* what to do next; poss. rxt */
struct mbuf *tp_sndnxt_m; /* packet corres. to sndnxt*/
int tp_Nwindow; /* for perf. measurement */
/* credit & sequencing info for RECEIVING */
SeqNum tp_rcvnxt; /* next DT seq # expect to recv */
SeqNum tp_sent_lcdt; /* cdt according to last ack sent */
SeqNum tp_sent_uwe; /* uwe according to last ack sent */
SeqNum tp_sent_rcvnxt; /* rcvnxt according to last ack sent
* needed for perf measurements only
*/
u_short tp_lcredit; /* current local credit in # packets */
SeqNum tp_rcvnxt; /* next DT seq # expect to recv */
struct tp_rtc *tp_rcvnxt_rtc; /* unacked stuff recvd out of order */
u_short tp_maxlcredit; /* needed for reassembly queue */
struct mbuf **tp_rsyq; /* unacked stuff recvd out of order */
int tp_rsycnt; /* number of packets "" "" "" "" */
u_long tp_rhiwat; /* remember original RCVBUF size */
/* receiver congestion state stuff ... */
u_int tp_win_recv;
@ -246,45 +230,47 @@ struct tp_pcb {
#define tp_dont_change_params _tp_param.p_dont_change_params
#define tp_netservice _tp_param.p_netservice
#define tp_version _tp_param.p_version
#define tp_ptpdusize _tp_param.p_ptpdusize
int tp_l_tpdusize;
int tp_l_tpdusize;
/* whereas tp_tpdusize is log2(the negotiated max size)
* l_tpdusize is the size we'll use when sending, in # chars
*/
struct timeval tp_rtv; /* max round-trip time variance */
struct timeval tp_rtt; /* smoothed round-trip time */
struct timeval tp_rttemit[ TP_RTT_NUM + 1 ];
/* times that the last TP_RTT_NUM DT_TPDUs were emitted */
int tp_rtv; /* max round-trip time variance */
int tp_rtt; /* smoothed round-trip time */
SeqNum tp_rttseq; /* packet being timed */
int tp_rttemit; /* when emitted, in ticks */
int tp_idle; /* last activity, in ticks */
short tp_rxtcur; /* current retransmit value */
short tp_rxtshift; /* log(2) of rexmt exp. backoff */
u_char tp_cebit_off; /* real DEC bit algorithms not in use */
u_char tp_oktonagle; /* Last unsent pckt may be append to */
u_char tp_flags; /* values: */
#define TPF_NLQOS_PDN TPFLAG_NLQOS_PDN
#define TPF_PEER_ON_SAMENET TPFLAG_PEER_ON_SAMENET
#define TPF_GENERAL_ADDR TPFLAG_GENERAL_ADDR
#define TPF_DELACK 0x8
#define TPF_ACKNOW 0x10
#define PEER_IS_LOCAL(t) (((t)->tp_flags & TPF_PEER_ON_SAME_NET) != 0)
#define USES_PDN(t) (((t)->tp_flags & TPF_NLQOS_PDN) != 0)
unsigned
tp_sendfcc:1, /* shall next ack include FCC parameter? */
tp_trace:1, /* is this pcb being traced? (not used yet) */
tp_perf_on:1, /* 0/1 -> performance measuring on */
tp_reneged:1, /* have we reneged on cdt since last ack? */
tp_decbit:3, /* dec bit was set, we're in reneg mode */
tp_cebit_off:1, /* the real DEC bit algorithms not in use */
tp_flags:8, /* values: */
#define TPF_CONN_DATA_OUT TPFLAG_CONN_DATA_OUT
#define TPF_CONN_DATA_IN TPFLAG_CONN_DATA_IN
#define TPF_DISC_DATA_IN TPFLAG_DISC_DATA_IN
#define TPF_DISC_DATA_OUT TPFLAG_DISC_DATA_OUT
#define TPF_XPD_PRESENT TPFLAG_XPD_PRESENT
#define TPF_NLQOS_PDN TPFLAG_NLQOS_PDN
#define TPF_PEER_ON_SAMENET TPFLAG_PEER_ON_SAMENET
#define PEER_IS_LOCAL(t) \
(((t)->tp_flags & TPF_PEER_ON_SAME_NET)==TPF_PEER_ON_SAME_NET)
#define USES_PDN(t) \
(((t)->tp_flags & TPF_NLQOS_PDN)==TPF_NLQOS_PDN)
tp_unused:16;
tp_notdetached:1; /* Call tp_detach before freeing XXXXXXX */
#ifdef TP_PERF_MEAS
/* performance stats - see tp_stat.h */
struct tp_pmeas *tp_p_meas;
struct mbuf *tp_p_mbuf;
#endif TP_PERF_MEAS
#endif /* TP_PERF_MEAS */
/* addressing */
u_short tp_domain; /* domain (INET, ISO) */
/* for compatibility with the *old* way and with INET, be sure that
@ -298,8 +284,12 @@ struct tp_pcb {
#define SHORT_LSUFXP(tpcb) ((short *)((tpcb)->tp_lsuffix))
#define SHORT_FSUFXP(tpcb) ((short *)((tpcb)->tp_fsuffix))
u_char tp_vers; /* protocol version */
u_char tp_peer_acktime; /* used to compute DT retrans time */
/* Timer stuff */
u_char tp_vers; /* protocol version */
u_char tp_peer_acktime; /* used for DT retrans time */
u_char tp_refstate; /* values REF_FROZEN, etc. above */
struct tp_pcb *tp_fasttimeo; /* limit pcbs to examine */
u_int tp_timer[TM_NTIMERS]; /* C timers */
struct sockbuf tp_Xsnd; /* for expedited data */
/* struct sockbuf tp_Xrcv; /* for expedited data */
@ -323,7 +313,7 @@ u_int tp_start_win;
#define CONG_INIT_SAMPLE(pcb) \
pcb->tp_cong_sample.cs_received = \
pcb->tp_cong_sample.cs_ce_set = 0; \
pcb->tp_cong_sample.cs_size = MAX(pcb->tp_lcredit, 1) << 1;
pcb->tp_cong_sample.cs_size = max(pcb->tp_lcredit, 1) << 1;
#define CONG_UPDATE_SAMPLE(pcb, ce_bit) \
pcb->tp_cong_sample.cs_received++; \
@ -334,7 +324,7 @@ u_int tp_start_win;
if ((pcb->tp_cong_sample.cs_ce_set << 1) >= \
pcb->tp_cong_sample.cs_size ) { \
pcb->tp_win_recv -= pcb->tp_win_recv >> 3; /* multiply by .875 */ \
pcb->tp_win_recv = MAX(1 << 8, pcb->tp_win_recv); \
pcb->tp_win_recv = max(1 << 8, pcb->tp_win_recv); \
} \
else { \
pcb->tp_win_recv += (1 << 8); /* add one to the scaled int */ \
@ -343,29 +333,19 @@ u_int tp_start_win;
CONG_INIT_SAMPLE(pcb); \
}
#define CONG_ACK(pcb, seq) \
{ int newacks = SEQ_SUB(pcb, seq, pcb->tp_snduna); \
if (newacks > 0) { \
pcb->tp_ackrcvd += newacks; \
if (pcb->tp_ackrcvd >= MIN(pcb->tp_fcredit, pcb->tp_cong_win)) { \
++pcb->tp_cong_win; \
pcb->tp_ackrcvd = 0; \
} \
} \
}
#ifdef KERNEL
extern struct tp_refinfo tp_refinfo;
extern struct timeval time;
extern struct tp_ref *tp_ref;
extern struct tp_ref *tp_ref;
extern struct tp_param tp_param;
extern struct nl_protosw nl_protosw[];
extern struct tp_pcb *tp_listeners;
extern struct tp_pcb *tp_intercepts;
extern struct tp_pcb *tp_ftimeolist;
#endif
#define sototpcb(so) ((struct tp_pcb *)(so->so_tpcb))
#define sototpref(so) ((struct tp_ref *)((so)->so_tpcb->tp_ref))
#define sototpcb(so) ((struct tp_pcb *)(so->so_pcb))
#define sototpref(so) ((sototpcb(so)->tp_ref))
#define tpcbtoso(tp) ((struct socket *)((tp)->tp_sock))
#define tpcbtoref(tp) ((struct tp_ref *)((tp)->tp_ref))
#endif /* !_NETISO_TP_PCB_H_ */
#endif /* _NETISO_TP_PCB_H_ */

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,13 +30,10 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)tp_seq.h 7.5 (Berkeley) 5/6/91
* $Id: tp_seq.h,v 1.3 1993/05/20 05:27:52 cgd Exp $
* from: @(#)tp_seq.h 8.1 (Berkeley) 6/10/93
* $Id: tp_seq.h,v 1.4 1994/05/13 06:09:39 mycroft Exp $
*/
#ifndef _NETISO_TP_SEQ_H_
#define _NETISO_TP_SEQ_H_
/***********************************************************
Copyright IBM Corporation 1987
@ -64,8 +61,6 @@ SOFTWARE.
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
*/
/*
* ARGO TP
*
* These macros perform sequence number arithmetic modulo (2**7 or 2**31).
* The relevant fields in the tpcb are:
* tp_seqmask : the mask of bits that define the sequence space.
@ -74,6 +69,9 @@ SOFTWARE.
* Not exactly fast, but at least it's maintainable.
*/
#ifndef _NETISO_TP_SEQ_H_
#define _NETISO_TP_SEQ_H_
#define SEQ(tpcb,x) \
((x) & (tpcb)->tp_seqmask)
@ -119,4 +117,4 @@ SOFTWARE.
#define IN_SWINDOW(tpcb, seq, lwe, uwe)\
( SEQ_GT(tpcb, seq, lwe) && SEQ_LEQ(tpcb, seq, uwe) )
#endif /* !_NETISO_TP_SEQ_H_ */
#endif /* _NETISO_TP_SEQ_H_ */

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,13 +30,10 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)tp_stat.h 7.5 (Berkeley) 6/27/91
* $Id: tp_stat.h,v 1.3 1993/05/20 05:27:53 cgd Exp $
* from: @(#)tp_stat.h 8.1 (Berkeley) 6/10/93
* $Id: tp_stat.h,v 1.4 1994/05/13 06:09:41 mycroft Exp $
*/
#ifndef _NETISO_TP_STAT_H_
#define _NETISO_TP_STAT_H_
/***********************************************************
Copyright IBM Corporation 1987
@ -64,12 +61,13 @@ SOFTWARE.
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
*/
/*
* ARGO TP
*
* Here are the data structures in which the global
* statistics(counters) are gathered.
*/
#ifndef _NETISO_TP_STAT_H_
#define _NETISO_TP_STAT_H_
struct tp_stat {
u_long ts_param_ignored;
u_long ts_unused3;
@ -144,6 +142,8 @@ struct tp_stat {
u_long ts_Cset;
u_long ts_Ccan_act;
u_long ts_Ccan_inact;
u_long ts_Fdelack;
u_long ts_Fpruned;
u_long ts_concat_rcvd;
@ -174,8 +174,8 @@ struct tp_stat {
* 2 --> tp_flags: TPF_PEER_ON_SAMENET | ~TPF_NL_PDN
* 3 --> tp_flags: TPF_PEER_ON_SAMENET | TPF_NL_PDN
*/
struct timeval ts_rtt[NRTT_CATEGORIES];
struct timeval ts_rtv[NRTT_CATEGORIES];
int ts_rtt[NRTT_CATEGORIES];
int ts_rtv[NRTT_CATEGORIES];
u_long ts_ackreason[_ACK_NUM_REASONS_];
/* ACK_DONT 0 / ACK_STRAT_EACH 0x1 / ACK_STRAT_FULLWIN 0x4
@ -217,7 +217,7 @@ struct tp_pmeas {
* Each window size, we keep the running average of the time
* taken by tp_sbsend() for each window size.
*/
struct timeval tps_sendtime[TP_PM_MAX+1];
int tps_sendtime[TP_PM_MAX+1];
/*
* n_TMsendack: # times ack sent because timer went off
* n_ack_cuz_eot: # times ack sent due to EOTSDU on incoming packet
@ -274,6 +274,6 @@ int PStat_Junk;
#define IFPERF(x) if (0) {
#define ENDPERF }
#endif TP_PERF_MEAS
#endif /* TP_PERF_MEAS */
#endif /* !_NETISO_TP_STAT_H_ */
#endif /* _NETISO_TP_STAT_H_ */

View File

@ -1,4 +1,4 @@
/* $Id: tp_states.h,v 1.2 1993/05/20 05:27:55 cgd Exp $ */
/* $Id: tp_states.h,v 1.3 1994/05/13 06:09:42 mycroft Exp $ */
#define ST_ERROR 0x0
#define TP_CLOSED 0x1

View File

@ -1,4 +1,4 @@
/* $Id: tp_states.init,v 1.2 1993/05/20 05:27:56 cgd Exp $ */
/* $Id: tp_states.init,v 1.3 1994/05/13 06:09:43 mycroft Exp $ */
{0x3,0x0},
{0x6,0x1},

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,8 +30,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)tp_subr2.c 7.10 (Berkeley) 6/27/91
* $Id: tp_subr2.c,v 1.4 1993/12/18 00:43:59 mycroft Exp $
* from: @(#)tp_subr2.c 8.1 (Berkeley) 6/10/93
* $Id: tp_subr2.c,v 1.5 1994/05/13 06:09:48 mycroft Exp $
*/
/***********************************************************
@ -61,8 +61,6 @@ SOFTWARE.
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
*/
/*
* ARGO TP
*
* Some auxiliary routines:
* tp_protocol_error: required by xebec- called when a combo of state,
* event, predicate isn't covered for by the transition file.
@ -84,13 +82,10 @@ SOFTWARE.
#include <sys/domain.h>
#include <sys/protosw.h>
#include <sys/errno.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/kernel.h>
#undef MNULL
#include <net/if.h>
#include <netiso/argo_debug.h>
#include <netiso/tp_param.h>
#include <netiso/tp_ip.h>
@ -106,6 +101,8 @@ SOFTWARE.
#include <netiso/tp_user.h>
#include <netiso/cons.h>
#include <net/if.h>
#include <net/if_types.h>
#ifdef TRUE
#undef FALSE
#undef TRUE
@ -114,10 +111,7 @@ SOFTWARE.
#include <netccitt/pk.h>
#include <netccitt/pk_var.h>
#ifndef TPCONS
static void
pk_flowcontrol() {}
#endif
void tp_rsyset();
/*
* NAME: tp_local_credit()
@ -146,7 +140,7 @@ tp_local_credit(tpcb)
LOCAL_CREDIT(tpcb);
IFDEBUG(D_CREDIT)
printf("ref 0x%x lcdt 0x%x l_tpdusize 0x%x decbit 0x%x\n",
tpcb->tp_refp - tp_ref,
tpcb->tp_lref,
tpcb->tp_lcredit,
tpcb->tp_l_tpdusize,
tpcb->tp_decbit,
@ -193,10 +187,10 @@ tp_protocol_error(e,tpcb)
/* Not used at the moment */
ProtoHook
void
tp_drain()
{
return 0;
}
@ -265,7 +259,8 @@ tp_indicate(ind, tpcb, error)
so->so_error = error;
if (ind == T_DISCONNECT) {
so->so_error = ENOTCONN;
if (error == 0)
so->so_error = ENOTCONN;
if ( tpcb->tp_no_disc_indications )
return;
}
@ -302,8 +297,9 @@ struct tp_pcb *tpcb;
tpcb->tp_xtd_format ? TP_XTD_FMT_BIT : TP_NML_FMT_BIT ;
tpcb->tp_seqhalf = tpcb->tp_seqbit >> 1;
tpcb->tp_dt_ticks =
MAX(tpcb->tp_dt_ticks, (tpcb->tp_peer_acktime + 2));
max(tpcb->tp_dt_ticks, (tpcb->tp_peer_acktime + 2));
tp_rsyset(tpcb);
}
/*
@ -372,11 +368,11 @@ tp_quench( tpcb, cmd )
ENDDEBUG
switch(cmd) {
case PRC_QUENCH:
tpcb->tp_cong_win = 1;
tpcb->tp_cong_win = tpcb->tp_l_tpdusize;
IncStat(ts_quench);
break;
case PRC_QUENCH2:
tpcb->tp_cong_win = 1; /* might as well quench source also */
tpcb->tp_cong_win = tpcb->tp_l_tpdusize; /* might as well quench source also */
tpcb->tp_decbit = TP_DECBIT_CLEAR_COUNT;
IncStat(ts_rcvdecbit);
break;
@ -413,17 +409,24 @@ tp_netcmd( tpcb, cmd )
case CONN_CLOSE:
case CONN_REFUSE:
if (isop->isop_refcnt == 1)
if (isop->isop_refcnt == 1) {
/* This is really superfluous, since it would happen
anyway in iso_pcbdetach, although it is a courtesy
to free up the x.25 channel before the refwait timer
expires. */
lcp->lcd_upper = 0;
lcp->lcd_upnext = 0;
pk_disconnect(lcp);
isop->isop_chan = 0;
isop->isop_refcnt = 0;
isop->isop_chan = 0;
isop->isop_refcnt = 0;
}
break;
default:
printf("tp_netcmd(0x%x, 0x%x) NOT IMPLEMENTED\n", tpcb, cmd);
break;
}
#else TPCONS
#else /* TPCONS */
printf("tp_netcmd(): X25 NOT CONFIGURED!!\n");
#endif
}
@ -471,31 +474,140 @@ copyQOSparms(src, dst)
dst->p_rx_strat = src->p_rx_strat;
#undef COPYSIZE
}
/*
* Determine a reasonable value for maxseg size.
* If the route is known, check route for mtu.
* We also initialize the congestion/slow start
* window to be a single segment if the destination isn't local.
* While looking at the routing entry, we also initialize other path-dependent
* parameters from pre-set or cached values in the routing entry.
*/
void
tp_mss(tpcb, nhdr_size)
register struct tp_pcb *tpcb;
int nhdr_size;
{
register struct rtentry *rt;
struct ifnet *ifp;
register int rtt, mss;
u_long bufsize;
int i, ssthresh = 0, rt_mss;
struct socket *so;
if (tpcb->tp_ptpdusize)
mss = tpcb->tp_ptpdusize << 7;
else
mss = 1 << tpcb->tp_tpdusize;
so = tpcb->tp_sock;
if ((rt = *(tpcb->tp_routep)) == 0) {
bufsize = so->so_rcv.sb_hiwat;
goto punt_route;
}
ifp = rt->rt_ifp;
#ifdef RTV_MTU /* if route characteristics exist ... */
/*
* While we're here, check if there's an initial rtt
* or rttvar. Convert from the route-table units
* to hz ticks for the smoothed timers and slow-timeout units
* for other inital variables.
*/
if (tpcb->tp_rtt == 0 && (rtt = rt->rt_rmx.rmx_rtt)) {
tpcb->tp_rtt = rtt * hz / RTM_RTTUNIT;
if (rt->rt_rmx.rmx_rttvar)
tpcb->tp_rtv = rt->rt_rmx.rmx_rttvar
* hz / RTM_RTTUNIT;
else
tpcb->tp_rtv = tpcb->tp_rtt;
}
/*
* if there's an mtu associated with the route, use it
*/
if (rt->rt_rmx.rmx_mtu)
rt_mss = rt->rt_rmx.rmx_mtu - nhdr_size;
else
#endif /* RTV_MTU */
rt_mss = (ifp->if_mtu - nhdr_size);
if (tpcb->tp_ptpdusize == 0 || /* assume application doesn't care */
mss > rt_mss /* network won't support what was asked for */)
mss = rt_mss;
/* can propose mtu which are multiples of 128 */
mss &= ~0x7f;
/*
* If there's a pipesize, change the socket buffer
* to that size.
*/
#ifdef RTV_SPIPE
if ((bufsize = rt->rt_rmx.rmx_sendpipe) > 0) {
#endif
bufsize = min(bufsize, so->so_snd.sb_hiwat);
(void) sbreserve(&so->so_snd, bufsize);
}
#ifdef RTV_SPIPE
if ((bufsize = rt->rt_rmx.rmx_recvpipe) > 0) {
#endif
bufsize = min(bufsize, so->so_rcv.sb_hiwat);
(void) sbreserve(&so->so_rcv, bufsize);
} else
bufsize = so->so_rcv.sb_hiwat;
#ifdef RTV_SSTHRESH
/*
* There's some sort of gateway or interface
* buffer limit on the path. Use this to set
* the slow start threshhold, but set the
* threshold to no less than 2*mss.
*/
ssthresh = rt->rt_rmx.rmx_ssthresh;
punt_route:
/*
* The current mss is initialized to the default value.
* If we compute a smaller value, reduce the current mss.
* If we compute a larger value, return it for use in sending
* a max seg size option.
* If we received an offer, don't exceed it.
* However, do not accept offers under 128 bytes.
*/
if (tpcb->tp_l_tpdusize)
mss = min(mss, tpcb->tp_l_tpdusize);
/*
* We want a minimum recv window of 4 packets to
* signal packet loss by duplicate acks.
*/
mss = min(mss, bufsize >> 2) & ~0x7f;
mss = max(mss, 128); /* sanity */
tpcb->tp_cong_win =
(rt == 0 || (rt->rt_flags & RTF_GATEWAY)) ? mss : bufsize;
tpcb->tp_l_tpdusize = mss;
tp_rsyset(tpcb);
tpcb->tp_ssthresh = max(2 * mss, ssthresh);
/* Calculate log2 of mss */
for (i = TP_MIN_TPDUSIZE + 1; i <= TP_MAX_TPDUSIZE; i++)
if ((1 << i) > mss)
break;
i--;
tpcb->tp_tpdusize = i;
#endif /* RTV_MTU */
}
/*
* CALLED FROM:
* tp_usrreq on PRU_CONNECT and tp_input on receipt of CR
*
* FUNCTION and ARGUMENTS:
* route directly to x.25 if the address is type 37 - GROT.
* furthermore, let TP0 handle only type-37 addresses
* -- An mbuf containing the peer's network address.
* -- Our control block, which will be modified
* -- In the case of cons, a control block for that layer.
*
* Since this assumes that its address argument is in a mbuf, the
* parameter was changed to reflect this assumtion. This also
* implies that an mbuf must be allocated when this is
* called from tp_input
*
* RETURNS:
* errno value :
* EAFNOSUPPORT if can't find an nl_protosw for x.25 (really could panic)
* ECONNREFUSED if trying to run TP0 with non-type 37 address
* possibly other E* returned from cons_netcmd()
* NOTE:
* Would like to eliminate as much of this as possible --
* only one set of defaults (let the user set the parms according
* to parameters provided in the directory service).
* Left here for now 'cause we don't yet have a clean way to handle
* it on the passive end.
*
* SIDE EFFECTS:
* Determines recommended tpdusize, buffering and intial delays
* based on information cached on the route.
*/
int
tp_route_to( m, tpcb, channel)
@ -505,8 +617,9 @@ tp_route_to( m, tpcb, channel)
{
register struct sockaddr_iso *siso; /* NOTE: this may be a sockaddr_in */
extern struct tp_conn_param tp_conn_param[];
struct pklcd *lcp = (struct pklcd *)channel;
int error = 0;
int error = 0, save_netservice = tpcb->tp_netservice;
register struct rtentry *rt = 0;
int nhdr_size, mtu, bufsize;
siso = mtod(m, struct sockaddr_iso *);
IFTRACE(D_CONN)
@ -521,115 +634,68 @@ tp_route_to( m, tpcb, channel)
printf("m->mlen x%x, m->m_data:\n", m->m_len);
dump_buf(mtod(m, caddr_t), m->m_len);
ENDDEBUG
if (siso->siso_family != tpcb->tp_domain) {
error = EAFNOSUPPORT;
goto done;
}
IFDEBUG(D_CONN)
printf("tp_route_to calling nlp_pcbconn, netserv %d\n",
tpcb->tp_netservice);
ENDDEBUG
if (channel) {
#ifdef TPCONS
if (lcp) {
struct pklcd *lcp = (struct pklcd *)channel;
struct isopcb *isop = (struct isopcb *)lcp->lcd_upnext,
*isop_new = (struct isopcb *)tpcb->tp_sock->so_pcb;
*isop_new = (struct isopcb *)tpcb->tp_npcb;
/* The next 2 lines believe that you haven't
set any network level options or done a pcbconnect
and XXXXXXX'edly apply to both inpcb's and isopcb's */
remque(isop_new);
free(isop_new, M_PCB);
tpcb->tp_sock->so_pcb = (caddr_t)isop;
if (isop->isop_refcnt == 0) {
extern struct isopcb tp_isopcb;
remque(isop);
insque(isop, &tp_isopcb);
isop->isop_head = &tp_isopcb;
tpcb->tp_npcb = (caddr_t)isop;
tpcb->tp_netservice = ISO_CONS;
tpcb->tp_nlproto = nl_protosw + ISO_CONS;
if (isop->isop_refcnt++ == 0) {
iso_putsufx(isop, tpcb->tp_lsuffix, tpcb->tp_lsuffixlen, TP_LOCAL);
}
/* else there are already connections sharing this */
isop->isop_refcnt++;
} else
isop->isop_socket = tpcb->tp_sock;
} else
/* there are already connections sharing this */;
#endif
error = (tpcb->tp_nlproto->nlp_pcbconn)(tpcb->tp_sock->so_pcb, m);
if( error )
goto done;
{
register int save_netservice = tpcb->tp_netservice;
switch(tpcb->tp_netservice) {
case ISO_COSNS:
case ISO_CLNS:
/* This is a kludge but seems necessary so the passive end
* can get long enough timers. sigh.
if( siso->siso_addr.osinet_idi[1] == (u_char)IDI_OSINET )
*/
#define IDI_OSINET 0x0004 /* bcd of "0004" */
if( siso->siso_addr.isoa_genaddr[2] == (char)IDI_OSINET ) {
if( tpcb->tp_dont_change_params == 0) {
copyQOSparms( &tp_conn_param[ISO_COSNS],
&tpcb->_tp_param);
}
tpcb->tp_flags |= TPF_NLQOS_PDN;
}
/* drop through to IN_CLNS*/
case IN_CLNS:
if (iso_localifa(siso))
tpcb->tp_flags |= TPF_PEER_ON_SAMENET;
if( (tpcb->tp_class & TP_CLASS_4)==0 ) {
error = EPROTOTYPE;
break;
}
tpcb->tp_class = TP_CLASS_4; /* IGNORE dont_change_parms */
break;
case ISO_CONS:
#ifdef TPCONS
tpcb->tp_flags |= TPF_NLQOS_PDN;
if( tpcb->tp_dont_change_params == 0 ) {
copyQOSparms( &tp_conn_param[ISO_CONS],
&tpcb->_tp_param);
}
/*
* for use over x.25 really need a small receive window,
* need to start slowly, need small max negotiable tpdu size,
* and need to use the congestion window to the max
* IGNORES tp_dont_change_params for these!
*/
if( tpcb->tp_sock->so_snd.sb_hiwat > 512 ) {
(void) soreserve(tpcb->tp_sock, 512, 512 );/* GAG */
}
tpcb->tp_rx_strat = TPRX_USE_CW;
if( (tpcb->tp_nlproto != &nl_protosw[ISO_CONS]) ) {
IFDEBUG(D_CONN)
printf(
"tp_route_to( CHANGING nlproto old 0x%x new 0x%x)\n",
tpcb->tp_nlproto , &nl_protosw[ISO_CONS]);
ENDDEBUG
tpcb->tp_nlproto = &nl_protosw[ISO_CONS];
}
/* class 4 doesn't need to open a vc now - may use one already
* opened or may open one only when it sends a pkt.
*/
#else TPCONS
error = ECONNREFUSED;
#endif TPCONS
break;
} else {
switch (siso->siso_family) {
default:
error = EPROTOTYPE;
error = EAFNOSUPPORT;
goto done;
#ifdef ISO
case AF_ISO:
{
struct isopcb *isop = (struct isopcb *)tpcb->tp_npcb;
int flags = tpcb->tp_sock->so_options & SO_DONTROUTE;
tpcb->tp_netservice = ISO_CLNS;
if (clnp_route(&siso->siso_addr, &isop->isop_route,
flags, (void **)0, (void **)0) == 0) {
rt = isop->isop_route.ro_rt;
if (rt && rt->rt_flags & RTF_PROTO1)
tpcb->tp_netservice = ISO_CONS;
}
} break;
#endif
#ifdef INET
case AF_INET:
tpcb->tp_netservice = IN_CLNS;
#endif
}
ASSERT( save_netservice == tpcb->tp_netservice);
if (tpcb->tp_nlproto->nlp_afamily != siso->siso_family) {
IFDEBUG(D_CONN)
printf("tp_route_to( CHANGING nlproto old 0x%x new 0x%x)\n",
save_netservice, tpcb->tp_netservice);
ENDDEBUG
if (error = tp_set_npcb(tpcb))
goto done;
}
IFDEBUG(D_CONN)
printf("tp_route_to calling nlp_pcbconn, netserv %d\n",
tpcb->tp_netservice);
ENDDEBUG
tpcb->tp_nlproto = nl_protosw + tpcb->tp_netservice;
error = (tpcb->tp_nlproto->nlp_pcbconn)(tpcb->tp_npcb, m);
}
if (error) {
tp_netcmd( tpcb, CONN_CLOSE);
if (error)
goto done;
}
{ /* start with the global rtt, rtv stats */
register int i =
(int) tpcb->tp_flags & (TPF_PEER_ON_SAMENET | TPF_NLQOS_PDN);
tpcb->tp_rtt = tp_stat.ts_rtt[i];
tpcb->tp_rtv = tp_stat.ts_rtv[i];
}
nhdr_size = tpcb->tp_nlproto->nlp_mtu(tpcb); /* only gets common info */
tp_mss(tpcb, nhdr_size);
done:
IFDEBUG(D_CONN)
printf("tp_route_to returns 0x%x\n", error);
@ -641,6 +707,10 @@ done:
return error;
}
#ifndef TPCONS
static
pk_flowcontrol() {}
#endif
/* class zero version */
void
@ -650,9 +720,9 @@ tp0_stash( tpcb, e )
{
#ifndef lint
#define E e->ATTR(DT_TPDU)
#else lint
#else /* lint */
#define E e->ev_union.EV_DT_TPDU
#endif lint
#endif /* lint */
register struct sockbuf *sb = &tpcb->tp_sock->so_rcv;
register struct isopcb *isop = (struct isopcb *)tpcb->tp_npcb;
@ -746,7 +816,7 @@ tp_setup_perf(tpcb)
}
return 0;
}
#endif TP_PERF_MEAS
#endif /* TP_PERF_MEAS */
#ifdef ARGO_DEBUG
dump_addr (addr)
@ -760,7 +830,7 @@ dump_addr (addr)
case AF_ISO:
dump_isoaddr((struct sockaddr_iso *)addr);
break;
#endif ISO
#endif /* ISO */
default:
printf("BAD AF: 0x%x\n", addr->sa_family);
break;
@ -803,7 +873,4 @@ int len;
printf("\n");
}
}
#endif ARGO_DEBUG
#endif /* ARGO_DEBUG */

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,8 +30,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)tp_timer.c 7.5 (Berkeley) 5/6/91
* $Id: tp_timer.c,v 1.3 1993/12/18 00:44:00 mycroft Exp $
* from: @(#)tp_timer.c 8.1 (Berkeley) 6/10/93
* $Id: tp_timer.c,v 1.4 1994/05/13 06:09:50 mycroft Exp $
*/
/***********************************************************
@ -60,47 +60,28 @@ SOFTWARE.
/*
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
*/
/*
* ARGO TP
*
* Contains all the timer code.
* There are two sources of calls to these routines:
* the clock, and tp.trans. (ok, and tp_pcb.c calls it at init time)
*
* Timers come in two flavors - those that generally get
* cancelled (tp_ctimeout, tp_cuntimeout)
* and those that either usually expire (tp_etimeout,
* tp_euntimeout, tp_slowtimo) or may require more than one instance
* of the timer active at a time.
*
* The C timers are stored in the tp_ref structure. Their "going off"
* is manifested by a driver event of the TM_xxx form.
*
* The E timers are handled like the generic kernel callouts.
* Their "going off" is manifested by a function call w/ 3 arguments.
*/
#include <sys/param.h>
#include <sys/types.h>
#include <sys/systm.h>
#include <sys/time.h>
#include <sys/malloc.h>
#include <sys/protosw.h>
#include <sys/socket.h>
#include <sys/kernel.h>
#include <netiso/argo_debug.h>
#include <netiso/tp_param.h>
#include <netiso/tp_timer.h>
#include <netiso/tp_stat.h>
#include <netiso/tp_pcb.h>
#include <netiso/tp_tpdu.h>
#include <netiso/argo_debug.h>
#include <netiso/tp_trace.h>
#include <netiso/tp_seq.h>
struct Ecallout *TP_callfree;
struct Ecallout *TP_callout;
struct tp_ref *tp_ref;
int N_TPREF = 100;
extern int tp_maxrefopen; /* highest ref # of an open tp connection */
int tp_rttdiv, tp_rttadd, N_TPREF = 127;
struct tp_refinfo tp_refinfo;
struct tp_pcb *tp_ftimeolist = (struct tp_pcb *)&tp_ftimeolist;
/*
* CALLED FROM:
@ -112,150 +93,53 @@ extern int tp_maxrefopen; /* highest ref # of an open tp connection */
void
tp_timerinit()
{
register struct Ecallout *e;
register int s;
#define GETME(x, t, n) {s = (n)*sizeof(*x); x = (t) malloc(s, M_PCB, M_NOWAIT);\
if (x == 0) panic("tp_timerinit"); bzero((caddr_t)x, s);}
/*
* Initialize storage
*/
GETME(TP_callout, struct Ecallout *, 2 * N_TPREF);
GETME(tp_ref, struct tp_ref *, 1 + N_TPREF);
TP_callfree = TP_callout + ((2 * N_TPREF) - 1);
for (e = TP_callfree; e > TP_callout; e--)
e->c_next = e - 1;
/* hate to do this but we really don't want zero to be a legit ref */
tp_maxrefopen = 1;
tp_ref[0].tpr_state = REF_FROZEN; /* white lie -- no ref timer, don't
* want this one to be allocated- ever
* unless, of course, you make refs and address instead of an
* index - then 0 can be allocated
*/
#undef GETME
if (tp_refinfo.tpr_base)
return;
tp_refinfo.tpr_size = N_TPREF + 1; /* Need to start somewhere */
s = sizeof(*tp_ref) * tp_refinfo.tpr_size;
if ((tp_ref = (struct tp_ref *) malloc(s, M_PCB, M_NOWAIT)) == 0)
panic("tp_timerinit");
bzero((caddr_t)tp_ref, (unsigned) s);
tp_refinfo.tpr_base = tp_ref;
tp_rttdiv = hz / PR_SLOWHZ;
tp_rttadd = (2 * tp_rttdiv) - 1;
}
#ifdef TP_DEBUG_TIMERS
/********************** e timers *************************/
/*
* CALLED FROM:
* tp_slowtimo() every 1/2 second, for each open reference
* FUNCTION and ARGUMENTS:
* (refp) indicates a reference structure that is in use.
* This ref structure may contain active E-type timers.
* Update the timers and if any expire, create an event and
* call the driver.
*/
static void
tp_Eclock(refp)
struct tp_ref *refp; /* the reference structure */
{
register struct Ecallout *p1; /* to drift through the list of callouts */
struct tp_event E; /* event to pass to tp_driver() */
int tp_driver(); /* drives the FSM */
/*
* Update real-time timeout queue.
* At front of queue are some number of events which are ``due''.
* The time to these is <= 0 and if negative represents the
* number of ticks which have passed since it was supposed to happen.
* The rest of the q elements (times > 0) are events yet to happen,
* where the time for each is given as a delta from the previous.
* Decrementing just the first of these serves to decrement the time
* to all events.
*
* This version, which calls the driver directly, doesn't pass
* along the ticks - may want to add the ticks if there's any use
* for them.
*/
IncStat(ts_Eticks);
p1 = refp->tpr_calltodo.c_next;
while (p1) {
if (--p1->c_time > 0)
break;
if (p1->c_time == 0)
break;
p1 = p1->c_next;
}
for (;;) {
struct tp_pcb *tpcb;
if ((p1 = refp->tpr_calltodo.c_next) == 0 || p1->c_time > 0) {
break;
}
refp->tpr_calltodo.c_next = p1->c_next;
p1->c_next = TP_callfree;
#ifndef lint
E.ev_number = p1->c_func;
E.ATTR(TM_data_retrans).e_low = (SeqNum) p1->c_arg1;
E.ATTR(TM_data_retrans).e_high = (SeqNum) p1->c_arg2;
E.ATTR(TM_data_retrans).e_retrans = p1->c_arg3;
#endif lint
IFDEBUG(D_TIMER)
printf("E expired! event 0x%x (0x%x,0x%x), pcb 0x%x ref %d\n",
p1->c_func, p1->c_arg1, p1->c_arg2, refp->tpr_pcb,
refp-tp_ref);
ENDDEBUG
TP_callfree = p1;
IncStat(ts_Eexpired);
(void) tp_driver( tpcb = refp->tpr_pcb, &E);
if (p1->c_func == TM_reference && tpcb->tp_state == TP_CLOSED)
free((caddr_t)tpcb, M_PCB); /* XXX wart; where else to do it? */
}
}
/*
* CALLED FROM:
* tp.trans all over
* FUNCTION and ARGUMENTS:
* Set an E type timer. (refp) is the ref structure.
* Causes fun(arg1,arg2,arg3) to be called after time t.
* Set an E type timer.
*/
void
tp_etimeout(refp, fun, arg1, arg2, arg3, ticks)
struct tp_ref *refp;
int fun; /* function to be called */
u_int arg1, arg2;
int arg3;
register int ticks;
tp_etimeout(tpcb, fun, ticks)
register struct tp_pcb *tpcb;
int fun; /* function to be called */
int ticks;
{
register struct Ecallout *p1, *p2, *pnew;
/* p1 and p2 drift through the list of timeout callout structures,
* pnew points to the newly created callout structure
*/
register u_int *callp;
IFDEBUG(D_TIMER)
printf("etimeout pcb 0x%x state 0x%x\n", refp->tpr_pcb,
refp->tpr_pcb->tp_state);
printf("etimeout pcb 0x%x state 0x%x\n", tpcb, tpcb->tp_state);
ENDDEBUG
IFTRACE(D_TIMER)
tptrace(TPPTmisc, "tp_etimeout ref refstate tks Etick", refp-tp_ref,
refp->tpr_state, ticks, tp_stat.ts_Eticks);
tptrace(TPPTmisc, "tp_etimeout ref refstate tks Etick", tpcb->tp_lref,
tpcb->tp_state, ticks, tp_stat.ts_Eticks);
ENDTRACE
if (tpcb == 0)
return;
IncStat(ts_Eset);
if (ticks == 0)
ticks = 1;
pnew = TP_callfree;
if (pnew == (struct Ecallout *)0)
panic("tp timeout table overflow");
TP_callfree = pnew->c_next;
pnew->c_arg1 = arg1;
pnew->c_arg2 = arg2;
pnew->c_arg3 = arg3;
pnew->c_func = fun;
for (p1 = &(refp->tpr_calltodo);
(p2 = p1->c_next) && p2->c_time < ticks; p1 = p2)
if (p2->c_time > 0)
ticks -= p2->c_time;
p1->c_next = pnew;
pnew->c_next = p2;
pnew->c_time = ticks;
if (p2)
p2->c_time -= ticks;
callp = tpcb->tp_timer + fun;
if (*callp == 0 || *callp > ticks)
*callp = ticks;
}
/*
@ -265,64 +149,16 @@ tp_etimeout(refp, fun, arg1, arg2, arg3, ticks)
* Cancel all occurrences of E-timer function (fun) for reference (refp)
*/
void
tp_euntimeout(refp, fun)
struct tp_ref *refp;
tp_euntimeout(tpcb, fun)
register struct tp_pcb *tpcb;
int fun;
{
register struct Ecallout *p1, *p2; /* ptrs to drift through the list */
IFTRACE(D_TIMER)
tptrace(TPPTmisc, "tp_euntimeout ref", refp-tp_ref, 0, 0, 0);
tptrace(TPPTmisc, "tp_euntimeout ref", tpcb->tp_lref, 0, 0, 0);
ENDTRACE
p1 = &refp->tpr_calltodo;
while ( (p2 = p1->c_next) != 0) {
if (p2->c_func == fun) {
if (p2->c_next && p2->c_time > 0)
p2->c_next->c_time += p2->c_time;
p1->c_next = p2->c_next;
p2->c_next = TP_callfree;
TP_callfree = p2;
IncStat(ts_Ecan_act);
continue;
}
p1 = p2;
}
}
/*
* CALLED FROM:
* tp.trans, when an incoming ACK causes things to be dropped
* from the retransmission queue, and we want their associated
* timers to be cancelled.
* FUNCTION and ARGUMENTS:
* cancel all occurrences of function (fun) where (arg2) < (seq)
*/
void
tp_euntimeout_lss(refp, fun, seq)
struct tp_ref *refp;
int fun;
SeqNum seq;
{
register struct Ecallout *p1, *p2;
IFTRACE(D_TIMER)
tptrace(TPPTmisc, "tp_euntimeoutLSS ref", refp-tp_ref, seq, 0, 0);
ENDTRACE
p1 = &refp->tpr_calltodo;
while ( (p2 = p1->c_next) != 0) {
if ((p2->c_func == fun) && SEQ_LT(refp->tpr_pcb, p2->c_arg2, seq)) {
if (p2->c_next && p2->c_time > 0)
p2->c_next->c_time += p2->c_time;
p1->c_next = p2->c_next;
p2->c_next = TP_callfree;
TP_callfree = p2;
IncStat(ts_Ecan_act);
continue;
}
p1 = p2;
}
if (tpcb)
tpcb->tp_timer[fun] = 0;
}
/**************** c timers **********************
@ -332,7 +168,7 @@ tp_euntimeout_lss(refp, fun, seq)
* are typically cancelled so it's faster not to
* mess with the chains
*/
#endif
/*
* CALLED FROM:
* the clock, every 500 ms
@ -340,47 +176,122 @@ tp_euntimeout_lss(refp, fun, seq)
* Look for open references with active timers.
* If they exist, call the appropriate timer routines to update
* the timers and possibly generate events.
* (The E timers are done in other procedures; the C timers are
* updated here, and events for them are generated here.)
*/
ProtoHook
void
tp_slowtimo()
{
register int r,t;
struct Ccallout *cp;
struct tp_ref *rp = tp_ref;
register u_int *cp;
register struct tp_ref *rp;
struct tp_pcb *tpcb;
struct tp_event E;
int s = splnet();
int s = splnet(), t;
/* check only open reference structures */
IncStat(ts_Cticks);
rp++; /* tp_ref[0] is never used */
for( r=1 ; (r <= tp_maxrefopen) ; r++,rp++ ) {
if (rp->tpr_state < REF_OPEN)
/* tp_ref[0] is never used */
for (rp = tp_ref + tp_refinfo.tpr_maxopen; rp > tp_ref; rp--) {
if ((tpcb = rp->tpr_pcb) == 0 || tpcb->tp_refstate < REF_OPEN)
continue;
/* check the C-type timers */
cp = rp->tpr_callout;
for (t=0 ; t < N_CTIMERS; t++,cp++) {
if( cp->c_active ) {
if( --cp->c_time <= 0 ) {
cp->c_active = FALSE;
E.ev_number = t;
IFDEBUG(D_TIMER)
printf("C expired! type 0x%x\n", t);
ENDDEBUG
IncStat(ts_Cexpired);
tp_driver( rp->tpr_pcb, &E);
/* check the timers */
for (t = 0; t < TM_NTIMERS; t++) {
cp = tpcb->tp_timer + t;
if (*cp && --(*cp) <= 0 ) {
*cp = 0;
E.ev_number = t;
IFDEBUG(D_TIMER)
printf("tp_slowtimo: pcb 0x%x t %d\n",
tpcb, t);
ENDDEBUG
IncStat(ts_Cexpired);
tp_driver(tpcb, &E);
if (t == TM_reference && tpcb->tp_state == TP_CLOSED) {
if (tpcb->tp_notdetached) {
IFDEBUG(D_CONN)
printf("PRU_DETACH: not detached\n");
ENDDEBUG
tp_detach(tpcb);
}
/* XXX wart; where else to do it? */
free((caddr_t)tpcb, M_PCB);
}
}
}
/* now update the list */
tp_Eclock(rp);
}
splx(s);
return 0;
}
/*
* Called From: tp.trans from tp_slowtimo() -- retransmission timer went off.
*/
tp_data_retrans(tpcb)
register struct tp_pcb *tpcb;
{
int rexmt, win;
tpcb->tp_rttemit = 0; /* cancel current round trip time */
tpcb->tp_dupacks = 0;
tpcb->tp_sndnxt = tpcb->tp_snduna;
if (tpcb->tp_fcredit == 0) {
/*
* We transmitted new data, started timing it and the window
* got shrunk under us. This can only happen if all data
* that they wanted us to send got acked, so don't
* bother shrinking the congestion windows, et. al.
* The retransmission timer should have been reset in goodack()
*/
IFDEBUG(D_ACKRECV)
printf("tp_data_retrans: 0 window tpcb 0x%x una 0x%x\n",
tpcb, tpcb->tp_snduna);
ENDDEBUG
tpcb->tp_rxtshift = 0;
tpcb->tp_timer[TM_data_retrans] = 0;
tpcb->tp_timer[TM_sendack] = tpcb->tp_dt_ticks;
return;
}
rexmt = tpcb->tp_dt_ticks << min(tpcb->tp_rxtshift, TP_MAXRXTSHIFT);
win = min(tpcb->tp_fcredit, (tpcb->tp_cong_win / tpcb->tp_l_tpdusize / 2));
win = max(win, 2);
tpcb->tp_cong_win = tpcb->tp_l_tpdusize; /* slow start again. */
tpcb->tp_ssthresh = win * tpcb->tp_l_tpdusize;
/* We're losing; our srtt estimate is probably bogus.
* Clobber it so we'll take the next rtt measurement as our srtt;
* Maintain current rxt times until then.
*/
if (++tpcb->tp_rxtshift > TP_NRETRANS / 4) {
/* tpcb->tp_nlprotosw->nlp_losing(tpcb->tp_npcb) someday */
tpcb->tp_rtt = 0;
}
TP_RANGESET(tpcb->tp_rxtcur, rexmt, tpcb->tp_peer_acktime, 128);
tpcb->tp_timer[TM_data_retrans] = tpcb->tp_rxtcur;
tp_send(tpcb);
}
void
tp_fasttimo()
{
register struct tp_pcb *t;
int s = splnet();
struct tp_event E;
E.ev_number = TM_sendack;
while ((t = tp_ftimeolist) != (struct tp_pcb *)&tp_ftimeolist) {
if (t == 0) {
printf("tp_fasttimeo: should panic");
tp_ftimeolist = (struct tp_pcb *)&tp_ftimeolist;
} else {
if (t->tp_flags & TPF_DELACK) {
IncStat(ts_Fdelack);
tp_driver(t, &E);
t->tp_flags &= ~TPF_DELACK;
} else
IncStat(ts_Fpruned);
tp_ftimeolist = t->tp_fasttimeo;
t->tp_fasttimeo = 0;
}
}
splx(s);
}
#ifdef TP_DEBUG_TIMERS
/*
* CALLED FROM:
* tp.trans, tp_emit()
@ -388,21 +299,21 @@ tp_slowtimo()
* Set a C type timer of type (which) to go off after (ticks) time.
*/
void
tp_ctimeout(refp, which, ticks)
register struct tp_ref *refp;
tp_ctimeout(tpcb, which, ticks)
register struct tp_pcb *tpcb;
int which, ticks;
{
register struct Ccallout *cp = &(refp->tpr_callout[which]);
IFTRACE(D_TIMER)
tptrace(TPPTmisc, "tp_ctimeout ref which tpcb active",
(int)(refp - tp_ref), which, refp->tpr_pcb, cp->c_active);
tpcb->tp_lref, which, tpcb, tpcb->tp_timer[which]);
ENDTRACE
if(cp->c_active)
if(tpcb->tp_timer[which])
IncStat(ts_Ccan_act);
IncStat(ts_Cset);
cp->c_time = ticks;
cp->c_active = TRUE;
if (ticks <= 0)
ticks = 1;
tpcb->tp_timer[which] = ticks;
}
/*
@ -413,25 +324,20 @@ tp_ctimeout(refp, which, ticks)
* parameter (ticks) is > the current value of the timer.
*/
void
tp_ctimeout_MIN(refp, which, ticks)
register struct tp_ref *refp;
tp_ctimeout_MIN(tpcb, which, ticks)
register struct tp_pcb *tpcb;
int which, ticks;
{
register struct Ccallout *cp = &(refp->tpr_callout[which]);
IFTRACE(D_TIMER)
tptrace(TPPTmisc, "tp_ctimeout_MIN ref which tpcb active",
(int)(refp - tp_ref), which, refp->tpr_pcb, cp->c_active);
tpcb->tp_lref, which, tpcb, tpcb->tp_timer[which]);
ENDTRACE
if(cp->c_active)
IncStat(ts_Ccan_act);
IncStat(ts_Cset);
if( cp->c_active )
cp->c_time = MIN(ticks, cp->c_time);
else {
cp->c_time = ticks;
cp->c_active = TRUE;
}
if (tpcb->tp_timer[which]) {
tpcb->tp_timer[which] = min(ticks, tpcb->tp_timer[which]);
IncStat(ts_Ccan_act);
} else
tpcb->tp_timer[which] = ticks;
}
/*
@ -441,26 +347,24 @@ tp_ctimeout_MIN(refp, which, ticks)
* Cancel the (which) timer in the ref structure indicated by (refp).
*/
void
tp_cuntimeout(refp, which)
tp_cuntimeout(tpcb, which)
register struct tp_pcb *tpcb;
int which;
register struct tp_ref *refp;
{
register struct Ccallout *cp;
cp = &(refp->tpr_callout[which]);
IFDEBUG(D_TIMER)
printf("tp_cuntimeout(0x%x, %d) active %d\n", refp, which, cp->c_active);
printf("tp_cuntimeout(0x%x, %d) active %d\n",
tpcb, which, tpcb->tp_timer[which]);
ENDDEBUG
IFTRACE(D_TIMER)
tptrace(TPPTmisc, "tp_cuntimeout ref which, active", refp-tp_ref,
which, cp->c_active, 0);
which, tpcb->tp_timer[which], 0);
ENDTRACE
if(cp->c_active)
if (tpcb->tp_timer[which])
IncStat(ts_Ccan_act);
else
IncStat(ts_Ccan_inact);
cp->c_active = FALSE;
tpcb->tp_timer[which] = 0;
}
#endif

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,13 +30,10 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)tp_timer.h 7.4 (Berkeley) 5/6/91
* $Id: tp_timer.h,v 1.3 1993/05/20 05:28:01 cgd Exp $
* from: @(#)tp_timer.h 8.1 (Berkeley) 6/10/93
* $Id: tp_timer.h,v 1.4 1994/05/13 06:09:51 mycroft Exp $
*/
#ifndef _NETISO_TP_TIMER_H_
#define _NETISO_TP_TIMER_H_
/***********************************************************
Copyright IBM Corporation 1987
@ -64,25 +61,28 @@ SOFTWARE.
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
*/
/*
* ARGO TP
* The callout structures used by the tp timers.
*/
/* C timers - one per tpcb, generally cancelled */
#ifndef _NETISO_TP_TIMER_H_
#define _NETISO_TP_TIMER_H_
struct Ccallout {
int c_time; /* incremental time */
int c_active; /* this timer is active? */
};
#define SET_DELACK(t) {\
(t)->tp_flags |= TPF_DELACK; \
if ((t)->tp_fasttimeo == 0)\
{ (t)->tp_fasttimeo = tp_ftimeolist; tp_ftimeolist = (t); } }
/* E timers - generally expire or there must be > 1 active per tpcb */
struct Ecallout {
int c_time; /* incremental time */
int c_func; /* function to call */
u_int c_arg1; /* argument to routine */
u_int c_arg2; /* argument to routine */
int c_arg3; /* argument to routine */
struct Ecallout *c_next;
};
#ifdef ARGO_DEBUG
#define TP_DEBUG_TIMERS
#endif
#endif /* !_NETISO_TP_TIMER_H_ */
#ifndef TP_DEBUG_TIMERS
#define tp_ctimeout(tpcb, which, timo) ((tpcb)->tp_timer[which] = (timo))
#define tp_cuntimeout(tpcb, which) ((tpcb)->tp_timer[which] = 0)
#define tp_etimeout tp_ctimeout
#define tp_euntimeout tp_cuntimeout
#define tp_ctimeout_MIN(p, w, t) \
{ if((p)->tp_timer[w] > (t)) (p)->tp_timer[w] = (t);}
#endif /* TP_DEBUG_TIMERS */
#endif /* _NETISO_TP_TIMER_H_ */

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,13 +30,10 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)tp_tpdu.h 7.4 (Berkeley) 5/6/91
* $Id: tp_tpdu.h,v 1.4 1994/05/05 07:56:39 cgd Exp $
* from: @(#)tp_tpdu.h 8.1 (Berkeley) 6/10/93
* $Id: tp_tpdu.h,v 1.5 1994/05/13 06:09:53 mycroft Exp $
*/
#ifndef _NETISO_TP_TPDU_H_
#define _NETISO_TP_TPDU_H_
/***********************************************************
Copyright IBM Corporation 1987
@ -64,9 +61,29 @@ SOFTWARE.
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
*/
/*
* ARGO TP
* This ghastly set of macros makes it possible to
* refer to tpdu structures without going mad.
*/
#ifndef _NETISO_TP_TPDU_H_
#define _NETISO_TP_TPDU_H_
#ifndef BYTE_ORDER
/*
* Definitions for byte order,
* according to byte significance from low address to high.
*/
#define LITTLE_ENDIAN 1234 /* least-significant byte first (vax) */
#define BIG_ENDIAN 4321 /* most-significant byte first (IBM, net) */
#define PDP_ENDIAN 3412 /* LSB first in word, MSW first in long (pdp) */
#ifdef vax
#define BYTE_ORDER LITTLE_ENDIAN
#else
#define BYTE_ORDER BIG_ENDIAN /* mc68000, tahoe, most others */
#endif
#endif /* BYTE_ORDER */
/* This much of a tpdu is the same for all types of tpdus (except
* DT tpdus in class 0; their exceptions are handled by the data
* structure below
@ -272,4 +289,4 @@ struct tpdu {
union tpdu_fixed_rest _tpdufr;
};
#endif /* !_NETISO_TP_TPDU_H_ */
#endif /* _NETISO_TP_TPDU_H_ */

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,8 +30,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)tp_trace.c 7.4 (Berkeley) 5/6/91
* $Id: tp_trace.c,v 1.3 1993/12/18 00:44:02 mycroft Exp $
* from: @(#)tp_trace.c 8.1 (Berkeley) 6/10/93
* $Id: tp_trace.c,v 1.4 1994/05/13 06:09:55 mycroft Exp $
*/
/***********************************************************
@ -61,8 +61,6 @@ SOFTWARE.
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
*/
/*
* ARGO TP
*
* The whole protocol trace module.
* We keep a circular buffer of trace structures, which are big
* unions of different structures we might want to see.
@ -76,7 +74,6 @@ SOFTWARE.
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/time.h>
#include <netiso/tp_param.h>
@ -171,4 +168,4 @@ tpTrace(tpcb, event, arg, src, len, arg4, arg5)
break;
}
}
#endif TPPT
#endif /* TPPT */

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,13 +30,10 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)tp_trace.h 7.5 (Berkeley) 6/27/91
* $Id: tp_trace.h,v 1.3 1993/05/20 05:28:06 cgd Exp $
* from: @(#)tp_trace.h 8.1 (Berkeley) 6/10/93
* $Id: tp_trace.h,v 1.4 1994/05/13 06:09:56 mycroft Exp $
*/
#ifndef _NETISO_TP_TRACE_H_
#define _NETISO_TP_TRACE_H_
/***********************************************************
Copyright IBM Corporation 1987
@ -64,11 +61,13 @@ SOFTWARE.
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
*/
/*
* ARGO TP
*
* Definitions needed for the protocol trace mechanism.
*/
#ifndef _NETISO_TP_TRACE_H_
#define _NETISO_TP_TRACE_H_
#define TPPTsendack 1
#define TPPTgotack 2
#define TPPTXack 3
@ -85,13 +84,13 @@ SOFTWARE.
#define TPPTdriver 14
#define TPPTtpduout 15
#include "../netiso/tp_pcb.h"
#include <netiso/tp_pcb.h>
/* this #if is to avoid lint */
#if defined(TP_TRACEFILE)||!defined(KERNEL)
#include "../netiso/tp_tpdu.h"
#include <netiso/tp_tpdu.h>
#define TPTRACE_STRLEN 50
@ -114,7 +113,7 @@ struct tp_Trace {
struct inpcb tpt_Inpcb; /* protocol control block */
struct tp_ref tpt_Ref; /* ref part of pcb */
struct tpdu tpt_Tpdu; /* header*/
struct tp_param tpt_Param; /* ?? bytes, make sure < 128??*/
struct tp_refinfo tpt_Param; /* ?? bytes, make sure < 128??*/
struct tp_timeval tpt_Time;
struct {
u_int tptm_2;
@ -145,7 +144,7 @@ struct tp_Trace {
#define tpt_window tpt_stuff.tpt_Time.tptv_window
#define tpt_size tpt_stuff.tpt_Time.tptv_size
#endif defined(TP_TRACEFILE)||!defined(KERNEL)
#endif /* defined(TP_TRACEFILE)||!defined(KERNEL) */
#ifdef TPPT
@ -173,8 +172,7 @@ int tp_Tracen = 0;
*/
#define ENDTRACE }
#else TPPT
#else /* TPPT */
/***********************************************
* NO TPPT TRACE STUFF
@ -187,6 +185,6 @@ int tp_Tracen = 0;
#define IFTRACE(ascii) if (0) {
#define ENDTRACE }
#endif TPPT
#endif /* TPPT */
#endif /* !_NETISO_TP_TRACE_H_ */
#endif /* _NETISO_TP_TRACE_H_ */

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,13 +30,10 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)tp_user.h 7.10 (Berkeley) 5/6/91
* $Id: tp_user.h,v 1.3 1993/05/20 05:28:08 cgd Exp $
* from: @(#)tp_user.h 8.1 (Berkeley) 6/10/93
* $Id: tp_user.h,v 1.4 1994/05/13 06:09:57 mycroft Exp $
*/
#ifndef _NETISO_TP_USER_H_
#define _NETISO_TP_USER_H_
/***********************************************************
Copyright IBM Corporation 1987
@ -64,18 +61,13 @@ SOFTWARE.
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
*/
/*
* ARGO TP
*
* These are the values a real-live user ;-) needs.
*/
#ifndef _TYPES_
#ifdef KERNEL
#include "../sys/types.h"
#else KERNEL
#include <sys/types.h>
#endif KERNEL
#endif
#include <sys/types.h>
#ifndef _NETISO_TP_USER_H_
#define _NETISO_TP_USER_H_
struct tp_conn_param {
/* PER CONNECTION parameters */
@ -94,7 +86,7 @@ struct tp_conn_param {
short p_ref_ticks;
short p_inact_ticks;
short p_unused; /* was .. local credit fraction reported (>0) */
short p_ptpdusize; /* preferred tpdusize/128 */
short p_winsize;
u_char p_tpdusize; /* log 2 of size */
@ -134,12 +126,11 @@ struct tp_conn_param {
#define TPOPT_DISC_DATA 0x500
#define TPOPT_CFRM_DATA 0x600
#define TPOPT_CDDATA_CLEAR 0x700
#define TPOPT_MY_TSEL 0x800
#define TPOPT_PEER_TSEL 0x900
#define TPOPT_PERF_MEAS 0xa00
#define TPOPT_PSTATISTICS 0xb00
#define TPOPT_PARAMS 0xc00 /* to replace a bunch of the others */
#define TPOPT_MY_TSEL 0x800
#define TPOPT_PEER_TSEL 0x900
#define TPOPT_NGC8_ACCEPT 0xd00 /* negotiate connection requests */
#define TPOPT_DISC_REASON 0xe00
struct tp_disc_reason {
@ -152,18 +143,14 @@ struct tp_disc_reason {
*/
/* read only flags */
#define TPFLAG_DISC_DATA_OUT (u_char)0x10 /* disc data present */
#define TPFLAG_DISC_DATA_IN (u_char)0x20 /* disc data present */
#define TPFLAG_CONN_DATA_OUT (u_char)0x40 /* conn data present */
#define TPFLAG_CONN_DATA_IN (u_char)0x80 /* conn data present */
#define TPFLAG_XPD_PRESENT (u_char)0x08 /* xpd data present */
#define TPFLAG_PEER_ON_SAMENET (u_char)0x02
#define TPFLAG_NLQOS_PDN (u_char)0x01
#define TPFLAG_NGC8_ACCEPT (u_char)0x04 /* negotiate conn rq's */
#define TPFLAG_PEER_ON_SAMENET (u_char)0x02
#define TPFLAG_GENERAL_ADDR (u_char)0x04 /* bound to wildcard addr */
/*
***********************end flags******************************
*/
#endif /* !_NETISO_TP_USER_H_ */
#endif /* _NETISO_TP_USER_H_ */

View File

@ -1,6 +1,6 @@
/*-
* Copyright (c) 1991 The Regents of the University of California.
* All rights reserved.
* Copyright (c) 1991, 1993
* The 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
@ -30,8 +30,8 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)tp_usrreq.c 7.17 (Berkeley) 6/27/91
* $Id: tp_usrreq.c,v 1.3 1993/12/18 00:44:04 mycroft Exp $
* from: @(#)tp_usrreq.c 8.1 (Berkeley) 6/10/93
* $Id: tp_usrreq.c,v 1.4 1994/05/13 06:09:59 mycroft Exp $
*/
/***********************************************************
@ -61,8 +61,6 @@ SOFTWARE.
* ARGO Project, Computer Sciences Dept., University of Wisconsin - Madison
*/
/*
* ARGO TP
*
* tp_usrreq(), the fellow that gets called from most of the socket code.
* Pretty straighforward.
* THe only really awful stuff here is the OOB processing, which is done
@ -92,7 +90,7 @@ SOFTWARE.
#include <netiso/iso.h>
#include <netiso/iso_errno.h>
int tp_attach(), tp_driver();
int tp_attach(), tp_pcbbind();
int TNew;
int TPNagle1, TPNagle2;
struct tp_pcb *tp_listeners, *tp_intercepts;
@ -137,7 +135,7 @@ dump_mbuf(n, str)
}
printf("\n");
}
#endif notdef
#endif /* notdef */
if (n->m_next == n) {
printf("LOOP!\n");
return;
@ -149,7 +147,7 @@ dump_mbuf(n, str)
printf("\n");
}
#endif ARGO_DEBUG
#endif /* ARGO_DEBUG */
/*
* CALLED FROM:
@ -206,7 +204,7 @@ restart:
* uipc_socket2.c (like sbappend).
*/
sblock(sb);
sblock(sb, M_WAITOK);
for (nn = &sb->sb_mb; n = *nn; nn = &n->m_act)
if (n->m_type == MT_OOBDATA)
break;
@ -243,7 +241,8 @@ restart:
if ((inflags & MSG_PEEK) == 0) {
n = *nn;
*nn = n->m_act;
sb->sb_cc -= m->m_len;
for (; n; n = m_free(n))
sbfree(sb, n);
}
release:
@ -311,7 +310,7 @@ tp_sendoob(tpcb, so, xdata, outflags)
while (sb->sb_mb) {
sbunlock(&so->so_snd); /* already locked by sosend */
sbwait(&so->so_snd);
sblock(&so->so_snd); /* sosend will unlock on return */
sblock(&so->so_snd, M_WAITOK); /* sosend will unlock on return */
}
}
@ -370,7 +369,7 @@ tp_sendoob(tpcb, so, xdata, outflags)
*
*/
/*ARGSUSED*/
ProtoHook
int
tp_usrreq(so, req, m, nam, controlp)
struct socket *so;
u_int req;
@ -406,18 +405,15 @@ tp_usrreq(so, req, m, nam, controlp)
case PRU_ATTACH:
if (tpcb) {
error = EISCONN;
break;
}
if (error = tp_attach(so, so->so_proto->pr_domain->dom_family))
break;
tpcb = sototpcb(so);
} else if ((error = tp_attach(so, (int)nam)) == 0)
tpcb = sototpcb(so);
break;
case PRU_ABORT: /* called from close() */
/* called for each incoming connect queued on the
* parent (accepting) socket
*/
if (tpcb->tp_state == TP_OPEN) {
if (tpcb->tp_state == TP_OPEN || tpcb->tp_state == TP_CONFIRMING) {
E.ATTR(T_DISC_req).e_reason = E_TP_NO_SESSION;
error = DoEvent(T_DISC_req); /* pretend it was a close() */
break;
@ -425,27 +421,14 @@ tp_usrreq(so, req, m, nam, controlp)
case PRU_DETACH: /* called from close() */
/* called only after disconnect was called */
if (tpcb->tp_state == TP_LISTENING) {
register struct tp_pcb **tt;
for (tt = &tp_listeners; *tt; tt = &((*tt)->tp_nextlisten))
if (*tt == tpcb)
break;
if (*tt)
*tt = tpcb->tp_nextlisten;
else {
for (tt = &tp_intercepts; *tt; tt = &((*tt)->tp_nextlisten))
if (*tt == tpcb)
break;
if (*tt)
*tt = tpcb->tp_nextlisten;
else
printf("tp_usrreq - detach: should panic\n");
}
}
if (tpcb->tp_next)
remque(tpcb);
error = DoEvent(T_DETACH);
if (tpcb->tp_state == TP_CLOSED) {
if (tpcb->tp_notdetached) {
IFDEBUG(D_CONN)
printf("PRU_DETACH: not detached\n");
ENDDEBUG
tp_detach(tpcb);
}
free((caddr_t)tpcb, M_PCB);
tpcb = 0;
}
@ -459,30 +442,24 @@ tp_usrreq(so, req, m, nam, controlp)
break;
case PRU_BIND:
error = (tpcb->tp_nlproto->nlp_pcbbind)(so->so_pcb, nam);
if (error == 0) {
(tpcb->tp_nlproto->nlp_getsufx)(so->so_pcb, &tpcb->tp_lsuffixlen,
tpcb->tp_lsuffix, TP_LOCAL);
}
error = tp_pcbbind(tpcb, nam);
break;
case PRU_LISTEN:
if (tpcb->tp_lsuffixlen == 0) {
if (error = (tpcb->tp_nlproto->nlp_pcbbind)(so->so_pcb, MNULL))
break;
(tpcb->tp_nlproto->nlp_getsufx)(so->so_pcb, &tpcb->tp_lsuffixlen,
tpcb->tp_lsuffix, TP_LOCAL);
}
if (tpcb->tp_next == 0) {
if (tpcb->tp_state != TP_CLOSED || tpcb->tp_lsuffixlen == 0 ||
tpcb->tp_next == 0)
error = EINVAL;
else {
register struct tp_pcb **tt;
remque(tpcb);
tpcb->tp_next = tpcb->tp_prev = tpcb;
tpcb->tp_nextlisten = tp_listeners;
tp_listeners = tpcb;
for (tt = &tp_listeners; *tt; tt = &((*tt)->tp_nextlisten))
if ((*tt)->tp_lsuffixlen)
break;
tpcb->tp_nextlisten = *tt;
*tt = tpcb;
error = DoEvent(T_LISTEN_req);
}
IFDEBUG(D_TPISO)
if (tpcb->tp_state != TP_CLOSED)
printf("LISTEN ERROR: state 0x%x\n", tpcb->tp_state);
ENDDEBUG
error = DoEvent(T_LISTEN_req);
break;
case PRU_CONNECT2:
@ -502,16 +479,13 @@ tp_usrreq(so, req, m, nam, controlp)
tpcb->tp_class);
ENDDEBUG
if (tpcb->tp_lsuffixlen == 0) {
if (error = (tpcb->tp_nlproto->nlp_pcbbind)(so->so_pcb, MNULL)) {
if (error = tp_pcbbind(tpcb, MNULL)) {
IFDEBUG(D_CONN)
printf("pcbbind returns error 0x%x\n", error);
ENDDEBUG
break;
}
(tpcb->tp_nlproto->nlp_getsufx)(so->so_pcb, &tpcb->tp_lsuffixlen,
tpcb->tp_lsuffix, TP_LOCAL);
}
IFDEBUG(D_CONN)
printf("isop 0x%x isop->isop_socket offset 12 :\n", tpcb->tp_npcb);
dump_buf(tpcb->tp_npcb, 16);
@ -527,16 +501,14 @@ tp_usrreq(so, req, m, nam, controlp)
ENDDEBUG
if (tpcb->tp_fsuffixlen == 0) {
/* didn't set peer extended suffix */
(tpcb->tp_nlproto->nlp_getsufx)(so->so_pcb, &tpcb->tp_fsuffixlen,
(tpcb->tp_nlproto->nlp_getsufx)(tpcb->tp_npcb, &tpcb->tp_fsuffixlen,
tpcb->tp_fsuffix, TP_FOREIGN);
}
(void) (tpcb->tp_nlproto->nlp_mtu)(so, so->so_pcb,
&tpcb->tp_l_tpdusize, &tpcb->tp_tpdusize, 0);
if (tpcb->tp_state == TP_CLOSED) {
soisconnecting(so);
error = DoEvent(T_CONN_req);
} else {
(tpcb->tp_nlproto->nlp_pcbdisc)(so->so_pcb);
(tpcb->tp_nlproto->nlp_pcbdisc)(tpcb->tp_npcb);
error = EISCONN;
}
IFPERF(tpcb)
@ -551,7 +523,7 @@ tp_usrreq(so, req, m, nam, controlp)
break;
case PRU_ACCEPT:
(tpcb->tp_nlproto->nlp_getnetaddr)(so->so_pcb, nam, TP_FOREIGN);
(tpcb->tp_nlproto->nlp_getnetaddr)(tpcb->tp_npcb, nam, TP_FOREIGN);
IFDEBUG(D_REQUEST)
printf("ACCEPT PEERADDDR:");
dump_buf(mtod(nam, char *), nam->m_len);
@ -647,19 +619,12 @@ tp_usrreq(so, req, m, nam, controlp)
* possibly by a whole cluster.
*/
{
register struct mbuf *n = m;
register struct sockbuf *sb = &so->so_snd;
int maxsize = tpcb->tp_l_tpdusize
- tp_headersize(DT_TPDU_type, tpcb)
- (tpcb->tp_use_checksum?4:0) ;
int totlen = n->m_pkthdr.len;
int mbufcnt = 0;
struct mbuf *nn;
/*
* Could have eotsdu and no data.(presently MUST have
* an mbuf though, even if its length == 0)
*/
int totlen = m->m_pkthdr.len;
struct sockbuf *sb = &so->so_snd;
IFPERF(tpcb)
PStat(tpcb, Nb_from_sess) += totlen;
tpmeas(tpcb->tp_lref, TPtime_from_session, 0, 0,
@ -672,65 +637,9 @@ tp_usrreq(so, req, m, nam, controlp)
dump_mbuf(sb->sb_mb, "so_snd.sb_mb");
dump_mbuf(m, "m : to be added");
ENDDEBUG
/*
* Pre-packetize the data in the sockbuf
* according to negotiated mtu. Do it here
* where we can safely wait for mbufs.
*
* This presumes knowledge of sockbuf conventions.
*/
if (n = sb->sb_mb)
while (n->m_act)
n = n->m_act;
if ((nn = n) && n->m_pkthdr.len < maxsize) {
u_int space = maxsize - n->m_pkthdr.len;
do {
if (n->m_flags & M_EOR)
goto on1;
} while (n->m_next && (n = n->m_next));
if (totlen <= space) {
TPNagle1++;
n->m_next = m;
nn->m_pkthdr.len += totlen;
while (n = n->m_next)
sballoc(sb, n);
if (eotsdu)
nn->m_flags |= M_EOR;
goto on2;
} else {
/*
* Can't sleep here, because when you wake up
* packet you want to attach to may be gone!
*/
if (TNew && (n->m_next = m_copym(m, 0, space, M_NOWAIT))) {
nn->m_pkthdr.len += space;
TPNagle2++;
while (n = n->m_next)
sballoc(sb, n);
m_adj(m, space);
}
}
}
on1: mbufcnt++;
for (n = m; n->m_pkthdr.len > maxsize;) {
nn = m_copym(n, 0, maxsize, M_WAIT);
sbappendrecord(sb, nn);
m_adj(n, maxsize);
mbufcnt++;
}
if (eotsdu)
n->m_flags |= M_EOR;
sbappendrecord(sb, n);
on2:
IFTRACE(D_DATA)
tptraceTPCB(TPPTmisc,
"SEND BF: maxsize totlen mbufcnt eotsdu",
maxsize, totlen, mbufcnt, eotsdu);
ENDTRACE
tp_packetize(tpcb, m, eotsdu);
IFDEBUG(D_SYSCALL)
printf("PRU_SEND: eot %d after sbappend 0x%x mbufcnt 0x%x\n",
eotsdu, n, mbufcnt);
printf("PRU_SEND: eot %d after sbappend 0x%x\n", eotsdu, m);
dump_mbuf(sb->sb_mb, "so_snd.sb_mb");
ENDDEBUG
if (tpcb->tp_state == TP_OPEN)
@ -745,11 +654,11 @@ tp_usrreq(so, req, m, nam, controlp)
break;
case PRU_SOCKADDR:
(tpcb->tp_nlproto->nlp_getnetaddr)(so->so_pcb, nam, TP_LOCAL);
(tpcb->tp_nlproto->nlp_getnetaddr)(tpcb->tp_npcb, nam, TP_LOCAL);
break;
case PRU_PEERADDR:
(tpcb->tp_nlproto->nlp_getnetaddr)(so->so_pcb, nam, TP_FOREIGN);
(tpcb->tp_nlproto->nlp_getnetaddr)(tpcb->tp_npcb, nam, TP_FOREIGN);
break;
case PRU_CONTROL:
@ -767,18 +676,18 @@ tp_usrreq(so, req, m, nam, controlp)
default:
#ifdef ARGO_DEBUG
printf("tp_usrreq UNKNOWN PRU %d\n", req);
#endif ARGO_DEBUG
#endif /* ARGO_DEBUG */
error = EOPNOTSUPP;
}
IFDEBUG(D_REQUEST)
printf("%s, so 0x%x, tpcb 0x%x, error %d, state %d\n",
"returning from tp_usrreq", so, tpcb, error,
tpcb ? 0 : tpcb->tp_state);
tpcb ? tpcb->tp_state : 0);
ENDDEBUG
IFTRACE(D_REQUEST)
tptraceTPCB(TPPTusrreq, "END req so m state [", req, so, m,
tpcb?0:tpcb->tp_state);
tpcb ? tpcb->tp_state : 0);
ENDTRACE
if (controlp) {
m_freem(controlp);

350
sys/netiso/tuba_subr.c Normal file
View File

@ -0,0 +1,350 @@
/*
* Copyright (c) 1992, 1993
* The 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.
*
* from: @(#)tuba_subr.c 8.1 (Berkeley) 6/10/93
* $Id: tuba_subr.c,v 1.1 1994/05/13 06:10:01 mycroft Exp $
*/
#include <sys/param.h>
#include <sys/proc.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/protosw.h>
#include <sys/errno.h>
#include <net/route.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/in_pcb.h>
#include <netinet/ip_var.h>
#include <netinet/ip_icmp.h>
#include <netinet/tcp.h>
#include <netinet/tcp_fsm.h>
#include <netinet/tcp_seq.h>
#include <netinet/tcp_timer.h>
#include <netinet/tcp_var.h>
#include <netinet/tcpip.h>
#include <netinet/tcp_debug.h>
#include <netiso/argo_debug.h>
#include <netiso/iso.h>
#include <netiso/clnp.h>
#include <netiso/iso_pcb.h>
#include <netiso/iso_var.h>
#include <netiso/tuba_table.h>
static struct sockaddr_iso null_siso = { sizeof(null_siso), AF_ISO, };
extern int tuba_table_size, tcp_keepidle, tcp_keepintvl, tcp_maxidle;
extern int tcppcbcachemiss, tcppredack, tcppreddat, tcprexmtthresh;
extern struct tcpiphdr tcp_saveti;
struct inpcb tuba_inpcb;
struct inpcb *tuba_last_inpcb = &tuba_inpcb;
struct isopcb tuba_isopcb;
/*
* Tuba initialization
*/
void
tuba_init()
{
#define TUBAHDRSIZE (3 /*LLC*/ + 9 /*CLNP Fixed*/ + 42 /*Addresses*/ \
+ 6 /*CLNP Segment*/ + 20 /*TCP*/)
tuba_inpcb.inp_next = tuba_inpcb.inp_prev = &tuba_inpcb;
tuba_isopcb.isop_next = tuba_isopcb.isop_prev = &tuba_isopcb;
tuba_isopcb.isop_faddr = &tuba_isopcb.isop_sfaddr;
tuba_isopcb.isop_laddr = &tuba_isopcb.isop_sladdr;
if (max_protohdr < TUBAHDRSIZE)
max_protohdr = TUBAHDRSIZE;
if (max_linkhdr + TUBAHDRSIZE > MHLEN)
panic("tuba_init");
}
struct addr_arg {
int error;
int offset;
u_long sum;
};
/*
* Calculate contribution to fudge factor for TCP checksum,
* and coincidentally set pointer for convenience of clnp_output
* if we are are responding when there is no isopcb around.
*/
static void
tuba_getaddr(arg, siso, index)
register struct addr_arg *arg;
struct sockaddr_iso **siso;
u_long index;
{
register struct tuba_cache *tc;
if (index <= tuba_table_size && (tc = tuba_table[index])) {
if (siso)
*siso = &tc->tc_siso;
arg->sum += (arg->offset & 1 ? tc->tc_ssum : tc->tc_sum)
+ (0xffff ^ index);
arg->offset += tc->tc_siso.siso_nlen + 1;
} else
arg->error = 1;
}
tuba_output(m, tp)
register struct mbuf *m;
struct tcpcb *tp;
{
register struct tcpiphdr *n;
struct isopcb *isop;
struct addr_arg arg;
if (tp == 0 || (n = tp->t_template) == 0 ||
(isop = (struct isopcb *)tp->t_tuba_pcb) == 0) {
isop = &tuba_isopcb;
n = mtod(m, struct tcpiphdr *);
arg.error = arg.sum = arg.offset = 0;
tuba_getaddr(&arg, &tuba_isopcb.isop_faddr, n->ti_dst.s_addr);
tuba_getaddr(&arg, &tuba_isopcb.isop_laddr, n->ti_src.s_addr);
REDUCE(arg.sum, arg.sum);
goto adjust;
}
if (n->ti_sum == 0) {
arg.error = arg.sum = arg.offset = 0;
tuba_getaddr(&arg, (struct sockaddr_iso **)0, n->ti_dst.s_addr);
tuba_getaddr(&arg, (struct sockaddr_iso **)0, n->ti_src.s_addr);
REDUCE(arg.sum, arg.sum);
n->ti_sum = arg.sum;
n = mtod(m, struct tcpiphdr *);
adjust:
if (arg.error) {
m_freem(m);
return (EADDRNOTAVAIL);
}
REDUCE(n->ti_sum, n->ti_sum + (0xffff ^ arg.sum));
}
m->m_len -= sizeof (struct ip);
m->m_pkthdr.len -= sizeof (struct ip);
m->m_data += sizeof (struct ip);
return (clnp_output(m, isop, m->m_pkthdr.len, 0));
}
tuba_refcnt(isop, delta)
struct isopcb *isop;
{
register struct tuba_cache *tc;
unsigned index, sum;
if (delta != 1)
delta = -1;
if (isop == 0 || isop->isop_faddr == 0 || isop->isop_laddr == 0 ||
(delta == -1 && isop->isop_tuba_cached == 0) ||
(delta == 1 && isop->isop_tuba_cached != 0))
return;
isop->isop_tuba_cached = (delta == 1);
if ((index = tuba_lookup(isop->isop_faddr, M_DONTWAIT)) != 0 &&
(tc = tuba_table[index]) != 0 && (delta == 1 || tc->tc_refcnt > 0))
tc->tc_refcnt += delta;
if ((index = tuba_lookup(isop->isop_laddr, M_DONTWAIT)) != 0 &&
(tc = tuba_table[index]) != 0 && (delta == 1 || tc->tc_refcnt > 0))
tc->tc_refcnt += delta;
}
tuba_pcbdetach(isop)
struct isopcb *isop;
{
if (isop == 0)
return;
tuba_refcnt(isop, -1);
isop->isop_socket = 0;
iso_pcbdetach(isop);
}
/*
* Avoid in_pcbconnect in faked out tcp_input()
*/
tuba_pcbconnect(inp, nam)
register struct inpcb *inp;
struct mbuf *nam;
{
register struct sockaddr_iso *siso;
struct sockaddr_in *sin = mtod(nam, struct sockaddr_in *);
struct tcpcb *tp = intotcpcb(inp);
struct isopcb *isop = (struct isopcb *)tp->t_tuba_pcb;
int error;
/* hardwire iso_pcbbind() here */
siso = isop->isop_laddr = &isop->isop_sladdr;
*siso = tuba_table[inp->inp_laddr.s_addr]->tc_siso;
siso->siso_tlen = sizeof(inp->inp_lport);
bcopy((caddr_t)&inp->inp_lport, TSEL(siso), sizeof(inp->inp_lport));
/* hardwire in_pcbconnect() here without assigning route */
inp->inp_fport = sin->sin_port;
inp->inp_faddr = sin->sin_addr;
/* reuse nam argument to call iso_pcbconnect() */
nam->m_len = sizeof(*siso);
siso = mtod(nam, struct sockaddr_iso *);
*siso = tuba_table[inp->inp_faddr.s_addr]->tc_siso;
siso->siso_tlen = sizeof(inp->inp_fport);
bcopy((caddr_t)&inp->inp_fport, TSEL(siso), sizeof(inp->inp_fport));
if ((error = iso_pcbconnect(isop, nam)) == 0)
tuba_refcnt(isop, 1);
return (error);
}
/*
* CALLED FROM:
* clnp's input routine, indirectly through the protosw.
* FUNCTION and ARGUMENTS:
* Take a packet (m) from clnp, strip off the clnp header
* and do tcp input processing.
* No return value.
*/
tuba_tcpinput(m, src, dst)
register struct mbuf *m;
struct sockaddr_iso *src, *dst;
{
unsigned long sum, lindex, findex;
register struct tcpiphdr *ti;
register struct inpcb *inp;
caddr_t optp = NULL;
int optlen;
int len, tlen, off;
register struct tcpcb *tp = 0;
int tiflags;
struct socket *so;
int todrop, acked, ourfinisacked, needoutput = 0;
short ostate;
struct in_addr laddr;
int dropsocket = 0, iss = 0;
u_long tiwin, ts_val, ts_ecr;
int ts_present = 0;
if ((m->m_flags & M_PKTHDR) == 0)
panic("tuba_tcpinput");
/*
* Do some housekeeping looking up CLNP addresses.
* If we are out of space might as well drop the packet now.
*/
tcpstat.tcps_rcvtotal++;
lindex = tuba_lookup(dst, M_DONTWAIT);
findex = tuba_lookup(src, M_DONTWAIT);
if (lindex == 0 || findex == 0)
goto drop;
/*
* CLNP gave us an mbuf chain WITH the clnp header pulled up,
* but the data pointer pushed past it.
*/
len = m->m_len;
tlen = m->m_pkthdr.len;
m->m_data -= sizeof(struct ip);
m->m_len += sizeof(struct ip);
m->m_pkthdr.len += sizeof(struct ip);
m->m_flags &= ~(M_MCAST|M_BCAST); /* XXX should do this in clnp_input */
/*
* The reassembly code assumes it will be overwriting a useless
* part of the packet, which is why we need to have it point
* into the packet itself.
*
* Check to see if the data is properly alligned
* so that we can save copying the tcp header.
* This code knows way too much about the structure of mbufs!
*/
off = ((sizeof (long) - 1) & ((m->m_flags & M_EXT) ?
(m->m_data - m->m_ext.ext_buf) : (m->m_data - m->m_pktdat)));
if (off || len < sizeof(struct tcphdr)) {
struct mbuf *m0 = m;
MGETHDR(m, M_DONTWAIT, MT_DATA);
if (m == 0) {
m = m0;
goto drop;
}
m->m_next = m0;
m->m_data += max_linkhdr;
m->m_pkthdr = m0->m_pkthdr;
m->m_flags = m0->m_flags & M_COPYFLAGS;
if (len < sizeof(struct tcphdr)) {
m->m_len = 0;
if ((m = m_pullup(m, sizeof(struct tcpiphdr))) == 0) {
tcpstat.tcps_rcvshort++;
return;
}
} else {
bcopy(mtod(m0, caddr_t) + sizeof(struct ip),
mtod(m, caddr_t) + sizeof(struct ip),
sizeof(struct tcphdr));
m0->m_len -= sizeof(struct tcpiphdr);
m0->m_data += sizeof(struct tcpiphdr);
m->m_len = sizeof(struct tcpiphdr);
}
}
/*
* Calculate checksum of extended TCP header and data,
* replacing what would have been IP addresses by
* the IP checksum of the CLNP addresses.
*/
ti = mtod(m, struct tcpiphdr *);
ti->ti_dst.s_addr = tuba_table[lindex]->tc_sum;
if (dst->siso_nlen & 1)
ti->ti_src.s_addr = tuba_table[findex]->tc_sum;
else
ti->ti_src.s_addr = tuba_table[findex]->tc_ssum;
ti->ti_prev = ti->ti_next = 0;
ti->ti_x1 = 0; ti->ti_pr = ISOPROTO_TCP;
ti->ti_len = htons((u_short)tlen);
if (ti->ti_sum = in_cksum(m, m->m_pkthdr.len)) {
tcpstat.tcps_rcvbadsum++;
goto drop;
}
ti->ti_src.s_addr = findex;
ti->ti_dst.s_addr = lindex;
/*
* Now include the rest of TCP input
*/
#define TUBA_INCLUDE
#define in_pcbconnect tuba_pcbconnect
#define tcb tuba_inpcb
#define tcp_last_inpcb tuba_last_inpcb
#include <netinet/tcp_input.c>
}
#define tcp_slowtimo tuba_slowtimo
#define tcp_fasttimo tuba_fasttimo
#include <netinet/tcp_timer.c>

144
sys/netiso/tuba_table.c Normal file
View File

@ -0,0 +1,144 @@
/*
* Copyright (c) 1992, 1993
* The 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.
*
* from: @(#)tuba_table.c 8.2 (Berkeley) 11/15/93
* $Id: tuba_table.c,v 1.1 1994/05/13 06:10:04 mycroft Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/domain.h>
#include <sys/protosw.h>
#include <sys/ioctl.h>
#include <sys/time.h>
#include <sys/kernel.h>
#include <net/if.h>
#include <net/radix.h>
#include <netiso/iso.h>
#include <netiso/tuba_table.h>
int tuba_table_size;
struct tuba_cache **tuba_table;
struct radix_node_head *tuba_tree;
extern int arpt_keep, arpt_prune; /* use same values as arp cache */
void
tuba_timer()
{
int s = splnet();
int i;
register struct tuba_cache *tc;
long timelimit = time.tv_sec - arpt_keep;
timeout(tuba_timer, (caddr_t)0, arpt_prune * hz);
for (i = tuba_table_size; i > 0; i--)
if ((tc = tuba_table[i]) && (tc->tc_refcnt == 0) &&
(tc->tc_time < timelimit)) {
tuba_table[i] = 0;
rn_delete(&tc->tc_siso.siso_addr, NULL, tuba_tree);
free((caddr_t)tc, M_RTABLE);
}
splx(s);
}
tuba_table_init()
{
rn_inithead((void **)&tuba_tree, 40);
timeout(tuba_timer, (caddr_t)0, arpt_prune * hz);
}
int
tuba_lookup(siso, wait)
register struct sockaddr_iso *siso;
{
struct radix_node *rn, *rn_match();
register struct tuba_cache *tc;
struct tuba_cache **new;
int dupentry = 0, sum_a = 0, sum_b = 0, old_size, i;
if ((rn = rn_match((caddr_t)&siso->siso_addr, tuba_tree->rnh_treetop))
&& ((rn->rn_flags & RNF_ROOT) == 0)) {
tc = (struct tuba_cache *)rn;
tc->tc_time = time.tv_sec;
return (tc->tc_index);
}
if ((tc = (struct tuba_cache *)malloc(sizeof(*tc), M_RTABLE, wait))
== NULL)
return (0);
bzero((caddr_t)tc, sizeof (*tc));
bcopy(siso->siso_data, tc->tc_siso.siso_data,
tc->tc_siso.siso_nlen = siso->siso_nlen);
rn_insert(&tc->tc_siso.siso_addr, tuba_tree, &dupentry, tc->tc_nodes);
if (dupentry)
panic("tuba_lookup 1");
tc->tc_siso.siso_family = AF_ISO;
tc->tc_siso.siso_len = sizeof(tc->tc_siso);
tc->tc_time = time.tv_sec;
for (i = sum_a = tc->tc_siso.siso_nlen; --i >= 0; )
(i & 1 ? sum_a : sum_b) += (u_char)tc->tc_siso.siso_data[i];
REDUCE(tc->tc_sum, (sum_a << 8) + sum_b);
HTONS(tc->tc_sum);
SWAB(tc->tc_ssum, tc->tc_sum);
for (i = tuba_table_size; i > 0; i--)
if (tuba_table[i] == 0)
goto fixup;
old_size = tuba_table_size;
if (tuba_table_size == 0)
tuba_table_size = 15;
if (tuba_table_size > 0x7fff)
return (0);
tuba_table_size = 1 + 2 * tuba_table_size;
i = (tuba_table_size + 1) * sizeof(tc);
new = (struct tuba_cache **)malloc((unsigned)i, M_RTABLE, wait);
if (new == 0) {
tuba_table_size = old_size;
rn_delete(&tc->tc_siso.siso_addr, NULL, tuba_tree);
free((caddr_t)tc, M_RTABLE);
return (0);
}
bzero((caddr_t)new, (unsigned)i);
if (tuba_table) {
bcopy((caddr_t)tuba_table, (caddr_t)new, i >> 1);
free((caddr_t)tuba_table, M_RTABLE);
}
tuba_table = new;
i = tuba_table_size;
fixup:
tuba_table[i] = tc;
tc->tc_index = i;
return (tc->tc_index);
}

60
sys/netiso/tuba_table.h Normal file
View File

@ -0,0 +1,60 @@
/*-
* Copyright (c) 1992, 1993
* The 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.
*
* from: @(#)tuba_table.h 8.1 (Berkeley) 6/10/93
* $Id: tuba_table.h,v 1.1 1994/05/13 06:10:07 mycroft Exp $
*/
struct tuba_cache {
struct radix_node tc_nodes[2]; /* convenient lookup */
int tc_refcnt;
int tc_time; /* last looked up */
int tc_flags;
#define TCF_PERM 1
int tc_index;
u_short tc_sum; /* cksum of nsap inc. length */
u_short tc_ssum; /* swab(tc_sum) */
struct sockaddr_iso tc_siso; /* for responding */
};
#define ADDCARRY(x) (x >= 65535 ? x -= 65535 : x)
#define REDUCE(a, b) { union { u_short s[2]; long l;} l_util; long x; \
l_util.l = (b); x = l_util.s[0] + l_util.s[1]; ADDCARRY(x); \
if (x == 0) x = 0xffff; a = x;}
#define SWAB(a, b) { union { u_char c[2]; u_short s;} s; u_char t; \
s.s = (b); t = s.c[0]; s.c[0] = s.c[1]; s.c[1] = t; a = s.s;}
#ifdef KERNEL
extern int tuba_table_size;
extern struct tuba_cache **tuba_table;
extern struct radix_node_head *tuba_tree;
#endif

313
sys/netiso/tuba_usrreq.c Normal file
View File

@ -0,0 +1,313 @@
/*
* Copyright (c) 1992, 1993
* The 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.
*
* from: @(#)tuba_usrreq.c 8.1 (Berkeley) 6/10/93
* $Id: tuba_usrreq.c,v 1.1 1994/05/13 06:10:10 mycroft Exp $
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/protosw.h>
#include <sys/errno.h>
#include <sys/stat.h>
#include <net/if.h>
#include <net/route.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/in_pcb.h>
#include <netinet/ip_var.h>
#include <netinet/tcp.h>
#include <netinet/tcp_fsm.h>
#include <netinet/tcp_seq.h>
#include <netinet/tcp_timer.h>
#include <netinet/tcp_var.h>
#include <netinet/tcpip.h>
#include <netinet/tcp_debug.h>
#include <netiso/argo_debug.h>
#include <netiso/iso.h>
#include <netiso/clnp.h>
#include <netiso/iso_pcb.h>
#include <netiso/iso_var.h>
#include <netiso/tuba_table.h>
/*
* TCP protocol interface to socket abstraction.
*/
extern char *tcpstates[];
extern struct inpcb tuba_inpcb;
extern struct isopcb tuba_isopcb;
/*
* Process a TCP user request for TCP tb. If this is a send request
* then m is the mbuf chain of send data. If this is a timer expiration
* (called from the software clock routine), then timertype tells which timer.
*/
/*ARGSUSED*/
tuba_usrreq(so, req, m, nam, control)
struct socket *so;
int req;
struct mbuf *m, *nam, *control;
{
register struct inpcb *inp;
register struct isopcb *isop;
register struct tcpcb *tp;
int s;
int error = 0;
int ostate;
struct sockaddr_iso *siso;
if (req == PRU_CONTROL)
return (iso_control(so, (int)m, (caddr_t)nam,
(struct ifnet *)control));
s = splnet();
inp = sotoinpcb(so);
/*
* When a TCP is attached to a socket, then there will be
* a (struct inpcb) pointed at by the socket, and this
* structure will point at a subsidary (struct tcpcb).
*/
if (inp == 0 && req != PRU_ATTACH) {
splx(s);
return (EINVAL); /* XXX */
}
if (inp) {
tp = intotcpcb(inp);
if (tp == 0)
panic("tuba_usrreq");
ostate = tp->t_state;
isop = (struct isopcb *)tp->t_tuba_pcb;
if (isop == 0)
panic("tuba_usrreq 2");
} else
ostate = 0;
switch (req) {
/*
* TCP attaches to socket via PRU_ATTACH, reserving space,
* and an internet control block. We also need to
* allocate an isopcb and separate the control block from
* tcp/ip ones.
*/
case PRU_ATTACH:
if (error = iso_pcballoc(so, &tuba_isopcb))
break;
isop = (struct isopcb *)so->so_pcb;
so->so_pcb = 0;
if (error = tcp_usrreq(so, req, m, nam, control)) {
isop->isop_socket = 0;
iso_pcbdetach(isop);
} else {
inp = sotoinpcb(so);
remque(inp);
insque(inp, &tuba_inpcb);
inp->inp_head = &tuba_inpcb;
tp = intotcpcb(inp);
if (tp == 0)
panic("tuba_usrreq 3");
tp->t_tuba_pcb = (caddr_t) isop;
}
goto notrace;
/*
* PRU_DETACH detaches the TCP protocol from the socket.
* If the protocol state is non-embryonic, then can't
* do this directly: have to initiate a PRU_DISCONNECT,
* which may finish later; embryonic TCB's can just
* be discarded here.
*/
case PRU_DETACH:
if (tp->t_state > TCPS_LISTEN)
tp = tcp_disconnect(tp);
else
tp = tcp_close(tp);
if (tp == 0)
tuba_pcbdetach(isop);
break;
/*
* Give the socket an address.
*/
case PRU_BIND:
siso = mtod(nam, struct sockaddr_iso *);
if (siso->siso_tlen && siso->siso_tlen != 2) {
error = EINVAL;
break;
}
if ((error = iso_pcbbind(isop, nam)) ||
(siso = isop->isop_laddr) == 0)
break;
bcopy(TSEL(siso), &inp->inp_lport, 2);
if (siso->siso_nlen &&
!(inp->inp_laddr.s_addr = tuba_lookup(siso, M_WAITOK)))
error = ENOBUFS;
break;
/*
* Prepare to accept connections.
*/
case PRU_CONNECT:
case PRU_LISTEN:
if (inp->inp_lport == 0 &&
(error = iso_pcbbind(isop, (struct mbuf *)0)))
break;
bcopy(TSEL(isop->isop_laddr), &inp->inp_lport, 2);
if (req == PRU_LISTEN) {
tp->t_state = TCPS_LISTEN;
break;
}
/*FALLTHROUGH*/
/*
* Initiate connection to peer.
* Create a template for use in transmissions on this connection.
* Enter SYN_SENT state, and mark socket as connecting.
* Start keep-alive timer, and seed output sequence space.
* Send initial segment on connection.
*/
/* case PRU_CONNECT: */
if (error = iso_pcbconnect(isop, nam))
break;
if ((siso = isop->isop_laddr) && siso->siso_nlen > 1)
siso->siso_data[siso->siso_nlen - 1] = ISOPROTO_TCP;
else
panic("tuba_usrreq: connect");
siso = mtod(nam, struct sockaddr_iso *);
if (!(inp->inp_faddr.s_addr = tuba_lookup(siso, M_WAITOK))) {
unconnect:
iso_pcbdisconnect(isop);
error = ENOBUFS;
break;
}
bcopy(TSEL(isop->isop_faddr), &inp->inp_fport, 2);
if (inp->inp_laddr.s_addr == 0 &&
(inp->inp_laddr.s_addr =
tuba_lookup(isop->isop_laddr, M_WAITOK)) == 0)
goto unconnect;
if ((tp->t_template = tcp_template(tp)) == 0)
goto unconnect;
soisconnecting(so);
tcpstat.tcps_connattempt++;
tp->t_state = TCPS_SYN_SENT;
tp->t_timer[TCPT_KEEP] = TCPTV_KEEP_INIT;
tp->iss = tcp_iss; tcp_iss += TCP_ISSINCR/2;
tcp_sendseqinit(tp);
error = tcp_output(tp);
tuba_refcnt(isop, 1);
break;
/*
* Initiate disconnect from peer.
* If connection never passed embryonic stage, just drop;
* else if don't need to let data drain, then can just drop anyways,
* else have to begin TCP shutdown process: mark socket disconnecting,
* drain unread data, state switch to reflect user close, and
* send segment (e.g. FIN) to peer. Socket will be really disconnected
* when peer sends FIN and acks ours.
*
* SHOULD IMPLEMENT LATER PRU_CONNECT VIA REALLOC TCPCB.
*/
case PRU_DISCONNECT:
if ((tp = tcp_disconnect(tp)) == 0)
tuba_pcbdetach(isop);
break;
/*
* Accept a connection. Essentially all the work is
* done at higher levels; just return the address
* of the peer, storing through addr.
*/
case PRU_ACCEPT:
bcopy((caddr_t)isop->isop_faddr, mtod(nam, caddr_t),
nam->m_len = isop->isop_faddr->siso_len);
break;
/*
* Mark the connection as being incapable of further output.
*/
case PRU_SHUTDOWN:
socantsendmore(so);
tp = tcp_usrclosed(tp);
if (tp)
error = tcp_output(tp);
else
tuba_pcbdetach(isop);
break;
/*
* Abort the TCP.
*/
case PRU_ABORT:
if ((tp = tcp_drop(tp, ECONNABORTED)) == 0)
tuba_pcbdetach(isop);
break;
case PRU_SOCKADDR:
if (isop->isop_laddr)
bcopy((caddr_t)isop->isop_laddr, mtod(nam, caddr_t),
nam->m_len = isop->isop_laddr->siso_len);
break;
case PRU_PEERADDR:
if (isop->isop_faddr)
bcopy((caddr_t)isop->isop_faddr, mtod(nam, caddr_t),
nam->m_len = isop->isop_faddr->siso_len);
break;
default:
error = tcp_usrreq(so, req, m, nam, control);
goto notrace;
}
if (tp && (so->so_options & SO_DEBUG))
tcp_trace(TA_USER, ostate, tp, (struct tcpiphdr *)0, req);
notrace:
splx(s);
return(error);
}
tuba_ctloutput(op, so, level, optname, mp)
int op;
struct socket *so;
int level, optname;
struct mbuf **mp;
{
int clnp_ctloutput(), tcp_ctloutput();
return ((level != IPPROTO_TCP ? clnp_ctloutput : tcp_ctloutput)
(op, so, level, optname, mp));
}