SRI-NOSC/ncpd/skt_oper.c

#

/*	skt_oper.c	*/

/*	globals declared in this file:
		skt_oper

	functions declared in this file:
		so_ignr
		so_glchk
		so_fseq
		so_match
		glsn_q
		lsint_q
		rfc_util
		rfc_rfcw
		rfc_slsn
		rfc_glsn
		cls_rfcw
		cls_q
		cls_cacw
		cls_clsw
		cls_open
		clo_lsn
		clo_rfop
		clo_cacw
		clo_c2cw
		so_ut1
		so_ut2
		so_ut3
		tmo_q
		stimeout
*/

#include	"hstlnk.h"
#include	"files.h"
#include	"socket.h"
#include	"kwrite.h"
#include	"globvar.h"

/* SCCS PROGRAM IDENTIFICATION STRING */
char id_skt_oper[] "~|^`skt_oper.c\tV3.9E0\tJan78\n";


/*name:
	so_ignr

function:
	"place holder" for null intersections in socket operation matrix.

algorithm:
	does nothing but return0 to indicate no match.

parameters:
	skt_p	pointer to socket struct with which it does nothing.

returns:
	zero.

globals:
	none.

calls:
	nothing.

called by:
	get_skt	thru skt_oper.

history:
	initial coding 1/7/75 by G. R. Grossman.

*/

int	so_ignr(skt_p)
struct socket	*skt_p;
{
	return(0);
}

/*name:
	so_glchk

function:
	given pointers to a socket struct with possible "wild" fields and
	a normal (tame) socket struct, check for match of host and foreign
	socket fields taking anything as a match for a wild field.
	if a match is made, copy tame fields into wild socket.

algorithm:
	if host field of wild socket is 0 (i.e., wild)
	or the host fields are equal:
		if foreign socket field of wild socket is 0 (i.e., wild)
		or foreign socket fields match via so_fseq:
			copy host and foreign socket fields from tame to
			wild socket.
			return 1.
	if any conditions are not met:
		return 0.

parameters:
	w_skt_p		pointer to socket struct with possible "wild" fields.
	t_skt_p		pointer to normal (tame) socket struct.

returns:
	1	iff a match was made.
	0	otherwise.

globals:
	s_*
	host=

calls:
	so_fseq

called by:
	glsn_q
	rfc_glsn

history:
	initial coding to replace so_cphfs 6/10/75 by G. R. Grossman.
	Bug 1/6/76 S. F. Holmgren:
	global host assigned from queued rfc so protocol resulting
	from the match will go to the right host.

*/

int	so_glchk ( w_skt_p, t_skt_p )
struct socket	*w_skt_p, *t_skt_p;
{
	register char	*tp,	/* points to "tame" struct for compares */
				/* and its foreign socket field for copy */
			*wp;	/* same for "wild" */

	register int	n;	/* counter for same */

	wp = w_skt_p;		/* copy pointers to registers */
	tp = t_skt_p;
	if (    ( wp->s_hstlnk.hl_host == 0 )	/* host wild? */
	     || ( wp->s_hstlnk.hl_host == tp->s_hstlnk.hl_host ) )
			/* or hosts =? */
	{
		if (    ( ( wp->s_fskt[0].word | w_skt_p->s_fskt[2].word )
			  == 0 )	/* foreign socket wild? */
		     || so_fseq ( wp, tp ) )	/* or foreign sockets
							   equal? */
		{
			wp->s_hstlnk.hl_host = tp->s_hstlnk.hl_host;
			host = (tp->s_hstlnk.hl_host & 0377);
				/* copy host from tame to wild */
			tp = &tp->s_fskt[0];	/* set source for copy */
			wp = &wp->s_fskt[0];	/* ditto for dest */
			for ( n = 4 ; n > 0 ; n-- )	/* copy four bytes */
				*wp++ = *tp++;
			return ( 1 );	/* indicate success */
		}
	}
	return ( 0 );	/* indicate failure */
}

/*name:
	so_fseq

function:
	compares foreign socket fields of two socket structs.

algorithm:
	establish char pointers to the two fields to be compared.
	step thru the fields a byte at a time:
		if bytes are not equal:
			return 0.
	if fall out of loop, fields are equal:
		return 1.

parameters:
	lsp	pointer to one of the socket structs whose foreign socket
		fields are to be comared.
	rsp	pointer to the other such socket struct.

returns:
	1	iff the two foreign sockets are byte-for-byte equal.
	0	otherwise.

globals:
	s_*

calls:
	nothing.

called by:
	so_glchk
	so_match

history:
	initial coding 6/10/75 by G. R. Grossman

*/

int	so_fseq ( lsp, rsp )
struct socket	*lsp, *rsp;
{
	register char	*lbp,	/* one of two pointers used for compare */
			*rbp;	/* other such pointer */
	register int	n;	/* counter for compare */

	lbp = &lsp->s_fskt[0];	/* set pointers */
	rbp = &rsp->s_fskt[0];
	for ( n = 4 ; n > 0 ; n-- )	/* compare four bytes */
		if ( *lbp++ != *rbp++ )		/* bytes not equal? */
			return ( 0 );		/* failure return */
	return ( 1 );		/* success return if fall out of loop */
}

/*name:
	so_match

function:
	determines whether host and foreign socket of skt_req and specified
	socket are equal.

algorithm:
	if hosts do not match:
		return 0.
	return result of match of foreign sockets via so_fseq.

parameters:
	skt_p	pointer to socket struct which is to be matched with
		skt_req.

returns:
	1	if host and foreign sockets match.
	0	if they do not.

globals:
	skt_req
	s_*

calls:
	so_fseq

called by:
	lsint_q
	rfc_util
	cls_rfcw
	cls_q
	cls_cacw
	cls_clsw
	cls_open

history:
	initial coding 1/7/75 by G. R. Grossman
	revised to use so_fseq 6/10/75 by G. R. Grossman

*/

int	so_match(skt_p)
struct socket	*skt_p;
{
	if ( skt_req.s_hstlnk.hl_host != skt_p->s_hstlnk.hl_host )
			/* hosts not equal? */
		return(0);
	return ( so_fseq ( &skt_req.lo_byte, skt_p ) );	/* return result of 
						   compare of foreign sockets */
}

/*name:
	glsn_q

function:
	handles the case in which a general listen matches a queued rfc.

algorithm:
	if a "wild" match for host and foreign socket is made via so_glchk:
		return result returned by lsint_q.
	otherwise:
		return 0.

parameters:
	skt_p	pointer to socket struct on which operation is to be
		performed.

returns:
	0	if some failure was detected by lsint_q.
	1	if lsint_q was successful.

globals:
	none.

calls:
	so_glchk
	lsint_q

called by:
	get_skt	through skt_oper.

history:
	initial coding 1/7/74 by G. R. Grossman
	revised to use so_glchk 6/10/75 by G. R. Grossman.

*/

int	glsn_q(skt_p)
struct socket	*skt_p;
{
	if ( so_glchk ( &skt_req.lo_byte, skt_p ) )	/* match? */
		return(lsint_q(skt_p));	/* let lsint_q do the work */
	return ( 0 );		/* otherwise failure return */
}

/*name:
	lsint_q

function:
	directly handles the cases in which an attempt is being made to
	match a specific listen or init with a queued rfc.
	indirectly handles the general listen - queued rfc case for
	glsn_q.

algorithm:
	if host and foreign sockets match (via so_match):
		if receive socket:
			copy link number from skt_req.
		otherwise:
			copy byte size from skt_req.
		copy file pointer and socket type from skt_req.
		attach socket to file via att_skt.
		set socket state to open.
		increment socket struct allocation counter to take into
		account the fact that it was decremented in open to
		reserve a socket struct and also in so_urfc when the
		struct was actually allocated to the queued rfc. (1/10/75 GRG)
		write setup to kernel (state = open, allocations = 0)
		via kw_sumod.
		send answering rfc via hw_rfc.
		pass open to file level via fi_sopn.
		return 1.
	otherwise, no match:
		return 0.

parameters:
	skt_p	pointer to socket struct on which operation is to be
		performed.

returns:
	0	if there was no match.
	1	if there was a match and the operation was performed.

globals:
	skt_req
	ss_open
	kwi_stup
	ksb_open

calls:
	so_match
	att_skt
	kw_sumod
	hw_rfc
	fi_sopn

called by:
	get_skt	through skt_oper.
	glsn_q

history:
	initial coding 1/7/74 by G. R. Grossman
	increment of n_s_left added 1/10/75 by G. R. Grossman

*/

int	lsint_q(skt_p)
struct socket	*skt_p;
{
	register struct socket	*s_p;	/* will point to socket struct */

	s_p = skt_p;
	if ( so_match(s_p) )	/* host and foreign socket match? */
	{
		if ( (skt_req.s_lskt[1] & 1) == 0 )	/* receive socket? */
			s_p->s_hstlnk.hl_link = skt_req.s_hstlnk.hl_link;
				/* copy link number */
		else					/* send socket */
			s_p->s_bysz = skt_req.s_bysz;	/* copy byte size */
		s_p->s_filep = skt_req.s_filep;		/* copy file ptr */
		s_p->s_sinx = skt_req.s_sinx;		/* socket type */
		att_skt(s_p);		/* attach socket to file */
		s_p->s_state = ss_open;	/* set socket state to open */
		n_s_left++;		/* this socket struct was accounted
					   for during the original
					   queuing operation in so_urfc and
					   also during the open. this increment
					   resolves the conflict. */
		kw_sumod(kwi_stup,s_p,ksb_open,0,0,0);	/* kernel setup:
							   status = open,
							   0 allocation */
		hw_rfc(s_p);		/* send answering rfc */
		fi_sopn(s_p);		/* tell file level about open */
		return(1);		/* all done successfully */
	}
	else	/* no match */
		return(0);
}

/*name:
	rfc_util

function:
	indirectly handles the case in which an attempt is being made to
	match an incoming rfc with a socket in the rrc wait state.
	also indirectly handles the case of matching incoming rfc's with
	listens for rfc_slsn.

algorithm:
	if hosts and foreign sockets match ( via so_match):
		if receive socket:
			copy byte size from skt_req.
		otherwise:
			copy link number from skt_req.
		set socket state to open.
		return 1.
	otherwise, no match:
		return 0.

parameters:
	skt_p	pointer to socket struct on which operation is to be
		performed.

returns:
	0	if there was no match.
	1	if there was a match and the operation was performed.

globals:
	skt_req
	ss_open

calls:
	so_match

called by:
	rfc_rfcw
	rfc_slsn

history:
	initial coding 1/7/74 by G. R. Grossman, as rfc_rfcw
	revised as rfc_util 6/11/75 by G. R. Grossman.

*/

int	rfc_util(skt_p)
struct socket	*skt_p;
{
	register struct socket	*s_p;	/* will point to socket struct */

	s_p = skt_p;
	if ( so_match(s_p) )	/* host and foreign socket match? */
	{
		if ( (skt_req.s_lskt[1] & 1) == 0 )	/* receive socket? */
			s_p->s_bysz = skt_req.s_bysz;	/* copy byte size */
		else					/* send socket */
			s_p->s_hstlnk.hl_link = skt_req.s_hstlnk.hl_link;
				/* copy link number */
		s_p->s_state = ss_open;	/* set socket state to open */
		return(1);		/* all done successfully */
	}
	else	/* no match */
		return(0);
}

/*name:
	rfc_rfcw

function:
	handles the case in which an attempt is being made to match
	an incoming rfc with a socket in the rfc wait state.

algorithm:
	if call on rfc_util is successful:
		pass to file level via fi_sopn.
		return 1.
	otherwise:
		return 0.

parameters:
	skt_p	pointer to socket struct on which operation is to be
		performed.

returns:
	0	if there was no match.
	1	if there was a match and the operation was performed.

globals:
	none.

calls:
	rfc_util
	fi_sopn

called by:
	get_skt thru skt_oper.

history:
	initial coding 1/7/75 by G. R. Grossman
	completely recoded 6/11/75 by G. R. Grossman.


*/

int	rfc_rfcw ( skt_p )
struct socket	*skt_p;
{
	if ( rfc_util ( skt_p ) )	/* match found via rfc_util? */
	{
		fi_sopn ( skt_p );	/* pass to file level */
		return ( 1 );		/* successful return */
	}
	return ( 0 );			/* failure return */
}

/*name:
	rfc_slsn

function:
	directly handles the case in which an attempt is being made to
	match an incoming rfc with a specific listen.
	indirectly handles the case in which an incoming rfc is matched
	to a general listen for rfc_glsn.

algorithm:
	if a call on rfc_util is successful:
		send answering rfc via hw_rfc.
		pass to file level via fi_sopn.
		return 1.
	otherwise:
		return 0.

parameters:
	skt_p	pointer to socket struct on which operation is to be
		performed.

returns:
	0	if there was no match.
	1	if there was a match and the operation was performed.

globals:
	none.

calls:
	rfc_util
	fi_sopn
	hw_rfc

called by:
	get_skt	through skt_oper.
	rfc_glsn

history:
	initial coding 1/7/74 by G. R. Grossman
	revised to use rfc_util and call fi_sopn 6/11/75 by G. R. Grossman.

*/

int	rfc_slsn(skt_p)
struct socket	*skt_p;
{
	if ( rfc_util(skt_p) )	/* match a success? */
	{
		hw_rfc(skt_p);	/* send answering rfc */
		fi_sopn ( skt_p );	/* pass to file level */
		return(1);
	}
	else
		return(0);
}

/*name:
	rfc_glsn

function:
	handles the case in which an incoming rfc matches a general listen.

algorithm:
	if a "wild" match is made via so_glchk:
		return result returned by calling so_slsn.
	otherwise:
		return 0.

parameters:
	skt_p	pointer to socket struct on which operation is to be
		performed.

returns:
	0	if there was no match.
	1	if there was a match and the operation was performed.

globals:
	none.

calls:
	so_glchk
	rfc_slsn

called by:
	get_skt	through skt_oper.

history:
	initial coding 1/7/74 by G. R. Grossman
	revised to use so_glchk 6/10/75 by G. R. Grossman.

*/

int	rfc_glsn(skt_p)
struct socket	*skt_p;
{
	if ( so_glchk ( skt_p, &skt_req.lo_byte ) )	/* match? */
		return(rfc_slsn(skt_p));	/* let him do the work */
	return ( 0 );		/* failure return */
}

/*name:
	cls_rfcw

function:
	handles the case in which an attempt is being made to match an
	incoming cls with a socket in the rfc wait state.

algorithm:
	if the host and foreign socket match (via so_match):
		send clean to kernel via kw_clean.
		send cls to host via hw_cls.
		set timeout for returning cls.
		set socket to state to close wait.
		clean up local and foreign skt num and host - link fields
		return 1.
	otherwise, no match:
		return 0.

parameters:
	skt_p	pointer to socket struct on which operation is to be
		performed.

returns:
	0	if there was no match.
	1	if there was a match and the operation was performed.

globals:
	ss_clow

calls:
	so_match
	kw_clean
	hw_cls
	clean_skt
	stimeout

called by:
	get_skt	through skt_oper.

history:
	initial coding 1/7/74 by G. R. Grossman
	modified to call clean_skt 7/7/76 by S. F. Holmgren
	modified by greep for timeout

*/

int	cls_rfcw(skt_p)
struct socket	*skt_p;
{
	if ( so_match(skt_p) )	/* host and foreign socket match? */
	{
		kw_clean(skt_p);	/* send clean to kernel */
		hw_cls(skt_p);		/* send cls to host */
		skt_p->s_state = ss_clow;	/* set socket state to close
						   wait */
		stimeout(skt_p);
		clean_skt( skt_p );	/* clean up part of socket info */
		return(1);	/* indicate success */
	}
	else		/* no match */
		return(0);
}

/*name:
	cls_q

function:
	handles the case in which an attempt is being made to match an
	incoming cls with a socket in the queued state.

algorithm:
	if the host and foreign socket match ( via so_match):
		send cls to host via hw_cls.
		de-allocate socket via free_skt.
		return 1.
	otherwise:
		return 0.

parameters:
	skt_p	pointer to socket struct on which operation is to be
		performed.

returns:
	0	if there was no match.
	1	if there was a match and the operation was performed.

globals:
	none.

calls:
	so_match
	hw_cls
	free_skt

called by:
	get_skt	through skt_oper.

history:
	initial coding 1/7/74 by G. R. Grossman

*/

int	cls_q(skt_p)
struct socket	*skt_p;
{
	if ( so_match(skt_p) )	/* host and foreign socket match? */
	{
		hw_cls(skt_p);  /* send answering cls */
		free_skt(skt_p);	/* de-allocate socket */
		return(1);
	}
	else
		return(0);
}

/*name:
	cls_cacw

function:
	handles the case in which an attempt is being made to match
	an incoming cls with a socket in the close and cls wait state.

algorithm:
	if the host and foreign socket match ( via so_match):
		set socket state to close wait.
		clean up part of socket info
		cancel timeout
		return 1.
	else
		return 0.

parameters:
	skt_p	pointer to socket struct on which operation is to be
		performed.

returns:
	0	if there was no match.
	1	if there was a match and the operation was performed.

globals:
	ss_clow

calls:
	so_match
	clean_skt

called by:
	get_skt	through skt_oper.

history:
	initial coding 1/7/74 by G. R. Grossman
	modified to call clean_skt 7/7/76 by S. F. Holmgren

*/

int	cls_cacw(skt_p)
struct socket	*skt_p;
{
	if ( so_match(skt_p) )	/* host and foreign socket match? */
	{
		skt_p->s_state = ss_clow;	/* set state to close wait */
		clean_skt( skt_p );		/* clean up socket */
		return(1);
	}
	else
		return(0);
}

/*name:
	cls_clsw

function:
	handles the cse in which an attempt is being made to match
	an incoming cls with a socket in the cls wait state.

algorithm:
	if the host and foreign socket match ( via so_match):
		cancel the timeout
		de-allocate the socket via free_skt.
		return 1.
	else
		return 0.

parameters:
	skt_p	pointer to socket struct on which operation is to be
		performed.

returns:
	0	if there was no match.
	1	if there was a match and the operation was performed.

globals:
	none.

calls:
	so_match
	free_skt

called by:
	get_skt	through skt_oper.

history:
	initial coding 1/7/74 by G. R. Grossman
	modified by greep for timeout

*/

int	cls_clsw(skt_p)
struct socket	*skt_p;
{
	if ( so_match(skt_p) )	/* host and foreign socket match? */
	{
		free_skt(skt_p);	/* de-allocate socket */
		return(1);
	}
	else
		return(0);
}

/*name:
	cls_open

function:
	handles the case in which an attempt is being made to match
	an incoming cls with a socket in the open state.

algorithm:
	if the host and foreign socket match (via so_match):
		send clean to kernel via kw_clean.
		set socket state to close to cls wait.
		return 1.
	otherwise:
		return 0.

parameters:
	skt_p	pointer to socket struct on which operation is to be
		performed.

returns:
	0	if there was no match.
	1	if there was a match and the operation was performed.

globals:
	ss_c2cw

calls:
	so_match
	kw_clean

called by:
	get_skt	through skt_oper.

history:
	initial coding 1/7/74 by G. R. Grossman

*/

int	cls_open(skt_p)
struct socket	*skt_p;
{
	if ( so_match(skt_p) )	/* host and foreign socket match? */
	{
		kw_clean(skt_p);	/* send clean to kernel */
		skt_p->s_state = ss_c2cw;	/* set state to close to cls
						   wait */
		return(1);
	}
	else
		return(0);
}

/*name:
	clo_lsn

function:
	performs a close operation on a socket in the general or specific
	listen state.

algorithm:
	send clean to kernel via kw_clean.
	de-allocate socket via free_skt.

parameters:
	skt_p	pointer to socket struct on which operation is to be
		performed.

returns:
	nothing.

globals:
	none.

calls:
	kw_clean
	free_skt

called by:
	hr_close	through skt_oper.

history:
	initial coding 1/7/74 by G. R. Grossman

*/

clo_lsn(skt_p)
struct socket	*skt_p;
{
	kw_clean(skt_p);	/* send clean to kernel */
	free_skt(skt_p);	/* de-allocate socket */
}

/*name:
	clo_rfop

function:
	performs a close operation on a socket in the rfc wait or open state.

algorithm:
	send cls to host via hw_cls.
	send clean to kernel via kw_clean.
	set socket state to cls wait.
	set timeout for returning cls.

parameters:
	skt_p	pointer to socket struct on which operation is to be
		performed.

returns:
	nothing.

globals:
	ss_clsw

calls:
	hw_cls
	kw_clean
	stimeout

called by:
	hr_close	through skt_oper.

history:
	initial coding 1/7/74 by G. R. Grossman
	modified by greep for timeout

*/

clo_rfop(skt_p)
struct socket	*skt_p;
{
	hw_cls(skt_p);		/* send cls to host */
	kw_clean(skt_p);	/* send clean to kernel */
	skt_p->s_state = ss_clsw;	/* set state to cls wait */
	stimeout(skt_p);
}

/*name:
	clo_cacw

function:
	performs a close operation on a socket in the close and cls wait
	state.

algorithm:
	set socket state to cls wait.

parameters:
	skt_p	pointer to socket struct on which operation is to be
		performed.

returns:
	nothing.

globals:
	none.

calls:
	nothing.

called by:
	hr_close	through skt_oper.

history:
	initial coding 1/7/74 by G. R. Grossman
	modified by greep for timeout

*/

clo_cacw(skt_p)
struct socket	*skt_p;
{
	skt_p->s_state = ss_clsw;	/* set state to cls wait */
	stimeout(skt_p);
}

/*name:
	clo_c2cw

function:
	performs a close operation on a socket in the close to cls state.

algorithm:
	send cls to host via hw_cls.
	de-allocate socket via free_skt.

parameters:
	skt_p	pointer to socket struct on which operation is to be
		performed.

returns:
	nothing.

globals:
	none.

calls:
	hw_cls
	free_skt

called by:
	hr_close	through skt_oper.

history:
	initial coding 1/7/74 by G. R. Grossman

*/

clo_c2cw(skt_p)
struct socket	*skt_p;
{
	hw_cls(skt_p);		/* send cls to host */
	free_skt(skt_p);	/* de-allocate socket */
}

/*name:
	so_ut1

function:
	performs the following operations on sockets in the following
	states:
		operation	states
		kill		general listen
				specific listen
		timeout		general listen
				specific listen
		dead		general listen
				specific listen
				rfc wait
				open

algorithm:
	send clean to kernel via kw_clean.
	set socket state to close wait.
	clean up part of the socket info

parameters:
	skt_p	pointer to socket struct on which operation is to be
		performed.

returns:
	nothing.

globals:
	ss_clow

calls:
	kw_clean
	clean_skt

called by:
	kill_skt	through skt_oper.
	h_dead		   "       "    .

history:
	initial coding 1/7/74 by G. R. Grossman
	modified to call clean_skt 7/7/76 by S. F. Holmgren

*/

so_ut1(skt_p)
struct socket	*skt_p;
{
	kw_clean(skt_p);	/* send clean to kernel */
	skt_p->s_state = ss_clow;	/* set state to close wait */
	clean_skt( skt_p );		/* clean up part of the socket */
}

/*name:
	so_ut2

function:
	performs the following operations on sockets in the following
	states:
		operation	state
		timeout		close and cls wait
		dead		close and cls wait
				close to cls wait

algorithm:
	set state to close wait.
	clean up part of the socket 

parameters:
	skt_p	pointer to socket struct on which operation is to be
		performed.

returns:
	nothing.

globals:
	ss_clow

calls:
	clean_skt

called by:
	h_dead	through skt_oper.

history:
	initial coding 1/7/74 by G. R. Grossman
	modified to call clean_skt 7/7/76 by S. F. Holmgren

*/

so_ut2(skt_p)
struct socket	*skt_p;
{
	skt_p->s_state = ss_clow;	/* set state to close wait */
	clean_skt( skt_p );		/* clean up part of socket info */
}

/*name:
	so_ut3

function:
	performs the following operations on sockets in the following
	states:
		operation	state
		kill		rfc wait
				open
		timeout		rfc wait

algorithm:
	send cls to host via hw_cls.
	send clean to kernel via kw_clean.
	set socket state to close and cls wait.
	set timeout for returninc cls.

parameters:
	skt_p	pointer to socket struct on which operation is to be
		performed.

returns:
	nothing.

globals:
	ss_cacw

calls:
	hw_cls
	kw_clean

called by:
	kill_skt	through skt_oper.

history:
	initial coding 1/7/74 by G. R. Grossman

*/

so_ut3(skt_p)
struct socket	*skt_p;
{
	hw_cls(skt_p);		/* send cls to host */
	kw_clean(skt_p);	/* send clean to kernel */
	skt_p->s_state = ss_cacw;	/* set to close and cls state */
}
/*name:
	tmo_q

function:
	performs the timeout operation on a socket in the queued rfc state.

algorithm:
	send cls to host via hw_cls.
	set socket state to cls wait.

parameters:
	skt_p	pointer to socket struct on which operation is to be
		performed.

returns:
	nothing.

globals:
	ss_clsw

calls:
	hw_cls

called by:
	currently not called. included for completeness.

history:
	initial coding 1/7/74 by G. R. Grossman
	modified by greep for timeout although this routine is not called

*/

tmo_q(skt_p)
struct socket	*skt_p;
{
	hw_cls(skt_p);		/* send cls to host */
	skt_p->s_state = ss_clsw;	/* set state to cls wait */
	stimeout(skt_p);
}

/*name:
	stimeout

function:
	sets the timeout for a socket

algorithm:
	set timeout value in socket.
	increment stimeo.

parameters:
	skt_p	pointer to socket struct on which operation is to be
		performed.

returns:
	nothing.

globals:
	stimeo

calls:
	nothing

called by:
	clo_rfop
	so_ut3
	cls_rfcw

history:
	initial coding by greep

*/
stimeout(skt_p)
struct socket	*skt_p;
{
	long int tim;

	time ( &tim );
	skt_p->s_timeo = tim + STIMEOUT;
	stimeo++;
}
/*	new action routines from BBN to solve problem with ICP from TIP.
	documentation is needed.
*/


cls_orfnmw(skt_p)
struct socket *skt_p;
{
	if ( so_match(skt_p) )
	{
		kw_clean(skt_p);
		skt_p->s_state = ss_clorfnmw;
		return(1);
	}
	else
		return(0);
}


clo_clorfnmw(skt_p)
struct socket *skt_p;
{
	hw_cls(skt_p);
	skt_p->s_state = ss_rfnmw;
}


ki_clorfnmw(skt_p)
struct socket *skt_p;
{
	skt_p->s_state = ss_c2cw;
}
/*skt_oper
*/
int	(*skt_oper[9][12])()
{
/* si_glsn */
&so_ignr,	&so_ignr,	&so_ignr,	&glsn_q,	&so_ignr,
&so_ignr,       &so_ignr,       &so_ignr,       &so_ignr,       &so_ignr,
&so_ignr,       &so_ignr,

/* si_slsn */
&so_ignr,	&so_ignr,	&so_ignr,	&lsint_q,	&so_ignr,
&so_ignr,       &so_ignr,       &so_ignr,       &so_ignr,       &so_ignr,
&so_ignr,       &so_ignr,

/* si_init */
&so_ignr,	&so_ignr,	&so_ignr,	&lsint_q,	&so_ignr,
&so_ignr,       &so_ignr,       &so_ignr,       &so_ignr,       &so_ignr,
&so_ignr,       &so_ignr,

/* si_rfc */
&rfc_glsn,	&rfc_slsn,	&rfc_rfcw,	&so_ignr,	&so_ignr,
&so_ignr,       &so_ignr,       &so_ignr,       &so_ignr,       &so_ignr,
&so_ignr,       &so_ignr,

/* si_cls */
&so_ignr,	&so_ignr,	&cls_rfcw,	&cls_q,		&cls_cacw,
&cls_clsw,      &so_ignr,       &cls_open,      &so_ignr,       &cls_orfnmw,
&so_ignr,       &so_ignr,

/* si_close */
&clo_lsn,	&clo_lsn,	&clo_rfop,	&so_ignr,	&clo_cacw,
&so_ignr,       &free_skt,      &clo_rfop,      &clo_c2cw,      &clo_rfop,
&clo_clorfnmw,  &so_ignr,

/* si_kill */
&so_ut1,	&so_ut1,	&so_ut3,	&so_ignr,	&so_ignr,
&so_ignr,       &so_ignr,       &so_ut3,        &so_ignr,       &so_ut3,
&ki_clorfnmw,   &free_skt,

/* si_timo */
&so_ignr,       &so_ignr,       &so_ignr,       &so_ignr,       &so_ignr,
&free_skt,      &so_ignr,       &so_ignr,       &so_ignr,       &so_ignr,
&so_ignr,       &so_ignr,

/* si_dead */
&so_ut1,	&so_ut1,	&so_ut1,	&free_skt,	&so_ut2,
&free_skt,      &so_ignr,       &so_ut1,        &so_ut2,        &so_ut1,
&so_ut2,        &free_skt

}
;